diff --git a/src/app/modules/main/wallet_section/send/controller.nim b/src/app/modules/main/wallet_section/send/controller.nim index fa032ca66a..b8d8db9caf 100644 --- a/src/app/modules/main/wallet_section/send/controller.nim +++ b/src/app/modules/main/wallet_section/send/controller.nim @@ -1,5 +1,5 @@ import sugar, sequtils, stint -import uuids, chronicles +import uuids, chronicles, options import io_interface import app_service/service/wallet_account/service as wallet_account_service import app_service/service/network/service as network_service @@ -116,9 +116,10 @@ proc suggestedRoutes*(self: Controller, accountFrom: string, accountTo: string, proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: string, toAssetKey: string, uuid: string, selectedRoutes: seq[TransactionPathDto], password: string, sendType: SendType, - usePassword: bool, doHashing: bool, tokenName: string, isOwnerToken: bool) = + usePassword: bool, doHashing: bool, tokenName: string, isOwnerToken: bool, + slippagePercentage: Option[float]) = self.transactionService.transfer(from_addr, to_addr, assetKey, toAssetKey, uuid, selectedRoutes, password, sendType, - usePassword, doHashing, tokenName, isOwnerToken) + usePassword, doHashing, tokenName, isOwnerToken, slippagePercentage) proc proceedWithTransactionsSignatures*(self: Controller, fromAddr: string, toAddr: string, uuid: string, signatures: TransactionsSignatures, selectedRoutes: seq[TransactionPathDto]) = diff --git a/src/app/modules/main/wallet_section/send/io_interface.nim b/src/app/modules/main/wallet_section/send/io_interface.nim index fbbd7c86f5..a378516654 100644 --- a/src/app/modules/main/wallet_section/send/io_interface.nim +++ b/src/app/modules/main/wallet_section/send/io_interface.nim @@ -1,4 +1,4 @@ -import stint +import stint, options import app/modules/shared_models/currency_amount import app_service/service/transaction/dto import app/modules/shared_models/collectibles_model as collectibles @@ -36,7 +36,8 @@ method authenticateAndTransfer*(self: AccessInterface, from_addr: string, to_add raise newException(ValueError, "No implementation available") method authenticateAndTransferWithPaths*(self: AccessInterface, from_addr: string, to_addr: string, assetKey: string, - toAssetKey: string, uuid: string, sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool, rawPaths: string) {.base.} = + toAssetKey: string, uuid: string, sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool, rawPaths: string, + slippagePercentage: Option[float]) {.base.} = raise newException(ValueError, "No implementation available") method onUserAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} = diff --git a/src/app/modules/main/wallet_section/send/module.nim b/src/app/modules/main/wallet_section/send/module.nim index 1d87595fbd..2500e3dcde 100644 --- a/src/app/modules/main/wallet_section/send/module.nim +++ b/src/app/modules/main/wallet_section/send/module.nim @@ -1,4 +1,4 @@ -import tables, NimQml, sequtils, sugar, stint, strutils, chronicles +import tables, NimQml, sequtils, sugar, stint, strutils, chronicles, options import ./io_interface, ./view, ./controller, ./network_item, ./transaction_routes, ./suggested_route_item, ./suggested_route_model, ./gas_estimate_item, ./gas_fees_item, ./network_model import ../io_interface as delegate_interface @@ -41,6 +41,7 @@ type TmpSendTransactionDetails = object resolvedSignatures: TransactionsSignatures tokenName: string isOwnerToken: bool + slippagePercentage: Option[float] type Module* = ref object of io_interface.AccessInterface @@ -282,8 +283,9 @@ method authenticateAndTransfer*(self: Module, fromAddr: string, toAddr: string, self.controller.authenticate() method authenticateAndTransferWithPaths*(self: Module, fromAddr: string, toAddr: string, assetKey: string, toAssetKey: string, uuid: string, - sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool, rawPaths: string) = + sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool, rawPaths: string, slippagePercentage: Option[float]) = self.tmpSendTransactionDetails.paths = rawPaths.convertToTransactionPathsDto() + self.tmpSendTransactionDetails.slippagePercentage = slippagePercentage self.authenticateAndTransfer(fromAddr, toAddr, assetKey, toAssetKey, uuid, sendType, selectedTokenName, selectedTokenIsOwnerToken) method onUserAuthenticated*(self: Module, password: string, pin: string) = @@ -297,7 +299,7 @@ method onUserAuthenticated*(self: Module, password: string, pin: string) = self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr, self.tmpSendTransactionDetails.assetKey, self.tmpSendTransactionDetails.toAssetKey, self.tmpSendTransactionDetails.uuid, self.tmpSendTransactionDetails.paths, password, self.tmpSendTransactionDetails.sendType, usePassword, doHashing, - self.tmpSendTransactionDetails.tokenName, self.tmpSendTransactionDetails.isOwnerToken + self.tmpSendTransactionDetails.tokenName, self.tmpSendTransactionDetails.isOwnerToken, self.tmpSendTransactionDetails.slippagePercentage ) proc signOnKeycard(self: Module) = @@ -344,6 +346,7 @@ method suggestedRoutes*(self: Module, accountFrom: string, accountTo: string, am method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto) = self.tmpSendTransactionDetails.paths = suggestedRoutes.best + self.tmpSendTransactionDetails.slippagePercentage = none(float) let paths = suggestedRoutes.best.map(x => self.convertTransactionPathDtoToSuggestedRouteItem(x)) let suggestedRouteModel = newSuggestedRouteModel() suggestedRouteModel.setItems(paths) diff --git a/src/app/modules/main/wallet_section/send/view.nim b/src/app/modules/main/wallet_section/send/view.nim index 29a56260a2..f07e380c79 100644 --- a/src/app/modules/main/wallet_section/send/view.nim +++ b/src/app/modules/main/wallet_section/send/view.nim @@ -1,4 +1,4 @@ -import NimQml, sequtils, strutils, stint, sugar +import NimQml, sequtils, strutils, stint, sugar, options import ./io_interface, ./accounts_model, ./account_item, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes import app/modules/shared_models/collectibles_model as collectibles @@ -340,6 +340,14 @@ QtObject: SendType(sendType), lockedInAmounts) proc authenticateAndTransferWithParameters*(self: View, uuid: string, accountFrom: string, accountTo: string, token: string, toToken: string, - sendType: int, tokenName: string, tokenIsOwnerToken: bool, rawPaths: string) {.slot.} = + sendTypeInt: int, tokenName: string, tokenIsOwnerToken: bool, rawPaths: string, slippagePercentageString: string) {.slot.} = + + let sendType = SendType(sendTypeInt) + + var slippagePercentage: Option[float] + if sendType == SendType.Swap: + if slippagePercentageString.len > 0: + slippagePercentage = slippagePercentageString.parseFloat().some + self.delegate.authenticateAndTransferWithPaths(accountFrom, accountTo, token, - toToken, uuid, SendType(sendType), tokenName, tokenIsOwnerToken, rawPaths) \ No newline at end of file + toToken, uuid, sendType, tokenName, tokenIsOwnerToken, rawPaths, slippagePercentage) \ No newline at end of file diff --git a/src/app_service/service/eth/dto/transaction.nim b/src/app_service/service/eth/dto/transaction.nim index 8688cf9040..1328b2db38 100644 --- a/src/app_service/service/eth/dto/transaction.nim +++ b/src/app_service/service/eth/dto/transaction.nim @@ -25,6 +25,8 @@ type tokenID*: Option[UInt256] # (optional) chainID in case of a ERC721 transaction + slippagePercentage*: Option[float] # (optional) max slippage percentage allowed in case of a Swap transaction + proc `%`*(x: TransactionDataDto): JsonNode = result = newJobject() result["from"] = %x.source @@ -59,6 +61,8 @@ proc `%`*(x: TransactionDataDto): JsonNode = result["bonderFee"] = %x.bonderFee.unsafeGet if x.tokenID.isSome: result["tokenID"] = %x.tokenID.unsafeGet + if x.slippagePercentage.isSome: + result["slippagePercentage"] = %x.slippagePercentage.unsafeGet type TransactionBridgeDto* = object bridgeName*: string diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim index eefa9d781d..32c17723ea 100644 --- a/src/app_service/service/transaction/service.nim +++ b/src/app_service/service/transaction/service.nim @@ -343,7 +343,8 @@ QtObject: uuid: string, routes: seq[TransactionPathDto], password: string, - sendType: SendType + sendType: SendType, + slippagePercentage: Option[float] ) = try: var paths: seq[TransactionBridgeDto] = @[] @@ -364,6 +365,7 @@ QtObject: 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 + txData.slippagePercentage = slippagePercentage paths.add(self.createPath(route, txData, tokenSymbol, to_addr)) @@ -402,7 +404,8 @@ QtObject: password: string, sendType: SendType, tokenName: string, - isOwnerToken: bool + isOwnerToken: bool, + slippagePercentage: Option[float] ) = var toContractAddress: Address @@ -473,6 +476,7 @@ QtObject: $route.gasFees.maxFeePerGasM ) txData.data = data + txData.slippagePercentage = slippagePercentage let path = self.createPath(route, txData, mtCommand.toAsset, mtCommand.toAddress) paths.add(path) @@ -500,7 +504,8 @@ QtObject: usePassword: bool, doHashing: bool, tokenName: string, - isOwnerToken: bool + isOwnerToken: bool, + slippagePercentage: Option[float] ) = var finalPassword = "" if usePassword: @@ -532,11 +537,11 @@ QtObject: let network = self.networkService.getNetworkByChainId(chainID) if not network.isNil and network.nativeCurrencySymbol == asset.symbol: - self.transferEth(fromAddr, toAddr, asset.symbol, toAsset.symbol, uuid, selectedRoutes, finalPassword, sendType) + self.transferEth(fromAddr, toAddr, asset.symbol, toAsset.symbol, uuid, selectedRoutes, finalPassword, sendType, slippagePercentage) return self.transferToken(fromAddr, toAddr, assetKey, asset, toAssetKey, toAsset, uuid, selectedRoutes, finalPassword, - sendType, tokenName, isOwnerToken) + 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}")) diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml index 07d6e17df9..f440c33aab 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml @@ -288,7 +288,7 @@ QObject { root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress, root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey, - Constants.SendType.Approve, "", false, root.swapOutputData.rawPaths) + Constants.SendType.Approve, "", false, root.swapOutputData.rawPaths, "") } function sendSwapTx() { @@ -297,6 +297,6 @@ QObject { root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress, root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey, - Constants.SendType.Swap, "", false, root.swapOutputData.rawPaths) + Constants.SendType.Swap, "", false, root.swapOutputData.rawPaths, root.swapFormData.selectedSlippage) } } diff --git a/ui/app/AppLayouts/Wallet/stores/SwapStore.qml b/ui/app/AppLayouts/Wallet/stores/SwapStore.qml index f1c3176bb8..bca1234a0a 100644 --- a/ui/app/AppLayouts/Wallet/stores/SwapStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/SwapStore.qml @@ -33,9 +33,9 @@ QtObject { } function authenticateAndTransfer(uuid, accountFrom, accountTo, - tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths) { + tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths, slippagePercentage) { root.walletSectionSendInst.authenticateAndTransferWithParameters(uuid, accountFrom, accountTo, - tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths) + tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths, slippagePercentage) } function getWei2Eth(wei, decimals) {