feat(wallet): Introduce simple account transaction list
There's still some things that needs to be done (possibly in future commits): [ ] Asset icons need to be determined so they can be displayed along the transaction [ ] Transaction values need to be converted to decimal values [ ] Date-time formatting [ ] Grouping of transactions by days
This commit is contained in:
parent
116b04a9ef
commit
0f7e08075b
|
@ -5,6 +5,7 @@ import strutils
|
|||
import views/asset_list
|
||||
import views/account_list
|
||||
import views/account_item
|
||||
import views/transaction_list
|
||||
import ../../status/wallet
|
||||
import ../../status/status
|
||||
import chronicles
|
||||
|
@ -15,6 +16,7 @@ QtObject:
|
|||
accounts*: AccountList
|
||||
currentAssetList*: AssetList
|
||||
currentAccount: AccountItemView
|
||||
currentTransactions: TransactionList
|
||||
status: Status
|
||||
totalFiatBalance: string
|
||||
|
||||
|
@ -30,6 +32,7 @@ QtObject:
|
|||
result.accounts = newAccountList()
|
||||
result.currentAccount = newAccountItemView()
|
||||
result.currentAssetList = newAssetList()
|
||||
result.currentTransactions = newTransactionList()
|
||||
result.totalFiatBalance = ""
|
||||
result.setup
|
||||
|
||||
|
@ -68,6 +71,20 @@ QtObject:
|
|||
write = setCurrentAssetList
|
||||
notify = currentAssetListChanged
|
||||
|
||||
proc currentTransactionsChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getCurrentTransactions*(self: WalletView): QVariant {.slot.} =
|
||||
return newQVariant(self.currentTransactions)
|
||||
|
||||
proc setCurrentTransactions*(self: WalletView, transactionList: seq[Transaction]) =
|
||||
self.currentTransactions.setNewData(transactionList)
|
||||
self.currentTransactionsChanged()
|
||||
|
||||
QtProperty[QVariant] transactions:
|
||||
read = getCurrentTransactions
|
||||
write = setCurrentTransactions
|
||||
notify = currentTransactionsChanged
|
||||
|
||||
proc totalFiatBalanceChanged*(self: WalletView) {.signal.}
|
||||
|
||||
proc getTotalFiatBalance(self: WalletView): string {.slot.} =
|
||||
|
@ -163,3 +180,6 @@ QtObject:
|
|||
|
||||
proc addCustomToken*(self: WalletView, address: string, name: string, symbol: string, decimals: string) {.slot.} =
|
||||
self.status.wallet.toggleAsset(symbol, true, address, name, parseInt(decimals), "")
|
||||
|
||||
proc loadTransactionsForAccount*(self: WalletView, address: string) {.slot.} =
|
||||
self.setCurrentTransactions(self.status.wallet.getTransfersByAddress(address))
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import NimQml
|
||||
import tables
|
||||
import ../../../status/wallet
|
||||
|
||||
type
|
||||
TransactionRoles {.pure.} = enum
|
||||
Type = UserRole + 1,
|
||||
Address = UserRole + 2,
|
||||
BlockNumber = UserRole + 3,
|
||||
BlockHash = UserRole + 4,
|
||||
Timestamp = UserRole + 5,
|
||||
GasPrice = UserRole + 6,
|
||||
GasLimit = UserRole + 7,
|
||||
GasUsed = UserRole + 8,
|
||||
Nonce = UserRole + 9,
|
||||
TxStatus = UserRole + 10,
|
||||
Value = UserRole + 11,
|
||||
From = UserRole + 12,
|
||||
To = UserRole + 13
|
||||
|
||||
QtObject:
|
||||
type TransactionList* = ref object of QAbstractListModel
|
||||
transactions*: seq[Transaction]
|
||||
|
||||
proc setup(self: TransactionList) = self.QAbstractListModel.setup
|
||||
|
||||
proc delete(self: TransactionList) =
|
||||
self.QAbstractListModel.delete
|
||||
self.transactions = @[]
|
||||
|
||||
proc newTransactionList*(): TransactionList =
|
||||
new(result, delete)
|
||||
result.transactions = @[]
|
||||
result.setup
|
||||
|
||||
method rowCount(self: TransactionList, index: QModelIndex = nil): int =
|
||||
return self.transactions.len
|
||||
|
||||
method data(self: TransactionList, index: QModelIndex, role: int): QVariant =
|
||||
if not index.isValid:
|
||||
return
|
||||
if index.row < 0 or index.row >= self.transactions.len:
|
||||
return
|
||||
let transaction = self.transactions[index.row]
|
||||
let transactionRole = role.TransactionRoles
|
||||
case transactionRole:
|
||||
of TransactionRoles.Type: result = newQVariant(transaction.typeValue)
|
||||
of TransactionRoles.Address: result = newQVariant(transaction.address)
|
||||
of TransactionRoles.BlockNumber: result = newQVariant(transaction.blockNumber)
|
||||
of TransactionRoles.BlockHash: result = newQVariant(transaction.blockHash)
|
||||
of TransactionRoles.Timestamp: result = newQVariant(transaction.timestamp)
|
||||
of TransactionRoles.GasPrice: result = newQVariant(transaction.gasPrice)
|
||||
of TransactionRoles.GasLimit: result = newQVariant(transaction.gasLimit)
|
||||
of TransactionRoles.GasUsed: result = newQVariant(transaction.gasUsed)
|
||||
of TransactionRoles.Nonce: result = newQVariant(transaction.nonce)
|
||||
of TransactionRoles.TxStatus: result = newQVariant(transaction.txStatus)
|
||||
of TransactionRoles.Value: result = newQVariant(transaction.value)
|
||||
of TransactionRoles.From: result = newQVariant(transaction.fromAddress)
|
||||
of TransactionRoles.To: result = newQVariant(transaction.to)
|
||||
|
||||
method roleNames(self: TransactionList): Table[int, string] =
|
||||
{ TransactionRoles.Type.int:"typeValue",
|
||||
TransactionRoles.Address.int:"address",
|
||||
TransactionRoles.BlockNumber.int:"blockNumber",
|
||||
TransactionRoles.BlockHash.int:"blockHash",
|
||||
TransactionRoles.Timestamp.int:"timestamp",
|
||||
TransactionRoles.GasPrice.int:"gasPrice",
|
||||
TransactionRoles.GasLimit.int:"gasLimit",
|
||||
TransactionRoles.GasUsed.int:"gasUsed",
|
||||
TransactionRoles.Nonce.int:"nonce",
|
||||
TransactionRoles.TxStatus.int:"txStatus",
|
||||
TransactionRoles.Value.int:"value",
|
||||
TransactionRoles.From.int:"fromAddress",
|
||||
TransactionRoles.To.int:"to" }.toTable
|
||||
|
||||
proc addTransactionToList*(self: TransactionList, transaction: Transaction) =
|
||||
self.beginInsertRows(newQModelIndex(), self.transactions.len, self.transactions.len)
|
||||
self.transactions.add(transaction)
|
||||
self.endInsertRows()
|
||||
|
||||
proc setNewData*(self: TransactionList, transactionList: seq[Transaction]) =
|
||||
self.beginResetModel()
|
||||
self.transactions = transactionList
|
||||
self.endResetModel()
|
||||
|
||||
proc forceUpdate*(self: TransactionList) =
|
||||
self.beginResetModel()
|
||||
self.endResetModel()
|
||||
|
|
@ -43,3 +43,12 @@ proc removePeer*(peer: string) =
|
|||
|
||||
proc markTrustedPeer*(peer: string) =
|
||||
discard callPrivateRPC("markTrustedPeer".prefix(false), %* [peer])
|
||||
|
||||
proc getContactByID*(id: string): string =
|
||||
result = callPrivateRPC("getContactByID".prefix, %* [id])
|
||||
|
||||
proc getBlockByNumber*(blockNumber: string): string =
|
||||
result = callPrivateRPC("eth_getBlockByNumber", %* [blockNumber, false])
|
||||
|
||||
proc getTransfersByAddress*(address: string, toBlock: string, limit: string): string =
|
||||
result = callPrivateRPC("wallet_getTransfersByAddress", %* [address, toBlock, limit])
|
||||
|
|
|
@ -75,3 +75,20 @@ type AccountArgs* = ref object of Args
|
|||
|
||||
type
|
||||
StatusGoException* = object of Exception
|
||||
|
||||
type
|
||||
Transaction* = ref object
|
||||
typeValue*: string
|
||||
address*: string
|
||||
blockNumber*: string
|
||||
blockHash*: string
|
||||
timestamp*: string
|
||||
gasPrice*: string
|
||||
gasLimit*: string
|
||||
gasUsed*: string
|
||||
nonce*: string
|
||||
txStatus*: string
|
||||
value*: string
|
||||
fromAddress*: string
|
||||
to*: string
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import strformat
|
|||
import stint
|
||||
import strutils, sequtils
|
||||
import chronicles
|
||||
import types
|
||||
import ../wallet/account
|
||||
|
||||
proc getWalletAccounts*(): seq[WalletAccount] =
|
||||
|
@ -32,6 +33,36 @@ proc getWalletAccounts*(): seq[WalletAccount] =
|
|||
let msg = getCurrentExceptionMsg()
|
||||
error "Failed getting wallet accounts", msg
|
||||
|
||||
proc getTransfersByAddress*(address: string): seq[Transaction] =
|
||||
try:
|
||||
let response = status.getBlockByNumber("latest")
|
||||
let latestBlock = parseJson(response)["result"]
|
||||
|
||||
let transactionsResponse = status.getTransfersByAddress(address, latestBlock["number"].getStr, "0x14")
|
||||
let transactions = parseJson(transactionsResponse)["result"]
|
||||
var accountTransactions: seq[Transaction] = @[]
|
||||
|
||||
for transaction in transactions:
|
||||
accountTransactions.add(Transaction(
|
||||
typeValue: transaction["type"].getStr,
|
||||
address: transaction["address"].getStr,
|
||||
blockNumber: transaction["blockNumber"].getStr,
|
||||
timestamp: transaction["timestamp"].getStr,
|
||||
gasPrice: transaction["gasPrice"].getStr,
|
||||
gasLimit: transaction["gasLimit"].getStr,
|
||||
gasUsed: transaction["gasUsed"].getStr,
|
||||
nonce: transaction["nonce"].getStr,
|
||||
txStatus: transaction["txStatus"].getStr,
|
||||
value: transaction["value"].getStr,
|
||||
fromAddress: transaction["from"].getStr,
|
||||
to: transaction["to"].getStr
|
||||
))
|
||||
result = accountTransactions
|
||||
except:
|
||||
let msg = getCurrentExceptionMsg()
|
||||
error "Failed getting wallet account transactions", msg
|
||||
|
||||
|
||||
proc sendTransaction*(from_address: string, to: string, value: string, password: string): string =
|
||||
var args = %* {
|
||||
"value": fmt"0x{toHex(value)}",
|
||||
|
|
|
@ -4,10 +4,11 @@ import libstatus/tokens as status_tokens
|
|||
import libstatus/settings as status_settings
|
||||
import libstatus/wallet as status_wallet
|
||||
import libstatus/accounts/constants as constants
|
||||
from libstatus/types import GeneratedAccount, DerivedAccount
|
||||
from libstatus/types import GeneratedAccount, DerivedAccount, Transaction
|
||||
import wallet/balance_manager
|
||||
import wallet/account
|
||||
export account
|
||||
export Transaction
|
||||
|
||||
type WalletModel* = ref object
|
||||
events*: EventEmitter
|
||||
|
@ -144,3 +145,6 @@ proc toggleAsset*(self: WalletModel, symbol: string, enable: bool, address: stri
|
|||
account.assetList = self.generateAccountConfiguredAssets(account.address)
|
||||
updateBalance(account, self.getDefaultCurrency())
|
||||
self.events.emit("assetChanged", Args())
|
||||
|
||||
proc getTransfersByAddress*(self: WalletModel, address: string): seq[Transaction] =
|
||||
result = status_wallet.getTransfersByAddress(address)
|
||||
|
|
|
@ -1,8 +1,118 @@
|
|||
import QtQuick 2.3
|
||||
import "../../../imports"
|
||||
|
||||
Item {
|
||||
Component {
|
||||
id: transactionListItem
|
||||
|
||||
Item {
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
height: 64
|
||||
|
||||
Item {
|
||||
|
||||
Rectangle {
|
||||
id: assetIcon
|
||||
color: "gray"
|
||||
width: 40
|
||||
height: 40
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 12
|
||||
radius: 50
|
||||
}
|
||||
|
||||
Text {
|
||||
id: name3
|
||||
text: "HISTORY"
|
||||
id: transferIcon
|
||||
anchors.topMargin: 25
|
||||
anchors.top: parent.top
|
||||
anchors.left: assetIcon.right
|
||||
anchors.leftMargin: 22
|
||||
height: 15
|
||||
width: 15
|
||||
color: to != walletModel.currentAccount.address ? "#4360DF" : "green"
|
||||
text: to != walletModel.currentAccount.address ? "↑" : "↓"
|
||||
}
|
||||
|
||||
Text {
|
||||
id: transactionValue
|
||||
anchors.left: transferIcon.right
|
||||
anchors.leftMargin: Theme.smallPadding
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.bigPadding
|
||||
font.pixelSize: 15
|
||||
text: value + " TOKEN"
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
anchors.right: timeInfo.left
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.bigPadding
|
||||
width: children[0].width + children[1].width
|
||||
|
||||
Text {
|
||||
text: to != walletModel.currentAccount.address ? "To " : "From "
|
||||
anchors.right: addressValue.left
|
||||
color: Theme.darkGrey
|
||||
anchors.top: parent.top
|
||||
font.pixelSize: 15
|
||||
font.strikeout: false
|
||||
}
|
||||
|
||||
Text {
|
||||
id: addressValue
|
||||
text: to
|
||||
width: 100
|
||||
elide: Text.ElideMiddle
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: timeInfo
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: Theme.bigPadding
|
||||
width: children[0].width + children[1].width + children[2].width
|
||||
|
||||
Text {
|
||||
text: "• "
|
||||
font.weight: Font.Bold
|
||||
anchors.right: timeIndicator.left
|
||||
color: Theme.darkGrey
|
||||
anchors.top: parent.top
|
||||
font.pixelSize: 15
|
||||
}
|
||||
|
||||
Text {
|
||||
id: timeIndicator
|
||||
text: "At "
|
||||
anchors.right: timeValue.left
|
||||
color: Theme.darkGrey
|
||||
anchors.top: parent.top
|
||||
font.pixelSize: 15
|
||||
font.strikeout: false
|
||||
}
|
||||
|
||||
Text {
|
||||
id: timeValue
|
||||
text: timestamp
|
||||
anchors.right: parent.right
|
||||
anchors.top: parent.top
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.topMargin: 20
|
||||
anchors.fill: parent
|
||||
model: walletModel.transactions
|
||||
delegate: transactionListItem
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,9 @@ SplitView {
|
|||
anchors.left: collectiblesBtn.right
|
||||
anchors.leftMargin: 32
|
||||
btnText: "History"
|
||||
onClicked: {
|
||||
walletModel.loadTransactionsForAccount(walletModel.currentAccount.address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue