Skip to content

Commit c5f40b3

Browse files
author
Bernard Snowden
committed
add /v2/balance/ endpoint; fix tests
1 parent acef65e commit c5f40b3

3 files changed

Lines changed: 116 additions & 12 deletions

File tree

packages/bitcore-wallet-client/src/lib/api.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1563,27 +1563,27 @@ export class API extends EventEmitter {
15631563
}
15641564

15651565
private convertBalance(inB) {
1566-
let ret: any = {};
1566+
let ret: any = {};
15671567
const fields = [
15681568
'totalAmount',
15691569
'lockedAmount',
15701570
'totalConfirmedAmount',
15711571
'lockedConfirmedAmount',
15721572
'availableAmount',
1573-
'availableConfirmedAmount',
1573+
'availableConfirmedAmount'
15741574
];
15751575

1576-
fields.forEach(x=> {
1576+
fields.forEach(x => {
15771577
ret[x] = BigInt(inB[x] || 0);
15781578
});
15791579

15801580
ret.byAddress = inB.byAddress;
1581-
ret.byAddress.forEach(x=> {
1581+
ret.byAddress.forEach(x => {
15821582
x = BigInt(x.amount || 0);
15831583
});
15841584

15851585
return ret;
1586-
};
1586+
}
15871587

15881588
// /**
15891589
// * Update wallet balance
@@ -1593,14 +1593,15 @@ export class API extends EventEmitter {
15931593
// * @param {String} opts.multisigContractAddress optional: MULTISIG ETH Contract Address
15941594
// * @param {Callback} cb
15951595
// */
1596-
getBalance(opts, cb) {
1596+
getBalance(opts, cb, baseUrl) {
15971597
if (!cb) {
15981598
cb = opts;
15991599
opts = {};
16001600
log.warn('DEPRECATED WARN: getBalance should receive 2 parameters.');
16011601
}
16021602

16031603
opts = opts || {};
1604+
baseUrl = baseUrl || '/v2/balance/';
16041605

16051606
$.checkState(
16061607
this.credentials && this.credentials.isComplete(),
@@ -1624,9 +1625,10 @@ export class API extends EventEmitter {
16241625
qs = '?' + args.join('&');
16251626
}
16261627

1627-
var url = '/v1/balance/' + qs;
1628+
var url = baseUrl + qs;
16281629
this.request.get(url, (err, inB) => {
16291630
if (err) return cb(err);
1631+
if (opts.doNotConvertResponse) return cb(null, inB);
16301632
return cb(null, this.convertBalance(inB));
16311633
});
16321634
}

packages/bitcore-wallet-client/test/api.test.js

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var chai = require('chai');
66
chai.config.includeStack = true;
77
var sinon = require('sinon');
88
var should = chai.should();
9+
var expect = chai.expect();
910
var async = require('async');
1011
var request = require('supertest');
1112
var Uuid = require('uuid');
@@ -41,6 +42,7 @@ var ExpressApp = BWS.ExpressApp;
4142
var Storage = BWS.Storage;
4243
var TestData = require('./testdata');
4344
var Errors = require('../ts_build/lib/errors');
45+
const { assert } = require('console');
4446

4547
var helpers = {};
4648
helpers.toSatoshi = btc => {
@@ -6998,7 +7000,70 @@ describe('client API', function() {
69987000
});
69997001
});
70007002

7001-
it('should be able to recover funds from recreated wallet', function(done) {
7003+
it('should be able to recover funds from recreated wallet /v1/balance/', function(done) {
7004+
this.timeout(10000);
7005+
helpers.createAndJoinWallet(clients, keys, 2, 2, {}, () => {
7006+
clients[0].createAddress((err, addr) => {
7007+
should.not.exist(err,err);
7008+
should.exist(addr);
7009+
blockchainExplorerMock.setUtxo(addr, 1, 2);
7010+
7011+
var storage = new Storage({
7012+
db: db2
7013+
});
7014+
var newApp;
7015+
var expressApp = new ExpressApp();
7016+
expressApp.start(
7017+
{
7018+
storage: storage,
7019+
blockchainExplorer: blockchainExplorerMock,
7020+
disableLogs: true
7021+
},
7022+
() => {
7023+
newApp = expressApp.app;
7024+
7025+
var recoveryClient = helpers.newClient(newApp);
7026+
recoveryClient.fromString(clients[0].toString());
7027+
7028+
recoveryClient.getStatus({}, (err, status) => {
7029+
should.exist(err);
7030+
err.should.be.an.instanceOf(Errors.NOT_AUTHORIZED);
7031+
recoveryClient.recreateWallet(err => {
7032+
should.not.exist(err,err);
7033+
recoveryClient.getStatus({}, (err, status) => {
7034+
should.not.exist(err,err);
7035+
recoveryClient.startScan({}, err => {
7036+
should.not.exist(err,err);
7037+
var balance = 0;
7038+
async.whilst(
7039+
() => {
7040+
return balance == 0;
7041+
},
7042+
next => {
7043+
setTimeout(() => {
7044+
recoveryClient.getBalance({doNotConvertResponse: true}, (err, b) => {
7045+
balance = b.totalAmount;
7046+
next(err);
7047+
}, '/v1/balance/');
7048+
}, 200);
7049+
},
7050+
err => {
7051+
should.not.exist(err,err);
7052+
(typeof(balance) === "string").should.equal(true);
7053+
done();
7054+
}
7055+
);
7056+
});
7057+
});
7058+
});
7059+
});
7060+
}
7061+
);
7062+
});
7063+
});
7064+
});
7065+
7066+
it('should be able to recover funds from recreated wallet /v2/balance/', function(done) {
70027067
this.timeout(10000);
70037068
helpers.createAndJoinWallet(clients, keys, 2, 2, {}, () => {
70047069
clients[0].createAddress((err, addr) => {
@@ -7042,12 +7107,12 @@ describe('client API', function() {
70427107
recoveryClient.getBalance({}, (err, b) => {
70437108
balance = b.totalAmount;
70447109
next(err);
7045-
});
7110+
}, '/v2/balance/');
70467111
}, 200);
70477112
},
70487113
err => {
70497114
should.not.exist(err,err);
7050-
balance.should.equal(1e8);
7115+
(typeof(balance) === "bigint").should.equal(true);
70517116
done();
70527117
}
70537118
);

packages/bitcore-wallet-service/src/lib/expressapp.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,14 @@ const Defaults = Common.Defaults;
1818

1919
// / Patch bigint for JSON serealization
2020
// @ts-ignore-start
21-
BigInt.prototype.toJSON = function() { return this.toString(); }
21+
BigInt.prototype.toJSON = function() {
22+
return this.toString();
23+
};
2224
// @ts-ignore-end/
2325

2426
export class ExpressApp {
2527
app: express.Express;
2628

27-
2829
constructor() {
2930
this.app = express();
3031
}
@@ -738,6 +739,42 @@ export class ExpressApp {
738739
});
739740
});
740741

742+
router.get('/v2/balance/', (req, res) => {
743+
getServerWithAuth(req, res, server => {
744+
const opts: {
745+
coin?: string;
746+
twoStep?: boolean;
747+
tokenAddress?: string;
748+
multisigContractAddress?: string;
749+
} = {};
750+
if (req.query.coin) opts.coin = req.query.coin;
751+
if (req.query.twoStep == '1') opts.twoStep = true;
752+
if (req.query.tokenAddress) opts.tokenAddress = req.query.tokenAddress;
753+
if (req.query.multisigContractAddress) opts.multisigContractAddress = req.query.multisigContractAddress;
754+
755+
server.getBalance(opts, (err, balance) => {
756+
let balanceResponse = {};
757+
758+
if (err) return returnError(err, res, req);
759+
_.forEach(balance, (value, key) => {
760+
if (key == 'totalAmount') {
761+
balanceResponse[key] = balance[key].toString();
762+
}
763+
764+
if (key == 'byAddress') {
765+
balanceResponse[key] = balance[key];
766+
if (balanceResponse[key].amount) {
767+
balanceResponse[key].amount = balanceResponse[key].amount.toString();
768+
}
769+
} else {
770+
balanceResponse[key] = balance[key];
771+
}
772+
});
773+
res.json(balanceResponse);
774+
});
775+
});
776+
});
777+
741778
let estimateFeeLimiter;
742779

743780
if (Defaults.RateLimit.estimateFee && !opts.ignoreRateLimiter) {

0 commit comments

Comments
 (0)