Skip to content

Commit

Permalink
JSON parsing hacks from javascript
Browse files Browse the repository at this point in the history
  • Loading branch information
polstianka committed Oct 27, 2024
1 parent 8404cf0 commit 74df4e2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.tonapps.wallet.data.core.entity

import android.os.Parcelable
import android.util.Log
import com.tonapps.blockchain.ton.extensions.cellFromBase64
import com.tonapps.extensions.optStringCompat
import kotlinx.parcelize.IgnoredOnParcel
Expand Down Expand Up @@ -31,23 +32,36 @@ data class RawMessageEntity(
Coins.ofNano(amount)
}

@IgnoredOnParcel
val stateInit: CellRef<StateInit>? by lazy {
val cell = stateInitValue?.cellFromBase64() ?: return@lazy null
cell.asRef(StateInit)
}

@IgnoredOnParcel
val payload: Cell by lazy {
payloadValue?.cellFromBase64() ?: Cell.empty()
}

constructor(json: JSONObject) : this(
json.getString("address"),
parseAmount(json.get("amount")),
json.optStringCompat("stateInit"),
json.optStringCompat("payload")
)
) {
if (stateInitValue?.startsWith("{") == true) {
throw IllegalArgumentException("Invalid data format. Base64 encoding required for data transfer, JavaScript objects not supported. Received: stateInit = $stateInitValue")
}
if (payloadValue?.startsWith("{") == true) {
throw IllegalArgumentException("Invalid data format. Base64 encoding required for data transfer, JavaScript objects not supported. Received: payload = $payloadValue")
}
}

fun getStateInitRef(): CellRef<StateInit>? {
try {
val cell = stateInitValue?.cellFromBase64() ?: return null
return cell.asRef(StateInit)
} catch (e: Throwable) {
throw IllegalArgumentException("Invalid data format. Received: stateInit = $stateInitValue", e)
}
}

fun getPayload(): Cell {
try {
return payloadValue?.cellFromBase64() ?: Cell.empty()
} catch (e: Throwable) {
throw IllegalArgumentException("Invalid data format. Received: payload = $payloadValue", e)
}
}

private companion object {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ private fun rebuildJettonWithCustomExcessesAccount(
builder: CellBuilder,
excessesAddress: AddrStd
): Cell {

try {
builder
.storeOpCode(TONOpCode.JETTON_TRANSFER)
Expand Down Expand Up @@ -81,7 +82,8 @@ private fun rebuildBodyWithCustomExcessesAccount(
}
}

private fun RawMessageEntity.rebuildJettonTransferWithCustomPayload(
private fun rebuildJettonTransferWithCustomPayload(
payload: Cell,
newCustomPayload: Cell,
): Cell {
val slice = payload.beginParse()
Expand Down Expand Up @@ -119,17 +121,18 @@ fun RawMessageEntity.getWalletTransfer(
newStateInit: CellRef<StateInit>? = null,
newCustomPayload: Cell? = null,
): WalletTransfer {
val payload = getPayload()
val body = if (excessesAddress != null) {
rebuildBodyWithCustomExcessesAccount(payload, excessesAddress)
} else if (newCustomPayload != null) {
rebuildJettonTransferWithCustomPayload(newCustomPayload)
rebuildJettonTransferWithCustomPayload(payload, newCustomPayload)
} else {
payload
}

val builder = WalletTransferBuilder()
builder.destination = address
builder.messageData = MessageData.Raw(body, newStateInit ?: stateInit)
builder.messageData = MessageData.Raw(body, newStateInit ?: getStateInitRef())
// builder.bounceable = address.isBounceable()
if (newCustomPayload != null) {
val defCoins = Coins.of(0.5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class SendTransactionScreen(wallet: WalletEntity) : WalletContextScreen(R.layout
when (state) {
is SendTransactionState.Details -> applyDetails(state)
is SendTransactionState.Failed -> setErrorTask(BridgeException(message = "Failed to send transaction in client"))
is SendTransactionState.FailedEmulation -> finish()
is SendTransactionState.FailedEmulation -> setErrorTask(BridgeException(message = "Transaction emulation failed. Verify 'payload' and 'stateInit' field validity. Invalid message assembly detected or base64 decoding error."))
is SendTransactionState.InsufficientBalance -> {
insufficientFundsDialog.show(state.wallet, state.balance, state.required, state.withRechargeBattery, state.singleWallet)
finish()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import org.json.JSONObject
fun JSONObject.optStringCompat(vararg keys: String): String? {
for (key in keys) {
val value = optString(key)
if (!value.isNullOrBlank()) {
if (!value.isNullOrBlank() && value != "null") {
return value
}
}
Expand Down

0 comments on commit 74df4e2

Please sign in to comment.