From c89203f371dcfe9f50f16598dae9df6f105d47fd Mon Sep 17 00:00:00 2001 From: Khushboo Mehta Date: Wed, 10 Jul 2024 20:33:51 +0200 Subject: [PATCH] feat(@desktop/wallet): Implementation of Notifications fixes #14834 --- src/app/modules/main/module.nim | 9 +- src/app/modules/main/view.nim | 5 +- .../main/wallet_section/send/controller.nim | 7 +- .../main/wallet_section/send/module.nim | 3 +- .../service/transaction/async_tasks.nim | 18 +++ .../service/transaction/service.nim | 89 ++++++++++--- ui/app/mainui/AppMain.qml | 122 ++++++++++++++++-- 7 files changed, 224 insertions(+), 29 deletions(-) diff --git a/src/app/modules/main/module.nim b/src/app/modules/main/module.nim index 88b5965459..a601de16e9 100644 --- a/src/app/modules/main/module.nim +++ b/src/app/modules/main/module.nim @@ -462,13 +462,20 @@ proc connectForNotificationsOnly[T](self: Module[T]) = self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args): let args = TransactionSentArgs(e) - self.view.showToastTransactionSent(args.chainId, args.txHash, args.uuid, args.error) + self.view.showToastTransactionSent(args.chainId, args.txHash, args.uuid, args.error, + ord(args.txType), args.fromAddress, args.toAddress, args.fromTokenKey, args.fromAmount, + args.fromTokenKey, args.toAmount) self.events.on(MARK_WALLET_ADDRESSES_AS_SHOWN) do(e:Args): let args = WalletAddressesArgs(e) for address in args.addresses: self.addressWasShown(address) + self.events.on(SIGNAL_TRANSACTION_SENDING_COMPLETE) do(e:Args): + let args = TransactionMinedArgs(e) + self.view.showToastTransactionSendingComplete(args.chainId, args.transactionHash, args.data, args.success, + ord(args.txType), args.fromAddress, args.toAddress, args.fromTokenKey, args.fromAmount, args.toTokenKey, args.toAmount) + method load*[T]( self: Module[T], events: EventEmitter, diff --git a/src/app/modules/main/view.nim b/src/app/modules/main/view.nim index 959655b9a8..35ad818e7b 100644 --- a/src/app/modules/main/view.nim +++ b/src/app/modules/main/view.nim @@ -341,7 +341,10 @@ QtObject: proc showNetworkEndpointUpdated*(self: View, name: string, isTest: bool, revertedToDefault: bool) {.signal.} proc showToastKeypairRemoved*(self: View, keypairName: string) {.signal.} proc showToastKeypairsImported*(self: View, keypairName: string, keypairsCount: int, error: string) {.signal.} - proc showToastTransactionSent*(self: View, chainId: int, txHash: string, uuid: string, error: string) {.signal.} + proc showToastTransactionSent*(self: View, chainId: int, txHash: string, uuid: string, error: string, + txType: int, fromAddr: string, toAddr: string, fromTokenKey: string, fromAmount: string, toTokenKey: string, toAmount: string) {.signal.} + proc showToastTransactionSendingComplete*(self: View, chainId: int, txHash: string, data: string, success: bool, + txType: int, fromAddr: string, toAddr: string, fromTokenKey: string, fromAmount: string, toTokenKey: string, toAmount: string) {.signal.} ## Used in test env only, for testing keycard flows proc registerMockedKeycard*(self: View, cardIndex: int, readerState: int, keycardState: int, diff --git a/src/app/modules/main/wallet_section/send/controller.nim b/src/app/modules/main/wallet_section/send/controller.nim index f7714f1358..5051ad940a 100644 --- a/src/app/modules/main/wallet_section/send/controller.nim +++ b/src/app/modules/main/wallet_section/send/controller.nim @@ -132,9 +132,10 @@ proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: s self.transactionService.transfer(from_addr, to_addr, assetKey, toAssetKey, uuid, selectedRoutes, password, sendType, usePassword, doHashing, tokenName, isOwnerToken, slippagePercentage) -proc proceedWithTransactionsSignatures*(self: Controller, fromAddr: string, toAddr: string, uuid: string, - signatures: TransactionsSignatures, selectedRoutes: seq[TransactionPathDto]) = - self.transactionService.proceedWithTransactionsSignatures(fromAddr, toAddr, uuid, signatures, selectedRoutes) +proc proceedWithTransactionsSignatures*(self: Controller, fromAddr: string, toAddr: string, + fromTokenKey: string, toTokenKey: string, uuid: string, signatures: TransactionsSignatures, + selectedRoutes: seq[TransactionPathDto], sendType: SendType) = + self.transactionService.proceedWithTransactionsSignatures(fromAddr, toAddr, fromTokenKey, toTokenKey, uuid, signatures, selectedRoutes, sendType) proc areTestNetworksEnabled*(self: Controller): bool = return self.walletAccountService.areTestNetworksEnabled() diff --git a/src/app/modules/main/wallet_section/send/module.nim b/src/app/modules/main/wallet_section/send/module.nim index 1d73483100..cfe5019bd3 100644 --- a/src/app/modules/main/wallet_section/send/module.nim +++ b/src/app/modules/main/wallet_section/send/module.nim @@ -252,7 +252,8 @@ proc signOnKeycard(self: Module) = break if self.tmpTxHashBeingProcessed.len == 0: self.controller.proceedWithTransactionsSignatures(self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr, - self.tmpSendTransactionDetails.uuid, self.tmpSendTransactionDetails.resolvedSignatures, self.tmpSendTransactionDetails.paths) + self.tmpSendTransactionDetails.assetKey, self.tmpSendTransactionDetails.toAssetKey, self.tmpSendTransactionDetails.uuid, + self.tmpSendTransactionDetails.resolvedSignatures, self.tmpSendTransactionDetails.paths, self.tmpSendTransactionDetails.sendType) method prepareSignaturesForTransactions*(self: Module, txHashes: seq[string]) = if txHashes.len == 0: diff --git a/src/app_service/service/transaction/async_tasks.nim b/src/app_service/service/transaction/async_tasks.nim index e910fd8967..3c6338a007 100644 --- a/src/app_service/service/transaction/async_tasks.nim +++ b/src/app_service/service/transaction/async_tasks.nim @@ -26,6 +26,12 @@ type chainId: int address: string trxType: string + txType: int + toAddress: string + fromTokenKey: string + fromAmount: string + toTokenKey: string + toAmount: string proc watchTransactionTask*(argEncoded: string) {.gcsafe, nimcall.} = let arg = decode[WatchTransactionTaskArg](argEncoded) @@ -36,6 +42,12 @@ proc watchTransactionTask*(argEncoded: string) {.gcsafe, nimcall.} = "address": arg.address, "chainId": arg.chainId, "trxType": arg.trxType, + "txType": arg.txType, + "toAddress": arg.toAddress, + "fromTokenKey": arg.fromTokenKey, + "fromAmount": arg.fromAmount, + "toTokenKey": arg.toTokenKey, + "toAmount": arg.toAmount, "isSuccessfull": transactions.watchTransaction(arg.chainId, arg.hash).error.isNil, } arg.finish(output) @@ -46,6 +58,12 @@ proc watchTransactionTask*(argEncoded: string) {.gcsafe, nimcall.} = "address": arg.address, "chainId": arg.chainId, "trxType": arg.trxType, + "txType": arg.txType, + "toAddress": arg.toAddress, + "fromTokenKey": arg.fromTokenKey, + "fromAmount": arg.fromAmount, + "toTokenKey": arg.toTokenKey, + "toAmount": arg.toAmount, "isSuccessfull": false } diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim index 936417d680..ade58d94c4 100644 --- a/src/app_service/service/transaction/service.nim +++ b/src/app_service/service/transaction/service.nim @@ -82,6 +82,13 @@ type transactionHash*: string chainId*: int success*: bool + txType*: SendType + fromAddress*: string + toAddress*: string + fromTokenKey*: string + fromAmount*: string + toTokenKey*: string + toAmount*: string proc `$`*(self: TransactionMinedArgs): string = try: @@ -90,6 +97,13 @@ proc `$`*(self: TransactionMinedArgs): string = chainId: {$self.chainId}, success: {$self.success}, data: {self.data}, + txType: {$self.txType}, + fromAddress: {$self.fromAddress}, + toAddress: {$self.toAddress}, + fromTokenKey: {$self.fromTokenKey}, + fromAmount: {$self.fromAmount}, + toTokenKey: {$self.toTokenKey}, + toAmount: {$self.toAmount}, )""" except ValueError: raiseAssert "static fmt" @@ -100,6 +114,13 @@ type txHash*: string uuid*: string error*: string + txType*: SendType + fromAddress*: string + toAddress*: string + fromTokenKey*: string + fromAmount*: string + toTokenKey*: string + toAmount*: string type OwnerTokenSentArgs* = ref object of Args @@ -207,18 +228,31 @@ QtObject: transactionHash: hash, chainId: chainId, success: transactionReceipt{"status"}.getStr == "0x1", + txType: SendType(watchTxResult["txType"].getInt), + fromAddress: address, + toAddress: watchTxResult["toAddress"].getStr, + fromTokenKey: watchTxResult["fromTokenKey"].getStr, + fromAmount: watchTxResult["fromAmount"].getStr, + toTokenKey: watchTxResult["toTokenKey"].getStr, + toAmount: watchTxResult["toAmount"].getStr, ) self.events.emit(parseEnum[PendingTransactionTypeDto](watchTxResult["trxType"].getStr).event, ev) transactions.checkRecentHistory(@[chainId], @[address]) proc watchTransaction*( - self: Service, hash: string, fromAddress: string, toAddress: string, trxType: string, data: string, chainId: int, track: bool = true + self: Service, hash: string, fromAddress: string, toAddress: string, trxType: string, data: string, chainId: int, + fromTokenKey: string = "", fromAmount: string = "", toTokenKey: string = "", toAmount: string = "", txType: SendType = SendType.Transfer ) = let arg = WatchTransactionTaskArg( chainId: chainId, hash: hash, address: fromAddress, trxType: trxType, + txType: ord(txType), + fromTokenKey: fromTokenKey, + fromAmount: fromAmount, + toTokenKey: toTokenKey, + toAmount: toAmount, data: data, tptr: watchTransactionTask, vptr: cast[ByteAddress](self.vptr), @@ -317,7 +351,8 @@ QtObject: path.cbridgeTx = cbridgeTx return path - proc sendTransactionSentSignal(self: Service, fromAddr: string, toAddr: string, uuid: string, + proc sendTransactionSentSignal(self: Service, txType: SendType, fromAddr: string, toAddr: string, + fromTokenKey: string, fromAmount: string, toTokenKey: string, toAmount: string, uuid: string, routes: seq[TransactionPathDto], response: RpcResponse[JsonNode], err: string = "", tokenName = "", isOwnerToken=false) = # While preparing the tx in the Send modal user cannot see the address, it's revealed once the tx is sent # (there are few places where we display the toast from and link to the etherscan where the address can be seen) @@ -325,17 +360,22 @@ QtObject: self.events.emit(MARK_WALLET_ADDRESSES_AS_SHOWN, WalletAddressesArgs(addresses: @[fromAddr, toAddr])) if err.len > 0: - self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(uuid: uuid, error: err)) + self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(uuid: uuid, error: err, txType: txType, + fromAddress: fromAddr, toAddress: toAddr, fromTokenKey: fromTokenKey, fromAmount: fromAmount, + toTokenKey: toTokenKey, toAmount: toAmount)) elif response.result{"hashes"} != nil: for route in routes: for hash in response.result["hashes"][$route.fromNetwork.chainID]: if isOwnerToken: - self.events.emit(SIGNAL_OWNER_TOKEN_SENT, OwnerTokenSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr, uuid: uuid, tokenName: tokenName, status: ContractTransactionStatus.InProgress)) + self.events.emit(SIGNAL_OWNER_TOKEN_SENT, OwnerTokenSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr, + uuid: uuid, tokenName: tokenName, status: ContractTransactionStatus.InProgress)) else: - self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr, uuid: uuid , error: "")) + self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr, uuid: uuid , + error: "", txType: txType, fromAddress: fromAddr, toAddress: toAddr, fromTokenKey: fromTokenKey, fromAmount: fromAmount, toTokenKey: toTokenKey, toAmount: toAmount)) let metadata = TokenTransferMetadata(tokenName: tokenName, isOwnerToken: isOwnerToken) - self.watchTransaction(hash.getStr, fromAddr, toAddr, $PendingTransactionTypeDto.WalletTransfer, $(%metadata), route.fromNetwork.chainID, track = false) + self.watchTransaction(hash.getStr, fromAddr, toAddr, $PendingTransactionTypeDto.WalletTransfer, $(%metadata), route.fromNetwork.chainID, + fromTokenKey, fromAmount, toTokenKey, toAmount, txType) proc isCollectiblesTransfer(self: Service, sendType: SendType): bool = return sendType == ERC721Transfer or sendType == ERC1155Transfer @@ -364,6 +404,7 @@ QtObject: try: var paths: seq[TransactionBridgeDto] = @[] var totalAmountToSend: UInt256 + var totalAmountToReceive: UInt256 let toAddress = parseAddress(to_addr) for route in routes: @@ -377,6 +418,7 @@ QtObject: paths.add(self.createApprovalPath(route, from_addr, toAddress, gasFees)) totalAmountToSend += route.amountIn + totalAmountToReceive += route.amountOut txData = ens_utils.buildTransaction(parseAddress(from_addr), route.amountIn, $route.gasAmount, gasFees, route.gasFees.eip1559Enabled, $route.gasFees.maxPriorityFeePerGas, $route.gasFees.maxFeePerGasM) txData.to = parseAddress(to_addr).some @@ -400,9 +442,11 @@ QtObject: ) if password != "": - self.sendTransactionSentSignal(from_addr, to_addr, uuid, routes, response) + self.sendTransactionSentSignal(sendType, from_addr, to_addr, tokenSymbol, totalAmountToSend.toString(10), + toTokenSymbol, totalAmountToReceive.toString(10), uuid, routes, response) except Exception as e: - self.sendTransactionSentSignal(from_addr, to_addr, uuid, @[], RpcResponse[JsonNode](), fmt"Error sending token transfer transaction: {e.msg}") + self.sendTransactionSentSignal(sendType, from_addr, to_addr, tokenSymbol, "", + toTokenSymbol, "", uuid, @[], RpcResponse[JsonNode](), fmt"Error sending token transfer transaction: {e.msg}") proc mustIgnoreApprovalRequests(sendType: SendType): bool = # Swap requires approvals to be done in advance in a separate Tx @@ -430,6 +474,7 @@ QtObject: toContractAddress: Address paths: seq[TransactionBridgeDto] = @[] totalAmountToSend: UInt256 + totalAmountToReceive: UInt256 mtCommand = MultiTransactionCommandDto( fromAddress: from_addr, toAddress: to_addr, @@ -474,6 +519,7 @@ QtObject: paths.add(approvalPath) totalAmountToSend += route.amountIn + totalAmountToReceive += route.amountOut if sendType == SendType.Approve: # We only do the approvals @@ -505,10 +551,14 @@ QtObject: let response = transactions.createMultiTransaction(mtCommand, paths, password) if password != "": - self.sendTransactionSentSignal(mtCommand.fromAddress, mtCommand.toAddress, uuid, routes, response, err="", tokenName, isOwnerToken) + self.sendTransactionSentSignal(sendType, mtCommand.fromAddress, mtCommand.toAddress, + assetKey, totalAmountToSend.toString(10), toAssetKey, totalAmountToReceive.toString(10), + uuid, routes, response, err="", tokenName, isOwnerToken) except Exception as e: - self.sendTransactionSentSignal(mtCommand.fromAddress, mtCommand.toAddress, uuid, @[], RpcResponse[JsonNode](), fmt"Error sending token transfer transaction: {e.msg}") + self.sendTransactionSentSignal(sendType, mtCommand.fromAddress, mtCommand.toAddress, + assetKey, "", toAssetKey, "", + uuid, @[], RpcResponse[JsonNode](), fmt"Error sending token transfer transaction: {e.msg}") proc transfer*( self: Service, @@ -563,15 +613,24 @@ QtObject: sendType, tokenName, isOwnerToken, slippagePercentage) except Exception as e: - self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(chainId: 0, txHash: "", uuid: uuid, error: fmt"Error sending token transfer transaction: {e.msg}")) + self.sendTransactionSentSignal(sendType, fromAddr, toAddr, assetKey, "", toAssetKey, "", uuid, @[], RpcResponse[JsonNode](), fmt"Error sending token transfer transaction: {e.msg}") - proc proceedWithTransactionsSignatures*(self: Service, fromAddr: string, toAddr: string, uuid: string, - signatures: TransactionsSignatures, selectedRoutes: seq[TransactionPathDto]) = + proc proceedWithTransactionsSignatures*(self: Service, fromAddr: string, toAddr: string, + fromTokenKey: string, toTokenKey: string, uuid: string, signatures: TransactionsSignatures, + selectedRoutes: seq[TransactionPathDto], sendType: SendType) = try: let response = transactions.proceedWithTransactionsSignatures(signatures) - self.sendTransactionSentSignal(fromAddr, toAddr, uuid, selectedRoutes, response) + + var totalAmountToSend: UInt256 + var totalAmountToReceive: UInt256 + for route in selectedRoutes: + totalAmountToSend += route.amountIn + totalAmountToReceive += route.amountOut + + self.sendTransactionSentSignal(sendType, fromAddr, toAddr, fromTokenKey, totalAmountToSend.toString(10), toTokenKey, totalAmountToReceive.toString(10), uuid, selectedRoutes, response) except Exception as e: - self.sendTransactionSentSignal(fromAddr, toAddr, uuid, @[], RpcResponse[JsonNode](), fmt"Error proceeding with transactions signatures: {e.msg}") + self.sendTransactionSentSignal(sendType, fromAddr, toAddr, fromTokenKey, "", toTokenKey, "", + uuid, @[], RpcResponse[JsonNode](), fmt"Error proceeding with transactions signatures: {e.msg}") proc suggestedFees*(self: Service, chainId: int): SuggestedFeesDto = try: diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index b7dc8e689a..dc4d1791b0 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -218,14 +218,120 @@ Item { ) } - function onShowToastTransactionSent(chainId: int, txHash: string, uuid: string, error: string) { - if (!error) { - Global.displayToastMessage(qsTr("Transaction pending..."), - qsTr("View on etherscan"), - "", - true, - Constants.ephemeralNotificationType.normal, - "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash)) + function onShowToastTransactionSent(chainId: int, txHash: string, uuid: string, error: string, txType: int, + fromAddr: string, toAddr: string, fromTokenKey: string, fromAmount: string, + toTokenKey: string, toAmount: string) { + switch(txType) { + case Constants.SendType.Approve: { + const fromToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", fromTokenKey) + const fromAccountName = SQUtils.ModelUtils.getByKey(appMain.transactionStore.accounts, "address", fromAddr, "name") + const networkName = SQUtils.ModelUtils.getByKey(WalletStore.RootStore.filteredFlatModel, "chainId", chainId, "chainName") + if(!!fromToken && !!fromAccountName && !!networkName) { + const approvalAmount = currencyStore.formatCurrencyAmountFromBigInt(fromAmount, fromToken.symbol, fromToken.decimals) + let toastTitle = qsTr("Setting spending cap: %1 in %2 for %3 on %4").arg(approvalAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + let toastSubtitle = qsTr("View on %1").arg(networkName) + let urlLink = "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash) + let toastType = Constants.ephemeralNotificationType.normal + let icon = "" + if(error) { + toastTitle = qsTr("Failed to set spending cap: %1 in %2 for %3 on %4").arg(approvalAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + toastSubtitle = "" + urlLink = "" + toastType = Constants.ephemeralNotificationType.danger + icon = "warning" + } + Global.displayToastMessage(toastTitle, toastSubtitle, icon, !error, toastType, urlLink) + } + break + } + case Constants.SendType.Swap: { + const fromToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", fromTokenKey) + const toToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", toTokenKey) + const fromAccountName = SQUtils.ModelUtils.getByKey(appMain.transactionStore.accounts, "address", fromAddr, "name") + const networkName = SQUtils.ModelUtils.getByKey(WalletStore.RootStore.filteredFlatModel, "chainId", chainId, "chainName") + if(!!fromToken && !!toToken && !!fromAccountName && !!networkName) { + const fromSwapAmount = currencyStore.formatCurrencyAmountFromBigInt(fromAmount, fromToken.symbol, fromToken.decimals) + const toSwapAmount = currencyStore.formatCurrencyAmountFromBigInt(toAmount, toToken.symbol, toToken.decimals) + let toastTitle = qsTr("Swapping %1 to %2 in %3 using %4 on %5").arg(fromSwapAmount).arg(toSwapAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + let toastSubtitle = qsTr("View on %1").arg(networkName) + let urlLink = "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash) + let toastType = Constants.ephemeralNotificationType.normal + let icon = "" + if(error) { + toastTitle = qsTr("Failed to swap %1 to %2 in %3 using %4 on %5").arg(fromSwapAmount).arg(toSwapAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + toastSubtitle = "" + urlLink = "" + toastType = Constants.ephemeralNotificationType.danger + icon = "warning" + } + Global.displayToastMessage(toastTitle, toastSubtitle, icon, !error, toastType, urlLink) + } + break + } + default: { + if (!error) { + let networkName = SQUtils.ModelUtils.getByKey(WalletStore.RootStore.filteredFlatModel, "chainId", chainId, "chainName") + if(!!networkName) { + Global.displayToastMessage(qsTr("Transaction pending..."), + qsTr("View on %1").arg(networkName), + "", + true, + Constants.ephemeralNotificationType.normal, + "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash)) + } + } + break + } + } + } + + function onShowToastTransactionSendingComplete(chainId: int, txHash: string, data: string, success: bool, + txType: int, fromAddr: string, toAddr: string, fromTokenKey: string, + fromAmount: string, toTokenKey: string, toAmount: string) { + switch(txType) { + case Constants.SendType.Approve: { + const fromToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", fromTokenKey) + const fromAccountName = SQUtils.ModelUtils.getByKey(appMain.transactionStore.accounts, "address", fromAddr, "name") + const networkName = SQUtils.ModelUtils.getByKey(WalletStore.RootStore.filteredFlatModel, "chainId", chainId, "chainName") + if(!!fromToken && !!fromAccountName && !!networkName) { + const approvalAmount = currencyStore.formatCurrencyAmountFromBigInt(fromAmount, fromToken.symbol, fromToken.decimals) + let toastTitle = qsTr("Spending cap set: %1 in %2 for %3 on %4").arg(approvalAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + const toastSubtitle = qsTr("View on %1").arg(networkName) + const urlLink = "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash) + let toastType = Constants.ephemeralNotificationType.success + let icon = "checkmark-circle" + if(!success) { + toastTitle = qsTr("Failed to set spending cap: %1 in %2 for %3 on %4").arg(approvalAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + toastType = Constants.ephemeralNotificationType.danger + icon = "warning" + } + Global.displayToastMessage(toastTitle, toastSubtitle, icon, false, toastType, urlLink) + } + break + } + case Constants.SendType.Swap: { + const fromToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", fromTokenKey) + const toToken = SQUtils.ModelUtils.getByKey(appMain.tokensStore.plainTokensBySymbolModel, "key", toTokenKey) + const fromAccountName = SQUtils.ModelUtils.getByKey(appMain.transactionStore.accounts, "address", fromAddr, "name") + const networkName = SQUtils.ModelUtils.getByKey(WalletStore.RootStore.filteredFlatModel, "chainId", chainId, "chainName") + if(!!fromToken && !!toToken && !!fromAccountName && !!networkName) { + const fromSwapAmount = currencyStore.formatCurrencyAmountFromBigInt(fromAmount, fromToken.symbol, fromToken.decimals) + const toSwapAmount = currencyStore.formatCurrencyAmountFromBigInt(toAmount, toToken.symbol, toToken.decimals) + let toastTitle = qsTr("Swapped %1 to %2 in %3 using %4 on %5").arg(fromSwapAmount).arg(toSwapAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + const toastSubtitle = qsTr("View on %1").arg(networkName) + const urlLink = "%1/%2".arg(appMain.rootStore.getEtherscanLink(chainId)).arg(txHash) + let toastType = Constants.ephemeralNotificationType.success + let icon = "checkmark-circle" + if(!success) { + toastTitle = qsTr("Failed to swap %1 to %2 in %3 using %4 on %5").arg(fromSwapAmount).arg(toSwapAmount).arg(fromAccountName).arg(Constants.swap.paraswapUrl).arg(networkName) + toastType = Constants.ephemeralNotificationType.danger + icon = "warning" + } + Global.displayToastMessage(toastTitle, toastSubtitle, icon, false, toastType, urlLink) + } + break + } + default: break } }