refactor: combine list of tokens with contracts

All tokens are now implemented as a strongly-typed Contract, Erc20Contract, or Erc721Contract. This prevents having two separate lists of overlapping tokens/contracts and normalises how to retreive the current SNT contract (depending on the network).
This commit is contained in:
emizzle 2020-10-02 20:06:08 +10:00 committed by Iuri Matias
parent 9b7ee3a2ee
commit 08efd6fc08
11 changed files with 369 additions and 1471 deletions

View File

@ -6,6 +6,7 @@ import ../../status/libstatus/wallet as status_wallet
import ../../status/libstatus/tokens
import ../../status/libstatus/types
import ../../status/libstatus/utils as status_utils
import ../../status/libstatus/eth/contracts
import ../../status/ens as status_ens
import views/[asset_list, account_list, account_item, token_list, transaction_list, collectibles_list]
@ -323,9 +324,9 @@ QtObject:
self.currentAccountChanged()
proc removeCustomToken*(self: WalletView, tokenAddress: string) {.slot.} =
let t = getTokenByAddress(getCustomTokens(), tokenAddress)
if t.kind == JNull: return
self.status.wallet.hideAsset(t["symbol"].getStr)
let t = getCustomTokens().getErc20ContractByAddress(parseAddress(tokenAddress))
if t == nil: return
self.status.wallet.hideAsset(t.symbol)
removeCustomToken(tokenAddress)
self.customTokenList.loadCustomTokens()
for account in self.status.wallet.accounts:

View File

@ -1,6 +1,7 @@
import NimQml, tables, json
import ../../../status/libstatus/default_tokens
import NimQml, tables
import ../../../status/libstatus/tokens
import ../../../status/libstatus/eth/contracts
from web3/conversions import `$`
type
TokenRoles {.pure.} = enum
@ -12,7 +13,7 @@ type
QtObject:
type TokenList* = ref object of QAbstractListModel
tokens*: seq[JsonNode]
tokens*: seq[Erc20Contract]
proc setup(self: TokenList) =
self.QAbstractListModel.setup
@ -25,12 +26,12 @@ QtObject:
proc loadDefaultTokens*(self:TokenList) =
if self.tokens.len == 0:
self.tokens = getDefaultTokens().getElems()
self.tokens = getErc20Contracts()
self.tokensLoaded(self.tokens.len)
proc loadCustomTokens*(self: TokenList) =
self.beginResetModel()
self.tokens = getCustomTokens().getElems()
self.tokens = getCustomTokens()
self.tokensLoaded(self.tokens.len)
self.endResetModel()
@ -44,11 +45,11 @@ QtObject:
return
let token = self.tokens[index]
case column:
of "name": result = token["name"].getStr
of "symbol": result = token["symbol"].getStr
of "hasIcon": result = $token["hasIcon"].getBool
of "address": result = token["address"].getStr
of "decimals": result = $token["decimals"].getInt
of "name": result = token.name
of "symbol": result = token.symbol
of "hasIcon": result = $token.hasIcon
of "address": result = $token.address
of "decimals": result = $token.decimals
method rowCount(self: TokenList, index: QModelIndex = nil): int =
return self.tokens.len
@ -61,11 +62,11 @@ QtObject:
let token = self.tokens[index.row]
let tokenRole = role.TokenRoles
case tokenRole:
of TokenRoles.Name: result = newQVariant(token["name"].getStr)
of TokenRoles.Symbol: result = newQVariant(token["symbol"].getStr)
of TokenRoles.HasIcon: result = newQVariant(token{"hasIcon"}.getBool)
of TokenRoles.Address: result = newQVariant(token["address"].getStr)
of TokenRoles.Decimals: result = newQVariant(token["decimals"].getInt)
of TokenRoles.Name: result = newQVariant(token.name)
of TokenRoles.Symbol: result = newQVariant(token.symbol)
of TokenRoles.HasIcon: result = newQVariant(token.hasIcon)
of TokenRoles.Address: result = newQVariant($token.address)
of TokenRoles.Decimals: result = newQVariant(token.decimals)
method roleNames(self: TokenList): Table[int, string] =
{TokenRoles.Name.int:"name",

View File

@ -153,7 +153,7 @@ proc registerUsernameEstimateGas*(username: string, address: string, pubKey: str
x = fromHex(FixedBytes[32], coordinates.x)
y = fromHex(FixedBytes[32], coordinates.y)
ensUsernamesContract = contracts.getContract("ens-usernames")
sntContract = contracts.getContract("snt")
sntContract = contracts.getSntContract()
price = getPrice()
let
@ -175,7 +175,7 @@ proc registerUsername*(username, pubKey, address, gas, gasPrice, password: stri
x = fromHex(FixedBytes[32], coordinates.x)
y = fromHex(FixedBytes[32], coordinates.y)
ensUsernamesContract = contracts.getContract("ens-usernames")
sntContract = contracts.getContract("snt")
sntContract = contracts.getSntContract()
price = getPrice()
let

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,8 @@
import
sequtils, sugar, macros, tables, strutils
sequtils, sugar, macros, tables, strutils, locks
import
web3/ethtypes, stew/byteutils, nimcrypto
web3/ethtypes, stew/byteutils, nimcrypto, json_serialization, chronicles
import
../types, ../settings, ../coder, transactions, methods, ../utils
@ -12,113 +12,300 @@ export
TokenOfOwnerByIndex, TokenPackId, TokenUri, FixedBytes, DynamicBytes, toHex, fromHex,
decodeContractResponse, encodeAbi, estimateGas, send, call
type Contract* = ref object
logScope:
topics = "contracts"
var contractsLock: Lock
initLock(contractsLock)
const ERC20_METHODS = @[
("name", Method(signature: "name()")),
("symbol", Method(signature: "symbol()")),
("decimals", Method(signature: "decimals()")),
("totalSupply", Method(signature: "totalSupply()")),
("balanceOf", Method(signature: "balanceOf(address)")),
("transfer", Method(signature: "transfer(address,uint256)")),
("allowance", Method(signature: "allowance(address,address)")),
("approve", Method(signature: "approve(address,uint256)")),
("transferFrom", Method(signature: "approve(address,address,uint256)")),
("increaseAllowance", Method(signature: "increaseAllowance(address,uint256)")),
("decreaseAllowance", Method(signature: "decreaseAllowance(address,uint256)")),
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)"))
]
const ERC721_ENUMERABLE_METHODS = @[
("balanceOf", Method(signature: "balanceOf(address)")),
("ownerOf", Method(signature: "ownerOf(uint256)")),
("name", Method(signature: "name()")),
("symbol", Method(signature: "symbol()")),
("tokenURI", Method(signature: "tokenURI(uint256)")),
("baseURI", Method(signature: "baseURI()")),
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)")),
("totalSupply", Method(signature: "totalSupply()")),
("tokenByIndex", Method(signature: "tokenByIndex(uint256)")),
("approve", Method(signature: "approve(address,uint256)")),
("getApproved", Method(signature: "getApproved(uint256)")),
("setApprovalForAll", Method(signature: "setApprovalForAll(address,bool)")),
("isApprovedForAll", Method(signature: "isApprovedForAll(address,address)")),
("transferFrom", Method(signature: "transferFrom(address,address,uint256)")),
("safeTransferFrom", Method(signature: "safeTransferFrom(address,address,uint256)")),
("safeTransferFromWithData", Method(signature: "safeTransferFrom(address,address,uint256,bytes)"))
]
type
Contract* = ref object of RootObj
name*: string
network*: Network
address*: Address
methods*: Table[string, Method]
methods* {.dontSerialize.}: Table[string, Method]
proc allContracts(): seq[Contract] = @[
Contract(name: "snt", network: Network.Mainnet, address: parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"),
methods: [
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)")),
("transfer", Method(signature: "transfer(address,uint256)"))
].toTable
),
Contract(name: "snt", network: Network.Testnet, address: parseAddress("0xc55cf4b03948d7ebc8b9e8bad92643703811d162"),
methods: [
("approveAndCall", Method(signature: "approveAndCall(address,uint256,bytes)")),
("transfer", Method(signature: "transfer(address,uint256)"))
].toTable
),
Contract(name: "tribute-to-talk", network: Network.Testnet, address: parseAddress("0xC61aa0287247a0398589a66fCD6146EC0F295432")),
Erc20Contract* = ref object of Contract
symbol*: string
decimals*: int
hasIcon* {.dontSerialize.}: bool
color*: string
Erc721Contract* = ref object of Contract
symbol*: string
hasIcon*: bool
proc newErc20Contract(name: string, network: Network, address: Address, symbol: string, decimals: int, hasIcon: bool): Erc20Contract =
Erc20Contract(name: name, network: network, address: address, methods: ERC20_METHODS.toTable, symbol: symbol, decimals: decimals, hasIcon: hasIcon)
proc newErc721Contract(name: string, network: Network, address: Address, symbol: string, hasIcon: bool, addlMethods: seq[tuple[name: string, meth: Method]] = @[]): Erc721Contract =
Erc721Contract(name: name, network: network, address: address, symbol: symbol, hasIcon: hasIcon, methods: ERC721_ENUMERABLE_METHODS.concat(addlMethods).toTable)
var ALL_CONTRACTS {.guard: contractsLock.}: seq[Contract] = @[
# Mainnet contracts
newErc20Contract("Status Network Token", Network.Mainnet, parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"), "SNT", 18, true),
newErc20Contract("Dai Stablecoin", Network.Mainnet, parseAddress("0x6b175474e89094c44da98b954eedeac495271d0f"), "DAI", 18, true),
newErc20Contract("Sai Stablecoin v1.0", Network.Mainnet, parseAddress("0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359"), "SAI", 18, true),
newErc20Contract("MKR", Network.Mainnet, parseAddress("0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"), "MKR", 18, true),
newErc20Contract("EOS", Network.Mainnet, parseAddress("0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0"), "EOS", 18, true),
newErc20Contract("OMGToken", Network.Mainnet, parseAddress("0xd26114cd6ee289accf82350c8d8487fedb8a0c07"), "OMG", 18, true),
newErc20Contract("Populous Platform", Network.Mainnet, parseAddress("0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a"), "PPT", 8, true),
newErc20Contract("Reputation", Network.Mainnet, parseAddress("0x1985365e9f78359a9b6ad760e32412f4a445e862"), "REP", 18, true),
newErc20Contract("PowerLedger", Network.Mainnet, parseAddress("0x595832f8fc6bf59c85c527fec3740a1b7a361269"), "POWR", 6, true),
newErc20Contract("TenX Pay Token", Network.Mainnet, parseAddress("0xb97048628db6b661d4c2aa833e95dbe1a905b280"), "PAY", 18, true),
newErc20Contract("Veros", Network.Mainnet, parseAddress("0x92e78dae1315067a8819efd6dca432de9dcde2e9"), "VRS", 6, false),
newErc20Contract("Golem Network Token", Network.Mainnet, parseAddress("0xa74476443119a942de498590fe1f2454d7d4ac0d"), "GNT", 18, true),
newErc20Contract("Salt", Network.Mainnet, parseAddress("0x4156d3342d5c385a87d264f90653733592000581"), "SALT", 8, true),
newErc20Contract("BNB", Network.Mainnet, parseAddress("0xb8c77482e45f1f44de1745f52c74426c631bdd52"), "BNB", 18, true),
newErc20Contract("Basic Attention Token", Network.Mainnet, parseAddress("0x0d8775f648430679a709e98d2b0cb6250d2887ef"), "BAT", 18, true),
newErc20Contract("Kyber Network Crystal", Network.Mainnet, parseAddress("0xdd974d5c2e2928dea5f71b9825b8b646686bd200"), "KNC", 18, true),
newErc20Contract("BTU Protocol", Network.Mainnet, parseAddress("0xb683D83a532e2Cb7DFa5275eED3698436371cc9f"), "BTU", 18, true),
newErc20Contract("Digix DAO", Network.Mainnet, parseAddress("0xe0b7927c4af23765cb51314a0e0521a9645f0e2a"), "DGD", 9, true),
newErc20Contract("Aeternity", Network.Mainnet, parseAddress("0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d"), "AE", 18, true),
newErc20Contract("Tronix", Network.Mainnet, parseAddress("0xf230b790e05390fc8295f4d3f60332c93bed42e2"), "TRX", 6, true),
newErc20Contract("Ethos", Network.Mainnet, parseAddress("0x5af2be193a6abca9c8817001f45744777db30756"), "ETHOS", 8, true),
newErc20Contract("Raiden Token", Network.Mainnet, parseAddress("0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6"), "RDN", 18, true),
newErc20Contract("Status Network Token", Network.Mainnet, parseAddress("0x744d70fdbe2ba4cf95131626614a1763df805b9e"), "SNT", 18, true),
newErc20Contract("SingularDTV", Network.Mainnet, parseAddress("0xaec2e87e0a235266d9c5adc9deb4b2e29b54d009"), "SNGLS", 0, true),
newErc20Contract("Gnosis Token", Network.Mainnet, parseAddress("0x6810e776880c02933d47db1b9fc05908e5386b96"), "GNO", 18, true),
newErc20Contract("StorjToken", Network.Mainnet, parseAddress("0xb64ef51c888972c908cfacf59b47c1afbc0ab8ac"), "STORJ", 8, true),
newErc20Contract("AdEx", Network.Mainnet, parseAddress("0x4470bb87d77b963a013db939be332f927f2b992e"), "ADX", 4, false),
newErc20Contract("FunFair", Network.Mainnet, parseAddress("0x419d0d8bdd9af5e606ae2232ed285aff190e711b"), "FUN", 8, true),
newErc20Contract("Civic", Network.Mainnet, parseAddress("0x41e5560054824ea6b0732e656e3ad64e20e94e45"), "CVC", 8, true),
newErc20Contract("ICONOMI", Network.Mainnet, parseAddress("0x888666ca69e0f178ded6d75b5726cee99a87d698"), "ICN", 18, true),
newErc20Contract("Walton Token", Network.Mainnet, parseAddress("0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74"), "WTC", 18, true),
newErc20Contract("Bytom", Network.Mainnet, parseAddress("0xcb97e65f07da24d46bcdd078ebebd7c6e6e3d750"), "BTM", 8, true),
newErc20Contract("0x Protocol Token", Network.Mainnet, parseAddress("0xe41d2489571d322189246dafa5ebde1f4699f498"), "ZRX", 18, true),
newErc20Contract("Bancor Network Token", Network.Mainnet, parseAddress("0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c"), "BNT", 18, true),
newErc20Contract("Metal", Network.Mainnet, parseAddress("0xf433089366899d83a9f26a773d59ec7ecf30355e"), "MTL", 8, false),
newErc20Contract("PayPie", Network.Mainnet, parseAddress("0xc42209accc14029c1012fb5680d95fbd6036e2a0"), "PPP", 18, true),
newErc20Contract("ChainLink Token", Network.Mainnet, parseAddress("0x514910771af9ca656af840dff83e8264ecf986ca"), "LINK", 18, true),
newErc20Contract("Kin", Network.Mainnet, parseAddress("0x818fc6c2ec5986bc6e2cbf00939d90556ab12ce5"), "KIN", 18, true),
newErc20Contract("Aragon Network Token", Network.Mainnet, parseAddress("0x960b236a07cf122663c4303350609a66a7b288c0"), "ANT", 18, true),
newErc20Contract("MobileGo Token", Network.Mainnet, parseAddress("0x40395044ac3c0c57051906da938b54bd6557f212"), "MGO", 8, true),
newErc20Contract("Monaco", Network.Mainnet, parseAddress("0xb63b606ac810a52cca15e44bb630fd42d8d1d83d"), "MCO", 8, true),
newErc20Contract("loopring", Network.Mainnet, parseAddress("0xef68e7c694f40c8202821edf525de3782458639f"), "LRC", 18, true),
newErc20Contract("Zeus Shield Coin", Network.Mainnet, parseAddress("0x7a41e0517a5eca4fdbc7fbeba4d4c47b9ff6dc63"), "ZSC", 18, true),
newErc20Contract("Streamr DATAcoin", Network.Mainnet, parseAddress("0x0cf0ee63788a0849fe5297f3407f701e122cc023"), "DATA", 18, true),
newErc20Contract("Ripio Credit Network Token", Network.Mainnet, parseAddress("0xf970b8e36e23f7fc3fd752eea86f8be8d83375a6"), "RCN", 18, true),
newErc20Contract("WINGS", Network.Mainnet, parseAddress("0x667088b212ce3d06a1b553a7221e1fd19000d9af"), "WINGS", 18, true),
newErc20Contract("Edgeless", Network.Mainnet, parseAddress("0x08711d3b02c8758f2fb3ab4e80228418a7f8e39c"), "EDG", 0, true),
newErc20Contract("Melon Token", Network.Mainnet, parseAddress("0xbeb9ef514a379b997e0798fdcc901ee474b6d9a1"), "MLN", 18, true),
newErc20Contract("Moeda Loyalty Points", Network.Mainnet, parseAddress("0x51db5ad35c671a87207d88fc11d593ac0c8415bd"), "MDA", 18, true),
newErc20Contract("PILLAR", Network.Mainnet, parseAddress("0xe3818504c1b32bf1557b16c238b2e01fd3149c17"), "PLR", 18, true),
newErc20Contract("QRL", Network.Mainnet, parseAddress("0x697beac28b09e122c4332d163985e8a73121b97f"), "QRL", 8, true),
newErc20Contract("Modum Token", Network.Mainnet, parseAddress("0x957c30ab0426e0c93cd8241e2c60392d08c6ac8e"), "MOD", 0, true),
newErc20Contract("Token-as-a-Service", Network.Mainnet, parseAddress("0xe7775a6e9bcf904eb39da2b68c5efb4f9360e08c"), "TAAS", 6, true),
newErc20Contract("GRID Token", Network.Mainnet, parseAddress("0x12b19d3e2ccc14da04fae33e63652ce469b3f2fd"), "GRID", 12, true),
newErc20Contract("SANtiment network token", Network.Mainnet, parseAddress("0x7c5a0ce9267ed19b22f8cae653f198e3e8daf098"), "SAN", 18, true),
newErc20Contract("SONM Token", Network.Mainnet, parseAddress("0x983f6d60db79ea8ca4eb9968c6aff8cfa04b3c63"), "SNM", 18, true),
newErc20Contract("Request Token", Network.Mainnet, parseAddress("0x8f8221afbb33998d8584a2b05749ba73c37a938a"), "REQ", 18, true),
newErc20Contract("Substratum", Network.Mainnet, parseAddress("0x12480e24eb5bec1a9d4369cab6a80cad3c0a377a"), "SUB", 2, true),
newErc20Contract("Decentraland MANA", Network.Mainnet, parseAddress("0x0f5d2fb29fb7d3cfee444a200298f468908cc942"), "MANA", 18, true),
newErc20Contract("AirSwap Token", Network.Mainnet, parseAddress("0x27054b13b1b798b345b591a4d22e6562d47ea75a"), "AST", 4, true),
newErc20Contract("R token", Network.Mainnet, parseAddress("0x48f775efbe4f5ece6e0df2f7b5932df56823b990"), "R", 0, true),
newErc20Contract("FirstBlood Token", Network.Mainnet, parseAddress("0xaf30d2a7e90d7dc361c8c4585e9bb7d2f6f15bc7"), "1ST", 18, true),
newErc20Contract("Cofoundit", Network.Mainnet, parseAddress("0x12fef5e57bf45873cd9b62e9dbd7bfb99e32d73e"), "CFI", 18, true),
newErc20Contract("Enigma", Network.Mainnet, parseAddress("0xf0ee6b27b759c9893ce4f094b49ad28fd15a23e4"), "ENG", 8, true),
newErc20Contract("Amber Token", Network.Mainnet, parseAddress("0x4dc3643dbc642b72c158e7f3d2ff232df61cb6ce"), "AMB", 18, true),
newErc20Contract("XPlay Token", Network.Mainnet, parseAddress("0x90528aeb3a2b736b780fd1b6c478bb7e1d643170"), "XPA", 18, true),
newErc20Contract("Open Trading Network", Network.Mainnet, parseAddress("0x881ef48211982d01e2cb7092c915e647cd40d85c"), "OTN", 18, true),
newErc20Contract("Trustcoin", Network.Mainnet, parseAddress("0xcb94be6f13a1182e4a4b6140cb7bf2025d28e41b"), "TRST", 6, true),
newErc20Contract("Monolith TKN", Network.Mainnet, parseAddress("0xaaaf91d9b90df800df4f55c205fd6989c977e73a"), "TKN", 8, true),
newErc20Contract("RHOC", Network.Mainnet, parseAddress("0x168296bb09e24a88805cb9c33356536b980d3fc5"), "RHOC", 8, true),
newErc20Contract("Target Coin", Network.Mainnet, parseAddress("0xac3da587eac229c9896d919abc235ca4fd7f72c1"), "TGT", 1, false),
newErc20Contract("Everex", Network.Mainnet, parseAddress("0xf3db5fa2c66b7af3eb0c0b782510816cbe4813b8"), "EVX", 4, true),
newErc20Contract("ICOS", Network.Mainnet, parseAddress("0x014b50466590340d41307cc54dcee990c8d58aa8"), "ICOS", 6, true),
newErc20Contract("district0x Network Token", Network.Mainnet, parseAddress("0x0abdace70d3790235af448c88547603b945604ea"), "DNT", 18, true),
newErc20Contract("Dentacoin", Network.Mainnet, parseAddress("0x08d32b0da63e2c3bcf8019c9c5d849d7a9d791e6"), "٨", 0, false),
newErc20Contract("Eidoo Token", Network.Mainnet, parseAddress("0xced4e93198734ddaff8492d525bd258d49eb388e"), "EDO", 18, true),
newErc20Contract("BitDice", Network.Mainnet, parseAddress("0x29d75277ac7f0335b2165d0895e8725cbf658d73"), "CSNO", 8, false),
newErc20Contract("Cobinhood Token", Network.Mainnet, parseAddress("0xb2f7eb1f2c37645be61d73953035360e768d81e6"), "COB", 18, true),
newErc20Contract("Enjin Coin", Network.Mainnet, parseAddress("0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c"), "ENJ", 18, false),
newErc20Contract("AVENTUS", Network.Mainnet, parseAddress("0x0d88ed6e74bbfd96b831231638b66c05571e824f"), "AVT", 18, false),
newErc20Contract("Chronobank TIME", Network.Mainnet, parseAddress("0x6531f133e6deebe7f2dce5a0441aa7ef330b4e53"), "TIME", 8, false),
newErc20Contract("Cindicator Token", Network.Mainnet, parseAddress("0xd4c435f5b09f855c3317c8524cb1f586e42795fa"), "CND", 18, true),
newErc20Contract("Stox", Network.Mainnet, parseAddress("0x006bea43baa3f7a6f765f14f10a1a1b08334ef45"), "STX", 18, true),
newErc20Contract("Xaurum", Network.Mainnet, parseAddress("0x4df812f6064def1e5e029f1ca858777cc98d2d81"), "XAUR", 8, true),
newErc20Contract("Vibe", Network.Mainnet, parseAddress("0x2c974b2d0ba1716e644c1fc59982a89ddd2ff724"), "VIB", 18, true),
newErc20Contract("PRG", Network.Mainnet, parseAddress("0x7728dfef5abd468669eb7f9b48a7f70a501ed29d"), "PRG", 6, false),
newErc20Contract("Delphy Token", Network.Mainnet, parseAddress("0x6c2adc2073994fb2ccc5032cc2906fa221e9b391"), "DPY", 18, true),
newErc20Contract("CoinDash Token", Network.Mainnet, parseAddress("0x2fe6ab85ebbf7776fee46d191ee4cea322cecf51"), "CDT", 18, true),
newErc20Contract("Tierion Network Token", Network.Mainnet, parseAddress("0x08f5a9235b08173b7569f83645d2c7fb55e8ccd8"), "TNT", 8, true),
newErc20Contract("DomRaiderToken", Network.Mainnet, parseAddress("0x9af4f26941677c706cfecf6d3379ff01bb85d5ab"), "DRT", 8, true),
newErc20Contract("SPANK", Network.Mainnet, parseAddress("0x42d6622dece394b54999fbd73d108123806f6a18"), "SPANK", 18, true),
newErc20Contract("Berlin Coin", Network.Mainnet, parseAddress("0x80046305aaab08f6033b56a360c184391165dc2d"), "BRLN", 18, true),
newErc20Contract("USD//C", Network.Mainnet, parseAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), "USDC", 6, true),
newErc20Contract("Livepeer Token", Network.Mainnet, parseAddress("0x58b6a8a3302369daec383334672404ee733ab239"), "LPT", 18, true),
newErc20Contract("Simple Token", Network.Mainnet, parseAddress("0x2c4e8f2d746113d0696ce89b35f0d8bf88e0aeca"), "ST", 18, true),
newErc20Contract("Wrapped BTC", Network.Mainnet, parseAddress("0x2260fac5e5542a773aa44fbcfedf7c193bc2c599"), "WBTC", 8, true),
newErc20Contract("Bloom Token", Network.Mainnet, parseAddress("0x107c4504cd79c5d2696ea0030a8dd4e92601b82e"), "BLT", 18, true),
Contract(name: "stickers", network: Network.Mainnet, address: parseAddress("0x0577215622f43a39f4bc9640806dfea9b10d2a36"),
methods: [
("packCount", Method(signature: "packCount()")),
("getPackData", Method(signature: "getPackData(uint256)"))
].toTable
),
Contract(name: "stickers", network: Network.Testnet, address: parseAddress("0x8cc272396be7583c65bee82cd7b743c69a87287d"),
methods: [
("packCount", Method(signature: "packCount()")),
("getPackData", Method(signature: "getPackData(uint256)"))
].toTable
),
Contract(name: "sticker-market", network: Network.Mainnet, address: parseAddress("0x12824271339304d3a9f7e096e62a2a7e73b4a7e7"),
methods: [
("buyToken", Method(signature: "buyToken(uint256,address,uint256)"))
].toTable
),
Contract(name: "sticker-market", network: Network.Testnet, address: parseAddress("0x6CC7274aF9cE9572d22DFD8545Fb8c9C9Bcb48AD"),
methods: [
("buyToken", Method(signature: "buyToken(uint256,address,uint256)"))
].toTable
),
Contract(name: "sticker-pack", network: Network.Mainnet, address: parseAddress("0x110101156e8F0743948B2A61aFcf3994A8Fb172e"),
methods: [
("balanceOf", Method(signature: "balanceOf(address)")),
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)")),
("tokenPackId", Method(signature: "tokenPackId(uint256)"))
].toTable
),
Contract(name: "sticker-pack", network: Network.Testnet, address: parseAddress("0xf852198d0385c4b871e0b91804ecd47c6ba97351"),
methods: [
("balanceOf", Method(signature: "balanceOf(address)")),
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)")),
("tokenPackId", Method(signature: "tokenPackId(uint256)"))
].toTable),
newErc721Contract("sticker-pack", Network.Mainnet, parseAddress("0x110101156e8F0743948B2A61aFcf3994A8Fb172e"), "PACK", false, @[("tokenPackId", Method(signature: "tokenPackId(uint256)"))]),
# Strikers seems dead. Their website doesn't work anymore
Contract(name: "strikers", network: Network.Mainnet, address: parseAddress("0xdcaad9fd9a74144d226dbf94ce6162ca9f09ed7e"),
methods: [
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)"))
].toTable
),
Contract(name: "ethermon", network: Network.Mainnet, address: parseAddress("0xb2c0782ae4a299f7358758b2d15da9bf29e1dd99"),
methods: [
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)"))
].toTable
),
Contract(name: "kudos", network: Network.Mainnet, address: parseAddress("0x2aea4add166ebf38b63d09a75de1a7b94aa24163"),
methods: [
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)")),
("tokenURI", Method(signature: "tokenURI(uint256)"))
].toTable
),
Contract(name: "kudos", network: Network.Testnet, address: parseAddress("0xcd520707fc68d153283d518b29ada466f9091ea8"),
methods: [
("tokenOfOwnerByIndex", Method(signature: "tokenOfOwnerByIndex(address,uint256)")),
("tokenURI", Method(signature: "tokenURI(uint256)"))
].toTable
),
Contract(name: "crypto-kitties", network: Network.Mainnet, address: parseAddress("0x06012c8cf97bead5deae237070f9587f8e7a266d")),
newErc721Contract("strikers", Network.Mainnet, parseAddress("0xdcaad9fd9a74144d226dbf94ce6162ca9f09ed7e"), "STRK", true),
newErc721Contract("ethermon", Network.Mainnet, parseAddress("0xb2c0782ae4a299f7358758b2d15da9bf29e1dd99"), "EMONA", true),
newErc721Contract("kudos", Network.Mainnet, parseAddress("0x2aea4add166ebf38b63d09a75de1a7b94aa24163"), "KDO", true),
newErc721Contract("crypto-kitties", Network.Mainnet, parseAddress("0x06012c8cf97bead5deae237070f9587f8e7a266d"), "CK", true),
Contract(name: "ens-usernames", network: Network.Mainnet, address: parseAddress("0xDB5ac1a559b02E12F29fC0eC0e37Be8E046DEF49"),
methods: [
("register", Method(signature: "register(bytes32,address,bytes32,bytes32)")),
("getPrice", Method(signature: "getPrice()"))
].toTable
),
Contract(name: "ens-usernames", network: Network.Testnet, address: parseAddress("0x11d9F481effd20D76cEE832559bd9Aca25405841"),
methods: [
("register", Method(signature: "register(bytes32,address,bytes32,bytes32)")),
("getPrice", Method(signature: "getPrice()"))
].toTable
),
Contract(name: "ens-resolver", network: Network.Mainnet, address: parseAddress("0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"),
methods: [
("setPubkey", Method(signature: "setPubkey(bytes32,bytes32,bytes32)"))
].toTable
),
# Testnet (Ropsten) contracts
newErc20Contract("Status Test Token", Network.Testnet, parseAddress("0xc55cf4b03948d7ebc8b9e8bad92643703811d162"), "STT", 18, true),
newErc20Contract("Handy Test Token", Network.Testnet, parseAddress("0xdee43a267e8726efd60c2e7d5b81552dcd4fa35c"), "HND", 0, false),
newErc20Contract("Lucky Test Token", Network.Testnet, parseAddress("0x703d7dc0bc8e314d65436adf985dda51e09ad43b"), "LXS", 2, false),
newErc20Contract("Adi Test Token", Network.Testnet, parseAddress("0xe639e24346d646e927f323558e6e0031bfc93581"), "ADI", 7, false),
newErc20Contract("Wagner Test Token", Network.Testnet, parseAddress("0x2e7cd05f437eb256f363417fd8f920e2efa77540"), "WGN", 10, false),
newErc20Contract("Modest Test Token", Network.Testnet, parseAddress("0x57cc9b83730e6d22b224e9dc3e370967b44a2de0"), "MDS", 18, false),
Contract(name: "tribute-to-talk", network: Network.Testnet, address: parseAddress("0xC61aa0287247a0398589a66fCD6146EC0F295432")),
Contract(name: "stickers", network: Network.Testnet, address: parseAddress("0x8cc272396be7583c65bee82cd7b743c69a87287d"),
methods: [
("packCount", Method(signature: "packCount()")),
("getPackData", Method(signature: "getPackData(uint256)"))
].toTable
),
Contract(name: "sticker-market", network: Network.Testnet, address: parseAddress("0x6CC7274aF9cE9572d22DFD8545Fb8c9C9Bcb48AD"),
methods: [
("buyToken", Method(signature: "buyToken(uint256,address,uint256)"))
].toTable
),
newErc721Contract("sticker-pack", Network.Testnet, parseAddress("0xf852198d0385c4b871e0b91804ecd47c6ba97351"), "PACK", false, @[("tokenPackId", Method(signature: "tokenPackId(uint256)"))]),
newErc721Contract("kudos", Network.Testnet, parseAddress("0xcd520707fc68d153283d518b29ada466f9091ea8"), "KDO", true),
Contract(name: "ens-usernames", network: Network.Testnet, address: parseAddress("0x11d9F481effd20D76cEE832559bd9Aca25405841"),
methods: [
("register", Method(signature: "register(bytes32,address,bytes32,bytes32)")),
("getPrice", Method(signature: "getPrice()"))
].toTable
),
Contract(name: "ens-resolver", network: Network.Testnet, address: parseAddress("0x42D63ae25990889E35F215bC95884039Ba354115"),
methods: [
("setPubkey", Method(signature: "setPubkey(bytes32,bytes32,bytes32)"))
].toTable
),
# Rinkeby contracts
newErc20Contract("Moksha Coin", Network.Rinkeby, parseAddress("0x6ba7dc8dd10880ab83041e60c4ede52bb607864b"), "MOKSHA", 18, false),
newErc20Contract("WIBB", Network.Rinkeby, parseAddress("0x7d4ccf6af2f0fdad48ee7958bcc28bdef7b732c7"), "WIBB", 18, false),
newErc20Contract("Status Test Token", Network.Rinkeby, parseAddress("0x43d5adc3b49130a575ae6e4b00dfa4bc55c71621"), "STT", 18, false),
# xDai contracts
newErc20Contract("buffiDai", Network.XDai, parseAddress("0x3e50bf6703fc132a94e4baff068db2055655f11b"), "BUFF", 18, false),
]
proc getContract(network: Network, name: string): Contract =
let found = allContracts().filter(contract => contract.name == name and contract.network == network)
{.gcsafe.}:
withLock contractsLock:
let found = ALL_CONTRACTS.filter(contract => contract.name == name and contract.network == network)
result = if found.len > 0: found[0] else: nil
proc getContract*(name: string): Contract =
let network = settings.getCurrentNetwork()
getContract(network, name)
proc getErc20ContractBySymbol*(contracts: seq[Erc20Contract], symbol: string): Erc20Contract =
let found = contracts.filter(contract => contract.symbol.toLower == symbol.toLower)
result = if found.len > 0: found[0] else: nil
proc getErc20ContractByAddress*(contracts: seq[Erc20Contract], address: Address): Erc20Contract =
let found = contracts.filter(contract => contract.address == address)
result = if found.len > 0: found[0] else: nil
proc getErc20Contract*(symbol: string): Erc20Contract =
let network = settings.getCurrentNetwork()
{.gcsafe.}:
withLock contractsLock:
result = ALL_CONTRACTS.filter(contract => contract.network == network and contract of Erc20Contract).map(contract => Erc20Contract(contract)).getErc20ContractBySymbol(symbol)
proc getErc20Contract*(address: Address): Erc20Contract =
let network = settings.getCurrentNetwork()
{.gcsafe.}:
withLock contractsLock:
result = ALL_CONTRACTS.filter(contract => contract.network == network and contract of Erc20Contract).map(contract => Erc20Contract(contract)).getErc20ContractByAddress(address)
proc getErc20Contracts*(): seq[Erc20Contract] =
let network = settings.getCurrentNetwork()
{.gcsafe.}:
withLock contractsLock:
result = ALL_CONTRACTS.filter(contract => contract of Erc20Contract and contract.network == network).map(contract => Erc20Contract(contract))
proc getErc721Contract(network: Network, name: string): Erc721Contract =
{.gcsafe.}:
withLock contractsLock:
let found = ALL_CONTRACTS.filter(contract => contract of Erc721Contract and Erc721Contract(contract).name.toLower == name.toLower and contract.network == network)
result = if found.len > 0: Erc721Contract(found[0]) else: nil
proc getErc721Contract*(name: string): Erc721Contract =
let network = settings.getCurrentNetwork()
getErc721Contract(network, name)
proc getErc721Contracts*(): seq[Erc721Contract] =
let network = settings.getCurrentNetwork()
{.gcsafe.}:
withLock contractsLock:
result = ALL_CONTRACTS.filter(contract => contract of Erc721Contract and contract.network == network).map(contract => Erc721Contract(contract))
proc getSntContract*(): Erc20Contract =
if settings.getCurrentNetwork() == Network.Mainnet:
result = getErc20Contract("snt")
else:
result = getErc20Contract("stt")
if result == nil:
# TODO: xDai network does not have an SNT contract listed. We will need to handle
# having no SNT contract in other places in the code (ie anywhere that
# getSntContract() is called)
raise newException(ValueError, "A status contract could not be found for the current network")

View File

@ -1,8 +1,8 @@
import ./core as status, ./types, ./eth/contracts, ./settings, ./edn_helpers
import
json, json_serialization, tables, chronicles, strutils, sequtils, httpclient,
json, json_serialization, tables, chronicles, sequtils, httpclient,
stint, libp2p/[multihash, multicodec, cid], web3/[ethtypes, conversions]
from strutils import parseHexInt
from strutils import parseHexInt, parseInt
from nimcrypto import fromHex
proc decodeContentHash*(value: string): string =
@ -71,7 +71,7 @@ proc getBalance*(address: Address): int =
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
if response.result == "0x":
return 0
result = fromHex[int](response.result)
result = parseHexInt(response.result)
# Gets number of sticker packs
proc getPackCount*(): int =
@ -87,7 +87,7 @@ proc getPackCount*(): int =
raise newException(RpcException, "Error getting stickers balance: " & response.error.message)
if response.result == "0x":
return 0
result = fromHex[int](response.result)
result = parseHexInt(response.result)
# Gets sticker pack data
proc getPackData*(id: Stuint[256]): StickerPack =
@ -139,7 +139,7 @@ proc tokenOfOwnerByIndex*(address: Address, idx: Stuint[256]): int =
raise newException(RpcException, "Error getting owned tokens: " & response.error.message)
if response.result == "0x":
return 0
result = fromHex[int](response.result)
result = parseHexInt(response.result)
proc getPackIdFromTokenId*(tokenId: Stuint[256]): int =
let
@ -156,7 +156,7 @@ proc getPackIdFromTokenId*(tokenId: Stuint[256]): int =
raise newException(RpcException, "Error getting pack id from token id: " & response.error.message)
if response.result == "0x":
return 0
result = fromHex[int](response.result)
result = parseHexInt(response.result)
proc saveInstalledStickerPacks*(installedStickerPacks: Table[int, StickerPack]) =
let json = %* {}

View File

@ -4,9 +4,8 @@ import ./eth/contracts
import web3/[ethtypes, conversions]
import json_serialization
import settings
from types import Setting, Network
import default_tokens
import strutils
from types import Setting, Network, RpcResponse, RpcException
from utils import parseAddress
import locks
logScope:
@ -15,80 +14,73 @@ logScope:
var customTokensLock: Lock
initLock(customTokensLock)
var customTokens {.guard: customTokensLock.} = %*{}
var customTokens {.guard: customTokensLock.}: seq[Erc20Contract] = @[]
var dirty {.guard: customTokensLock.} = true
proc getCustomTokens*(useCached: bool = true): JsonNode =
proc getCustomTokens*(useCached: bool = true): seq[Erc20Contract] =
{.gcsafe.}:
withLock customTokensLock:
if useCached and not dirty:
result = customTokens
else:
let payload = %* []
result = callPrivateRPC("wallet_getCustomTokens", payload).parseJSON()["result"]
if result.kind == JNull: result = %* []
let responseStr = callPrivateRPC("wallet_getCustomTokens", payload)
# TODO: this should be handled in the deserialisation of RpcResponse,
# question has been posed: https://discordapp.com/channels/613988663034118151/616299964242460682/762828178624217109
let response = RpcResponse(result: $(responseStr.parseJSON()["result"]))
if not response.error.isNil:
raise newException(RpcException, "Error getting custom tokens: " & response.error.message)
result = if response.result == "null": @[] else: Json.decode(response.result, seq[Erc20Contract])
dirty = false
customTokens = result
proc getTokenBySymbol*(tokenList: JsonNode, symbol: string): JsonNode =
for defToken in tokenList.getElems():
if defToken["symbol"].getStr == symbol:
return defToken
return newJNull()
proc getTokenByAddress*(tokenList: JsonNode, address: string): JsonNode =
for defToken in tokenList.getElems():
if defToken["address"].getStr == address:
return defToken
return newJNull()
proc visibleTokensSNTDefault(): JsonNode =
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
let SNT = if getCurrentNetwork() == Network.Testnet: "STT" else: "SNT"
let currentNetwork = getCurrentNetwork()
let SNT = if currentNetwork == Network.Testnet: "STT" else: "SNT"
let response = getSetting[string](Setting.VisibleTokens, "{}").parseJSON
if response.hasKey(currentNetwork): return response
if not response.hasKey($currentNetwork):
# Set STT/SNT visible by default
response[currentNetwork] = %* [SNT]
response[$currentNetwork] = %* [SNT]
return response
proc toggleAsset*(symbol: string) =
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
let currentNetwork = getCurrentNetwork()
let visibleTokens = visibleTokensSNTDefault()
var visibleTokenList = visibleTokens[currentNetwork].to(seq[string])
var symbolIdx = visibleTokenList.find(symbol)
var visibleTokenList = visibleTokens[$currentNetwork].to(seq[string])
let symbolIdx = visibleTokenList.find(symbol)
if symbolIdx > -1:
visibleTokenList.del(symbolIdx)
else:
visibleTokenList.add symbol
visibleTokens[currentNetwork] = newJArray()
visibleTokens[currentNetwork] = %* visibleTokenList
visibleTokens[$currentNetwork] = newJArray()
visibleTokens[$currentNetwork] = %* visibleTokenList
discard saveSetting(Setting.VisibleTokens, $visibleTokens)
proc hideAsset*(symbol: string) =
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
let currentNetwork = getCurrentNetwork()
let visibleTokens = visibleTokensSNTDefault()
var visibleTokenList = visibleTokens[currentNetwork].to(seq[string])
var visibleTokenList = visibleTokens[$currentNetwork].to(seq[string])
var symbolIdx = visibleTokenList.find(symbol)
if symbolIdx > -1:
visibleTokenList.del(symbolIdx)
visibleTokens[currentNetwork] = newJArray()
visibleTokens[currentNetwork] = %* visibleTokenList
visibleTokens[$currentNetwork] = newJArray()
visibleTokens[$currentNetwork] = %* visibleTokenList
discard saveSetting(Setting.VisibleTokens, $visibleTokens)
proc getVisibleTokens*(): JsonNode =
let currentNetwork = getSetting[string](Setting.Networks_CurrentNetwork)
proc getVisibleTokens*(): seq[Erc20Contract] =
let currentNetwork = getCurrentNetwork()
let visibleTokens = visibleTokensSNTDefault()
let visibleTokenList = visibleTokens[currentNetwork].to(seq[string])
var visibleTokenList = visibleTokens[$currentNetwork].to(seq[string])
let customTokens = getCustomTokens()
result = newJArray()
result = @[]
for v in visibleTokenList:
let t = getTokenBySymbol(getDefaultTokens(), v)
if t.kind != JNull: result.elems.add(t)
let ct = getTokenBySymbol(getCustomTokens(), v)
if ct.kind != JNull: result.elems.add(ct)
let t = getErc20Contract(v)
if t != nil: result.add t
let ct = customTokens.getErc20ContractBySymbol(v)
if ct != nil: result.add ct
proc addCustomToken*(address: string, name: string, symbol: string, decimals: int, color: string) =
let payload = %* [{"address": address, "name": name, "symbol": symbol, "decimals": decimals, "color": color}]
@ -119,19 +111,20 @@ proc getTokenBalance*(tokenAddress: string, account: string): string =
let balance = response.parseJson["result"].getStr
var decimals = 18
let t = getTokenByAddress(getDefaultTokens(), tokenAddress)
let ct = getTokenByAddress(getCustomTokens(), tokenAddress)
if t.kind != JNull:
decimals = t["decimals"].getInt
elif ct.kind != JNull:
decimals = ct["decimals"].getInt
let address = parseAddress(tokenAddress)
let t = getErc20Contract(address)
let ct = getCustomTokens().getErc20ContractByAddress(address)
if t != nil:
decimals = t.decimals
elif ct != nil:
decimals = ct.decimals
result = $hex2Token(balance, decimals)
proc getSNTAddress*(): string =
let snt = contracts.getContract("snt")
result = "0x" & $snt.address
let snt = contracts.getSntContract()
result = $snt.address
proc getSNTBalance*(account: string): string =
let snt = contracts.getContract("snt")
result = getTokenBalance("0x" & $snt.address, account)
let snt = contracts.getSntContract()
result = getTokenBalance($snt.address, account)

View File

@ -139,13 +139,13 @@ proc readValue*(reader: var JsonReader, value: var Stuint[256])
type
Network* {.pure.} = enum
Mainnet,
Testnet,
Rinkeby,
Goerli,
XDai,
Poa,
Other
Mainnet = "mainnet_rpc",
Testnet = "testnet_rpc",
Rinkeby = "rinkeby_rpc",
Goerli = "goerli_rpc",
XDai = "xdai_rpc",
Poa = "poa_rpc",
Other = "other"
Setting* {.pure.} = enum
Appearance = "appearance",

View File

@ -42,8 +42,8 @@ proc init*(self: StickersModel) =
var evArgs = StickerArgs(e)
self.addStickerToRecent(evArgs.sticker, evArgs.save)
proc buildTransaction(self: StickersModel, packId: Uint256, address: Address, price: Uint256, approveAndCall: var ApproveAndCall[100], sntContract: var Contract, gas = "", gasPrice = ""): EthSend =
sntContract = status_contracts.getContract("snt")
proc buildTransaction(self: StickersModel, packId: Uint256, address: Address, price: Uint256, approveAndCall: var ApproveAndCall[100], sntContract: var Erc20Contract, gas = "", gasPrice = ""): EthSend =
sntContract = status_contracts.getSntContract()
let
stickerMktContract = status_contracts.getContract("sticker-market")
buyToken = BuyToken(packId: packId, address: address, price: price)
@ -54,7 +54,7 @@ proc buildTransaction(self: StickersModel, packId: Uint256, address: Address, pr
proc estimateGas*(self: StickersModel, packId: int, address: string, price: string, success: var bool): int =
var
approveAndCall: ApproveAndCall[100]
sntContract = status_contracts.getContract("snt")
sntContract = status_contracts.getSntContract()
tx = self.buildTransaction(
packId.u256,
parseAddress(address),
@ -68,7 +68,7 @@ proc estimateGas*(self: StickersModel, packId: int, address: string, price: stri
proc buyPack*(self: StickersModel, packId: int, address, price, gas, gasPrice, password: string, success: var bool): string =
var
sntContract: Contract
sntContract: Erc20Contract
approveAndCall: ApproveAndCall[100]
tx = self.buildTransaction(
packId.u256,

View File

@ -33,7 +33,7 @@ type WalletModel* = ref object
events*: EventEmitter
accounts*: seq[WalletAccount]
defaultCurrency*: string
tokens*: JsonNode
tokens*: seq[Erc20Contract]
totalBalance*: float
proc getDefaultCurrency*(self: WalletModel): string
@ -42,7 +42,7 @@ proc calculateTotalFiatBalance*(self: WalletModel)
proc newWalletModel*(events: EventEmitter): WalletModel =
result = WalletModel()
result.accounts = @[]
result.tokens = %* []
result.tokens = @[]
result.events = events
result.defaultCurrency = ""
result.totalBalance = 0.0
@ -61,10 +61,9 @@ proc initEvents*(self: WalletModel) =
proc delete*(self: WalletModel) =
discard
proc buildTokenTransaction(self: WalletModel, source, to, assetAddress: Address, value: float, transfer: var Transfer, contract: var Contract, gas = "", gasPrice = ""): EthSend =
let token = self.tokens.first("address", $assetAddress)
contract = getContract("snt")
transfer = Transfer(to: to, value: eth2Wei(value, token["decimals"].getInt))
proc buildTokenTransaction(self: WalletModel, source, to, assetAddress: Address, value: float, transfer: var Transfer, contract: var Erc20Contract, gas = "", gasPrice = ""): EthSend =
contract = getErc20Contract(assetAddress)
transfer = Transfer(to: to, value: eth2Wei(value, contract.decimals))
transactions.buildTokenTransaction(source, assetAddress, gas, gasPrice)
proc estimateGas*(self: WalletModel, source, to, value: string, success: var bool): int =
@ -102,7 +101,7 @@ proc checkPendingTransactions*(self: WalletModel, address: string, blockNumber:
proc estimateTokenGas*(self: WalletModel, source, to, assetAddress, value: string, success: var bool): int =
var
transfer: Transfer
contract: Contract
contract: Erc20Contract
tx = self.buildTokenTransaction(
parseAddress(source),
parseAddress(to),
@ -129,7 +128,7 @@ proc sendTransaction*(self: WalletModel, source, to, value, gas, gasPrice, passw
proc sendTokenTransaction*(self: WalletModel, source, to, assetAddress, value, gas, gasPrice, password: string, success: var bool): string =
var
transfer: Transfer
contract: Contract
contract: Erc20Contract
tx = self.buildTokenTransaction(
parseAddress(source),
parseAddress(to),
@ -153,13 +152,12 @@ proc getDefaultCurrency*(self: WalletModel): string =
# TODO: This needs to be removed or refactored so that test tokens are shown
# when on testnet https://github.com/status-im/nim-status-client/issues/613.
proc getStatusToken*(self: WalletModel): string =
var token = Asset(address: $getContract("snt").address)
if status_settings.getCurrentNetwork() == Network.Testnet:
token.name = "Status Test Token"
token.symbol = "STT"
else:
token.name = "Status Network Token"
token.symbol = "SNT"
var
token = Asset()
erc20Contract = getSntContract()
token.name = erc20Contract.name
token.symbol = erc20Contract.symbol
token.address = $erc20Contract.address
result = $(%token)
proc setDefaultCurrency*(self: WalletModel, currency: string) =
@ -171,8 +169,8 @@ proc generateAccountConfiguredAssets*(self: WalletModel, accountAddress: string)
var asset = Asset(name:"Ethereum", symbol: "ETH", value: "0.0", fiatBalanceDisplay: "0.0", accountAddress: accountAddress)
assets.add(asset)
for token in self.tokens:
var symbol = token["symbol"].getStr
var existingToken = Asset(name: token["name"].getStr, symbol: symbol, value: fmt"0.0", fiatBalanceDisplay: "$0.0", accountAddress: accountAddress, address: token["address"].getStr)
var symbol = token.symbol
var existingToken = Asset(name: token.name, symbol: symbol, value: fmt"0.0", fiatBalanceDisplay: "$0.0", accountAddress: accountAddress, address: $token.address)
assets.add(existingToken)
assets
@ -271,7 +269,7 @@ proc addWatchOnlyAccount*(self: WalletModel, address: string, accountName: strin
proc hasAsset*(self: WalletModel, account: string, symbol: string): bool =
self.tokens = status_tokens.getVisibleTokens()
self.tokens.anyIt(it["symbol"].getStr == symbol)
self.tokens.anyIt(it.symbol == symbol)
proc changeAccountSettings*(self: WalletModel, address: string, accountName: string, color: string): string =
var selectedAccount: WalletAccount

View File

@ -16,7 +16,7 @@ const COLLECTIBLE_TYPES* = [CRYPTOKITTY, KUDO, ETHERMON, STICKER]
const MAX_TOKENS = 200
proc getTokenUri(contract: Contract, tokenId: Stuint[256]): string =
proc getTokenUri(contract: Erc721Contract, tokenId: Stuint[256]): string =
try:
let
tokenUri = TokenUri(tokenId: tokenId)
@ -37,7 +37,7 @@ proc getTokenUri(contract: Contract, tokenId: Stuint[256]): string =
error "Error getting the token URI", mes = e.msg
result = ""
proc tokenOfOwnerByIndex(contract: Contract, address: Address, index: Stuint[256]): int =
proc tokenOfOwnerByIndex(contract: Erc721Contract, address: Address, index: Stuint[256]): int =
let
tokenOfOwnerByIndex = TokenOfOwnerByIndex(address: address, index: index)
payload = %* [{
@ -50,7 +50,7 @@ proc tokenOfOwnerByIndex(contract: Contract, address: Address, index: Stuint[256
return -1
result = fromHex[int](res)
proc tokensOfOwnerByIndex(contract: Contract, address: Address): seq[int] =
proc tokensOfOwnerByIndex(contract: Erc721Contract, address: Address): seq[int] =
var index = 0
var token: int
result = @[]
@ -117,7 +117,7 @@ proc getEthermons*(address: Address): string =
try:
var ethermons: seq[Collectible]
ethermons = @[]
let contract = getContract("ethermon")
let contract = getErc721Contract("ethermon")
if contract == nil: return $(%*ethermons)
let tokens = tokensOfOwnerByIndex(contract, address)
@ -156,7 +156,7 @@ proc getKudos*(address: Address): string =
try:
var kudos: seq[Collectible]
kudos = @[]
let contract = getContract("kudos")
let contract = getErc721Contract("kudos")
if contract == nil: return $(%*kudos)
let tokens = tokensOfOwnerByIndex(contract, address)
@ -196,7 +196,7 @@ proc getStickers*(address: Address): string =
try:
var stickers: seq[Collectible]
stickers = @[]
let contract = getContract("sticker-pack")
let contract = getErc721Contract("sticker-pack")
if contract == nil: return
let tokensIds = tokensOfOwnerByIndex(contract, address)