mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-20 12:15:51 +00:00
Move to new ripple-keypairs API
This commit is contained in:
4
npm-shrinkwrap.json
generated
4
npm-shrinkwrap.json
generated
@@ -133,8 +133,8 @@
|
||||
}
|
||||
},
|
||||
"ripple-keypairs": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.8.0.tgz",
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.9.0.tgz",
|
||||
"dependencies": {
|
||||
"brorand": {
|
||||
"version": "1.0.5",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"lodash": "^3.1.0",
|
||||
"lru-cache": "~2.5.0",
|
||||
"ripple-address-codec": "^1.6.0",
|
||||
"ripple-keypairs": "^0.8.0",
|
||||
"ripple-keypairs": "^0.9.0",
|
||||
"ripple-lib-transactionparser": "^0.5.0",
|
||||
"sjcl-codec": "0.1.0",
|
||||
"ws": "~0.7.1"
|
||||
|
||||
@@ -29,8 +29,10 @@ function toRippledAmount(amount: Amount): string|Amount {
|
||||
}
|
||||
|
||||
function generateAddress(options?: Object): Object {
|
||||
const {accountID, seed} = keypairs.generateWallet(options);
|
||||
return {secret: seed, address: accountID};
|
||||
const secret = keypairs.generateSeed(options);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
const address = keypairs.deriveAddress(keypair.publicKey);
|
||||
return {secret, address};
|
||||
}
|
||||
|
||||
type AsyncFunction = (...x: any) => void
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const _ = require('lodash');
|
||||
const core = require('./utils').core;
|
||||
const deriveKeypair = require('ripple-keypairs').deriveKeypair;
|
||||
const ValidationError = require('./errors').ValidationError;
|
||||
const schemaValidate = require('./schema-validator').schemaValidate;
|
||||
|
||||
@@ -9,6 +9,15 @@ function error(text) {
|
||||
return new ValidationError(text);
|
||||
}
|
||||
|
||||
function isValidSecret(secret) {
|
||||
try {
|
||||
deriveKeypair(secret);
|
||||
return true;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function validateAddressAndSecret(obj: {address: string, secret: string}
|
||||
): void {
|
||||
const address = obj.address;
|
||||
@@ -17,8 +26,8 @@ function validateAddressAndSecret(obj: {address: string, secret: string}
|
||||
if (!secret) {
|
||||
throw error('Parameter missing: secret');
|
||||
}
|
||||
if (!core.Seed.from_json(secret).is_valid()) {
|
||||
throw error('secret is invalid');
|
||||
if (!isValidSecret(secret)) {
|
||||
throw error('Invalid parameter: secret');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,13 +35,9 @@ function validateSecret(secret: string): void {
|
||||
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');
|
||||
if (typeof secret !== 'string' || secret[0] !== 's'
|
||||
|| !isValidSecret(secret)) {
|
||||
throw error('Invalid parameter: secret');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* @flow */
|
||||
'use strict';
|
||||
const utils = require('./utils');
|
||||
const keypairs = require('ripple-keypairs');
|
||||
const core = utils.common.core;
|
||||
const validate = utils.common.validate;
|
||||
|
||||
@@ -16,14 +17,6 @@ const validate = utils.common.validate;
|
||||
*/
|
||||
const HASH_TX_ID = 0x54584E00; // 'TXN'
|
||||
|
||||
function getKeyPair(secret) {
|
||||
return core.Seed.from_json(secret).get_key();
|
||||
}
|
||||
|
||||
function getPublicKeyHex(keypair) {
|
||||
return keypair.pubKeyHex();
|
||||
}
|
||||
|
||||
function serialize(txJSON) {
|
||||
return core.SerializedObject.from_json(txJSON);
|
||||
}
|
||||
@@ -36,8 +29,8 @@ function signingData(txJSON) {
|
||||
return core.Transaction.from_json(txJSON).signingData().buffer;
|
||||
}
|
||||
|
||||
function computeSignature(txJSON, keypair) {
|
||||
return keypair.signHex(signingData(txJSON));
|
||||
function computeSignature(txJSON, privateKey) {
|
||||
return keypairs.sign(signingData(txJSON), privateKey);
|
||||
}
|
||||
|
||||
function sign(txJSON: string, secret: string
|
||||
@@ -46,11 +39,11 @@ function sign(txJSON: string, secret: string
|
||||
validate.txJSON(tx);
|
||||
validate.secret(secret);
|
||||
|
||||
const keypair = getKeyPair(secret);
|
||||
const keypair = keypairs.deriveKeypair(secret);
|
||||
if (tx.SigningPubKey === undefined) {
|
||||
tx.SigningPubKey = getPublicKeyHex(keypair);
|
||||
tx.SigningPubKey = keypair.publicKey;
|
||||
}
|
||||
tx.TxnSignature = computeSignature(tx, keypair);
|
||||
tx.TxnSignature = computeSignature(tx, keypair.privateKey);
|
||||
const serialized = serialize(tx);
|
||||
return {
|
||||
signedTransaction: serialized.to_hex(),
|
||||
|
||||
@@ -14,10 +14,8 @@ const _ = require('lodash');
|
||||
const async = require('async');
|
||||
const extend = require('extend');
|
||||
const util = require('util');
|
||||
const {createAccountID} = require('ripple-keypairs');
|
||||
const {encodeAccountID} = require('ripple-address-codec');
|
||||
const {deriveAddress} = require('ripple-keypairs');
|
||||
const {EventEmitter} = require('events');
|
||||
const {hexToArray} = require('./utils');
|
||||
const {TransactionManager} = require('./transactionmanager');
|
||||
const {UInt160} = require('./uint160');
|
||||
|
||||
@@ -377,7 +375,7 @@ Account.prototype.publicKeyIsActive = function(public_key, callback) {
|
||||
Account._publicKeyToAddress = function(public_key) {
|
||||
// Based on functions in /src/js/ripple/keypair.js
|
||||
function hexToUInt160(publicKey) {
|
||||
return encodeAccountID(createAccountID(hexToArray(publicKey)));
|
||||
return deriveAddress(publicKey);
|
||||
}
|
||||
|
||||
if (UInt160.is_valid(public_key)) {
|
||||
|
||||
@@ -7,7 +7,6 @@ const assert = require('assert');
|
||||
const extend = require('extend');
|
||||
const utils = require('./utils');
|
||||
const UInt160 = require('./uint160').UInt160;
|
||||
const Seed = require('./seed').Seed;
|
||||
const Currency = require('./currency').Currency;
|
||||
const Value = require('./value').Value;
|
||||
const IOUValue = require('./iouvalue').IOUValue;
|
||||
@@ -1008,10 +1007,4 @@ Amount.prototype.not_equals_why = function(d, ignore_issuer) {
|
||||
};
|
||||
|
||||
exports.Amount = Amount;
|
||||
|
||||
// DEPRECATED: Include the corresponding files instead.
|
||||
exports.Currency = Currency;
|
||||
exports.Seed = Seed;
|
||||
exports.UInt160 = UInt160;
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
|
||||
@@ -9,7 +9,6 @@ exports.Base = require('./base').Base;
|
||||
exports.UInt128 = require('./uint128').UInt128;
|
||||
exports.UInt160 = require('./uint160').UInt160;
|
||||
exports.UInt256 = require('./uint256').UInt256;
|
||||
exports.Seed = require('./seed').Seed;
|
||||
exports.Meta = require('./meta').Meta;
|
||||
exports.SerializedObject = require('./serializedobject').SerializedObject;
|
||||
exports.RippleError = require('./rippleerror').RippleError;
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
//
|
||||
// Seed support
|
||||
//
|
||||
|
||||
const {KeyPair, KeyType} = require('ripple-keypairs');
|
||||
const {decodeSeed, encodeSeed} = require('ripple-address-codec');
|
||||
const extend = require('extend');
|
||||
const sjclcodec = require('sjcl-codec');
|
||||
const BN = require('bn.js');
|
||||
const hashjs = require('hash.js');
|
||||
|
||||
const UInt = require('./uint').UInt;
|
||||
|
||||
const Seed = extend(function() {
|
||||
this._value = NaN;
|
||||
this._type = KeyType.secp256k1;
|
||||
}, UInt);
|
||||
|
||||
Seed.width = 16;
|
||||
Seed.prototype = Object.create(extend({}, UInt.prototype));
|
||||
Seed.prototype.constructor = Seed;
|
||||
|
||||
// value = NaN on error.
|
||||
// One day this will support rfc1751 too.
|
||||
Seed.prototype.parse_json = function(j) {
|
||||
if (typeof j === 'string') {
|
||||
if (!j.length) {
|
||||
this._value = NaN;
|
||||
} else {
|
||||
this.parse_base58(j);
|
||||
if (!this.is_valid()) {
|
||||
this.parse_hex(j);
|
||||
// XXX Should also try 1751
|
||||
}
|
||||
if (!this.is_valid() && j[0] !== 's') {
|
||||
this.parse_passphrase(j);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this._value = NaN;
|
||||
}
|
||||
|
||||
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 {
|
||||
try {
|
||||
const {bytes, type} = decodeSeed(j);
|
||||
this._value = new BN(bytes);
|
||||
this._type = type;
|
||||
} catch (e) {
|
||||
this._value = NaN;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.set_ed25519 = function() {
|
||||
this._type = KeyType.ed25519;
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.parse_passphrase = function(j) {
|
||||
if (typeof j !== 'string') {
|
||||
throw new Error('Passphrase must be a string');
|
||||
}
|
||||
|
||||
const phraseBytes = sjclcodec.bytes.fromBits(sjclcodec.utf8String.toBits(j));
|
||||
const hash = hashjs.sha512().update(phraseBytes).digest();
|
||||
this.parse_bytes(hash.slice(0, 16));
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
Seed.prototype.to_json = function() {
|
||||
if (!(this.is_valid())) {
|
||||
return NaN;
|
||||
}
|
||||
return encodeSeed(this.to_bytes(), this._type);
|
||||
};
|
||||
|
||||
Seed.prototype.get_key = function() {
|
||||
if (!this.is_valid()) {
|
||||
throw new Error('Cannot generate keys from invalid seed!');
|
||||
}
|
||||
return KeyPair.fromSeed(this.to_bytes(), this._type);
|
||||
};
|
||||
|
||||
exports.Seed = Seed;
|
||||
@@ -3,14 +3,13 @@
|
||||
const assert = require('assert');
|
||||
const util = require('util');
|
||||
const _ = require('lodash');
|
||||
const {deriveKeypair, sign} = require('ripple-keypairs');
|
||||
const EventEmitter = require('events').EventEmitter;
|
||||
const utils = require('./utils');
|
||||
const sjclcodec = require('sjcl-codec');
|
||||
const Amount = require('./amount').Amount;
|
||||
const Currency = require('./amount').Currency;
|
||||
const UInt160 = require('./amount').UInt160;
|
||||
const Seed = require('./seed').Seed;
|
||||
const KeyPair = require('ripple-keypairs').KeyPair;
|
||||
const Currency = require('./currency').Currency;
|
||||
const UInt160 = require('./uint160').UInt160;
|
||||
const SerializedObject = require('./serializedobject').SerializedObject;
|
||||
const RippleError = require('./rippleerror').RippleError;
|
||||
const hashprefixes = require('./hashprefixes');
|
||||
@@ -430,31 +429,12 @@ Transaction.prototype.complete = function() {
|
||||
return this.tx_json;
|
||||
};
|
||||
|
||||
Transaction.prototype.getKeyPair = function(secret_) {
|
||||
if (this._keyPair) {
|
||||
return this._keyPair;
|
||||
}
|
||||
|
||||
const secret = secret_ || this._secret;
|
||||
assert(secret, 'Secret missing');
|
||||
|
||||
const keyPair = Seed.from_json(secret).get_key();
|
||||
this._keyPair = keyPair;
|
||||
|
||||
return keyPair;
|
||||
};
|
||||
|
||||
Transaction.prototype.getSigningPubKey = function(secret) {
|
||||
return this.getKeyPair(secret).pubKeyHex();
|
||||
return deriveKeypair(secret || this._secret).publicKey;
|
||||
};
|
||||
|
||||
Transaction.prototype.setSigningPubKey = function(key) {
|
||||
if (_.isString(key)) {
|
||||
this.tx_json.SigningPubKey = key;
|
||||
} else if (key instanceof KeyPair) {
|
||||
this.tx_json.SigningPubKey = key.pubKeyHex();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -509,16 +489,13 @@ Transaction.prototype.hash = function(prefix_, asUINT256, serialized) {
|
||||
return asUINT256 ? hash : hash.to_hex();
|
||||
};
|
||||
|
||||
Transaction.prototype.sign = function() {
|
||||
Transaction.prototype.sign = function(secret) {
|
||||
if (this.hasMultiSigners()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
const keyPair = this.getKeyPair();
|
||||
const prev_sig = this.tx_json.TxnSignature;
|
||||
|
||||
delete this.tx_json.TxnSignature;
|
||||
|
||||
const hash = this.signingHash();
|
||||
|
||||
// If the hash is the same, we can re-use the previous signature
|
||||
@@ -527,7 +504,9 @@ Transaction.prototype.sign = function() {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.tx_json.TxnSignature = keyPair.signHex(this.signingData().buffer);
|
||||
const keypair = deriveKeypair(secret || this._secret);
|
||||
this.tx_json.TxnSignature = sign(this.signingData().buffer,
|
||||
keypair.privateKey);
|
||||
this.previousSigningHash = hash;
|
||||
|
||||
return this;
|
||||
@@ -1675,12 +1654,12 @@ Transaction.prototype.getMultiSigningJson = function() {
|
||||
|
||||
Transaction.prototype.multiSign = function(account, secret) {
|
||||
const signingData = this.multiSigningData(account);
|
||||
const keyPair = Seed.from_json(secret).get_key();
|
||||
const keypair = deriveKeypair(secret);
|
||||
|
||||
const signer = {
|
||||
Account: account,
|
||||
TxnSignature: keyPair.signHex(signingData.buffer),
|
||||
SigningPubKey: keyPair.pubKeyHex()
|
||||
TxnSignature: sign(signingData.buffer, keypair.privateKey),
|
||||
SigningPubKey: keypair.publicKey
|
||||
};
|
||||
|
||||
return signer;
|
||||
|
||||
@@ -481,7 +481,7 @@ describe('RippleAPI', function() {
|
||||
function random() {
|
||||
return _.fill(Array(16), 0);
|
||||
}
|
||||
assert.deepEqual(this.api.generateAddress({random}),
|
||||
assert.deepEqual(this.api.generateAddress({entropy: random()}),
|
||||
responses.generateAddress);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
/* eslint max-len: 0 */
|
||||
/* eslint-disable max-nested-callbacks */
|
||||
'use strict';
|
||||
const assert = require('assert');
|
||||
const Seed = require('ripple-lib').Seed;
|
||||
|
||||
describe('Seed', function() {
|
||||
it('saESc82Vun7Ta5EJRzGJbrXb5HNYk', function() {
|
||||
const seed = Seed.from_json('saESc82Vun7Ta5EJRzGJbrXb5HNYk');
|
||||
assert.strictEqual(seed.to_hex(), 'FF1CF838D02B2CF7B45BAC27F5F24F4F');
|
||||
});
|
||||
it('can create ed25519 seeds from a phrase', function() {
|
||||
const seed = Seed.from_json('phrase').set_ed25519().to_json();
|
||||
assert.strictEqual(seed, 'sEdT7U4WpkoiH6wBoNeLzDi1eu9N64Y');
|
||||
});
|
||||
it('sp6iDHnmiPN7tQFHm5sCW59ax3hfE', 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('should return the key_pair for a valid account and secret pair', function() {
|
||||
const address = 'r3GgMwvgvP8h4yVWvjH1dPZNvC37TjzBBE';
|
||||
const seed = Seed.from_json('shsWGZcmZz6YsWWmcnpfr6fLTdtFV');
|
||||
const keyPair = seed.get_key();
|
||||
assert.strictEqual(keyPair.accountID(), address);
|
||||
assert.strictEqual(keyPair.pubKeyHex(), '02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8');
|
||||
});
|
||||
});
|
||||
|
||||
// vim:sw=2:sts=2:ts=8:et
|
||||
@@ -1,62 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const Seed = require('ripple-lib').Seed;
|
||||
|
||||
function _isNaN(n) {
|
||||
return typeof n === 'number' && isNaN(n);
|
||||
}
|
||||
|
||||
describe('Signing', function() {
|
||||
describe('Keys', function() {
|
||||
it('SigningPubKey 1 (ripple-client issue #245)', function() {
|
||||
const seed = Seed.from_json('saESc82Vun7Ta5EJRzGJbrXb5HNYk');
|
||||
const key = seed.get_key('rBZ4j6MsoctipM6GEyHSjQKzXG3yambDnZ');
|
||||
const pub = key.pubKeyHex();
|
||||
assert.strictEqual(
|
||||
pub,
|
||||
'0396941B22791A448E5877A44CE98434DB217D6FB97D63F0DAD23BE49ED45173C9');
|
||||
});
|
||||
it('SigningPubKey 2 (master seed)', function() {
|
||||
const seed = Seed.from_json('snoPBrXtMeMyMHUVTgbuqAfg1SUTb');
|
||||
const key = seed.get_key('rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh');
|
||||
const pub = key.pubKeyHex();
|
||||
assert.strictEqual(
|
||||
pub,
|
||||
'0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020');
|
||||
});
|
||||
});
|
||||
describe('parse_json', function() {
|
||||
it('empty string', function() {
|
||||
assert(_isNaN(new Seed().parse_json('').to_json()));
|
||||
});
|
||||
it('hex string', function() {
|
||||
// 32 0s is a valid hex repr of seed bytes
|
||||
const str = new Array(33).join('0');
|
||||
assert.strictEqual((new Seed().parse_json(str).to_json()),
|
||||
'sp6JS7f14BuwFY8Mw6bTtLKWauoUs');
|
||||
});
|
||||
it('passphrase', function() {
|
||||
const str = new Array(60).join('0');
|
||||
assert.strictEqual('snFRPnVL3secohdpwSie8ANXdFQvG',
|
||||
new Seed().parse_json(str).to_json());
|
||||
});
|
||||
it('null', function() {
|
||||
assert(_isNaN(new Seed().parse_json(null).to_json()));
|
||||
});
|
||||
});
|
||||
describe('parse_passphrase', function() {
|
||||
it('invalid passphrase', function() {
|
||||
assert.throws(function() {
|
||||
new Seed().parse_passphrase(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('get_key', function() {
|
||||
it('get key from invalid seed', function() {
|
||||
assert.throws(function() {
|
||||
new Seed().get_key('rBZ4j6MsoctipM6GEyHSjQKzXG3yambDnZ');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const assert = require('assert-diff');
|
||||
const lodash = require('lodash');
|
||||
const addresses = require('./fixtures/addresses');
|
||||
const ripple = require('ripple-lib');
|
||||
const Transaction = require('ripple-lib').Transaction;
|
||||
const TransactionQueue = require('ripple-lib').TransactionQueue;
|
||||
@@ -340,7 +341,7 @@ describe('Transaction', function() {
|
||||
const dst = 'rGihwhaqU8g7ahwAvTq6iX5rvsfcbgZw6v';
|
||||
|
||||
transaction.payment(src, dst, '100');
|
||||
remote.setSecret(src, 'masterpassphrase');
|
||||
remote.setSecret(src, addresses.SECRET);
|
||||
|
||||
assert(transaction.complete());
|
||||
const json = transaction.serialize().to_json();
|
||||
@@ -2278,20 +2279,19 @@ describe('Transaction', function() {
|
||||
const a1 = 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK';
|
||||
const a2 = 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW';
|
||||
|
||||
const s1 = t1.multiSign(a1, 'alice');
|
||||
const s1 = t1.multiSign(a1, addresses.SECRET);
|
||||
assert.deepEqual(s1, {
|
||||
Account: 'rPMh7Pi9ct699iZUTWaytJUoHcJ7cgyziK',
|
||||
TxnSignature: '3045022100DB13DC794DDFA1E27D099CDBFC7DB5B1EE892AD1725B0CEEE97D8B1C4C2055C7022030B3372C96D08106594B3CF8CDF88E05CC6260C51954F02387289CB69B839D7A',
|
||||
SigningPubKey: '0388935426E0D08083314842EDFBB2D517BD47699F9A4527318A8E10468C97C052'
|
||||
TxnSignature: '30440220613DF9410B4844C7FAB637FD707F5185A2107DD10D0C2F59155844CD1910AB99022004A2AE607C15DD0959FDB3AAEE6A0337AA5337515230CE6EC11E32B74EEE896E',
|
||||
SigningPubKey: '02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
|
||||
});
|
||||
|
||||
const s2 = t1.multiSign(a2, 'bob');
|
||||
const s2 = t1.multiSign(a2, addresses.SECRET);
|
||||
assert.deepEqual(s2, {
|
||||
Account: 'rH4KEcG9dEwGwpn6AyoWK9cZPLL4RLSmWW',
|
||||
TxnSignature: '304402207A22109088069C5ABE3E961C2F85B2B8111C5666C869E8BA3F2A57C2ECEA7FC402205F9D87FB42266CC498FCE9B4904955D0E6D5F44D092596F5DE3E25843F6D10AB',
|
||||
SigningPubKey: '02691AC5AE1C4C333AE5DF8A93BDC495F0EEBFC6DB0DA7EB6EF808F3AFC006E3FE'
|
||||
|
||||
TxnSignature: '3044022011762BC175E166EF540ABB162F0E8B48250E7C95DE5E8464E3F648EAF9A94A50022022439146DC3C6BB943C719F89696E7EBED14888A653F4618F62F8DA5CE202A45',
|
||||
SigningPubKey: '02F89EAEC7667B30F33D0687BBA86C3FE2A08CCA40A9186C5BDE2DAA6FA97A37D8'
|
||||
});
|
||||
|
||||
transaction.addMultiSigner(s1);
|
||||
|
||||
Reference in New Issue
Block a user