feat: check if a transaction is confirmed before installing a sticker pack

This commit is contained in:
Richard Ramos 2020-09-09 11:49:10 -04:00 committed by Iuri Matias
parent 80f0f9466b
commit 2f1416e042
6 changed files with 70 additions and 7 deletions

View File

@ -5,7 +5,7 @@ import ../../status/messages as messages_model
import ../../status/signals/types
import ../../status/libstatus/types as status_types
import ../../status/libstatus/settings as status_settings
import ../../status/[chat, contacts, status]
import ../../status/[chat, contacts, status, wallet]
import view, views/channels_list, views/message_list
logScope:

View File

@ -1,4 +1,4 @@
import sugar, sequtils, times
import sugar, sequtils, times, strutils
proc handleChatEvents(self: ChatController) =
# Display already saved messages
@ -75,6 +75,10 @@ proc handleChatEvents(self: ChatController) =
self.status.events.on("chat:connected") do(e: Args):
self.view.setConnected(true)
self.status.events.on(PendingTransactionType.BuyingStickerPack.event) do(e: Args):
var data = TransactionMinedArgs(e).data
self.view.installStickerPack(data.parseInt)
proc handleMailserverEvents(self: ChatController) =
self.status.events.on("mailserverTopics") do(e: Args):
var topics = TopicArgs(e).topics

View File

@ -12,6 +12,7 @@ import ../../status/libstatus/stickers as status_stickers
import ../../status/contacts as status_contacts
import ../../status/ens as status_ens
import ../../status/chat/[chat, message]
import ../../status/wallet
import ../../status/libstatus/types
import ../../status/profile/profile
import eth/common/eth_types
@ -115,6 +116,9 @@ QtObject:
try:
let response = self.status.stickers.buyPack(packId, address, price, gas, gasPrice, password)
result = $(%* { "result": %response })
# TODO:
# check if response["error"] is not null and handle the error
self.status.wallet.trackPendingTransaction(address, response, PendingTransactionType.BuyingStickerPack, $packId)
except RpcException as e:
result = $(%* { "error": %* { "message": %e.msg }})

View File

@ -51,6 +51,7 @@ proc init*(self: WalletController) =
of "newblock":
for acc in data.accounts:
self.status.wallet.updateAccount(acc)
self.status.wallet.checkPendingTransactions(acc, data.blockNumber)
# TODO: show notification
of "recent-history-fetching":
self.view.setHistoryFetchState(data.accounts, true)

View File

@ -31,6 +31,9 @@ proc getWalletAccounts*(): seq[WalletAccount] =
let msg = getCurrentExceptionMsg()
error "Failed getting wallet accounts", msg
proc getTransactionReceipt*(transactionHash: string): string =
result = callPrivateRPC("eth_getTransactionReceipt", %* [transactionHash])
proc getTransfersByAddress*(address: string): seq[types.Transaction] =
try:
let response = getBlockByNumber("latest")

View File

@ -2,6 +2,7 @@ import eventemitter, json, strformat, strutils, chronicles, sequtils, httpclient
import json_serialization, stint
from eth/common/utils import parseAddress
from eth/common/eth_types import EthAddress
from libstatus/core import getBlockByNumber
import libstatus/accounts as status_accounts
import libstatus/tokens as status_tokens
import libstatus/settings as status_settings
@ -18,12 +19,31 @@ export Transaction
logScope:
topics = "wallet-model"
type PendingTransactionType* {.pure.} = enum
RegisterENS = "RegisterENS",
ReleaseENS = "ReleaseENS",
BuyingStickerPack = "BuyingStickerPack"
proc event*(self:PendingTransactionType):string =
result = "transaction:" & $self
type PendingTransaction* = object
transactionHash*: string
blockNumber*: int
trxType*: PendingTransactionType
data*: string
mined: bool
type TransactionMinedArgs* = ref object of Args
data*: string
type WalletModel* = ref object
events*: EventEmitter
accounts*: seq[WalletAccount]
defaultCurrency*: string
tokens*: JsonNode
totalBalance*: float
events*: EventEmitter
accounts*: seq[WalletAccount]
defaultCurrency*: string
tokens*: JsonNode
totalBalance*: float
pendingTransactions: Table[string, seq[PendingTransaction]]
proc getDefaultCurrency*(self: WalletModel): string
proc calculateTotalFiatBalance*(self: WalletModel)
@ -32,6 +52,7 @@ proc newWalletModel*(events: EventEmitter): WalletModel =
result = WalletModel()
result.accounts = @[]
result.tokens = %* []
result.pendingTransactions = initTable[string, seq[PendingTransaction]]()
result.events = events
result.defaultCurrency = ""
result.totalBalance = 0.0
@ -68,6 +89,36 @@ proc estimateGas*(self: WalletModel, source, to, value: string): int =
except RpcException as e:
raise
proc trackPendingTransaction*(self: WalletModel, address: string, trxHash: string, trxType: PendingTransactionType, data: string) =
let latestBlock = getBlockByNumber("latest").parseJson()["result"].getInt
if not self.pendingTransactions.hasKey(address):
self.pendingTransactions[address] = @[]
self.pendingTransactions[address].add PendingTransaction(
transactionHash: trxHash,
trxType: trxType,
blockNumber: latestBlock,
data: data,
mined: false
)
proc getTransactionReceipt*(self: WalletModel, transactionHash: string): JsonNode =
result = status_wallet.getTransactionReceipt(transactionHash).parseJSON()["result"]
proc checkPendingTransactions*(self: WalletModel, address: string, blockNumber: int) =
if not self.pendingTransactions.hasKey(address): return
for trx in self.pendingTransactions[address].mitems:
if trx.mined: continue
let transactionReceipt = self.getTransactionReceipt(trx.transactionHash)
if transactionReceipt.kind != JNull:
trx.mined = true
if transactionReceipt{"status"}.getStr == "0x1": # mined successfully
self.events.emit(trx.trxType.event, TransactionMinedArgs(data: trx.data))
else:
discard # TODO: what should we do if the transaction reverted?
proc estimateTokenGas*(self: WalletModel, source, to, assetAddress, value: string): int =
var
transfer: Transfer