Merge branch 'release-8.0' into 8.0-to-8.1-merge

This commit is contained in:
André Sá 2022-07-26 11:25:04 +01:00
commit e7c2456ff7
25 changed files with 149 additions and 75 deletions

View file

@ -144,7 +144,7 @@ function run () {
_.filter(c => c.type !== 'erc-20'), _.filter(c => c.type !== 'erc-20'),
_.map(c => { _.map(c => {
const checked = isInstalledSoftware(c) && isInstalledVolume(c) const checked = isInstalledSoftware(c) && isInstalledVolume(c)
const name = c.code === 'ethereum' ? 'Ethereum' : c.display const name = c.code === 'ethereum' ? 'Ethereum and/or USDT' : c.display
return { return {
name, name,
value: c.code, value: c.code,

View file

@ -484,7 +484,7 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
const sql = `SELECT id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_override, const sql = `SELECT id, authorized_override, days_suspended, is_suspended, front_camera_path, front_camera_override,
phone, sms_override, id_card_data, id_card_data_override, id_card_data_expiration, phone, sms_override, id_card_data, id_card_data_override, id_card_data_expiration,
id_card_photo_path, id_card_photo_override, us_ssn, us_ssn_override, sanctions, sanctions_at, id_card_photo_path, id_card_photo_override, us_ssn, us_ssn_override, sanctions, sanctions_at,
sanctions_override, total_txs, total_spent, LEAST(created, last_transaction) AS last_active, fiat AS last_tx_fiat, sanctions_override, total_txs, total_spent, GREATEST(created, last_transaction, last_data_provided) AS last_active, fiat AS last_tx_fiat,
fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, custom_fields, notes, is_test_customer fiat_code AS last_tx_fiat_code, tx_class AS last_tx_class, custom_fields, notes, is_test_customer
FROM ( FROM (
SELECT c.id, c.authorized_override, SELECT c.id, c.authorized_override,
@ -493,6 +493,7 @@ function getCustomersList (phone = null, name = null, address = null, id = null)
c.front_camera_path, c.front_camera_override, c.front_camera_path, c.front_camera_override,
c.phone, c.sms_override, c.id_card_data, c.id_card_data_override, c.id_card_data_expiration, c.phone, c.sms_override, c.id_card_data, c.id_card_data_override, c.id_card_data_expiration,
c.id_card_photo_path, c.id_card_photo_override, c.us_ssn, c.us_ssn_override, c.sanctions, c.id_card_photo_path, c.id_card_photo_override, c.us_ssn, c.us_ssn_override, c.sanctions,
GREATEST(c.phone_at, c.id_card_data_at, c.front_camera_at, c.id_card_photo_at, c.us_ssn_at) AS last_data_provided,
c.sanctions_at, c.sanctions_override, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes, c.sanctions_at, c.sanctions_override, c.is_test_customer, c.created, t.tx_class, t.fiat, t.fiat_code, t.created as last_transaction, cn.notes,
row_number() OVER (partition by c.id order by t.created desc) AS rn, row_number() OVER (partition by c.id order by t.created desc) AS rn,
sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (partition by c.id) AS total_txs, sum(CASE WHEN t.id IS NOT NULL THEN 1 ELSE 0 END) OVER (partition by c.id) AS total_txs,

View file

@ -3,8 +3,8 @@ const _ = require('lodash/fp')
const { ALL } = require('../../plugins/common/ccxt') const { ALL } = require('../../plugins/common/ccxt')
const { BTC, BCH, DASH, ETH, LTC, ZEC, XMR } = COINS const { BTC, BCH, DASH, ETH, LTC, USDT, ZEC, XMR } = COINS
const { bitpay, coinbase, itbit, bitstamp, kraken, binanceus, cex, ftx, binance } = ALL const { bitpay, coinbase, itbit, bitstamp, kraken, binanceus, cex, ftx } = ALL
const TICKER = 'ticker' const TICKER = 'ticker'
const WALLET = 'wallet' const WALLET = 'wallet'
@ -29,8 +29,8 @@ const ALL_ACCOUNTS = [
{ code: 'mock-ticker', display: 'Mock (Caution!)', class: TICKER, cryptos: ALL_CRYPTOS, dev: true }, { code: 'mock-ticker', display: 'Mock (Caution!)', class: TICKER, cryptos: ALL_CRYPTOS, dev: true },
{ code: 'bitcoind', display: 'bitcoind', class: WALLET, cryptos: [BTC] }, { code: 'bitcoind', display: 'bitcoind', class: WALLET, cryptos: [BTC] },
{ code: 'no-layer2', display: 'No Layer 2', class: LAYER_2, cryptos: ALL_CRYPTOS }, { code: 'no-layer2', display: 'No Layer 2', class: LAYER_2, cryptos: ALL_CRYPTOS },
{ code: 'infura', display: 'Infura', class: WALLET, cryptos: [ETH] }, { code: 'infura', display: 'Infura', class: WALLET, cryptos: [ETH, USDT] },
{ code: 'geth', display: 'geth', class: WALLET, cryptos: [ETH] }, { code: 'geth', display: 'geth', class: WALLET, cryptos: [ETH, USDT] },
{ code: 'zcashd', display: 'zcashd', class: WALLET, cryptos: [ZEC] }, { code: 'zcashd', display: 'zcashd', class: WALLET, cryptos: [ZEC] },
{ code: 'litecoind', display: 'litecoind', class: WALLET, cryptos: [LTC] }, { code: 'litecoind', display: 'litecoind', class: WALLET, cryptos: [LTC] },
{ code: 'dashd', display: 'dashd', class: WALLET, cryptos: [DASH] }, { code: 'dashd', display: 'dashd', class: WALLET, cryptos: [DASH] },

View file

@ -218,6 +218,7 @@ function plugins (settings, deviceId) {
return { return {
cryptoCode, cryptoCode,
display: cryptoRec.display, display: cryptoRec.display,
isCashInOnly: Boolean(cryptoRec.isCashinOnly),
minimumTx: BN.max(minimumTx, cashInFee), minimumTx: BN.max(minimumTx, cashInFee),
cashInFee, cashInFee,
cashInCommission, cashInCommission,

View file

@ -11,7 +11,7 @@ const bitpay = require('../ticker/bitpay')
const binance = require('../exchange/binance') const binance = require('../exchange/binance')
const logger = require('../../logger') const logger = require('../../logger')
const { BTC, BCH, DASH, ETH, LTC, ZEC } = COINS const { BTC, BCH, DASH, ETH, LTC, ZEC, USDT } = COINS
const ALL = { const ALL = {
cex: cex, cex: cex,
@ -22,7 +22,7 @@ const ALL = {
itbit: itbit, itbit: itbit,
bitpay: bitpay, bitpay: bitpay,
coinbase: { coinbase: {
CRYPTO: [BTC, ETH, LTC, DASH, ZEC, BCH], CRYPTO: [BTC, ETH, LTC, DASH, ZEC, BCH, USDT],
FIAT: 'ALL_CURRENCIES' FIAT: 'ALL_CURRENCIES'
}, },
binance: binance binance: binance

View file

@ -4,8 +4,8 @@ const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts') const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, DASH, ETH, LTC, ZEC } = COINS const { BTC, BCH, DASH, ETH, LTC, ZEC, USDT } = COINS
const CRYPTO = [BTC, ETH, LTC, DASH, ZEC, BCH] const CRYPTO = [BTC, ETH, LTC, DASH, ZEC, BCH, USDT]
const FIAT = ['USD'] const FIAT = ['USD']
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey'] const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey']

View file

@ -4,8 +4,8 @@ const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts') const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, ETH, LTC, BCH } = COINS const { BTC, ETH, LTC, BCH, USDT } = COINS
const CRYPTO = [BTC, ETH, LTC, BCH] const CRYPTO = [BTC, ETH, LTC, BCH, USDT]
const FIAT = ['USD', 'EUR'] const FIAT = ['USD', 'EUR']
const AMOUNT_PRECISION = 8 const AMOUNT_PRECISION = 8
const REQUIRED_CONFIG_FIELDS = ['key', 'secret', 'clientId'] const REQUIRED_CONFIG_FIELDS = ['key', 'secret', 'clientId']

View file

@ -4,8 +4,8 @@ const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts') const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, DASH, ETH, LTC } = COINS const { BTC, BCH, DASH, ETH, LTC, USDT } = COINS
const CRYPTO = [BTC, ETH, LTC, DASH, BCH] const CRYPTO = [BTC, ETH, LTC, DASH, BCH, USDT]
const FIAT = ['USD', 'EUR'] const FIAT = ['USD', 'EUR']
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey'] const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey']

View file

@ -4,8 +4,8 @@ const _ = require('lodash/fp')
const { ORDER_TYPES } = require('./consts') const { ORDER_TYPES } = require('./consts')
const ORDER_TYPE = ORDER_TYPES.MARKET const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, ETH, LTC } = COINS const { BTC, BCH, ETH, LTC, USDT } = COINS
const CRYPTO = [BTC, ETH, LTC, BCH] const CRYPTO = [BTC, ETH, LTC, BCH, USDT]
const FIAT = ['USD'] const FIAT = ['USD']
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey'] const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey']

View file

@ -4,8 +4,8 @@ const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins') const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.LIMIT const ORDER_TYPE = ORDER_TYPES.LIMIT
const { BTC, ETH } = COINS const { BTC, ETH, USDT } = COINS
const CRYPTO = [BTC, ETH] const CRYPTO = [BTC, ETH, USDT]
const FIAT = ['USD'] const FIAT = ['USD']
const AMOUNT_PRECISION = 4 const AMOUNT_PRECISION = 4
const REQUIRED_CONFIG_FIELDS = ['clientKey', 'clientSecret', 'userId', 'walletId'] const REQUIRED_CONFIG_FIELDS = ['clientKey', 'clientSecret', 'userId', 'walletId']

View file

@ -4,8 +4,8 @@ const { ORDER_TYPES } = require('./consts')
const { COINS } = require('@lamassu/coins') const { COINS } = require('@lamassu/coins')
const ORDER_TYPE = ORDER_TYPES.MARKET const ORDER_TYPE = ORDER_TYPES.MARKET
const { BTC, BCH, DASH, ETH, LTC, ZEC, XMR } = COINS const { BTC, BCH, DASH, ETH, LTC, ZEC, XMR, USDT } = COINS
const CRYPTO = [BTC, ETH, LTC, DASH, ZEC, BCH, XMR] const CRYPTO = [BTC, ETH, LTC, DASH, ZEC, BCH, XMR, USDT]
const FIAT = ['USD', 'EUR'] const FIAT = ['USD', 'EUR']
const AMOUNT_PRECISION = 6 const AMOUNT_PRECISION = 6
const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey'] const REQUIRED_CONFIG_FIELDS = ['apiKey', 'privateKey']

View file

@ -6,13 +6,15 @@ const web3 = new Web3()
const hdkey = require('ethereumjs-wallet/hdkey') const hdkey = require('ethereumjs-wallet/hdkey')
const { FeeMarketEIP1559Transaction } = require('@ethereumjs/tx') const { FeeMarketEIP1559Transaction } = require('@ethereumjs/tx')
const { default: Common, Chain, Hardfork } = require('@ethereumjs/common') const { default: Common, Chain, Hardfork } = require('@ethereumjs/common')
const Tx = require('ethereumjs-tx')
const { default: PQueue } = require('p-queue')
const util = require('ethereumjs-util') const util = require('ethereumjs-util')
const coins = require('@lamassu/coins') const coins = require('@lamassu/coins')
const { default: PQueue } = require('p-queue')
const pify = require('pify') const _pify = require('pify')
const BN = require('../../../bn') const BN = require('../../../bn')
const ABI = require('../../tokens') const ABI = require('../../tokens')
const logger = require('../../../logger')
exports.SUPPORTED_MODULES = ['wallet'] exports.SUPPORTED_MODULES = ['wallet']
@ -40,6 +42,19 @@ const SWEEP_QUEUE = new PQueue({
interval: 250, interval: 250,
}) })
const infuraCalls = {}
const pify = _function => {
if (_.isString(_function.call)) logInfuraCall(_function.call)
return _pify(_function)
}
const logInfuraCall = call => {
if (!_.includes('infura', web3.currentProvider.host)) return
_.isNil(infuraCalls[call]) ? infuraCalls[call] = 1 : infuraCalls[call]++
logger.info(`Calling web3 method ${call} via Infura. Current count for this session: ${JSON.stringify(infuraCalls)}`)
}
function connect (url) { function connect (url) {
web3.setProvider(new web3.providers.HttpProvider(url)) web3.setProvider(new web3.providers.HttpProvider(url))
} }
@ -56,7 +71,9 @@ function isStrictAddress (cryptoCode, toAddress, settings, operatorId) {
function sendCoins (account, tx, settings, operatorId, feeMultiplier) { function sendCoins (account, tx, settings, operatorId, feeMultiplier) {
const { toAddress, cryptoAtoms, cryptoCode } = tx const { toAddress, cryptoAtoms, cryptoCode } = tx
return generateTx(toAddress, defaultWallet(account), cryptoAtoms, false, cryptoCode) const isErc20Token = coins.utils.isErc20Token(cryptoCode)
return (isErc20Token ? generateErc20Tx : generateTx)(toAddress, defaultWallet(account), cryptoAtoms, false, cryptoCode)
.then(pify(web3.eth.sendSignedTransaction)) .then(pify(web3.eth.sendSignedTransaction))
.then(txid => { .then(txid => {
return pify(web3.eth.getTransaction)(txid) return pify(web3.eth.getTransaction)(txid)
@ -84,14 +101,16 @@ function balance (account, cryptoCode, settings, operatorId) {
const pendingBalance = (address, cryptoCode) => { const pendingBalance = (address, cryptoCode) => {
const promises = [_balance(true, address, cryptoCode), _balance(false, address, cryptoCode)] const promises = [_balance(true, address, cryptoCode), _balance(false, address, cryptoCode)]
return Promise.all(promises).then(([pending, confirmed]) => pending.minus(confirmed)) return Promise.all(promises).then(([pending, confirmed]) => BN(pending).minus(confirmed))
} }
const confirmedBalance = (address, cryptoCode) => _balance(false, address, cryptoCode) const confirmedBalance = (address, cryptoCode) => _balance(false, address, cryptoCode)
function _balance (includePending, address, cryptoCode) { function _balance (includePending, address, cryptoCode) {
if (coins.utils.isErc20Token(cryptoCode)) { if (coins.utils.isErc20Token(cryptoCode)) {
const contract = web3.eth.contract(ABI.ERC20).at(coins.utils.getErc20Token(cryptoCode).contractAddress) const contract = new web3.eth.Contract(ABI.ERC20, coins.utils.getErc20Token(cryptoCode).contractAddress)
return contract.balanceOf(address.toLowerCase()) return contract.methods.balanceOf(address.toLowerCase()).call((_, balance) => {
return contract.methods.decimals().call((_, decimals) => BN(balance).div(10 ** decimals))
})
} }
const block = includePending ? 'pending' : undefined const block = includePending ? 'pending' : undefined
return pify(web3.eth.getBalance)(address.toLowerCase(), block) return pify(web3.eth.getBalance)(address.toLowerCase(), block)
@ -99,17 +118,66 @@ function _balance (includePending, address, cryptoCode) {
.then(balance => balance ? BN(balance) : BN(0)) .then(balance => balance ? BN(balance) : BN(0))
} }
function generateErc20Tx (_toAddress, wallet, amount, includesFee, cryptoCode) {
const fromAddress = '0x' + wallet.getAddress().toString('hex')
const toAddress = coins.utils.getErc20Token(cryptoCode).contractAddress
const contract = new web3.eth.Contract(ABI.ERC20, toAddress)
const contractData = contract.methods.transfer(_toAddress.toLowerCase(), hex(amount))
const txTemplate = {
from: fromAddress,
to: toAddress,
value: hex(BN(0)),
data: contractData.encodeABI()
}
const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London })
const promises = [
pify(contractData.estimateGas)(txTemplate),
pify(web3.eth.getTransactionCount)(fromAddress),
pify(web3.eth.getBlock)('pending')
]
return Promise.all(promises)
.then(([gas, txCount, { baseFeePerGas }]) => [
BN(gas),
_.max([0, txCount, lastUsedNonces[fromAddress] + 1]),
BN(baseFeePerGas)
])
.then(([gas, txCount, baseFeePerGas]) => {
lastUsedNonces[fromAddress] = txCount
const maxPriorityFeePerGas = new BN(web3.utils.toWei('2.5', 'gwei')) // web3 default value
const maxFeePerGas = new BN(2).times(baseFeePerGas).plus(maxPriorityFeePerGas)
const rawTx = {
chainId: 1,
nonce: txCount,
maxPriorityFeePerGas: web3.utils.toHex(maxPriorityFeePerGas),
maxFeePerGas: web3.utils.toHex(maxFeePerGas),
gasLimit: hex(gas),
to: toAddress,
from: fromAddress,
value: hex(BN(0)),
data: contractData.encodeABI()
}
const tx = FeeMarketEIP1559Transaction.fromTxData(rawTx, { common })
const privateKey = wallet.getPrivateKey()
const signedTx = tx.sign(privateKey)
return '0x' + signedTx.serialize().toString('hex')
})
}
function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) { function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
const fromAddress = '0x' + wallet.getAddress().toString('hex') const fromAddress = '0x' + wallet.getAddress().toString('hex')
const isErc20Token = coins.utils.isErc20Token(cryptoCode) const toAddress = _toAddress.toLowerCase()
const toAddress = isErc20Token ? coins.utils.getErc20Token(cryptoCode).contractAddress : _toAddress.toLowerCase()
let contract, contractData
if (isErc20Token) {
contract = web3.eth.contract(ABI.ERC20).at(toAddress)
contractData = isErc20Token && contract.transfer.getData(_toAddress.toLowerCase(), hex(toSend))
}
const txTemplate = { const txTemplate = {
from: fromAddress, from: fromAddress,
@ -117,9 +185,7 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
value: amount.toString() value: amount.toString()
} }
if (isErc20Token) txTemplate.data = contractData const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.London })
const common = new Common({ chain: Chain.Ropsten, hardfork: Hardfork.London })
const promises = [ const promises = [
pify(web3.eth.estimateGas)(txTemplate), pify(web3.eth.estimateGas)(txTemplate),
@ -129,10 +195,11 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
] ]
return Promise.all(promises) return Promise.all(promises)
.then(([gas, gasPrice, txCount]) => [ .then(([gas, gasPrice, txCount, { baseFeePerGas }]) => [
BN(gas), BN(gas),
BN(gasPrice), BN(gasPrice),
_.max([0, txCount, lastUsedNonces[fromAddress] + 1]) _.max([0, txCount, lastUsedNonces[fromAddress] + 1]),
BN(baseFeePerGas)
]) ])
.then(([gas, gasPrice, txCount, baseFeePerGas]) => { .then(([gas, gasPrice, txCount, baseFeePerGas]) => {
lastUsedNonces[fromAddress] = txCount lastUsedNonces[fromAddress] = txCount
@ -141,7 +208,7 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
? amount.minus(gasPrice.times(gas)) ? amount.minus(gasPrice.times(gas))
: amount : amount
const maxPriorityFeePerGas = new BN(2.5) // web3 default value const maxPriorityFeePerGas = new BN(web3.utils.toWei('2.5', 'gwei')) // web3 default value
const maxFeePerGas = new BN(2).times(baseFeePerGas).plus(maxPriorityFeePerGas) const maxFeePerGas = new BN(2).times(baseFeePerGas).plus(maxPriorityFeePerGas)
const rawTx = { const rawTx = {
@ -152,11 +219,7 @@ function generateTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
gasLimit: hex(gas), gasLimit: hex(gas),
to: toAddress, to: toAddress,
from: fromAddress, from: fromAddress,
value: isErc20Token ? hex(BN(0)) : hex(toSend) value: hex(toSend)
}
if (isErc20Token) {
rawTx.data = contractData
} }
const tx = FeeMarketEIP1559Transaction.fromTxData(rawTx, { common }) const tx = FeeMarketEIP1559Transaction.fromTxData(rawTx, { common })

View file

@ -1,3 +1,4 @@
const _ = require('lodash/fp')
const mem = require('mem') const mem = require('mem')
const configManager = require('./new-config-manager') const configManager = require('./new-config-manager')
const logger = require('./logger') const logger = require('./logger')
@ -9,6 +10,8 @@ const bitpay = require('./plugins/ticker/bitpay')
const FETCH_INTERVAL = 58000 const FETCH_INTERVAL = 58000
const PEGGED_FIAT_CURRENCIES = { NAD: 'ZAR' }
function _getRates (settings, fiatCode, cryptoCode) { function _getRates (settings, fiatCode, cryptoCode) {
return Promise.resolve() return Promise.resolve()
.then(() => { .then(() => {
@ -33,9 +36,12 @@ function _getRates (settings, fiatCode, cryptoCode) {
} }
function buildTicker (fiatCode, cryptoCode, tickerName) { function buildTicker (fiatCode, cryptoCode, tickerName) {
if (tickerName === 'bitpay') return bitpay.ticker(fiatCode, cryptoCode) const fiatPeggedEquivalent = _.includes(fiatCode, _.keys(PEGGED_FIAT_CURRENCIES))
if (tickerName === 'mock-ticker') return mockTicker.ticker(fiatCode, cryptoCode) ? PEGGED_FIAT_CURRENCIES[fiatCode]
return ccxt.ticker(fiatCode, cryptoCode, tickerName) : fiatCode
if (tickerName === 'bitpay') return bitpay.ticker(fiatPeggedEquivalent, cryptoCode)
if (tickerName === 'mock-ticker') return mockTicker.ticker(fiatPeggedEquivalent, cryptoCode)
return ccxt.ticker(fiatPeggedEquivalent, cryptoCode, tickerName)
} }
const getRates = mem(_getRates, { const getRates = mem(_getRates, {

View file

@ -34,6 +34,7 @@ const BlackListModal = ({
DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn', DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn',
ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR', ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR',
BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm', BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm',
USDT: '0x5754284f345afc66a98fbb0a0afe71e0f007b949',
XMR: XMR:
'888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H' '888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H'
} }

View file

@ -195,7 +195,7 @@ const getAdvancedWalletElementsOverrides = (
const has0Conf = R.complement( const has0Conf = R.complement(
/* NOTE: List of coins without 0conf settings. */ /* NOTE: List of coins without 0conf settings. */
R.pipe(R.prop('id'), R.flip(R.includes)(['ETH'])) R.pipe(R.prop('id'), R.flip(R.includes)(['ETH', 'USDT']))
) )
const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => { const getElements = (cryptoCurrencies, accounts, onChange, wizard = false) => {

24
package-lock.json generated
View file

@ -1431,7 +1431,7 @@
"resolved": "https://registry.npmjs.org/@celo/utils/-/utils-0.1.17.tgz", "resolved": "https://registry.npmjs.org/@celo/utils/-/utils-0.1.17.tgz",
"integrity": "sha512-XKIoGAij/FHWCzgIlZxkQR6PVWEGeE1V6rjOwDrM7WwGx9HJ3q3WBBUTibGTCz5gypMeurBbYGym/AZD/Nb78g==", "integrity": "sha512-XKIoGAij/FHWCzgIlZxkQR6PVWEGeE1V6rjOwDrM7WwGx9HJ3q3WBBUTibGTCz5gypMeurBbYGym/AZD/Nb78g==",
"requires": { "requires": {
"@umpirsky/country-list": "https://github.com/umpirsky/country-list.git#05fda51", "@umpirsky/country-list": "git://github.com/umpirsky/country-list.git#05fda51",
"bigi": "^1.1.0", "bigi": "^1.1.0",
"bignumber.js": "^9.0.0", "bignumber.js": "^9.0.0",
"bip32": "2.0.5", "bip32": "2.0.5",
@ -1455,6 +1455,10 @@
"resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.6.tgz",
"integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ==" "integrity": "sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ=="
}, },
"@umpirsky/country-list": {
"version": "git://github.com/umpirsky/country-list.git#05fda51cd97b3294e8175ffed06104c44b3c71d7",
"from": "git://github.com/umpirsky/country-list.git#05fda51"
},
"bip39": { "bip39": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz", "resolved": "https://registry.npmjs.org/bip39/-/bip39-3.0.2.tgz",
@ -4362,10 +4366,6 @@
"resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz", "resolved": "https://registry.npmjs.org/@types/zen-observable/-/zen-observable-0.8.2.tgz",
"integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg==" "integrity": "sha512-HrCIVMLjE1MOozVoD86622S7aunluLb2PJdPfb3nYiEtohm8mIB/vyv0Fd37AdeMFrTUQXEunw78YloMA3Qilg=="
}, },
"@umpirsky/country-list": {
"version": "https://github.com/umpirsky/country-list.git#05fda51cd97b3294e8175ffed06104c44b3c71d7",
"from": "https://github.com/umpirsky/country-list.git#05fda51"
},
"@ungap/global-this": { "@ungap/global-this": {
"version": "0.4.4", "version": "0.4.4",
"resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.4.tgz", "resolved": "https://registry.npmjs.org/@ungap/global-this/-/global-this-0.4.4.tgz",
@ -5457,7 +5457,14 @@
"resolved": "https://registry.npmjs.org/asn1js/-/asn1js-2.1.1.tgz", "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-2.1.1.tgz",
"integrity": "sha512-t9u0dU0rJN4ML+uxgN6VM2Z4H5jWIYm0w8LsZLzMJaQsgL3IJNbxHgmbWDvJAwspyHpDFuzUaUFh4c05UB4+6g==", "integrity": "sha512-t9u0dU0rJN4ML+uxgN6VM2Z4H5jWIYm0w8LsZLzMJaQsgL3IJNbxHgmbWDvJAwspyHpDFuzUaUFh4c05UB4+6g==",
"requires": { "requires": {
"pvutils": "^1.0.17" "pvutils": "^1.1.3"
},
"dependencies": {
"pvutils": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz",
"integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ=="
}
} }
}, },
"assert": { "assert": {
@ -17950,11 +17957,6 @@
} }
} }
}, },
"pvutils": {
"version": "1.0.17",
"resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.0.17.tgz",
"integrity": "sha512-wLHYUQxWaXVQvKnwIDWFVKDJku9XDCvyhhxoq8dc5MFdIlRenyPI9eSfEtcvgHgD7FlvCyGAlWgOzRnZD99GZQ=="
},
"q": { "q": {
"version": "2.0.3", "version": "2.0.3",
"resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz", "resolved": "https://registry.npmjs.org/q/-/q-2.0.3.tgz",

View file

@ -1,13 +1,13 @@
{ {
"files": { "files": {
"main.js": "/static/js/main.25dad505.chunk.js", "main.js": "/static/js/main.82144b16.chunk.js",
"main.js.map": "/static/js/main.25dad505.chunk.js.map", "main.js.map": "/static/js/main.82144b16.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.5b925903.js", "runtime-main.js": "/static/js/runtime-main.5b925903.js",
"runtime-main.js.map": "/static/js/runtime-main.5b925903.js.map", "runtime-main.js.map": "/static/js/runtime-main.5b925903.js.map",
"static/js/2.539ca5ff.chunk.js": "/static/js/2.539ca5ff.chunk.js", "static/js/2.b9be2e01.chunk.js": "/static/js/2.b9be2e01.chunk.js",
"static/js/2.539ca5ff.chunk.js.map": "/static/js/2.539ca5ff.chunk.js.map", "static/js/2.b9be2e01.chunk.js.map": "/static/js/2.b9be2e01.chunk.js.map",
"index.html": "/index.html", "index.html": "/index.html",
"static/js/2.539ca5ff.chunk.js.LICENSE.txt": "/static/js/2.539ca5ff.chunk.js.LICENSE.txt", "static/js/2.b9be2e01.chunk.js.LICENSE.txt": "/static/js/2.b9be2e01.chunk.js.LICENSE.txt",
"static/media/3-cassettes-open-1-left.d6d9aa73.svg": "/static/media/3-cassettes-open-1-left.d6d9aa73.svg", "static/media/3-cassettes-open-1-left.d6d9aa73.svg": "/static/media/3-cassettes-open-1-left.d6d9aa73.svg",
"static/media/3-cassettes-open-2-left.a9ee8d4c.svg": "/static/media/3-cassettes-open-2-left.a9ee8d4c.svg", "static/media/3-cassettes-open-2-left.a9ee8d4c.svg": "/static/media/3-cassettes-open-2-left.a9ee8d4c.svg",
"static/media/3-cassettes-open-3-left.08fed660.svg": "/static/media/3-cassettes-open-3-left.08fed660.svg", "static/media/3-cassettes-open-3-left.08fed660.svg": "/static/media/3-cassettes-open-3-left.08fed660.svg",
@ -153,7 +153,7 @@
}, },
"entrypoints": [ "entrypoints": [
"static/js/runtime-main.5b925903.js", "static/js/runtime-main.5b925903.js",
"static/js/2.539ca5ff.chunk.js", "static/js/2.b9be2e01.chunk.js",
"static/js/main.25dad505.chunk.js" "static/js/main.82144b16.chunk.js"
] ]
} }

View file

@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="robots" content="noindex"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Lamassu Admin</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],i=r[1],f=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var i=t[l];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this["webpackJsonplamassu-admin"]=this["webpackJsonplamassu-admin"]||[],i=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var p=i;t()}([])</script><script src="/static/js/2.539ca5ff.chunk.js"></script><script src="/static/js/main.25dad505.chunk.js"></script></body></html> <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="shortcut icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"/><meta name="robots" content="noindex"/><meta name="theme-color" content="#000000"/><link rel="manifest" href="/manifest.json"/><title>Lamassu Admin</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root" class="root"></div><script>!function(e){function r(r){for(var n,a,l=r[0],i=r[1],f=r[2],c=0,s=[];c<l.length;c++)a=l[c],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,l=1;l<t.length;l++){var i=t[l];0!==o[i]&&(n=!1)}n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={1:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,function(r){return e[r]}.bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="/";var l=this["webpackJsonplamassu-admin"]=this["webpackJsonplamassu-admin"]||[],i=l.push.bind(l);l.push=r,l=l.slice();for(var f=0;f<l.length;f++)r(l[f]);var p=i;t()}([])</script><script src="/static/js/2.b9be2e01.chunk.js"></script><script src="/static/js/main.82144b16.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long