parent
d3d0080b2d
commit
7e9f680e0b
|
@ -3,7 +3,10 @@
|
||||||
type SignalType* {.pure.} = enum
|
type SignalType* {.pure.} = enum
|
||||||
Message = "messages.new"
|
Message = "messages.new"
|
||||||
MessageDelivered = "message.delivered"
|
MessageDelivered = "message.delivered"
|
||||||
|
## Wallet Signals
|
||||||
Wallet = "wallet"
|
Wallet = "wallet"
|
||||||
|
WalletSignTransactions = "wallet.sign.transactions"
|
||||||
|
WalletSuggestedRoutes = "wallet.suggested.routes"
|
||||||
NodeReady = "node.ready"
|
NodeReady = "node.ready"
|
||||||
NodeCrashed = "node.crashed"
|
NodeCrashed = "node.crashed"
|
||||||
NodeStarted = "node.started"
|
NodeStarted = "node.started"
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import json, options
|
import json, options, sequtils, sugar, chronicles
|
||||||
|
|
||||||
import base
|
import base
|
||||||
import signal_type
|
import signal_type
|
||||||
|
|
||||||
|
import app_service/service/transaction/dtoV2
|
||||||
|
|
||||||
const SignTransactionsEventType* = "sing-transactions"
|
const SignTransactionsEventType* = "sing-transactions"
|
||||||
|
|
||||||
type WalletSignal* = ref object of Signal
|
type WalletSignal* = ref object of Signal
|
||||||
|
@ -17,20 +19,20 @@ type WalletSignal* = ref object of Signal
|
||||||
message*: string
|
message*: string
|
||||||
requestId*: Option[int]
|
requestId*: Option[int]
|
||||||
txHashes*: seq[string]
|
txHashes*: seq[string]
|
||||||
|
uuid*: string
|
||||||
|
bestRoute*: seq[TransactionPathDtoV2]
|
||||||
|
error*: string
|
||||||
|
errorCode*: string
|
||||||
|
|
||||||
proc fromEvent*(T: type WalletSignal, jsonSignal: JsonNode): WalletSignal =
|
proc fromEvent*(T: type WalletSignal, signalType: SignalType, jsonSignal: JsonNode): WalletSignal =
|
||||||
result = WalletSignal()
|
result = WalletSignal()
|
||||||
result.signalType = SignalType.Wallet
|
result.signalType = SignalType.Wallet
|
||||||
result.content = $jsonSignal
|
|
||||||
let event = jsonSignal["event"]
|
let event = jsonSignal["event"]
|
||||||
if event.kind != JNull:
|
if event.kind == JNull:
|
||||||
|
return
|
||||||
|
if signalType == SignalType.Wallet:
|
||||||
|
result.content = $jsonSignal
|
||||||
result.eventType = event["type"].getStr
|
result.eventType = event["type"].getStr
|
||||||
if result.eventType == SignTransactionsEventType:
|
|
||||||
if event["transactions"].kind != JArray:
|
|
||||||
return
|
|
||||||
for tx in event["transactions"]:
|
|
||||||
result.txHashes.add(tx.getStr)
|
|
||||||
return
|
|
||||||
result.blockNumber = event{"blockNumber"}.getInt
|
result.blockNumber = event{"blockNumber"}.getInt
|
||||||
result.erc20 = event{"erc20"}.getBool
|
result.erc20 = event{"erc20"}.getBool
|
||||||
result.accounts = @[]
|
result.accounts = @[]
|
||||||
|
@ -43,3 +45,23 @@ proc fromEvent*(T: type WalletSignal, jsonSignal: JsonNode): WalletSignal =
|
||||||
const requestIdName = "requestId"
|
const requestIdName = "requestId"
|
||||||
if event.contains(requestIdName):
|
if event.contains(requestIdName):
|
||||||
result.requestId = some(event[requestIdName].getInt())
|
result.requestId = some(event[requestIdName].getInt())
|
||||||
|
return
|
||||||
|
if signalType == SignalType.WalletSignTransactions:
|
||||||
|
if event.kind != JArray:
|
||||||
|
return
|
||||||
|
for tx in event:
|
||||||
|
result.txHashes.add(tx.getStr)
|
||||||
|
return
|
||||||
|
if signalType == SignalType.WalletSuggestedRoutes:
|
||||||
|
try:
|
||||||
|
if event.contains("Uuid"):
|
||||||
|
result.uuid = event["Uuid"].getStr()
|
||||||
|
if event.contains("Best"):
|
||||||
|
result.bestRoute = event["Best"].getElems().map(x => x.toTransactionPathDtoV2())
|
||||||
|
if event.contains("details"):
|
||||||
|
result.error = event["details"].getStr
|
||||||
|
if event.contains("code"):
|
||||||
|
result.errorCode = event["code"].getStr
|
||||||
|
except:
|
||||||
|
error "Error parsing best route"
|
||||||
|
return
|
||||||
|
|
|
@ -26,7 +26,7 @@ QtObject:
|
||||||
result.setup()
|
result.setup()
|
||||||
result.events = events
|
result.events = events
|
||||||
|
|
||||||
# This method might be called with `ChroniclesLogs` event from `nim_status_client`.
|
# This method might be called with `ChroniclesLogs` event from `nim_status_client`.
|
||||||
# In such case we must not log anything to prevent recursive calls.
|
# In such case we must not log anything to prevent recursive calls.
|
||||||
# I tried to make a better solution, but ended up with such workaround, check out PR for more details.
|
# I tried to make a better solution, but ended up with such workaround, check out PR for more details.
|
||||||
proc processSignal(self: SignalsManager, statusSignal: string, allowLogging: bool) =
|
proc processSignal(self: SignalsManager, statusSignal: string, allowLogging: bool) =
|
||||||
|
@ -79,7 +79,10 @@ QtObject:
|
||||||
of SignalType.EnvelopeSent: EnvelopeSentSignal.fromEvent(jsonSignal)
|
of SignalType.EnvelopeSent: EnvelopeSentSignal.fromEvent(jsonSignal)
|
||||||
of SignalType.EnvelopeExpired: EnvelopeExpiredSignal.fromEvent(jsonSignal)
|
of SignalType.EnvelopeExpired: EnvelopeExpiredSignal.fromEvent(jsonSignal)
|
||||||
of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal)
|
of SignalType.WhisperFilterAdded: WhisperFilterSignal.fromEvent(jsonSignal)
|
||||||
of SignalType.Wallet: WalletSignal.fromEvent(jsonSignal)
|
of SignalType.Wallet,
|
||||||
|
SignalType.WalletSignTransactions,
|
||||||
|
SignalType.WalletSuggestedRoutes:
|
||||||
|
WalletSignal.fromEvent(signalType, jsonSignal)
|
||||||
of SignalType.NodeReady,
|
of SignalType.NodeReady,
|
||||||
SignalType.NodeCrashed,
|
SignalType.NodeCrashed,
|
||||||
SignalType.NodeStarted,
|
SignalType.NodeStarted,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import sugar, sequtils, stint
|
import Tables, sugar, sequtils
|
||||||
import uuids, chronicles, options
|
import uuids, chronicles, options
|
||||||
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
|
||||||
|
@ -71,10 +71,8 @@ proc init*(self: Controller) =
|
||||||
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
|
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
|
||||||
self.delegate.suggestedRoutesReady(SuggestedRoutesArgs(e).suggestedRoutes)
|
self.delegate.suggestedRoutesReady(SuggestedRoutesArgs(e).suggestedRoutes)
|
||||||
|
|
||||||
self.events.on(SignalType.Wallet.event) do(e:Args):
|
self.events.on(SignalType.WalletSignTransactions.event) do(e:Args):
|
||||||
var data = WalletSignal(e)
|
var data = WalletSignal(e)
|
||||||
if data.eventType != SignTransactionsEventType:
|
|
||||||
return
|
|
||||||
self.delegate.prepareSignaturesForTransactions(data.txHashes)
|
self.delegate.prepareSignaturesForTransactions(data.txHashes)
|
||||||
|
|
||||||
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
proc getWalletAccounts*(self: Controller): seq[wallet_account_service.WalletAccountDto] =
|
||||||
|
@ -109,10 +107,20 @@ proc authenticate*(self: Controller, keyUid = "") =
|
||||||
keyUid: keyUid)
|
keyUid: keyUid)
|
||||||
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
self.events.emit(SIGNAL_SHARED_KEYCARD_MODULE_AUTHENTICATE_USER, data)
|
||||||
|
|
||||||
proc suggestedRoutes*(self: Controller, accountFrom: string, accountTo: string, amount: Uint256, token: string, toToken: string,
|
proc suggestedRoutes*(self: Controller,
|
||||||
disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) =
|
sendType: SendType,
|
||||||
self.transactionService.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs,
|
accountFrom: string,
|
||||||
disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
|
accountTo: string,
|
||||||
|
token: string,
|
||||||
|
amountIn: string,
|
||||||
|
toToken: string = "",
|
||||||
|
amountOut: string = "",
|
||||||
|
disabledFromChainIDs: seq[int] = @[],
|
||||||
|
disabledToChainIDs: seq[int] = @[],
|
||||||
|
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
||||||
|
extraParamsTable: Table[string, string] = initTable[string, string]()) =
|
||||||
|
self.transactionService.suggestedRoutes(sendType, accountFrom, accountTo, token, amountIn, toToken, amountOut,
|
||||||
|
disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
|
|
||||||
proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: string, toAssetKey: string,
|
proc transfer*(self: Controller, from_addr: string, to_addr: string, assetKey: string, toAssetKey: string,
|
||||||
uuid: string, selectedRoutes: seq[TransactionPathDto], password: string, sendType: SendType,
|
uuid: string, selectedRoutes: seq[TransactionPathDto], password: string, sendType: SendType,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import stint, options
|
import Tables, options
|
||||||
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/modules/shared_models/collectibles_model as collectibles
|
import app/modules/shared_models/collectibles_model as collectibles
|
||||||
|
@ -24,8 +24,18 @@ method refreshWalletAccounts*(self: AccessInterface) {.base.} =
|
||||||
method getTokenBalance*(self: AccessInterface, address: string, chainId: int, tokensKey: string): CurrencyAmount {.base.} =
|
method getTokenBalance*(self: AccessInterface, address: string, chainId: int, tokensKey: string): CurrencyAmount {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method suggestedRoutes*(self: AccessInterface, accountFrom: string, accountTo: string, amount: UInt256, token: string, toToken: string,
|
method suggestedRoutes*(self: AccessInterface,
|
||||||
disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) {.base.} =
|
sendType: SendType,
|
||||||
|
accountFrom: string,
|
||||||
|
accountTo: string,
|
||||||
|
token: string,
|
||||||
|
amountIn: string,
|
||||||
|
toToken: string = "",
|
||||||
|
amountOut: string = "",
|
||||||
|
disabledFromChainIDs: seq[int] = @[],
|
||||||
|
disabledToChainIDs: seq[int] = @[],
|
||||||
|
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
||||||
|
extraParamsTable: Table[string, string] = initTable[string, string]()) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: SuggestedRoutesDto) {.base.} =
|
method suggestedRoutesReady*(self: AccessInterface, suggestedRoutes: SuggestedRoutesDto) {.base.} =
|
||||||
|
|
|
@ -339,11 +339,6 @@ method transactionWasSent*(self: Module, chainId: int, txHash, uuid, error: stri
|
||||||
return
|
return
|
||||||
self.view.sendTransactionSentSignal(chainId, txHash, uuid, error)
|
self.view.sendTransactionSentSignal(chainId, txHash, uuid, error)
|
||||||
|
|
||||||
method suggestedRoutes*(self: Module, accountFrom: string, accountTo: string, amount: UInt256, token: string, toToken: string,
|
|
||||||
disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) =
|
|
||||||
self.controller.suggestedRoutes(accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs,
|
|
||||||
disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
|
|
||||||
|
|
||||||
method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto) =
|
method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto) =
|
||||||
self.tmpSendTransactionDetails.paths = suggestedRoutes.best
|
self.tmpSendTransactionDetails.paths = suggestedRoutes.best
|
||||||
self.tmpSendTransactionDetails.slippagePercentage = none(float)
|
self.tmpSendTransactionDetails.slippagePercentage = none(float)
|
||||||
|
@ -363,6 +358,32 @@ method suggestedRoutesReady*(self: Module, suggestedRoutes: SuggestedRoutesDto)
|
||||||
rawPaths = suggestedRoutes.rawBest)
|
rawPaths = suggestedRoutes.rawBest)
|
||||||
self.view.setTransactionRoute(transactionRoutes)
|
self.view.setTransactionRoute(transactionRoutes)
|
||||||
|
|
||||||
|
method suggestedRoutes*(self: Module,
|
||||||
|
sendType: SendType,
|
||||||
|
accountFrom: string,
|
||||||
|
accountTo: string,
|
||||||
|
token: string,
|
||||||
|
amountIn: string,
|
||||||
|
toToken: string = "",
|
||||||
|
amountOut: string = "",
|
||||||
|
disabledFromChainIDs: seq[int] = @[],
|
||||||
|
disabledToChainIDs: seq[int] = @[],
|
||||||
|
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
||||||
|
extraParamsTable: Table[string, string] = initTable[string, string]()) =
|
||||||
|
self.controller.suggestedRoutes(
|
||||||
|
sendType,
|
||||||
|
accountFrom,
|
||||||
|
accountTo,
|
||||||
|
token,
|
||||||
|
amountIn,
|
||||||
|
toToken,
|
||||||
|
amountOut,
|
||||||
|
disabledFromChainIDs,
|
||||||
|
disabledToChainIDs,
|
||||||
|
lockedInAmounts,
|
||||||
|
extraParamsTable
|
||||||
|
)
|
||||||
|
|
||||||
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
|
method filterChanged*(self: Module, addresses: seq[string], chainIds: seq[int]) =
|
||||||
if addresses.len == 0:
|
if addresses.len == 0:
|
||||||
return
|
return
|
||||||
|
|
|
@ -205,12 +205,12 @@ QtObject:
|
||||||
disbaledChains.add(item.getChainId())
|
disbaledChains.add(item.getChainId())
|
||||||
return disbaledChains
|
return disbaledChains
|
||||||
|
|
||||||
proc getRouteLockedChainIds*(self: NetworkModel): string =
|
proc getRouteLockedChainIds*(self: NetworkModel): Table[string, string] =
|
||||||
var jsonObject = newJObject()
|
var lockedChains: Table[string, string]
|
||||||
for item in self.items:
|
for item in self.items:
|
||||||
if item.getLocked():
|
if item.getLocked():
|
||||||
jsonObject[$item.getChainId()] = %* ("0x" & item.getLockedAmount())
|
lockedChains[$item.getChainId()] = "0x" & item.getLockedAmount()
|
||||||
return $jsonObject
|
return lockedChains
|
||||||
|
|
||||||
proc updateRoutePreferredChains*(self: NetworkModel, chainIds: string) =
|
proc updateRoutePreferredChains*(self: NetworkModel, chainIds: string) =
|
||||||
try:
|
try:
|
||||||
|
@ -232,12 +232,6 @@ QtObject:
|
||||||
except:
|
except:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc getRoutePreferredNetworkChainIds*(self: NetworkModel): seq[int] =
|
|
||||||
var preferredChains: seq[int] = @[]
|
|
||||||
for item in self.items:
|
|
||||||
if item.getIsPreferred():
|
|
||||||
preferredChains.add(item.getChainId())
|
|
||||||
return preferredChains
|
|
||||||
|
|
||||||
proc disableRouteUnpreferredChains*(self: NetworkModel) =
|
proc disableRouteUnpreferredChains*(self: NetworkModel) =
|
||||||
for i in 0 ..< self.items.len:
|
for i in 0 ..< self.items.len:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import NimQml, sequtils, strutils, stint, sugar, options
|
import NimQml, Tables, json, sequtils, strutils, stint, sugar, options, chronicles
|
||||||
|
|
||||||
import ./io_interface, ./accounts_model, ./account_item, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes
|
import ./io_interface, ./accounts_model, ./account_item, ./network_model, ./network_item, ./suggested_route_item, ./transaction_routes
|
||||||
import app/modules/shared_models/collectibles_model as collectibles
|
import app/modules/shared_models/collectibles_model as collectibles
|
||||||
|
@ -218,14 +218,6 @@ QtObject:
|
||||||
proc sendTransactionSentSignal*(self: View, chainId: int, txHash: string, uuid: string, error: string) =
|
proc sendTransactionSentSignal*(self: View, chainId: int, txHash: string, uuid: string, error: string) =
|
||||||
self.transactionSent(chainId, txHash, uuid, error)
|
self.transactionSent(chainId, txHash, uuid, error)
|
||||||
|
|
||||||
proc parseAmount(amount: string): Uint256 =
|
|
||||||
var parsedAmount = stint.u256(0)
|
|
||||||
try:
|
|
||||||
parsedAmount = amount.parse(Uint256)
|
|
||||||
except Exception as e:
|
|
||||||
discard
|
|
||||||
return parsedAmount
|
|
||||||
|
|
||||||
proc parseChainIds(chainIds: string): seq[int] =
|
proc parseChainIds(chainIds: string): seq[int] =
|
||||||
var parsedChainIds: seq[int] = @[]
|
var parsedChainIds: seq[int] = @[]
|
||||||
for chainId in chainIds.split(':'):
|
for chainId in chainIds.split(':'):
|
||||||
|
@ -241,11 +233,28 @@ QtObject:
|
||||||
self.transactionRoutes = routes
|
self.transactionRoutes = routes
|
||||||
self.suggestedRoutesReady(newQVariant(self.transactionRoutes))
|
self.suggestedRoutesReady(newQVariant(self.transactionRoutes))
|
||||||
|
|
||||||
proc suggestedRoutes*(self: View, amount: string) {.slot.} =
|
proc suggestedRoutes*(self: View, amountIn: string, amountOut: string, extraParamsJson: string) {.slot.} =
|
||||||
self.delegate.suggestedRoutes(self.selectedSenderAccount.address(), self.selectedRecipient,
|
var extraParamsTable: Table[string, string]
|
||||||
parseAmount(amount), self.selectedAssetKey, self.selectedToAssetKey, self.fromNetworksModel.getRouteDisabledNetworkChainIds(),
|
try:
|
||||||
self.toNetworksModel.getRouteDisabledNetworkChainIds(), self.toNetworksModel.getRoutePreferredNetworkChainIds(),
|
if extraParamsJson.len > 0:
|
||||||
self.sendType, self.fromNetworksModel.getRouteLockedChainIds())
|
for key, value in parseJson(extraParamsJson):
|
||||||
|
extraParamsTable[key] = value.getStr()
|
||||||
|
except Exception as e:
|
||||||
|
error "Error parsing extraParamsJson: ", msg=e.msg
|
||||||
|
|
||||||
|
self.delegate.suggestedRoutes(
|
||||||
|
self.sendType,
|
||||||
|
self.selectedSenderAccount.address(),
|
||||||
|
self.selectedRecipient,
|
||||||
|
self.selectedAssetKey,
|
||||||
|
amountIn,
|
||||||
|
self.selectedToAssetKey,
|
||||||
|
amountOut,
|
||||||
|
self.fromNetworksModel.getRouteDisabledNetworkChainIds(),
|
||||||
|
self.toNetworksModel.getRouteDisabledNetworkChainIds(),
|
||||||
|
self.fromNetworksModel.getRouteLockedChainIds(),
|
||||||
|
extraParamsTable
|
||||||
|
)
|
||||||
|
|
||||||
proc switchSenderAccountByAddress*(self: View, address: string) {.slot.} =
|
proc switchSenderAccountByAddress*(self: View, address: string) {.slot.} =
|
||||||
let (account, index) = self.senderAccounts.getItemByAddress(address)
|
let (account, index) = self.senderAccounts.getItemByAddress(address)
|
||||||
|
@ -332,13 +341,37 @@ QtObject:
|
||||||
return self.fromNetworksModel.getIconUrl(chainId)
|
return self.fromNetworksModel.getIconUrl(chainId)
|
||||||
|
|
||||||
# "Stateless" methods
|
# "Stateless" methods
|
||||||
proc fetchSuggestedRoutesWithParameters*(self: View, accountFrom: string, accountTo: string, amount: string, token: string, toToken: string,
|
proc fetchSuggestedRoutesWithParameters*(self: View,
|
||||||
disabledFromChainIDs: string, disabledToChainIDs: string, preferredChainIDs: string, sendType: int, lockedInAmounts: string) {.slot.} =
|
accountFrom: string,
|
||||||
self.delegate.suggestedRoutes(accountFrom, accountTo,
|
accountTo: string,
|
||||||
parseAmount(amount), token, toToken,
|
amountIn: string,
|
||||||
parseChainIds(disabledFromChainIDs), parseChainIds(disabledToChainIDs), parseChainIds(preferredChainIDs),
|
amountOut: string,
|
||||||
SendType(sendType), lockedInAmounts)
|
token: string,
|
||||||
|
toToken: string,
|
||||||
|
disabledFromChainIDs: string,
|
||||||
|
disabledToChainIDs: string,
|
||||||
|
sendType: int,
|
||||||
|
lockedInAmounts: string) {.slot.} =
|
||||||
|
# Prepare lockedInAmountsTable
|
||||||
|
var lockedInAmountsTable = Table[string, string] : initTable[string, string]()
|
||||||
|
try:
|
||||||
|
for chainId, lockedAmount in parseJson(lockedInAmounts):
|
||||||
|
lockedInAmountsTable[chainId] = lockedAmount.getStr
|
||||||
|
except:
|
||||||
|
discard
|
||||||
|
# Resolve the best route
|
||||||
|
self.delegate.suggestedRoutes(
|
||||||
|
SendType(sendType),
|
||||||
|
accountFrom,
|
||||||
|
accountTo,
|
||||||
|
token,
|
||||||
|
amountIn,
|
||||||
|
toToken,
|
||||||
|
amountOut,
|
||||||
|
parseChainIds(disabledFromChainIDs),
|
||||||
|
parseChainIds(disabledToChainIDs),
|
||||||
|
lockedInAmountsTable)
|
||||||
|
|
||||||
proc authenticateAndTransferWithParameters*(self: View, uuid: string, accountFrom: string, accountTo: string, token: string, toToken: string,
|
proc authenticateAndTransferWithParameters*(self: View, uuid: string, accountFrom: string, accountTo: string, token: string, toToken: string,
|
||||||
sendTypeInt: int, tokenName: string, tokenIsOwnerToken: bool, rawPaths: string, slippagePercentageString: string) {.slot.} =
|
sendTypeInt: int, tokenName: string, tokenIsOwnerToken: bool, rawPaths: string, slippagePercentageString: string) {.slot.} =
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import json, times, strutils, sugar, os, re, chronicles
|
import json, times, stint, strutils, sugar, os, re, chronicles
|
||||||
|
|
||||||
import nimcrypto
|
import nimcrypto
|
||||||
import account_constants
|
import account_constants
|
||||||
|
|
||||||
|
@ -7,12 +8,12 @@ import ../../constants as main_constants
|
||||||
const STATUS_DOMAIN* = ".stateofus.eth"
|
const STATUS_DOMAIN* = ".stateofus.eth"
|
||||||
const ETH_DOMAIN* = ".eth"
|
const ETH_DOMAIN* = ".eth"
|
||||||
|
|
||||||
proc arrayContains*[T](arr: seq[T], value: T): bool =
|
proc arrayContains*[T](arr: seq[T], value: T): bool =
|
||||||
return arr.any(x => x == value)
|
return arr.any(x => x == value)
|
||||||
|
|
||||||
proc hashPassword*(password: string, lower: bool = true): string =
|
proc hashPassword*(password: string, lower: bool = true): string =
|
||||||
let hashed = "0x" & $keccak_256.digest(password)
|
let hashed = "0x" & $keccak_256.digest(password)
|
||||||
|
|
||||||
if lower:
|
if lower:
|
||||||
return hashed.toLowerAscii()
|
return hashed.toLowerAscii()
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ proc validateLink*(link: string): bool =
|
||||||
proc isPathOutOfTheDefaultStatusDerivationTree*(path: string): bool =
|
proc isPathOutOfTheDefaultStatusDerivationTree*(path: string): bool =
|
||||||
if not path.startsWith(account_constants.PATH_WALLET_ROOT&"/") or
|
if not path.startsWith(account_constants.PATH_WALLET_ROOT&"/") or
|
||||||
path.count("'") != 3 or
|
path.count("'") != 3 or
|
||||||
path.count("/") != 5:
|
path.count("/") != 5:
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@ -82,3 +83,11 @@ proc intersectSeqs*[T](seq1, seq2: seq[T]): seq[T] =
|
||||||
for item in seq1:
|
for item in seq1:
|
||||||
if item in seq2:
|
if item in seq2:
|
||||||
result.add(item)
|
result.add(item)
|
||||||
|
|
||||||
|
proc stringToUint256*(value: string): Uint256 =
|
||||||
|
var parsedValue = stint.u256(0)
|
||||||
|
try:
|
||||||
|
parsedValue = value.parse(Uint256)
|
||||||
|
except Exception as e:
|
||||||
|
discard
|
||||||
|
return parsedValue
|
|
@ -41,6 +41,7 @@ proc getFeesTotal*(paths: seq[TransactionPathDto]): FeesDto =
|
||||||
|
|
||||||
fees.totalFeesInEth += getGasEthValue(optimalPrice, path.gasAmount)
|
fees.totalFeesInEth += getGasEthValue(optimalPrice, path.gasAmount)
|
||||||
fees.totalFeesInEth += parseFloat(service_conversion.wei2Eth(service_conversion.gwei2Wei(path.gasFees.l1GasFee)))
|
fees.totalFeesInEth += parseFloat(service_conversion.wei2Eth(service_conversion.gwei2Wei(path.gasFees.l1GasFee)))
|
||||||
|
fees.totalFeesInEth += path.approvalGasFees
|
||||||
fees.totalTokenFees += path.tokenFees
|
fees.totalTokenFees += path.tokenFees
|
||||||
fees.totalTime += path.estimatedTime
|
fees.totalTime += path.estimatedTime
|
||||||
return fees
|
return fees
|
||||||
|
@ -77,47 +78,6 @@ proc addFirstSimpleBridgeTxFlag(paths: seq[TransactionPathDto]) : seq[Transactio
|
||||||
|
|
||||||
return txPaths
|
return txPaths
|
||||||
|
|
||||||
proc getSuggestedRoutesTask*(argEncoded: string) {.gcsafe, nimcall.} =
|
|
||||||
let arg = decode[GetSuggestedRoutesTaskArg](argEncoded)
|
|
||||||
|
|
||||||
try:
|
|
||||||
let amountAsHex = "0x" & eth_utils.stripLeadingZeros(arg.amount.toHex)
|
|
||||||
var lockedInAmounts = Table[string, string] : initTable[string, string]()
|
|
||||||
|
|
||||||
try:
|
|
||||||
for chainId, lockedAmount in parseJson(arg.lockedInAmounts):
|
|
||||||
lockedInAmounts[chainId] = lockedAmount.getStr
|
|
||||||
except:
|
|
||||||
discard
|
|
||||||
|
|
||||||
let response = eth.suggestedRoutes(arg.accountFrom, arg.accountTo, amountAsHex, arg.token, arg.toToken, arg.disabledFromChainIDs,
|
|
||||||
arg.disabledToChainIDs, arg.preferredChainIDs, ord(arg.sendType), lockedInAmounts).result
|
|
||||||
var bestPaths = response["Best"].getElems().map(x => x.toTransactionPathDto())
|
|
||||||
|
|
||||||
# retry along with unpreferred chains incase no route is possible with preferred chains
|
|
||||||
if arg.sendType != SendType.Swap and bestPaths.len == 0 and arg.preferredChainIDs.len > 0:
|
|
||||||
let response = eth.suggestedRoutes(arg.accountFrom, arg.accountTo, amountAsHex, arg.token, arg.toToken, arg.disabledFromChainIDs,
|
|
||||||
arg.disabledToChainIDs, @[], ord(arg.sendType), lockedInAmounts).result
|
|
||||||
bestPaths = response["Best"].getElems().map(x => x.toTransactionPathDto())
|
|
||||||
|
|
||||||
bestPaths.sort(sortAsc[TransactionPathDto])
|
|
||||||
|
|
||||||
let output = %*{
|
|
||||||
"suggestedRoutes": SuggestedRoutesDto(
|
|
||||||
best: addFirstSimpleBridgeTxFlag(bestPaths),
|
|
||||||
gasTimeEstimate: getFeesTotal(bestPaths),
|
|
||||||
amountToReceive: getTotalAmountToReceive(bestPaths),
|
|
||||||
toNetworks: getToNetworksList(bestPaths)),
|
|
||||||
"error": ""
|
|
||||||
}
|
|
||||||
arg.finish(output)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
let output = %* {
|
|
||||||
"suggestedRoutes": SuggestedRoutesDto(best: @[], gasTimeEstimate: FeesDto(), amountToReceive: stint.u256(0), toNetworks: @[]),
|
|
||||||
"error": fmt"Error getting suggested routes: {e.msg}"
|
|
||||||
}
|
|
||||||
arg.finish(output)
|
|
||||||
|
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import json, strutils, stint, json_serialization, stew/shims/strformat, sugar, sequtils
|
import json, strutils, stint, json_serialization, stew/shims/strformat
|
||||||
|
|
||||||
import
|
import
|
||||||
web3/ethtypes
|
web3/ethtypes
|
||||||
|
@ -334,7 +334,7 @@ proc convertToTransactionPathsDto*(jsonObj: JsonNode): seq[TransactionPathDto] =
|
||||||
|
|
||||||
proc convertToTransactionPathsDto*(paths: string): seq[TransactionPathDto] =
|
proc convertToTransactionPathsDto*(paths: string): seq[TransactionPathDto] =
|
||||||
return paths.parseJson.convertToTransactionPathsDto()
|
return paths.parseJson.convertToTransactionPathsDto()
|
||||||
|
|
||||||
type
|
type
|
||||||
FeesDto* = ref object
|
FeesDto* = ref object
|
||||||
totalFeesInEth*: float
|
totalFeesInEth*: float
|
||||||
|
@ -384,19 +384,3 @@ type
|
||||||
amountToReceive*: UInt256
|
amountToReceive*: UInt256
|
||||||
toNetworks*: seq[SendToNetwork]
|
toNetworks*: seq[SendToNetwork]
|
||||||
|
|
||||||
proc `$`*(self: SuggestedRoutesDto): string =
|
|
||||||
return fmt"""SuggestedRoutesDto(
|
|
||||||
best:{self.best},
|
|
||||||
rawBest:{self.rawBest},
|
|
||||||
gasTimeEstimate:{self.gasTimeEstimate},
|
|
||||||
amountToReceive:{self.amountToReceive},
|
|
||||||
toNetworks:{self.toNetworks},
|
|
||||||
)"""
|
|
||||||
|
|
||||||
proc convertToSuggestedRoutesDto*(jsonObj: JsonNode): SuggestedRoutesDto =
|
|
||||||
result = SuggestedRoutesDto()
|
|
||||||
result.rawBest = $jsonObj["suggestedRoutes"]["best"]
|
|
||||||
result.best = result.rawBest.convertToTransactionPathsDto()
|
|
||||||
result.gasTimeEstimate = jsonObj["suggestedRoutes"]["gasTimeEstimate"].convertToFeesDto()
|
|
||||||
result.amountToReceive = stint.u256(jsonObj["suggestedRoutes"]["amountToReceive"].getStr)
|
|
||||||
result.toNetworks = jsonObj["suggestedRoutes"]["toNetworks"].getElems().map(x => x.convertSendToNetwork())
|
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
# import json, json_serialization, stint
|
||||||
|
|
||||||
|
# import ../network/dto, ../token/dto
|
||||||
|
|
||||||
|
# include app_service/common/json_utils
|
||||||
|
|
||||||
|
import json, strutils, stint, json_serialization
|
||||||
|
|
||||||
|
import
|
||||||
|
web3/ethtypes
|
||||||
|
|
||||||
|
include ../../common/json_utils
|
||||||
|
import ../network/dto, ../token/dto
|
||||||
|
|
||||||
|
type
|
||||||
|
SuggestedLevelsForMaxFeesPerGasDto* = ref object
|
||||||
|
low*: UInt256
|
||||||
|
medium*: UInt256
|
||||||
|
high*: UInt256
|
||||||
|
|
||||||
|
type
|
||||||
|
TransactionPathDtoV2* = ref object
|
||||||
|
processorName*: string
|
||||||
|
fromChain*: NetworkDto
|
||||||
|
toChain*: NetworkDto
|
||||||
|
fromToken*: TokenDto
|
||||||
|
amountIn*: UInt256
|
||||||
|
amountInLocked*: bool
|
||||||
|
amountOut*: UInt256
|
||||||
|
suggestedLevelsForMaxFeesPerGas*: SuggestedLevelsForMaxFeesPerGasDto
|
||||||
|
txBaseFee*: UInt256
|
||||||
|
txPriorityFee*: UInt256
|
||||||
|
txGasAmount*: uint64
|
||||||
|
txBonderFees*: UInt256
|
||||||
|
txTokenFees*: UInt256
|
||||||
|
txL1Fee*: UInt256
|
||||||
|
approvalRequired*: bool
|
||||||
|
approvalAmountRequired*: UInt256
|
||||||
|
approvalContractAddress*: string
|
||||||
|
approvalBaseFee*: UInt256
|
||||||
|
approvalPriorityFee*: UInt256
|
||||||
|
approvalGasAmount*: uint64
|
||||||
|
approvalL1Fee*: UInt256
|
||||||
|
estimatedTime*: int
|
||||||
|
|
||||||
|
proc toSuggestedLevelsForMaxFeesPerGasDto*(jsonObj: JsonNode): SuggestedLevelsForMaxFeesPerGasDto =
|
||||||
|
result = SuggestedLevelsForMaxFeesPerGasDto()
|
||||||
|
var value: string
|
||||||
|
if jsonObj.getProp("low", value):
|
||||||
|
result.low = stint.fromHex(UInt256, $value)
|
||||||
|
if jsonObj.getProp("medium", value):
|
||||||
|
result.medium = stint.fromHex(UInt256, $value)
|
||||||
|
if jsonObj.getProp("high", value):
|
||||||
|
result.high = stint.fromHex(UInt256, $value)
|
||||||
|
|
||||||
|
proc toTransactionPathDtoV2*(jsonObj: JsonNode): TransactionPathDtoV2 =
|
||||||
|
result = TransactionPathDtoV2()
|
||||||
|
discard jsonObj.getProp("ProcessorName", result.processorName)
|
||||||
|
result.fromChain = Json.decode($jsonObj["FromChain"], NetworkDto, allowUnknownFields = true)
|
||||||
|
result.toChain = Json.decode($jsonObj["ToChain"], NetworkDto, allowUnknownFields = true)
|
||||||
|
result.fromToken = Json.decode($jsonObj["FromToken"], TokenDto, allowUnknownFields = true)
|
||||||
|
result.amountIn = stint.fromHex(UInt256, jsonObj{"AmountIn"}.getStr)
|
||||||
|
discard jsonObj.getProp("AmountInLocked", result.amountInLocked)
|
||||||
|
result.amountOut = stint.fromHex(UInt256, jsonObj{"AmountOut"}.getStr)
|
||||||
|
result.suggestedLevelsForMaxFeesPerGas = jsonObj["SuggestedLevelsForMaxFeesPerGas"].toSuggestedLevelsForMaxFeesPerGasDto()
|
||||||
|
result.txBaseFee = stint.fromHex(UInt256, jsonObj{"TxBaseFee"}.getStr)
|
||||||
|
result.txPriorityFee = stint.fromHex(UInt256, jsonObj{"TxPriorityFee"}.getStr)
|
||||||
|
discard jsonObj.getProp("TxGasAmount", result.txGasAmount)
|
||||||
|
result.txBonderFees = stint.fromHex(UInt256, jsonObj{"TxBonderFees"}.getStr)
|
||||||
|
result.txTokenFees = stint.fromHex(UInt256, jsonObj{"TxTokenFees"}.getStr)
|
||||||
|
result.txL1Fee = stint.fromHex(UInt256, jsonObj{"TxL1Fee"}.getStr)
|
||||||
|
discard jsonObj.getProp("ApprovalRequired", result.approvalRequired)
|
||||||
|
result.approvalAmountRequired = stint.fromHex(UInt256, jsonObj{"ApprovalAmountRequired"}.getStr)
|
||||||
|
discard jsonObj.getProp("ApprovalContractAddress", result.approvalContractAddress)
|
||||||
|
result.approvalBaseFee = stint.fromHex(UInt256, jsonObj{"ApprovalBaseFee"}.getStr)
|
||||||
|
result.approvalPriorityFee = stint.fromHex(UInt256, jsonObj{"ApprovalPriorityFee"}.getStr)
|
||||||
|
discard jsonObj.getProp("ApprovalGasAmount", result.approvalGasAmount)
|
||||||
|
result.approvalL1Fee = stint.fromHex(UInt256, jsonObj{"ApprovalL1Fee"}.getStr)
|
||||||
|
result.estimatedTime = jsonObj{"EstimatedTime"}.getInt
|
|
@ -1,4 +1,4 @@
|
||||||
import Tables, NimQml, chronicles, sequtils, sugar, stint, strutils, json, stew/shims/strformat, algorithm
|
import Tables, NimQml, chronicles, sequtils, sugar, stint, strutils, json, algorithm, uuids, stew/shims/strformat
|
||||||
|
|
||||||
import backend/collectibles as collectibles
|
import backend/collectibles as collectibles
|
||||||
import backend/transactions as transactions
|
import backend/transactions as transactions
|
||||||
|
@ -23,6 +23,7 @@ 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/transaction as transaction_data_dto
|
||||||
import app_service/service/eth/dto/[coder, method_dto]
|
import app_service/service/eth/dto/[coder, method_dto]
|
||||||
import ./dto as transaction_dto
|
import ./dto as transaction_dto
|
||||||
|
import ./dtoV2
|
||||||
import ./cryptoRampDto
|
import ./cryptoRampDto
|
||||||
import app_service/service/eth/utils as eth_utils
|
import app_service/service/eth/utils as eth_utils
|
||||||
import app_service/common/conversion
|
import app_service/common/conversion
|
||||||
|
@ -128,6 +129,9 @@ QtObject:
|
||||||
settingsService: settings_service.Service
|
settingsService: settings_service.Service
|
||||||
tokenService: token_service.Service
|
tokenService: token_service.Service
|
||||||
|
|
||||||
|
## Forward declarations
|
||||||
|
proc suggestedRoutesV2Ready(self: Service, uuid: string, route: seq[TransactionPathDtoV2], error: string, errCode: string)
|
||||||
|
|
||||||
proc delete*(self: Service) =
|
proc delete*(self: Service) =
|
||||||
self.QObject.delete
|
self.QObject.delete
|
||||||
|
|
||||||
|
@ -155,6 +159,10 @@ QtObject:
|
||||||
of transactions.EventFetchingHistoryError:
|
of transactions.EventFetchingHistoryError:
|
||||||
self.events.emit(SIGNAL_HISTORY_ERROR, Args())
|
self.events.emit(SIGNAL_HISTORY_ERROR, Args())
|
||||||
|
|
||||||
|
self.events.on(SignalType.WalletSuggestedRoutes.event) do(e:Args):
|
||||||
|
var data = WalletSignal(e)
|
||||||
|
self.suggestedRoutesV2Ready(data.uuid, data.bestRoute, data.error, data.errorCode)
|
||||||
|
|
||||||
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)
|
||||||
|
@ -561,46 +569,106 @@ QtObject:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error "Error getting suggested fees", msg = e.msg
|
error "Error getting suggested fees", msg = e.msg
|
||||||
|
|
||||||
proc suggestedRoutesReady*(self: Service, suggestedRoutes: string) {.slot.} =
|
proc convertToOldRoute(route: seq[TransactionPathDtoV2]): seq[TransactionPathDto] =
|
||||||
var suggestedRoutesDto: SuggestedRoutesDto = SuggestedRoutesDto()
|
const
|
||||||
try:
|
gweiDecimals = 9
|
||||||
let responseObj = suggestedRoutes.parseJson
|
ethDecimals = 18
|
||||||
suggestedRoutesDto = responseObj.convertToSuggestedRoutesDto()
|
for p in route:
|
||||||
except Exception as e:
|
var
|
||||||
error "error handling suggestedRoutesReady response", errDesription=e.msg
|
fees = SuggestedFeesDto()
|
||||||
self.events.emit(SIGNAL_SUGGESTED_ROUTES_READY, SuggestedRoutesArgs(suggestedRoutes: suggestedRoutesDto))
|
trPath = TransactionPathDto()
|
||||||
|
|
||||||
proc suggestedRoutes*(self: Service, accountFrom: string, accountTo: string, amount: Uint256, token: string, toToken: string,
|
try:
|
||||||
disabledFromChainIDs, disabledToChainIDs, preferredChainIDs: seq[int], sendType: SendType, lockedInAmounts: string) =
|
# prepare fees
|
||||||
var
|
fees.gasPrice = 0
|
||||||
tokenId: string
|
var value = conversion.wei2Eth(input = p.txBaseFee, decimals = gweiDecimals)
|
||||||
toTokenId: string
|
fees.baseFee = parseFloat(value)
|
||||||
|
value = conversion.wei2Eth(input = p.txPriorityFee, decimals = gweiDecimals)
|
||||||
|
fees.maxPriorityFeePerGas = parseFloat(value)
|
||||||
|
value = conversion.wei2Eth(input = p.suggestedLevelsForMaxFeesPerGas.low, decimals = gweiDecimals)
|
||||||
|
fees.maxFeePerGasL = parseFloat(value)
|
||||||
|
value = conversion.wei2Eth(input = p.suggestedLevelsForMaxFeesPerGas.medium, decimals = gweiDecimals)
|
||||||
|
fees.maxFeePerGasM = parseFloat(value)
|
||||||
|
value = conversion.wei2Eth(input = p.suggestedLevelsForMaxFeesPerGas.high, decimals = gweiDecimals)
|
||||||
|
fees.maxFeePerGasH = parseFloat(value)
|
||||||
|
value = conversion.wei2Eth(input = p.txL1Fee, decimals = gweiDecimals)
|
||||||
|
fees.l1GasFee = parseFloat(value)
|
||||||
|
fees.eip1559Enabled = true
|
||||||
|
|
||||||
if self.isCollectiblesTransfer(sendType):
|
# prepare tx path
|
||||||
tokenId = token
|
trPath.bridgeName = p.processorName
|
||||||
else:
|
trPath.fromNetwork = p.fromChain
|
||||||
let token = self.tokenService.getTokenBySymbolByTokensKey(token)
|
trPath.toNetwork = p.toChain
|
||||||
if token != nil:
|
trPath.gasFees = fees
|
||||||
tokenId = token.symbol
|
# trPath.cost = not in use for old approach in the desktop app
|
||||||
let toToken = self.tokenService.getTokenBySymbolByTokensKey(toToken)
|
value = conversion.wei2Eth(input = p.txTokenFees, decimals = p.fromToken.decimals)
|
||||||
if toToken != nil:
|
trPath.tokenFees = parseFloat(value)
|
||||||
toTokenId = toToken.symbol
|
value = conversion.wei2Eth(input = p.txBonderFees, decimals = p.fromToken.decimals)
|
||||||
let arg = GetSuggestedRoutesTaskArg(
|
trPath.bonderFees = value
|
||||||
tptr: getSuggestedRoutesTask,
|
trPath.tokenFees += parseFloat(value) # we add bonder fees to the token fees cause in the UI, atm, we show only token fees
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
trPath.maxAmountIn = stint.fromHex(UInt256, "0x0")
|
||||||
slot: "suggestedRoutesReady",
|
trPath.amountIn = p.amountIn
|
||||||
accountFrom: accountFrom,
|
trPath.amountOut = p.amountOut
|
||||||
accountTo: accountTo,
|
trPath.approvalRequired = p.approvalRequired
|
||||||
amount: amount,
|
trPath.approvalAmountRequired = p.approvalAmountRequired
|
||||||
token: tokenId,
|
trPath.approvalContractAddress = p.approvalContractAddress
|
||||||
toToken: toTokenId,
|
trPath.amountInLocked = p.amountInLocked
|
||||||
disabledFromChainIDs: disabledFromChainIDs,
|
trPath.estimatedTime = p.estimatedTime
|
||||||
disabledToChainIDs: disabledToChainIDs,
|
trPath.gasAmount = p.txGasAmount
|
||||||
preferredChainIDs: preferredChainIDs,
|
|
||||||
sendType: sendType,
|
value = conversion.wei2Eth(p.suggestedLevelsForMaxFeesPerGas.medium, decimals = ethDecimals)
|
||||||
lockedInAmounts: lockedInAmounts
|
trPath.approvalGasFees = parseFloat(value) * float64(p.approvalGasAmount)
|
||||||
|
value = conversion.wei2Eth(p.approvalL1Fee, decimals = ethDecimals)
|
||||||
|
trPath.approvalGasFees += parseFloat(value)
|
||||||
|
|
||||||
|
trPath.isFirstSimpleTx = false
|
||||||
|
trPath.isFirstBridgeTx = false
|
||||||
|
except Exception as e:
|
||||||
|
error "Error converting to old path", msg = e.msg
|
||||||
|
|
||||||
|
# add tx path to the list
|
||||||
|
result.add(trPath)
|
||||||
|
|
||||||
|
result.sort(sortAsc[TransactionPathDto])
|
||||||
|
|
||||||
|
proc suggestedRoutesV2Ready(self: Service, uuid: string, route: seq[TransactionPathDtoV2], error: string, errCode: string) =
|
||||||
|
# TODO: refactor sending modal part of the app, but for now since we're integrating the router v2 just map params to the old dto
|
||||||
|
|
||||||
|
var oldRoute = convertToOldRoute(route)
|
||||||
|
|
||||||
|
let suggestedDto = SuggestedRoutesDto(
|
||||||
|
best: addFirstSimpleBridgeTxFlag(oldRoute),
|
||||||
|
gasTimeEstimate: getFeesTotal(oldRoute),
|
||||||
|
amountToReceive: getTotalAmountToReceive(oldRoute),
|
||||||
|
toNetworks: getToNetworksList(oldRoute),
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.events.emit(SIGNAL_SUGGESTED_ROUTES_READY, SuggestedRoutesArgs(suggestedRoutes: suggestedDto))
|
||||||
|
|
||||||
|
proc suggestedRoutes*(self: Service,
|
||||||
|
sendType: SendType,
|
||||||
|
accountFrom: string,
|
||||||
|
accountTo: string,
|
||||||
|
token: string,
|
||||||
|
amountIn: string,
|
||||||
|
toToken: string = "",
|
||||||
|
amountOut: string = "",
|
||||||
|
disabledFromChainIDs: seq[int] = @[],
|
||||||
|
disabledToChainIDs: seq[int] = @[],
|
||||||
|
lockedInAmounts: Table[string, string] = initTable[string, string](),
|
||||||
|
extraParamsTable: Table[string, string] = initTable[string, string]()) =
|
||||||
|
|
||||||
|
let
|
||||||
|
bigAmountIn = common_utils.stringToUint256(amountIn)
|
||||||
|
bigAmountOut = common_utils.stringToUint256(amountOut)
|
||||||
|
amountInHex = "0x" & eth_utils.stripLeadingZeros(bigAmountIn.toHex)
|
||||||
|
amountOutHex = "0x" & eth_utils.stripLeadingZeros(bigAmountOut.toHex)
|
||||||
|
|
||||||
|
try:
|
||||||
|
let uuid = $genUUID()
|
||||||
|
let res = eth.suggestedRoutesV2Async(uuid, ord(sendType), accountFrom, accountTo, amountInHex, amountOutHex, token,
|
||||||
|
toToken, disabledFromChainIDs, disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
|
except CatchableError as e:
|
||||||
|
error "suggestedRoutes", exception=e.msg
|
||||||
|
|
||||||
proc onFetchCryptoServices*(self: Service, response: string) {.slot.} =
|
proc onFetchCryptoServices*(self: Service, response: string) {.slot.} =
|
||||||
let cryptoServices = parseJson(response){"result"}.getElems().map(x => x.toCryptoRampDto())
|
let cryptoServices = parseJson(response){"result"}.getElems().map(x => x.toCryptoRampDto())
|
||||||
|
|
|
@ -4,6 +4,18 @@ from ./gen import rpc
|
||||||
|
|
||||||
export response_type
|
export response_type
|
||||||
|
|
||||||
|
const
|
||||||
|
GasFeeLow* = 0
|
||||||
|
GasFeeMedium* = 1
|
||||||
|
GasFeeHigh* = 2
|
||||||
|
|
||||||
|
const
|
||||||
|
ExtraKeyUsername* = "username"
|
||||||
|
ExtraKeyPublicKey* = "publicKey"
|
||||||
|
ExtraKeyPackId* = "packID"
|
||||||
|
|
||||||
|
ExtraKeys = @[ExtraKeyUsername, ExtraKeyPublicKey, ExtraKeyPackId]
|
||||||
|
|
||||||
proc getAccounts*(): RpcResponse[JsonNode] =
|
proc getAccounts*(): RpcResponse[JsonNode] =
|
||||||
return core.callPrivateRPC("eth_accounts")
|
return core.callPrivateRPC("eth_accounts")
|
||||||
|
|
||||||
|
@ -26,11 +38,56 @@ proc suggestedFees*(chainId: int): RpcResponse[JsonNode] =
|
||||||
let payload = %* [chainId]
|
let payload = %* [chainId]
|
||||||
return core.callPrivateRPC("wallet_getSuggestedFees", payload)
|
return core.callPrivateRPC("wallet_getSuggestedFees", payload)
|
||||||
|
|
||||||
proc suggestedRoutes*(accountFrom: string, accountTo: string, amount: string, token: string, toToken: string, disabledFromChainIDs,
|
proc prepareDataForSuggestedRoutesV2(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string,
|
||||||
disabledToChainIDs, preferredChainIDs: seq[int], sendType: int, lockedInAmounts: var Table[string, string]): RpcResponse[JsonNode] =
|
token: string, toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
let payload = %* [sendType, accountFrom, accountTo, amount, token, toToken, disabledFromChainIDs, disabledToChainIDs,
|
extraParamsTable: Table[string, string]): JsonNode =
|
||||||
preferredChainIDs, 1, lockedInAmounts]
|
|
||||||
return core.callPrivateRPC("wallet_getSuggestedRoutes", payload)
|
let data = %* {
|
||||||
|
"uuid": uuid,
|
||||||
|
"sendType": sendType,
|
||||||
|
"addrFrom": accountFrom,
|
||||||
|
"addrTo": accountTo,
|
||||||
|
"amountIn": amountIn,
|
||||||
|
"amountOut": amountOut,
|
||||||
|
"tokenID": token,
|
||||||
|
"toTokenID": toToken,
|
||||||
|
"disabledFromChainIDs": disabledFromChainIDs,
|
||||||
|
"disabledToChainIDs": disabledToChainIDs,
|
||||||
|
"gasFeeMode": GasFeeMedium,
|
||||||
|
"fromLockedAmount": lockedInAmounts
|
||||||
|
}
|
||||||
|
|
||||||
|
# `extraParamsTable` is used for send types like EnsRegister, EnsRelease, EnsSetPubKey, StickersBuy
|
||||||
|
# keys that can be used in `extraParamsTable` are:
|
||||||
|
# "username", "publicKey", "packID"
|
||||||
|
for key, value in extraParamsTable:
|
||||||
|
if key in ExtraKeys:
|
||||||
|
data[key] = %* value
|
||||||
|
else:
|
||||||
|
return nil
|
||||||
|
|
||||||
|
return %* [data]
|
||||||
|
|
||||||
|
proc suggestedRoutesV2*(sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
||||||
|
toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
|
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
||||||
|
let payload = prepareDataForSuggestedRoutesV2(uuid = "", sendType, accountFrom, accountTo, amountIn, amountOut, token, toToken, disabledFromChainIDs,
|
||||||
|
disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
|
if payload.isNil:
|
||||||
|
raise newException(RpcException, "Invalid key in extraParamsTable")
|
||||||
|
return core.callPrivateRPC("wallet_getSuggestedRoutesV2", payload)
|
||||||
|
|
||||||
|
proc suggestedRoutesV2Async*(uuid: string, sendType: int, accountFrom: string, accountTo: string, amountIn: string, amountOut: string, token: string,
|
||||||
|
toToken: string, disabledFromChainIDs, disabledToChainIDs: seq[int], lockedInAmounts: Table[string, string],
|
||||||
|
extraParamsTable: Table[string, string]): RpcResponse[JsonNode] {.raises: [RpcException].} =
|
||||||
|
let payload = prepareDataForSuggestedRoutesV2(uuid, sendType, accountFrom, accountTo, amountIn, amountOut, token, toToken, disabledFromChainIDs,
|
||||||
|
disabledToChainIDs, lockedInAmounts, extraParamsTable)
|
||||||
|
if payload.isNil:
|
||||||
|
raise newException(RpcException, "Invalid key in extraParamsTable")
|
||||||
|
return core.callPrivateRPC("wallet_getSuggestedRoutesV2Async", payload)
|
||||||
|
|
||||||
|
proc stopSuggestedRoutesV2AsyncCalcualtion*() : RpcResponse[JsonNode] =
|
||||||
|
return core.callPrivateRPC("wallet_stopSuggestedRoutesV2AsyncCalcualtion")
|
||||||
|
|
||||||
rpc(getEstimatedLatestBlockNumber, "wallet"):
|
rpc(getEstimatedLatestBlockNumber, "wallet"):
|
||||||
chainId: int
|
chainId: int
|
||||||
|
|
|
@ -188,10 +188,6 @@ QObject {
|
||||||
return root.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
return root.currencyStore.formatCurrencyAmountFromBigInt(balance, symbol, decimals, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllChainIds() {
|
|
||||||
return ModelUtils.joinModelEntries(root.filteredFlatNetworksModel, "chainId", ":")
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDisabledChainIds(enabledChainId) {
|
function getDisabledChainIds(enabledChainId) {
|
||||||
let disabledChainIds = []
|
let disabledChainIds = []
|
||||||
let chainIds = ModelUtils.modelToFlatArray(root.filteredFlatNetworksModel, "chainId")
|
let chainIds = ModelUtils.modelToFlatArray(root.filteredFlatNetworksModel, "chainId")
|
||||||
|
@ -203,8 +199,8 @@ QObject {
|
||||||
return disabledChainIds.join(":")
|
return disabledChainIds.join(":")
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchSuggestedRoutes(cryptoValueRaw) {
|
function fetchSuggestedRoutes(cryptoValueInRaw) {
|
||||||
if (root.swapFormData.isFormFilledCorrectly() && !!cryptoValueRaw) {
|
if (root.swapFormData.isFormFilledCorrectly() && !!cryptoValueInRaw) {
|
||||||
root.swapProposalLoading = true
|
root.swapProposalLoading = true
|
||||||
root.swapOutputData.reset()
|
root.swapOutputData.reset()
|
||||||
|
|
||||||
|
@ -214,12 +210,10 @@ QObject {
|
||||||
let account = selectedAccountEntry.item
|
let account = selectedAccountEntry.item
|
||||||
let accountAddress = account.address
|
let accountAddress = account.address
|
||||||
let disabledChainIds = getDisabledChainIds(root.swapFormData.selectedNetworkChainId)
|
let disabledChainIds = getDisabledChainIds(root.swapFormData.selectedNetworkChainId)
|
||||||
let preferedChainIds = getAllChainIds()
|
|
||||||
|
|
||||||
root.swapStore.fetchSuggestedRoutes(accountAddress, accountAddress,
|
root.swapStore.fetchSuggestedRoutes(accountAddress, accountAddress,
|
||||||
cryptoValueRaw, root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
cryptoValueInRaw, "0", root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
||||||
disabledChainIds, disabledChainIds, preferedChainIds,
|
disabledChainIds, disabledChainIds, Constants.SendType.Swap, "")
|
||||||
Constants.SendType.Swap, "")
|
|
||||||
} else {
|
} else {
|
||||||
root.swapProposalLoading = false
|
root.swapProposalLoading = false
|
||||||
}
|
}
|
||||||
|
@ -230,7 +224,7 @@ QObject {
|
||||||
let accountAddress = account.address
|
let accountAddress = account.address
|
||||||
|
|
||||||
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
||||||
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
||||||
Constants.SendType.Approve, "", false, root.swapOutputData.rawPaths, "")
|
Constants.SendType.Approve, "", false, root.swapOutputData.rawPaths, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +233,7 @@ QObject {
|
||||||
let accountAddress = account.address
|
let accountAddress = account.address
|
||||||
|
|
||||||
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
root.swapStore.authenticateAndTransfer(d.uuid, accountAddress, accountAddress,
|
||||||
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
root.swapFormData.fromTokensKey, root.swapFormData.toTokenKey,
|
||||||
Constants.SendType.Swap, "", false, root.swapOutputData.rawPaths, root.swapFormData.selectedSlippage)
|
Constants.SendType.Swap, "", false, root.swapOutputData.rawPaths, root.swapFormData.selectedSlippage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,12 @@ QtObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchSuggestedRoutes(accountFrom, accountTo, amount, tokenFrom, tokenTo,
|
function fetchSuggestedRoutes(accountFrom, accountTo, amountIn, amountOut, tokenFrom, tokenTo,
|
||||||
disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts) {
|
disabledFromChainIDs, disabledToChainIDs, sendType, lockedInAmounts) {
|
||||||
const value = AmountsArithmetic.fromNumber(amount)
|
const valueIn = AmountsArithmetic.fromNumber(amountIn)
|
||||||
root.walletSectionSendInst.fetchSuggestedRoutesWithParameters(accountFrom, accountTo, value.toFixed(),
|
const valueOut = AmountsArithmetic.fromNumber(amountOut)
|
||||||
tokenFrom, tokenTo, disabledFromChainIDs, disabledToChainIDs, preferredChainIDs, sendType, lockedInAmounts)
|
root.walletSectionSendInst.fetchSuggestedRoutesWithParameters(accountFrom, accountTo, valueIn.toFixed(), valueOut.toFixed(),
|
||||||
|
tokenFrom, tokenTo, disabledFromChainIDs, disabledToChainIDs, sendType, lockedInAmounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
function authenticateAndTransfer(uuid, accountFrom, accountTo,
|
function authenticateAndTransfer(uuid, accountFrom, accountTo,
|
||||||
|
|
|
@ -57,9 +57,9 @@ Item {
|
||||||
return fee
|
return fee
|
||||||
}
|
}
|
||||||
property double totalGasAmountL1Eth: {
|
property double totalGasAmountL1Eth: {
|
||||||
let maxFees = modelData.gasFees.maxFeePerGasM
|
const l1FeeInGWei = modelData.gasFees.l1GasFee
|
||||||
let gasPrice = modelData.gasFees.eip1559Enabled? maxFees : modelData.gasFees.gasPrice
|
const l1FeeInEth = globalUtils.wei2Eth(l1FeeInGWei, 9)
|
||||||
return root.getGasEthValue(gasPrice , modelData.gasFees.l1GasFee)
|
return l1FeeInEth
|
||||||
}
|
}
|
||||||
|
|
||||||
property double totalGasAmountEth: {
|
property double totalGasAmountEth: {
|
||||||
|
|
|
@ -66,9 +66,10 @@ QtObject {
|
||||||
walletSectionSendInst.authenticateAndTransfer(uuid)
|
walletSectionSendInst.authenticateAndTransfer(uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
function suggestedRoutes(amount) {
|
function suggestedRoutes(amountIn, amountOut = "0", extraParamsJson = "") {
|
||||||
const value = AmountsArithmetic.fromNumber(amount)
|
const valueIn = AmountsArithmetic.fromNumber(amountIn)
|
||||||
walletSectionSendInst.suggestedRoutes(value.toFixed())
|
const valueOut = AmountsArithmetic.fromNumber(amountOut)
|
||||||
|
walletSectionSendInst.suggestedRoutes(valueIn.toFixed(), valueOut.toFixed(), extraParamsJson)
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveENS(value) {
|
function resolveENS(value) {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit e6bf7e7df9939efb05b0349a87c163540fe08dd9
|
Subproject commit 4d7c2683f5536c2b5a10a3b7d2230ec9c8860f0f
|
Loading…
Reference in New Issue