mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 20:25:48 +00:00
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:
@@ -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'),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -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 = [
|
||||
|
||||
Reference in New Issue
Block a user