diff --git a/src/defaults.js b/src/defaults.js index 468e174..4557a5c 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -1 +1,6 @@ export const DEFAULT_ETH_NODE = 'wss://mainnet.eth.aragon.network/ws' +export const DEFAULT_CURRENCY = { + name: 'Ether', + symbol: 'ETH', + decimals: 18 +} diff --git a/src/evaluator/index.js b/src/evaluator/index.js index 83b7cc3..b385a5b 100644 --- a/src/evaluator/index.js +++ b/src/evaluator/index.js @@ -8,7 +8,7 @@ import Web3Utils from 'web3-utils' import BN from 'bn.js' import types from '../types' import HelperManager from '../helpers/HelperManager' -import { DEFAULT_ETH_NODE } from '../defaults' +import { DEFAULT_ETH_NODE, DEFAULT_CURRENCY } from '../defaults' /** * A value coupled with a type @@ -54,6 +54,7 @@ class TypedValue { * @param {radspec/Bindings} bindings An object of bindings and their values * @param {?Object} options An options object * @param {?Object} options.availablehelpers Available helpers + * @param {?Object} options.currency Native currency of the blockchain * @param {?Web3} options.eth Web3 instance (used over options.ethNode) * @param {?string} options.ethNode The URL to an Ethereum node * @param {?string} options.to The destination address for this expression's transaction @@ -61,7 +62,7 @@ class TypedValue { * @property {radspec/Bindings} bindings */ export class Evaluator { - constructor (ast, bindings, { availableHelpers = {}, eth, ethNode, from, to, value = '0', data } = {}) { + constructor (ast, bindings, { availableHelpers = {}, eth, ethNode, from, to, value = '0', data, currency } = {}) { this.ast = ast this.bindings = bindings this.eth = eth || new Eth(ethNode || DEFAULT_ETH_NODE) @@ -70,6 +71,7 @@ export class Evaluator { this.value = new TypedValue('uint', new BN(value)) this.data = data && new TypedValue('bytes', data) this.helpers = new HelperManager(availableHelpers) + this.currency = currency || DEFAULT_CURRENCY } /** @@ -358,6 +360,7 @@ export class Evaluator { * @param {?Object} options An options object * @param {?string} options.ethNode The URL to an Ethereum node * @param {?string} options.to The destination address for this expression's transaction + * @param {?Object} options.currency The native currency of the blockchain * @return {string} */ export function evaluate (ast, bindings, options) { diff --git a/src/helpers/lib/token.js b/src/helpers/lib/token.js index 883b601..69b0110 100644 --- a/src/helpers/lib/token.js +++ b/src/helpers/lib/token.js @@ -1,4 +1,5 @@ -export const ETH = '0x0000000000000000000000000000000000000000' +export const NON_TOKEN_ADDRESS = '0x0000000000000000000000000000000000000000' +export const ETH = NON_TOKEN_ADDRESS /* eslint-disable key-spacing, quotes */ export const ERC20_SYMBOL_BYTES32_ABI = [ diff --git a/src/helpers/tokenAmount.js b/src/helpers/tokenAmount.js index 4b60a43..28dcc77 100644 --- a/src/helpers/tokenAmount.js +++ b/src/helpers/tokenAmount.js @@ -1,9 +1,13 @@ import BN from 'bn.js' import { toUtf8 } from 'web3-utils' -import { ERC20_SYMBOL_BYTES32_ABI, ERC20_SYMBOL_DECIMALS_ABI, ETH } from './lib/token' +import { + ERC20_SYMBOL_BYTES32_ABI, + ERC20_SYMBOL_DECIMALS_ABI, + NON_TOKEN_ADDRESS +} from './lib/token' import { formatBN, tenPow } from './lib/formatBN' -export default (eth) => +export default (eth, evaluator) => /** * Format token amounts taking decimals into account * @@ -20,10 +24,10 @@ export default (eth) => let decimals let symbol - if (tokenAddress === ETH) { - decimals = new BN(18) + if (tokenAddress === NON_TOKEN_ADDRESS) { + decimals = new BN(evaluator.currency.decimals) if (showSymbol) { - symbol = 'ETH' + symbol = evaluator.currency.symbol } } else { let token = new eth.Contract(ERC20_SYMBOL_DECIMALS_ABI, tokenAddress) diff --git a/src/index.js b/src/index.js index 483a6a4..0e6eee0 100644 --- a/src/index.js +++ b/src/index.js @@ -53,6 +53,7 @@ import { evaluateRaw } from './lib' * @param {?Web3} options.eth Web3 instance (used over options.ethNode) * @param {?string} options.ethNode The URL to an Ethereum node * @param {?Object} options.userHelpers User defined helpers + * @param {?Object} options.currency Native currency of the blockchain * @return {Promise} The result of the evaluation */ function evaluate (source, call, { userHelpers = {}, ...options } = {}) { diff --git a/test/examples/examples.js b/test/examples/examples.js index 76f8bc8..dc8b91a 100644 --- a/test/examples/examples.js +++ b/test/examples/examples.js @@ -166,9 +166,8 @@ const helperCases = [ bindings: { token: address('0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359'), balance: int('1000000000000000001') } }, 'Balance: 1.000000000000000001 DAI'], [{ - source: 'Balance: `@tokenAmount(self.token(): address, balance)`', - bindings: { balance: int('10000000000000000000') }, - options: { to: '0xD39902f046B5885D70e9E66594b65f84D4d1c952' } + source: 'Balance: `@tokenAmount(token, balance)`', + bindings: { balance: int('10000000000000000000'), token: address('0x960b236A07cf122663c4303350609A66A7B288C0') }, }, 'Balance: 10 ANT'], [{ source: 'Ethereum launched `@formatDate(date)`', @@ -760,10 +759,10 @@ const cases = [ options: { to: '0x960b236A07cf122663c4303350609A66A7B288C0' } }, 'Burns the ANT balance of 0x0000000000000000000000000000000000000001 (balance is 0)'], [{ - source: 'Send ETH to the sale at block `((self.controller(): address).sale(): address).initialBlock(): uint` from `person`', + source: 'Send ETH to the sale at block `self.creationBlock(): uint` from `person`', bindings: { person: address('0x0000000000000000000000000000000000000001') }, options: { to: '0x960b236A07cf122663c4303350609A66A7B288C0' } - }, 'Send ETH to the sale at block 3723000 from 0x0000000000000000000000000000000000000001'], + }, 'Send ETH to the sale at block 3711733 from 0x0000000000000000000000000000000000000001'], [{ source: "Initialize Finance app for Vault at `_vault` with period length of `(_periodDuration - _periodDuration % 86400) / 86400` day`_periodDuration >= 172800 ? 's' : ' '`", bindings: { _periodDuration: int(86400 * 2), _vault: address('0x960b236A07cf122663c4303350609A66A7B288C0') }