feat(wallet) fetch multi-transaction information

Prepare the business logic for the upcoming multi-transaction UX
changes.

Bump the status-go HEAD with the corresponding changes

Updates #7663
This commit is contained in:
Stefan 2023-03-01 20:36:51 +01:00 committed by Stefan Dunca
parent 77ac9b0e78
commit 7cbe7332b8
8 changed files with 139 additions and 8 deletions

View File

@ -25,7 +25,7 @@ proc initItem*(
result.isTest = isTest result.isTest = isTest
proc `$`*(self: Item): string = proc `$`*(self: Item): string =
result = fmt"""AllTokensItem( result = fmt"""SavedAddressItem(
name: {self.name}, name: {self.name},
address: {self.address}, address: {self.address},
favourite: {self.favourite}, favourite: {self.favourite},

View File

@ -149,3 +149,6 @@ proc getCurrencyFormat*(self: Controller, symbol: string): CurrencyFormatDto =
proc findTokenSymbolByAddress*(self: Controller, address: string): string = proc findTokenSymbolByAddress*(self: Controller, address: string): string =
return self.walletAccountService.findTokenSymbolByAddress(address) return self.walletAccountService.findTokenSymbolByAddress(address)
proc getMultiTransactions*(self: Controller, transactionIDs: seq[int]): seq[MultiTransactionDto] =
return self.transactionService.getMultiTransactions(transactionIDs)

View File

@ -1,6 +1,6 @@
import NimQml, stint, json, sequtils, sugar import NimQml, stint, json, sequtils, sugar
import ./io_interface, ./view, ./controller, ./item, ./utils import ./io_interface, ./view, ./controller, ./item, ./utils, ./multi_transaction_item
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
import ../../../../global/global_singleton import ../../../../global/global_singleton
import ../../../../core/eventemitter import ../../../../core/eventemitter
@ -76,6 +76,22 @@ proc transactionsToItems(self: Module, transactions: seq[TransactionDto], collec
let gweiFormat = self.controller.getCurrencyFormat("Gwei") let gweiFormat = self.controller.getCurrencyFormat("Gwei")
let ethFormat = self.controller.getCurrencyFormat("ETH") let ethFormat = self.controller.getCurrencyFormat("ETH")
# TODO: Continue merging multi-transactions with transactions
#
# let transactionIDs = transactions.filter(t => t.multiTransactionID != MultiTransactionMissingID).map(t => t.multiTransactionID)
# let multiTransactions = self.controller.getMultiTransactions(transactionIDs)
# for mt in multiTransactions:
# let mtItem = multiTransactionToItem(mt)
#
# Tip: depending of the new design best will be to replace the transaction.View
# with a new ActivityEntry that contains eighter a transaction or a multi-transaction
# Refactor transaction Model to serve ActivityEntry istead of Views
#
# Here we should filter all transactions that are part of a multi-transaciton
# and add them to the multi-transaction View associated with an ActivityEntry
# and the remaining "free" transactions to the corresponding ActivityEntry
# TODO: check TransactionsItem changes
transactions.map(t => (block: transactions.map(t => (block:
if t.typeValue == ERC721_TRANSACTION_TYPE: if t.typeValue == ERC721_TRANSACTION_TYPE:
for c in collectibles: for c in collectibles:

View File

@ -0,0 +1,71 @@
import strformat
import ../../../../../app_service/service/transaction/dto
const MultiTransactionMissingID* = 0
type
MultiTransactionItem* = object
id: int
timestamp: int
fromAddress: string
toAddress: string
fromAsset: string
toAsset: string
fromAmount: string
multiTxtype: MultiTransactionType
proc initMultiTransactionItem*(
id: int,
timestamp: int,
fromAddress: string,
toAddress: string,
fromAsset: string,
toAsset: string,
fromAmount: string,
multiTxtype: MultiTransactionType,
): MultiTransactionItem =
result.id = id
result.timestamp = timestamp
result.fromAddress = fromAddress
result.toAddress = toAddress
result.fromAsset = fromAsset
result.toAsset = toAsset
result.fromAmount = fromAmount
result.multiTxtype = multiTxtype
proc `$`*(self: MultiTransactionItem): string =
result = fmt"""MultiTransactionItem(
id: {self.id},
timestamp: {self.timestamp},
fromAddress: {self.fromAddress},
toAddress: {self.toAddress},
fromAsset: {self.fromAsset},
toAsset: {self.toAsset},
fromAmount: {self.fromAmount},
multiTxtype: {self.multiTxtype},
]"""
proc getId*(self: MultiTransactionItem): int =
return self.id
proc getTimestamp*(self: MultiTransactionItem): int =
return self.timestamp
proc getFromAddress*(self: MultiTransactionItem): string =
return self.fromAddress
proc getToAddress*(self: MultiTransactionItem): string =
return self.toAddress
proc getFromAsset*(self: MultiTransactionItem): string =
return self.fromAsset
proc getToAsset*(self: MultiTransactionItem): string =
return self.toAsset
proc getFromAmount*(self: MultiTransactionItem): string =
return self.fromAmount
proc getMultiTxtype*(self: MultiTransactionItem): MultiTransactionType =
return self.multiTxtype

View File

@ -8,6 +8,7 @@ import ../../../shared_models/currency_amount
import ../../../shared_models/currency_amount_utils import ../../../shared_models/currency_amount_utils
import ./item import ./item
import ./multi_transaction_item
proc hex2GweiCurrencyAmount(hexValueStr: string, gweiFormat: CurrencyFormatDto): CurrencyAmount = proc hex2GweiCurrencyAmount(hexValueStr: string, gweiFormat: CurrencyFormatDto): CurrencyAmount =
let value = parseFloat(singletonInstance.utils.hex2Gwei(hexValueStr)) let value = parseFloat(singletonInstance.utils.hex2Gwei(hexValueStr))
@ -79,4 +80,16 @@ proc transactionToNFTItem*(t: TransactionDto, c: CollectibleDto, ethFormat: Curr
t.tokenId, t.tokenId,
c.name, c.name,
c.imageUrl c.imageUrl
)
proc multiTransactionToItem*(t: MultiTransactionDto): MultiTransactionItem =
return initMultiTransactionItem(
t.id,
t.timestamp,
t.fromAddress,
t.toAddress,
t.fromAsset,
t.toAsset,
t.fromAmount,
t.multiTxtype
) )

View File

@ -33,7 +33,7 @@ type MultiTransactionDto* = ref object of RootObj
toAsset* {.serializedFieldName("toAsset").}: string toAsset* {.serializedFieldName("toAsset").}: string
fromAmount* {.serializedFieldName("fromAmount").}: string fromAmount* {.serializedFieldName("fromAmount").}: string
multiTxtype* {.serializedFieldName("type").}: MultiTransactionType multiTxtype* {.serializedFieldName("type").}: MultiTransactionType
type type
TransactionDto* = ref object of RootObj TransactionDto* = ref object of RootObj
id*: string id*: string
@ -151,6 +151,20 @@ proc toPendingTransactionDto*(jsonObj: JsonNode): TransactionDto =
discard jsonObj.getProp("data", result.input) discard jsonObj.getProp("data", result.input)
discard jsonObj.getProp("symbol", result.symbol) discard jsonObj.getProp("symbol", result.symbol)
proc toMultiTransactionDto*(jsonObj: JsonNode): MultiTransactionDto =
result = MultiTransactionDto()
discard jsonObj.getProp("id", result.id)
discard jsonObj.getProp("timestamp", result.timestamp)
discard jsonObj.getProp("fromAddress", result.fromAddress)
discard jsonObj.getProp("toAddress", result.toAddress)
discard jsonObj.getProp("fromAsset", result.fromAsset)
discard jsonObj.getProp("toAsset", result.toAsset)
discard jsonObj.getProp("fromAmount", result.fromAmount)
var multiTxType: int
discard jsonObj.getProp("type", multiTxType)
result.multiTxtype = cast[MultiTransactionType](multiTxType)
proc cmpTransactions*(x, y: TransactionDto): int = proc cmpTransactions*(x, y: TransactionDto): int =
# Sort proc to compare transactions from a single account. # Sort proc to compare transactions from a single account.
# Compares first by block number, then by nonce # Compares first by block number, then by nonce

View File

@ -158,6 +158,16 @@ QtObject:
error "error: ", errDescription error "error: ", errDescription
return return
proc getMultiTransactions*(self: Service, transactionIDs: seq[int]): seq[MultiTransactionDto] =
try:
let response = transactions.getMultiTransactions(transactionIDs).result
return response.getElems().map(x => x.toMultiTransactionDto())
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
return
proc watchTransactionResult*(self: Service, watchTxResult: string) {.slot.} = proc watchTransactionResult*(self: Service, watchTxResult: string) {.slot.} =
let watchTxResult = parseJson(watchTxResult) let watchTxResult = parseJson(watchTxResult)
let success = watchTxResult["isSuccessfull"].getBool let success = watchTxResult["isSuccessfull"].getBool

View File

@ -32,20 +32,24 @@ proc trackPendingTransaction*(hash: string, fromAddress: string, toAddress: stri
}] }]
core.callPrivateRPC("wallet_storePendingTransaction", payload) core.callPrivateRPC("wallet_storePendingTransaction", payload)
proc getTransactionReceipt*(chainId: int, transactionHash: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc getTransactionReceipt*(chainId: int, transactionHash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPCWithChainId("eth_getTransactionReceipt", chainId, %* [transactionHash]) core.callPrivateRPCWithChainId("eth_getTransactionReceipt", chainId, %* [transactionHash])
proc deletePendingTransaction*(chainId: int, transactionHash: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc deletePendingTransaction*(chainId: int, transactionHash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, transactionHash] let payload = %* [chainId, transactionHash]
result = core.callPrivateRPC("wallet_deletePendingTransactionByChainID", payload) result = core.callPrivateRPC("wallet_deletePendingTransactionByChainID", payload)
proc fetchCryptoServices*(): RpcResponse[JsonNode] {.raises: [Exception].} = proc fetchCryptoServices*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = core.callPrivateRPC("wallet_getCryptoOnRamps", %* []) result = core.callPrivateRPC("wallet_getCryptoOnRamps", %* [])
proc createMultiTransaction*(multiTransaction: MultiTransactionDto, data: seq[TransactionBridgeDto], password: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc createMultiTransaction*(multiTransaction: MultiTransactionDto, data: seq[TransactionBridgeDto], password: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [multiTransaction, data, hashPassword(password)] let payload = %* [multiTransaction, data, hashPassword(password)]
result = core.callPrivateRPC("wallet_createMultiTransaction", payload) result = core.callPrivateRPC("wallet_createMultiTransaction", payload)
proc getMultiTransactions*(transactionIDs: seq[int]): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [transactionIDs]
result = core.callPrivateRPC("wallet_getMultiTransactions", payload)
proc watchTransaction*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc watchTransaction*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, hash] let payload = %* [chainId, hash]
core.callPrivateRPC("wallet_watchTransactionByChainID", payload) core.callPrivateRPC("wallet_watchTransactionByChainID", payload)