Add ZEC, BCH, and LTC to BitGO wallet plugin (#240)

* Add ZEC, BCH and LTC to BitGO wallet plugin

* Convert to legacyAddress on bitgo plugin
This commit is contained in:
Rafael Taranto 2018-12-30 11:48:40 -03:00 committed by Josh Harvey
parent b254f7f2be
commit e59ec4ed28
5 changed files with 144 additions and 32 deletions

View file

@ -190,7 +190,7 @@ function fetchData () {
{code: 'litecoind', display: 'litecoind', class: 'wallet', cryptos: ['LTC']},
{code: 'dashd', display: 'dashd', class: 'wallet', cryptos: ['DASH']},
{code: 'bitcoincashd', display: 'bitcoincashd', class: 'wallet', cryptos: ['BCH']},
{code: 'bitgo', display: 'BitGo', class: 'wallet', cryptos: ['BTC']},
{code: 'bitgo', display: 'BitGo', class: 'wallet', cryptos: ['BTC', 'ZEC', 'LTC', 'BCH']},
{code: 'bitstamp', display: 'Bitstamp', class: 'exchange', cryptos: ['BTC', 'ETH', 'LTC', 'BCH']},
{code: 'itbit', display: 'itBit', class: 'exchange', cryptos: ['BTC']},
{code: 'kraken', display: 'Kraken', class: 'exchange', cryptos: ['BTC', 'ETH', 'LTC', 'DASH', 'ZEC', 'BCH']},

View file

@ -1,4 +1,5 @@
const BitGo = require('bitgo')
const { toLegacyAddress, toCashAddress } = require('bchaddrjs')
const BN = require('../../../bn')
@ -8,35 +9,50 @@ const pjson = require('../../../../package.json')
const userAgent = 'Lamassu-Server/' + pjson.version
const NAME = 'BitGo'
const SUPPORTED_COINS = ['BTC', 'ZEC', 'LTC', 'BCH']
function buildBitgo (account) {
const env = account.environment === 'test' ? 'test' : 'prod'
return new BitGo.BitGo({ accessToken: account.token, env, userAgent: userAgent })
}
function getWallet (account) {
function getWallet (account, cryptoCode) {
const bitgo = buildBitgo(account)
const coin = account.environment === 'test' ? 'tbtc' : 'btc'
const coin = account.environment === 'test' ? `t${cryptoCode.toLowerCase()}` : cryptoCode.toLowerCase()
return bitgo.coin(coin).wallets().get({ id: account.walletId })
return bitgo.coin(coin).wallets().get({ id: account[`${cryptoCode}WalletId`] })
}
function checkCryptoCode (cryptoCode) {
if (cryptoCode !== 'BTC') {
if (!SUPPORTED_COINS.includes(cryptoCode)) {
return Promise.reject(new Error('Unsupported crypto: ' + cryptoCode))
}
return Promise.resolve()
}
function getLegacyAddress (address, cryptoCode) {
const BCH_CODES = ['BCH', 'TBCH']
if (!BCH_CODES.includes(cryptoCode)) return address
return toLegacyAddress(address)
}
function getCashAddress (address, cryptoCode) {
const BCH_CODES = ['BCH', 'TBCH']
if (!BCH_CODES.includes(cryptoCode)) return address
return toCashAddress(address)
}
function sendCoins (account, address, cryptoAtoms, cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => getWallet(account))
.then(() => getWallet(account, cryptoCode))
.then(wallet => {
const params = {
address: address,
address: getLegacyAddress(address, cryptoCode),
amount: cryptoAtoms.toNumber(),
walletPassphrase: account.walletPassphrase
walletPassphrase: account[`${cryptoCode}WalletPassphrase`]
}
return wallet.send(params)
})
@ -51,13 +67,13 @@ function sendCoins (account, address, cryptoAtoms, cryptoCode) {
function balance (account, cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => getWallet(account))
.then(() => getWallet(account, cryptoCode))
.then(wallet => BN(wallet._wallet.spendableBalanceString))
}
function newAddress (account, info) {
return checkCryptoCode(info.cryptoCode)
.then(() => getWallet(account))
.then(() => getWallet(account, info.cryptoCode))
.then(wallet => {
return wallet.createAddress()
.then(result => {
@ -66,10 +82,10 @@ function newAddress (account, info) {
// If a label was provided, set the label
if (info.label) {
return wallet.updateAddress({ address: address, label: info.label })
.then(() => address)
.then(() => getCashAddress(address, info.cryptoCode))
}
return address
return getCashAddress(address, info.cryptoCode)
})
})
}
@ -77,7 +93,7 @@ function newAddress (account, info) {
function getStatus (account, toAddress, requested, cryptoCode) {
const bitgo = buildBitgo(account)
return checkCryptoCode(cryptoCode)
.then(() => bitgo.blockchain().getAddress({ address: toAddress }))
.then(() => bitgo.blockchain().getAddress({ address: getLegacyAddress(toAddress, cryptoCode) }))
.then(rec => {
if (rec.balance === 0) return { status: 'notSeen' }
if (requested.gt(rec.balance)) return { status: 'insufficientFunds' }
@ -89,7 +105,7 @@ function getStatus (account, toAddress, requested, cryptoCode) {
function newFunding (account, cryptoCode) {
return checkCryptoCode(cryptoCode)
.then(() => {
return getWallet(account)
return getWallet(account, cryptoCode)
.then(wallet => {
return wallet.createAddress()
.then(result => {
@ -98,7 +114,7 @@ function newFunding (account, cryptoCode) {
.then(() => ({
fundingPendingBalance: BN(wallet._wallet.balanceString),
fundingConfirmedBalance: BN(wallet._wallet.confirmedBalanceString),
fundingAddress
fundingAddress: getCashAddress(fundingAddress, cryptoCode)
}))
})
})

73
package-lock.json generated
View file

@ -1096,6 +1096,40 @@
}
}
},
"bchaddrjs": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/bchaddrjs/-/bchaddrjs-0.3.0.tgz",
"integrity": "sha512-XtOie1INzvGsoXKzOh/CUQ4p98Z/X+MSOV1aqFZZXG8BdZofvlXwtwcNrJDlwdfOqCVCVcFBgLBkuXEOcIQ/0w==",
"requires": {
"bs58check": "^2.1.2",
"cashaddrjs": "^0.2.9"
},
"dependencies": {
"bs58": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
"integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
"requires": {
"base-x": "^3.0.2"
}
},
"bs58check": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz",
"integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==",
"requires": {
"bs58": "^4.0.0",
"create-hash": "^1.1.0",
"safe-buffer": "^5.1.2"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
}
}
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
@ -1118,9 +1152,14 @@
"callsite": "1.0.0"
}
},
"big-integer": {
"version": "1.6.40",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.40.tgz",
"integrity": "sha512-CjhtJp0BViLzP1ZkEnoywjgtFQXS2pomKjAJtIISTCnuHILkLcAXLdFLG/nxsHc4s9kJfc+82Xpg8WNyhfACzQ=="
},
"big.js": {
"version": "3.1.3",
"resolved": "http://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz",
"integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg="
},
"bigi": {
@ -1475,7 +1514,7 @@
},
"ethereumjs-util": {
"version": "4.4.1",
"resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.4.1.tgz",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.4.1.tgz",
"integrity": "sha1-Yxa/vIoByHZ6eGIJKO1570JMP5I=",
"optional": true,
"requires": {
@ -1611,7 +1650,7 @@
},
"minimist": {
"version": "0.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
"integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784="
},
"moment": {
@ -1980,7 +2019,7 @@
},
"buffer-equals": {
"version": "1.0.4",
"resolved": "http://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz",
"resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz",
"integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U="
},
"buffer-writer": {
@ -2137,6 +2176,14 @@
}
}
},
"cashaddrjs": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/cashaddrjs/-/cashaddrjs-0.2.9.tgz",
"integrity": "sha512-DhJF4iAH0/RM3UjHDHKRxzs09YGL9px+oTyizzydanhC7jTyM2aJ+aLKA96vZGTTWayvvr2iDF2l13lpqXiRFg==",
"requires": {
"big-integer": "^1.6.34"
}
},
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
@ -3006,14 +3053,14 @@
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
"integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
}
}
},
"domelementtype": {
"version": "1.3.0",
"resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
"integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
},
"domhandler": {
@ -3623,7 +3670,7 @@
"dependencies": {
"doctrine": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
"resolved": "http://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
"integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
"dev": true,
"requires": {
@ -3884,7 +3931,7 @@
"dependencies": {
"ethereumjs-util": {
"version": "4.5.0",
"resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz",
"resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz",
"integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=",
"optional": true,
"requires": {
@ -5911,7 +5958,7 @@
},
"http-proxy": {
"version": "1.11.1",
"resolved": "http://registry.npmjs.org/http-proxy/-/http-proxy-1.11.1.tgz",
"resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.11.1.tgz",
"integrity": "sha1-cd9VdX6ALVjqgQ3yJEAZ3aBa6F0=",
"requires": {
"eventemitter3": "1.x.x",
@ -9433,7 +9480,7 @@
"dependencies": {
"babel-runtime": {
"version": "5.8.38",
"resolved": "http://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
"integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=",
"requires": {
"core-js": "^1.0.0"
@ -9446,7 +9493,7 @@
},
"core-js": {
"version": "1.2.7",
"resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
},
"elliptic": {
@ -9568,7 +9615,7 @@
},
"sanitize-html": {
"version": "1.13.0",
"resolved": "http://registry.npmjs.org/sanitize-html/-/sanitize-html-1.13.0.tgz",
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.13.0.tgz",
"integrity": "sha1-TuF8vsUWv+MvLOZoaladfmtPNjE=",
"requires": {
"htmlparser2": "^3.9.0",
@ -11195,7 +11242,7 @@
"dependencies": {
"base-x": {
"version": "1.1.0",
"resolved": "http://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz",
"resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz",
"integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w="
}
}

View file

@ -9,6 +9,7 @@
"@fczbkk/uuid4": "^3.0.0",
"axios": "^0.16.1",
"base-x": "^3.0.2",
"bchaddrjs": "^0.3.0",
"bignumber.js": "^4.1.0",
"bip39": "^2.3.1",
"bitcoind-rpc": "^0.7.0",

View file

@ -11,16 +11,64 @@
"value": ""
},
{
"code": "walletId",
"display": "Wallet ID",
"code": "BTCWalletId",
"display": "BTC Wallet ID",
"fieldType": "string",
"secret": false,
"required": true,
"value": ""
},
{
"code": "walletPassphrase",
"display": "Wallet passphrase",
"code": "BTCWalletPassphrase",
"display": "BTC Wallet passphrase",
"fieldType": "password",
"secret": true,
"required": true,
"value": ""
},
{
"code": "LTCWalletId",
"display": "LTC Wallet ID",
"fieldType": "string",
"secret": false,
"required": true,
"value": ""
},
{
"code": "LTCWalletPassphrase",
"display": "LTC Wallet passphrase",
"fieldType": "password",
"secret": true,
"required": true,
"value": ""
},
{
"code": "ZECWalletId",
"display": "ZEC Wallet ID",
"fieldType": "string",
"secret": false,
"required": true,
"value": ""
},
{
"code": "ZECWalletPassphrase",
"display": "ZEC Wallet passphrase",
"fieldType": "password",
"secret": true,
"required": true,
"value": ""
},
{
"code": "BCHWalletId",
"display": "BCH Wallet ID",
"fieldType": "string",
"secret": false,
"required": true,
"value": ""
},
{
"code": "BCHWalletPassphrase",
"display": "BCH Wallet passphrase",
"fieldType": "password",
"secret": true,
"required": true,