mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 04:35:49 +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) {
|
function validateLedgerRange(options) {
|
||||||
if (!_.isUndefined(options.minLedgerVersion)
|
if (!_.isUndefined(options.minLedgerVersion)
|
||||||
&& !_.isUndefined(options.maxLedgerVersion)) {
|
&& !_.isUndefined(options.maxLedgerVersion)) {
|
||||||
@@ -41,6 +55,7 @@ function validateOptions(schema, options) {
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
address: _.partial(schemaValidate, 'address'),
|
address: _.partial(schemaValidate, 'address'),
|
||||||
addressAndSecret: validateAddressAndSecret,
|
addressAndSecret: validateAddressAndSecret,
|
||||||
|
secret: validateSecret,
|
||||||
currency: _.partial(schemaValidate, 'currency'),
|
currency: _.partial(schemaValidate, 'currency'),
|
||||||
identifier: _.partial(schemaValidate, 'hash256'),
|
identifier: _.partial(schemaValidate, 'hash256'),
|
||||||
sequence: _.partial(schemaValidate, 'sequence'),
|
sequence: _.partial(schemaValidate, 'sequence'),
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ const HASH_TX_ID = 0x54584E00; // 'TXN'
|
|||||||
const HASH_TX_SIGN = 0x53545800; // 'STX'
|
const HASH_TX_SIGN = 0x53545800; // 'STX'
|
||||||
const HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'
|
const HASH_TX_SIGN_TESTNET = 0x73747800; // 'stx'
|
||||||
|
|
||||||
function getKeyPair(address, secret) {
|
function getKeyPair(secret) {
|
||||||
return core.Seed.from_json(secret).get_key(address);
|
return core.Seed.from_json(secret).get_key();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPublicKeyHex(keypair) {
|
function getPublicKeyHex(keypair) {
|
||||||
@@ -51,9 +51,9 @@ function sign(txJSON: {Account: string; SigningPubKey: string,
|
|||||||
TxnSignature: string}, secret: string):
|
TxnSignature: string}, secret: string):
|
||||||
{signedTransaction: string; id: string} {
|
{signedTransaction: string; id: string} {
|
||||||
validate.txJSON(txJSON);
|
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) {
|
if (txJSON.SigningPubKey === undefined) {
|
||||||
txJSON.SigningPubKey = getPublicKeyHex(keypair);
|
txJSON.SigningPubKey = getPublicKeyHex(keypair);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,15 +28,16 @@ Seed.prototype.parse_json = function(j) {
|
|||||||
if (typeof j === 'string') {
|
if (typeof j === 'string') {
|
||||||
if (!j.length) {
|
if (!j.length) {
|
||||||
this._value = NaN;
|
this._value = NaN;
|
||||||
// XXX Should actually always try and continue if it failed.
|
} else {
|
||||||
} else if (j[0] === 's') {
|
this.parse_base58(j);
|
||||||
this._value = Base.decode_check(Base.VER_FAMILY_SEED, j);
|
if (!this.is_valid()) {
|
||||||
} else if (/^[0-9a-fA-f]{32}$/.test(j)) {
|
|
||||||
this.parse_hex(j);
|
this.parse_hex(j);
|
||||||
// XXX Should also try 1751
|
// XXX Should also try 1751
|
||||||
} else {
|
}
|
||||||
|
if (!this.is_valid()) {
|
||||||
this.parse_passphrase(j);
|
this.parse_passphrase(j);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this._value = NaN;
|
this._value = NaN;
|
||||||
}
|
}
|
||||||
@@ -44,6 +45,19 @@ Seed.prototype.parse_json = function(j) {
|
|||||||
return this;
|
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) {
|
Seed.prototype.parse_passphrase = function(j) {
|
||||||
if (typeof j !== 'string') {
|
if (typeof j !== 'string') {
|
||||||
throw new Error('Passphrase must be a string');
|
throw new Error('Passphrase must be a string');
|
||||||
|
|||||||
@@ -562,6 +562,20 @@ describe('RippleAPI', function() {
|
|||||||
secret: 'shzjfakiK79YQdMjy4h8cGGfQSV6u'
|
secret: 'shzjfakiK79YQdMjy4h8cGGfQSV6u'
|
||||||
};
|
};
|
||||||
assert.doesNotThrow(_.partial(validate.addressAndSecret, goodWallet));
|
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 max-len: 0 */
|
||||||
|
/* eslint-disable max-nested-callbacks */
|
||||||
'use strict';
|
'use strict';
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const Seed = require('ripple-lib').Seed;
|
const Seed = require('ripple-lib').Seed;
|
||||||
@@ -18,6 +19,23 @@ describe('Seed', function() {
|
|||||||
const seed = Seed.from_json('sp6iDHnmiPN7tQFHm5sCW59ax3hfE');
|
const seed = Seed.from_json('sp6iDHnmiPN7tQFHm5sCW59ax3hfE');
|
||||||
assert.strictEqual(seed.to_hex(), '00AD8DA764C3C8AF5F9B8D51C94B9E49');
|
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() {
|
it('can generate many addresses', function() {
|
||||||
|
|
||||||
const test_data = [
|
const test_data = [
|
||||||
|
|||||||
Reference in New Issue
Block a user