diff --git a/src/ethereum/ethEngine.js b/src/ethereum/ethEngine.js index 41cb8ba94..8251d203c 100644 --- a/src/ethereum/ethEngine.js +++ b/src/ethereum/ethEngine.js @@ -46,10 +46,14 @@ import { type EthereumTxOtherParams, type EthereumWalletOtherData, type LastEstimatedGasLimit, - asEthereumFees + type MetaToken, + type MetaTokenMap, + asEthereumFees, + asMetaTokenMap } from './ethTypes.js' const NETWORKFEES_POLL_MILLISECONDS = 60 * 10 * 1000 // 10 minutes +const METATOKENS_UPDATE_MILLISECONDS = 24 * 60 * 60 * 1000 // 1 day const ETH_GAS_STATION_WEI_MULTIPLIER = 100000000 // 100 million is the multiplier for ethgassstation because it uses 10x gwei const WEI_MULTIPLIER = 1000000000 const GAS_PRICE_SANITY_CHECK = 30000 // 3000 Gwei (ethgasstation api reports gas prices with additional decimal place) @@ -60,6 +64,7 @@ export class EthereumEngine extends CurrencyEngine { ethNetwork: EthereumNetwork lastEstimatedGasLimit: LastEstimatedGasLimit fetchCors: EdgeFetchFunction + otherMethods: Object constructor( currencyPlugin: EthereumPlugin, @@ -86,6 +91,10 @@ export class EthereumEngine extends CurrencyEngine { gasLimit: '' } this.fetchCors = fetchCors + + this.otherMethods = { + getTokenInfo: this.getTokenInfo.bind(this) + } } updateBalance(tk: string, balance: string) { @@ -191,6 +200,43 @@ export class EthereumEngine extends CurrencyEngine { this.updateNetworkFeesFromBaseFeePerGas(hexToDecimal(baseFeePerGas)) } + async checkUpdateCustomMetaTokens() { + // Get the meta tokens from the info server + try { + const infoServer = getEdgeInfoServer() + const url = `${infoServer}/v1/knownContract/allContracts` + const jsonObj: MetaTokenMap = await this.ethNetwork.fetchGet(url) + const valid = asMaybe(asMetaTokenMap)(jsonObj) != null + + if (valid) { + for (const contractAddress in jsonObj) { + const { name, symbol, decimals, iconUrl }: MetaToken = + jsonObj[contractAddress] + + this.allTokens.push({ + currencyCode: symbol, + currencyName: name, + denominations: [ + { + name: symbol, + multiplier: Math.pow(10, decimals).toString() + } + ], + symbolImage: iconUrl, + contractAddress + }) + } + } else { + this.log.error( + `Error: Fetched invalid metaTokens ${JSON.stringify(jsonObj)}` + ) + } + } catch (err) { + this.log.error(`Error fetching metaTokens from Edge info server`) + this.log.error(err) + } + } + async updateNetworkFeesFromBaseFeePerGas(baseFeePerGas: string) { /* This algorithm calculates fee amounts using the base multiplier from the @@ -352,6 +398,10 @@ export class EthereumEngine extends CurrencyEngine { async startEngine() { this.engineOn = true this.addToLoop('checkUpdateNetworkFees', NETWORKFEES_POLL_MILLISECONDS) + this.addToLoop( + 'checkUpdateCustomMetaTokens', + METATOKENS_UPDATE_MILLISECONDS + ) this.ethNetwork.needsLoop() diff --git a/src/ethereum/ethTypes.js b/src/ethereum/ethTypes.js index 78990f57b..52c1b5007 100644 --- a/src/ethereum/ethTypes.js +++ b/src/ethereum/ethTypes.js @@ -77,6 +77,20 @@ export const asEthereumFees = asObject<EthereumFee>(asEthereumFee) export type EthereumFees = $Call<typeof asEthereumFees> +export const asMetaToken = asObject({ + name: asString, + symbol: asString, + decimals: asNumber, + tradable: asBoolean, + iconUrl: asString +}) + +export type MetaToken = $Call<typeof asMetaToken> + +export const asMetaTokenMap = asObject<MetaToken>(asMetaToken) + +export type MetaTokenMap = $Call<typeof asMetaTokenMap> + export type EthereumCalcedFees = { gasPrice: string, gasLimit: string,