mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-23 09:52:26 +01:00
Add CurrencyDisplay and TokenCurrencyDisplay components
This commit is contained in:
parent
6670bc0e09
commit
da0df79047
@ -0,0 +1,24 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
export default class CurrencyDisplay extends PureComponent {
|
||||
static propTypes = {
|
||||
className: PropTypes.string,
|
||||
displayValue: PropTypes.string,
|
||||
prefix: PropTypes.string,
|
||||
}
|
||||
|
||||
render () {
|
||||
const { className, displayValue, prefix } = this.props
|
||||
const text = `${prefix || ''}${displayValue}`
|
||||
|
||||
return (
|
||||
<div
|
||||
className={className}
|
||||
title={text}
|
||||
>
|
||||
{ text }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { connect } from 'react-redux'
|
||||
import CurrencyDisplay from './currency-display.component'
|
||||
import { getValueFromWeiHex, formatCurrency } from '../../helpers/confirm-transaction/util'
|
||||
import { ETH } from '../../constants/common'
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const { value, numberOfDecimals = 2, currency } = ownProps
|
||||
const { metamask: { currentCurrency, conversionRate } } = state
|
||||
|
||||
const toCurrency = currency === ETH ? ETH : currentCurrency
|
||||
const convertedValue = getValueFromWeiHex({ value, toCurrency, conversionRate, numberOfDecimals })
|
||||
const formattedValue = formatCurrency(convertedValue, toCurrency)
|
||||
const displayValue = `${formattedValue} ${toCurrency.toUpperCase()}`
|
||||
|
||||
return {
|
||||
displayValue,
|
||||
}
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(CurrencyDisplay)
|
1
ui/app/components/currency-display/index.js
Normal file
1
ui/app/components/currency-display/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './currency-display.container'
|
@ -0,0 +1,27 @@
|
||||
import React from 'react'
|
||||
import assert from 'assert'
|
||||
import { shallow } from 'enzyme'
|
||||
import CurrencyDisplay from '../currency-display.component'
|
||||
|
||||
describe('CurrencyDisplay Component', () => {
|
||||
it('should render text with a className', () => {
|
||||
const wrapper = shallow(<CurrencyDisplay
|
||||
displayValue="$123.45"
|
||||
className="currency-display"
|
||||
/>)
|
||||
|
||||
assert.ok(wrapper.hasClass('currency-display'))
|
||||
assert.equal(wrapper.text(), '$123.45')
|
||||
})
|
||||
|
||||
it('should render text with a prefix', () => {
|
||||
const wrapper = shallow(<CurrencyDisplay
|
||||
displayValue="$123.45"
|
||||
className="currency-display"
|
||||
prefix="-"
|
||||
/>)
|
||||
|
||||
assert.ok(wrapper.hasClass('currency-display'))
|
||||
assert.equal(wrapper.text(), '-$123.45')
|
||||
})
|
||||
})
|
@ -0,0 +1,61 @@
|
||||
import assert from 'assert'
|
||||
import proxyquire from 'proxyquire'
|
||||
|
||||
let mapStateToProps
|
||||
|
||||
proxyquire('../currency-display.container.js', {
|
||||
'react-redux': {
|
||||
connect: ms => {
|
||||
mapStateToProps = ms
|
||||
return () => ({})
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
describe('CurrencyDisplay container', () => {
|
||||
describe('mapStateToProps()', () => {
|
||||
it('should return the correct props', () => {
|
||||
const mockState = {
|
||||
metamask: {
|
||||
conversionRate: 280.45,
|
||||
currentCurrency: 'usd',
|
||||
},
|
||||
}
|
||||
|
||||
const tests = [
|
||||
{
|
||||
props: {
|
||||
value: '0x2386f26fc10000',
|
||||
numberOfDecimals: 2,
|
||||
currency: 'usd',
|
||||
},
|
||||
result: {
|
||||
displayValue: '$2.80 USD',
|
||||
},
|
||||
},
|
||||
{
|
||||
props: {
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
result: {
|
||||
displayValue: '$2.80 USD',
|
||||
},
|
||||
},
|
||||
{
|
||||
props: {
|
||||
value: '0x1193461d01595930',
|
||||
currency: 'ETH',
|
||||
numberOfDecimals: 3,
|
||||
},
|
||||
result: {
|
||||
displayValue: '1.266 ETH',
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
tests.forEach(({ props, result }) => {
|
||||
assert.deepEqual(mapStateToProps(mockState, props), result)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
1
ui/app/components/token-currency-display/index.js
Normal file
1
ui/app/components/token-currency-display/index.js
Normal file
@ -0,0 +1 @@
|
||||
export { default } from './token-currency-display.component'
|
@ -0,0 +1,54 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import CurrencyDisplay from '../currency-display/currency-display.component'
|
||||
import { getTokenData } from '../../helpers/transactions.util'
|
||||
import { calcTokenAmount } from '../../token-util'
|
||||
|
||||
export default class TokenCurrencyDisplayContainer extends PureComponent {
|
||||
static propTypes = {
|
||||
transactionData: PropTypes.string,
|
||||
token: PropTypes.object,
|
||||
}
|
||||
|
||||
state = {
|
||||
displayValue: '',
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this.setDisplayValue()
|
||||
}
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
const { transactionData } = this.props
|
||||
const { transactionData: prevTransactionData } = prevProps
|
||||
|
||||
if (transactionData !== prevTransactionData) {
|
||||
this.setDisplayValue()
|
||||
}
|
||||
}
|
||||
|
||||
setDisplayValue () {
|
||||
const { transactionData: data, token } = this.props
|
||||
const { decimals = '', symbol = '' } = token
|
||||
const tokenData = getTokenData(data)
|
||||
|
||||
let displayValue
|
||||
|
||||
if (tokenData.params && tokenData.params.length === 2) {
|
||||
const tokenValue = tokenData.params[1].value
|
||||
const tokenAmount = calcTokenAmount(tokenValue, decimals)
|
||||
displayValue = `${tokenAmount} ${symbol}`
|
||||
}
|
||||
|
||||
this.setState({ displayValue })
|
||||
}
|
||||
|
||||
render () {
|
||||
return (
|
||||
<CurrencyDisplay
|
||||
{...this.props}
|
||||
displayValue={this.state.displayValue}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
import React from 'react'
|
||||
import assert from 'assert'
|
||||
import { shallow } from 'enzyme'
|
||||
import sinon from 'sinon'
|
||||
import TokenBalance from '../../token-balance'
|
||||
import CurrencyDisplay from '../../currency-display'
|
||||
import { SEND_ROUTE } from '../../../routes'
|
||||
import TokenViewBalance from '../token-view-balance.component'
|
||||
|
||||
const propsMethodSpies = {
|
||||
showDepositModal: sinon.spy(),
|
||||
}
|
||||
|
||||
const historySpies = {
|
||||
push: sinon.spy(),
|
||||
}
|
||||
|
||||
const t = (str1, str2) => str2 ? str1 + str2 : str1
|
||||
|
||||
describe('TokenViewBalance Component', () => {
|
||||
afterEach(() => {
|
||||
propsMethodSpies.showDepositModal.resetHistory()
|
||||
historySpies.push.resetHistory()
|
||||
})
|
||||
|
||||
it('should render ETH balance properly', () => {
|
||||
const wrapper = shallow(<TokenViewBalance
|
||||
showDepositModal={propsMethodSpies.showDepositModal}
|
||||
history={historySpies}
|
||||
network="3"
|
||||
ethBalance={123}
|
||||
fiatBalance={456}
|
||||
currentCurrency="usd"
|
||||
/>, { context: { t } })
|
||||
|
||||
assert.equal(wrapper.find('.token-view-balance').length, 1)
|
||||
assert.equal(wrapper.find('.token-view-balance__button').length, 2)
|
||||
assert.equal(wrapper.find(CurrencyDisplay).length, 2)
|
||||
|
||||
const buttons = wrapper.find('.token-view-balance__buttons')
|
||||
assert.equal(propsMethodSpies.showDepositModal.callCount, 0)
|
||||
buttons.childAt(0).simulate('click')
|
||||
assert.equal(propsMethodSpies.showDepositModal.callCount, 1)
|
||||
assert.equal(historySpies.push.callCount, 0)
|
||||
buttons.childAt(1).simulate('click')
|
||||
assert.equal(historySpies.push.callCount, 1)
|
||||
assert.equal(historySpies.push.getCall(0).args[0], SEND_ROUTE)
|
||||
})
|
||||
|
||||
it('should render token balance properly', () => {
|
||||
const token = {
|
||||
address: '0x35865238f0bec9d5ce6abff0fdaebe7b853dfcc5',
|
||||
decimals: '2',
|
||||
symbol: 'ABC',
|
||||
}
|
||||
|
||||
const wrapper = shallow(<TokenViewBalance
|
||||
showDepositModal={propsMethodSpies.showDepositModal}
|
||||
history={historySpies}
|
||||
network="3"
|
||||
ethBalance={123}
|
||||
fiatBalance={456}
|
||||
currentCurrency="usd"
|
||||
selectedToken={token}
|
||||
/>, { context: { t } })
|
||||
|
||||
assert.equal(wrapper.find('.token-view-balance').length, 1)
|
||||
assert.equal(wrapper.find('.token-view-balance__button').length, 1)
|
||||
assert.equal(wrapper.find(TokenBalance).length, 1)
|
||||
})
|
||||
})
|
@ -3,8 +3,9 @@ import PropTypes from 'prop-types'
|
||||
import Button from '../button'
|
||||
import Identicon from '../identicon'
|
||||
import TokenBalance from '../token-balance'
|
||||
import CurrencyDisplay from '../currency-display'
|
||||
import { SEND_ROUTE } from '../../routes'
|
||||
import { formatCurrency } from '../../helpers/confirm-transaction/util'
|
||||
import { ETH } from '../../constants/common'
|
||||
|
||||
export default class TokenViewBalance extends PureComponent {
|
||||
static contextTypes = {
|
||||
@ -16,14 +17,11 @@ export default class TokenViewBalance extends PureComponent {
|
||||
selectedToken: PropTypes.object,
|
||||
history: PropTypes.object,
|
||||
network: PropTypes.string,
|
||||
ethBalance: PropTypes.string,
|
||||
fiatBalance: PropTypes.string,
|
||||
currentCurrency: PropTypes.string,
|
||||
balance: PropTypes.string,
|
||||
}
|
||||
|
||||
renderBalance () {
|
||||
const { selectedToken, ethBalance, fiatBalance, currentCurrency } = this.props
|
||||
const formattedFiatBalance = formatCurrency(fiatBalance, currentCurrency)
|
||||
const { selectedToken, balance } = this.props
|
||||
|
||||
return selectedToken
|
||||
? (
|
||||
@ -34,12 +32,16 @@ export default class TokenViewBalance extends PureComponent {
|
||||
/>
|
||||
) : (
|
||||
<div className="token-view-balance__balance">
|
||||
<div className="token-view-balance__primary-balance">
|
||||
{ `${ethBalance} ETH` }
|
||||
</div>
|
||||
<div className="token-view-balance__secondary-balance">
|
||||
{ formattedFiatBalance }
|
||||
</div>
|
||||
<CurrencyDisplay
|
||||
className="token-view-balance__primary-balance"
|
||||
value={balance}
|
||||
currency={ETH}
|
||||
numberOfDecimals={3}
|
||||
/>
|
||||
<CurrencyDisplay
|
||||
className="token-view-balance__secondary-balance"
|
||||
value={balance}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -4,29 +4,17 @@ import { compose } from 'recompose'
|
||||
import TokenViewBalance from './token-view-balance.component'
|
||||
import { getSelectedToken, getSelectedAddress } from '../../selectors'
|
||||
import { showModal } from '../../actions'
|
||||
import { getValueFromWeiHex } from '../../helpers/confirm-transaction/util'
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const selectedAddress = getSelectedAddress(state)
|
||||
const { metamask } = state
|
||||
const { network, accounts, currentCurrency, conversionRate } = metamask
|
||||
const { metamask: { network, accounts } } = state
|
||||
const account = accounts[selectedAddress]
|
||||
const { balance: value } = account
|
||||
|
||||
const ethBalance = getValueFromWeiHex({
|
||||
value, toCurrency: 'ETH', conversionRate, numberOfDecimals: 3,
|
||||
})
|
||||
|
||||
const fiatBalance = getValueFromWeiHex({
|
||||
value, toCurrency: currentCurrency, conversionRate, numberOfDecimals: 2,
|
||||
})
|
||||
const { balance } = account
|
||||
|
||||
return {
|
||||
selectedToken: getSelectedToken(state),
|
||||
network,
|
||||
ethBalance,
|
||||
fiatBalance,
|
||||
currentCurrency,
|
||||
balance,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,102 @@
|
||||
import React from 'react'
|
||||
import assert from 'assert'
|
||||
import { shallow } from 'enzyme'
|
||||
import TransactionAction from '../transaction-action.component'
|
||||
|
||||
describe('TransactionAction Component', () => {
|
||||
const tOrDefault = key => key
|
||||
|
||||
describe('Outgoing transaction', () => {
|
||||
it('should render -- when methodData is still fetching', () => {
|
||||
const methodData = { data: {}, done: false, error: null }
|
||||
const transaction = {
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
submittedTime: 1534045442919,
|
||||
time: 1534045440641,
|
||||
txParams: {
|
||||
from: '0xc5ae6383e126f901dcb06131d97a88745bfa88d6',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0x96',
|
||||
to: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
}
|
||||
|
||||
const wrapper = shallow(<TransactionAction
|
||||
methodData={methodData}
|
||||
transaction={transaction}
|
||||
className="transaction-action"
|
||||
/>, { context: { tOrDefault }})
|
||||
|
||||
assert.equal(wrapper.find('.transaction-action').length, 1)
|
||||
assert.equal(wrapper.text(), '--')
|
||||
})
|
||||
|
||||
it('should render Outgoing', () => {
|
||||
const methodData = { data: {}, done: true, error: null }
|
||||
const transaction = {
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
submittedTime: 1534045442919,
|
||||
time: 1534045440641,
|
||||
txParams: {
|
||||
from: '0xc5ae6383e126f901dcb06131d97a88745bfa88d6',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0x96',
|
||||
to: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706',
|
||||
value: '0x2386f26fc10000',
|
||||
},
|
||||
}
|
||||
|
||||
const wrapper = shallow(<TransactionAction
|
||||
methodData={methodData}
|
||||
transaction={transaction}
|
||||
className="transaction-action"
|
||||
/>, { context: { tOrDefault }})
|
||||
|
||||
assert.equal(wrapper.find('.transaction-action').length, 1)
|
||||
assert.equal(wrapper.text(), 'outgoing')
|
||||
})
|
||||
|
||||
it('should render Approved', () => {
|
||||
const methodData = {
|
||||
data: {
|
||||
name: 'Approve',
|
||||
params: [
|
||||
{ type: 'address' },
|
||||
{ type: 'uint256' },
|
||||
],
|
||||
},
|
||||
done: true,
|
||||
error: null,
|
||||
}
|
||||
const transaction = {
|
||||
id: 1,
|
||||
status: 'confirmed',
|
||||
submittedTime: 1534045442919,
|
||||
time: 1534045440641,
|
||||
txParams: {
|
||||
from: '0xc5ae6383e126f901dcb06131d97a88745bfa88d6',
|
||||
gas: '0x5208',
|
||||
gasPrice: '0x3b9aca00',
|
||||
nonce: '0x96',
|
||||
to: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706',
|
||||
value: '0x2386f26fc10000',
|
||||
data: '0x095ea7b300000000000000000000000050a9d56c2b8ba9a5c7f2c08c3d26e0499f23a7060000000000000000000000000000000000000000000000000000000000000003',
|
||||
},
|
||||
}
|
||||
|
||||
const wrapper = shallow(<TransactionAction
|
||||
methodData={methodData}
|
||||
transaction={transaction}
|
||||
className="transaction-action"
|
||||
/>, { context: { tOrDefault }})
|
||||
|
||||
assert.equal(wrapper.find('.transaction-action').length, 1)
|
||||
assert.equal(wrapper.text(), 'approve')
|
||||
})
|
||||
})
|
||||
})
|
@ -3,21 +3,24 @@ import PropTypes from 'prop-types'
|
||||
import Identicon from '../identicon'
|
||||
import TransactionStatus from '../transaction-status'
|
||||
import TransactionAction from '../transaction-action'
|
||||
import CurrencyDisplay from '../currency-display'
|
||||
import TokenCurrencyDisplay from '../token-currency-display'
|
||||
import prefixForNetwork from '../../../lib/etherscan-prefix-for-network'
|
||||
import { CONFIRM_TRANSACTION_ROUTE } from '../../routes'
|
||||
import { UNAPPROVED_STATUS, TOKEN_METHOD_TRANSFER } from '../../constants/transactions'
|
||||
import { ETH } from '../../constants/common'
|
||||
|
||||
export default class TransactionListItem extends PureComponent {
|
||||
static propTypes = {
|
||||
history: PropTypes.object,
|
||||
transaction: PropTypes.object,
|
||||
ethTransactionAmount: PropTypes.string,
|
||||
fiatDisplayValue: PropTypes.string,
|
||||
value: PropTypes.string,
|
||||
methodData: PropTypes.object,
|
||||
showRetry: PropTypes.bool,
|
||||
retryTransaction: PropTypes.func,
|
||||
setSelectedToken: PropTypes.func,
|
||||
nonceAndDate: PropTypes.string,
|
||||
token: PropTypes.object,
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
@ -55,18 +58,50 @@ export default class TransactionListItem extends PureComponent {
|
||||
.then(id => history.push(`${CONFIRM_TRANSACTION_ROUTE}/${id}`))
|
||||
}
|
||||
|
||||
renderPrimaryCurrency () {
|
||||
const { token, transaction: { txParams: { data } = {} } = {}, value } = this.props
|
||||
|
||||
return token
|
||||
? (
|
||||
<TokenCurrencyDisplay
|
||||
className="transaction-list-item__amount transaction-list-item__amount--primary"
|
||||
token={token}
|
||||
transactionData={data}
|
||||
prefix="-"
|
||||
/>
|
||||
) : (
|
||||
<CurrencyDisplay
|
||||
className="transaction-list-item__amount transaction-list-item__amount--primary"
|
||||
value={value}
|
||||
prefix="-"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
renderSecondaryCurrency () {
|
||||
const { token, value } = this.props
|
||||
|
||||
return token
|
||||
? null
|
||||
: (
|
||||
<CurrencyDisplay
|
||||
className="transaction-list-item__amount transaction-list-item__amount--secondary"
|
||||
prefix="-"
|
||||
value={value}
|
||||
numberOfDecimals={2}
|
||||
currency={ETH}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
render () {
|
||||
const {
|
||||
transaction,
|
||||
ethTransactionAmount,
|
||||
fiatDisplayValue,
|
||||
methodData,
|
||||
showRetry,
|
||||
nonceAndDate,
|
||||
} = this.props
|
||||
const { txParams = {} } = transaction
|
||||
const fiatDisplayText = `-${fiatDisplayValue}`
|
||||
const ethDisplayText = ethTransactionAmount && `-${ethTransactionAmount} ETH`
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -94,18 +129,8 @@ export default class TransactionListItem extends PureComponent {
|
||||
className="transaction-list-item__status"
|
||||
status={transaction.status}
|
||||
/>
|
||||
<div
|
||||
className="transaction-list-item__amount transaction-list-item__amount--primary"
|
||||
title={fiatDisplayText}
|
||||
>
|
||||
{ fiatDisplayText }
|
||||
</div>
|
||||
<div
|
||||
className="transaction-list-item__amount transaction-list-item__amount--secondary"
|
||||
title={ethDisplayText}
|
||||
>
|
||||
{ ethDisplayText }
|
||||
</div>
|
||||
{ this.renderPrimaryCurrency() }
|
||||
{ this.renderSecondaryCurrency() }
|
||||
</div>
|
||||
{
|
||||
showRetry && !methodData.isFetching && (
|
||||
|
@ -4,42 +4,16 @@ import { compose } from 'recompose'
|
||||
import withMethodData from '../../higher-order-components/with-method-data'
|
||||
import TransactionListItem from './transaction-list-item.component'
|
||||
import { setSelectedToken, retryTransaction } from '../../actions'
|
||||
import { getEthFromWeiHex, getValueFromWeiHex, hexToDecimal } from '../../helpers/conversions.util'
|
||||
import { getTokenData } from '../../helpers/transactions.util'
|
||||
import { formatCurrency } from '../../helpers/confirm-transaction/util'
|
||||
import { calcTokenAmount } from '../../token-util'
|
||||
import { hexToDecimal } from '../../helpers/conversions.util'
|
||||
import { formatDate } from '../../util'
|
||||
|
||||
const mapStateToProps = (state, ownProps) => {
|
||||
const { metamask } = state
|
||||
const { currentCurrency, conversionRate } = metamask
|
||||
const { transaction: { txParams: { value, data, nonce } = {}, time } = {}, token } = ownProps
|
||||
|
||||
let ethTransactionAmount, fiatDisplayValue
|
||||
|
||||
if (token) {
|
||||
const { decimals = '', symbol = '' } = token
|
||||
const tokenData = getTokenData(data)
|
||||
|
||||
if (tokenData.params && tokenData.params.length === 2) {
|
||||
const tokenValue = tokenData.params[1].value
|
||||
const tokenAmount = calcTokenAmount(tokenValue, decimals)
|
||||
fiatDisplayValue = `${tokenAmount} ${symbol}`
|
||||
}
|
||||
} else {
|
||||
ethTransactionAmount = getEthFromWeiHex({ value, conversionRate })
|
||||
const fiatTransactionAmount = getValueFromWeiHex({
|
||||
value, conversionRate, toCurrency: currentCurrency, numberOfDecimals: 2,
|
||||
})
|
||||
const fiatFormattedAmount = formatCurrency(fiatTransactionAmount, currentCurrency)
|
||||
fiatDisplayValue = `${fiatFormattedAmount} ${currentCurrency.toUpperCase()}`
|
||||
}
|
||||
const { transaction: { txParams: { value, nonce } = {}, time } = {} } = ownProps
|
||||
|
||||
const nonceAndDate = nonce ? `#${hexToDecimal(nonce)} - ${formatDate(time)}` : formatDate(time)
|
||||
|
||||
return {
|
||||
ethTransactionAmount,
|
||||
fiatDisplayValue,
|
||||
value,
|
||||
nonceAndDate,
|
||||
}
|
||||
}
|
||||
|
1
ui/app/constants/common.js
Normal file
1
ui/app/constants/common.js
Normal file
@ -0,0 +1 @@
|
||||
export const ETH = 'ETH'
|
Loading…
Reference in New Issue
Block a user