UNPKG

2.25 kBPlain TextView Raw
1/**
2 * @hidden
3 */
4
5/**
6 */
7import * as rippleKeypairs from 'ripple-keypairs';
8import * as ripple from 'ripple-lib';
9import { ECPair } from '@bitgo/utxo-lib';
10
11import * as binary from 'ripple-binary-codec';
12import { computeBinaryTransactionHash } from 'ripple-lib/dist/npm/common/hashes';
13
14function computeSignature(tx, privateKey, signAs) {
15 const signingData = signAs ?
16 binary.encodeForMultisigning(tx, signAs) : binary.encodeForSigning(tx);
17 return rippleKeypairs.sign(signingData, privateKey);
18}
19
20/**
21 * Sign Ripple transaction with a secp256k1 private key
22 * @param txHex
23 * @param privateKey
24 * @param options
25 * @returns {{signedTransaction: *, id}}
26 */
27const signWithPrivateKey = function (txHex, privateKey, options) {
28 let privateKeyBuffer = Buffer.from(privateKey, 'hex');
29 if (privateKeyBuffer.length === 33 && privateKeyBuffer[0] === 0) {
30 privateKeyBuffer = privateKeyBuffer.slice(1, 33);
31 }
32 const publicKey = ECPair.fromPrivateKey(privateKeyBuffer).publicKey.toString('hex').toUpperCase();
33
34 let tx;
35 try {
36 tx = binary.decode(txHex);
37 } catch (e) {
38 try {
39 tx = JSON.parse(txHex);
40 } catch (e) {
41 throw new Error('txHex needs to be either hex or JSON string for XRP');
42 }
43 }
44 if (tx.TxnSignature || tx.Signers) {
45 throw new Error('transaction must not contain "TxnSignature" or "Signers" properties');
46 }
47
48 tx.SigningPubKey = (options && options.signAs) ? '' : publicKey;
49
50 if (options && options.signAs) {
51 const expectedSigner = rippleKeypairs.deriveAddress(publicKey);
52 if (options.signAs !== expectedSigner) {
53 throw new Error('signAs does not match private key');
54 }
55 const signer = {
56 Account: options.signAs,
57 SigningPubKey: publicKey,
58 TxnSignature: computeSignature(tx, privateKey, options.signAs),
59 };
60 tx.Signers = [{ Signer: signer }];
61 } else {
62 tx.TxnSignature = computeSignature(tx, privateKey, undefined);
63 }
64
65 const serialized = binary.encode(tx);
66 return {
67 signedTransaction: serialized,
68 id: computeBinaryTransactionHash(serialized),
69 };
70};
71
72export = (params): ripple.RippleAPI => {
73 const rippleLib = new ripple.RippleAPI(params);
74 (rippleLib as any).signWithPrivateKey = signWithPrivateKey;
75 return rippleLib;
76};