feat: populate token details from contract address
This commit is contained in:
parent
bc1525f513
commit
bba08d87b8
|
@ -1,7 +1,7 @@
|
||||||
import NimQml, tables
|
import NimQml, tables, json
|
||||||
import ../../../status/libstatus/tokens
|
import ../../../status/libstatus/[tokens, settings, utils, eth/contracts]
|
||||||
import ../../../status/libstatus/eth/contracts
|
|
||||||
from web3/conversions import `$`
|
from web3/conversions import `$`
|
||||||
|
import ../../../status/threads
|
||||||
|
|
||||||
type
|
type
|
||||||
TokenRoles {.pure.} = enum
|
TokenRoles {.pure.} = enum
|
||||||
|
@ -81,3 +81,21 @@ QtObject:
|
||||||
TokenRoles.Decimals.int:"decimals",
|
TokenRoles.Decimals.int:"decimals",
|
||||||
TokenRoles.IsCustom.int:"isCustom"}.toTable
|
TokenRoles.IsCustom.int:"isCustom"}.toTable
|
||||||
|
|
||||||
|
# Resolving a ENS name
|
||||||
|
proc getTokenDetails*(self: TokenList, address: string) {.slot.} =
|
||||||
|
spawnAndSend(self, "tokenDetailsResolved") do:
|
||||||
|
let tkn = newErc20Contract("", getCurrentNetwork(), address.parseAddress, "", 18, false)
|
||||||
|
|
||||||
|
let decimals = tkn.tokenDecimals()
|
||||||
|
|
||||||
|
$ (%* {
|
||||||
|
"address": address,
|
||||||
|
"name": tkn.tokenName(),
|
||||||
|
"symbol": tkn.tokenSymbol(),
|
||||||
|
"decimals": (if decimals == 0: "" else: $decimals)
|
||||||
|
})
|
||||||
|
|
||||||
|
proc tokenDetailsWereResolved*(self: TokenList, tokenDetails: string) {.signal.}
|
||||||
|
|
||||||
|
proc tokenDetailsResolved(self: TokenList, tokenDetails: string) {.slot.} =
|
||||||
|
self.tokenDetailsWereResolved(tokenDetails)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import json, chronicles, strformat, stint, strutils, sequtils
|
import json, chronicles, strformat, stint, strutils, sequtils, tables
|
||||||
import core, wallet
|
import core, wallet
|
||||||
import ./eth/contracts
|
import ./eth/contracts
|
||||||
import web3/[ethtypes, conversions]
|
import web3/[ethtypes, conversions]
|
||||||
|
@ -131,3 +131,37 @@ proc getSNTAddress*(): string =
|
||||||
proc getSNTBalance*(account: string): string =
|
proc getSNTBalance*(account: string): string =
|
||||||
let snt = contracts.getSntContract()
|
let snt = contracts.getSntContract()
|
||||||
result = getTokenBalance($snt.address, account)
|
result = getTokenBalance($snt.address, account)
|
||||||
|
|
||||||
|
proc getTokenString*(contract: Contract, methodName: string): string =
|
||||||
|
let payload = %* [{
|
||||||
|
"to": $contract.address,
|
||||||
|
"data": contract.methods[methodName].encodeAbi()
|
||||||
|
}, "latest"]
|
||||||
|
|
||||||
|
let responseStr = callPrivateRPC("eth_call", payload)
|
||||||
|
let response = Json.decode(responseStr, RpcResponse)
|
||||||
|
if not response.error.isNil:
|
||||||
|
raise newException(RpcException, "Error getting token string - " & methodName & ": " & response.error.message)
|
||||||
|
if response.result == "0x":
|
||||||
|
return ""
|
||||||
|
|
||||||
|
let size = fromHex(Stuint[256], response.result[66..129]).toInt
|
||||||
|
result = response.result[130..129+size*2].parseHexStr
|
||||||
|
|
||||||
|
proc tokenName*(contract: Contract): string = getTokenString(contract, "name")
|
||||||
|
|
||||||
|
proc tokenSymbol*(contract: Contract): string = getTokenString(contract, "symbol")
|
||||||
|
|
||||||
|
proc tokenDecimals*(contract: Contract): int =
|
||||||
|
let payload = %* [{
|
||||||
|
"to": $contract.address,
|
||||||
|
"data": contract.methods["decimals"].encodeAbi()
|
||||||
|
}, "latest"]
|
||||||
|
|
||||||
|
let responseStr = callPrivateRPC("eth_call", payload)
|
||||||
|
let response = Json.decode(responseStr, RpcResponse)
|
||||||
|
if not response.error.isNil:
|
||||||
|
raise newException(RpcException, "Error getting token decimals: " & response.error.message)
|
||||||
|
if response.result == "0x":
|
||||||
|
return 0
|
||||||
|
result = parseHexInt(response.result)
|
||||||
|
|
|
@ -9,6 +9,7 @@ ModalPopup {
|
||||||
|
|
||||||
property bool editable: true
|
property bool editable: true
|
||||||
property int marginBetweenInputs: 35
|
property int marginBetweenInputs: 35
|
||||||
|
property string validationError: ""
|
||||||
|
|
||||||
title: editable ?
|
title: editable ?
|
||||||
//% "Add custom token"
|
//% "Add custom token"
|
||||||
|
@ -39,13 +40,57 @@ ModalPopup {
|
||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function validate() {
|
||||||
|
if (addressInput.text !== "" && !Utils.isAddress(addressInput.text)) {
|
||||||
|
validationError = qsTr("This needs to be a valid address");
|
||||||
|
}
|
||||||
|
return validationError === ""
|
||||||
|
}
|
||||||
|
|
||||||
|
property var getTokenDetails: Backpressure.debounce(popup, 500, function (tokenAddress){
|
||||||
|
walletModel.customTokenList.getTokenDetails(tokenAddress)
|
||||||
|
});
|
||||||
|
|
||||||
|
function onKeyReleased(){
|
||||||
|
validationError = "";
|
||||||
|
|
||||||
|
if (!validate() || addressInput.text === "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Qt.callLater(getTokenDetails, addressInput.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
Connections {
|
||||||
|
target: walletModel.customTokenList
|
||||||
|
onTokenDetailsWereResolved: {
|
||||||
|
const jsonObj = JSON.parse(tokenDetails)
|
||||||
|
|
||||||
|
if(jsonObj.address === ""){
|
||||||
|
validationError = qsTr("Invalid ERC20 address")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(addressInput.text.toLowerCase() === jsonObj.address.toLowerCase()){
|
||||||
|
symbolInput.text = jsonObj.symbol;
|
||||||
|
decimalsInput.text = jsonObj.decimals;
|
||||||
|
nameInput.text = jsonObj.name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
id: addressInput
|
id: addressInput
|
||||||
readOnly: !editable
|
readOnly: !editable
|
||||||
|
textField.maximumLength: 42
|
||||||
//% "Enter contract address..."
|
//% "Enter contract address..."
|
||||||
placeholderText: qsTrId("enter-contract-address...")
|
placeholderText: qsTrId("enter-contract-address...")
|
||||||
//% "Contract address"
|
//% "Contract address"
|
||||||
label: qsTrId("contract-address")
|
label: qsTrId("contract-address")
|
||||||
|
validationError: popup.validationError
|
||||||
|
Keys.onReleased: onKeyReleased()
|
||||||
}
|
}
|
||||||
|
|
||||||
Input {
|
Input {
|
||||||
|
@ -98,7 +143,7 @@ ModalPopup {
|
||||||
//% "Add"
|
//% "Add"
|
||||||
label: qsTrId("add")
|
label: qsTrId("add")
|
||||||
|
|
||||||
disabled: addressInput.text === "" || nameInput.text === "" || symbolInput.text === "" || decimalsInput.text === ""
|
disabled: validationError !== "" && addressInput.text === "" || nameInput.text === "" || symbolInput.text === "" || decimalsInput.text === ""
|
||||||
|
|
||||||
onClicked : {
|
onClicked : {
|
||||||
const error = walletModel.addCustomToken(addressInput.text, nameInput.text, symbolInput.text, decimalsInput.text);
|
const error = walletModel.addCustomToken(addressInput.text, nameInput.text, symbolInput.text, decimalsInput.text);
|
||||||
|
|
Loading…
Reference in New Issue