From 5a61a2e34a6774fc31cb2b029628400f309d2011 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Sun, 12 Nov 2017 05:05:39 -0300 Subject: [PATCH 1/5] translate address for inputs and outputs --- lib/addresses.js | 39 ++--- lib/addresstranslator.js | 56 +++++++ lib/common.js | 44 ++++++ lib/index.js | 6 +- lib/transactions.js | 16 +- package-lock.json | 60 +++++++ package.json | 1 + test/addressesCash.js | 306 ++++++++++++++++++++++++++++++++++++ test/addressestranslator.js | 53 +++++++ 9 files changed, 550 insertions(+), 31 deletions(-) create mode 100644 lib/addresstranslator.js create mode 100644 test/addressesCash.js create mode 100644 test/addressestranslator.js diff --git a/lib/addresses.js b/lib/addresses.js index 854a718..6bc3d4f 100644 --- a/lib/addresses.js +++ b/lib/addresses.js @@ -8,12 +8,12 @@ var Common = require('./common'); var _ = require('lodash'); var LRU = require('lru-cache'); -function AddressController(node) { +function AddressController(node, translateAddresses) { this.node = node; this._address = this.node.services.address; this._block = this.node.services.block; - this.txController = new TxController(node); - this.common = new Common({log: this.node.log}); + this.txController = new TxController(node, translateAddresses); + this.common = new Common({log: this.node.log, translateAddresses: translateAddresses}); this._block = this.node.services.block; this._utxoCache = new LRU({ max: 250, @@ -73,6 +73,7 @@ AddressController.prototype.addressSummarySubQuery = function(req, res, param) { }; AddressController.prototype.getAddressSummary = function(address, options, callback) { + var self = this; this._address.getAddressSummary(address, options, function(err, summary) { if(err) { @@ -80,7 +81,7 @@ AddressController.prototype.getAddressSummary = function(address, options, callb } var transformed = { - addrStr: address, + address: self.common.translateOutputAddress(address), balance: Unit.fromSatoshis(summary.balance).toBTC(), balanceSat: summary.balance, totalReceived: Unit.fromSatoshis(summary.totalReceived).toBTC(), @@ -99,6 +100,7 @@ AddressController.prototype.getAddressSummary = function(address, options, callb }; AddressController.prototype.checkAddrs = function(req, res, next) { + var self = this; function makeArray(addrs) { if (_.isString(addrs)) { @@ -123,29 +125,18 @@ AddressController.prototype.checkAddrs = function(req, res, next) { }, res); } - var inValid = this.check(req.addrs); - - if (inValid) { + try { + req.addrs = self.common.translateInputAddresses(req.addrs); + req.addr = req.addrs[0]; + } catch(e) { +console.log('[addresses.js.130]', e); //TODO return this.common.handleErrors({ - message: 'Invalid address: ' + inValid.message, + message: 'Invalid address: ' + e, code: 1 }, res); - } + }; next(); - -}; - -AddressController.prototype.check = function(addresses) { - - for(var i = 0; i < addresses.length; i++) { - try { - new bitcore.Address(addresses[i]); - } catch(e) { - return addresses[i]; - } - } - }; AddressController.prototype.utxo = function(req, res) { @@ -170,9 +161,11 @@ AddressController.prototype.utxo = function(req, res) { }); }; + AddressController.prototype.transformUtxo = function(utxoArg) { + var utxo = { - address: utxoArg.address, + address: this.common.translateOutputAddress(utxoArg.address), txid: utxoArg.txid, vout: utxoArg.vout, scriptPubKey: utxoArg.scriptPubKey, diff --git a/lib/addresstranslator.js b/lib/addresstranslator.js new file mode 100644 index 0000000..db6e4a9 --- /dev/null +++ b/lib/addresstranslator.js @@ -0,0 +1,56 @@ +var Bitcore_ = { + btc: require('bitcore-lib'), + bch: require('bitcore-lib-cash') +}; + +var _ = require('lodash'); + +function AddressTranslator() { +}; + + +AddressTranslator.getAddressCoin = function(address) { + try { + new Bitcore_['btc'].Address(address); + return 'btc'; + } catch (e) { + try { + new Bitcore_['bch'].Address(address); + return 'bch'; + } catch (e) { + return; + } + } +}; + +AddressTranslator.translate = function(addresses, coin, origCoin) { + var wasArray = true; + if (!_.isArray(addresses)) { + wasArray = false; + addresses = [addresses]; + } + origCoin = origCoin || AddressTranslator.getAddressCoin(addresses[0]); + var ret = _.map(addresses, function(x) { + var orig = new Bitcore_[origCoin].Address(x).toObject(); + return Bitcore_[coin].Address.fromObject(orig).toString(); + }); + + if (wasArray) + return ret; + else + return ret[0]; + +}; + +AddressTranslator.translateInput = function(addresses) { + return this.translate(addresses, 'btc', 'bch'); +} + +AddressTranslator.translateOutput = function(addresses) { + return this.translate(addresses, 'bch', 'btc'); +} + + + + +module.exports = AddressTranslator; diff --git a/lib/common.js b/lib/common.js index ea90111..cfe8feb 100644 --- a/lib/common.js +++ b/lib/common.js @@ -1,7 +1,12 @@ 'use strict'; +var _ = require('lodash'); +var AddressTranslator = require('./addresstranslator'); +var bitcore = require('bitcore-lib'); + function Common(options) { this.log = options.log; + this.translateAddresses = options.translateAddresses; } Common.prototype.notReady = function (err, res, p) { @@ -21,4 +26,43 @@ Common.prototype.handleErrors = function (err, res) { } }; + +Common.prototype.translateInputAddresses= function(addresses) { + var self = this; + + if (!addresses) return; + + if (!_.isArray(addresses)) + addresses = [ addresses ]; + + function check(addresses) { + if (!addresses) return; + + for(var i = 0; i < addresses.length; i++) { + try { + new bitcore.Address(addresses[i]); + } catch(e) { + + throw addresses[i]; + } + } + } + + if (this.translateAddresses) { + addresses = AddressTranslator.translateInput(addresses); + } else + check(addresses); + + return addresses; +}; + + + + +Common.prototype.translateOutputAddress= function(address) { + if (!this.translateAddresses) return address; + return AddressTranslator.translateOutput(address); +}; + + module.exports = Common; diff --git a/lib/index.js b/lib/index.js index 41a09c7..c6519cf 100644 --- a/lib/index.js +++ b/lib/index.js @@ -27,6 +27,7 @@ var EventEmitter = require('events').EventEmitter; * @param {Number} options.cacheShortSeconds - The time to cache short lived cache responses. * @param {Number} options.cacheLongSeconds - The time to cache long lived cache responses. * @param {String} options.routePrefix - The URL route prefix + * @param {String} options.translateAddresses - Translate request and output address to Copay's BCH address version (see https://support.bitpay.com/hc/en-us/articles/115004671663-BitPay-s-Adopted-Conventions-for-Bitcoin-Cash-Addresses-URIs-and-Payment-Requests) */ var InsightAPI = function(options) { BaseService.call(this, options); @@ -47,6 +48,7 @@ var InsightAPI = function(options) { this.rateLimiterOptions = options.rateLimiterOptions; this.disableRateLimiter = options.disableRateLimiter; + this.translateAddresses = options.translateAddresses; this.blockSummaryCacheSize = options.blockSummaryCacheSize || BlockController.DEFAULT_BLOCKSUMMARY_CACHE_SIZE; this.blockCacheSize = options.blockCacheSize || BlockController.DEFAULT_BLOCK_CACHE_SIZE; @@ -201,7 +203,7 @@ InsightAPI.prototype.setupRoutes = function(app) { app.param('height', blocks.blockIndex.bind(blocks)); // Transaction routes - var transactions = new TxController(this.node); + var transactions = new TxController(this.node, this.translateAddresses); app.get('/tx/:txid', this.cacheShort(), transactions.show.bind(transactions)); app.param('txid', transactions.transaction.bind(transactions)); app.get('/txs', this.cacheShort(), transactions.list.bind(transactions)); @@ -212,7 +214,7 @@ InsightAPI.prototype.setupRoutes = function(app) { app.param('txid', transactions.rawTransaction.bind(transactions)); // Address routes - var addresses = new AddressController(this.node); + var addresses = new AddressController(this.node, this.translateAddresses); app.get('/addr/:addr', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.show.bind(addresses)); app.get('/addr/:addr/utxo', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.utxo.bind(addresses)); app.get('/addrs/:addrs/utxo', this.cacheShort(), addresses.checkAddrs.bind(addresses), addresses.multiutxo.bind(addresses)); diff --git a/lib/transactions.js b/lib/transactions.js index 4484d94..42b2e14 100644 --- a/lib/transactions.js +++ b/lib/transactions.js @@ -8,9 +8,9 @@ var async = require('async'); var MAXINT = 0xffffffff; // Math.pow(2, 32) - 1; -function TxController(node) { +function TxController(node, translateAddresses) { this.node = node; - this.common = new Common({log: this.node.log}); + this.common = new Common({log: this.node.log, translateAddresses: translateAddresses}); this._block = this.node.services.block; this._transaction = this.node.services.transaction; this._address = this.node.services.address; @@ -134,7 +134,8 @@ TxController.prototype.transformInput = function(options, input, index) { var address = input.getAddress(); if (address) { address.network = this._network; - transformed.addr = address.toString(); + transformed.addr = this.common.translateOutputAddress(address.toString()); + } else { transformed.addr = null; } @@ -170,13 +171,16 @@ TxController.prototype.transformOutput = function(options, output, index) { var address = output.getAddress(); if (address) { address.network = this._network; - transformed.scriptPubKey.addresses = [address.toString()]; + transformed.scriptPubKey.addresses = [this.common.translateOutputAddress(address.toString())]; + transformed.scriptPubKey.type = address.getType(); } return transformed; }; TxController.prototype.transformInvTransaction = function(transaction) { + var self = this; + var valueOut = 0; var vout = []; for (var i = 0; i < transaction.outputs.length; i++) { @@ -190,7 +194,7 @@ TxController.prototype.transformInvTransaction = function(transaction) { } address.network = this._network; - address = address.toString(); + address = self.common.translateOutputAddress(address.toString()); var obj = {}; obj[address] = output.value; @@ -244,7 +248,7 @@ TxController.prototype.list = function(req, res) { var self = this; var blockHash = req.query.block; - var address = req.query.address; + var address = this.common.translateInputAddresses(req.query.address); var page = parseInt(req.query.pageNum) || 0; var pageLength = 10; var pagesTotal = 1; diff --git a/package-lock.json b/package-lock.json index 77681c0..1bd9fa1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -80,6 +80,14 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, + "base-x": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.2.tgz", + "integrity": "sha1-v4c4YbdRQnm3lp80CSnquHwR0TA=", + "requires": { + "safe-buffer": "5.1.1" + } + }, "base64-arraybuffer": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", @@ -184,6 +192,58 @@ } } }, + "bitcore-lib-cash": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/bitcore-lib-cash/-/bitcore-lib-cash-0.15.1.tgz", + "integrity": "sha512-2fftReEqbkohCwiblBGteEX5S7lc6oTGM1QyDr6rz88QA7xLqhtVkT9hWrwirZfw6H4IfApS2gAAtHGExCqMsw==", + "requires": { + "bn.js": "4.11.8", + "bs58": "4.0.1", + "buffer-compare": "1.1.1", + "elliptic": "6.4.0", + "inherits": "2.0.1", + "lodash": "4.17.4" + }, + "dependencies": { + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, + "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" + } + }, + "buffer-compare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-compare/-/buffer-compare-1.1.1.tgz", + "integrity": "sha1-W+e+hTr4kZjR9N3AkNHWakiu9ZY=" + }, + "elliptic": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", + "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", + "requires": { + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.1", + "minimalistic-assert": "1.0.0", + "minimalistic-crypto-utils": "1.0.1" + } + }, + "lodash": { + "version": "4.17.4", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", + "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" + } + } + }, "bitcore-message": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bitcore-message/-/bitcore-message-1.0.2.tgz", diff --git a/package.json b/package.json index 9fad72d..dc03344 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "async": "*", "bcoin": "bcoin-org/bcoin#886008a1822ce1da7fa8395ee7db4bcc1750a28a", "bitcore-lib": "5.0.0-beta.1", + "bitcore-lib-cash": "0.15.1", "bitcore-message": "^1.0.1", "body-parser": "^1.13.3", "compression": "^1.6.1", diff --git a/test/addressesCash.js b/test/addressesCash.js new file mode 100644 index 0000000..3c8f42a --- /dev/null +++ b/test/addressesCash.js @@ -0,0 +1,306 @@ +'use strict'; + +var should = require('should'); +var sinon = require('sinon'); +var AddressController = require('../lib/addresses'); +var _ = require('lodash'); +var bitcore = require('bitcore-lib'); +var bcoin = require('bcoin'); + + + +var rawHex = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d010bffffffff0100f2052a010000004341047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac00000000"; + +var bcoinTx = bcoin.tx.fromRaw(rawHex, 'hex'); +bcoinTx.__blockhash = '0000000000000041ddc94ecf4f86a456a83b2e320c36c6f0c13ff92c7e75f013'; +bcoinTx.blockhash = '0000000000000041ddc94ecf4f86a456a83b2e320c36c6f0c13ff92c7e75f013'; +bcoinTx.__height = 534181; +bcoinTx.__timestamp = 1441116143; +bcoinTx.outputSatoshis = 53829829; + +var txinfos2 = { + totalCount: 1, + items: [ bcoinTx ] +}; + +var utxos = [ + { + 'address': '1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', + 'txid': '63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73', + 'vout': 1, + 'timestamp': 1441116143, + 'satoshis': 53320000, + 'scriptPubKey': '76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac', + 'height': 534181, + 'confirmations': 50 + }, + { + 'address': '3EDL9HSincwLGfYbWPQ7LXtc4VqdwGoraS', + 'txid': '63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73', + 'vout': 2, + 'timestamp': 1441116143, + 'satoshis': 289829, + 'scriptPubKey': '76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac', + 'height': 534181, + 'confirmations': 50 + } +]; + +describe('Addresses / Bitcoin Cash', function() { + var summary = { + addrStr: 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', + balance: 0, + totalReceivedSat: 2782729129, + totalSentSat: 2782729129, + unconfirmedBalance: 0, + appearances: 2, + unconfirmedAppearances: 0, + txids: [ + 'bb0ec3b96209fac9529570ea6f83a86af2cceedde4aaf2bfcc4796680d23f1c7', + '01f700df84c466f2a389440e5eeacdc47d04f380c39e5d19dce2ce91a11ecba3' + ] + }; + describe('/addr/:addr', function() { + var node = { + + services: { + address: { + getAddressSummary: sinon.stub().callsArgWith(2, null, summary) + } + } + + }; + + var addresses = new AddressController(node, true); + var req = { + addr: '', + query: {} + }; + it('checkAddrs', function(done) { + var insight = 0; + + var req = { + query: { + noTxList: 1 + }, + params: { + addr: 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz' + }, + }; + + var send = sinon.stub(); + var status = sinon.stub().returns({send: send}); + + var res = { + status: status + }; + + addresses.checkAddrs(req, res, function(req2) { + req.addr.should.equal('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA'); + req.addrs[0].should.equal('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA'); + done(); + }); + }); + }); + + + describe('/addr/:addr/utxo', function() { + it('should have correct data', function(done) { + var insight = [ + { + 'address': 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', + 'txid': '63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73', + 'vout': 1, + 'ts': 1441116143, + 'scriptPubKey': '76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac', + 'amount': 0.5332, + 'confirmations': 50, + 'height': 534181, + 'satoshis': 53320000, + 'confirmationsFromCache': true + } + ]; + + var todos = [ + { + confirmationsFromCache: true + } + ]; + + var node = { + services: { + block: { + getTip: sinon.stub().returns({ height: 534230 }) + }, + address: { + getAddressUnspentOutputs: sinon.stub().callsArgWith(2, null, utxos.slice(0, 1)) + } + }, + + }; + + var addresses = new AddressController(node, true); + + var req = { + addr: 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz' + }; + + var res = { + jsonp: function(data) { + var merged = _.merge(data, todos); + should(merged).eql(insight); + done(); + } + }; + + addresses.utxo(req, res); + }); + }); + + describe('/addrs/:addrs/utxo', function() { + + it('should have the correct data', function(done) { + + var insight = [ + { + 'address': 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', + 'txid': '63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73', + 'vout': 1, + 'ts': 1441116143, + 'scriptPubKey': '76a914d2ec20bb8e5f25a52f730384b803d95683250e0b88ac', + 'amount': 0.5332, + 'height': 534181, + 'satoshis': 53320000, + 'confirmations': 50 + }, + { + 'address': 'HK3Sc5sodw9ztqRdN54GJvR969rejftcS9', + 'txid': '63b68becb0e514b32317f4b29a5cf0627d4087e54ac17f686fcb1d9a27680f73', + 'vout': 2, + 'ts': 1441116143, + 'scriptPubKey': '76a914583df9fa56ad961051e00ca93e68dfaf1eab9ec588ac', + 'amount': 0.00289829, + 'height': 534181, + 'satoshis': 289829, + 'confirmations': 50 + } + ]; + + var utxoStub = sinon.stub(); + utxoStub.onCall(0).callsArgWith(2, null, [utxos[0]]); + utxoStub.onCall(1).callsArgWith(2, null, [utxos[1]]); + + var node = { + services: { + address: { + getAddressUnspentOutputs: utxoStub + }, + block: { + getTip: sinon.stub().returns({ height: 534230 }) + } + }, + + }; + + var addresses = new AddressController(node, true); + + var req = { + addrs: 'mzkD4nmQ8ixqxySdBgsXTpgvAMK5iRZpNK,moZY18rGNmh4YCPeugtGW46AkkWMQttBUD' + }; + + var finalData = ''; + + var res = { + write: function(data) { + finalData += data; + }, + end: function() { + var finalObject = JSON.parse(finalData); + finalObject.should.eql(insight); + done(); + } + }; + + addresses.multiutxo(req, res); + }); + }); + + describe('/addrs/:addrs/txs', function() { + + it('should have correct data', function(done) { + + var insight = { + 'totalItems': 1, + 'from': 0, + 'to': 1, + 'items': [ + { + 'txid': '9b0fc92260312ce44e74ef369f5c66bbb85848f2eddd5a7a1cde251e54ccfdd5', + 'version': 1, + 'isCoinBase': true, + 'locktime': 0, + 'vin': [ + { + 'coinbase': '04ffff001d010b', + 'sequence': 4294967295, + 'n': 0 + } + ], + 'vout': [ + { + 'value': '50.00000000', + 'n': 0, + 'scriptPubKey': { + 'asm': '047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77 OP_CHECKSIG', + 'hex': '41047211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073dee6c89064984f03385237d92167c13e236446b417ab79a0fcae412ae3316b77ac', + 'type': 'pubkeyhash', + 'addresses': [ + 'CYognBa8KGDnHMcyM7siKgxRkCkUqLb4YM' + ] + }, + spentHeight: null, + spentIndex: null, + spentTxId: null + } + ], + 'blockhash': '0000000000000041ddc94ecf4f86a456a83b2e320c36c6f0c13ff92c7e75f013', + 'blockheight': 534181, + 'confirmations': 52, + 'time': 1441116143, + 'blocktime': 1441116143, + 'valueOut': 0.53829829, + 'size': 134 + } + ] + }; + + var node = { + services: { + address: { + getAddressHistory: sinon.stub().callsArgWith(2, null, txinfos2), + }, + block: { + getTip: sinon.stub().returns({ height: 534232 }) + } + } + }; + + var addresses = new AddressController(node, true); + + var req = { + addrs: 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz,HK3Sc5sodw9ztqRdN54GJvR969rejftcS9', + query: {}, + body: {} + }; + + var res = { + jsonp: function(data) { + should(data).eql(insight); + done(); + } + }; + + addresses.multitxs(req, res); + }); + }); +}); diff --git a/test/addressestranslator.js b/test/addressestranslator.js new file mode 100644 index 0000000..924ad0d --- /dev/null +++ b/test/addressestranslator.js @@ -0,0 +1,53 @@ + +var _ = require('lodash'); +var chai = require('chai'); +var sinon = require('sinon'); +var assert = require('assert'); +var should = chai.should; + +var AddressTranslator = require('../lib/addresstranslator'); + +describe('#AddressTranslator', function() { + it('should translate address from btc to bch', function() { + var res = AddressTranslator.translate('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', 'bch'); + assert( res == 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz'); + }); + it('should translate address from bch to btc', function() { + var res = AddressTranslator.translateInput('HBf8isgS8EXG1r3X6GP89FmooUmiJ42wHS'); + assert(res=='36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r'); + }); + + it('should keep the address if there is nothing to do (bch)', function() { + var res = AddressTranslator.translate('CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz', 'bch'); + assert(res=='CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz'); + }); + it('should keep the address if there is nothing to do (btc)', function() { + var res = AddressTranslator.translate('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', 'btc'); + assert(res=='1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA'); + }); + it('should support 3 params NOK', function() { + + var a; + try { + var res = AddressTranslator.translate('1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', 'btc', 'bch'); + } catch (e) { + a=e.toString(); + assert(a.match(/Address has mismatched network type/)); + }; + }); + it('should support 3 params OK', function() { + var res = AddressTranslator.translate('HBf8isgS8EXG1r3X6GP89FmooUmiJ42wHS', 'btc', 'bch'); + assert(res=='36q2G5FMGvJbPgAVEaiyAsFGmpkhPKwk2r'); + }); + + it('should work with arrays also', function() { + var res = AddressTranslator.translateOutput(['1LqBGSKuX5yYUonjxT5qGfpUsXKYYWeabA', '37YHiaQnMjy73GS1UpiE8p2Ju6MyrrDw3J', '1DuPdCpGzVX73kBYaAbu5XDNDgE2Lza5Ed']); + assert(res[0] == 'CcJ4qUfyQ8x5NwhAeCQkrBSWVeXxXghcNz'); + assert(res[1] == 'HCNQBNqsD4BmfSK3LWNP7CYqvkNznSrXS3'); + assert(res[2] == 'CVNHCFALsYVdwt5yFuvpf2qPqoSSGtvY7t'); + }); + + +}); + + From d3267f47ef84a9d3f31f3e5929d8037c825c7f75 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 13 Nov 2017 00:10:07 -0300 Subject: [PATCH 2/5] update readme --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 49dd414..4d5208c 100644 --- a/README.md +++ b/README.md @@ -7,18 +7,18 @@ This is a backend-only service. If you're looking for the web frontend applicati ## Getting Started ```bashl -npm install -g bitcore-node@latest -bitcore-node create mynode +npm install -g bitcore@latest +bitcore create mynode cd mynode -bitcore-node install insight-api -bitcore-node start +bitcore install insight-api +bitcore start ``` The API endpoints will be available by default at: `http://localhost:3001/insight-api/` ## Prerequisites -- [Bitcore Node 3.x](https://github.com/bitpay/bitcore-node) +- [Bitcore 5.x](https://github.com/bitpay/bitcore) **Note:** You can use an existing Bitcoin data directory, however `txindex`, `addressindex`, `timestampindex` and `spentindex` needs to be set to true in `bitcoin.conf`, as well as a few other additional fields. From ef451f8342595b83d1d0a14210249dcd245b7ec7 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 13 Nov 2017 01:10:28 -0300 Subject: [PATCH 3/5] fix utxo cache --- lib/addresses.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/addresses.js b/lib/addresses.js index 6bc3d4f..8a9c02c 100644 --- a/lib/addresses.js +++ b/lib/addresses.js @@ -244,8 +244,9 @@ AddressController.prototype.multiutxo = function(req, res) { if (utxos.length - 1 === i) { sep = ''; } + utxos[i] = self.transformUtxo(utxos[i]); cache.push(utxos[i]); - res.write(JSON.stringify(self.transformUtxo(utxos[i])) + sep); + res.write(JSON.stringify(utxos[i]) + sep); } sep = ','; From 136755fcda4b51b06ba9ae82684a5ffaeabe6506 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 13 Nov 2017 01:21:02 -0300 Subject: [PATCH 4/5] fix /addr/<1xxx> translation --- lib/addresses.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/addresses.js b/lib/addresses.js index 8a9c02c..ef37d0d 100644 --- a/lib/addresses.js +++ b/lib/addresses.js @@ -38,6 +38,9 @@ AddressController.prototype.show = function(req, res) { this._address.getAddressSummary(req.addr, options, function(err, data) { + if (data.addrStr) + data.addrStr = self.common.translateOutputAddress(data.addrStr); + if(err) { return self.common.handleErrors(err, res); } From 72827b12a6eea599c82cd459d85214b65bce270a Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 13 Nov 2017 11:32:07 -0300 Subject: [PATCH 5/5] fix data. handling --- lib/addresses.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/addresses.js b/lib/addresses.js index ef37d0d..4c1f58d 100644 --- a/lib/addresses.js +++ b/lib/addresses.js @@ -37,13 +37,14 @@ AddressController.prototype.show = function(req, res) { } this._address.getAddressSummary(req.addr, options, function(err, data) { - - if (data.addrStr) - data.addrStr = self.common.translateOutputAddress(data.addrStr); - if(err) { return self.common.handleErrors(err, res); } + + if (data && data.addrStr) + data.addrStr = self.common.translateOutputAddress(data.addrStr); + + res.jsonp(data); }); };