diff --git a/src/app/modules/main/wallet_section/send/controller.nim b/src/app/modules/main/wallet_section/send/controller.nim index e7ebf4f5cf..fa032ca66a 100644 --- a/src/app/modules/main/wallet_section/send/controller.nim +++ b/src/app/modules/main/wallet_section/send/controller.nim @@ -1,4 +1,4 @@ -import sugar, sequtils, stint, json, json_serialization +import sugar, sequtils, stint import uuids, chronicles import io_interface import app_service/service/wallet_account/service as wallet_account_service @@ -110,10 +110,9 @@ proc authenticate*(self: Controller, keyUid = "") = self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data) proc suggestedRoutes*(self: Controller, accountFrom: string, accountTo: string, amount: Uint256, token: string, toToken: string, - disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string): string = - let suggestedRoutes = self.transactionService.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs, + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) = + self.transactionService.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) - return suggestedRoutes.toJson() proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: string, toAssetKey: string, uuid: string, selectedRoutes: seq[TransactionPathDto], password: string, sendType: SendType, 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 5190a4097b..fbbd7c86f5 100644 --- a/src/app/modules/main/wallet_section/send/io_interface.nim +++ b/src/app/modules/main/wallet_section/send/io_interface.nim @@ -25,7 +25,7 @@ method getTokenBalance*(self: AccessInterface, address: string, chainId: int, to raise newException(ValueError, "No implementation available") method suggestedRoutes*(self: AccessInterface, accountFrom: string, accountTo: string, amount: UInt256, token: string, toToken: string, - disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string): string {.base.} = + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) {.base.} = raise newException(ValueError, "No implementation available") method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: SuggestedRoutesDto) {.base.} = @@ -35,6 +35,10 @@ method authenticateAndTransfer*(self: AccessInterface, from_addr: string, to_add toAssetKey: string, uuid: string, sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool) {.base.} = 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.} = + raise newException(ValueError, "No implementation available") + method onUserAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/wallet_section/send/module.nim b/src/app/modules/main/wallet_section/send/module.nim index 5baa5dc498..1d87595fbd 100644 --- a/src/app/modules/main/wallet_section/send/module.nim +++ b/src/app/modules/main/wallet_section/send/module.nim @@ -281,6 +281,11 @@ method authenticateAndTransfer*(self: Module, fromAddr: string, toAddr: string, else: 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) = + self.tmpSendTransactionDetails.paths = rawPaths.convertToTransactionPathsDto() + self.authenticateAndTransfer(fromAddr, toAddr, assetKey, toAssetKey, uuid, sendType, selectedTokenName, selectedTokenIsOwnerToken) + method onUserAuthenticated*(self: Module, password: string, pin: string) = if password.len == 0: self.transactionWasSent(chainId = 0, txHash = "", uuid = self.tmpSendTransactionDetails.uuid, error = authenticationCanceled) @@ -333,8 +338,8 @@ method transactionWasSent*(self: Module, chainId: int, txHash, uuid, error: stri self.view.sendTransactionSentSignal(chainId, txHash, uuid, error) method suggestedRoutes*(self: Module, accountFrom: string, accountTo: string, amount: UInt256, token: string, toToken: string, - disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string): string = - return self.controller.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs, + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) = + self.controller.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto) = @@ -351,7 +356,8 @@ method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto) suggestedRoutes = suggestedRouteModel, gasTimeEstimate = gasTimeEstimate, amountToReceive = suggestedRoutes.amountToReceive, - toNetworksModel = toNetworksModel) + toNetworksModel = toNetworksModel, + rawPaths = suggestedRoutes.rawBest) self.view.setTransactionRoute(transactionRoutes) method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) = diff --git a/src/app/modules/main/wallet_section/send/transaction_routes.nim b/src/app/modules/main/wallet_section/send/transaction_routes.nim index e3a2516b23..a50ed5d7bb 100644 --- a/src/app/modules/main/wallet_section/send/transaction_routes.nim +++ b/src/app/modules/main/wallet_section/send/transaction_routes.nim @@ -8,18 +8,21 @@ QtObject: gasTimeEstimate: GasEstimateItem amountToReceive: UInt256 toNetworksModel: NetworkModel + rawPaths: string proc setup*(self: TransactionRoutes, suggestedRoutes: SuggestedRouteModel, gasTimeEstimate: GasEstimateItem, amountToReceive: UInt256, - toNetworksModel: NetworkModel + toNetworksModel: NetworkModel, + rawPaths: string ) = self.QObject.setup self.suggestedRoutes = suggestedRoutes self.gasTimeEstimate = gasTimeEstimate self.amountToReceive = amountToReceive self.toNetworksModel = toNetworksModel + self.rawPaths = rawPaths proc delete*(self: TransactionRoutes) = self.QObject.delete @@ -28,10 +31,11 @@ QtObject: suggestedRoutes: SuggestedRouteModel = newSuggestedRouteModel(), gasTimeEstimate: GasEstimateItem = newGasEstimateItem(), amountToReceive: UInt256 = stint.u256(0), - toNetworksModel: NetworkModel = newNetworkModel() + toNetworksModel: NetworkModel = newNetworkModel(), + rawPaths: string = "" ): TransactionRoutes = new(result, delete) - result.setup(suggestedRoutes, gasTimeEstimate, amountToReceive, toNetworksModel) + result.setup(suggestedRoutes, gasTimeEstimate, amountToReceive, toNetworksModel, rawPaths) proc `$`*(self: TransactionRoutes): string = result = fmt"""TransactionRoutes( @@ -39,6 +43,7 @@ QtObject: gasTimeEstimate: {self.gasTimeEstimate}, amountToReceive: {self.amountToReceive}, toNetworksModel: {self.toNetworksModel}, + rawPaths: {self.rawPaths}, ]""" proc suggestedRoutesChanged*(self: TransactionRoutes) {.signal.} @@ -68,3 +73,10 @@ QtObject: QtProperty[QVariant] toNetworksModel: read = getToNetworks notify = toNetworksChanged + + proc rawPathsChanged*(self: TransactionRoutes) {.signal.} + proc getRawPaths*(self: TransactionRoutes): string {.slot.} = + return self.rawPaths + QtProperty[string] rawPaths: + read = getRawPaths + notify = rawPathsChanged diff --git a/src/app/modules/main/wallet_section/send/view.nim b/src/app/modules/main/wallet_section/send/view.nim index 3104ce4a35..29a56260a2 100644 --- a/src/app/modules/main/wallet_section/send/view.nim +++ b/src/app/modules/main/wallet_section/send/view.nim @@ -218,6 +218,20 @@ QtObject: proc sendTransactionSentSignal*(self: View, chainId: int, txHash: string, uuid: string, error: string) = self.transactionSent(chainId, txHash, uuid, error) + proc parseAmount(amount: string): Uint256 = + var parsedAmount = stint.u256(0) + try: + parsedAmount = amount.parse(Uint256) + except Exception as e: + discard + return parsedAmount + + proc parseChainIds(chainIds: string): seq[int] = + var parsedChainIds: seq[int] = @[] + for chainId in chainIds.split(':'): + parsedChainIds.add(chainId.parseInt()) + return parsedChainIds + proc authenticateAndTransfer*(self: View, uuid: string) {.slot.} = self.delegate.authenticateAndTransfer(self.selectedSenderAccount.address(), self.selectedRecipient, self.selectedAssetKey, self.selectedToAssetKey, uuid, self.sendType, self.selectedTokenName, self.selectedTokenIsOwnerToken) @@ -227,15 +241,9 @@ QtObject: self.transactionRoutes = routes self.suggestedRoutesReady(newQVariant(self.transactionRoutes)) - proc suggestedRoutes*(self: View, amount: string): string {.slot.} = - var parsedAmount = stint.u256(0) - try: - parsedAmount = amount.parse(Uint256) - except Exception as e: - discard - - return self.delegate.suggestedRoutes(self.selectedSenderAccount.address(), self.selectedRecipient, - parsedAmount, self.selectedAssetKey, self.selectedToAssetKey, self.fromNetworksModel.getRouteDisabledNetworkChainIds(), + proc suggestedRoutes*(self: View, amount: string) {.slot.} = + self.delegate.suggestedRoutes(self.selectedSenderAccount.address(), self.selectedRecipient, + parseAmount(amount), self.selectedAssetKey, self.selectedToAssetKey, self.fromNetworksModel.getRouteDisabledNetworkChainIds(), self.toNetworksModel.getRouteDisabledNetworkChainIds(), self.toNetworksModel.getRoutePreferredNetworkChainIds(), self.sendType, self.fromNetworksModel.getRouteLockedChainIds()) @@ -322,3 +330,16 @@ QtObject: proc getIconUrl*(self: View, chainId: int): string {.slot.} = return self.fromNetworksModel.getIconUrl(chainId) + +# "Stateless" methods + proc fetchSuggestedRoutesWithParameters*(self: View, accountFrom: string, accountTo: string, amount: string, token: string, toToken: string, + disabledFromChainIDs: string, disabledToChainIDs: string, preferredChainIDs: string, sendType: int, lockedInAmounts: string) {.slot.} = + self.delegate.suggestedRoutes(accountFrom, accountTo, + parseAmount(amount), token, toToken, + parseChainIds(disabledFromChainIDs), parseChainIds(disabledToChainIDs), parseChainIds(preferredChainIDs), + 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.} = + self.delegate.authenticateAndTransferWithPaths(accountFrom, accountTo, token, + toToken, uuid, SendType(sendType), tokenName, tokenIsOwnerToken, rawPaths) \ No newline at end of file diff --git a/src/app_service/service/transaction/dto.nim b/src/app_service/service/transaction/dto.nim index 6c3c14d5b9..f1e7391f6e 100644 --- a/src/app_service/service/transaction/dto.nim +++ b/src/app_service/service/transaction/dto.nim @@ -20,6 +20,7 @@ type ERC721Transfer ERC1155Transfer Swap + Approve type PendingTransactionTypeDto* {.pure.} = enum @@ -325,6 +326,15 @@ proc convertToTransactionPathDto*(jsonObj: JsonNode): TransactionPathDto = discard jsonObj.getProp("approvalGasFees", result.approvalGasFees) discard jsonObj.getProp("approvalContractAddress", result.approvalContractAddress) +proc convertToTransactionPathsDto*(jsonObj: JsonNode): seq[TransactionPathDto] = + result = @[] + for path in jsonObj.getElems(): + result.add(path.convertToTransactionPathDto()) + return result + +proc convertToTransactionPathsDto*(paths: string): seq[TransactionPathDto] = + return paths.parseJson.convertToTransactionPathsDto() + type FeesDto* = ref object totalFeesInEth*: float @@ -369,6 +379,7 @@ proc convertSendToNetwork*(jsonObj: JsonNode): SendToNetwork = type SuggestedRoutesDto* = ref object best*: seq[TransactionPathDto] + rawBest*: string gasTimeEstimate*: FeesDto amountToReceive*: UInt256 toNetworks*: seq[SendToNetwork] @@ -376,6 +387,7 @@ type proc `$`*(self: SuggestedRoutesDto): string = return fmt"""SuggestedRoutesDto( best:{self.best}, + rawBest:{self.rawBest}, gasTimeEstimate:{self.gasTimeEstimate}, amountToReceive:{self.amountToReceive}, toNetworks:{self.toNetworks}, @@ -383,7 +395,8 @@ proc `$`*(self: SuggestedRoutesDto): string = proc convertToSuggestedRoutesDto*(jsonObj: JsonNode): SuggestedRoutesDto = result = SuggestedRoutesDto() - result.best = jsonObj["suggestedRoutes"]["best"].getElems().map(x => x.convertToTransactionPathDto()) + result.rawBest = $jsonObj["suggestedRoutes"]["best"] + result.best = result.rawBest.convertToTransactionPathsDto() result.gasTimeEstimate = jsonObj["suggestedRoutes"]["gasTimeEstimate"].convertToFeesDto() result.amountToReceive = stint.u256(jsonObj["suggestedRoutes"]["amountToReceive"].getStr) result.toNetworks = jsonObj["suggestedRoutes"]["toNetworks"].getElems().map(x => x.convertSendToNetwork()) diff --git a/src/app_service/service/transaction/service.nim b/src/app_service/service/transaction/service.nim index f0e85770c6..52b8d404d8 100644 --- a/src/app_service/service/transaction/service.nim +++ b/src/app_service/service/transaction/service.nim @@ -325,6 +325,15 @@ QtObject: proc isCollectiblesTransfer(self: Service, sendType: SendType): bool = return sendType == ERC721Transfer or sendType == ERC1155Transfer + proc sendTypeToMultiTxType(sendType: SendType): transactions.MultiTransactionType = + case sendType + of SendType.Swap: + return transactions.MultiTransactionType.MultiTransactionSwap + of SendType.Approve: + return transactions.MultiTransactionType.MultiTransactionApprove + else: + return transactions.MultiTransactionType.MultiTransactionSend + proc transferEth( self: Service, from_addr: string, @@ -364,12 +373,9 @@ QtObject: fromAsset: tokenSymbol, toAsset: toTokenSymbol, fromAmount: "0x" & totalAmountToSend.toHex, - multiTxType: transactions.MultiTransactionType.MultiTransactionSend, + multiTxType: sendTypeToMultiTxType(sendType), ) - if sendType == Swap: - mtCommand.multiTxType = transactions.MultiTransactionType.MultiTransactionSwap - let response = transactions.createMultiTransaction( mtCommand, paths, @@ -407,7 +413,7 @@ QtObject: toAddress: to_addr, fromAsset: if not asset.isNil: asset.symbol else: assetKey, toAsset: if not toAsset.isNil: toAsset.symbol else: toAssetKey, - multiTxType: transactions.MultiTransactionType.MultiTransactionSend, + multiTxType: sendTypeToMultiTxType(sendType), ) # if collectibles transfer ... @@ -421,9 +427,6 @@ QtObject: error "Invalid assetKey for collectibles transfer", assetKey=assetKey return - if sendType == Swap: - mtCommand.multiTxType = transactions.MultiTransactionType.MultiTransactionSwap - try: for route in routes: var txData = TransactionDataDto() @@ -449,6 +452,11 @@ QtObject: paths.add(approvalPath) totalAmountToSend += route.amountIn + + if sendType == SendType.Approve: + # We only do the approvals + continue + let transfer = Transfer( to: parseAddress(mtCommand.toAddress), value: route.amountIn, @@ -558,7 +566,7 @@ QtObject: self.events.emit(SIGNAL_SUGGESTED_ROUTES_READY, SuggestedRoutesArgs(suggestedRoutes: suggestedRoutesDto)) proc suggestedRoutes*(self: Service, accountFrom: string, accountTo: string, amount: Uint256, token: string, toToken: string, - disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string): SuggestedRoutesDto = + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) = var tokenId: string toTokenId: string diff --git a/src/backend/transactions.nim b/src/backend/transactions.nim index 1fe5ca1a98..f441cbab0b 100644 --- a/src/backend/transactions.nim +++ b/src/backend/transactions.nim @@ -11,7 +11,8 @@ type MultiTransactionType* = enum MultiTransactionSend = 0, MultiTransactionSwap = 1, - MultiTransactionBridge = 2 + MultiTransactionBridge = 2, + MultiTransactionApprove = 3 MultiTransactionCommandDto* = ref object of RootObj fromAddress* {.serializedFieldName("fromAddress").}: string diff --git a/storybook/pages/SwapModalPage.qml b/storybook/pages/SwapModalPage.qml index bdbb1c27da..b7d8cf10e4 100644 --- a/storybook/pages/SwapModalPage.qml +++ b/storybook/pages/SwapModalPage.qml @@ -95,6 +95,13 @@ SplitView { readonly property var accounts: d.accountsModel readonly property var flatNetworks: d.flatNetworksModel readonly property bool areTestNetworksEnabled: areTestNetworksEnabledCheckbox.checked + + signal suggestedRoutesReady(var txRoutes) + + function fetchSuggestedRoutes(accountFrom, accountTo, amount, tokenFrom, tokenTo, + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) {} + function authenticateAndTransfer(uuid, accountFrom, accountTo, + tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths) {} } walletAssetsStore: WalletAssetsStore { id: thisWalletAssetStore diff --git a/ui/StatusQ/src/StatusQ/Core/Utils/ModelUtils.qml b/ui/StatusQ/src/StatusQ/Core/Utils/ModelUtils.qml index 87b777efca..ea509e53f4 100644 --- a/ui/StatusQ/src/StatusQ/Core/Utils/ModelUtils.qml +++ b/ui/StatusQ/src/StatusQ/Core/Utils/ModelUtils.qml @@ -55,6 +55,10 @@ QtObject { return modelToArray(model, [role]).map(entry => entry[role]) } + function joinModelEntries(model, role, separator) { + return modelToFlatArray(model, role).join(separator) + } + function indexOf(model, role, key) { if (!model) return -1 diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml index 7e23f77e93..187433e6ab 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapModal.qml @@ -4,8 +4,10 @@ import QtQml.Models 2.15 import utils 1.0 +import StatusQ.Controls 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 +import StatusQ.Core.Utils 0.1 as SQUtils import StatusQ.Popups.Dialog 0.1 import StatusQ.Controls 0.1 @@ -108,6 +110,36 @@ StatusDialog { StatusBaseText { text: qsTr("to token amount: %1").arg(swapInputParamsForm.toTokenAmount) } + StatusButton { + text: "Fetch Suggested Routes" + onClicked: { + swapAdaptor.fetchSuggestedRoutes() + } + } + StatusButton { + text: "Send Approve Tx" + onClicked: { + swapAdaptor.sendApproveTx() + } + } + StatusButton { + text: "Send Swap Tx" + onClicked: { + swapAdaptor.sendSwapTx() + } + } + StatusScrollView { + Layout.fillWidth: true + Layout.preferredHeight: 200 + + StatusTextArea { + text: { + let routes = SQUtils.ModelUtils.modelToArray(swapAdaptor.suggestedRoutes) + let routesString = JSON.stringify(routes, null, " ") + return qsTr("Suggested routes: \n%1").arg(routesString) + } + } + } // End temporary placeholders EditSlippagePanel { diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml index c483509394..1c071f7707 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapModalAdaptor.qml @@ -26,6 +26,28 @@ QObject { readonly property var fromToken: ModelUtils.getByKey(root.walletAssetsStore.walletTokensStore.plainTokensBySymbolModel, "key", root.swapFormData.fromTokensKey) readonly property var toToken: ModelUtils.getByKey(root.walletAssetsStore.walletTokensStore.plainTokensBySymbolModel, "key", root.swapFormData.toTokenKey) + readonly property alias suggestedRoutes: d.suggestedRoutes + + QtObject { + id: d + + property string uuid + // TODO: Remove these properties swap proposal is properly handled + property var suggestedRoutes + property string rawPaths + } + + Connections { + target: root.swapStore + function onSuggestedRoutesReady(txRoutes) { + root.swapProposalReady = txRoutes.suggestedRoutes.count > 0 + root.swapProposalLoading = false + + d.suggestedRoutes = txRoutes.suggestedRoutes + d.rawPaths = txRoutes.rawPaths + } + } + readonly property var nonWatchAccounts: SortFilterProxyModel { sourceModel: root.swapStore.accounts filters: ValueFilter { @@ -72,6 +94,21 @@ QObject { return root.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals) } + function getAllChainIds() { + return ModelUtils.joinModelEntries(root.filteredFlatNetworksModel, "chainId", ":") + } + + function getDisabledChainIds(enabledChainId) { + let disabledChainIds = [] + let chainIds = ModelUtils.modelToFlatArray(root.filteredFlatNetworksModel, "chainId") + for (let i = 0; i < chainIds.length; i++) { + if (chainIds[i] !== enabledChainId) { + disabledChainIds.push(chainIds[i]) + } + } + return disabledChainIds.join(":") + } + // TODO: remove once the AccountsModalHeader is reworked!! function getSelectedAccount(index) { if (root.nonWatchAccounts.count > 0 && index >= 0) { @@ -198,4 +235,42 @@ QObject { } return totalBalance } + + function fetchSuggestedRoutes() { + root.swapProposalReady = false + root.swapProposalLoading = true + + // Identify new swap with a different uuid + d.uuid = Utils.uuid() + + let account = getSelectedAccount(root.swapFormData.selectedAccountIndex) + let accountAddress = account.address + let disabledChainIds = getDisabledChainIds(root.swapFormData.selectedNetworkChainId) + let preferedChainIds = getAllChainIds() + + // TODO #14825: amount should be in BigInt string representation (fromTokenAmount * 10^decimals) + // Make sure that's replaced when the input component is integrated + root.swapStore.fetchSuggestedRoutes(accountAddress, accountAddress, + root.swapFormData.fromTokenAmount, root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey, + disabledChainIds, disabledChainIds, preferedChainIds, + Constants.SendType.Swap, "") + } + + function sendApproveTx() { + let account = getSelectedAccount(root.swapFormData.selectedAccountIndex) + let accountAddress = account.address + + root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress, + root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey, + Constants.SendType.Approve, "", false, d.rawPaths) + } + + function sendSwapTx() { + let account = getSelectedAccount(root.swapFormData.selectedAccountIndex) + let accountAddress = account.address + + root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress, + root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey, + Constants.SendType.Swap, "", false, d.rawPaths) + } } diff --git a/ui/app/AppLayouts/Wallet/stores/SwapStore.qml b/ui/app/AppLayouts/Wallet/stores/SwapStore.qml index 44ab78acaf..c7fa3bb6c8 100644 --- a/ui/app/AppLayouts/Wallet/stores/SwapStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/SwapStore.qml @@ -1,5 +1,8 @@ import QtQuick 2.15 +import StatusQ 0.1 +import StatusQ.Core.Utils 0.1 + QtObject { id: root @@ -8,4 +11,30 @@ QtObject { readonly property var accounts: walletSectionAccounts.accounts readonly property var flatNetworks: networksModule.flatNetworks readonly property bool areTestNetworksEnabled: networksModule.areTestNetworksEnabled + + /* TODO: Send module should be reworked into a lighter, generic, "stateless" module. + Remove these and use the new TransactorStore in SwapModalAdaptor when that happens. */ + readonly property var walletSectionSendInst: walletSectionSend + + signal suggestedRoutesReady(var txRoutes) + + readonly property Connections walletSectionSendConnections: Connections { + target: root.walletSectionSendInst + function onSuggestedRoutesReady(txRoutes) { + root.suggestedRoutesReady(txRoutes) + } + } + + function fetchSuggestedRoutes(accountFrom, accountTo, amount, tokenFrom, tokenTo, + disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) { + const value = AmountsArithmetic.fromNumber(amount) + root.walletSectionSendInst.fetchSuggestedRoutesWithParameters(accountFrom, accountTo, value.toFixed(), + tokenFrom, tokenTo, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) + } + + function authenticateAndTransfer(uuid, accountFrom, accountTo, + tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths) { + root.walletSectionSendInst.authenticateAndTransferWithParameters(uuid, accountFrom, accountTo, + tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths) + } } diff --git a/ui/imports/utils/Constants.qml b/ui/imports/utils/Constants.qml index 24e95cf698..4a63626942 100644 --- a/ui/imports/utils/Constants.qml +++ b/ui/imports/utils/Constants.qml @@ -1026,6 +1026,8 @@ QtObject { Bridge, ERC721Transfer, ERC1155Transfer, + Swap, + Approve, Unknown } diff --git a/vendor/status-go b/vendor/status-go index 27687eb8f4..fb63f0c1e0 160000 --- a/vendor/status-go +++ b/vendor/status-go @@ -1 +1 @@ -Subproject commit 27687eb8f4afea90e67811b4613761d154c43d44 +Subproject commit fb63f0c1e091cd42201bea4cd4d4ffc29544d928