Merge pull request #5121 from MetaMask/i5099-approve
Prevent token symbol from showing as null in the confirm screenfeature/default_network_editable
commit
0259eb0214
@ -1,55 +1,113 @@ |
|||||||
const log = require('loglevel') |
const log = require('loglevel') |
||||||
const util = require('./util') |
const util = require('./util') |
||||||
const BigNumber = require('bignumber.js') |
const BigNumber = require('bignumber.js') |
||||||
|
import contractMap from 'eth-contract-metadata' |
||||||
|
|
||||||
function tokenInfoGetter () { |
const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { |
||||||
const tokens = {} |
return { |
||||||
|
...acc, |
||||||
|
[base.toLowerCase()]: contractMap[base], |
||||||
|
} |
||||||
|
}, {}) |
||||||
|
|
||||||
return async (address) => { |
const DEFAULT_SYMBOL = '' |
||||||
if (tokens[address]) { |
const DEFAULT_DECIMALS = '0' |
||||||
return tokens[address] |
|
||||||
|
async function getSymbolFromContract (tokenAddress) { |
||||||
|
const token = util.getContractAtAddress(tokenAddress) |
||||||
|
|
||||||
|
try { |
||||||
|
const result = await token.symbol() |
||||||
|
return result[0] |
||||||
|
} catch (error) { |
||||||
|
log.warn(`symbol() call for token at address ${tokenAddress} resulted in error:`, error) |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
tokens[address] = await getSymbolAndDecimals(address) |
async function getDecimalsFromContract (tokenAddress) { |
||||||
|
const token = util.getContractAtAddress(tokenAddress) |
||||||
|
|
||||||
return tokens[address] |
try { |
||||||
|
const result = await token.decimals() |
||||||
|
const decimalsBN = result[0] |
||||||
|
return decimalsBN && decimalsBN.toString() |
||||||
|
} catch (error) { |
||||||
|
log.warn(`decimals() call for token at address ${tokenAddress} resulted in error:`, error) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function getContractMetadata (tokenAddress) { |
||||||
|
return tokenAddress && casedContractMap[tokenAddress.toLowerCase()] |
||||||
|
} |
||||||
|
|
||||||
|
async function getSymbol (tokenAddress) { |
||||||
|
let symbol = await getSymbolFromContract(tokenAddress) |
||||||
|
|
||||||
|
if (!symbol) { |
||||||
|
const contractMetadataInfo = getContractMetadata(tokenAddress) |
||||||
|
|
||||||
|
if (contractMetadataInfo) { |
||||||
|
symbol = contractMetadataInfo.symbol |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return symbol |
||||||
|
} |
||||||
|
|
||||||
|
async function getDecimals (tokenAddress) { |
||||||
|
let decimals = await getDecimalsFromContract(tokenAddress) |
||||||
|
|
||||||
|
if (!decimals || decimals === '0') { |
||||||
|
const contractMetadataInfo = getContractMetadata(tokenAddress) |
||||||
|
|
||||||
|
if (contractMetadataInfo) { |
||||||
|
decimals = contractMetadataInfo.decimals |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
async function getSymbolAndDecimals (tokenAddress, existingTokens = []) { |
return decimals |
||||||
|
} |
||||||
|
|
||||||
|
export async function getSymbolAndDecimals (tokenAddress, existingTokens = []) { |
||||||
const existingToken = existingTokens.find(({ address }) => tokenAddress === address) |
const existingToken = existingTokens.find(({ address }) => tokenAddress === address) |
||||||
|
|
||||||
if (existingToken) { |
if (existingToken) { |
||||||
return existingToken |
return { |
||||||
|
symbol: existingToken.symbol, |
||||||
|
decimals: existingToken.decimals, |
||||||
|
} |
||||||
} |
} |
||||||
|
|
||||||
let result = [] |
let symbol, decimals |
||||||
try { |
|
||||||
const token = util.getContractAtAddress(tokenAddress) |
|
||||||
|
|
||||||
result = await Promise.all([ |
try { |
||||||
token.symbol(), |
symbol = await getSymbol(tokenAddress) |
||||||
token.decimals(), |
decimals = await getDecimals(tokenAddress) |
||||||
]) |
} catch (error) { |
||||||
} catch (err) { |
log.warn(`symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, error) |
||||||
log.warn(`symbol() and decimal() calls for token at address ${tokenAddress} resulted in error:`, err) |
|
||||||
} |
} |
||||||
|
|
||||||
const [ symbol = [], decimals = [] ] = result |
|
||||||
|
|
||||||
return { |
return { |
||||||
symbol: symbol[0] || null, |
symbol: symbol || DEFAULT_SYMBOL, |
||||||
decimals: decimals[0] && decimals[0].toString() || null, |
decimals: decimals || DEFAULT_DECIMALS, |
||||||
} |
} |
||||||
} |
} |
||||||
|
|
||||||
function calcTokenAmount (value, decimals) { |
export function tokenInfoGetter () { |
||||||
const multiplier = Math.pow(10, Number(decimals || 0)) |
const tokens = {} |
||||||
return new BigNumber(String(value)).div(multiplier).toNumber() |
|
||||||
|
return async (address) => { |
||||||
|
if (tokens[address]) { |
||||||
|
return tokens[address] |
||||||
} |
} |
||||||
|
|
||||||
|
tokens[address] = await getSymbolAndDecimals(address) |
||||||
|
|
||||||
module.exports = { |
return tokens[address] |
||||||
tokenInfoGetter, |
} |
||||||
calcTokenAmount, |
} |
||||||
getSymbolAndDecimals, |
|
||||||
|
export function calcTokenAmount (value, decimals) { |
||||||
|
const multiplier = Math.pow(10, Number(decimals || 0)) |
||||||
|
return new BigNumber(String(value)).div(multiplier).toNumber() |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue