allow to sign transaction in api.sign using regular key

make Seed.parse_json try different input types instead
of stopping on first failing
This commit is contained in:
Ivan Tivonenko
2015-07-28 03:19:53 +03:00
parent e76e693bdb
commit 03a2109e24
5 changed files with 72 additions and 11 deletions

View File

@@ -24,6 +24,20 @@ function validateAddressAndSecret(obj) {
}
}
function validateSecret(secret) {
if (!secret) {
throw error('Parameter missing: secret');
}
if (typeof secret !== 'string' || secret[0] !== 's') {
throw error('Invalid parameter');
}
const seed = new core.Seed().parse_base58(secret);
if (!seed.is_valid()) {
throw error('invalid seed');
}
}
function validateLedgerRange(options) {
if (!_.isUndefined(options.minLedgerVersion)
&& !_.isUndefined(options.maxLedgerVersion)) {
@@ -41,6 +55,7 @@ function validateOptions(schema, options) {
module.exports = {
address: _.partial(schemaValidate, 'address'),
addressAndSecret: validateAddressAndSecret,
secret: validateSecret,
currency: _.partial(schemaValidate, 'currency'),
identifier: _.partial(schemaValidate, 'hash256'),
sequence: _.partial(schemaValidate, 'sequence'),

View File

@@ -18,8 +18,8 @@ const HASH_TX_ID = 0x54584E00; // 'TXN'
const HASH_TX_SIGN = 0x53545800; // 'STX'
const HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'
function getKeyPair(address, secret) {
return core.Seed.from_json(secret).get_key(address);
function getKeyPair(secret) {
return core.Seed.from_json(secret).get_key();
}
function getPublicKeyHex(keypair) {
@@ -51,9 +51,9 @@ function sign(txJSON: {Account: string; SigningPubKey: string,
TxnSignature: string}, secret: string):
{signedTransaction: string; id: string} {
validate.txJSON(txJSON);
validate.addressAndSecret({address: txJSON.Account, secret: secret});
validate.secret(secret);
const keypair = getKeyPair(txJSON.Account, secret);
const keypair = getKeyPair(secret);
if (txJSON.SigningPubKey === undefined) {
txJSON.SigningPubKey = getPublicKeyHex(keypair);
}

View File

@@ -28,15 +28,16 @@ Seed.prototype.parse_json = function(j) {
if (typeof j === 'string') {
if (!j.length) {
this._value = NaN;
// XXX Should actually always try and continue if it failed.
} else if (j[0] === 's') {
this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);
} else if (/^[0-9a-fA-f]{32}$/.test(j)) {
} else {
this.parse_base58(j);
if (!this.is_valid()) {
this.parse_hex(j);
// XXX Should also try 1751
} else {
}
if (!this.is_valid()) {
this.parse_passphrase(j);
}
}
} else {
this._value = NaN;
}
@@ -44,6 +45,19 @@ Seed.prototype.parse_json = function(j) {
return this;
};
Seed.prototype.parse_base58 = function(j) {
if (typeof j !== 'string') {
throw new Error('Value must be a string');
}
if (!j.length || j[0] !== 's') {
this._value = NaN;
} else {
this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);
}
return this;
};
Seed.prototype.parse_passphrase = function(j) {
if (typeof j !== 'string') {
throw new Error('Passphrase must be a string');

View File

@@ -562,6 +562,20 @@ describe('RippleAPI', function() {
secret: 'shzjfakiK79YQdMjy4h8cGGfQSV6u'
};
assert.doesNotThrow(_.partial(validate.addressAndSecret, goodWallet));
assert.doesNotThrow(_.partial(validate.secret,
'shzjfakiK79YQdMjy4h8cGGfQSV6u'));
assert.throws(_.partial(validate.secret, 1),
/Invalid parameter/);
assert.throws(_.partial(validate.secret, ''),
this.api.errors.ValidationError);
assert.throws(_.partial(validate.secret, 's!!!'),
this.api.errors.ValidationError);
assert.throws(_.partial(validate.secret, 'passphrase'),
this.api.errors.ValidationError);
// 32 0s is a valid hex repr of seed bytes
const hex = new Array(33).join('0');
assert.throws(_.partial(validate.secret, hex),
this.api.errors.ValidationError);
});
});

View File

@@ -1,4 +1,5 @@
/* eslint max-len: 0 */
/* eslint-disable max-nested-callbacks */
'use strict';
const assert = require('assert');
const Seed = require('ripple-lib').Seed;
@@ -18,6 +19,23 @@ describe('Seed', function() {
const seed = Seed.from_json('sp6iDHnmiPN7tQFHm5sCW59ax3hfE');
assert.strictEqual(seed.to_hex(), '00AD8DA764C3C8AF5F9B8D51C94B9E49');
});
it('sp6iDHnmiPN7tQFHm5sCW59ax3hfE using parse_base58', function() {
const seed = new Seed().parse_base58('sp6iDHnmiPN7tQFHm5sCW59ax3hfE');
assert.strictEqual(seed.to_hex(), '00AD8DA764C3C8AF5F9B8D51C94B9E49');
});
it('parse_base58 should throw on non-string input', function() {
assert.throws(function() {
new Seed().parse_base58(1);
});
});
it('parse_base58 should make invalid seed from empty string', function() {
const seed = new Seed().parse_base58('');
assert(!seed.is_valid());
});
it('parse_base58 should make invalid seed from invalid input', function() {
const seed = new Seed().parse_base58('Xs');
assert(!seed.is_valid());
});
it('can generate many addresses', function() {
const test_data = [