move parseAmount to CLI only
This commit is contained in:
parent
345938824f
commit
675369eed0
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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',
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue