feat: integration of erc-20 tokens

This commit is contained in:
Sérgio Salgado 2021-02-05 18:18:23 +00:00 committed by Josh Harvey
parent 0b5da0b78f
commit dfca785ed0
7 changed files with 127 additions and 29 deletions

View file

@ -17,7 +17,7 @@ const paymentPrefixPath = "m/44'/60'/0'/0'"
const defaultPrefixPath = "m/44'/60'/1'/0'"
let lastUsedNonces = {}
const contract = web3.eth.contract(erc20ABIs.usdt, coins.utils.getErc20Token('USDT').contractAddress)
// const contract = web3.eth.contract(erc20ABIs.usdt, coins.utils.getErc20Token('USDT').contractAddress)
// console.log(contract)
module.exports = {
@ -52,8 +52,8 @@ function isStrictAddress (cryptoCode, toAddress, settings, operatorId) {
}
function sendCoins (account, tx, settings, operatorId) {
const { toAddress, cryptoAtoms } = tx
return generateTx(toAddress, defaultWallet(account), cryptoAtoms, false)
const { toAddress, cryptoAtoms, cryptoCode } = tx
return generateTx(toAddress, defaultWallet(account), cryptoAtoms, false, cryptoCode)
.then(pify(web3.eth.sendRawTransaction))
.then(txid => {
return pify(web3.eth.getTransaction)(txid)
@ -68,29 +68,89 @@ function sendCoins (account, tx, settings, operatorId) {
}
function checkCryptoCode (cryptoCode) {
console.log('estou a entrar no checkCryptoCode do ETH com o valor ' + cryptoCode)
if (cryptoCode === 'ETH' || coins.utils.isErc20Token(cryptoCode)) return Promise.resolve()
if (cryptoCode === 'ETH' || coins.utils.isErc20Token(cryptoCode)) {
// console.log(cryptoCode)
return Promise.resolve(cryptoCode)
}
return Promise.reject(new Error('cryptoCode must be ETH'))
}
function balance (account, cryptoCode, settings, operatorId) {
return checkCryptoCode(cryptoCode)
.then(() => confirmedBalance(defaultAddress(account)))
.then(code => confirmedBalance(defaultAddress(account), code))
}
const pendingBalance = address => {
const promises = [_balance(true, address), _balance(false, address)]
const pendingBalance = (address, cryptoCode) => {
const promises = [_balance(true, address, cryptoCode), _balance(false, address, cryptoCode)]
return Promise.all(promises).then(([pending, confirmed]) => pending - confirmed)
}
const confirmedBalance = address => _balance(false, address)
const confirmedBalance = (address, cryptoCode) => _balance(false, address, cryptoCode)
function _balance (includePending, address) {
function _balance (includePending, address, cryptoCode) {
if (coins.utils.getCryptoCurrency(cryptoCode).type === 'erc-20') {
const contract = web3.eth.contract(erc20ABIs[cryptoCode]).at(coins.utils.getErc20Token(cryptoCode).contractAddress)
return contract.balanceOf(address.toLowerCase())
}
const block = includePending ? 'pending' : undefined
return pify(web3.eth.getBalance)(address.toLowerCase(), block)
}
function generateTx (_toAddress, wallet, amount, includesFee) {
function generateTx (toAddress, wallet, amount, includesFee, cryptoCode) {
return coins.utils.getCryptoCurrency(cryptoCode).type === 'erc-20'
? generateContractTx(toAddress, wallet, amount, includesFee, cryptoCode)
: generateCoinTx(toAddress, wallet, amount, includesFee)
}
function generateContractTx (_toAddress, wallet, amount, includesFee, cryptoCode) {
const contract = web3.eth.contract(erc20ABIs[cryptoCode]).at(coins.utils.getErc20Token(cryptoCode).contractAddress)
const fromAddress = '0x' + wallet.getAddress().toString('hex')
const toAddress = _toAddress.toLowerCase()
const txTemplate = {
from: fromAddress,
to: coins.utils.getErc20Token(cryptoCode).contractAddress,
value: amount
}
const promises = [
pify(web3.eth.estimateGas)(txTemplate),
pify(web3.eth.getGasPrice)(),
pify(web3.eth.getTransactionCount)(fromAddress)
]
return Promise.all(promises)
.then(arr => {
const gas = arr[0]
const gasPrice = arr[1]
const txCount = arr[2] <= lastUsedNonces[fromAddress]
? lastUsedNonces[fromAddress] + 1
: arr[2]
const toSend = includesFee
? amount.minus(gasPrice.times(gas))
: amount
const rawTx = {
nonce: txCount,
gasPrice: hex(gasPrice),
gasLimit: gas,
to: coins.utils.getErc20Token(cryptoCode).contractAddress,
from: fromAddress,
value: hex(BN(0)),
data: contract.transfer.getData(toAddress, hex(toSend))
}
const tx = new Tx(rawTx)
const privateKey = wallet.getPrivateKey()
tx.sign(privateKey)
return '0x' + tx.serialize().toString('hex')
})
}
function generateCoinTx (_toAddress, wallet, amount, includesFee) {
const fromAddress = '0x' + wallet.getAddress().toString('hex')
const toAddress = _toAddress.toLowerCase()
@ -150,11 +210,11 @@ function sweep (account, cryptoCode, hdIndex, settings, operatorId) {
const wallet = paymentHdNode(account).deriveChild(hdIndex).getWallet()
const fromAddress = wallet.getChecksumAddressString()
return confirmedBalance(fromAddress)
return confirmedBalance(fromAddress, cryptoCode)
.then(r => {
if (r.eq(0)) return
return generateTx(defaultAddress(account), wallet, r, true)
return generateTx(defaultAddress(account), wallet, r, true, cryptoCode)
.then(signedTx => pify(web3.eth.sendRawTransaction)(signedTx))
})
}
@ -167,11 +227,11 @@ function newAddress (account, info, tx, settings, operatorId) {
function getStatus (account, tx, requested, settings, operatorId) {
const { toAddress, cryptoCode } = tx
return checkCryptoCode(cryptoCode)
.then(() => confirmedBalance(toAddress))
.then(confirmed => {
.then(code => Promise.all([confirmedBalance(toAddress, code), code]))
.then(([confirmed, code]) => {
if (confirmed.gte(requested)) return { receivedCryptoAtoms: confirmed, status: 'confirmed' }
return pendingBalance(toAddress)
return pendingBalance(toAddress, code)
.then(pending => {
if (pending.gte(requested)) return { receivedCryptoAtoms: pending, status: 'published' }
if (pending.gt(0)) return { receivedCryptoAtoms: pending, status: 'insufficientFunds' }
@ -196,12 +256,12 @@ function defaultHdNode (account) {
function newFunding (account, cryptoCode, settings, operatorId) {
return checkCryptoCode(cryptoCode)
.then(() => {
.then(code => {
const fundingAddress = defaultAddress(account)
const promises = [
pendingBalance(fundingAddress),
confirmedBalance(fundingAddress)
pendingBalance(fundingAddress, code),
confirmedBalance(fundingAddress, code)
]
return Promise.all(promises)