feat: tron cash-out
This commit is contained in:
parent
bb8b6ce354
commit
7f2963bc85
15 changed files with 795 additions and 9637 deletions
|
|
@ -22,10 +22,8 @@ const PLUGINS = {
|
|||
BTC: require('./bitcoin.js'),
|
||||
BCH: require('./bitcoincash.js'),
|
||||
DASH: require('./dash.js'),
|
||||
ETH: require('./ethereum.js'),
|
||||
LTC: require('./litecoin.js'),
|
||||
XMR: require('./monero.js'),
|
||||
ZEC: require('./zcash.js')
|
||||
XMR: require('./monero.js')
|
||||
}
|
||||
|
||||
const BLOCKCHAIN_DIR = process.env.BLOCKCHAIN_DIR
|
||||
|
|
@ -145,10 +143,6 @@ function isInstalled (crypto) {
|
|||
|
||||
function isDisabled (crypto) {
|
||||
switch (crypto.cryptoCode) {
|
||||
case 'ETH':
|
||||
return 'Use admin\'s Infura plugin'
|
||||
case 'ZEC':
|
||||
return 'Use admin\'s BitGo plugin'
|
||||
case 'XMR':
|
||||
return isInstalled(crypto) && 'Installed' || isInstalled(_.find(it => it.code === 'zcash', cryptos)) && 'Insufficient resources. Contact support.'
|
||||
default:
|
||||
|
|
@ -158,11 +152,10 @@ function isDisabled (crypto) {
|
|||
|
||||
function run () {
|
||||
const choices = _.flow([
|
||||
_.filter(c => c.type !== 'erc-20'),
|
||||
_.filter(c => !c.hideFromInstall),
|
||||
_.map(c => {
|
||||
const name = c.code === 'ethereum' ? 'Ethereum and/or USDT' : c.display
|
||||
return {
|
||||
name,
|
||||
name: c.display,
|
||||
value: c.code,
|
||||
checked: isInstalled(c),
|
||||
disabled: isDisabled(c)
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ const searchPathWrapper = (t, cb) => {
|
|||
}
|
||||
|
||||
const pgp = Pgp({
|
||||
// pgNative: true,
|
||||
pgNative: true,
|
||||
schema: 'ERROR_SCHEMA',
|
||||
extend (obj, dbContext) {
|
||||
obj.__taskEx = function (cb, throwOnError = true) {
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ const staticConfig = ({ currentConfigVersion, deviceId, deviceName, pq, settings
|
|||
'cashInFee',
|
||||
'cashOutCommission',
|
||||
'cryptoCode',
|
||||
'cryptoCodeDisplay',
|
||||
'cryptoNetwork',
|
||||
'cryptoUnits',
|
||||
'display',
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const { gql } = require('apollo-server-express')
|
|||
module.exports = gql`
|
||||
type Coin {
|
||||
cryptoCode: String!
|
||||
cryptoCodeDisplay: String!
|
||||
display: String!
|
||||
minimumTx: String!
|
||||
cashInFee: String!
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ const mapLanguage = lang => {
|
|||
const massageCryptos = cryptos => {
|
||||
const convert = crypto => ({
|
||||
code: crypto['cryptoCode'],
|
||||
display: crypto['display']
|
||||
display: crypto['display'],
|
||||
codeDisplay: crypto['cryptoCodeDisplay'] ?? crypto['cryptoCode']
|
||||
})
|
||||
|
||||
return _.map(convert, cryptos)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ const typeDef = gql`
|
|||
type CryptoCurrency {
|
||||
code: String!
|
||||
display: String!
|
||||
codeDisplay: String!
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
|
|
|||
|
|
@ -214,6 +214,7 @@ function plugins (settings, deviceId) {
|
|||
|
||||
return {
|
||||
cryptoCode,
|
||||
cryptoCodeDisplay: cryptoRec.cryptoCodeDisplay ?? cryptoCode,
|
||||
display: cryptoRec.display,
|
||||
isCashInOnly: Boolean(cryptoRec.isCashinOnly),
|
||||
minimumTx: BN.max(minimumTx, cashInFee),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,18 @@
|
|||
const TronWeb = require('tronweb')
|
||||
const coins = require('@lamassu/coins')
|
||||
const { default: PQueue } = require('p-queue')
|
||||
|
||||
const BN = require('../../../bn')
|
||||
|
||||
let tronWeb = null
|
||||
|
||||
const DEFAULT_PREFIX_PATH = "m/44'/195'/1'/0"
|
||||
const DEFAULT_PREFIX_PATH = "m/44'/195'/0'/0"
|
||||
const PAYMENT_PREFIX_PATH = "m/44'/195'/1'/0"
|
||||
|
||||
const SWEEP_QUEUE = new PQueue({
|
||||
concurrency: 3,
|
||||
interval: 250,
|
||||
})
|
||||
|
||||
function checkCryptoCode (cryptoCode) {
|
||||
if (cryptoCode === 'TRX' || coins.utils.isTrc20Token(cryptoCode)) {
|
||||
|
|
@ -18,9 +25,19 @@ function defaultWallet (account) {
|
|||
const mnemonic = account.mnemonic
|
||||
if (!mnemonic) throw new Error('No mnemonic seed!')
|
||||
|
||||
const key = TronWeb.fromMnemonic(mnemonic.replace(/[\r\n]/gm, ' ').trim(), `${DEFAULT_PREFIX_PATH}\/0`)
|
||||
return TronWeb.fromMnemonic(mnemonic.replace(/[\r\n]/gm, ' ').trim(), `${DEFAULT_PREFIX_PATH}\/0`)
|
||||
}
|
||||
|
||||
return key
|
||||
function paymentWallet (account, index) {
|
||||
const mnemonic = account.mnemonic
|
||||
if (!mnemonic) throw new Error('No mnemonic seed!')
|
||||
|
||||
return TronWeb.fromMnemonic(mnemonic.replace(/[\r\n]/gm, ' ').trim(), `${PAYMENT_PREFIX_PATH}\/${index}`)
|
||||
}
|
||||
|
||||
function newAddress (account, info, tx, settings, operatorId) {
|
||||
const wallet = paymentWallet(account, info.hdIndex)
|
||||
return Promise.resolve(wallet.address)
|
||||
}
|
||||
|
||||
function defaultAddress (account) {
|
||||
|
|
@ -41,8 +58,6 @@ const _balance = async (address, cryptoCode) => {
|
|||
const contract = tronWeb.contract(abi.entrys, contractAddress)
|
||||
|
||||
const balance = await contract.methods.balanceOf(address).call()
|
||||
// const decimals = await contract.methods.decimals().call()
|
||||
// BN(balance.toString()).div(10 ** decimals).toString()
|
||||
return BN(balance.toString())
|
||||
}
|
||||
|
||||
|
|
@ -61,6 +76,7 @@ const sendCoins = async (account, tx) => {
|
|||
|
||||
try {
|
||||
response = await tronWeb.trx.sendRawTransaction(rawTx)
|
||||
if (!response.result) throw new Error(response.code)
|
||||
} catch (err) {
|
||||
// for some reason err here is just a string
|
||||
throw new Error(err)
|
||||
|
|
@ -112,6 +128,29 @@ function newFunding (account, cryptoCode) {
|
|||
})
|
||||
}
|
||||
|
||||
function sweep (account, txId, cryptoCode, hdIndex) {
|
||||
const wallet = paymentWallet(account, hdIndex)
|
||||
const fromAddress = wallet.address
|
||||
const isTrc20Token = coins.utils.isTrc20Token(cryptoCode)
|
||||
|
||||
const txFunction = isTrc20Token ? generateTrc20Tx : generateTx
|
||||
|
||||
return SWEEP_QUEUE.add(async () => {
|
||||
const r = await confirmedBalance(fromAddress, cryptoCode)
|
||||
if (r.eq(0)) return
|
||||
const signedTx = await txFunction(defaultAddress(account), wallet, r.toString(), cryptoCode)
|
||||
let response = null
|
||||
try {
|
||||
response = await tronWeb.trx.sendRawTransaction(signedTx)
|
||||
if (!response.result) throw new Error(response.code)
|
||||
} catch (err) {
|
||||
// for some reason err here is just a string
|
||||
throw new Error(err)
|
||||
}
|
||||
return response
|
||||
})
|
||||
}
|
||||
|
||||
function connect(account) {
|
||||
if (tronWeb != null) return
|
||||
const endpoint = account.endpoint
|
||||
|
|
@ -133,15 +172,19 @@ function getStatus (account, tx, requested, settings, operatorId) {
|
|||
})
|
||||
}
|
||||
|
||||
function getTxHashesByAddress (cryptoCode, address) {
|
||||
throw new Error(`Transactions hash retrieval is not implemented for this coin!`)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
balance,
|
||||
sendCoins,
|
||||
// newAddress,
|
||||
newAddress,
|
||||
getStatus,
|
||||
// sweep,
|
||||
sweep,
|
||||
defaultAddress,
|
||||
supportsHd: true,
|
||||
newFunding,
|
||||
connect,
|
||||
// getTxHashesByAddress,
|
||||
getTxHashesByAddress,
|
||||
}
|
||||
|
|
@ -4,12 +4,11 @@ const base = require('../tron/base')
|
|||
const NAME = 'trongrid'
|
||||
|
||||
function run (account) {
|
||||
if (!account.endpoint) throw new Error('Need to configure API endpoint for Infura')
|
||||
if (!account.endpoint) throw new Error('Need to configure API endpoint for trongrid')
|
||||
|
||||
const endpoint = _.startsWith('https://')(account.endpoint)
|
||||
? account.endpoint : `https://${account.endpoint}`
|
||||
const endpoint = 'https://api.trongrid.io'
|
||||
|
||||
base.connect(endpoint)
|
||||
base.connect({ ...account, endpoint })
|
||||
}
|
||||
|
||||
module.exports = _.merge(base, { NAME, run })
|
||||
|
|
|
|||
5141
new-lamassu-admin/package-lock.json
generated
5141
new-lamassu-admin/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -4,7 +4,7 @@
|
|||
"license": "unlicense",
|
||||
"dependencies": {
|
||||
"@apollo/react-hooks": "^3.1.3",
|
||||
"@lamassu/coins": "v1.3.1-trx.1",
|
||||
"@lamassu/coins": "v1.3.1-trx.3",
|
||||
"@material-ui/core": "4.11.0",
|
||||
"@material-ui/icons": "4.9.1",
|
||||
"@material-ui/lab": "^4.0.0-alpha.56",
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ const Funding = () => {
|
|||
{selected && !viewHistory && !selected.errorMsg && (
|
||||
<div className={classes.main}>
|
||||
<div className={classes.firstSide}>
|
||||
<H3>Balance ({selected.display})</H3>
|
||||
<H3>Balance</H3>
|
||||
<div className={classes.coinTotal}>
|
||||
<Info1 inline noMargin>
|
||||
{`${selected.confirmedBalance} ${selected.cryptoCode}`}
|
||||
|
|
|
|||
|
|
@ -9,16 +9,10 @@ export default {
|
|||
elements: [
|
||||
{
|
||||
code: 'apiKey',
|
||||
display: 'Project ID',
|
||||
display: 'API Key',
|
||||
component: TextInputFormik,
|
||||
face: true,
|
||||
long: true
|
||||
},
|
||||
{
|
||||
code: 'endpoint',
|
||||
display: 'Endpoint',
|
||||
component: TextInputFormik,
|
||||
face: true
|
||||
}
|
||||
],
|
||||
getValidationSchema: account => {
|
||||
|
|
|
|||
5187
package-lock.json
generated
5187
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -9,7 +9,7 @@
|
|||
"@ethereumjs/common": "^2.6.4",
|
||||
"@ethereumjs/tx": "^3.5.1",
|
||||
"@graphql-tools/merge": "^6.2.5",
|
||||
"@lamassu/coins": "v1.3.1-trx.1",
|
||||
"@lamassu/coins": "v1.3.1-trx.3",
|
||||
"@simplewebauthn/server": "^3.0.0",
|
||||
"@vonage/auth": "^1.5.0",
|
||||
"@vonage/sms": "^1.7.0",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue