Skip to content

Commit

Permalink
draft for pending Tx
Browse files Browse the repository at this point in the history
  • Loading branch information
Khushboo-dev-cpp committed Nov 18, 2022
1 parent 93428d8 commit e7b0eb7
Show file tree
Hide file tree
Showing 20 changed files with 154 additions and 72 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ proc delete*(self: Controller) =
proc init*(self: Controller) =
self.events.on(SignalType.Wallet.event) do(e:Args):
var data = WalletSignal(e)
echo "SignalType.Wallet.event >>>>>>>>>",data.eventType
case data.eventType:
of "new-transfers":
for account in data.accounts:
Expand Down Expand Up @@ -81,8 +82,11 @@ proc init*(self: Controller) =
self.events.on(SIGNAL_SUGGESTED_ROUTES_READY) do(e:Args):
self.delegate.suggestedRoutesReady(SuggestedRoutesArgs(e).suggestedRoutes)

proc checkPendingTransactions*(self: Controller) =
self.transactionService.checkPendingTransactions()
self.events.on(SIGNAL_DELETE_PENDING_TX) do(e:Args):
self.walletAccountService.checkRecentHistory()

proc checkPendingTransactions*(self: Controller): seq[TransactionDto] =
return self.transactionService.checkPendingTransactions()

proc checkRecentHistory*(self: Controller) =
self.walletAccountService.checkRecentHistory()
Expand Down
11 changes: 9 additions & 2 deletions src/app/modules/main/wallet_section/transactions/item.nim
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ type
baseGasFees: string
totalFees: string
maxTotalFees: string
symbol: string

proc initItem*(
id: string,
Expand All @@ -53,7 +54,8 @@ proc initItem*(
isTimeStamp: bool,
baseGasFees: string,
totalFees: string,
maxTotalFees: string
maxTotalFees: string,
symbol: string
): Item =
result.id = id
result.typ = typ
Expand All @@ -80,6 +82,7 @@ proc initItem*(
result.baseGasFees = baseGasFees
result.totalFees = totalFees
result.maxTotalFees = maxTotalFees
result.symbol = symbol

proc `$`*(self: Item): string =
result = fmt"""AllTokensItem(
Expand Down Expand Up @@ -108,6 +111,7 @@ proc `$`*(self: Item): string =
baseGasFees: {self.baseGasFees},
totalFees: {self.totalFees},
maxTotalFees: {self.maxTotalFees},
symbol: {self.symbol},
]"""

proc getId*(self: Item): string =
Expand Down Expand Up @@ -183,4 +187,7 @@ proc getTotalFees*(self: Item): string =
return self.totalFees

proc getMaxTotalFees*(self: Item): string =
return self.maxTotalFees
return self.maxTotalFees

proc getSymbol*(self: Item): string =
return self.symbol
18 changes: 13 additions & 5 deletions src/app/modules/main/wallet_section/transactions/model.nim
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ type
BaseGasFees
TotalFees
MaxTotalFees
Symbol

QtObject:
type
Model* = ref object of QAbstractListModel
items: seq[Item]
pendingItems: seq[Item]
itemsWithDateHeaders: seq[Item]
hasMore: bool

Expand Down Expand Up @@ -94,7 +96,8 @@ QtObject:
ModelRole.IsTimeStamp.int: "isTimeStamp",
ModelRole.BaseGasFees.int: "baseGasFees",
ModelRole.TotalFees.int: "totalFees",
ModelRole.MaxTotalFees.int: "maxTotalFees"
ModelRole.MaxTotalFees.int: "maxTotalFees",
ModelRole.Symbol.int: "symbol"
}.toTable

method data(self: Model, index: QModelIndex, role: int): QVariant =
Expand Down Expand Up @@ -158,6 +161,8 @@ QtObject:
result = newQVariant(item.getTotalFees())
of ModelRole.MaxTotalFees:
result = newQVariant(item.getMaxTotalFees())
of ModelRole.Symbol:
result = newQVariant(item.getSymbol())

proc setItems*(self: Model, items: seq[Item]) =
self.beginResetModel()
Expand Down Expand Up @@ -187,6 +192,8 @@ QtObject:
proc cmpTransactions*(x, y: Item): int =
# Sort proc to compare transactions from a single account.
# Compares first by block number, then by nonce
if x.getBlockNumber().isEmptyOrWhitespace or y.getBlockNumber().isEmptyOrWhitespace :
return cmp(x.getTimestamp(), y.getTimestamp())
result = cmp(x.getBlockNumber().parseHexInt, y.getBlockNumber().parseHexInt)
if result == 0:
result = cmp(x.getNonce(), y.getNonce())
Expand Down Expand Up @@ -222,19 +229,20 @@ QtObject:
t.baseGasFees,
t.totalFees,
t.maxTotalFees,
t.symbol
))

var allTxs = self.items.concat(newTxItems)
allTxs.sort(cmpTransactions, SortOrder.Descending)
eth_service_utils.deduplicate(allTxs, tx => tx.getId())
eth_service_utils.deduplicate(allTxs, tx => tx.getTxHash())

# add day headers to the transaction list
var itemsWithDateHeaders: seq[Item] = @[]
var tempTimeStamp: Time
for tx in allTxs:
let duration = fromUnix(tx.getTimestamp()) - tempTimeStamp
if(duration.inDays != 0):
itemsWithDateHeaders.add(initItem("", "", "", "", "", tx.getTimestamp(), "", "", "", "", "", "", "", "", "", 0, "", "", "", "", 0, true, "", "", ""))
let durationInDays = (tempTimeStamp.toTimeInterval() - fromUnix(tx.getTimestamp()).toTimeInterval()).days
if(durationInDays != 0):
itemsWithDateHeaders.add(initItem("", "", "", "", "", tx.getTimestamp(), "", "", "", "", "", "", "", "", "", 0, "", "", "", "", 0, true, "", "", "", ""))
itemsWithDateHeaders.add(tx)
tempTimeStamp = fromUnix(tx.getTimestamp())

Expand Down
5 changes: 4 additions & 1 deletion src/app/modules/main/wallet_section/transactions/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,15 @@ method isLoaded*(self: Module): bool =
return self.moduleLoaded

method viewDidLoad*(self: Module) =
echo "TX module.nim viewDidLoad >>>"
self.checkRecentHistory()
let accounts = self.getWalletAccounts()

self.moduleLoaded = true
self.delegate.transactionsModuleDidLoad()

self.controller.checkPendingTransactions()
echo "SETTING CHEKCING PENDING TX"
self.view.setPendingTx(self.controller.checkPendingTransactions())

method switchAccount*(self: Module, accountIndex: int) =
let walletAccount = self.controller.getWalletAccount(accountIndex)
Expand Down Expand Up @@ -146,6 +148,7 @@ method onUserAuthenticated*(self: Module, password: string) =

method transactionWasSent*(self: Module, result: string) =
self.view.transactionWasSent(result)
self.view.setPendingTx(self.controller.checkPendingTransactions())

method suggestedFees*(self: Module, chainId: int): string =
return self.controller.suggestedFees(chainId)
Expand Down
6 changes: 6 additions & 0 deletions src/app/modules/main/wallet_section/transactions/view.nim
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,9 @@ QtObject:
return self.delegate.getLastTxBlockNumber()

proc suggestedRoutesReady*(self: View, suggestedRoutes: string) {.signal.}

proc setPendingTx*(self: View, pendingTx: seq[TransactionDto]) =
for tx in pendingTx:
if not self.models.hasKey(tx.fromAddress):
self.models[tx.fromAddress] = newModel()
self.models[tx.fromAddress].addNewTransactions(@[tx], false)
2 changes: 1 addition & 1 deletion src/app_service/service/eth/utils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ proc isUnique*[T](key: T, existingKeys: var seq[T]): bool =

proc deduplicate*[T](txs: var seq[T], key: (T) -> string) =
var existingKeys: seq[string] = @[]
txs.keepIf(tx => tx.key().isUnique(existingKeys))
txs.keepIf(tx => tx.key().isEmptyOrWhitespace or tx.key().isUnique(existingKeys))

# TODO: make this public in nim-web3 lib
proc stripLeadingZeros*(value: string): string =
Expand Down
19 changes: 19 additions & 0 deletions src/app_service/service/transaction/async_tasks.nim
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,22 @@ const getSuggestedRoutesTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall
"error": fmt"Error getting suggested routes: {e.msg}"
}
arg.finish(output)

type
WatchTransactionTaskArg* = ref object of QObjectTaskArg
chainId: int
txHash: string

const watchTransactionsTask*: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[WatchTransactionTaskArg](argEncoded)
try:
let output = %*{
"txHash": arg.txHash,
"isSuccessfull": transactions.watchTransaction(arg.chainId, arg.txHash).error.isNil,
}
arg.finish(output)
except Exception as e:
let output = %* {
"hash": arg.txHash,
"isSuccessfull": false
}
37 changes: 36 additions & 1 deletion src/app_service/service/transaction/dto.nim
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json, strutils, stint, json_serialization, strformat
include ../../common/json_utils
import ../network/dto
import ../../common/conversion as service_conversion

type
PendingTransactionTypeDto* {.pure.} = enum
Expand Down Expand Up @@ -53,7 +54,8 @@ type
baseGasFees*: string
totalFees*: string
maxTotalFees*: string

additionalData*: string
symbol*: string

proc getTotalFees(tip: string, baseFee: string, gasUsed: string, maxFee: string): string =
var maxFees = stint.fromHex(Uint256, maxFee)
Expand Down Expand Up @@ -93,6 +95,39 @@ proc toTransactionDto*(jsonObj: JsonNode): TransactionDto =
result.totalFees = getTotalFees(result.maxPriorityFeePerGas, result.baseGasFees, result.gasUsed, result.maxFeePerGas)
result.maxTotalFees = getMaxTotalFees(result.maxFeePerGas, result.gasLimit)

#type PendingTransaction struct {
# Hash common.Hash `json:"hash"`
# Timestamp uint64 `json:"timestamp"`
# Value bigint.BigInt `json:"value"`
# From common.Address `json:"from"`
# To common.Address `json:"to"`
# Data string `json:"data"`
# Symbol string `json:"symbol"`
# GasPrice bigint.BigInt `json:"gasPrice"`
# GasLimit bigint.BigInt `json:"gasLimit"`
# Type PendingTrxType `json:"type"`
# AdditionalData string `json:"additionalData"`
# ChainID uint64 `json:"network_id"`
# MultiTransactionID int64 `json:"multi_transaction_id"`
#}

proc toPendingTransactionDto*(jsonObj: JsonNode): TransactionDto =
result = TransactionDto()
echo "toPendingTransactionDto = ",jsonObj
result.value = "0x" & toHex(toUInt256(parseFloat(jsonObj{"value"}.getStr)))
discard jsonObj.getProp("hash", result.txHash)
result.timestamp = u256(jsonObj{"timestamp"}.getInt)
discard jsonObj.getProp("from", result.fromAddress)
discard jsonObj.getProp("to", result.to)
discard jsonObj.getProp("gasPrice", result.gasPrice)
discard jsonObj.getProp("gasLimit", result.gasLimit)
discard jsonObj.getProp("type", result.typeValue)
discard jsonObj.getProp("network_id", result.chainId)
discard jsonObj.getProp("multi_transaction_id", result.multiTransactionID)
discard jsonObj.getProp("additionalData", result.additionalData)
discard jsonObj.getProp("data", result.input)
discard jsonObj.getProp("symbol", result.symbol)

proc cmpTransactions*(x, y: TransactionDto): int =
# Sort proc to compare transactions from a single account.
# Compares first by block number, then by nonce
Expand Down
54 changes: 42 additions & 12 deletions src/app_service/service/transaction/service.nim
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ include ../../common/json_utils
const SIGNAL_TRANSACTIONS_LOADED* = "transactionsLoaded"
const SIGNAL_TRANSACTION_SENT* = "transactionSent"
const SIGNAL_SUGGESTED_ROUTES_READY* = "suggestedRoutesReady"
const SIGNAL_DELETE_PENDING_TX* = "deletePendingTransaction"

type
EstimatedTime* {.pure.} = enum
Expand Down Expand Up @@ -73,7 +74,7 @@ QtObject:
tokenService: token_service.Service

# Forward declaration
proc checkPendingTransactions*(self: Service)
proc checkPendingTransactions*(self: Service): seq[TransactionDto]
proc checkPendingTransactions*(self: Service, address: string)

proc delete*(self: Service) =
Expand All @@ -97,12 +98,31 @@ QtObject:
proc doConnect*(self: Service) =
self.events.on(SignalType.Wallet.event) do(e:Args):
var data = WalletSignal(e)
echo "SignalType.Wallet.event >>>>>>>>>>",data.eventType
if(data.eventType == "newblock"):
echo "SignalType.Wallet.event data.eventType newblock >>>>>>>>>>"
for acc in data.accounts:
self.checkPendingTransactions(acc)

proc init*(self: Service) =
self.doConnect()

proc watchTransactionResult*(self: Service, watchTxResult: string) {.slot.} =
let watchTxResult = parseJson(watchTxResult)
let txHash = watchTxResult["txHash"].getStr
let success = watchTxResult["isSuccessfull"].getBool
if(success):
self.events.emit(SIGNAL_DELETE_PENDING_TX)

proc watchTransaction*(self: Service, chainId: int, transactionHash: string) =
let arg = WatchTransactionTaskArg(
chainId: chainId,
txHash: transactionHash,
tptr: cast[ByteAddress](watchTransactionsTask),
vptr: cast[ByteAddress](self.vptr),
slot: "watchTransactionResult",
)
self.threadpool.start(arg)

proc getTransactionReceipt*(self: Service, chainId: int, transactionHash: string): JsonNode =
try:
Expand All @@ -119,19 +139,19 @@ QtObject:
let errDescription = e.msg
error "error deleting pending transaction: ", errDescription

proc confirmTransactionStatus(self: Service, pendingTransactions: JsonNode) =
for trx in pendingTransactions.getElems():
let transactionReceipt = self.getTransactionReceipt(trx["network_id"].getInt, trx["hash"].getStr)
proc confirmTransactionStatus(self: Service, pendingTransactions: seq[TransactionDto]) =
for trx in pendingTransactions:
let transactionReceipt = self.getTransactionReceipt(trx.chainId, trx.txHash)
if transactionReceipt != nil and transactionReceipt.kind != JNull:
self.deletePendingTransaction(trx["network_id"].getInt, trx["hash"].getStr)
self.deletePendingTransaction(trx.chainId, trx.txHash)
let ev = TransactionMinedArgs(
data: trx["additionalData"].getStr,
transactionHash: trx["hash"].getStr,
chainId: trx["network_id"].getInt,
data: trx.additionalData,
transactionHash: trx.txHash,
chainId: trx.chainId,
success: transactionReceipt{"status"}.getStr == "0x1",
revertReason: ""
)
self.events.emit(parseEnum[PendingTransactionTypeDto](trx["type"].getStr).event, ev)
self.events.emit(parseEnum[PendingTransactionTypeDto](trx.typeValue).event, ev)

proc getPendingTransactions*(self: Service): JsonNode =
try:
Expand All @@ -151,14 +171,21 @@ QtObject:
let errDescription = e.msg
error "error getting pending txs by address: ", errDescription, address

proc checkPendingTransactions*(self: Service) =
proc checkPendingTransactions*(self: Service): seq[TransactionDto] =
# TODO move this to a thread
let pendingTransactions = self.getPendingTransactions()
echo "checkPendingTransactions >>> ",pendingTransactions.kind
echo "checkPendingTransactions >>> ",pendingTransactions.len
if (pendingTransactions.kind == JArray and pendingTransactions.len > 0):
self.confirmTransactionStatus(pendingTransactions)
let pendingTxs = pendingTransactions.getElems().map(x => x.toPendingTransactionDto())
self.confirmTransactionStatus(pendingTxs)
for tx in pendingTxs:
self.watchTransaction(tx.chainId, tx.txHash)
return pendingTxs

proc checkPendingTransactions*(self: Service, address: string) =
self.confirmTransactionStatus(self.getPendingOutboundTransactionsByAddress(address))
let pendingTxs = self.getPendingOutboundTransactionsByAddress(address).getElems().map(x => x.toPendingTransactionDto())
self.confirmTransactionStatus(pendingTxs)

proc trackPendingTransaction*(self: Service, hash: string, fromAddress: string, toAddress: string, trxType: string,
data: string, chainId: int) =
Expand Down Expand Up @@ -337,6 +364,9 @@ QtObject:
paths,
password,
)
if response.result{"hashes"} != nil:
let txHash = response.result["hashes"][$chainID][0].getStr
self.watchTransaction(chainID, txHash)
let output = %* {"result": response.result{"hashes"}, "success":true, "uuid": %uuid }
self.events.emit(SIGNAL_TRANSACTION_SENT, TransactionSentArgs(result: $output))
except Exception as e:
Expand Down
4 changes: 4 additions & 0 deletions src/backend/transactions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,7 @@ proc createMultiTransaction*(multiTransaction: MultiTransactionDto, data: seq[Tr
var hashed_password = "0x" & $keccak_256.digest(password)
let payload = %* [multiTransaction, data, hashed_password]
result = core.callPrivateRPC("wallet_createMultiTransaction", payload)

proc watchTransaction*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [chainId, hash]
core.callPrivateRPC("wallet_watchTransactionByChainID", payload)
1 change: 1 addition & 0 deletions ui/app/AppLayouts/Onboarding/views/LoginView.qml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ Item {
property StartupStore startupStore

Component.onCompleted: {
d.doLogin("khushboomehta")
d.resetLogin()
}

Expand Down
Loading

0 comments on commit e7b0eb7

Please sign in to comment.