chore: improvements of the sending route generated by the router process
Closes #14636
This commit is contained in:
parent
8bc6db5405
commit
ad7e2df78a
|
@ -6,6 +6,10 @@ type SignalType* {.pure.} = enum
|
||||||
## Wallet Signals
|
## Wallet Signals
|
||||||
Wallet = "wallet"
|
Wallet = "wallet"
|
||||||
WalletSignTransactions = "wallet.sign.transactions"
|
WalletSignTransactions = "wallet.sign.transactions"
|
||||||
|
WalletRouterSendingTransactionsStarted = "wallet.router.sending-transactions-started"
|
||||||
|
WalletRouterSignTransactions = "wallet.router.sign-transactions"
|
||||||
|
WalletRouterTransactionsSent = "wallet.router.transactions-sent"
|
||||||
|
WalletTransactionStatusChanged = "wallet.transaction.status-changed"
|
||||||
WalletSuggestedRoutes = "wallet.suggested.routes"
|
WalletSuggestedRoutes = "wallet.suggested.routes"
|
||||||
NodeReady = "node.ready"
|
NodeReady = "node.ready"
|
||||||
NodeCrashed = "node.crashed"
|
NodeCrashed = "node.crashed"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import base
|
||||||
import signal_type
|
import signal_type
|
||||||
|
|
||||||
import app_service/service/transaction/dtoV2
|
import app_service/service/transaction/dtoV2
|
||||||
|
import app_service/service/transaction/router_transactions_dto
|
||||||
|
|
||||||
const SignTransactionsEventType* = "sing-transactions"
|
const SignTransactionsEventType* = "sing-transactions"
|
||||||
|
|
||||||
|
@ -25,6 +26,10 @@ type WalletSignal* = ref object of Signal
|
||||||
error*: string
|
error*: string
|
||||||
errorCode*: string
|
errorCode*: string
|
||||||
updatedPrices*: Table[string, float64]
|
updatedPrices*: Table[string, float64]
|
||||||
|
routerTransactionsSendingDetails*: SendDetailsDto
|
||||||
|
routerTransactionsForSigning*: RouterTransactionsForSigningDto
|
||||||
|
routerSentTransactions*: RouterSentTransactionsDto
|
||||||
|
transactionStatusChange*: TransactionStatusChange
|
||||||
|
|
||||||
proc fromEvent*(T: type WalletSignal, signalType: SignalType, jsonSignal: JsonNode): WalletSignal =
|
proc fromEvent*(T: type WalletSignal, signalType: SignalType, jsonSignal: JsonNode): WalletSignal =
|
||||||
result = WalletSignal()
|
result = WalletSignal()
|
||||||
|
@ -54,6 +59,24 @@ proc fromEvent*(T: type WalletSignal, signalType: SignalType, jsonSignal: JsonNo
|
||||||
for tx in event:
|
for tx in event:
|
||||||
result.txHashes.add(tx.getStr)
|
result.txHashes.add(tx.getStr)
|
||||||
return
|
return
|
||||||
|
if signalType == SignalType.WalletRouterSignTransactions:
|
||||||
|
if event.kind != JObject:
|
||||||
|
return
|
||||||
|
result.routerTransactionsForSigning = toRouterTransactionsForSigningDto(event)
|
||||||
|
return
|
||||||
|
if signalType == SignalType.WalletRouterTransactionsSent:
|
||||||
|
if event.kind != JObject:
|
||||||
|
return
|
||||||
|
result.routerSentTransactions = toRouterSentTransactionsDto(event)
|
||||||
|
return
|
||||||
|
if signalType == SignalType.WalletRouterSendingTransactionsStarted:
|
||||||
|
result.routerTransactionsSendingDetails = toSendDetailsDto(event)
|
||||||
|
return
|
||||||
|
if signalType == SignalType.WalletTransactionStatusChanged:
|
||||||
|
if event.kind != JObject:
|
||||||
|
return
|
||||||
|
result.transactionStatusChange = toTransactionStatusChange(event)
|
||||||
|
return
|
||||||
if signalType == SignalType.WalletSuggestedRoutes:
|
if signalType == SignalType.WalletSuggestedRoutes:
|
||||||
try:
|
try:
|
||||||
if event.contains("Uuid"):
|
if event.contains("Uuid"):
|
||||||
|
|
|
@ -81,8 +81,12 @@ QtObject:
|
||||||
of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal)
|
of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal)
|
||||||
of SignalType.Wallet,
|
of SignalType.Wallet,
|
||||||
SignalType.WalletSignTransactions,
|
SignalType.WalletSignTransactions,
|
||||||
|
SignalType.WalletRouterSendingTransactionsStarted,
|
||||||
|
SignalType.WalletRouterSignTransactions,
|
||||||
|
SignalType.WalletRouterTransactionsSent,
|
||||||
|
SignalType.WalletTransactionStatusChanged,
|
||||||
SignalType.WalletSuggestedRoutes:
|
SignalType.WalletSuggestedRoutes:
|
||||||
WalletSignal.fromEvent(signalType, jsonSignal)
|
WalletSignal.fromEvent(signalType, jsonSignal)
|
||||||
of SignalType.NodeReady,
|
of SignalType.NodeReady,
|
||||||
SignalType.NodeCrashed,
|
SignalType.NodeCrashed,
|
||||||
SignalType.NodeStarted,
|
SignalType.NodeStarted,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Tables
|
import Tables
|
||||||
import uuids, chronicles, options
|
import uuids, chronicles
|
||||||
import io_interface
|
import io_interface
|
||||||
import app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
|
@ -13,7 +13,6 @@ import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_m
|
||||||
import app/modules/shared/wallet_utils
|
import app/modules/shared/wallet_utils
|
||||||
import app/modules/shared_models/currency_amount
|
import app/modules/shared_models/currency_amount
|
||||||
|
|
||||||
import app/core/signals/types
|
|
||||||
import app/core/eventemitter
|
import app/core/eventemitter
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
|
@ -56,11 +55,11 @@ proc delete*(self: Controller) =
|
||||||
proc init*(self: Controller) =
|
proc init*(self: Controller) =
|
||||||
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
|
self.events.on(SIGNAL_TRANSACTION_SENT) do(e:Args):
|
||||||
let args = TransactionSentArgs(e)
|
let args = TransactionSentArgs(e)
|
||||||
self.delegate.transactionWasSent(args.chainId, args.txHash, args.uuid, args.error)
|
self.delegate.transactionWasSent(args.uuid, args.chainId, args.approvalTx, args.txHash, args.error)
|
||||||
|
|
||||||
self.events.on(SIGNAL_OWNER_TOKEN_SENT) do(e:Args):
|
self.events.on(SIGNAL_OWNER_TOKEN_SENT) do(e:Args):
|
||||||
let args = OwnerTokenSentArgs(e)
|
let args = OwnerTokenSentArgs(e)
|
||||||
self.delegate.transactionWasSent(args.chainId, args.txHash, args.uuid, "")
|
self.delegate.transactionWasSent(args.uuid, args.chainId, approvalTx = false, args.txHash, error = "")
|
||||||
|
|
||||||
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
self.events.on(SIGNAL_SHARED_KEYCARD_MODULE_USER_AUTHENTICATED) do(e: Args):
|
||||||
let args = SharedKeycarModuleArgs(e)
|
let args = SharedKeycarModuleArgs(e)
|
||||||
|
@ -72,13 +71,13 @@ proc init*(self: Controller) =
|
||||||
let args = SuggestedRoutesArgs(e)
|
let args = SuggestedRoutesArgs(e)
|
||||||
self.delegate.suggestedRoutesReady(args.uuid, args.suggestedRoutes, args.errCode, args.errDescription)
|
self.delegate.suggestedRoutesReady(args.uuid, args.suggestedRoutes, args.errCode, args.errDescription)
|
||||||
|
|
||||||
self.events.on(SignalType.WalletSignTransactions.event) do(e:Args):
|
self.events.on(SIGNAL_SIGN_ROUTER_TRANSACTIONS) do(e:Args):
|
||||||
var data = WalletSignal(e)
|
var data = RouterTransactionsForSigningArgs(e)
|
||||||
self.delegate.prepareSignaturesForTransactions(data.txHashes)
|
self.delegate.prepareSignaturesForTransactions(data.data)
|
||||||
|
|
||||||
self.events.on(SIGNAL_TRANSACTION_SENDING_COMPLETE) do(e:Args):
|
self.events.on(SIGNAL_TRANSACTION_STATUS_CHANGED) do(e:Args):
|
||||||
let args = TransactionMinedArgs(e)
|
let args = TransactionStatusArgs(e)
|
||||||
self.delegate.transactionSendingComplete(args.transactionHash, args.success)
|
self.delegate.transactionSendingComplete(args.data.hash, args.data.status)
|
||||||
|
|
||||||
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||||
return self.walletAccountService.getWalletAccounts()
|
return self.walletAccountService.getWalletAccounts()
|
||||||
|
@ -115,6 +114,7 @@ proc suggestedRoutes*(self: Controller,
|
||||||
accountFrom: string,
|
accountFrom: string,
|
||||||
accountTo: string,
|
accountTo: string,
|
||||||
token: string,
|
token: string,
|
||||||
|
tokenIsOwnerToken: bool,
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
toToken: string = "",
|
toToken: string = "",
|
||||||
amountOut: string = "",
|
amountOut: string = "",
|
||||||
|
@ -122,23 +122,20 @@ proc suggestedRoutes*(self: Controller,
|
||||||
disabledToChainIDs: seq[int] = @[],
|
disabledToChainIDs: seq[int] = @[],
|
||||||
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
||||||
extraParamsTable: Table[string, string] = initTable[string, string]()) =
|
extraParamsTable: Table[string, string] = initTable[string, string]()) =
|
||||||
self.transactionService.suggestedRoutes(uuid, sendType, accountFrom, accountTo, token, amountIn, toToken, amountOut,
|
self.transactionService.suggestedRoutes(uuid, sendType, accountFrom, accountTo, token, tokenIsOwnerToken, amountIn, toToken, amountOut,
|
||||||
disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
|
|
||||||
proc stopSuggestedRoutesAsyncCalculation*(self: Controller) =
|
proc stopSuggestedRoutesAsyncCalculation*(self: Controller) =
|
||||||
self.transactionService.stopSuggestedRoutesAsyncCalculation()
|
self.transactionService.stopSuggestedRoutesAsyncCalculation()
|
||||||
|
|
||||||
proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: string, toAssetKey: string,
|
proc buildTransactionsFromRoute*(self: Controller, uuid: string, slippagePercentage: float): string =
|
||||||
uuid: string, selectedRoutes: seq[TransactionPathDto], password: string, sendType: SendType,
|
return self.transactionService.buildTransactionsFromRoute(uuid, slippagePercentage)
|
||||||
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, slippagePercentage)
|
|
||||||
|
|
||||||
proc proceedWithTransactionsSignatures*(self: Controller, fromAddr: string, toAddr: string,
|
proc signMessage*(self: Controller, address: string, hashedPassword: string, hashedMessage: string): tuple[res: string, err: string] =
|
||||||
fromTokenKey: string, toTokenKey: string, uuid: string, signatures: TransactionsSignatures,
|
return self.transactionService.signMessage(address, hashedPassword, hashedMessage)
|
||||||
selectedRoutes: seq[TransactionPathDto], sendType: SendType) =
|
|
||||||
self.transactionService.proceedWithTransactionsSignatures(fromAddr, toAddr, fromTokenKey, toTokenKey, uuid, signatures, selectedRoutes, sendType)
|
proc sendRouterTransactionsWithSignatures*(self: Controller, uuid: string, signatures: TransactionsSignatures): string =
|
||||||
|
return self.transactionService.sendRouterTransactionsWithSignatures(uuid, signatures)
|
||||||
|
|
||||||
proc areTestNetworksEnabled*(self: Controller): bool =
|
proc areTestNetworksEnabled*(self: Controller): bool =
|
||||||
return self.walletAccountService.areTestNetworksEnabled()
|
return self.walletAccountService.areTestNetworksEnabled()
|
||||||
|
@ -159,7 +156,7 @@ proc connectKeycardReponseSignal(self: Controller) =
|
||||||
let currentFlow = self.keycardService.getCurrentFlow()
|
let currentFlow = self.keycardService.getCurrentFlow()
|
||||||
if currentFlow != KCSFlowType.Sign:
|
if currentFlow != KCSFlowType.Sign:
|
||||||
error "trying to use keycard in the other than the signing a transaction flow"
|
error "trying to use keycard in the other than the signing a transaction flow"
|
||||||
self.delegate.transactionWasSent()
|
self.delegate.transactionWasSent(uuid = "", chainId = 0, approvalTx = false, txHash = "", error = "trying to use keycard in the other than the signing a transaction flow")
|
||||||
return
|
return
|
||||||
self.delegate.onTransactionSigned(args.flowType, args.flowEvent)
|
self.delegate.onTransactionSigned(args.flowType, args.flowEvent)
|
||||||
|
|
||||||
|
@ -172,4 +169,4 @@ proc runSignFlow*(self: Controller, pin, bip44Path, txHash: string) =
|
||||||
self.keycardService.startSignFlow(bip44Path, txHash, pin)
|
self.keycardService.startSignFlow(bip44Path, txHash, pin)
|
||||||
|
|
||||||
proc getChainsWithNoGasFromError*(self: Controller, errCode: string, errDescription: string): Table[int, string] =
|
proc getChainsWithNoGasFromError*(self: Controller, errCode: string, errDescription: string): Table[int, string] =
|
||||||
return self.walletAccountService.getChainsWithNoGasFromError(errCode, errDescription)
|
return self.walletAccountService.getChainsWithNoGasFromError(errCode, errDescription)
|
|
@ -1,6 +1,7 @@
|
||||||
import Tables, options
|
import Tables
|
||||||
import app/modules/shared_models/currency_amount
|
import app/modules/shared_models/currency_amount
|
||||||
import app_service/service/transaction/dto
|
import app_service/service/transaction/dto
|
||||||
|
import app_service/service/transaction/router_transactions_dto
|
||||||
import app_service/service/network/network_item
|
import app_service/service/network/network_item
|
||||||
import app/modules/shared_models/collectibles_model as collectibles
|
import app/modules/shared_models/collectibles_model as collectibles
|
||||||
from app_service/service/keycard/service import KeycardEvent
|
from app_service/service/keycard/service import KeycardEvent
|
||||||
|
@ -27,6 +28,7 @@ method suggestedRoutes*(self: AccessInterface,
|
||||||
accountFrom: string,
|
accountFrom: string,
|
||||||
accountTo: string,
|
accountTo: string,
|
||||||
token: string,
|
token: string,
|
||||||
|
tokenIsOwnerToken: bool,
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
toToken: string = "",
|
toToken: string = "",
|
||||||
amountOut: string = "",
|
amountOut: string = "",
|
||||||
|
@ -42,19 +44,13 @@ method stopUpdatesForSuggestedRoute*(self: AccessInterface) {.base.} =
|
||||||
method suggestedRoutesReady*(self: AccessInterface, uuid: string, suggestedRoutes: SuggestedRoutesDto, errCode: string, errDescription: string) {.base.} =
|
method suggestedRoutesReady*(self: AccessInterface, uuid: string, suggestedRoutes: SuggestedRoutesDto, errCode: string, errDescription: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method authenticateAndTransfer*(self: AccessInterface, from_addr: string, to_addr: string, assetKey: string,
|
method authenticateAndTransferV2*(self: AccessInterface, fromAddr: string, uuid: string, slippagePercentage: float) {.base.} =
|
||||||
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,
|
|
||||||
slippagePercentage: Option[float]) {.base.} =
|
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onUserAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} =
|
method onUserAuthenticated*(self: AccessInterface, password: string, pin: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method transactionWasSent*(self: AccessInterface, chainId: int = 0, txHash, uuid, error: string = "") {.base.} =
|
method transactionWasSent*(self: AccessInterface, uuid: string, chainId: int = 0, approvalTx: bool = false, txHash: string = "", error: string = "") {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
@ -78,7 +74,7 @@ method getCollectiblesModel*(self: AccessInterface): collectibles.Model {.base.}
|
||||||
method splitAndFormatAddressPrefix*(self: AccessInterface, text : string, updateInStore: bool): string {.base.} =
|
method splitAndFormatAddressPrefix*(self: AccessInterface, text : string, updateInStore: bool): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method prepareSignaturesForTransactions*(self: AccessInterface, txHashes: seq[string]) {.base.} =
|
method prepareSignaturesForTransactions*(self:AccessInterface, txForSigning: RouterTransactionsForSigningDto) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method onTransactionSigned*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} =
|
method onTransactionSigned*(self: AccessInterface, keycardFlowType: string, keycardEvent: KeycardEvent) {.base.} =
|
||||||
|
@ -87,7 +83,7 @@ method onTransactionSigned*(self: AccessInterface, keycardFlowType: string, keyc
|
||||||
method hasGas*(self: AccessInterface, accountAddress: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.base.} =
|
method hasGas*(self: AccessInterface, accountAddress: string, chainId: int, nativeGasSymbol: string, requiredGas: float): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method transactionSendingComplete*(self: AccessInterface, txHash: string, success: bool) {.base.} =
|
method transactionSendingComplete*(self: AccessInterface, txHash: string, status: string) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getNetworkItem*(self: AccessInterface, chainId: int): NetworkItem {.base.} =
|
method getNetworkItem*(self: AccessInterface, chainId: int): NetworkItem {.base.} =
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import tables, NimQml, sequtils, sugar, stint, strutils, chronicles, options
|
import tables, NimQml, sequtils, sugar, stint, strutils, chronicles
|
||||||
|
|
||||||
import ./io_interface, ./view, ./controller, ./network_route_item, ./transaction_routes, ./suggested_route_item, ./suggested_route_model, ./gas_estimate_item, ./gas_fees_item, ./network_route_model
|
import ./io_interface, ./view, ./controller, ./network_route_item, ./transaction_routes, ./suggested_route_item, ./suggested_route_model, ./gas_estimate_item, ./gas_fees_item, ./network_route_model
|
||||||
import ../io_interface as delegate_interface
|
import ../io_interface as delegate_interface
|
||||||
import app/global/global_singleton
|
import app/global/global_singleton
|
||||||
|
import app/global/utils
|
||||||
import app/core/eventemitter
|
import app/core/eventemitter
|
||||||
|
import app_service/common/utils
|
||||||
|
import app_service/common/wallet_constants
|
||||||
import app_service/service/wallet_account/service as wallet_account_service
|
import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
import app_service/service/currency/service as currency_service
|
import app_service/service/currency/service as currency_service
|
||||||
|
@ -11,8 +14,6 @@ import app_service/service/transaction/service as transaction_service
|
||||||
import app_service/service/keycard/service as keycard_service
|
import app_service/service/keycard/service as keycard_service
|
||||||
import app_service/service/keycard/constants as keycard_constants
|
import app_service/service/keycard/constants as keycard_constants
|
||||||
import app_service/service/transaction/dto
|
import app_service/service/transaction/dto
|
||||||
import app_service/service/transaction/dtoV2
|
|
||||||
import app_service/service/transaction/dto_conversion
|
|
||||||
import app/modules/shared_models/currency_amount
|
import app/modules/shared_models/currency_amount
|
||||||
import app_service/service/network/network_item as network_service_item
|
import app_service/service/network/network_item as network_service_item
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ type TmpSendTransactionDetails = object
|
||||||
resolvedSignatures: TransactionsSignatures
|
resolvedSignatures: TransactionsSignatures
|
||||||
tokenName: string
|
tokenName: string
|
||||||
isOwnerToken: bool
|
isOwnerToken: bool
|
||||||
slippagePercentage: Option[float]
|
slippagePercentage: float
|
||||||
|
|
||||||
type
|
type
|
||||||
Module* = ref object of io_interface.AccessInterface
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
@ -48,6 +49,7 @@ type
|
||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
tmpSendTransactionDetails: TmpSendTransactionDetails
|
tmpSendTransactionDetails: TmpSendTransactionDetails
|
||||||
tmpPin: string
|
tmpPin: string
|
||||||
|
tmpPassword: string
|
||||||
tmpTxHashBeingProcessed: string
|
tmpTxHashBeingProcessed: string
|
||||||
|
|
||||||
# Forward declaration
|
# Forward declaration
|
||||||
|
@ -77,6 +79,13 @@ method delete*(self: Module) =
|
||||||
self.view.delete
|
self.view.delete
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
|
||||||
|
proc clearTmpData(self: Module) =
|
||||||
|
self.tmpPin = ""
|
||||||
|
self.tmpPassword = ""
|
||||||
|
self.tmpTxHashBeingProcessed = ""
|
||||||
|
self.tmpSendTransactionDetails = TmpSendTransactionDetails()
|
||||||
|
writeStackTrace()
|
||||||
|
|
||||||
proc convertSendToNetworkToNetworkItem(self: Module, network: SendToNetwork): NetworkRouteItem =
|
proc convertSendToNetworkToNetworkItem(self: Module, network: SendToNetwork): NetworkRouteItem =
|
||||||
result = initNetworkRouteItem(
|
result = initNetworkRouteItem(
|
||||||
network.chainId,
|
network.chainId,
|
||||||
|
@ -174,18 +183,10 @@ method getNetworkItem*(self: Module, chainId: int): network_service_item.Network
|
||||||
return nil
|
return nil
|
||||||
return networks[0]
|
return networks[0]
|
||||||
|
|
||||||
method authenticateAndTransfer*(self: Module, fromAddr: string, toAddr: string, assetKey: string, toAssetKey: string, uuid: string,
|
method authenticateAndTransferV2*(self: Module, fromAddr: string, uuid: string, slippagePercentage: float) =
|
||||||
sendType: SendType, selectedTokenName: string, selectedTokenIsOwnerToken: bool) =
|
|
||||||
self.tmpSendTransactionDetails.fromAddr = fromAddr
|
|
||||||
self.tmpSendTransactionDetails.toAddr = toAddr
|
|
||||||
self.tmpSendTransactionDetails.assetKey = assetKey
|
|
||||||
self.tmpSendTransactionDetails.toAssetKey = toAssetKey
|
|
||||||
self.tmpSendTransactionDetails.uuid = uuid
|
self.tmpSendTransactionDetails.uuid = uuid
|
||||||
self.tmpSendTransactionDetails.sendType = sendType
|
self.tmpSendTransactionDetails.slippagePercentage = slippagePercentage
|
||||||
self.tmpSendTransactionDetails.fromAddrPath = ""
|
|
||||||
self.tmpSendTransactionDetails.resolvedSignatures.clear()
|
self.tmpSendTransactionDetails.resolvedSignatures.clear()
|
||||||
self.tmpSendTransactionDetails.tokenName = selectedTokenName
|
|
||||||
self.tmpSendTransactionDetails.isOwnerToken = selectedTokenIsOwnerToken
|
|
||||||
|
|
||||||
let kp = self.controller.getKeypairByAccountAddress(fromAddr)
|
let kp = self.controller.getKeypairByAccountAddress(fromAddr)
|
||||||
if kp.migratedToKeycard():
|
if kp.migratedToKeycard():
|
||||||
|
@ -193,34 +194,36 @@ method authenticateAndTransfer*(self: Module, fromAddr: string, toAddr: string,
|
||||||
if accounts.len != 1:
|
if accounts.len != 1:
|
||||||
error "cannot resolve selected account to send from among known keypair accounts"
|
error "cannot resolve selected account to send from among known keypair accounts"
|
||||||
return
|
return
|
||||||
self.tmpSendTransactionDetails.fromAddrPath = accounts[0].path
|
|
||||||
self.controller.authenticate(kp.keyUid)
|
self.controller.authenticate(kp.keyUid)
|
||||||
else:
|
else:
|
||||||
self.controller.authenticate()
|
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, slippagePercentage: Option[float]) =
|
|
||||||
# Temporary until transaction service rework is completed
|
|
||||||
let pathsV2 = rawPaths.toTransactionPathsDtoV2()
|
|
||||||
let pathsV1 = pathsV2.convertToOldRoute().addFirstSimpleBridgeTxFlag()
|
|
||||||
|
|
||||||
self.tmpSendTransactionDetails.paths = pathsV1
|
|
||||||
self.tmpSendTransactionDetails.slippagePercentage = slippagePercentage
|
|
||||||
self.authenticateAndTransfer(fromAddr, toAddr, assetKey, toAssetKey, uuid, sendType, selectedTokenName, selectedTokenIsOwnerToken)
|
|
||||||
|
|
||||||
method onUserAuthenticated*(self: Module, password: string, pin: string) =
|
method onUserAuthenticated*(self: Module, password: string, pin: string) =
|
||||||
if password.len == 0:
|
if password.len == 0:
|
||||||
self.transactionWasSent(chainId = 0, txHash = "", uuid = self.tmpSendTransactionDetails.uuid, error = authenticationCanceled)
|
self.transactionWasSent(uuid = self.tmpSendTransactionDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error = authenticationCanceled)
|
||||||
|
self.clearTmpData()
|
||||||
else:
|
else:
|
||||||
self.tmpPin = pin
|
self.tmpPin = pin
|
||||||
let doHashing = self.tmpPin.len == 0
|
self.tmpPassword = password
|
||||||
let usePassword = self.tmpSendTransactionDetails.fromAddrPath.len == 0
|
let err = self.controller.buildTransactionsFromRoute(self.tmpSendTransactionDetails.uuid, self.tmpSendTransactionDetails.slippagePercentage)
|
||||||
self.controller.transfer(
|
if err.len > 0:
|
||||||
self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr,
|
self.transactionWasSent(uuid = self.tmpSendTransactionDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error = err)
|
||||||
self.tmpSendTransactionDetails.assetKey, self.tmpSendTransactionDetails.toAssetKey, self.tmpSendTransactionDetails.uuid,
|
self.clearTmpData()
|
||||||
self.tmpSendTransactionDetails.paths, password, self.tmpSendTransactionDetails.sendType, usePassword, doHashing,
|
|
||||||
self.tmpSendTransactionDetails.tokenName, self.tmpSendTransactionDetails.isOwnerToken, self.tmpSendTransactionDetails.slippagePercentage
|
proc sendSignedTransactions*(self: Module) =
|
||||||
)
|
try:
|
||||||
|
# check if all transactions are signed
|
||||||
|
for _, (r, s, v) in self.tmpSendTransactionDetails.resolvedSignatures.pairs:
|
||||||
|
if r.len == 0 or s.len == 0 or v.len == 0:
|
||||||
|
raise newException(CatchableError, "not all transactions are signed")
|
||||||
|
|
||||||
|
let err = self.controller.sendRouterTransactionsWithSignatures(self.tmpSendTransactionDetails.uuid, self.tmpSendTransactionDetails.resolvedSignatures)
|
||||||
|
if err.len > 0:
|
||||||
|
raise newException(CatchableError, "sending transaction failed: " & err)
|
||||||
|
except Exception as e:
|
||||||
|
error "sendSignedTransactions failed: ", msg=e.msg
|
||||||
|
self.transactionWasSent(uuid = self.tmpSendTransactionDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error = e.msg)
|
||||||
|
self.clearTmpData()
|
||||||
|
|
||||||
proc signOnKeycard(self: Module) =
|
proc signOnKeycard(self: Module) =
|
||||||
self.tmpTxHashBeingProcessed = ""
|
self.tmpTxHashBeingProcessed = ""
|
||||||
|
@ -234,35 +237,70 @@ proc signOnKeycard(self: Module) =
|
||||||
self.controller.runSignFlow(self.tmpPin, self.tmpSendTransactionDetails.fromAddrPath, txForKcFlow)
|
self.controller.runSignFlow(self.tmpPin, self.tmpSendTransactionDetails.fromAddrPath, txForKcFlow)
|
||||||
break
|
break
|
||||||
if self.tmpTxHashBeingProcessed.len == 0:
|
if self.tmpTxHashBeingProcessed.len == 0:
|
||||||
self.controller.proceedWithTransactionsSignatures(self.tmpSendTransactionDetails.fromAddr, self.tmpSendTransactionDetails.toAddr,
|
self.sendSignedTransactions()
|
||||||
self.tmpSendTransactionDetails.assetKey, self.tmpSendTransactionDetails.toAssetKey, self.tmpSendTransactionDetails.uuid,
|
self.clearTmpData()
|
||||||
self.tmpSendTransactionDetails.resolvedSignatures, self.tmpSendTransactionDetails.paths, self.tmpSendTransactionDetails.sendType)
|
|
||||||
|
|
||||||
method prepareSignaturesForTransactions*(self: Module, txHashes: seq[string]) =
|
proc getRSVFromSignature(self: Module, signature: string): (string, string, string) =
|
||||||
if txHashes.len == 0:
|
let finalSignature = singletonInstance.utils.removeHexPrefix(signature)
|
||||||
error "no transaction hashes to be signed"
|
if finalSignature.len != SIGNATURE_LEN:
|
||||||
return
|
return ("", "", "")
|
||||||
for h in txHashes:
|
let r = finalSignature[0..63]
|
||||||
self.tmpSendTransactionDetails.resolvedSignatures[h] = ("", "", "")
|
let s = finalSignature[64..127]
|
||||||
self.signOnKeycard()
|
let v = finalSignature[128..129]
|
||||||
|
return (r, s, v)
|
||||||
|
|
||||||
|
method prepareSignaturesForTransactions*(self:Module, txForSigning: RouterTransactionsForSigningDto) =
|
||||||
|
var res = ""
|
||||||
|
try:
|
||||||
|
if txForSigning.sendDetails.uuid != self.tmpSendTransactionDetails.uuid:
|
||||||
|
raise newException(CatchableError, "preparing signatures for transactions are not matching the initial request")
|
||||||
|
if txForSigning.signingDetails.hashes.len == 0:
|
||||||
|
raise newException(CatchableError, "no transaction hashes to be signed")
|
||||||
|
if txForSigning.signingDetails.keyUid == "" or txForSigning.signingDetails.address == "" or txForSigning.signingDetails.addressPath == "":
|
||||||
|
raise newException(CatchableError, "preparing signatures for transactions failed")
|
||||||
|
|
||||||
|
if txForSigning.signingDetails.signOnKeycard:
|
||||||
|
self.tmpSendTransactionDetails.fromAddrPath = txForSigning.signingDetails.addressPath
|
||||||
|
for h in txForSigning.signingDetails.hashes:
|
||||||
|
self.tmpSendTransactionDetails.resolvedSignatures[h] = ("", "", "")
|
||||||
|
self.signOnKeycard()
|
||||||
|
else:
|
||||||
|
let finalPassword = hashPassword(self.tmpPassword)
|
||||||
|
for h in txForSigning.signingDetails.hashes:
|
||||||
|
self.tmpSendTransactionDetails.resolvedSignatures[h] = ("", "", "")
|
||||||
|
var
|
||||||
|
signature = ""
|
||||||
|
err: string
|
||||||
|
(signature, err) = self.controller.signMessage(txForSigning.signingDetails.address, finalPassword, h)
|
||||||
|
if err.len > 0:
|
||||||
|
raise newException(CatchableError, "signing transaction failed: " & err)
|
||||||
|
self.tmpSendTransactionDetails.resolvedSignatures[h] = self.getRSVFromSignature(signature)
|
||||||
|
self.sendSignedTransactions()
|
||||||
|
except Exception as e:
|
||||||
|
error "signMessageWithCallback failed: ", msg=e.msg
|
||||||
|
self.transactionWasSent(uuid = txForSigning.sendDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error = e.msg)
|
||||||
|
self.clearTmpData()
|
||||||
|
|
||||||
method onTransactionSigned*(self: Module, keycardFlowType: string, keycardEvent: KeycardEvent) =
|
method onTransactionSigned*(self: Module, keycardFlowType: string, keycardEvent: KeycardEvent) =
|
||||||
if keycardFlowType != keycard_constants.ResponseTypeValueKeycardFlowResult:
|
if keycardFlowType != keycard_constants.ResponseTypeValueKeycardFlowResult:
|
||||||
error "unexpected error while keycard signing transaction"
|
let err = "unexpected error while keycard signing transaction"
|
||||||
|
error "error", err=err
|
||||||
|
self.transactionWasSent(uuid = self.tmpSendTransactionDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error = err)
|
||||||
|
self.clearTmpData()
|
||||||
return
|
return
|
||||||
self.tmpSendTransactionDetails.resolvedSignatures[self.tmpTxHashBeingProcessed] = (keycardEvent.txSignature.r,
|
self.tmpSendTransactionDetails.resolvedSignatures[self.tmpTxHashBeingProcessed] = (keycardEvent.txSignature.r,
|
||||||
keycardEvent.txSignature.s, keycardEvent.txSignature.v)
|
keycardEvent.txSignature.s, keycardEvent.txSignature.v)
|
||||||
self.signOnKeycard()
|
self.signOnKeycard()
|
||||||
|
|
||||||
method transactionWasSent*(self: Module, chainId: int, txHash, uuid, error: string) =
|
method transactionWasSent*(self: Module, uuid: string, chainId: int = 0, approvalTx: bool = false, txHash: string = "", error: string = "") =
|
||||||
if txHash.len == 0:
|
if txHash.len == 0:
|
||||||
self.view.sendTransactionSentSignal(chainId = 0, txHash = "", uuid = self.tmpSendTransactionDetails.uuid, error)
|
self.view.sendTransactionSentSignal(uuid = self.tmpSendTransactionDetails.uuid, chainId = 0, approvalTx = false, txHash = "", error)
|
||||||
return
|
return
|
||||||
self.view.sendTransactionSentSignal(chainId, txHash, uuid, error)
|
self.view.sendTransactionSentSignal(uuid, chainId, approvalTx, txHash, error)
|
||||||
|
|
||||||
method suggestedRoutesReady*(self: Module, uuid: string, suggestedRoutes: SuggestedRoutesDto, errCode: string, errDescription: string) =
|
method suggestedRoutesReady*(self: Module, uuid: string, suggestedRoutes: SuggestedRoutesDto, errCode: string, errDescription: string) =
|
||||||
self.tmpSendTransactionDetails.paths = suggestedRoutes.best
|
self.tmpSendTransactionDetails.paths = suggestedRoutes.best
|
||||||
self.tmpSendTransactionDetails.slippagePercentage = none(float)
|
self.tmpSendTransactionDetails.slippagePercentage = 0
|
||||||
let paths = suggestedRoutes.best.map(x => self.convertTransactionPathDtoToSuggestedRouteItem(x))
|
let paths = suggestedRoutes.best.map(x => self.convertTransactionPathDtoToSuggestedRouteItem(x))
|
||||||
let suggestedRouteModel = newSuggestedRouteModel()
|
let suggestedRouteModel = newSuggestedRouteModel()
|
||||||
suggestedRouteModel.setItems(paths)
|
suggestedRouteModel.setItems(paths)
|
||||||
|
@ -286,6 +324,7 @@ method suggestedRoutes*(self: Module,
|
||||||
accountFrom: string,
|
accountFrom: string,
|
||||||
accountTo: string,
|
accountTo: string,
|
||||||
token: string,
|
token: string,
|
||||||
|
tokenIsOwnerToken: bool,
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
toToken: string = "",
|
toToken: string = "",
|
||||||
amountOut: string = "",
|
amountOut: string = "",
|
||||||
|
@ -299,6 +338,7 @@ method suggestedRoutes*(self: Module,
|
||||||
accountFrom,
|
accountFrom,
|
||||||
accountTo,
|
accountTo,
|
||||||
token,
|
token,
|
||||||
|
tokenIsOwnerToken,
|
||||||
amountIn,
|
amountIn,
|
||||||
toToken,
|
toToken,
|
||||||
amountOut,
|
amountOut,
|
||||||
|
@ -362,5 +402,5 @@ method splitAndFormatAddressPrefix*(self: Module, text : string, updateInStore:
|
||||||
editedText = "<a><p>" & editedText & "</a></p>"
|
editedText = "<a><p>" & editedText & "</a></p>"
|
||||||
return editedText
|
return editedText
|
||||||
|
|
||||||
method transactionSendingComplete*(self: Module, txHash: string, success: bool) =
|
method transactionSendingComplete*(self: Module, txHash: string, status: string) =
|
||||||
self.view.sendtransactionSendingCompleteSignal(txHash, success)
|
self.view.sendtransactionSendingCompleteSignal(txHash, status)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import NimQml, Tables, json, sequtils, strutils, stint, options, chronicles
|
import NimQml, Tables, json, sequtils, strutils, stint, chronicles
|
||||||
import uuids
|
|
||||||
|
|
||||||
import ./io_interface, ./network_route_model, ./network_route_item, ./suggested_route_item, ./transaction_routes
|
import ./io_interface, ./network_route_model, ./network_route_item, ./suggested_route_item, ./transaction_routes
|
||||||
import app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
|
@ -165,9 +164,9 @@ QtObject:
|
||||||
self.fromNetworksRouteModel.setItems(fromNetworks)
|
self.fromNetworksRouteModel.setItems(fromNetworks)
|
||||||
self.toNetworksRouteModel.setItems(toNetworks)
|
self.toNetworksRouteModel.setItems(toNetworks)
|
||||||
|
|
||||||
proc transactionSent*(self: View, chainId: int, txHash: string, uuid: string, error: string) {.signal.}
|
proc transactionSent*(self: View, uuid: string, chainId: int, approvalTx: bool, txHash: string, error: string) {.signal.}
|
||||||
proc sendTransactionSentSignal*(self: View, chainId: int, txHash: string, uuid: string, error: string) =
|
proc sendTransactionSentSignal*(self: View, uuid: string, chainId: int, approvalTx: bool, txHash: string, error: string) =
|
||||||
self.transactionSent(chainId, txHash, uuid, error)
|
self.transactionSent(uuid, chainId, approvalTx, txHash, error)
|
||||||
|
|
||||||
proc parseChainIds(chainIds: string): seq[int] =
|
proc parseChainIds(chainIds: string): seq[int] =
|
||||||
var parsedChainIds: seq[int] = @[]
|
var parsedChainIds: seq[int] = @[]
|
||||||
|
@ -175,9 +174,13 @@ QtObject:
|
||||||
parsedChainIds.add(chainId.parseInt())
|
parsedChainIds.add(chainId.parseInt())
|
||||||
return parsedChainIds
|
return parsedChainIds
|
||||||
|
|
||||||
proc authenticateAndTransfer*(self: View, uuid: string) {.slot.} =
|
proc authenticateAndTransfer*(self: View, uuid: string, slippagePercentageString: string) {.slot.} =
|
||||||
self.delegate.authenticateAndTransfer(self.selectedSenderAccountAddress, self.selectedRecipient, self.selectedAssetKey,
|
var slippagePercentage: float
|
||||||
self.selectedToAssetKey, uuid, self.sendType, self.selectedTokenName, self.selectedTokenIsOwnerToken)
|
try:
|
||||||
|
slippagePercentage = slippagePercentageString.parseFloat()
|
||||||
|
except:
|
||||||
|
error "parsing slippage failed", slippage=slippagePercentageString
|
||||||
|
self.delegate.authenticateAndTransferV2(self.selectedSenderAccountAddress, uuid, slippagePercentage)
|
||||||
|
|
||||||
proc suggestedRoutesReady*(self: View, suggestedRoutes: QVariant, errCode: string, errDescription: string) {.signal.}
|
proc suggestedRoutesReady*(self: View, suggestedRoutes: QVariant, errCode: string, errDescription: string) {.signal.}
|
||||||
proc setTransactionRoute*(self: View, routes: TransactionRoutes, errCode: string, errDescription: string) =
|
proc setTransactionRoute*(self: View, routes: TransactionRoutes, errCode: string, errDescription: string) =
|
||||||
|
@ -186,7 +189,7 @@ QtObject:
|
||||||
self.errDescription = errDescription
|
self.errDescription = errDescription
|
||||||
self.suggestedRoutesReady(newQVariant(self.transactionRoutes), errCode, errDescription)
|
self.suggestedRoutesReady(newQVariant(self.transactionRoutes), errCode, errDescription)
|
||||||
|
|
||||||
proc suggestedRoutes*(self: View, amountIn: string, amountOut: string, extraParamsJson: string) {.slot.} =
|
proc suggestedRoutes*(self: View, uuid: string, amountIn: string, amountOut: string, extraParamsJson: string) {.slot.} =
|
||||||
var extraParamsTable: Table[string, string]
|
var extraParamsTable: Table[string, string]
|
||||||
try:
|
try:
|
||||||
if extraParamsJson.len > 0:
|
if extraParamsJson.len > 0:
|
||||||
|
@ -201,11 +204,12 @@ QtObject:
|
||||||
error "Error parsing extraParamsJson: ", msg=e.msg
|
error "Error parsing extraParamsJson: ", msg=e.msg
|
||||||
|
|
||||||
self.delegate.suggestedRoutes(
|
self.delegate.suggestedRoutes(
|
||||||
$genUUID(),
|
uuid,
|
||||||
self.sendType,
|
self.sendType,
|
||||||
self.selectedSenderAccountAddress,
|
self.selectedSenderAccountAddress,
|
||||||
self.selectedRecipient,
|
self.selectedRecipient,
|
||||||
self.selectedAssetKey,
|
self.selectedAssetKey,
|
||||||
|
self.selectedTokenIsOwnerToken,
|
||||||
amountIn,
|
amountIn,
|
||||||
self.selectedToAssetKey,
|
self.selectedToAssetKey,
|
||||||
amountOut,
|
amountOut,
|
||||||
|
@ -283,6 +287,7 @@ QtObject:
|
||||||
accountFrom,
|
accountFrom,
|
||||||
accountTo,
|
accountTo,
|
||||||
token,
|
token,
|
||||||
|
self.selectedTokenIsOwnerToken,
|
||||||
amountIn,
|
amountIn,
|
||||||
toToken,
|
toToken,
|
||||||
amountOut,
|
amountOut,
|
||||||
|
@ -290,22 +295,9 @@ QtObject:
|
||||||
parseChainIds(disabledToChainIDs),
|
parseChainIds(disabledToChainIDs),
|
||||||
lockedInAmountsTable)
|
lockedInAmountsTable)
|
||||||
|
|
||||||
proc authenticateAndTransferWithParameters*(self: View, uuid: string, accountFrom: string, accountTo: string, token: string, toToken: string,
|
proc transactionSendingComplete*(self: View, txHash: string, status: string) {.signal.}
|
||||||
sendTypeInt: int, tokenName: string, tokenIsOwnerToken: bool, rawPaths: string, slippagePercentageString: string) {.slot.} =
|
proc sendtransactionSendingCompleteSignal*(self: View, txHash: string, status: string) =
|
||||||
|
self.transactionSendingComplete(txHash, status)
|
||||||
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, tokenName, tokenIsOwnerToken, rawPaths, slippagePercentage)
|
|
||||||
|
|
||||||
proc transactionSendingComplete*(self: View, txHash: string, success: bool) {.signal.}
|
|
||||||
proc sendtransactionSendingCompleteSignal*(self: View, txHash: string, success: bool) =
|
|
||||||
self.transactionSendingComplete(txHash, success)
|
|
||||||
|
|
||||||
proc setSenderAccount*(self: View, address: string) {.slot.} =
|
proc setSenderAccount*(self: View, address: string) {.slot.} =
|
||||||
self.setSelectedSenderAccountAddress(address)
|
self.setSelectedSenderAccountAddress(address)
|
||||||
|
|
|
@ -119,7 +119,10 @@ QtObject:
|
||||||
debug "signMessageWithCallback: signing on keycard started successfully"
|
debug "signMessageWithCallback: signing on keycard started successfully"
|
||||||
return
|
return
|
||||||
let finalPassword = self.preparePassword(password)
|
let finalPassword = self.preparePassword(password)
|
||||||
res = self.service.signMessage(address, finalPassword, message)
|
var err: string
|
||||||
|
(res, err) = self.service.signMessage(address, finalPassword, message)
|
||||||
|
if err.len > 0:
|
||||||
|
raise newException(CatchableError, "signMessage failed: " & err)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "signMessageWithCallback failed: ", msg=e.msg
|
error "signMessageWithCallback failed: ", msg=e.msg
|
||||||
callback(topic, id, "", address, res)
|
callback(topic, id, "", address, res)
|
||||||
|
|
|
@ -7,6 +7,9 @@ const
|
||||||
STT_CONTRACT_ADDRESS_GOERLI* = "0x3d6afaa395c31fcd391fe3d562e75fe9e8ec7e6a"
|
STT_CONTRACT_ADDRESS_GOERLI* = "0x3d6afaa395c31fcd391fe3d562e75fe9e8ec7e6a"
|
||||||
STT_CONTRACT_ADDRESS_SEPOLIA* = "0xE452027cdEF746c7Cd3DB31CB700428b16cD8E51"
|
STT_CONTRACT_ADDRESS_SEPOLIA* = "0xE452027cdEF746c7Cd3DB31CB700428b16cD8E51"
|
||||||
|
|
||||||
|
SIGNATURE_LEN* = 130
|
||||||
|
SIGNATURE_LEN_0X_INCLUDED* = SIGNATURE_LEN + 2
|
||||||
|
|
||||||
TX_HASH_LEN* = 32 * 2
|
TX_HASH_LEN* = 32 * 2
|
||||||
TX_HASH_LEN_WITH_PREFIX* = TX_HASH_LEN + 2
|
TX_HASH_LEN_WITH_PREFIX* = TX_HASH_LEN + 2
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
import stint
|
import stint
|
||||||
import ../../../backend/backend as backend
|
import ../../../backend/backend as backend
|
||||||
import ../../common/conversion as service_conversion
|
|
||||||
|
|
||||||
type
|
type
|
||||||
GetSuggestedRoutesTaskArg* = ref object of QObjectTaskArg
|
GetSuggestedRoutesTaskArg* = ref object of QObjectTaskArg
|
||||||
|
|
|
@ -0,0 +1,142 @@
|
||||||
|
import json, stint
|
||||||
|
|
||||||
|
include ../../common/json_utils
|
||||||
|
|
||||||
|
const
|
||||||
|
TxStatusPending* = "Pending"
|
||||||
|
TxStatusSuccess* = "Success"
|
||||||
|
TxStatusFailed* = "Failed"
|
||||||
|
|
||||||
|
type
|
||||||
|
TransactionStatusChange* = ref object
|
||||||
|
status*: string
|
||||||
|
hash*: string
|
||||||
|
chainId*: int
|
||||||
|
|
||||||
|
type
|
||||||
|
ErrorResponse* = ref object
|
||||||
|
details*: string
|
||||||
|
code*: string
|
||||||
|
type
|
||||||
|
SendDetailsDto* = ref object
|
||||||
|
uuid*: string
|
||||||
|
sendType*: int
|
||||||
|
fromAddress*: string
|
||||||
|
toAddress*: string
|
||||||
|
fromToken*: string
|
||||||
|
toToken*: string
|
||||||
|
fromAmount*: UInt256 # total amount
|
||||||
|
toAmount*: UInt256
|
||||||
|
ownerTokenBeingSent*: bool
|
||||||
|
errorResponse*: ErrorResponse
|
||||||
|
username*: string
|
||||||
|
publicKey*: string
|
||||||
|
packId*: string
|
||||||
|
|
||||||
|
type
|
||||||
|
SigningDetails* = ref object
|
||||||
|
address*: string
|
||||||
|
addressPath*: string
|
||||||
|
keyUid*: string
|
||||||
|
signOnKeycard*: bool
|
||||||
|
hashes*: seq[string]
|
||||||
|
|
||||||
|
type
|
||||||
|
RouterTransactionsForSigningDto* = ref object
|
||||||
|
sendDetails*: SendDetailsDto
|
||||||
|
signingDetails*: SigningDetails
|
||||||
|
|
||||||
|
type
|
||||||
|
RouterSentTransaction* = ref object
|
||||||
|
fromAddress*: string
|
||||||
|
toAddress*: string
|
||||||
|
fromChain*: int
|
||||||
|
toChain*: int
|
||||||
|
fromToken*: string
|
||||||
|
toToken*: string
|
||||||
|
amount*: UInt256 # amount of the transaction
|
||||||
|
hash*: string
|
||||||
|
approvalTx*: bool
|
||||||
|
|
||||||
|
type
|
||||||
|
RouterSentTransactionsDto* = ref object
|
||||||
|
sendDetails*: SendDetailsDto
|
||||||
|
sentTransactions*: seq[RouterSentTransaction]
|
||||||
|
|
||||||
|
proc toTransactionStatusChange*(jsonObj: JsonNode): TransactionStatusChange =
|
||||||
|
result = TransactionStatusChange()
|
||||||
|
discard jsonObj.getProp("status", result.status)
|
||||||
|
discard jsonObj.getProp("hash", result.hash)
|
||||||
|
discard jsonObj.getProp("chainId", result.chainId)
|
||||||
|
|
||||||
|
proc toErrorResponse*(jsonObj: JsonNode): ErrorResponse =
|
||||||
|
result = ErrorResponse()
|
||||||
|
if jsonObj.contains("details"):
|
||||||
|
result.details = jsonObj["details"].getStr
|
||||||
|
if jsonObj.contains("code"):
|
||||||
|
result.code = jsonObj["code"].getStr
|
||||||
|
|
||||||
|
proc toSendDetailsDto*(jsonObj: JsonNode): SendDetailsDto =
|
||||||
|
result = SendDetailsDto()
|
||||||
|
discard jsonObj.getProp("uuid", result.uuid)
|
||||||
|
discard jsonObj.getProp("sendType", result.sendType)
|
||||||
|
discard jsonObj.getProp("fromAddress", result.fromAddress)
|
||||||
|
discard jsonObj.getProp("toAddress", result.toAddress)
|
||||||
|
discard jsonObj.getProp("fromToken", result.fromToken)
|
||||||
|
discard jsonObj.getProp("toToken", result.toToken)
|
||||||
|
discard jsonObj.getProp("ownerTokenBeingSent", result.ownerTokenBeingSent)
|
||||||
|
var tmpObj: JsonNode
|
||||||
|
if jsonObj.getProp("fromAmount", tmpObj):
|
||||||
|
result.fromAmount = stint.fromHex(UInt256, tmpObj.getStr)
|
||||||
|
if jsonObj.getProp("toAmount", tmpObj):
|
||||||
|
result.toAmount = stint.fromHex(UInt256, tmpObj.getStr)
|
||||||
|
if jsonObj.getProp("errorResponse", tmpObj) and tmpObj.kind == JObject:
|
||||||
|
result.errorResponse = toErrorResponse(tmpObj)
|
||||||
|
discard jsonObj.getProp("username", result.username)
|
||||||
|
discard jsonObj.getProp("publicKey", result.publicKey)
|
||||||
|
if jsonObj.getProp("packId", tmpObj):
|
||||||
|
let packId = stint.fromHex(UInt256, tmpObj.getStr)
|
||||||
|
result.packId = $packId
|
||||||
|
|
||||||
|
|
||||||
|
proc toSigningDetails*(jsonObj: JsonNode): SigningDetails =
|
||||||
|
result = SigningDetails()
|
||||||
|
discard jsonObj.getProp("address", result.address)
|
||||||
|
discard jsonObj.getProp("addressPath", result.addressPath)
|
||||||
|
discard jsonObj.getProp("keyUid", result.keyUid)
|
||||||
|
discard jsonObj.getProp("signOnKeycard", result.signOnKeycard)
|
||||||
|
var tmpObj: JsonNode
|
||||||
|
if jsonObj.getProp("hashes", tmpObj) and tmpObj.kind == JArray:
|
||||||
|
for tx in tmpObj:
|
||||||
|
result.hashes.add(tx.getStr)
|
||||||
|
|
||||||
|
proc toRouterTransactionsForSigningDto*(jsonObj: JsonNode): RouterTransactionsForSigningDto =
|
||||||
|
result = RouterTransactionsForSigningDto()
|
||||||
|
var tmpObj: JsonNode
|
||||||
|
if jsonObj.getProp("sendDetails", tmpObj) and tmpObj.kind == JObject:
|
||||||
|
result.sendDetails = toSendDetailsDto(tmpObj)
|
||||||
|
if jsonObj.getProp("signingDetails", tmpObj) and tmpObj.kind == JObject:
|
||||||
|
result.signingDetails = toSigningDetails(tmpObj)
|
||||||
|
|
||||||
|
proc toRouterSentTransaction*(jsonObj: JsonNode): RouterSentTransaction =
|
||||||
|
result = RouterSentTransaction()
|
||||||
|
discard jsonObj.getProp("fromAddress", result.fromAddress)
|
||||||
|
discard jsonObj.getProp("toAddress", result.toAddress)
|
||||||
|
discard jsonObj.getProp("fromChain", result.fromChain)
|
||||||
|
discard jsonObj.getProp("toChain", result.toChain)
|
||||||
|
discard jsonObj.getProp("fromToken", result.fromToken)
|
||||||
|
discard jsonObj.getProp("toToken", result.toToken)
|
||||||
|
discard jsonObj.getProp("hash", result.hash)
|
||||||
|
discard jsonObj.getProp("approvalTx", result.approvalTx)
|
||||||
|
var tmpObj: JsonNode
|
||||||
|
if jsonObj.getProp("amount", tmpObj):
|
||||||
|
result.amount = stint.fromHex(UInt256, tmpObj.getStr)
|
||||||
|
|
||||||
|
proc toRouterSentTransactionsDto*(jsonObj: JsonNode): RouterSentTransactionsDto =
|
||||||
|
result = RouterSentTransactionsDto()
|
||||||
|
var tmpObj: JsonNode
|
||||||
|
if jsonObj.getProp("sendDetails", tmpObj) and tmpObj.kind == JObject:
|
||||||
|
result.sendDetails = toSendDetailsDto(tmpObj)
|
||||||
|
if jsonObj.getProp("sentTransactions", tmpObj) and tmpObj.kind == JArray:
|
||||||
|
for tx in tmpObj:
|
||||||
|
result.sentTransactions.add(toRouterSentTransaction(tx))
|
|
@ -4,8 +4,8 @@ import backend/collectibles as collectibles
|
||||||
import backend/transactions as transactions
|
import backend/transactions as transactions
|
||||||
import backend/backend
|
import backend/backend
|
||||||
import backend/eth
|
import backend/eth
|
||||||
|
import backend/wallet
|
||||||
|
|
||||||
import app_service/service/ens/utils as ens_utils
|
|
||||||
import app_service/common/utils as common_utils
|
import app_service/common/utils as common_utils
|
||||||
import app_service/common/types as common_types
|
import app_service/common/types as common_types
|
||||||
|
|
||||||
|
@ -19,15 +19,14 @@ import app_service/service/wallet_account/service as wallet_account_service
|
||||||
import app_service/service/network/service as network_service
|
import app_service/service/network/service as network_service
|
||||||
import app_service/service/token/service as token_service
|
import app_service/service/token/service as token_service
|
||||||
import app_service/service/settings/service as settings_service
|
import app_service/service/settings/service as settings_service
|
||||||
import app_service/service/eth/dto/transaction as transaction_data_dto
|
|
||||||
import app_service/service/eth/dto/[coder, method_dto]
|
|
||||||
import ./dto as transaction_dto
|
import ./dto as transaction_dto
|
||||||
import ./dtoV2
|
import ./dtoV2
|
||||||
import ./dto_conversion
|
import ./dto_conversion
|
||||||
|
import ./router_transactions_dto
|
||||||
import app_service/service/eth/utils as eth_utils
|
import app_service/service/eth/utils as eth_utils
|
||||||
|
|
||||||
|
|
||||||
export transaction_dto
|
export transaction_dto, router_transactions_dto
|
||||||
export transactions.TransactionsSignatures
|
export transactions.TransactionsSignatures
|
||||||
|
|
||||||
logScope:
|
logScope:
|
||||||
|
@ -37,6 +36,8 @@ include async_tasks
|
||||||
include app_service/common/json_utils
|
include app_service/common/json_utils
|
||||||
|
|
||||||
# Signals which may be emitted by this service:
|
# Signals which may be emitted by this service:
|
||||||
|
const SIGNAL_SIGN_ROUTER_TRANSACTIONS* = "signRouterTransactions"
|
||||||
|
const SIGNAL_SENDING_TRANSACTIONS_STARTED* = "sendingTransactionsStarted"
|
||||||
const SIGNAL_TRANSACTION_SENT* = "transactionSent"
|
const SIGNAL_TRANSACTION_SENT* = "transactionSent"
|
||||||
const SIGNAL_SUGGESTED_ROUTES_READY* = "suggestedRoutesReady"
|
const SIGNAL_SUGGESTED_ROUTES_READY* = "suggestedRoutesReady"
|
||||||
const SIGNAL_HISTORY_NON_ARCHIVAL_NODE* = "historyNonArchivalNode"
|
const SIGNAL_HISTORY_NON_ARCHIVAL_NODE* = "historyNonArchivalNode"
|
||||||
|
@ -44,12 +45,7 @@ const SIGNAL_HISTORY_ERROR* = "historyError"
|
||||||
const SIGNAL_TRANSACTION_DECODED* = "transactionDecoded"
|
const SIGNAL_TRANSACTION_DECODED* = "transactionDecoded"
|
||||||
const SIGNAL_OWNER_TOKEN_SENT* = "ownerTokenSent"
|
const SIGNAL_OWNER_TOKEN_SENT* = "ownerTokenSent"
|
||||||
const SIGNAL_TRANSACTION_SENDING_COMPLETE* = "transactionSendingComplete"
|
const SIGNAL_TRANSACTION_SENDING_COMPLETE* = "transactionSendingComplete"
|
||||||
|
const SIGNAL_TRANSACTION_STATUS_CHANGED* = "transactionStatusChanged"
|
||||||
const SIMPLE_TX_BRIDGE_NAME = "Transfer"
|
|
||||||
const HOP_TX_BRIDGE_NAME = "Hop"
|
|
||||||
const ERC721_TRANSFER_NAME = "ERC721Transfer"
|
|
||||||
const ERC1155_TRANSFER_NAME = "ERC1155Transfer"
|
|
||||||
const SWAP_PARASWAP_NAME = "Paraswap"
|
|
||||||
|
|
||||||
type TokenTransferMetadata* = object
|
type TokenTransferMetadata* = object
|
||||||
tokenName*: string
|
tokenName*: string
|
||||||
|
@ -119,6 +115,10 @@ type
|
||||||
fromAmount*: string
|
fromAmount*: string
|
||||||
toTokenKey*: string
|
toTokenKey*: string
|
||||||
toAmount*: string
|
toAmount*: string
|
||||||
|
approvalTx*: bool
|
||||||
|
username*: string
|
||||||
|
publicKey*: string
|
||||||
|
packId*: string
|
||||||
|
|
||||||
type
|
type
|
||||||
OwnerTokenSentArgs* = ref object of Args
|
OwnerTokenSentArgs* = ref object of Args
|
||||||
|
@ -140,6 +140,18 @@ type
|
||||||
dataDecoded*: string
|
dataDecoded*: string
|
||||||
txHash*: string
|
txHash*: string
|
||||||
|
|
||||||
|
type
|
||||||
|
RouterTransactionsForSigningArgs* = ref object of Args
|
||||||
|
data*: RouterTransactionsForSigningDto
|
||||||
|
|
||||||
|
type
|
||||||
|
RouterTransactionsSendingStartedArgs* = ref object of Args
|
||||||
|
data*: SendDetailsDto
|
||||||
|
|
||||||
|
type
|
||||||
|
TransactionStatusArgs* = ref object of Args
|
||||||
|
data*: TransactionStatusChange
|
||||||
|
|
||||||
QtObject:
|
QtObject:
|
||||||
type Service* = ref object of QObject
|
type Service* = ref object of QObject
|
||||||
events: EventEmitter
|
events: EventEmitter
|
||||||
|
@ -151,6 +163,7 @@ QtObject:
|
||||||
|
|
||||||
## Forward declarations
|
## Forward declarations
|
||||||
proc suggestedRoutesReady(self: Service, uuid: string, route: seq[TransactionPathDtoV2], routeRaw: string, errCode: string, errDescription: string)
|
proc suggestedRoutesReady(self: Service, uuid: string, route: seq[TransactionPathDtoV2], routeRaw: string, errCode: string, errDescription: string)
|
||||||
|
proc sendTransactionsSignal(self: Service, sendDetails: SendDetailsDto, sentTransactions: seq[RouterSentTransaction] = @[])
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
@ -184,6 +197,28 @@ QtObject:
|
||||||
self.tokenService.updateTokenPrices(data.updatedPrices)
|
self.tokenService.updateTokenPrices(data.updatedPrices)
|
||||||
self.suggestedRoutesReady(data.uuid, data.bestRoute, data.bestRouteRaw, data.errorCode, data.error)
|
self.suggestedRoutesReady(data.uuid, data.bestRoute, data.bestRouteRaw, data.errorCode, data.error)
|
||||||
|
|
||||||
|
self.events.on(SignalType.WalletRouterSendingTransactionsStarted.event) do(e:Args):
|
||||||
|
var data = WalletSignal(e)
|
||||||
|
self.events.emit(SIGNAL_SENDING_TRANSACTIONS_STARTED, RouterTransactionsSendingStartedArgs(data: data.routerTransactionsSendingDetails))
|
||||||
|
# TODO: the line below is to aling with the old implementation, remove it
|
||||||
|
self.sendTransactionsSignal(data.routerTransactionsSendingDetails)
|
||||||
|
|
||||||
|
self.events.on(SignalType.WalletRouterSignTransactions.event) do(e:Args):
|
||||||
|
var data = WalletSignal(e)
|
||||||
|
if data.routerTransactionsForSigning.sendDetails.errorResponse.isNil and
|
||||||
|
not data.routerTransactionsForSigning.signingDetails.isNil:
|
||||||
|
self.events.emit(SIGNAL_SIGN_ROUTER_TRANSACTIONS, RouterTransactionsForSigningArgs(data: data.routerTransactionsForSigning))
|
||||||
|
return
|
||||||
|
self.sendTransactionsSignal(data.routerTransactionsForSigning.sendDetails)
|
||||||
|
|
||||||
|
self.events.on(SignalType.WalletRouterTransactionsSent.event) do(e:Args):
|
||||||
|
var data = WalletSignal(e)
|
||||||
|
self.sendTransactionsSignal(data.routerSentTransactions.sendDetails, data.routerSentTransactions.sentTransactions)
|
||||||
|
|
||||||
|
self.events.on(SignalType.WalletTransactionStatusChanged.event) do(e:Args):
|
||||||
|
var data = WalletSignal(e)
|
||||||
|
self.events.emit(SIGNAL_TRANSACTION_STATUS_CHANGED, TransactionStatusArgs(data: data.transactionStatusChange))
|
||||||
|
|
||||||
self.events.on(PendingTransactionTypeDto.WalletTransfer.event) do(e: Args):
|
self.events.on(PendingTransactionTypeDto.WalletTransfer.event) do(e: Args):
|
||||||
try:
|
try:
|
||||||
var receivedData = TransactionMinedArgs(e)
|
var receivedData = TransactionMinedArgs(e)
|
||||||
|
@ -287,372 +322,55 @@ QtObject:
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
proc createApprovalPath*(self: Service, route: TransactionPathDto, from_addr: string, toAddress: Address, gasFees: string): TransactionBridgeDto =
|
proc sendTransactionsSignal(self: Service, sendDetails: SendDetailsDto, sentTransactions: seq[RouterSentTransaction] = @[]) =
|
||||||
var txData = TransactionDataDto()
|
|
||||||
let approve = Approve(
|
|
||||||
to: parseAddress(route.approvalContractAddress),
|
|
||||||
value: route.approvalAmountRequired,
|
|
||||||
)
|
|
||||||
let data = ERC20_procS.toTable["approve"].encodeAbi(approve)
|
|
||||||
txData = ens_utils.buildTokenTransaction(
|
|
||||||
parseAddress(from_addr),
|
|
||||||
toAddress,
|
|
||||||
$route.gasAmount,
|
|
||||||
gasFees,
|
|
||||||
route.gasFees.eip1559Enabled,
|
|
||||||
$route.gasFees.maxPriorityFeePerGas,
|
|
||||||
$route.gasFees.maxFeePerGasM
|
|
||||||
)
|
|
||||||
txData.data = data
|
|
||||||
|
|
||||||
var path = TransactionBridgeDto(bridgeName: SIMPLE_TX_BRIDGE_NAME, chainID: route.fromNetwork.chainId)
|
|
||||||
path.transferTx = txData
|
|
||||||
return path
|
|
||||||
|
|
||||||
proc createPath*(self: Service, route: TransactionPathDto, txData: TransactionDataDto, tokenSymbol: string, to_addr: string): TransactionBridgeDto =
|
|
||||||
var path = TransactionBridgeDto(bridgeName: route.bridgeName, chainID: route.fromNetwork.chainId)
|
|
||||||
var hopTx = TransactionDataDto()
|
|
||||||
var cbridgeTx = TransactionDataDto()
|
|
||||||
var eRC721TransferTx = TransactionDataDto()
|
|
||||||
var eRC1155TransferTx = TransactionDataDto()
|
|
||||||
var swapTx = TransactionDataDto()
|
|
||||||
|
|
||||||
if(route.bridgeName == SIMPLE_TX_BRIDGE_NAME):
|
|
||||||
path.transferTx = txData
|
|
||||||
elif(route.bridgeName == HOP_TX_BRIDGE_NAME):
|
|
||||||
hopTx = txData
|
|
||||||
hopTx.chainID = route.fromNetwork.chainId.some
|
|
||||||
hopTx.chainIDTo = route.toNetwork.chainId.some
|
|
||||||
hopTx.symbol = tokenSymbol.some
|
|
||||||
hopTx.recipient = parseAddress(to_addr).some
|
|
||||||
hopTx.amount = route.amountIn.some
|
|
||||||
hopTx.bonderFee = route.txBonderFees.some
|
|
||||||
path.hopTx = hopTx
|
|
||||||
elif(route.bridgeName == ERC721_TRANSFER_NAME):
|
|
||||||
eRC721TransferTx = txData
|
|
||||||
eRC721TransferTx.chainID = route.toNetwork.chainId.some
|
|
||||||
eRC721TransferTx.recipient = parseAddress(to_addr).some
|
|
||||||
eRC721TransferTx.tokenID = stint.u256(tokenSymbol).some
|
|
||||||
path.eRC721TransferTx = eRC721TransferTx
|
|
||||||
elif(route.bridgeName == ERC1155_TRANSFER_NAME):
|
|
||||||
eRC1155TransferTx = txData
|
|
||||||
eRC1155TransferTx.chainID = route.toNetwork.chainId.some
|
|
||||||
eRC1155TransferTx.recipient = parseAddress(to_addr).some
|
|
||||||
eRC1155TransferTx.tokenID = stint.u256(tokenSymbol).some
|
|
||||||
eRC1155TransferTx.amount = route.amountIn.some
|
|
||||||
path.eRC1155TransferTx = eRC1155TransferTx
|
|
||||||
elif(route.bridgeName == SWAP_PARASWAP_NAME):
|
|
||||||
swapTx = txData
|
|
||||||
swapTx.chainID = route.fromNetwork.chainId.some
|
|
||||||
swapTx.chainIDTo = route.toNetwork.chainId.some
|
|
||||||
swapTx.tokenIdFrom = route.fromToken.symbol.some
|
|
||||||
swapTx.tokenIdTo = route.toToken.symbol.some
|
|
||||||
path.swapTx = swapTx
|
|
||||||
else:
|
|
||||||
cbridgeTx = txData
|
|
||||||
cbridgeTx.chainID = route.toNetwork.chainId.some
|
|
||||||
cbridgeTx.symbol = tokenSymbol.some
|
|
||||||
cbridgeTx.recipient = parseAddress(to_addr).some
|
|
||||||
cbridgeTx.amount = route.amountIn.some
|
|
||||||
path.cbridgeTx = cbridgeTx
|
|
||||||
return path
|
|
||||||
|
|
||||||
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
|
# 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)
|
# (there are few places where we display the toast from and link to the etherscan where the address can be seen)
|
||||||
# that's why we need to mark the addresses as shown here (safer).
|
# that's why we need to mark the addresses as shown here (safer).
|
||||||
self.events.emit(MARK_WALLET_ADDRESSES_AS_SHOWN, WalletAddressesArgs(addresses: @[fromAddr, toAddr]))
|
self.events.emit(MARK_WALLET_ADDRESSES_AS_SHOWN, WalletAddressesArgs(addresses: @[sendDetails.fromAddress, sendDetails.toAddress]))
|
||||||
|
|
||||||
if err.len > 0:
|
if not sendDetails.errorResponse.isNil and sendDetails.errorResponse.details.len > 0:
|
||||||
self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(uuid: uuid, error: err, txType: txType,
|
self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(
|
||||||
fromAddress: fromAddr, toAddress: toAddr, fromTokenKey: fromTokenKey, fromAmount: fromAmount,
|
uuid: sendDetails.uuid,
|
||||||
toTokenKey: toTokenKey, toAmount: toAmount))
|
error: sendDetails.errorResponse.details,
|
||||||
if txType == SendType.Swap:
|
txType: SendType(sendDetails.sendType),
|
||||||
singletonInstance.globalEvents.addCentralizedMetricIfEnabled("swap", $(%*{"subEvent": "tx error"}))
|
fromAddress: sendDetails.fromAddress,
|
||||||
elif response.result{"hashes"} != nil:
|
toAddress: sendDetails.toAddress,
|
||||||
for route in routes:
|
fromTokenKey: sendDetails.fromToken,
|
||||||
for hash in response.result["hashes"][$route.fromNetwork.chainID]:
|
fromAmount: sendDetails.fromAmount.toString(10),
|
||||||
if isOwnerToken:
|
toTokenKey: sendDetails.toToken,
|
||||||
self.events.emit(SIGNAL_OWNER_TOKEN_SENT, OwnerTokenSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr,
|
toAmount: sendDetails.toAmount.toString(10),
|
||||||
uuid: uuid, tokenName: tokenName, status: ContractTransactionStatus.InProgress))
|
username: sendDetails.username,
|
||||||
else:
|
publicKey: sendDetails.publicKey,
|
||||||
self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(chainId: route.fromNetwork.chainID, txHash: hash.getStr, uuid: uuid ,
|
packId: sendDetails.packId
|
||||||
error: "", txType: txType, fromAddress: fromAddr, toAddress: toAddr, fromTokenKey: fromTokenKey, fromAmount: fromAmount, toTokenKey: toTokenKey, toAmount: toAmount))
|
))
|
||||||
|
return
|
||||||
|
|
||||||
let metadata = TokenTransferMetadata(tokenName: tokenName, isOwnerToken: isOwnerToken)
|
for tx in sentTransactions:
|
||||||
self.watchTransaction(hash.getStr, fromAddr, toAddr, $PendingTransactionTypeDto.WalletTransfer, $(%metadata), route.fromNetwork.chainID,
|
if sendDetails.ownerTokenBeingSent:
|
||||||
fromTokenKey, fromAmount, toTokenKey, toAmount, txType)
|
self.events.emit(SIGNAL_OWNER_TOKEN_SENT, OwnerTokenSentArgs(
|
||||||
|
chainId: tx.fromChain,
|
||||||
if txType == SendType.Swap:
|
txHash: tx.hash,
|
||||||
singletonInstance.globalEvents.addCentralizedMetricIfEnabled("swap", $(%*{"subEvent": "tx success"}))
|
uuid: sendDetails.uuid,
|
||||||
|
tokenName: tx.fromToken,
|
||||||
proc isCollectiblesTransfer(self: Service, sendType: SendType): bool =
|
status: ContractTransactionStatus.InProgress
|
||||||
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
|
|
||||||
of SendType.Bridge:
|
|
||||||
return transactions.MultiTransactionType.MultiTransactionBridge
|
|
||||||
else:
|
|
||||||
return transactions.MultiTransactionType.MultiTransactionSend
|
|
||||||
|
|
||||||
proc transferEth(
|
|
||||||
self: Service,
|
|
||||||
from_addr: string,
|
|
||||||
to_addr: string,
|
|
||||||
tokenSymbol: string,
|
|
||||||
toTokenSymbol: string,
|
|
||||||
uuid: string,
|
|
||||||
routes: seq[TransactionPathDto],
|
|
||||||
password: string,
|
|
||||||
sendType: SendType,
|
|
||||||
slippagePercentage: Option[float]
|
|
||||||
) =
|
|
||||||
try:
|
|
||||||
var paths: seq[TransactionBridgeDto] = @[]
|
|
||||||
var totalAmountToSend: UInt256
|
|
||||||
var totalAmountToReceive: UInt256
|
|
||||||
let toAddress = parseAddress(to_addr)
|
|
||||||
|
|
||||||
for route in routes:
|
|
||||||
var txData = TransactionDataDto()
|
|
||||||
var gasFees: string = ""
|
|
||||||
|
|
||||||
if( not route.gasFees.eip1559Enabled):
|
|
||||||
gasFees = $route.gasFees.gasPrice
|
|
||||||
|
|
||||||
if route.approvalRequired:
|
|
||||||
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
|
|
||||||
if sendType == SendType.Swap:
|
|
||||||
txData.slippagePercentage = slippagePercentage
|
|
||||||
|
|
||||||
paths.add(self.createPath(route, txData, tokenSymbol, to_addr))
|
|
||||||
|
|
||||||
var mtCommand = MultiTransactionCommandDto(
|
|
||||||
fromAddress: from_addr,
|
|
||||||
toAddress: to_addr,
|
|
||||||
fromAsset: tokenSymbol,
|
|
||||||
toAsset: toTokenSymbol,
|
|
||||||
fromAmount: "0x" & totalAmountToSend.toHex,
|
|
||||||
multiTxType: sendTypeToMultiTxType(sendType),
|
|
||||||
)
|
|
||||||
|
|
||||||
if sendType == SendType.Swap:
|
|
||||||
mtCommand.toAmount = "0x" & totalAmountToReceive.toHex
|
|
||||||
singletonInstance.globalEvents.addCentralizedMetricIfEnabled("swap", $(%*{"subEvent": "send tx"}))
|
|
||||||
|
|
||||||
let response = transactions.createMultiTransaction(
|
|
||||||
mtCommand,
|
|
||||||
paths,
|
|
||||||
password,
|
|
||||||
)
|
|
||||||
|
|
||||||
if password != "":
|
|
||||||
self.sendTransactionSentSignal(sendType, from_addr, to_addr, tokenSymbol, totalAmountToSend.toString(10),
|
|
||||||
toTokenSymbol, totalAmountToReceive.toString(10), uuid, routes, response)
|
|
||||||
except Exception as e:
|
|
||||||
self.sendTransactionSentSignal(sendType, from_addr, to_addr, tokenSymbol, "",
|
|
||||||
toTokenSymbol, "", uuid, @[], RpcResponse[JsonNode](), self.extractRpcErrorMessage(e.msg))
|
|
||||||
|
|
||||||
proc mustIgnoreApprovalRequests(sendType: SendType): bool =
|
|
||||||
# Swap requires approvals to be done in advance in a separate Tx
|
|
||||||
return sendType == SendType.Swap
|
|
||||||
|
|
||||||
# in case of collectibles transfer, assetKey is used to get the contract address and token id
|
|
||||||
# in case of asset transfer, asset is valid and used to get the asset symbol and contract address
|
|
||||||
proc transferToken(
|
|
||||||
self: Service,
|
|
||||||
from_addr: string,
|
|
||||||
to_addr: string,
|
|
||||||
assetKey: string,
|
|
||||||
asset: TokenBySymbolItem,
|
|
||||||
toAssetKey: string,
|
|
||||||
toAsset: TokenBySymbolItem,
|
|
||||||
uuid: string,
|
|
||||||
routes: seq[TransactionPathDto],
|
|
||||||
password: string,
|
|
||||||
sendType: SendType,
|
|
||||||
tokenName: string,
|
|
||||||
isOwnerToken: bool,
|
|
||||||
slippagePercentage: Option[float]
|
|
||||||
) =
|
|
||||||
var
|
|
||||||
toContractAddress: Address
|
|
||||||
paths: seq[TransactionBridgeDto] = @[]
|
|
||||||
totalAmountToSend: UInt256
|
|
||||||
totalAmountToReceive: UInt256
|
|
||||||
mtCommand = MultiTransactionCommandDto(
|
|
||||||
fromAddress: from_addr,
|
|
||||||
toAddress: to_addr,
|
|
||||||
fromAsset: if not asset.isNil: asset.symbol else: assetKey,
|
|
||||||
toAsset: if not toAsset.isNil: toAsset.symbol else: toAssetKey,
|
|
||||||
multiTxType: sendTypeToMultiTxType(sendType),
|
|
||||||
)
|
|
||||||
|
|
||||||
# if collectibles transfer ...
|
|
||||||
if asset.isNil:
|
|
||||||
let contract_tokenId = assetKey.split(":")
|
|
||||||
if contract_tokenId.len == 2:
|
|
||||||
toContractAddress = parseAddress(contract_tokenId[0])
|
|
||||||
mtCommand.fromAsset = contract_tokenId[1]
|
|
||||||
mtCommand.toAsset = contract_tokenId[1]
|
|
||||||
else:
|
else:
|
||||||
error "Invalid assetKey for collectibles transfer", assetKey=assetKey
|
self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(
|
||||||
return
|
chainId: tx.fromChain,
|
||||||
|
txHash: tx.hash,
|
||||||
try:
|
uuid: sendDetails.uuid,
|
||||||
for route in routes:
|
txType: SendType(sendDetails.sendType),
|
||||||
var txData = TransactionDataDto()
|
fromAddress: tx.fromAddress,
|
||||||
var gasFees: string = ""
|
toAddress: tx.toAddress,
|
||||||
|
fromTokenKey: tx.fromToken,
|
||||||
# If not collectible ...
|
fromAmount: tx.amount.toString(10),
|
||||||
if not asset.isNil:
|
toTokenKey: tx.toToken,
|
||||||
var foundAddress = false
|
toAmount: tx.amount.toString(10),
|
||||||
for addressPerChain in asset.addressPerChainId:
|
approvalTx: tx.approvalTx,
|
||||||
if addressPerChain.chainId == route.fromNetwork.chainId:
|
username: sendDetails.username,
|
||||||
toContractAddress = parseAddress(addressPerChain.address)
|
publicKey: sendDetails.publicKey,
|
||||||
foundAddress = true
|
packId: sendDetails.packId
|
||||||
break
|
))
|
||||||
if not foundAddress:
|
|
||||||
error "Contract address not found for asset", assetKey=assetKey
|
|
||||||
return
|
|
||||||
|
|
||||||
if not route.gasFees.eip1559Enabled:
|
|
||||||
gasFees = $route.gasFees.gasPrice
|
|
||||||
|
|
||||||
if route.approvalRequired and not mustIgnoreApprovalRequests(sendType):
|
|
||||||
let approvalPath = self.createApprovalPath(route, mtCommand.fromAddress, toContractAddress, gasFees)
|
|
||||||
paths.add(approvalPath)
|
|
||||||
|
|
||||||
totalAmountToSend += route.amountIn
|
|
||||||
totalAmountToReceive += route.amountOut
|
|
||||||
|
|
||||||
if sendType == SendType.Approve:
|
|
||||||
# We only do the approvals
|
|
||||||
continue
|
|
||||||
|
|
||||||
let transfer = Transfer(
|
|
||||||
to: parseAddress(mtCommand.toAddress),
|
|
||||||
value: route.amountIn,
|
|
||||||
)
|
|
||||||
let data = ERC20_procS.toTable["transfer"].encodeAbi(transfer)
|
|
||||||
|
|
||||||
txData = ens_utils.buildTokenTransaction(
|
|
||||||
parseAddress(mtCommand.fromAddress),
|
|
||||||
toContractAddress,
|
|
||||||
$route.gasAmount,
|
|
||||||
gasFees,
|
|
||||||
route.gasFees.eip1559Enabled,
|
|
||||||
$route.gasFees.maxPriorityFeePerGas,
|
|
||||||
$route.gasFees.maxFeePerGasM
|
|
||||||
)
|
|
||||||
txData.data = data
|
|
||||||
if sendType == SendType.Swap:
|
|
||||||
txData.slippagePercentage = slippagePercentage
|
|
||||||
|
|
||||||
let path = self.createPath(route, txData, mtCommand.toAsset, mtCommand.toAddress)
|
|
||||||
paths.add(path)
|
|
||||||
|
|
||||||
mtCommand.fromAmount = "0x" & totalAmountToSend.toHex
|
|
||||||
if sendType == SendType.Swap:
|
|
||||||
mtCommand.toAmount = "0x" & totalAmountToReceive.toHex
|
|
||||||
singletonInstance.globalEvents.addCentralizedMetricIfEnabled("swap", $(%*{"subEvent": "send tx"}))
|
|
||||||
|
|
||||||
let response = transactions.createMultiTransaction(mtCommand, paths, password)
|
|
||||||
|
|
||||||
if password != "":
|
|
||||||
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(sendType, mtCommand.fromAddress, mtCommand.toAddress,
|
|
||||||
assetKey, "", toAssetKey, "",
|
|
||||||
uuid, @[], RpcResponse[JsonNode](), self.extractRpcErrorMessage(e.msg))
|
|
||||||
|
|
||||||
proc transfer*(
|
|
||||||
self: Service,
|
|
||||||
fromAddr: string,
|
|
||||||
toAddr: string,
|
|
||||||
assetKey: string,
|
|
||||||
toAssetKey: string,
|
|
||||||
uuid: string,
|
|
||||||
selectedRoutes: seq[TransactionPathDto],
|
|
||||||
password: string,
|
|
||||||
sendType: SendType,
|
|
||||||
usePassword: bool,
|
|
||||||
doHashing: bool,
|
|
||||||
tokenName: string,
|
|
||||||
isOwnerToken: bool,
|
|
||||||
slippagePercentage: Option[float]
|
|
||||||
) =
|
|
||||||
var finalPassword = ""
|
|
||||||
if usePassword:
|
|
||||||
finalPassword = password
|
|
||||||
if doHashing:
|
|
||||||
finalPassword = common_utils.hashPassword(password)
|
|
||||||
try:
|
|
||||||
var chainID = 0
|
|
||||||
|
|
||||||
if(selectedRoutes.len > 0):
|
|
||||||
chainID = selectedRoutes[0].fromNetwork.chainID
|
|
||||||
|
|
||||||
# asset == nil means transferToken is executed for a collectibles transfer
|
|
||||||
var
|
|
||||||
asset: TokenBySymbolItem
|
|
||||||
toAsset: TokenBySymbolItem
|
|
||||||
if not self.isCollectiblesTransfer(sendType):
|
|
||||||
asset = self.tokenService.getTokenBySymbolByTokensKey(assetKey)
|
|
||||||
if asset.isNil:
|
|
||||||
error "Asset not found for", assetKey=assetKey
|
|
||||||
return
|
|
||||||
|
|
||||||
toAsset = asset
|
|
||||||
if sendType == Swap:
|
|
||||||
toAsset = self.tokenService.getTokenBySymbolByTokensKey(toAssetKey)
|
|
||||||
if toAsset.isNil:
|
|
||||||
error "Asset not found for", assetKey=assetKey
|
|
||||||
return
|
|
||||||
|
|
||||||
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, slippagePercentage)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.transferToken(fromAddr, toAddr, assetKey, asset, toAssetKey, toAsset, uuid, selectedRoutes, finalPassword,
|
|
||||||
sendType, tokenName, isOwnerToken, slippagePercentage)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.sendTransactionSentSignal(sendType, fromAddr, toAddr, assetKey, "", toAssetKey, "", uuid, @[], RpcResponse[JsonNode](), self.extractRpcErrorMessage(e.msg))
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
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(sendType, fromAddr, toAddr, fromTokenKey, "", toTokenKey, "",
|
|
||||||
uuid, @[], RpcResponse[JsonNode](), fmt"Error proceeding with transactions signatures: {e.msg}")
|
|
||||||
|
|
||||||
proc suggestedFees*(self: Service, chainId: int): SuggestedFeesDto =
|
proc suggestedFees*(self: Service, chainId: int): SuggestedFeesDto =
|
||||||
try:
|
try:
|
||||||
|
@ -688,6 +406,7 @@ QtObject:
|
||||||
accountFrom: string,
|
accountFrom: string,
|
||||||
accountTo: string,
|
accountTo: string,
|
||||||
token: string,
|
token: string,
|
||||||
|
tokenIsOwnerToken: bool,
|
||||||
amountIn: string,
|
amountIn: string,
|
||||||
toToken: string = "",
|
toToken: string = "",
|
||||||
amountOut: string = "",
|
amountOut: string = "",
|
||||||
|
@ -706,7 +425,7 @@ QtObject:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
let res = eth.suggestedRoutesAsync(uuid, ord(sendType), accountFrom, accountTo, amountInHex, amountOutHex, token,
|
let res = eth.suggestedRoutesAsync(uuid, ord(sendType), accountFrom, accountTo, amountInHex, amountOutHex, token,
|
||||||
toToken, disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
tokenIsOwnerToken, toToken, disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
except CatchableError as e:
|
except CatchableError as e:
|
||||||
error "suggestedRoutes", exception=e.msg
|
error "suggestedRoutes", exception=e.msg
|
||||||
|
|
||||||
|
@ -747,3 +466,38 @@ proc getMultiTransactions*(transactionIDs: seq[int]): seq[MultiTransactionDto] =
|
||||||
let errDescription = e.msg
|
let errDescription = e.msg
|
||||||
error "error: ", errDescription
|
error "error: ", errDescription
|
||||||
return
|
return
|
||||||
|
|
||||||
|
proc signMessage*(self: Service, address: string, hashedPassword: string, hashedMessage: string): tuple[res: string, err: string] =
|
||||||
|
var signMsgRes: JsonNode
|
||||||
|
let err = wallet.signMessage(signMsgRes,
|
||||||
|
hashedMessage,
|
||||||
|
address,
|
||||||
|
hashedPassword)
|
||||||
|
if err.len > 0:
|
||||||
|
error "status-go - wallet_signMessage failed", err=err
|
||||||
|
result.err = err
|
||||||
|
return
|
||||||
|
result.res = signMsgRes.getStr
|
||||||
|
return
|
||||||
|
|
||||||
|
proc buildTransactionsFromRoute*(self: Service, uuid: string, slippagePercentage: float): string =
|
||||||
|
var response: JsonNode
|
||||||
|
let err = transactions.buildTransactionsFromRoute(response, uuid, slippagePercentage)
|
||||||
|
if err.len > 0:
|
||||||
|
error "status-go - transfer failed", err=err
|
||||||
|
return err
|
||||||
|
if response.kind != JNull:
|
||||||
|
error "unexpected transfer response"
|
||||||
|
return "unexpected transfer response"
|
||||||
|
return ""
|
||||||
|
|
||||||
|
proc sendRouterTransactionsWithSignatures*(self: Service, uuid: string, signatures: TransactionsSignatures): string =
|
||||||
|
var response: JsonNode
|
||||||
|
let err = transactions.sendRouterTransactionsWithSignatures(response, uuid, signatures)
|
||||||
|
if err.len > 0:
|
||||||
|
error "status-go - wallet_sendRouterTransactionsWithSignatures failed", err=err
|
||||||
|
return err
|
||||||
|
if response.kind != JNull:
|
||||||
|
error "unexpected sending transactions response"
|
||||||
|
return "unexpected sending transactions response"
|
||||||
|
return ""
|
||||||
|
|
|
@ -138,15 +138,8 @@ QtObject:
|
||||||
return ""
|
return ""
|
||||||
return hashRes.result.getStr()
|
return hashRes.result.getStr()
|
||||||
|
|
||||||
proc signMessage*(self: Service, address: string, hashedPassword: string, hashedMessage: string): string =
|
proc signMessage*(self: Service, address: string, hashedPassword: string, hashedMessage: string): tuple[res: string, err: string] =
|
||||||
var signMsgRes: JsonNode
|
return self.transactions.signMessage(address, hashedPassword, hashedMessage)
|
||||||
let err = wallet.signMessage(signMsgRes,
|
|
||||||
hashedMessage,
|
|
||||||
address,
|
|
||||||
hashedPassword)
|
|
||||||
if err.len > 0:
|
|
||||||
error "status-go - wallet_signMessage failed", err=err
|
|
||||||
return signMsgRes.getStr
|
|
||||||
|
|
||||||
proc buildTransaction*(self: Service, chainId: int, txJson: string): tuple[txToSign: string, txData: JsonNode] =
|
proc buildTransaction*(self: Service, chainId: int, txJson: string): tuple[txToSign: string, txData: JsonNode] =
|
||||||
var buildTxResponse: JsonNode
|
var buildTxResponse: JsonNode
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import json
|
||||||
|
import response_type
|
||||||
|
|
||||||
|
const NO_RESULT* = "no result"
|
||||||
|
|
||||||
|
proc isErrorResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
||||||
|
if not rpcResponse.error.isNil:
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
proc prepareResponse(resultOut: var JsonNode, rpcResponse: RpcResponse[JsonNode]): string =
|
||||||
|
if isErrorResponse(rpcResponse):
|
||||||
|
return rpcResponse.error.message
|
||||||
|
if rpcResponse.result.isNil:
|
||||||
|
return NO_RESULT
|
||||||
|
resultOut = rpcResponse.result
|
|
@ -39,7 +39,7 @@ proc suggestedFees*(chainId: int): RpcResponse[JsonNode] =
|
||||||
return core.callPrivateRPC("wallet_getSuggestedFees", payload)
|
return core.callPrivateRPC("wallet_getSuggestedFees", payload)
|
||||||
|
|
||||||
proc prepareDataForSuggestedRoutes(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string,
|
proc prepareDataForSuggestedRoutes(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string,
|
||||||
token: string, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
token: string, tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
extraParamsTable: Table[string, string]): JsonNode =
|
extraParamsTable: Table[string, string]): JsonNode =
|
||||||
|
|
||||||
let data = %* {
|
let data = %* {
|
||||||
|
@ -50,6 +50,7 @@ proc prepareDataForSuggestedRoutes(uuid: string, sendType: int, accountFrom: str
|
||||||
"amountIn": amountIn,
|
"amountIn": amountIn,
|
||||||
"amountOut": amountOut,
|
"amountOut": amountOut,
|
||||||
"tokenID": token,
|
"tokenID": token,
|
||||||
|
"tokenIDIsOwnerToken": tokenIsOwnerToken,
|
||||||
"toTokenID": toToken,
|
"toTokenID": toToken,
|
||||||
"disabledFromChainIDs": disabledFromChainIDs,
|
"disabledFromChainIDs": disabledFromChainIDs,
|
||||||
"disabledToChainIDs": disabledToChainIDs,
|
"disabledToChainIDs": disabledToChainIDs,
|
||||||
|
@ -69,19 +70,19 @@ proc prepareDataForSuggestedRoutes(uuid: string, sendType: int, accountFrom: str
|
||||||
return %* [data]
|
return %* [data]
|
||||||
|
|
||||||
proc suggestedRoutes*(sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
proc suggestedRoutes*(sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
||||||
toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
||||||
let payload = prepareDataForSuggestedRoutes(uuid = "", sendType, accountFrom, accountTo, amountIn, amountOut, token, toToken, disabledFromChainIDs,
|
let payload = prepareDataForSuggestedRoutes(uuid = "", sendType, accountFrom, accountTo, amountIn, amountOut, token, tokenIsOwnerToken, toToken,
|
||||||
disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
if payload.isNil:
|
if payload.isNil:
|
||||||
raise newException(RpcException, "Invalid key in extraParamsTable")
|
raise newException(RpcException, "Invalid key in extraParamsTable")
|
||||||
return core.callPrivateRPC("wallet_getSuggestedRoutes", payload)
|
return core.callPrivateRPC("wallet_getSuggestedRoutes", payload)
|
||||||
|
|
||||||
proc suggestedRoutesAsync*(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
proc suggestedRoutesAsync*(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
||||||
toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
tokenIsOwnerToken: bool, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
||||||
let payload = prepareDataForSuggestedRoutes(uuid, sendType, accountFrom, accountTo, amountIn, amountOut, token, toToken, disabledFromChainIDs,
|
let payload = prepareDataForSuggestedRoutes(uuid, sendType, accountFrom, accountTo, amountIn, amountOut, token, tokenIsOwnerToken, toToken,
|
||||||
disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
if payload.isNil:
|
if payload.isNil:
|
||||||
raise newException(RpcException, "Invalid key in extraParamsTable")
|
raise newException(RpcException, "Invalid key in extraParamsTable")
|
||||||
return core.callPrivateRPC("wallet_getSuggestedRoutesAsync", payload)
|
return core.callPrivateRPC("wallet_getSuggestedRoutesAsync", payload)
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import Tables, json, stint, json_serialization, stew/shims/strformat
|
import Tables, json, stint, json_serialization, stew/shims/strformat, logging
|
||||||
|
|
||||||
import ../app_service/service/eth/dto/transaction
|
|
||||||
import ./core as core
|
import ./core as core
|
||||||
|
|
||||||
|
include common
|
||||||
|
|
||||||
type
|
type
|
||||||
TransactionsSignatures* = Table[string, tuple[r: string, s: string, v: string]]
|
TransactionsSignatures* = Table[string, tuple[r: string, s: string, v: string]]
|
||||||
|
|
||||||
|
@ -82,18 +83,6 @@ proc getTransfersByAddress*(chainId: int, address: string, toBlock: Uint256, lim
|
||||||
proc getTransactionReceipt*(chainId: int, transactionHash: string): RpcResponse[JsonNode] =
|
proc getTransactionReceipt*(chainId: int, transactionHash: string): RpcResponse[JsonNode] =
|
||||||
core.callPrivateRPCWithChainId("eth_getTransactionReceipt", chainId, %* [transactionHash])
|
core.callPrivateRPCWithChainId("eth_getTransactionReceipt", chainId, %* [transactionHash])
|
||||||
|
|
||||||
proc createMultiTransaction*(multiTransactionCommand: MultiTransactionCommandDto, data: seq[TransactionBridgeDto], password: string): RpcResponse[JsonNode] =
|
|
||||||
let payload = %* [multiTransactionCommand, data, password]
|
|
||||||
result = core.callPrivateRPC("wallet_createMultiTransaction", payload)
|
|
||||||
|
|
||||||
proc proceedWithTransactionsSignatures*(signatures: TransactionsSignatures): RpcResponse[JsonNode] =
|
|
||||||
var data = %* {}
|
|
||||||
for key, value in signatures:
|
|
||||||
data[key] = %* { "r": value.r, "s": value.s, "v": value.v }
|
|
||||||
|
|
||||||
var payload = %* [data]
|
|
||||||
result = core.callPrivateRPC("wallet_proceedWithTransactionsSignatures", payload)
|
|
||||||
|
|
||||||
proc getMultiTransactions*(transactionIDs: seq[int]): RpcResponse[JsonNode] =
|
proc getMultiTransactions*(transactionIDs: seq[int]): RpcResponse[JsonNode] =
|
||||||
let payload = %* [transactionIDs]
|
let payload = %* [transactionIDs]
|
||||||
result = core.callPrivateRPC("wallet_getMultiTransactions", payload)
|
result = core.callPrivateRPC("wallet_getMultiTransactions", payload)
|
||||||
|
@ -101,3 +90,31 @@ proc getMultiTransactions*(transactionIDs: seq[int]): RpcResponse[JsonNode] =
|
||||||
proc watchTransaction*(chainId: int, hash: string): RpcResponse[JsonNode] =
|
proc watchTransaction*(chainId: int, hash: string): RpcResponse[JsonNode] =
|
||||||
let payload = %* [chainId, hash]
|
let payload = %* [chainId, hash]
|
||||||
core.callPrivateRPC("wallet_watchTransactionByChainID", payload)
|
core.callPrivateRPC("wallet_watchTransactionByChainID", payload)
|
||||||
|
|
||||||
|
proc buildTransactionsFromRoute*(resultOut: var JsonNode, uuid: string, slippagePercentage: float): string =
|
||||||
|
try:
|
||||||
|
let payload = %* [{
|
||||||
|
"uuid": uuid,
|
||||||
|
"slippagePercentage": slippagePercentage
|
||||||
|
}]
|
||||||
|
let response = core.callPrivateRPC("wallet_buildTransactionsFromRoute", payload)
|
||||||
|
return prepareResponse(resultOut, response)
|
||||||
|
except Exception as e:
|
||||||
|
warn e.msg
|
||||||
|
return e.msg
|
||||||
|
|
||||||
|
proc sendRouterTransactionsWithSignatures*(resultOut: var JsonNode, uuid: string, signatures: TransactionsSignatures): string =
|
||||||
|
try:
|
||||||
|
var jsonSignatures = %* {}
|
||||||
|
for key, value in signatures:
|
||||||
|
jsonSignatures[key] = %* { "r": value.r, "s": value.s, "v": value.v }
|
||||||
|
|
||||||
|
var payload = %* [{
|
||||||
|
"uuid": uuid,
|
||||||
|
"signatures": jsonSignatures
|
||||||
|
}]
|
||||||
|
let response = core.callPrivateRPC("wallet_sendRouterTransactionsWithSignatures", payload)
|
||||||
|
return prepareResponse(resultOut, response)
|
||||||
|
except Exception as e:
|
||||||
|
warn e.msg
|
||||||
|
return e.msg
|
|
@ -4,6 +4,8 @@ from ./gen import rpc
|
||||||
|
|
||||||
import status_go
|
import status_go
|
||||||
|
|
||||||
|
include common
|
||||||
|
|
||||||
rpc(signMessage, "wallet"):
|
rpc(signMessage, "wallet"):
|
||||||
message: string
|
message: string
|
||||||
address: string
|
address: string
|
||||||
|
@ -24,17 +26,6 @@ rpc(sendTransactionWithSignature, "wallet"):
|
||||||
sendTxArgsJson: string
|
sendTxArgsJson: string
|
||||||
signature: string
|
signature: string
|
||||||
|
|
||||||
proc isErrorResponse(rpcResponse: RpcResponse[JsonNode]): bool =
|
|
||||||
if not rpcResponse.error.isNil:
|
|
||||||
return true
|
|
||||||
return false
|
|
||||||
|
|
||||||
proc prepareResponse(resultOut: var JsonNode, rpcResponse: RpcResponse[JsonNode]): string =
|
|
||||||
if isErrorResponse(rpcResponse):
|
|
||||||
return rpcResponse.error.message
|
|
||||||
if rpcResponse.result.isNil:
|
|
||||||
return "no result"
|
|
||||||
resultOut = rpcResponse.result
|
|
||||||
|
|
||||||
## Signs the provided message with the provided account using the provided hashed password, performs `crypto.Sign`
|
## Signs the provided message with the provided account using the provided hashed password, performs `crypto.Sign`
|
||||||
## `resultOut` represents a json object that contains the signature if the call was successful, or `nil`
|
## `resultOut` represents a json object that contains the signature if the call was successful, or `nil`
|
||||||
|
|
|
@ -71,7 +71,7 @@ SplitView {
|
||||||
readonly property bool areTestNetworksEnabled: true
|
readonly property bool areTestNetworksEnabled: true
|
||||||
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
||||||
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
||||||
signal transactionSendingComplete(var txHash, var success)
|
signal transactionSendingComplete(var txHash, var status)
|
||||||
}
|
}
|
||||||
walletAssetsStore: WalletAssetsStore {
|
walletAssetsStore: WalletAssetsStore {
|
||||||
id: thisWalletAssetStore
|
id: thisWalletAssetStore
|
||||||
|
|
|
@ -75,7 +75,7 @@ SplitView {
|
||||||
id: dSwapStore
|
id: dSwapStore
|
||||||
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
||||||
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
||||||
signal transactionSendingComplete(var txHash, var success)
|
signal transactionSendingComplete(var txHash, var status)
|
||||||
|
|
||||||
readonly property var accounts: WalletAccountsModel {}
|
readonly property var accounts: WalletAccountsModel {}
|
||||||
readonly property var flatNetworks: NetworksModel.flatNetworks
|
readonly property var flatNetworks: NetworksModel.flatNetworks
|
||||||
|
@ -312,7 +312,7 @@ SplitView {
|
||||||
dSwapStore.transactionSent(networksComboBox.currentValue, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", d.uuid, "")
|
dSwapStore.transactionSent(networksComboBox.currentValue, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", d.uuid, "")
|
||||||
})()
|
})()
|
||||||
Backpressure.debounce(this, 2000, () => {
|
Backpressure.debounce(this, 2000, () => {
|
||||||
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", true)
|
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Success")
|
||||||
})()
|
})()
|
||||||
fetchSuggestedRoutesSpy.wait()
|
fetchSuggestedRoutesSpy.wait()
|
||||||
Backpressure.debounce(this, 1000, () => {
|
Backpressure.debounce(this, 1000, () => {
|
||||||
|
@ -352,7 +352,7 @@ SplitView {
|
||||||
dSwapStore.transactionSent(networksComboBox.currentValue, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", d.uuid, "")
|
dSwapStore.transactionSent(networksComboBox.currentValue, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", d.uuid, "")
|
||||||
})()
|
})()
|
||||||
Backpressure.debounce(this, 2000, () => {
|
Backpressure.debounce(this, 2000, () => {
|
||||||
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", false)
|
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Failed")
|
||||||
})()
|
})()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +433,7 @@ SplitView {
|
||||||
Button {
|
Button {
|
||||||
text: "emit approval completed successfully"
|
text: "emit approval completed successfully"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", true)
|
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Success")
|
||||||
}
|
}
|
||||||
visible: advancedSignalsCheckBox.checked
|
visible: advancedSignalsCheckBox.checked
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ SplitView {
|
||||||
Button {
|
Button {
|
||||||
text: "emit approval completed with failure"
|
text: "emit approval completed with failure"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", false)
|
dSwapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Failed")
|
||||||
}
|
}
|
||||||
visible: advancedSignalsCheckBox.checked
|
visible: advancedSignalsCheckBox.checked
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ Item {
|
||||||
readonly property var swapStore: SwapStore {
|
readonly property var swapStore: SwapStore {
|
||||||
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
||||||
signal transactionSent(var chainId,var txHash, var uuid, var error)
|
signal transactionSent(var chainId,var txHash, var uuid, var error)
|
||||||
signal transactionSendingComplete(var txHash, var success)
|
signal transactionSendingComplete(var txHash, var status)
|
||||||
|
|
||||||
readonly property var accounts: WalletAccountsModel {}
|
readonly property var accounts: WalletAccountsModel {}
|
||||||
readonly property var flatNetworks: NetworksModel.flatNetworks
|
readonly property var flatNetworks: NetworksModel.flatNetworks
|
||||||
|
@ -1548,7 +1548,7 @@ Item {
|
||||||
root.swapAdaptor.currencyStore.currentCurrency))
|
root.swapAdaptor.currencyStore.currentCurrency))
|
||||||
|
|
||||||
// simulate user click on approve button and approval failed
|
// simulate user click on approve button and approval failed
|
||||||
root.swapStore.transactionSent(root.swapFormData.selectedNetworkChainId, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", root.swapAdaptor.uuid, "")
|
root.swapStore.transactionSent(root.swapAdaptor.uuid, root.swapFormData.selectedNetworkChainId, true, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "")
|
||||||
|
|
||||||
verify(root.swapAdaptor.approvalPending)
|
verify(root.swapAdaptor.approvalPending)
|
||||||
verify(!root.swapAdaptor.approvalSuccessful)
|
verify(!root.swapAdaptor.approvalSuccessful)
|
||||||
|
@ -1562,7 +1562,7 @@ Item {
|
||||||
root.swapAdaptor.currencyStore.currentCurrency))
|
root.swapAdaptor.currencyStore.currentCurrency))
|
||||||
|
|
||||||
// simulate approval tx was unsuccessful
|
// simulate approval tx was unsuccessful
|
||||||
root.swapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", false)
|
root.swapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Failed")
|
||||||
|
|
||||||
verify(!root.swapAdaptor.approvalPending)
|
verify(!root.swapAdaptor.approvalPending)
|
||||||
verify(!root.swapAdaptor.approvalSuccessful)
|
verify(!root.swapAdaptor.approvalSuccessful)
|
||||||
|
@ -1577,7 +1577,7 @@ Item {
|
||||||
|
|
||||||
// simulate user click on approve button and successful approval tx made
|
// simulate user click on approve button and successful approval tx made
|
||||||
signButton.clicked()
|
signButton.clicked()
|
||||||
root.swapStore.transactionSent(root.swapFormData.selectedNetworkChainId, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", root.swapAdaptor.uuid, "")
|
root.swapStore.transactionSent(root.swapAdaptor.uuid, root.swapFormData.selectedNetworkChainId, true, "0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "")
|
||||||
|
|
||||||
verify(root.swapAdaptor.approvalPending)
|
verify(root.swapAdaptor.approvalPending)
|
||||||
verify(!root.swapAdaptor.approvalSuccessful)
|
verify(!root.swapAdaptor.approvalSuccessful)
|
||||||
|
@ -1590,30 +1590,29 @@ Item {
|
||||||
root.swapAdaptor.swapOutputData.totalFees,
|
root.swapAdaptor.swapOutputData.totalFees,
|
||||||
root.swapAdaptor.currencyStore.currentCurrency))
|
root.swapAdaptor.currencyStore.currentCurrency))
|
||||||
|
|
||||||
|
root.swapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Success")
|
||||||
|
|
||||||
// simulate approval tx was successful
|
// simulate approval tx was successful
|
||||||
signButton.clicked()
|
signButton.clicked()
|
||||||
root.swapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", true)
|
|
||||||
|
|
||||||
// check if fetchSuggestedRoutes called
|
root.swapStore.transactionSendingComplete("0x877ffe47fc29340312611d4e833ab189fe4f4152b01cc9a05bb4125b81b2a89a", "Success")
|
||||||
fetchSuggestedRoutesCalled.wait()
|
|
||||||
|
|
||||||
// verify loading state was set and no errors currently
|
|
||||||
verifyLoadingAndNoErrorsState(payPanel, receivePanel)
|
|
||||||
|
|
||||||
verify(!root.swapAdaptor.approvalPending)
|
verify(!root.swapAdaptor.approvalPending)
|
||||||
verify(!root.swapAdaptor.approvalSuccessful)
|
verify(root.swapAdaptor.approvalSuccessful)
|
||||||
verify(!errorTag.visible)
|
verify(!errorTag.visible)
|
||||||
verify(!signButton.interactive)
|
verify(signButton.interactive)
|
||||||
verify(!signButton.loadingWithText)
|
verify(!signButton.loadingWithText)
|
||||||
compare(signButton.text, qsTr("Swap"))
|
compare(signButton.text, qsTr("Swap"))
|
||||||
compare(maxFeesValue.text, Constants.dummyText)
|
compare(maxFeesValue.text, root.swapAdaptor.currencyStore.formatCurrencyAmount(
|
||||||
|
root.swapAdaptor.swapOutputData.totalFees,
|
||||||
|
root.swapAdaptor.currencyStore.currentCurrency))
|
||||||
|
|
||||||
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
|
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
|
||||||
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
|
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
|
||||||
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval, "", "")
|
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval, "", "")
|
||||||
|
|
||||||
verify(!root.swapAdaptor.approvalPending)
|
verify(!root.swapAdaptor.approvalPending)
|
||||||
verify(!root.swapAdaptor.approvalSuccessful)
|
verify(root.swapAdaptor.approvalSuccessful)
|
||||||
verify(!errorTag.visible)
|
verify(!errorTag.visible)
|
||||||
verify(signButton.enabled)
|
verify(signButton.enabled)
|
||||||
verify(!signButton.loadingWithText)
|
verify(!signButton.loadingWithText)
|
||||||
|
@ -1784,9 +1783,6 @@ Item {
|
||||||
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
|
let txHasRouteNoApproval = root.dummySwapTransactionRoutes.txHasRouteNoApproval
|
||||||
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
|
txHasRouteNoApproval.uuid = root.swapAdaptor.uuid
|
||||||
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval, "", "")
|
root.swapStore.suggestedRoutesReady(txHasRouteNoApproval, "", "")
|
||||||
|
|
||||||
// check if fetch occurs automatically after 15 seconds
|
|
||||||
fetchSuggestedRoutesCalled.wait()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_deleteing_input_characters_data() {
|
function test_deleteing_input_characters_data() {
|
||||||
|
@ -1833,38 +1829,38 @@ Item {
|
||||||
root.swapFormData.autoRefreshTime = 1200
|
root.swapFormData.autoRefreshTime = 1200
|
||||||
|
|
||||||
// Launch popup
|
// Launch popup
|
||||||
launchAndVerfyModal()
|
// launchAndVerfyModal()
|
||||||
|
|
||||||
// check if fetchSuggestedRoutes called
|
// // check if fetchSuggestedRoutes called
|
||||||
tryCompare(fetchSuggestedRoutesCalled, "count", 1)
|
// tryCompare(fetchSuggestedRoutesCalled, "count", 1)
|
||||||
|
|
||||||
// no new calls to fetch new proposal should be made as the proposal is still loading
|
// no new calls to fetch new proposal should be made as the proposal is still loading
|
||||||
wait(root.swapFormData.autoRefreshTime*2)
|
// wait(root.swapFormData.autoRefreshTime*2)
|
||||||
compare(fetchSuggestedRoutesCalled.count, 1)
|
// compare(fetchSuggestedRoutesCalled.count, 1)
|
||||||
|
|
||||||
// emit routes ready
|
// // emit routes ready
|
||||||
let txHasRouteApproval = root.dummySwapTransactionRoutes.txHasRoutesApprovalNeeded
|
// let txHasRouteApproval = root.dummySwapTransactionRoutes.txHasRoutesApprovalNeeded
|
||||||
txHasRouteApproval.uuid = root.swapAdaptor.uuid
|
// txHasRouteApproval.uuid = root.swapAdaptor.uuid
|
||||||
root.swapStore.suggestedRoutesReady(txHasRouteApproval, "", "")
|
// root.swapStore.suggestedRoutesReady(txHasRouteApproval, "", "")
|
||||||
|
|
||||||
// now refresh can occur as no propsal or signing is pending
|
// // now refresh can occur as no propsal or signing is pending
|
||||||
tryCompare(fetchSuggestedRoutesCalled, "count", 2)
|
// tryCompare(fetchSuggestedRoutesCalled, "count", 2)
|
||||||
|
|
||||||
// emit routes ready
|
// // emit routes ready
|
||||||
txHasRouteApproval.uuid = root.swapAdaptor.uuid
|
// txHasRouteApproval.uuid = root.swapAdaptor.uuid
|
||||||
root.swapStore.suggestedRoutesReady(txHasRouteApproval, "", "")
|
// root.swapStore.suggestedRoutesReady(txHasRouteApproval, "", "")
|
||||||
|
|
||||||
verify(root.swapAdaptor.swapOutputData.approvalNeeded)
|
// verify(root.swapAdaptor.swapOutputData.approvalNeeded)
|
||||||
verify(!root.swapAdaptor.approvalPending)
|
// verify(!root.swapAdaptor.approvalPending)
|
||||||
|
|
||||||
// sign approval and check that auto refresh doesnt occur
|
// // sign approval and check that auto refresh doesnt occur
|
||||||
root.swapAdaptor.sendApproveTx()
|
// root.swapAdaptor.sendApproveTx()
|
||||||
|
|
||||||
// no new calls to fetch new proposal should be made as the approval is pending
|
// // no new calls to fetch new proposal should be made as the approval is pending
|
||||||
verify(root.swapAdaptor.swapOutputData.approvalNeeded)
|
// verify(root.swapAdaptor.swapOutputData.approvalNeeded)
|
||||||
verify(root.swapAdaptor.approvalPending)
|
// verify(root.swapAdaptor.approvalPending)
|
||||||
wait(root.swapFormData.autoRefreshTime*2)
|
// wait(root.swapFormData.autoRefreshTime*2)
|
||||||
compare(fetchSuggestedRoutesCalled.count, 2)
|
// compare(fetchSuggestedRoutesCalled.count, 2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,17 +39,6 @@ StatusDialog {
|
||||||
root.swapAdaptor.fetchSuggestedRoutes(payPanel.rawValue)
|
root.swapAdaptor.fetchSuggestedRoutes(payPanel.rawValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
property Timer autoRefreshTimer: Timer {
|
|
||||||
interval: root.swapInputParamsForm.autoRefreshTime
|
|
||||||
running: false
|
|
||||||
repeat: false
|
|
||||||
onTriggered: {
|
|
||||||
if(!root.swapAdaptor.swapProposalLoading && !root.swapAdaptor.approvalPending) {
|
|
||||||
d.fetchSuggestedRoutes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchSuggestedRoutes() {
|
function fetchSuggestedRoutes() {
|
||||||
if (root.swapInputParamsForm.isFormFilledCorrectly()) {
|
if (root.swapInputParamsForm.isFormFilledCorrectly()) {
|
||||||
root.swapAdaptor.swapProposalLoading = true
|
root.swapAdaptor.swapProposalLoading = true
|
||||||
|
@ -91,19 +80,6 @@ StatusDialog {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: root.swapAdaptor
|
|
||||||
function onApprovalSuccessfulChanged() {
|
|
||||||
// perform a recalculation to make sure expected outcome shown is accurate
|
|
||||||
if(root.swapAdaptor.approvalSuccessful) {
|
|
||||||
d.fetchSuggestedRoutes()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onSuggestedRoutesReady() {
|
|
||||||
d.autoRefreshTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// needed as the first time the value not loaded correctly without this Binding
|
// needed as the first time the value not loaded correctly without this Binding
|
||||||
Binding {
|
Binding {
|
||||||
target: root.swapAdaptor
|
target: root.swapAdaptor
|
||||||
|
|
|
@ -264,7 +264,7 @@ QObject {
|
||||||
root.suggestedRoutesReady()
|
root.suggestedRoutesReady()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTransactionSent(chainId, txHash, uuid, error) {
|
function onTransactionSent(uuid, chainId, approvalTx, txHash, error) {
|
||||||
if(root.swapOutputData.approvalNeeded) {
|
if(root.swapOutputData.approvalNeeded) {
|
||||||
if (uuid !== d.uuid || !!error) {
|
if (uuid !== d.uuid || !!error) {
|
||||||
root.approvalPending = false
|
root.approvalPending = false
|
||||||
|
@ -276,11 +276,15 @@ QObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTransactionSendingComplete(txHash, success) {
|
function onTransactionSendingComplete(txHash, status) {
|
||||||
if(d.txHash === txHash && root.swapOutputData.approvalNeeded && root.approvalPending) {
|
if(d.txHash === txHash && root.swapOutputData.approvalNeeded && root.approvalPending) {
|
||||||
root.approvalPending = false
|
root.approvalPending = false
|
||||||
root.approvalSuccessful = success
|
root.approvalSuccessful = status == "Success" // TODO: make a all tx statuses Constants (success, pending, failed)
|
||||||
d.txHash = ""
|
d.txHash = ""
|
||||||
|
|
||||||
|
if (root.approvalSuccessful) {
|
||||||
|
root.swapOutputData.approvalNeeded = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,16 +346,12 @@ QObject {
|
||||||
root.approvalPending = true
|
root.approvalPending = true
|
||||||
const accountAddress = root.swapFormData.selectedAccountAddress
|
const accountAddress = root.swapFormData.selectedAccountAddress
|
||||||
|
|
||||||
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
root.swapStore.authenticateAndTransfer(d.uuid, "")
|
||||||
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
|
||||||
Constants.SendType.Approve, "", false, root.swapOutputData.rawPaths, "")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendSwapTx() {
|
function sendSwapTx() {
|
||||||
const accountAddress = root.swapFormData.selectedAccountAddress
|
const accountAddress = root.swapFormData.selectedAccountAddress
|
||||||
|
|
||||||
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
root.swapStore.authenticateAndTransfer(d.uuid, root.swapFormData.selectedSlippage)
|
||||||
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
|
||||||
Constants.SendType.Swap, "", false, root.swapOutputData.rawPaths, root.swapFormData.selectedSlippage)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ QtObject {
|
||||||
readonly property var walletSectionSendInst: walletSectionSend
|
readonly property var walletSectionSendInst: walletSectionSend
|
||||||
|
|
||||||
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
signal suggestedRoutesReady(var txRoutes, string errCode, string errDescription)
|
||||||
signal transactionSent(var chainId, var txHash, var uuid, var error)
|
signal transactionSent(var uuid, var chainId, var approvalTx, var txHash, var error)
|
||||||
signal transactionSendingComplete(var txHash, var success)
|
signal transactionSendingComplete(var txHash, var success)
|
||||||
|
|
||||||
readonly property Connections walletSectionSendConnections: Connections {
|
readonly property Connections walletSectionSendConnections: Connections {
|
||||||
|
@ -25,8 +25,8 @@ QtObject {
|
||||||
function onSuggestedRoutesReady(txRoutes, errCode, errDescription) {
|
function onSuggestedRoutesReady(txRoutes, errCode, errDescription) {
|
||||||
root.suggestedRoutesReady(txRoutes, errCode, errDescription)
|
root.suggestedRoutesReady(txRoutes, errCode, errDescription)
|
||||||
}
|
}
|
||||||
function onTransactionSent(chainId, txHash, uuid, error) {
|
function onTransactionSent(uuid, chainId, approvalTx, txHash, error) {
|
||||||
root.transactionSent(chainId, txHash, uuid, error)
|
root.transactionSent(uuid, chainId, approvalTx, txHash, error)
|
||||||
}
|
}
|
||||||
function onTransactionSendingComplete(txHash, success) {
|
function onTransactionSendingComplete(txHash, success) {
|
||||||
root.transactionSendingComplete(txHash, success)
|
root.transactionSendingComplete(txHash, success)
|
||||||
|
@ -45,10 +45,8 @@ QtObject {
|
||||||
root.walletSectionSendInst.stopUpdatesForSuggestedRoute()
|
root.walletSectionSendInst.stopUpdatesForSuggestedRoute()
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateAndTransfer(uuid, accountFrom, accountTo,
|
function authenticateAndTransfer(uuid, slippagePercentage) {
|
||||||
tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths, slippagePercentage) {
|
root.walletSectionSendInst.authenticateAndTransfer(uuid, slippagePercentage)
|
||||||
root.walletSectionSendInst.authenticateAndTransferWithParameters(uuid, accountFrom, accountTo,
|
|
||||||
tokenFrom, tokenTo, sendType, tokenName, tokenIsOwnerToken, paths, slippagePercentage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWei2Eth(wei, decimals) {
|
function getWei2Eth(wei, decimals) {
|
||||||
|
|
|
@ -78,7 +78,7 @@ StatusDialog {
|
||||||
popup.isLoading = true
|
popup.isLoading = true
|
||||||
d.routerError = ""
|
d.routerError = ""
|
||||||
d.routerErrorDetails = ""
|
d.routerErrorDetails = ""
|
||||||
popup.store.suggestedRoutes(d.isCollectiblesTransfer ? "1" : amountToSend.amount, "0", d.extraParamsJson)
|
popup.store.suggestedRoutes(d.uuid, d.isCollectiblesTransfer ? "1" : amountToSend.amount, "0", d.extraParamsJson)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -788,7 +788,7 @@ StatusDialog {
|
||||||
popup.isLoading = false
|
popup.isLoading = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTransactionSent(chainId: int, txHash: string, uuid: string, error: string) {
|
function onTransactionSent(uuid: string, chainId: int, approvalTx: bool, txHash: string, error: string) {
|
||||||
d.isPendingTx = false
|
d.isPendingTx = false
|
||||||
if (uuid !== d.uuid) return
|
if (uuid !== d.uuid) return
|
||||||
if (!!error) {
|
if (!!error) {
|
||||||
|
|
|
@ -58,14 +58,14 @@ QtObject {
|
||||||
return networksModule.getBlockExplorerURL(chainID)
|
return networksModule.getBlockExplorerURL(chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateAndTransfer(uuid) {
|
function authenticateAndTransfer(uuid, slippagePercentage = "") {
|
||||||
walletSectionSendInst.authenticateAndTransfer(uuid)
|
walletSectionSendInst.authenticateAndTransfer(uuid, slippagePercentage)
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedRoutes(amountIn, amountOut = "0", extraParamsJson = "") {
|
function suggestedRoutes(uuid, amountIn, amountOut = "0", extraParamsJson = "") {
|
||||||
const valueIn = AmountsArithmetic.fromNumber(amountIn)
|
const valueIn = AmountsArithmetic.fromNumber(amountIn)
|
||||||
const valueOut = AmountsArithmetic.fromNumber(amountOut)
|
const valueOut = AmountsArithmetic.fromNumber(amountOut)
|
||||||
walletSectionSendInst.suggestedRoutes(valueIn.toFixed(), valueOut.toFixed(), extraParamsJson)
|
walletSectionSendInst.suggestedRoutes(uuid, valueIn.toFixed(), valueOut.toFixed(), extraParamsJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopUpdatesForSuggestedRoute() {
|
function stopUpdatesForSuggestedRoute() {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 2f71d9d9f2529cfa21cabb216be7992a5f9f6717
|
Subproject commit 107e2cb8daef1b89b5f6b8dac6f0aa70d901f711
|
Loading…
Reference in New Issue