feat(wallet) handle new pending transactions notification in filter

Process pending updates events and trigger button show

Also: improve parsing of activity entry

Updates #11233
This commit is contained in:
Stefan 2023-07-05 13:35:11 +01:00 committed by Stefan Dunca
parent e109865f73
commit 976e5c9549
4 changed files with 32 additions and 15 deletions

View File

@ -110,7 +110,7 @@ QtObject:
let response = backend.getTransfersForIdentities(transactionIdentities)
let res = response.result
if response.error != nil or res.kind != JArray or res.len == 0:
raise newException(Defect, "failed fetching transaction details")
error "failed fetching transaction details; err: ", response.error, ", kind: ", res.kind, ", res.len: ", res.len
let transactionsDtos = res.getElems().map(x => x.toTransactionDto())
let trItems = self.transactionsModule.transactionsToItems(transactionsDtos, @[])
@ -122,7 +122,7 @@ QtObject:
let response = backend.getPendingTransactionsForIdentities(pendingTransactionIdentities)
let res = response.result
if response.error != nil or res.kind != JArray or res.len == 0:
raise newException(Defect, "failed fetching pending transactions details")
error "failed fetching pending transactions details; err: ", response.error, ", kind: ", res.kind, ", res.len: ", res.len
let pendingTransactionsDtos = res.getElems().map(x => x.toPendingTransactionDto())
let trItems = self.transactionsModule.transactionsToItems(pendingTransactionsDtos, @[])
@ -174,12 +174,12 @@ QtObject:
if res.errorCode != ErrorCodeSuccess:
error "error fetching activity entries: ", res.errorCode
return
try:
let entries = self.backendToPresentation(res.activities)
self.model.setEntries(entries, res.offset, res.hasMore)
except Exception as e:
error "Error converting activity entries: ", e.msg
let entries = self.backendToPresentation(res.activities)
self.model.setEntries(entries, res.offset, res.hasMore)
if len(entries) > 0:
self.eventsHandler.updateRelevantTimestamp(entries[len(entries) - 1].getTimestamp())
proc updateFilter*(self: Controller) {.slot.} =
self.status.setLoadingData(true)

View File

@ -24,6 +24,8 @@ QtObject:
eventHandlers: Table[string, EventCallbackProc]
walletEventHandlers: Table[string, WalletEventCallbackProc]
# Ignore events older than this relevantTimestamp
relevantTimestamp: int
subscribedAddresses: HashSet[string]
newDataAvailableFn: proc()
@ -64,11 +66,15 @@ QtObject:
discard
proc setupWalletEventHandlers(self: EventsHandler) =
self.walletEventHandlers[EventNewTransfers] = proc (data: WalletSignal) =
let newDataAvailableCallback = proc (data: WalletSignal) =
if self.newDataAvailableFn == nil:
return
var contains = false
if data.at > 0 and self.relevantTimestamp > 0 and data.at < self.relevantTimestamp:
return
# Check addresses if any was reported
var contains = data.accounts.len == 0
for address in data.accounts:
if address in self.subscribedAddresses:
contains = true
@ -76,9 +82,11 @@ QtObject:
if contains:
# TODO: throttle down the number of events to one per 1 seconds until the backend supports subscription
self.newDataAvailableFn()
self.walletEventHandlers[EventNewTransfers] = newDataAvailableCallback
self.walletEventHandlers[EventPendingTransactionUpdate] = newDataAvailableCallback
proc newEventsHandler*(events: EventEmitter): EventsHandler =
new(result, delete)
result.events = events
@ -96,6 +104,9 @@ QtObject:
eventsHandler.handleApiEvents(e)
)
proc updateRelevantTimestamp*(self: EventsHandler, timestamp: int) =
self.relevantTimestamp = timestamp
proc updateSubscribedAddresses*(self: EventsHandler, addresses: seq[string]) =
self.subscribedAddresses.clear()
for address in addresses:

View File

@ -1,4 +1,4 @@
import times, strformat, options
import times, strformat, options, logging
import json, json_serialization
import core, response_type
import stint
@ -289,9 +289,12 @@ proc fromJson*(e: JsonNode, T: typedesc[FilterResponse]): FilterResponse {.inlin
var backendEntities: seq[ActivityEntry]
if e.hasKey("activities"):
let jsonEntries = e["activities"]
backendEntities = newSeq[ActivityEntry](jsonEntries.len)
for i in 0 ..< jsonEntries.len:
backendEntities[i] = fromJson(jsonEntries[i], ActivityEntry)
if jsonEntries.kind == JArray:
backendEntities = newSeq[ActivityEntry](jsonEntries.len)
for i in 0 ..< jsonEntries.len:
backendEntities[i] = fromJson(jsonEntries[i], ActivityEntry)
elif jsonEntries.kind != JNull:
error "Invalid activities field in FilterResponse; kind: ", jsonEntries.kind
result = T(
activities: backendEntities,

View File

@ -37,6 +37,9 @@ const EventRecentHistoryReady*: string = "recent-history-ready"
const EventFetchingHistoryError*: string = "fetching-history-error"
const EventNonArchivalNodeDetected*: string = "non-archival-node-detected"
# Mirrors the pending transfer event from status-go, status-go/services/wallet/transfer/transaction.go
const EventPendingTransactionUpdate*: string = "pending-transaction-update"
proc getTransactionByHash*(chainId: int, hash: string): RpcResponse[JsonNode] {.raises: [Exception].} =
core.callPrivateRPCWithChainId("eth_getTransactionByHash", chainId, %* [hash])