xrpl 5.0.0 → 5.1.0-batch.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"batchSigner.d.ts","sourceRoot":"","sources":["../../../src/Wallet/batchSigner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAyB,MAAM,WAAW,CAAA;AAMxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAgDrC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,KAAK,EAClB,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GACjE,IAAI,CA4CN;AAYD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAClC,MAAM,CAmCR"}
1
+ {"version":3,"file":"batchSigner.d.ts","sourceRoot":"","sources":["../../../src/Wallet/batchSigner.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAyB,MAAM,WAAW,CAAA;AAMxD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAgErC,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,KAAK,EAClB,IAAI,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAO,GACjE,IAAI,CA0DN;AAYD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAClC,MAAM,CAmCR"}
@@ -37,6 +37,14 @@ function constructBatchSignerObject(batchAccount, wallet, signature, multisignAd
37
37
  }
38
38
  return batchSigner;
39
39
  }
40
+ function getBatchSeqValue(transaction) {
41
+ var _a, _b;
42
+ const sequence = (_a = transaction.Sequence) !== null && _a !== void 0 ? _a : 0;
43
+ if (sequence !== 0) {
44
+ return sequence;
45
+ }
46
+ return (_b = transaction.TicketSequence) !== null && _b !== void 0 ? _b : 0;
47
+ }
40
48
  function signMultiBatch(wallet, transaction, opts = {}) {
41
49
  var _a;
42
50
  const batchAccount = (_a = opts.batchAccount) !== null && _a !== void 0 ? _a : wallet.classicAddress;
@@ -51,14 +59,19 @@ function signMultiBatch(wallet, transaction, opts = {}) {
51
59
  throw new errors_1.ValidationError('Must be a Batch transaction.');
52
60
  }
53
61
  (0, models_1.validate)(transaction);
54
- const involvedAccounts = new Set(transaction.RawTransactions.map((raw) => raw.RawTransaction.Account));
62
+ const involvedAccounts = new Set();
63
+ transaction.RawTransactions.forEach((raw) => {
64
+ involvedAccounts.add(raw.RawTransaction.Account);
65
+ const counterparty = raw.RawTransaction
66
+ .Counterparty;
67
+ if (typeof counterparty === 'string') {
68
+ involvedAccounts.add(counterparty);
69
+ }
70
+ });
55
71
  if (!involvedAccounts.has(batchAccount)) {
56
72
  throw new errors_1.ValidationError('Must be signing for an address submitting a transaction in the Batch.');
57
73
  }
58
- const fieldsToSign = {
59
- flags: transaction.Flags,
60
- txIDs: transaction.RawTransactions.map((rawTx) => (0, hashes_1.hashSignedTx)(rawTx.RawTransaction)),
61
- };
74
+ const fieldsToSign = Object.assign({ account: transaction.Account, sequence: getBatchSeqValue(transaction), flags: transaction.Flags, txIDs: transaction.RawTransactions.map((rawTx) => (0, hashes_1.hashSignedTx)(rawTx.RawTransaction)), batchAccount }, (multisignAddress ? { signerAccount: multisignAddress } : {}));
62
75
  const signature = (0, ripple_keypairs_1.sign)((0, ripple_binary_codec_1.encodeForSigningBatch)(fieldsToSign), wallet.privateKey);
63
76
  transaction.BatchSigners = [
64
77
  constructBatchSignerObject(batchAccount, wallet, signature, multisignAddress),
@@ -89,23 +102,37 @@ function combineBatchSigners(transactions) {
89
102
  return (0, ripple_binary_codec_1.encode)(getTransactionWithAllBatchSigners(batchTransactions));
90
103
  }
91
104
  exports.combineBatchSigners = combineBatchSigners;
92
- function validateBatchTransactionEquivalence(transactions) {
93
- const exampleTransaction = JSON.stringify({
94
- flags: transactions[0].Flags,
95
- transactionIDs: transactions[0].RawTransactions.map((rawTx) => (0, hashes_1.hashSignedTx)(rawTx.RawTransaction)),
96
- });
97
- if (transactions.slice(1).some((tx) => JSON.stringify({
105
+ function getBatchEquivalenceKey(tx) {
106
+ return JSON.stringify({
107
+ account: tx.Account,
108
+ sequence: getBatchSeqValue(tx),
98
109
  flags: tx.Flags,
99
110
  transactionIDs: tx.RawTransactions.map((rawTx) => (0, hashes_1.hashSignedTx)(rawTx.RawTransaction)),
100
- }) !== exampleTransaction)) {
101
- throw new errors_1.ValidationError('Flags and transaction hashes are not the same for all provided transactions.');
111
+ });
112
+ }
113
+ function validateBatchTransactionEquivalence(transactions) {
114
+ const exampleTransaction = getBatchEquivalenceKey(transactions[0]);
115
+ if (transactions
116
+ .slice(1)
117
+ .some((tx) => getBatchEquivalenceKey(tx) !== exampleTransaction)) {
118
+ throw new errors_1.ValidationError('Account, sequence, flags, and transaction hashes must be the same for all provided transactions.');
102
119
  }
103
120
  }
104
121
  function getTransactionWithAllBatchSigners(transactions) {
122
+ const outerAccount = transactions[0].Account;
105
123
  const sortedSigners = transactions
106
124
  .flatMap((tx) => { var _a; return (_a = tx.BatchSigners) !== null && _a !== void 0 ? _a : []; })
107
- .filter((signer) => signer.BatchSigner.Account !== transactions[0].Account)
125
+ .filter((signer) => signer.BatchSigner.Account !== outerAccount)
108
126
  .sort((signer1, signer2) => (0, utils_1.compareSigners)(signer1.BatchSigner, signer2.BatchSigner));
109
- return Object.assign(Object.assign({}, transactions[0]), { BatchSigners: sortedSigners });
127
+ const dedupedSigners = [];
128
+ let lastAccount = '';
129
+ for (const signer of sortedSigners) {
130
+ const account = signer.BatchSigner.Account;
131
+ if (account !== lastAccount) {
132
+ dedupedSigners.push(signer);
133
+ lastAccount = account;
134
+ }
135
+ }
136
+ return Object.assign(Object.assign({}, transactions[0]), { BatchSigners: dedupedSigners });
110
137
  }
111
138
  //# sourceMappingURL=batchSigner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"batchSigner.js","sourceRoot":"","sources":["../../../src/Wallet/batchSigner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"batchSigner.js","sourceRoot":"","sources":["../../../src/Wallet/batchSigner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xrpl",
3
- "version": "5.0.0",
3
+ "version": "5.1.0-batch.1",
4
4
  "license": "ISC",
5
5
  "description": "A TypeScript/JavaScript API for interacting with the XRP Ledger in Node.js and the browser",
6
6
  "files": [
@@ -30,7 +30,7 @@
30
30
  "eventemitter3": "^5.0.1",
31
31
  "fast-json-stable-stringify": "^2.1.0",
32
32
  "ripple-address-codec": "^5.0.1",
33
- "ripple-binary-codec": "^2.8.0",
33
+ "ripple-binary-codec": "^2.9.0-batch.1",
34
34
  "ripple-keypairs": "^3.0.0"
35
35
  },
36
36
  "devDependencies": {
@@ -45,6 +45,21 @@ function constructBatchSignerObject(
45
45
  return batchSigner
46
46
  }
47
47
 
48
+ /**
49
+ * Resolve the sequence value bound into a Batch signature: the `Sequence` when
50
+ * non-zero, otherwise the `TicketSequence` value (or 0).
51
+ *
52
+ * @param transaction - The Batch transaction being signed.
53
+ * @returns The sequence value to bind into the signature.
54
+ */
55
+ function getBatchSeqValue(transaction: Batch): number {
56
+ const sequence = transaction.Sequence ?? 0
57
+ if (sequence !== 0) {
58
+ return sequence
59
+ }
60
+ return transaction.TicketSequence ?? 0
61
+ }
62
+
48
63
  /**
49
64
  * Sign a multi-account Batch transaction.
50
65
  *
@@ -56,6 +71,7 @@ function constructBatchSignerObject(
56
71
  * The actual address is only needed in the case of regular key usage.
57
72
  * @throws ValidationError if the transaction is malformed.
58
73
  */
74
+ // eslint-disable-next-line max-lines-per-function -- cohesive signing routine
59
75
  export function signMultiBatch(
60
76
  wallet: Wallet,
61
77
  transaction: Batch,
@@ -79,19 +95,33 @@ export function signMultiBatch(
79
95
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- validate does not accept Transaction type
80
96
  validate(transaction as unknown as Record<string, unknown>)
81
97
 
82
- const involvedAccounts = new Set(
83
- transaction.RawTransactions.map((raw) => raw.RawTransaction.Account),
84
- )
98
+ // An account must sign the Batch if it submits an inner transaction or is the
99
+ // `Counterparty` of one.
100
+ const involvedAccounts = new Set<string>()
101
+ transaction.RawTransactions.forEach((raw) => {
102
+ involvedAccounts.add(raw.RawTransaction.Account)
103
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Counterparty only exists on some inner tx types
104
+ const counterparty = (raw.RawTransaction as Record<string, unknown>)
105
+ .Counterparty
106
+ if (typeof counterparty === 'string') {
107
+ involvedAccounts.add(counterparty)
108
+ }
109
+ })
85
110
  if (!involvedAccounts.has(batchAccount)) {
86
111
  throw new ValidationError(
87
112
  'Must be signing for an address submitting a transaction in the Batch.',
88
113
  )
89
114
  }
90
115
  const fieldsToSign = {
116
+ account: transaction.Account,
117
+ sequence: getBatchSeqValue(transaction),
91
118
  flags: transaction.Flags,
92
119
  txIDs: transaction.RawTransactions.map((rawTx) =>
93
120
  hashSignedTx(rawTx.RawTransaction),
94
121
  ),
122
+ batchAccount,
123
+ // Multi-signed batch signers also bind the inner signer account.
124
+ ...(multisignAddress ? { signerAccount: multisignAddress } : {}),
95
125
  }
96
126
  const signature = sign(encodeForSigningBatch(fieldsToSign), wallet.privateKey)
97
127
 
@@ -155,6 +185,26 @@ export function combineBatchSigners(
155
185
  return encode(getTransactionWithAllBatchSigners(batchTransactions))
156
186
  }
157
187
 
188
+ /**
189
+ * Builds a comparison key over every field bound into a Batch signature
190
+ * (XLS-56 V1_1): the outer account, sequence value, flags, and inner
191
+ * transaction IDs. Fragments that disagree on any of these were signed over
192
+ * different payloads and cannot be combined.
193
+ *
194
+ * @param tx - The Batch transaction to derive the key from.
195
+ * @returns A stable string key for equivalence comparison.
196
+ */
197
+ function getBatchEquivalenceKey(tx: Batch): string {
198
+ return JSON.stringify({
199
+ account: tx.Account,
200
+ sequence: getBatchSeqValue(tx),
201
+ flags: tx.Flags,
202
+ transactionIDs: tx.RawTransactions.map((rawTx) =>
203
+ hashSignedTx(rawTx.RawTransaction),
204
+ ),
205
+ })
206
+ }
207
+
158
208
  /**
159
209
  * The transactions should all be equal except for the 'Signers' field.
160
210
  *
@@ -162,37 +212,41 @@ export function combineBatchSigners(
162
212
  * @throws ValidationError if the transactions are not equal in any field other than 'Signers'.
163
213
  */
164
214
  function validateBatchTransactionEquivalence(transactions: Batch[]): void {
165
- const exampleTransaction = JSON.stringify({
166
- flags: transactions[0].Flags,
167
- transactionIDs: transactions[0].RawTransactions.map((rawTx) =>
168
- hashSignedTx(rawTx.RawTransaction),
169
- ),
170
- })
215
+ const exampleTransaction = getBatchEquivalenceKey(transactions[0])
171
216
  if (
172
- transactions.slice(1).some(
173
- (tx) =>
174
- JSON.stringify({
175
- flags: tx.Flags,
176
- transactionIDs: tx.RawTransactions.map((rawTx) =>
177
- hashSignedTx(rawTx.RawTransaction),
178
- ),
179
- }) !== exampleTransaction,
180
- )
217
+ transactions
218
+ .slice(1)
219
+ .some((tx) => getBatchEquivalenceKey(tx) !== exampleTransaction)
181
220
  ) {
182
221
  throw new ValidationError(
183
- 'Flags and transaction hashes are not the same for all provided transactions.',
222
+ 'Account, sequence, flags, and transaction hashes must be the same for all provided transactions.',
184
223
  )
185
224
  }
186
225
  }
187
226
 
188
227
  function getTransactionWithAllBatchSigners(transactions: Batch[]): Batch {
228
+ const outerAccount = transactions[0].Account
229
+
189
230
  // Signers must be sorted in the combined transaction - See compareSigners' documentation for more details
190
231
  const sortedSigners: BatchSigner[] = transactions
191
232
  .flatMap((tx) => tx.BatchSigners ?? [])
192
- .filter((signer) => signer.BatchSigner.Account !== transactions[0].Account)
233
+ // A batch signer cannot be the outer account (rippled: temBAD_SIGNER).
234
+ .filter((signer) => signer.BatchSigner.Account !== outerAccount)
193
235
  .sort((signer1, signer2) =>
194
236
  compareSigners(signer1.BatchSigner, signer2.BatchSigner),
195
237
  )
196
238
 
197
- return { ...transactions[0], BatchSigners: sortedSigners }
239
+ // BatchSigners must be strictly ascending and unique by account, so
240
+ // de-duplicate when combining fragments that share a signer.
241
+ const dedupedSigners: BatchSigner[] = []
242
+ let lastAccount = ''
243
+ for (const signer of sortedSigners) {
244
+ const account = signer.BatchSigner.Account
245
+ if (account !== lastAccount) {
246
+ dedupedSigners.push(signer)
247
+ lastAccount = account
248
+ }
249
+ }
250
+
251
+ return { ...transactions[0], BatchSigners: dedupedSigners }
198
252
  }