Merge branch 'release-8.0' into 8.0-to-8.1-merge
This commit is contained in:
commit
e7c2456ff7
25 changed files with 149 additions and 75 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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] },
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
|
||||||
|
|
@ -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']
|
||||||
|
|
|
||||||
|
|
@ -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 })
|
||||||
|
|
|
||||||
|
|
@ -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, {
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ const BlackListModal = ({
|
||||||
DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn',
|
DASH: 'XqQ7gU8eM76rEfey726cJpT2RGKyJyBrcn',
|
||||||
ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR',
|
ZEC: 't1KGyyv24eL354C9gjveBGEe8Xz9UoPKvHR',
|
||||||
BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm',
|
BCH: 'qrd6za97wm03lfyg82w0c9vqgc727rhemg5yd9k3dm',
|
||||||
|
USDT: '0x5754284f345afc66a98fbb0a0afe71e0f007b949',
|
||||||
XMR:
|
XMR:
|
||||||
'888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H'
|
'888tNkZrPN6JsEgekjMnABU4TBzc2Dt29EPAvkRxbANsAnjyPbb3iQ1YBRk1UXcdRsiKc9dhwMVgN5S9cQUiyoogDavup3H'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
24
package-lock.json
generated
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -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
2
public/static/js/main.82144b16.chunk.js
Normal file
2
public/static/js/main.82144b16.chunk.js
Normal file
File diff suppressed because one or more lines are too long
1
public/static/js/main.82144b16.chunk.js.map
Normal file
1
public/static/js/main.82144b16.chunk.js.map
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue