move parseAmount to CLI only

This commit is contained in:
Ivan Socolsky 2015-02-19 21:37:13 -03:00
parent 345938824f
commit 675369eed0
7 changed files with 119 additions and 108 deletions

View File

@ -17,7 +17,12 @@ if (!args[0] || !args[1] || !args[2])
program.help();
var address = args[0];
var amount = args[1];
var amount;
try {
amount = utils.parseAmount(args[1]);
} catch (ex) {
utils.die(ex);
}
var message = args[2];
var client = utils.getClient(program);

View File

@ -1,4 +1,3 @@
var _ = require('lodash');
var Client = require('../lib/client');
@ -12,14 +11,14 @@ var die = Utils.die = function(err) {
};
Utils.parseMN = function(MN) {
if (!MN)
if (!MN)
die('No m-n parameter');
var mn = MN.split('-');
var m = parseInt(mn[0]);
var m = parseInt(mn[0]);
var n = parseInt(mn[1]);
if (!m || ! n) {
if (!m || !n) {
die('Bad m-n parameter:' + MN);
}
@ -62,6 +61,33 @@ Utils.findOneTxProposal = function(txps, id) {
return matches[0];
};
Utils.UNITS = {
'btc': 100000000,
'bit': 100,
'sat': 1,
};
Utils.parseAmount = function(text) {
if (!_.isString(text))
text = text.toString();
var regex = '^(\\d*(\\.\\d{0,8})?)\\s*(' + _.keys(Utils.UNITS).join('|') + ')?$';
var match = new RegExp(regex, 'i').exec(text.trim());
if (!match || match.length === 0) throw new Error('Invalid amount');
var amount = parseFloat(match[1]);
if (!_.isNumber(amount) || _.isNaN(amount)) throw new Error('Invalid amount');
var unit = (match[3] || 'sat').toLowerCase();
var rate = Utils.UNITS[unit];
if (!rate) throw new Error('Invalid unit')
var amountSat = parseFloat((amount * rate).toPrecision(12));
if (amountSat != Math.round(amountSat)) throw new Error('Invalid amount');
return amountSat;
};
module.exports = Utils;

67
bit-wallet/tests.js Normal file
View File

@ -0,0 +1,67 @@
'use strict';
var _ = require('lodash');
var chai = require('chai');
var sinon = require('sinon');
var should = chai.should();
var CliUtils = require('./cli-utils');
describe('CliUtils', function() {
describe('#parseAmount', function() {
it('should successfully parse amounts', function() {
var texts = {
'1': 1,
'0': 0,
'1.': 1,
'000000.0000': 0,
'123': 123,
'123sat': 123,
'123 sat': 123,
'00123 sat': 123,
'1.23bit': 123,
'1.23 bit': 123,
'0 bit': 0,
'.45bit': 45,
'1btc': 100000000,
' 1btc': 100000000,
'9999btc': 999900000000,
'0.00000001btc': 1,
'00000.00000001BTC': 1,
'0.00000001 BTC': 1,
'0.123btc': 12300000,
'0.123 bTc': 12300000,
};
_.each(texts, function(satoshi, text) {
var amount = CliUtils.parseAmount(text);
amount.should.equal(satoshi);
});
});
it('should fail to parse incorrect amounts', function() {
var texts = [
'',
' ',
'btc',
'1satoshi',
'no-number',
'-3',
'1 b t c',
'btc1',
'btc 1',
'1,234',
'0.000000001btc',
'0.1sat',
'0.123bit',
'2.000000009btc',
];
_.each(texts, function(text) {
var valid = true;
try {
var amount = CliUtils.parseAmount(text);
} catch (e) {
valid = false;
}
valid.should.be.false;
});
});
});
});

View File

@ -44,7 +44,10 @@ function _parseError(body) {
var code = body.code || 'ERROR';
var message = body.error || 'There was an unknown error processing the request';
log.error(code, message);
return {message: message, code: code};
return {
message: message,
code: code
};
};
function _signRequest(method, url, args, privKey) {
@ -61,7 +64,7 @@ function API(opts) {
this.verbose = !!opts.verbose;
this.request = request || opts.request;
this.baseUrl = opts.baseUrl || BASE_URL;
this.basePath = this.baseUrl.replace(/http.?:\/\/[a-zA-Z0-9:-]*\//,'/');
this.basePath = this.baseUrl.replace(/http.?:\/\/[a-zA-Z0-9:-]*\//, '/');
if (this.verbose) {
log.level = 'debug';
} else {
@ -321,21 +324,17 @@ API.prototype.getStatus = function(cb) {
* @param opts.message
*/
API.prototype.sendTxProposal = function(opts, cb) {
$.checkArgument(opts);
$.shouldBeNumber(opts.amount);
var self = this;
this._loadAndCheck(function(err, data) {
if (err) return cb(err);
var amount;
try {
amount = WalletUtils.parseAmount(opts.amount);
} catch (ex) {
return cb(ex);
}
var args = {
toAddress: opts.toAddress,
amount: amount,
amount: opts.amount,
message: _encryptProposalMessage(opts.message, data.sharedEncryptingKey),
};
var hash = WalletUtils.getProposalHash(args.toAddress, args.amount, args.message);
@ -450,9 +449,10 @@ API.prototype.getTxProposals = function(opts, cb) {
};
API.prototype.signTxProposal = function(txp, cb) {
var self = this;
$.checkArgument(txp.creatorId);
var self = this;
this._loadAndCheck(function(err, data) {
if (err) return cb(err);
@ -499,9 +499,10 @@ API.prototype.signTxProposal = function(txp, cb) {
};
API.prototype.rejectTxProposal = function(txp, reason, cb) {
var self = this;
$.checkArgument(cb);
var self = this;
this._loadAndCheck(
function(err, data) {
if (err) return cb(err);

View File

@ -105,33 +105,4 @@ WalletUtils.decryptMessage = function(cyphertextJson, encryptingKey) {
return sjcl.decrypt(key, cyphertextJson);
};
WalletUtils.UNITS = {
'btc': 100000000,
'bit': 100,
'sat': 1,
};
WalletUtils.parseAmount = function(text) {
if (!_.isString(text))
text = text.toString();
var regex = '^(\\d*(\\.\\d{0,8})?)\\s*(' + _.keys(WalletUtils.UNITS).join('|') + ')?$';
var match = new RegExp(regex, 'i').exec(text.trim());
if (!match || match.length === 0) throw new Error('Invalid amount');
var amount = parseFloat(match[1]);
if (!_.isNumber(amount) || _.isNaN(amount)) throw new Error('Invalid amount');
var unit = (match[3] || 'sat').toLowerCase();
var rate = WalletUtils.UNITS[unit];
if (!rate) throw new Error('Invalid unit')
var amountSat = Utils.strip(amount * rate);
if (amountSat != Math.round(amountSat)) throw new Error('Invalid amount');
return amountSat;
};
module.exports = WalletUtils;

View File

@ -370,7 +370,7 @@ describe('client API ', function() {
should.exist(x0.address);
blockExplorerMock.setUtxo(x0, 1, 1);
var opts = {
amount: '0.1btc',
amount: 10000000,
toAddress: 'n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5',
message: 'hola 1-1',
};
@ -526,7 +526,7 @@ describe('client API ', function() {
});
});
describe('Transaction Troposals and Locked funds', function() {
describe('Transaction proposals and locked funds', function() {
it('Should lock and release funds', function(done) {
helpers.createAndJoinWallet(clients, 2, 2, function(err, w) {
clients[0].createAddress(function(err, x0) {
@ -535,7 +535,7 @@ describe('client API ', function() {
blockExplorerMock.setUtxo(x0, 1, 2);
blockExplorerMock.setUtxo(x0, 1, 2);
var opts = {
amount: '1.2btc',
amount: 120000000,
toAddress: 'n2TBMPzPECGUfcT2EByiTJ12TPZkhN2mN5',
message: 'hola 1-1',
};

View File

@ -74,63 +74,4 @@ describe('WalletUtils', function() {
msg.should.equal('hello world');
});
});
describe('#parseAmount', function() {
it('should successfully parse amounts', function() {
var texts = {
'1': 1,
'0': 0,
'1.': 1,
'000000.0000': 0,
'123': 123,
'123sat': 123,
'123 sat': 123,
'00123 sat': 123,
'1.23bit': 123,
'1.23 bit': 123,
'0 bit': 0,
'.45bit': 45,
'1btc': 100000000,
' 1btc': 100000000,
'9999btc': 999900000000,
'0.00000001btc': 1,
'00000.00000001BTC': 1,
'0.00000001 BTC': 1,
'0.123btc': 12300000,
'0.123 bTc': 12300000,
};
_.each(texts, function(satoshi, text) {
var amount = WalletUtils.parseAmount(text);
amount.should.equal(satoshi);
});
});
it('should fail to parse incorrect amounts', function() {
var texts = [
'',
' ',
'btc',
'1satoshi',
'no-number',
'-3',
'1 b t c',
'btc1',
'btc 1',
'1,234',
'0.000000001btc',
'0.1sat',
'0.123bit',
'2.000000009btc',
];
_.each(texts, function(text) {
var valid = true;
try {
var amount = WalletUtils.parseAmount(text);
} catch (e) {
valid = false;
}
valid.should.be.false;
});
});
});
});