diff --git a/.gitignore b/.gitignore index 42ebec6aa6..65381e1023 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ noBackup/ *.pro.user *.pro.autosave *.qml.autosave +.update.timestamp .vscode bin/ /bottles/ diff --git a/.gitmodules b/.gitmodules index e741ea9740..3e1d9b65f4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -91,3 +91,9 @@ [submodule "vendor/nim-status-go"] path = vendor/nim-status-go url = https://github.com/status-im/nim-status-go.git +[submodule "vendor/nim-task-runner"] + path = vendor/nim-task-runner + url = https://github.com/status-im/nim-task-runner.git +[submodule "vendor/edn.nim"] + path = vendor/edn.nim + url = https://github.com/status-im/edn.nim.git diff --git a/src/app/chat/views/stickers.nim b/src/app/chat/views/stickers.nim index 00e6e39887..25016b64aa 100644 --- a/src/app/chat/views/stickers.nim +++ b/src/app/chat/views/stickers.nim @@ -5,6 +5,7 @@ import ../../../status/libstatus/stickers as status_stickers import ../../../status/libstatus/wallet as status_wallet import sticker_pack_list, sticker_list, chat_item import json_serialization +import ../../../status/tasks/task_manager logScope: topics = "stickers-view" @@ -30,10 +31,10 @@ QtObject: result.recentStickers = newStickerList() result.activeChannel = activeChannel result.setup - + proc addStickerPackToList*(self: StickersView, stickerPack: StickerPack, isInstalled, isBought, isPending: bool) = self.stickerPacks.addStickerPackToList(stickerPack, newStickerList(stickerPack.stickers), isInstalled, isBought, isPending) - + proc getStickerPackList(self: StickersView): QVariant {.slot.} = newQVariant(self.stickerPacks) @@ -41,19 +42,12 @@ QtObject: read = getStickerPackList proc transactionWasSent*(self: StickersView, txResult: string) {.signal.} - + proc transactionCompleted*(self: StickersView, success: bool, txHash: string, revertReason: string = "") {.signal.} proc estimate*(self: StickersView, packId: int, address: string, price: string, uuid: string) {.slot.} = - let status_stickers = self.status.stickers - spawnAndSend(self, "setGasEstimate") do: - var success: bool - var estimate = status_stickers.estimateGas(packId, address, price, success) - if not success: - estimate = 325000 - let result: tuple[estimate: int, uuid: string] = (estimate, uuid) - Json.encode(result) - + self.status.taskManager.threadPool.stickers.stickerPackPurchaseGasEstimate(cast[pointer](self.vptr), "setGasEstimate", packId, address, price, uuid) + proc gasEstimateReturned*(self: StickersView, estimate: int, uuid: string) {.signal.} proc setGasEstimate*(self: StickersView, estimateJson: string) {.slot.} = @@ -63,7 +57,7 @@ QtObject: proc buy*(self: StickersView, packId: int, address: string, price: string, gas: string, gasPrice: string, password: string): string {.slot.} = var success: bool let response = self.status.stickers.buyPack(packId, address, price, gas, gasPrice, password, success) - # TODO: + # TODO: # check if response["error"] is not null and handle the error result = $(%* { "result": %response, "success": %success }) if success: @@ -133,7 +127,7 @@ QtObject: proc resetBuyAttempt*(self: StickersView, packId: int) {.slot.} = self.stickerPacks.updateStickerPackInList(packId, false, false) - + proc uninstall*(self: StickersView, packId: int) {.slot.} = self.status.stickers.uninstallStickerPack(packId) self.status.stickers.removeRecentStickers(packId) @@ -156,4 +150,4 @@ QtObject: proc send*(self: StickersView, hash: string, pack: int) {.slot.} = let sticker = Sticker(hash: hash, packId: pack) self.addRecentStickerToList(sticker) - self.status.chat.sendSticker(self.activeChannel.id, sticker) \ No newline at end of file + self.status.chat.sendSticker(self.activeChannel.id, sticker) diff --git a/src/app/wallet/view.nim b/src/app/wallet/view.nim index 804c5a6416..9d4ffc80df 100644 --- a/src/app/wallet/view.nim +++ b/src/app/wallet/view.nim @@ -491,9 +491,8 @@ QtObject: proc gasPricePredictionsChanged*(self: WalletView) {.signal.} proc getGasPricePredictions*(self: WalletView) {.slot.} = - let walletModel = self.status.wallet spawnAndSend(self, "getGasPricePredictionsResult") do: - $ %walletModel.getGasPricePredictions() + $ %getGasPricePredictions2() proc getGasPricePredictionsResult(self: WalletView, gasPricePredictionsJson: string) {.slot.} = let prediction = Json.decode(gasPricePredictionsJson, GasPricePrediction) diff --git a/src/nim_status_client.nim b/src/nim_status_client.nim index 94fe69f325..d089d97a0d 100644 --- a/src/nim_status_client.nim +++ b/src/nim_status_client.nim @@ -10,11 +10,13 @@ import app/onboarding/core as onboarding import app/login/core as login import app/provider/core as provider import status/signals/core as signals +import status/tasks/task_manager import status/libstatus/types import status/libstatus/accounts/constants import status_go import status/status as statuslib import ./eventemitter +import chronos, task_runner var signalsQObjPointer: pointer @@ -28,7 +30,9 @@ proc mainProc() = else: "/../fleets.json" - let status = statuslib.newStatusInstance(readFile(joinPath(getAppDir(), fleets))) + let taskManager = newTaskManager() + taskManager.init() + let status = statuslib.newStatusInstance(taskManager, readFile(joinPath(getAppDir(), fleets))) status.initNode() enableHDPI() @@ -132,6 +136,7 @@ proc mainProc() = wallet.checkPendingTransactions() wallet.start() + engine.setRootContextProperty("loginModel", login.variant) engine.setRootContextProperty("onboardingModel", onboarding.variant) @@ -152,6 +157,7 @@ proc mainProc() = profile.delete() utilsController.delete() browserController.delete() + taskManager.teardown() # Initialize only controllers whose init functions @@ -188,9 +194,7 @@ proc mainProc() = # it will be passed as a regular C function to libstatus. This means that # we cannot capture any local variables here (we must rely on globals) var callback: SignalCallback = proc(p0: cstring) {.cdecl.} = - setupForeignThreadGc() signal_handler(signalsQObjPointer, p0, "receiveSignal") - tearDownForeignThreadGc() status_go.setSignalEventCallback(callback) diff --git a/src/status/ens.nim b/src/status/ens.nim index 9ce98762ce..dd7d0227e6 100644 --- a/src/status/ens.nim +++ b/src/status/ens.nim @@ -21,12 +21,12 @@ const domain* = ".stateofus.eth" proc userName*(ensName: string, removeSuffix: bool = false): string = if ensName != "" and ensName.endsWith(domain): - if removeSuffix: + if removeSuffix: result = ensName.split(".")[0] else: result = ensName else: - if ensName.endsWith(".eth") and removeSuffix: + if ensName.endsWith(".eth") and removeSuffix: return ensName.split(".")[0] result = ensName @@ -63,7 +63,7 @@ proc namehash*(ensName:string): string = concatArrays[0..31] = node concatArrays[32..63] = elem node = keccak_256.digest(concatArrays).data - + result = "0x" & node.toHex() const registry* = "0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e" @@ -81,7 +81,7 @@ proc resolver*(usernameHash: string): string = result = "0x" & resolverAddr const owner_signature = "0x02571be3" # owner(bytes32 node) -proc owner*(username: string): string = +proc owner*(username: string): string = var userNameHash = namehash(addDomain(username)) userNameHash.removePrefix("0x") let payload = %* [{ @@ -97,7 +97,7 @@ proc owner*(username: string): string = result = "0x" & ownerAddr.substr(26) const pubkey_signature = "0xc8690233" # pubkey(bytes32 node) -proc pubkey*(username: string): string = +proc pubkey*(username: string): string = var userNameHash = namehash(addDomain(username)) userNameHash.removePrefix("0x") let ensResolver = resolver(userNameHash) @@ -116,7 +116,7 @@ proc pubkey*(username: string): string = result = "0x04" & pubkey const address_signature = "0x3b3b57de" # addr(bytes32 node) -proc address*(username: string): string = +proc address*(username: string): string = var userNameHash = namehash(addDomain(username)) userNameHash.removePrefix("0x") let ensResolver = resolver(userNameHash) @@ -133,7 +133,7 @@ proc address*(username: string): string = result = "0x" & address.substr(26) const contenthash_signature = "0xbc1c58d1" # contenthash(bytes32) -proc contenthash*(ensAddr: string): string = +proc contenthash*(ensAddr: string): string = var ensHash = namehash(ensAddr) ensHash.removePrefix("0x") let ensResolver = resolver(ensHash) @@ -147,7 +147,7 @@ proc contenthash*(ensAddr: string): string = let bytesResponse = response.parseJson["result"].getStr; if bytesResponse == "0x": return "" - + let size = fromHex(Stuint[256], bytesResponse[66..129]).truncate(int) result = bytesResponse[130..129+size*2] @@ -159,7 +159,7 @@ proc getPrice*(): Stuint[256] = "to": $contract.address, "data": contract.methods["getPrice"].encodeAbi() }, "latest"] - + let responseStr = callPrivateRPC("eth_call", payload) let response = Json.decode(responseStr, RpcResponse) if not response.error.isNil: @@ -180,7 +180,7 @@ proc registerUsernameEstimateGas*(username: string, address: string, pubKey: str ensUsernamesContract = contracts.getContract("ens-usernames") sntContract = contracts.getSntContract() price = getPrice() - + let register = Register(label: label, account: parseAddress(address), x: x, y: y) registerAbiEncoded = ensUsernamesContract.methods["register"].encodeAbi(register) @@ -188,7 +188,7 @@ proc registerUsernameEstimateGas*(username: string, address: string, pubKey: str approveAndCallAbiEncoded = sntContract.methods["approveAndCall"].encodeAbi(approveAndCallObj) var tx = transactions.buildTokenTransaction(parseAddress(address), sntContract.address, "", "") - + let response = sntContract.methods["approveAndCall"].estimateGas(tx, approveAndCallObj, success) if success: result = fromHex[int](response) @@ -202,11 +202,11 @@ proc registerUsername*(username, pubKey, address, gas, gasPrice, password: stri ensUsernamesContract = contracts.getContract("ens-usernames") sntContract = contracts.getSntContract() price = getPrice() - + let register = Register(label: label, account: parseAddress(address), x: x, y: y) registerAbiEncoded = ensUsernamesContract.methods["register"].encodeAbi(register) - approveAndCallObj = ApproveAndCall[132](to: ensUsernamesContract.address, value: price, data: DynamicBytes[132].fromHex(registerAbiEncoded)) + approveAndCallObj = ApproveAndCall[132](to: ensUsernamesContract.address, value: price, data: DynamicBytes[132].fromHex(registerAbiEncoded)) var tx = transactions.buildTokenTransaction(parseAddress(address), sntContract.address, gas, gasPrice) @@ -227,7 +227,7 @@ proc setPubKeyEstimateGas*(username: string, address: string, pubKey: string, su resolverAddress = resolver(hash) var tx = transactions.buildTokenTransaction(parseAddress(address), parseAddress(resolverAddress), "", "") - + try: let response = resolverContract.methods["setPubkey"].estimateGas(tx, setPubkey, success) if success: @@ -295,8 +295,10 @@ proc decodeENSContentHash*(value: string): tuple[ensType: ENSType, output: strin # 12 = identifies sha2-256 hash # 20 = multihash length = 32 # ...rest = multihash digest - let multiHash = MultiHash.init(nimcrypto.fromHex(multiHashStr)).get() - return (ENSType.IPFS, $Cid.init(CIDv0, MultiCodec.codec(codec), multiHash)) + let + multiHash = MultiHash.init(nimcrypto.fromHex(multiHashStr)).get() + decoded = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get() + return (ENSType.IPFS, $decoded) except Exception as e: error "Error decoding ENS contenthash", hash=value, exception=e.msg raise diff --git a/src/status/libstatus/eth/contracts.nim b/src/status/libstatus/eth/contracts.nim index 5c98cf4e23..aa7896061b 100644 --- a/src/status/libstatus/eth/contracts.nim +++ b/src/status/libstatus/eth/contracts.nim @@ -1,5 +1,5 @@ import - sequtils, sugar, macros, tables, strutils, locks + sequtils, sugar, macros, tables, strutils import web3/ethtypes, stew/byteutils, nimcrypto, json_serialization, chronicles @@ -16,9 +16,6 @@ export logScope: topics = "contracts" -var contractsLock: Lock -initLock(contractsLock) - const ERC20_METHODS = @[ ("name", Method(signature: "name()")), ("symbol", Method(signature: "symbol()")), @@ -80,186 +77,193 @@ proc newErc721Contract(name: string, network: Network, address: Address, symbol: 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("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: "sticker-market", network: Network.Mainnet, address: parseAddress("0x12824271339304d3a9f7e096e62a2a7e73b4a7e7"), - methods: [ - ("buyToken", Method(signature: "buyToken(uint256,address,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 - 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-resolver", network: Network.Mainnet, address: parseAddress("0x4976fb03C32e5B8cfe2b6cCB31c09Ba78EBaBa41"), - methods: [ - ("setPubkey", Method(signature: "setPubkey(bytes32,bytes32,bytes32)")) - ].toTable - ), +var + contracts {.threadvar.}: seq[Contract] + contractsInited {.threadvar.}: bool +proc allContracts(): seq[Contract] = + if contractsInited: + result = contracts + else: + contracts = @[ + # 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("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: "sticker-market", network: Network.Mainnet, address: parseAddress("0x12824271339304d3a9f7e096e62a2a7e73b4a7e7"), + methods: [ + ("buyToken", Method(signature: "buyToken(uint256,address,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 + 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-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 - ), + # 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), + # 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), + # xDai contracts + newErc20Contract("buffiDai", Network.XDai, parseAddress("0x3e50bf6703fc132a94e4baff068db2055655f11b"), "BUFF", 18, false), - newErc20Contract("Uniswap", Network.Mainnet, parseAddress("0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"), "UNI", 18, true), - newErc20Contract("Compound", Network.Mainnet, parseAddress("0xc00e94cb662c3520282e6f5717214004a7f26888"), "COMP", 18, true), - newErc20Contract("Balancer", Network.Mainnet, parseAddress("0xba100000625a3754423978a60c9317c58a424e3d"), "BAL", 18, true), - newErc20Contract("Akropolis", Network.Mainnet, parseAddress("0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7"), "AKRO", 18, true), - newErc20Contract("Orchid", Network.Mainnet, parseAddress("0x4575f41308EC1483f3d399aa9a2826d74Da13Deb"), "OXT", 18, false), -] + newErc20Contract("Uniswap", Network.Mainnet, parseAddress("0x1f9840a85d5af5bf1d1762f925bdaddc4201f984"), "UNI", 18, true), + newErc20Contract("Compound", Network.Mainnet, parseAddress("0xc00e94cb662c3520282e6f5717214004a7f26888"), "COMP", 18, true), + newErc20Contract("Balancer", Network.Mainnet, parseAddress("0xba100000625a3754423978a60c9317c58a424e3d"), "BAL", 18, true), + newErc20Contract("Akropolis", Network.Mainnet, parseAddress("0x8ab7404063ec4dbcfd4598215992dc3f8ec853d7"), "AKRO", 18, true), + newErc20Contract("Orchid", Network.Mainnet, parseAddress("0x4575f41308EC1483f3d399aa9a2826d74Da13Deb"), "OXT", 18, false), + ] + contractsInited = true + result = contracts proc getContract(network: Network, name: string): Contract = - {.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 + let found = allContracts().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() @@ -275,27 +279,19 @@ proc getErc20ContractByAddress*(contracts: seq[Erc20Contract], address: Address) 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) + result = allContracts().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) + result = allContracts().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)) + result = allContracts().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 + let found = allContracts().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() @@ -303,9 +299,7 @@ proc getErc721Contract*(name: string): Erc721Contract = 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)) + result = allContracts().filter(contract => contract of Erc721Contract and contract.network == network).map(contract => Erc721Contract(contract)) proc getSntContract*(): Erc20Contract = if settings.getCurrentNetwork() == Network.Mainnet: diff --git a/src/status/libstatus/settings.nim b/src/status/libstatus/settings.nim index 7b29953f21..abf3c34905 100644 --- a/src/status/libstatus/settings.nim +++ b/src/status/libstatus/settings.nim @@ -1,37 +1,46 @@ -import core, ./types, ../signals/types as statusgo_types, ./accounts/constants, ./utils -import json, tables, sugar, sequtils, strutils -import json_serialization -import locks -import uuids +import + json, tables, sugar, sequtils, strutils, atomics -var settingsLock {.global.}: Lock -initLock(settingsLock) +import + json_serialization, chronicles, uuids -var settings = %*{} -var dirty = true +import + ./core, ./types, ../signals/types as statusgo_types, ./accounts/constants, + ./utils + +var + settings {.threadvar.}: JsonNode + settingsInited {.threadvar.}: bool + dirty: Atomic[bool] + +dirty.store(true) +settings = %* {} proc saveSetting*(key: Setting, value: string | JsonNode): StatusGoError = - withLock settingsLock: - try: - let response = callPrivateRPC("settings_saveSetting", %* [key, value]) - result = Json.decode($response, StatusGoError) - except: - dirty = true + try: + let response = callPrivateRPC("settings_saveSetting", %* [key, value]) + let responseResult = $(response.parseJSON(){"result"}) + if responseResult == "null": + result.error = "" + else: result = Json.decode(response, StatusGoError) + except Exception as e: + error "Error saving setting", key=key, value=value, msg=e.msg + dirty.store(true) proc getWeb3ClientVersion*(): string = parseJson(callPrivateRPC("web3_clientVersion"))["result"].getStr proc getSettings*(useCached: bool = true, keepSensitiveData: bool = false): JsonNode = - withLock settingsLock: - {.gcsafe.}: - if useCached and not dirty and not keepSensitiveData: - result = settings - else: - result = callPrivateRPC("settings_getSettings").parseJSON()["result"] - if not keepSensitiveData: - dirty = false - delete(result, "mnemonic") - settings = result + let cacheIsDirty = (not settingsInited) or dirty.load + if useCached and (not cacheIsDirty) and (not keepSensitiveData): + result = settings + else: + result = callPrivateRPC("settings_getSettings").parseJSON()["result"] + if not keepSensitiveData: + dirty.store(false) + delete(result, "mnemonic") + settings = result + settingsInited = true proc getSetting*[T](name: Setting, defaultValue: T, useCached: bool = true): T = let settings: JsonNode = getSettings(useCached, $name == "mnemonic") diff --git a/src/status/libstatus/stickers.nim b/src/status/libstatus/stickers.nim index 2aba83304a..52bf22abe1 100644 --- a/src/status/libstatus/stickers.nim +++ b/src/status/libstatus/stickers.nim @@ -47,7 +47,8 @@ proc decodeContentHash*(value: string): string = # 20 = multihash length = 32 # ...rest = multihash digest let multiHash = MultiHash.init(nimcrypto.fromHex(multiHashStr)).get() - result = $Cid.init(CIDv0, MultiCodec.codec(codec), multiHash) + let resultTyped = Cid.init(CIDv0, MultiCodec.codec(codec), multiHash).get() + result = $resultTyped trace "Decoded sticker hash", cid=result except Exception as e: error "Error decoding sticker", hash=value, exception=e.msg @@ -59,14 +60,14 @@ proc decodeContentHash*(value: string): string = proc getBalance*(address: Address): int = let contract = contracts.getContract("sticker-pack") if contract == nil: return 0 - + let balanceOf = BalanceOf(address: address) payload = %* [{ "to": $contract.address, "data": contract.methods["balanceOf"].encodeAbi(balanceOf) }, "latest"] - + let responseStr = status.callPrivateRPC("eth_call", payload) let response = Json.decode(responseStr, RpcResponse) if not response.error.isNil: @@ -84,7 +85,7 @@ proc getPackCount*(): int = "to": $contract.address, "data": contract.methods["packCount"].encodeAbi() }, "latest"] - + let responseStr = status.callPrivateRPC("eth_call", payload) let response = Json.decode(responseStr, RpcResponse) if not response.error.isNil: @@ -95,39 +96,38 @@ proc getPackCount*(): int = # Gets sticker pack data proc getPackData*(id: Stuint[256]): StickerPack = - {.gcsafe.}: - let - contract = contracts.getContract("stickers") - contractMethod = contract.methods["getPackData"] - getPackData = GetPackData(packId: id) - payload = %* [{ - "to": $contract.address, - "data": contractMethod.encodeAbi(getPackData) - }, "latest"] - let responseStr = status.callPrivateRPC("eth_call", payload) - let response = Json.decode(responseStr, RpcResponse) - if not response.error.isNil: - raise newException(RpcException, "Error getting sticker pack data: " & response.error.message) + let + contract = contracts.getContract("stickers") + contractMethod = contract.methods["getPackData"] + getPackData = GetPackData(packId: id) + payload = %* [{ + "to": $contract.address, + "data": contractMethod.encodeAbi(getPackData) + }, "latest"] + let responseStr = status.callPrivateRPC("eth_call", payload) + let response = Json.decode(responseStr, RpcResponse) + if not response.error.isNil: + raise newException(RpcException, "Error getting sticker pack data: " & response.error.message) - let packData = contracts.decodeContractResponse[PackData](response.result) + let packData = contracts.decodeContractResponse[PackData](response.result) - # contract response includes a contenthash, which needs to be decoded to reveal - # an IPFS identifier. Once decoded, download the content from IPFS. This content - # is in EDN format, ie https://ipfs.infura.io/ipfs/QmWVVLwVKCwkVNjYJrRzQWREVvEk917PhbHYAUhA1gECTM - # and it also needs to be decoded in to a nim type - let secureSSLContext = newContext() - let client = newHttpClient(sslContext = secureSSLContext) - let contentHash = contracts.toHex(packData.contentHash) - let url = "https://ipfs.infura.io/ipfs/" & decodeContentHash(contentHash) - var ednMeta = client.getContent(url) + # contract response includes a contenthash, which needs to be decoded to reveal + # an IPFS identifier. Once decoded, download the content from IPFS. This content + # is in EDN format, ie https://ipfs.infura.io/ipfs/QmWVVLwVKCwkVNjYJrRzQWREVvEk917PhbHYAUhA1gECTM + # and it also needs to be decoded in to a nim type + let secureSSLContext = newContext() + let client = newHttpClient(sslContext = secureSSLContext) + let contentHash = contracts.toHex(packData.contentHash) + let url = "https://ipfs.infura.io/ipfs/" & decodeContentHash(contentHash) + var ednMeta = client.getContent(url) - # decode the EDN content in to a StickerPack - result = edn_helpers.decode[StickerPack](ednMeta) - # EDN doesn't include a packId for each sticker, so add it here - result.stickers.apply(proc(sticker: var Sticker) = - sticker.packId = truncate(id, int)) - result.id = truncate(id, int) - result.price = packData.price + # decode the EDN content in to a StickerPack + result = edn_helpers.decode[StickerPack](ednMeta) + # EDN doesn't include a packId for each sticker, so add it here + result.stickers.apply(proc(sticker: var Sticker) = + sticker.packId = truncate(id, int)) + result.id = truncate(id, int) + result.price = packData.price proc tokenOfOwnerByIndex*(address: Address, idx: Stuint[256]): int = let @@ -137,7 +137,7 @@ proc tokenOfOwnerByIndex*(address: Address, idx: Stuint[256]): int = "to": $contract.address, "data": contract.methods["tokenOfOwnerByIndex"].encodeAbi(tokenOfOwnerByIndex) }, "latest"] - + let responseStr = status.callPrivateRPC("eth_call", payload) let response = Json.decode(responseStr, RpcResponse) if not response.error.isNil: @@ -154,7 +154,7 @@ proc getPackIdFromTokenId*(tokenId: Stuint[256]): int = "to": $contract.address, "data": contract.methods["tokenPackId"].encodeAbi(tokenPackId) }, "latest"] - + let responseStr = status.callPrivateRPC("eth_call", payload) let response = Json.decode(responseStr, RpcResponse) if not response.error.isNil: @@ -202,7 +202,7 @@ proc getRecentStickers*(): seq[Sticker] = proc getAvailableStickerPacks*(): Table[int, StickerPack] = var availableStickerPacks = initTable[int, StickerPack]() - try: + try: let numPacks = getPackCount() for i in 0.. 0: + info "[threadpool] removing from taskQueue", + newlength=(taskQueue.len - 1) + task = taskQueue[0] + taskQueue.delete 0, 0 + + info "[threadpool] removing from threadsIdle", + newlength=(threadsIdle.len - 1) + let tpl = threadsIdle[0] + threadsIdle.delete 0, 0 + info "[threadpool] adding to threadsBusy", + newlength=(threadsBusy.len + 1), threadid=tpl.id + threadsBusy.add tpl.id, (tpl.thr, tpl.chanSendToTask) + await tpl.chanSendToTask.send(task.safe) + + else: + error "[threadpool] unknown notification", notice=notification.notice + except Exception as e: + warn "[threadpool] unknown error in thread notification", message=task, error=e.msg + + else: # must be a request to do task work + if allReady < arg.size or threadsBusy.len == arg.size: + # add to queue + info "[threadpool] adding to taskQueue", + newlength=(taskQueue.len + 1) + taskQueue.add task + + # do we have available threads in the threadpool? + elif threadsBusy.len < arg.size: + # check if we have tasks waiting on queue + if taskQueue.len > 0: + # remove first element from the task queue + info "[threadpool] adding to taskQueue", + newlength=(taskQueue.len + 1) + taskQueue.add task + info "[threadpool] removing from taskQueue", + newlength=(taskQueue.len - 1) + task = taskQueue[0] + taskQueue.delete 0, 0 + + info "[threadpool] removing from threadsIdle", + newlength=(threadsIdle.len - 1) + let tpl = threadsIdle[0] + threadsIdle.delete 0, 0 + info "[threadpool] adding to threadsBusy", + newlength=(threadsBusy.len + 1), threadid=tpl.id + threadsBusy.add tpl.id, (tpl.thr, tpl.chanSendToTask) + await tpl.chanSendToTask.send(task.safe) + + + var allTaskThreads: seq[Thread[TaskThreadArg]] = @[] + + for tpl in threadsIdle: + tpl.chanSendToTask.close() + allTaskThreads.add tpl.thr + for tpl in threadsBusy.values: + tpl.chanSendToTask.close() + allTaskThreads.add tpl.thr + + chanSendToMain.close() + chanRecvFromMainOrTask.close() + + joinThreads(allTaskThreads) + +proc poolThread(arg: PoolThreadArg) {.thread.} = + waitFor pool(arg) diff --git a/src/status/wallet.nim b/src/status/wallet.nim index 01a5d2c48d..fe5ce3e812 100644 --- a/src/status/wallet.nim +++ b/src/status/wallet.nim @@ -349,3 +349,18 @@ proc getGasPricePredictions*(self: WalletModel): GasPricePrediction = except Exception as e: echo "error getting gas price predictions" echo e.msg + +proc getGasPricePredictions2*(): GasPricePrediction = + if status_settings.getCurrentNetwork() != Network.Mainnet: + # TODO: what about other chains like xdai? + return GasPricePrediction(safeLow: 1.0, standard: 2.0, fast: 3.0, fastest: 4.0) + try: + let url: string = fmt"https://etherchain.org/api/gasPriceOracle" + let secureSSLContext = newContext() + let client = newHttpClient(sslContext = secureSSLContext) + client.headers = newHttpHeaders({ "Content-Type": "application/json" }) + let response = client.request(url) + result = Json.decode(response.body, GasPricePrediction) + except Exception as e: + echo "error getting gas price predictions" + echo e.msg diff --git a/vendor/DOtherSide b/vendor/DOtherSide index 1cc16aaa5c..5177a129d4 160000 --- a/vendor/DOtherSide +++ b/vendor/DOtherSide @@ -1 +1 @@ -Subproject commit 1cc16aaa5c643d0d33c31f9953fbe4a9f6bde151 +Subproject commit 5177a129d45985bb61471d7afecd397a82ed9d42 diff --git a/vendor/edn.nim b/vendor/edn.nim index 4cda60880e..3305e41f9d 160000 --- a/vendor/edn.nim +++ b/vendor/edn.nim @@ -1 +1 @@ -Subproject commit 4cda60880e108f0cb7efe1c209308f2db03267d9 +Subproject commit 3305e41f9da3f2f21c56bd23b74b0a3589f3bf3e diff --git a/vendor/nim-libp2p b/vendor/nim-libp2p index 8d9e231a74..70deac9e0d 160000 --- a/vendor/nim-libp2p +++ b/vendor/nim-libp2p @@ -1 +1 @@ -Subproject commit 8d9e231a74c1afc76b6745e05020f8d4e33501e7 +Subproject commit 70deac9e0d16f7d00a0d4404ed191042dbf079be diff --git a/vendor/nim-task-runner b/vendor/nim-task-runner new file mode 160000 index 0000000000..a87f3f85be --- /dev/null +++ b/vendor/nim-task-runner @@ -0,0 +1 @@ +Subproject commit a87f3f85be052fb3332358f95079a059cf1daf15