feat: make token send and eth send work
This commit is contained in:
parent
19f8f8e457
commit
81e7dffaa2
|
@ -157,8 +157,8 @@ QtObject:
|
|||
read = getAccountList
|
||||
notify = accountListChanged
|
||||
|
||||
proc onSendTransaction*(self: WalletView, from_value: string, to: string, value: string, password: string): string {.slot.} =
|
||||
result = self.status.wallet.sendTransaction(from_value, to, value, password)
|
||||
proc onSendTransaction*(self: WalletView, from_value: string, to: string, assetAddress: string, value: string, password: string): string {.slot.} =
|
||||
return self.status.wallet.sendTransaction(from_value, to, assetAddress, value, password)
|
||||
|
||||
proc getDefaultAccount*(self: WalletView): string {.slot.} =
|
||||
self.currentAccount.address
|
||||
|
|
|
@ -7,6 +7,7 @@ type
|
|||
Symbol = UserRole + 2,
|
||||
Value = UserRole + 3,
|
||||
FiatValue = UserRole + 4
|
||||
Address = UserRole + 5
|
||||
|
||||
QtObject:
|
||||
type AssetList* = ref object of QAbstractListModel
|
||||
|
@ -32,6 +33,7 @@ QtObject:
|
|||
of "symbol": result = asset.symbol
|
||||
of "value": result = asset.value
|
||||
of "fiatValue": result = asset.fiatValue
|
||||
of "address": result = asset.address
|
||||
|
||||
method rowCount(self: AssetList, index: QModelIndex = nil): int =
|
||||
return self.assets.len
|
||||
|
@ -48,12 +50,14 @@ QtObject:
|
|||
of AssetRoles.Symbol: result = newQVariant(asset.symbol)
|
||||
of AssetRoles.Value: result = newQVariant(asset.value)
|
||||
of AssetRoles.FiatValue: result = newQVariant(asset.fiatValue)
|
||||
of AssetRoles.Address: result = newQVariant(asset.address)
|
||||
|
||||
method roleNames(self: AssetList): Table[int, string] =
|
||||
{ AssetRoles.Name.int:"name",
|
||||
AssetRoles.Symbol.int:"symbol",
|
||||
AssetRoles.Value.int:"value",
|
||||
AssetRoles.FiatValue.int:"fiatValue" }.toTable
|
||||
AssetRoles.FiatValue.int:"fiatValue",
|
||||
AssetRoles.Address.int:"address" }.toTable
|
||||
|
||||
proc addAssetToList*(self: AssetList, asset: Asset) =
|
||||
self.beginInsertRows(newQModelIndex(), self.assets.len, self.assets.len)
|
||||
|
|
|
@ -5,6 +5,8 @@ const SEED* = "seed"
|
|||
const KEY* = "key"
|
||||
const WATCH* = "watch"
|
||||
|
||||
const ZERO_ADDRESS* = "0x0000000000000000000000000000000000000000"
|
||||
|
||||
const PATH_WALLET_ROOT* = "m/44'/60'/0'/0"
|
||||
# EIP1581 Root Key, the extended key from which any whisper key/encryption key can be derived
|
||||
const PATH_EIP_1581* = "m/43'/60'/1581'"
|
||||
|
|
|
@ -7,10 +7,10 @@ type
|
|||
Mainnet,
|
||||
Testnet
|
||||
|
||||
type Method = object
|
||||
name: string
|
||||
signature: string
|
||||
noPadding: bool
|
||||
type Method* = object
|
||||
name*: string
|
||||
signature*: string
|
||||
noPadding*: bool
|
||||
|
||||
type Contract* = ref object
|
||||
name*: string
|
||||
|
@ -21,7 +21,8 @@ type Contract* = ref object
|
|||
let CONTRACTS: seq[Contract] = @[
|
||||
Contract(name: "snt", network: Network.Mainnet, address: parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"),
|
||||
methods: [
|
||||
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)"))
|
||||
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)")),
|
||||
("transfer", Method(signature: "transfer(address,uint256)"))
|
||||
].toTable
|
||||
),
|
||||
Contract(name: "snt", network: Network.Testnet, address: parseAddress("0xc55cf4b03948d7ebc8b9e8bad92643703811d162")),
|
||||
|
@ -77,6 +78,8 @@ proc encodeParam[T](value: T): string =
|
|||
result = toHex(value, 64)
|
||||
elif T is EthAddress:
|
||||
result = value.toHex()
|
||||
else:
|
||||
result = align(value, 64, '0')
|
||||
|
||||
macro encodeAbi*(self: Method, params: varargs[untyped]): untyped =
|
||||
result = quote do:
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
import json, json, strformat, stint, strutils, chronicles
|
||||
import json, httpclient, json, strformat, stint, strutils, sequtils, chronicles, parseutils, tables
|
||||
import libstatus, core, types
|
||||
import ../wallet/account
|
||||
from ./accounts/constants import ZERO_ADDRESS
|
||||
import ./contracts as contractMethods
|
||||
from eth/common/utils import parseAddress
|
||||
|
||||
proc getWalletAccounts*(): seq[WalletAccount] =
|
||||
try:
|
||||
|
@ -26,17 +29,17 @@ proc getWalletAccounts*(): seq[WalletAccount] =
|
|||
let msg = getCurrentExceptionMsg()
|
||||
error "Failed getting wallet accounts", msg
|
||||
|
||||
proc getTransfersByAddress*(address: string): seq[Transaction] =
|
||||
proc getTransfersByAddress*(address: string): seq[types.Transaction] =
|
||||
try:
|
||||
let response = getBlockByNumber("latest")
|
||||
let latestBlock = parseJson(response)["result"]
|
||||
|
||||
let transactionsResponse = getTransfersByAddress(address, latestBlock["number"].getStr, "0x14")
|
||||
let transactions = parseJson(transactionsResponse)["result"]
|
||||
var accountTransactions: seq[Transaction] = @[]
|
||||
var accountTransactions: seq[types.Transaction] = @[]
|
||||
|
||||
for transaction in transactions:
|
||||
accountTransactions.add(Transaction(
|
||||
accountTransactions.add(types.Transaction(
|
||||
typeValue: transaction["type"].getStr,
|
||||
address: transaction["address"].getStr,
|
||||
contract: transaction["contract"].getStr,
|
||||
|
@ -58,14 +61,42 @@ proc getTransfersByAddress*(address: string): seq[Transaction] =
|
|||
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)}",
|
||||
"from": from_address,
|
||||
"to": to
|
||||
}
|
||||
var response = sendTransaction($args, password)
|
||||
result = response
|
||||
proc sendTransaction*(from_address: string, to: string, assetAddress: string, value: string, password: string): string =
|
||||
try:
|
||||
var args: JsonNode
|
||||
if (assetAddress == ZERO_ADDRESS or assetAddress == ""):
|
||||
var weiValue = value.parseFloat() * float(1000000000000000000)
|
||||
var stringValue = fmt"{weiValue:<.0f}"
|
||||
stringValue.removeSuffix('.')
|
||||
var hexValue = parseBiggestInt(stringValue).toHex()
|
||||
hexValue.removePrefix('0')
|
||||
args = %* {
|
||||
"value": fmt"0x{hexValue}",
|
||||
"from": from_address,
|
||||
"to": to
|
||||
}
|
||||
else:
|
||||
var bigIntValue = u256(value)
|
||||
# TODO get decimals from the token
|
||||
bigIntValue = bigIntValue * u256(1000000000000000000)
|
||||
# Just using mainnet SNT to get the method ABI
|
||||
let contract = getContract(Network.Mainnet, "snt")
|
||||
let transferEncoded = contract.methods["transfer"].encodeAbi(parseAddress(to), bigIntValue.toHex())
|
||||
|
||||
args = %* {
|
||||
"from": from_address,
|
||||
"to": assetAddress,
|
||||
"data": transferEncoded
|
||||
}
|
||||
|
||||
let response = sendTransaction($args, password)
|
||||
let parsedResponse = parseJson(response)
|
||||
|
||||
result = parsedResponse["result"].getStr
|
||||
trace "Transaction sent succesfully", hash=result
|
||||
except Exception as e:
|
||||
error "Error submitting transaction", msg=e.msg
|
||||
result = e.msg
|
||||
|
||||
proc getBalance*(address: string): string =
|
||||
let payload = %* [address, "latest"]
|
||||
|
|
|
@ -44,8 +44,8 @@ proc initEvents*(self: WalletModel) =
|
|||
proc delete*(self: WalletModel) =
|
||||
discard
|
||||
|
||||
proc sendTransaction*(self: WalletModel, from_value: string, to: string, value: string, password: string): string =
|
||||
status_wallet.sendTransaction(from_value, to, value, password)
|
||||
proc sendTransaction*(self: WalletModel, from_value: string, to: string, assetAddress: string, value: string, password: string): string =
|
||||
status_wallet.sendTransaction(from_value, to, assetAddress, value, password)
|
||||
|
||||
proc getDefaultCurrency*(self: WalletModel): string =
|
||||
# TODO: this should come from a model? It is going to be used too in the
|
||||
|
|
|
@ -15,7 +15,6 @@ ModalPopup {
|
|||
onOpened: {
|
||||
sendModalContent.amountInput.text = ""
|
||||
sendModalContent.amountInput.forceActiveFocus(Qt.MouseFocusReason)
|
||||
sendModalContent.defaultAccount = walletModel.getDefaultAccount()
|
||||
const accounts = walletModel.accounts
|
||||
const numAccounts = accounts.rowCount()
|
||||
const accountsData = []
|
||||
|
@ -35,7 +34,8 @@ ModalPopup {
|
|||
assetsData.push({
|
||||
name: assets.rowData(f, 'name'),
|
||||
symbol: assets.rowData(f, 'symbol'),
|
||||
value: assets.rowData(f, 'value')
|
||||
value: assets.rowData(f, 'value'),
|
||||
address: assets.rowData(f, 'address')
|
||||
})
|
||||
}
|
||||
sendModalContent.assets = assetsData
|
||||
|
|
|
@ -7,7 +7,7 @@ Item {
|
|||
property alias amountInput: txtAmount
|
||||
property var accounts: []
|
||||
property var assets: []
|
||||
property string defaultAccount: "0x1234"
|
||||
property string defaultAccount: "0x8558BFe81d00333379Af1Cd4c07F3dc50081FEC4"
|
||||
|
||||
property int selectedAccountIndex: 0
|
||||
property string selectedAccountAddress: accounts && accounts.length ? accounts[selectedAccountIndex].address : ""
|
||||
|
@ -16,6 +16,7 @@ Item {
|
|||
|
||||
property int selectedAssetIndex: 0
|
||||
property string selectedAssetName: assets && assets.length ? assets[selectedAssetIndex].name : ""
|
||||
property string selectedAssetAddress: assets && assets.length ? assets[selectedAssetIndex].address : ""
|
||||
property string selectedAssetSymbol: assets && assets.length ? assets[selectedAssetIndex].symbol : ""
|
||||
property string selectedAccountValue: assets && assets.length ? assets[selectedAssetIndex].value : ""
|
||||
|
||||
|
@ -27,12 +28,22 @@ Item {
|
|||
if (!validate()) {
|
||||
return;
|
||||
}
|
||||
// Convert to Wei
|
||||
// TODO use the decimal value fo the token, it's not always 18
|
||||
// TODO add big number support
|
||||
// const weiValue = parseFloat(txtAmount.text, 10) * 1000000000000000000
|
||||
|
||||
console.log('SENDING', selectedAccountAddress,
|
||||
txtTo.text,
|
||||
selectedAssetAddress,
|
||||
txtAmount.text,
|
||||
txtPassword.text)
|
||||
let result = walletModel.onSendTransaction(selectedAccountAddress,
|
||||
txtTo.text,
|
||||
selectedAssetAddress,
|
||||
txtAmount.text,
|
||||
txtPassword.text)
|
||||
console.log(result)
|
||||
console.log('hash', result)
|
||||
}
|
||||
|
||||
function validate() {
|
||||
|
@ -56,7 +67,7 @@ Item {
|
|||
amountValidationError = qsTr("You need to enter an amount")
|
||||
} else if (isNaN(txtAmount.text)) {
|
||||
amountValidationError = qsTr("This needs to be a number")
|
||||
} else if (parseInt(txtAmount.text, 10) > parseInt(selectedAccountValue, 10)) {
|
||||
} else if (parseFloat(txtAmount.text) > parseFloat(selectedAccountValue)) {
|
||||
amountValidationError = qsTr("Amount needs to be lower than your balance (%1)").arg(selectedAccountValue)
|
||||
} else {
|
||||
amountValidationError = ""
|
||||
|
|
Loading…
Reference in New Issue