diff --git a/apps/wallet/data/core/src/main/java/com/tonapps/wallet/data/core/entity/RawMessageEntity.kt b/apps/wallet/data/core/src/main/java/com/tonapps/wallet/data/core/entity/RawMessageEntity.kt index 31908652..9461c7c7 100644 --- a/apps/wallet/data/core/src/main/java/com/tonapps/wallet/data/core/entity/RawMessageEntity.kt +++ b/apps/wallet/data/core/src/main/java/com/tonapps/wallet/data/core/entity/RawMessageEntity.kt @@ -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 @@ -31,23 +32,36 @@ data class RawMessageEntity( Coins.ofNano(amount) } - @IgnoredOnParcel - val stateInit: CellRef? 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? { + 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 { diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/RawMessageEntity.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/RawMessageEntity.kt index 55d889e2..055b6e03 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/RawMessageEntity.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/RawMessageEntity.kt @@ -29,6 +29,7 @@ private fun rebuildJettonWithCustomExcessesAccount( builder: CellBuilder, excessesAddress: AddrStd ): Cell { + try { builder .storeOpCode(TONOpCode.JETTON_TRANSFER) @@ -81,7 +82,8 @@ private fun rebuildBodyWithCustomExcessesAccount( } } -private fun RawMessageEntity.rebuildJettonTransferWithCustomPayload( +private fun rebuildJettonTransferWithCustomPayload( + payload: Cell, newCustomPayload: Cell, ): Cell { val slice = payload.beginParse() @@ -119,17 +121,18 @@ fun RawMessageEntity.getWalletTransfer( newStateInit: CellRef? = 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) diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/transaction/SendTransactionScreen.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/transaction/SendTransactionScreen.kt index ce520402..951e51dd 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/transaction/SendTransactionScreen.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/transaction/SendTransactionScreen.kt @@ -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() diff --git a/lib/extensions/src/main/java/com/tonapps/extensions/JSONObject.kt b/lib/extensions/src/main/java/com/tonapps/extensions/JSONObject.kt index 8237ad8e..ee9159ba 100644 --- a/lib/extensions/src/main/java/com/tonapps/extensions/JSONObject.kt +++ b/lib/extensions/src/main/java/com/tonapps/extensions/JSONObject.kt @@ -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 } }