@bsv/sdk 1.1.24 → 1.1.26

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.
Files changed (53) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/totp/totp.js +1 -1
  3. package/dist/cjs/src/totp/totp.js.map +1 -1
  4. package/dist/cjs/src/transaction/Beef.js +492 -0
  5. package/dist/cjs/src/transaction/Beef.js.map +1 -0
  6. package/dist/cjs/src/transaction/BeefParty.js +97 -0
  7. package/dist/cjs/src/transaction/BeefParty.js.map +1 -0
  8. package/dist/cjs/src/transaction/BeefTx.js +123 -0
  9. package/dist/cjs/src/transaction/BeefTx.js.map +1 -0
  10. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  11. package/dist/cjs/src/transaction/Transaction.js +156 -35
  12. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  13. package/dist/cjs/src/transaction/index.js +7 -1
  14. package/dist/cjs/src/transaction/index.js.map +1 -1
  15. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  16. package/dist/esm/src/totp/totp.js +1 -1
  17. package/dist/esm/src/totp/totp.js.map +1 -1
  18. package/dist/esm/src/transaction/Beef.js +485 -0
  19. package/dist/esm/src/transaction/Beef.js.map +1 -0
  20. package/dist/esm/src/transaction/BeefParty.js +93 -0
  21. package/dist/esm/src/transaction/BeefParty.js.map +1 -0
  22. package/dist/esm/src/transaction/BeefTx.js +121 -0
  23. package/dist/esm/src/transaction/BeefTx.js.map +1 -0
  24. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  25. package/dist/esm/src/transaction/Transaction.js +156 -35
  26. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  27. package/dist/esm/src/transaction/index.js +3 -0
  28. package/dist/esm/src/transaction/index.js.map +1 -1
  29. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  30. package/dist/types/src/transaction/Beef.d.ts +143 -0
  31. package/dist/types/src/transaction/Beef.d.ts.map +1 -0
  32. package/dist/types/src/transaction/BeefParty.d.ts +62 -0
  33. package/dist/types/src/transaction/BeefParty.d.ts.map +1 -0
  34. package/dist/types/src/transaction/BeefTx.d.ts +35 -0
  35. package/dist/types/src/transaction/BeefTx.d.ts.map +1 -0
  36. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  37. package/dist/types/src/transaction/Transaction.d.ts +44 -4
  38. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  39. package/dist/types/src/transaction/index.d.ts +3 -0
  40. package/dist/types/src/transaction/index.d.ts.map +1 -1
  41. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  42. package/docs/primitives.md +372 -55
  43. package/docs/transaction.md +531 -5
  44. package/package.json +1 -1
  45. package/src/totp/totp.ts +1 -1
  46. package/src/transaction/Beef.ts +533 -0
  47. package/src/transaction/BeefParty.ts +100 -0
  48. package/src/transaction/BeefTx.ts +121 -0
  49. package/src/transaction/MerklePath.ts +11 -11
  50. package/src/transaction/Transaction.ts +196 -59
  51. package/src/transaction/__tests/Beef.test.ts +290 -0
  52. package/src/transaction/__tests/Transaction.test.ts +222 -3
  53. package/src/transaction/index.ts +3 -0
@@ -0,0 +1,485 @@
1
+ import MerklePath from "./MerklePath.js";
2
+ import BeefTx from "./BeefTx.js";
3
+ import { Reader, Writer, toHex, toArray } from "../primitives/utils.js";
4
+ export const BEEF_MAGIC = 4022206465; // 0100BEEF in LE order
5
+ export const BEEF_MAGIC_V2 = 4022206466; // 0200BEEF in LE order
6
+ export const BEEF_MAGIC_TXID_ONLY_EXTENSION = 4022206465; // 0100BEEF in LE order
7
+ /*
8
+ * BEEF standard: BRC-62: Background Evaluation Extended Format (BEEF) Transactions
9
+ * https://github.com/bitcoin-sv/BRCs/blob/master/transactions/0062.md
10
+ *
11
+ * BUMP standard: BRC-74: BSV Unified Merkle Path (BUMP) Format
12
+ * https://github.com/bitcoin-sv/BRCs/blob/master/transactions/0074.md
13
+ *
14
+ * A valid serialized BEEF is the cornerstone of Simplified Payment Validation (SPV)
15
+ * where they are exchanged between two non-trusting parties to establish the
16
+ * validity of a newly constructed bitcoin transaction and its inputs from prior
17
+ * transactions.
18
+ *
19
+ * A `Beef` is fundamentally an list of `BUMP`s and a list of transactions.
20
+ *
21
+ * A `BUMP` is a partial merkle tree for a 'mined' bitcoin block.
22
+ * It can therefore be used to prove the validity of transaction data
23
+ * for each transaction txid whose merkle path is included in the tree.
24
+ *
25
+ * To be valid, the list of transactions must be sorted in dependency order:
26
+ * oldest transaction first;
27
+ * and each transaction must either
28
+ * have a merkle path in one of the BUMPs, or
29
+ * have all of its input transactions included in the list of transactions.
30
+ *
31
+ * The `Beef` class supports the construction of valid BEEFs by allowing BUMPs
32
+ * (merkle paths) and transactions to be merged sequentially.
33
+ *
34
+ * The `Beef` class also extends the standard by supporting 'known' transactions.
35
+ * A 'known' transaction is represented solely by its txid.
36
+ * To become valid, all the 'known' transactions in a `Beef` must be replaced by full
37
+ * transactions and merkle paths, if they are mined.
38
+ *
39
+ * The purpose of supporting 'known' transactions is that one or both parties
40
+ * generating and exchanging BEEFs often possess partial knowledge of valid transactions
41
+ * due to their history.
42
+ *
43
+ * A valid `Beef` is only required when sent to a party with no shared history,
44
+ * such as a transaction processor.
45
+ */
46
+ export class Beef {
47
+ bumps = [];
48
+ txs = [];
49
+ constructor() {
50
+ }
51
+ /**
52
+ * BEEF_MAGIC is the original V1 version.
53
+ * BEEF_MAGIC_V2 includes support for txidOnly transactions in serialized beefs.
54
+ * @returns version based on current contents.
55
+ */
56
+ get version() {
57
+ const hasTxidOnly = !this.txs.every(tx => !tx.isTxidOnly);
58
+ if (hasTxidOnly)
59
+ return BEEF_MAGIC_V2;
60
+ else
61
+ return BEEF_MAGIC;
62
+ }
63
+ /**
64
+ * @param txid of `beefTx` to find
65
+ * @returns `BeefTx` in `txs` with `txid`.
66
+ */
67
+ findTxid(txid) {
68
+ return this.txs.find(tx => tx.txid === txid);
69
+ }
70
+ /**
71
+ * Merge a MerklePath that is assumed to be fully valid.
72
+ * @param bump
73
+ * @returns index of merged bump
74
+ */
75
+ mergeBump(bump) {
76
+ let bumpIndex = undefined;
77
+ // If this proof is identical to another one previously added, we use that first. Otherwise, we try to merge it with proofs from the same block.
78
+ for (let i = 0; i < this.bumps.length; i++) {
79
+ const b = this.bumps[i];
80
+ if (b === bump) { // Literally the same
81
+ return i;
82
+ }
83
+ if (b.blockHeight === bump.blockHeight) {
84
+ // Probably the same...
85
+ const rootA = b.computeRoot();
86
+ const rootB = bump.computeRoot();
87
+ if (rootA === rootB) {
88
+ // Definitely the same... combine them to save space
89
+ b.combine(bump);
90
+ bumpIndex = i;
91
+ break;
92
+ }
93
+ }
94
+ }
95
+ // if the proof is not yet added, add a new path.
96
+ if (bumpIndex === undefined) {
97
+ bumpIndex = this.bumps.length;
98
+ this.bumps.push(bump);
99
+ }
100
+ // review if any transactions are proven by this bump
101
+ const b = this.bumps[bumpIndex];
102
+ for (const tx of this.txs) {
103
+ const txid = tx.txid;
104
+ if (!tx.bumpIndex) {
105
+ for (const n of b.path[0]) {
106
+ if (n.hash === txid) {
107
+ tx.bumpIndex = bumpIndex;
108
+ n.txid = true;
109
+ break;
110
+ }
111
+ }
112
+ }
113
+ }
114
+ return bumpIndex;
115
+ }
116
+ /**
117
+ * Merge a serialized transaction.
118
+ *
119
+ * Checks that a transaction with the same txid hasn't already been merged.
120
+ *
121
+ * Replaces existing transaction with same txid.
122
+ *
123
+ * @param rawTx
124
+ * @param bumpIndex Optional. If a number, must be valid index into bumps array.
125
+ * @returns txid of rawTx
126
+ */
127
+ mergeRawTx(rawTx, bumpIndex) {
128
+ const newTx = new BeefTx(rawTx, bumpIndex);
129
+ this.removeExistingTxid(newTx.txid);
130
+ this.txs.push(newTx);
131
+ this.tryToValidateBumpIndex(newTx);
132
+ return newTx;
133
+ }
134
+ /**
135
+ * Merge a `Transaction` and any referenced `merklePath` and `sourceTransaction`, recursifely.
136
+ *
137
+ * Replaces existing transaction with same txid.
138
+ *
139
+ * Attempts to match an existing bump to the new transaction.
140
+ *
141
+ * @param tx
142
+ * @returns txid of tx
143
+ */
144
+ mergeTransaction(tx) {
145
+ const txid = tx.id('hex');
146
+ this.removeExistingTxid(txid);
147
+ let bumpIndex = undefined;
148
+ if (tx.merklePath)
149
+ bumpIndex = this.mergeBump(tx.merklePath);
150
+ const newTx = new BeefTx(tx, bumpIndex);
151
+ this.txs.push(newTx);
152
+ this.tryToValidateBumpIndex(newTx);
153
+ bumpIndex = newTx.bumpIndex;
154
+ if (bumpIndex === undefined) {
155
+ for (const input of tx.inputs) {
156
+ if (input.sourceTransaction)
157
+ this.mergeTransaction(input.sourceTransaction);
158
+ }
159
+ }
160
+ return newTx;
161
+ }
162
+ /**
163
+ * Removes an existing transaction from the BEEF, given its TXID
164
+ * @param txid TXID of the transaction to remove
165
+ */
166
+ removeExistingTxid(txid) {
167
+ const existingTxIndex = this.txs.findIndex(t => t.txid === txid);
168
+ if (existingTxIndex >= 0)
169
+ this.txs.splice(existingTxIndex, 1);
170
+ }
171
+ mergeTxidOnly(txid) {
172
+ let tx = this.txs.find(t => t.txid === txid);
173
+ if (!tx) {
174
+ tx = new BeefTx(txid);
175
+ this.txs.push(tx);
176
+ this.tryToValidateBumpIndex(tx);
177
+ }
178
+ return tx;
179
+ }
180
+ mergeBeefTx(btx) {
181
+ let beefTx = this.findTxid(btx.txid);
182
+ if (!beefTx && btx.isTxidOnly)
183
+ beefTx = this.mergeTxidOnly(btx.txid);
184
+ else if (!beefTx || beefTx.isTxidOnly) {
185
+ if (btx._tx)
186
+ beefTx = this.mergeTransaction(btx._tx);
187
+ else
188
+ beefTx = this.mergeRawTx(btx._rawTx);
189
+ }
190
+ return beefTx;
191
+ }
192
+ mergeBeef(beef) {
193
+ const b = Array.isArray(beef) ? Beef.fromBinary(beef) : beef;
194
+ for (const bump of b.bumps)
195
+ this.mergeBump(bump);
196
+ for (const tx of b.txs)
197
+ this.mergeBeefTx(tx);
198
+ }
199
+ /**
200
+ * Sorts `txs` and checks structural validity of beef.
201
+ *
202
+ * Does NOT verify merkle roots.
203
+ *
204
+ * Validity requirements:
205
+ * 1. No 'known' txids, unless `allowTxidOnly` is true.
206
+ * 2. All transactions have bumps or their inputs chain back to bumps (or are known).
207
+ * 3. Order of transactions satisfies dependencies before dependents.
208
+ * 4. No transactions with duplicate txids.
209
+ *
210
+ * @param allowTxidOnly optional. If true, transaction txid only is assumed valid
211
+ */
212
+ isValid(allowTxidOnly) {
213
+ return this.verifyValid(allowTxidOnly).valid;
214
+ }
215
+ /**
216
+ * Sorts `txs` and confirms validity of transaction data contained in beef
217
+ * by validating structure of this beef and confirming computed merkle roots
218
+ * using `chainTracker`.
219
+ *
220
+ * Validity requirements:
221
+ * 1. No 'known' txids, unless `allowTxidOnly` is true.
222
+ * 2. All transactions have bumps or their inputs chain back to bumps (or are known).
223
+ * 3. Order of transactions satisfies dependencies before dependents.
224
+ * 4. No transactions with duplicate txids.
225
+ *
226
+ * @param chainTracker Used to verify computed merkle path roots for all bump txids.
227
+ * @param allowTxidOnly optional. If true, transaction txid is assumed valid
228
+ */
229
+ async verify(chainTracker, allowTxidOnly) {
230
+ const r = this.verifyValid(allowTxidOnly);
231
+ if (!r.valid)
232
+ return false;
233
+ for (const height of Object.keys(r.roots)) {
234
+ const isValid = await chainTracker.isValidRootForHeight(r.roots[height], Number(height));
235
+ if (!isValid)
236
+ return false;
237
+ }
238
+ return true;
239
+ }
240
+ verifyValid(allowTxidOnly) {
241
+ const r = { valid: false, roots: {} };
242
+ this.sortTxs();
243
+ // valid txids: only txids if allowed, bump txids, then txids with input's in txids
244
+ const txids = {};
245
+ for (const tx of this.txs) {
246
+ if (tx.isTxidOnly) {
247
+ if (!allowTxidOnly)
248
+ return r;
249
+ txids[tx.txid] = true;
250
+ }
251
+ }
252
+ const confirmComputedRoot = (b, txid) => {
253
+ const root = b.computeRoot(txid);
254
+ if (!r.roots[b.blockHeight]) {
255
+ // accept the root as valid for this block and reuse for subsequent txids
256
+ r.roots[b.blockHeight] = root;
257
+ }
258
+ if (r.roots[b.blockHeight] !== root)
259
+ return false;
260
+ return true;
261
+ };
262
+ for (const b of this.bumps) {
263
+ for (const n of b.path[0]) {
264
+ if (n.txid && n.hash) {
265
+ txids[n.hash] = true;
266
+ // all txid hashes in all bumps must have agree on computed merkle path roots
267
+ if (!confirmComputedRoot(b, n.hash))
268
+ return r;
269
+ }
270
+ }
271
+ }
272
+ for (const t of this.txs) {
273
+ for (const i of t.inputTxids)
274
+ // all input txids must be included before they are referenced
275
+ if (!txids[i])
276
+ return r;
277
+ txids[t.txid] = true;
278
+ }
279
+ r.valid = true;
280
+ return r;
281
+ }
282
+ /**
283
+ * Returns a binary array representing the serialized BEEF
284
+ * @returns A binary array representing the BEEF
285
+ */
286
+ toBinary() {
287
+ const writer = new Writer();
288
+ writer.writeUInt32LE(this.version);
289
+ writer.writeVarIntNum(this.bumps.length);
290
+ for (const b of this.bumps) {
291
+ writer.write(b.toBinary());
292
+ }
293
+ writer.writeVarIntNum(this.txs.length);
294
+ for (const tx of this.txs) {
295
+ tx.toWriter(writer);
296
+ }
297
+ return writer.toArray();
298
+ }
299
+ /**
300
+ * Returns a hex string representing the serialized BEEF
301
+ * @returns A hex string representing the BEEF
302
+ */
303
+ toHex() {
304
+ return toHex(this.toBinary());
305
+ }
306
+ static fromReader(br) {
307
+ const version = br.readUInt32LE();
308
+ if (version !== BEEF_MAGIC && version !== BEEF_MAGIC_V2)
309
+ throw new Error(`Serialized BEEF must start with ${BEEF_MAGIC} or ${BEEF_MAGIC_V2} but starts with ${version}`);
310
+ const beef = new Beef();
311
+ const bumpsLength = br.readVarIntNum();
312
+ for (let i = 0; i < bumpsLength; i++) {
313
+ const bump = MerklePath.fromReader(br);
314
+ beef.bumps.push(bump);
315
+ }
316
+ const txsLength = br.readVarIntNum();
317
+ for (let i = 0; i < txsLength; i++) {
318
+ const beefTx = BeefTx.fromReader(br);
319
+ beef.txs.push(beefTx);
320
+ }
321
+ return beef;
322
+ }
323
+ /**
324
+ * Constructs an instance of the Beef class based on the provided binary array
325
+ * @param bin The binary array from which to construct BEEF
326
+ * @returns An instance of the Beef class constructed from the binary data
327
+ */
328
+ static fromBinary(bin) {
329
+ const br = new Reader(bin);
330
+ return Beef.fromReader(br);
331
+ }
332
+ /**
333
+ * Constructs an instance of the Beef class based on the provided string
334
+ * @param s The string value from which to construct BEEF
335
+ * @param enc The encoding of the string value from which BEEF should be constructed
336
+ * @returns An instance of the Beef class constructed from the string
337
+ */
338
+ static fromString(s, enc) {
339
+ enc ||= 'hex';
340
+ const bin = toArray(s, enc);
341
+ const br = new Reader(bin);
342
+ return Beef.fromReader(br);
343
+ }
344
+ /**
345
+ * Try to validate newTx.bumpIndex by looking for an existing bump
346
+ * that proves newTx.txid
347
+ *
348
+ * @param newTx A new `BeefTx` that has been added to this.txs
349
+ * @returns true if a bump was found, false otherwise
350
+ */
351
+ tryToValidateBumpIndex(newTx) {
352
+ if (newTx.bumpIndex !== undefined)
353
+ return true;
354
+ const txid = newTx.txid;
355
+ for (let i = 0; i < this.bumps.length; i++) {
356
+ const j = this.bumps[i].path[0].findIndex(b => b.hash === txid);
357
+ if (j >= 0) {
358
+ newTx.bumpIndex = i;
359
+ this.bumps[i].path[0][j].txid = true;
360
+ return true;
361
+ }
362
+ }
363
+ return false;
364
+ }
365
+ /**
366
+ * Sort the `txs` by input txid dependency order.
367
+ * @returns array of input txids of unproven transactions that aren't included in txs.
368
+ */
369
+ sortTxs() {
370
+ const missingInputs = {};
371
+ const txidToTx = {};
372
+ for (const tx of this.txs) {
373
+ txidToTx[tx.txid] = tx;
374
+ // All transactions in this beef start at degree zero.
375
+ tx.degree = 0;
376
+ }
377
+ for (const tx of this.txs) {
378
+ if (tx.bumpIndex === undefined) {
379
+ // For all the unproven transactions,
380
+ // link their inputs that exist in this beef,
381
+ // make a note of missing inputs.
382
+ for (const inputTxid of tx.inputTxids) {
383
+ if (!txidToTx[inputTxid])
384
+ missingInputs[inputTxid] = true;
385
+ }
386
+ }
387
+ }
388
+ // queue of transactions that no unsorted transactions depend upon...
389
+ const queue = [];
390
+ // sorted transactions
391
+ const result = [];
392
+ // Increment each txid's degree for every input reference to it by another txid
393
+ for (const tx of this.txs) {
394
+ for (const inputTxid of tx.inputTxids) {
395
+ const tx = txidToTx[inputTxid];
396
+ if (tx)
397
+ tx.degree++;
398
+ }
399
+ }
400
+ // Since circular dependencies aren't possible, start with the txids no one depends on.
401
+ // These are the transactions that should be sent last...
402
+ for (const tx of this.txs) {
403
+ if (tx.degree === 0) {
404
+ queue.push(tx);
405
+ }
406
+ }
407
+ // As long as we have transactions to send...
408
+ while (queue.length) {
409
+ let tx = queue.shift();
410
+ // Add it as new first to send
411
+ result.unshift(tx);
412
+ // And remove its impact on degree
413
+ // noting that any tx achieving a
414
+ // value of zero can be sent...
415
+ for (const inputTxid of tx.inputTxids) {
416
+ const inputTx = txidToTx[inputTxid];
417
+ if (inputTx) {
418
+ inputTx.degree--;
419
+ if (inputTx.degree === 0) {
420
+ queue.push(inputTx);
421
+ }
422
+ }
423
+ }
424
+ }
425
+ this.txs = result;
426
+ return Object.keys(missingInputs);
427
+ }
428
+ /**
429
+ * @returns a shallow copy of this beef
430
+ */
431
+ clone() {
432
+ const c = new Beef();
433
+ c.bumps = Array.from(this.bumps);
434
+ c.txs = Array.from(this.txs);
435
+ return c;
436
+ }
437
+ /**
438
+ * Ensure that all the txids in `knownTxids` are txidOnly
439
+ * @param knownTxids
440
+ */
441
+ trimKnownTxids(knownTxids) {
442
+ for (let i = 0; i < this.txs.length;) {
443
+ const tx = this.txs[i];
444
+ if (tx.isTxidOnly && -1 < knownTxids.indexOf(tx.txid)) {
445
+ this.txs.splice(i, 1);
446
+ }
447
+ else {
448
+ i++;
449
+ }
450
+ }
451
+ // TODO: bumps could be trimmed to eliminate unreferenced proofs.
452
+ }
453
+ /**
454
+ * @returns Summary of `Beef` contents as multi-line string.
455
+ */
456
+ toLogString() {
457
+ let log = '';
458
+ log += `BEEF with ${this.bumps.length} BUMPS and ${this.txs.length} Transactions, isValid ${this.isValid()}\n`;
459
+ let i = -1;
460
+ for (const b of this.bumps) {
461
+ i++;
462
+ log += ` BUMP ${i}\n block: ${b.blockHeight}\n txids: [\n${b.path[0].filter(n => !!n.txid).map(n => ` '${n.hash}'`).join(',\n')}\n ]\n`;
463
+ }
464
+ i = -1;
465
+ for (const t of this.txs) {
466
+ i++;
467
+ log += ` TX ${i}\n txid: ${t.txid}\n`;
468
+ if (t.bumpIndex !== undefined) {
469
+ log += ` bumpIndex: ${t.bumpIndex}\n`;
470
+ }
471
+ if (t.isTxidOnly) {
472
+ log += ` txidOnly\n`;
473
+ }
474
+ else {
475
+ log += ` rawTx length=${t.rawTx.length}\n`;
476
+ }
477
+ if (t.inputTxids.length > 0) {
478
+ log += ` inputs: [\n${t.inputTxids.map(it => ` '${it}'`).join(',\n')}\n ]\n`;
479
+ }
480
+ }
481
+ return log;
482
+ }
483
+ }
484
+ export default Beef;
485
+ //# sourceMappingURL=Beef.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Beef.js","sourceRoot":"","sources":["../../../../src/transaction/Beef.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ import { Beef } from "./Beef.js";
2
+ /**
3
+ * Extends `Beef` that is used to exchange transaction validity data with more than one external party.
4
+ *
5
+ * Use `addKnownTxidsForParty` to keep track of who knows what to reduce re-transmission of potentially large transactions.
6
+ *
7
+ * Use `getTrimmedBeefForParty` to obtain a `Beef` trimmed of transaction validity data known to a specific party.
8
+ *
9
+ * Typical usage scenario:
10
+ *
11
+ * 1. Query a wallet storage provider for spendable outputs.
12
+ * 2. The provider replies with a Beef validating the returned outputs.
13
+ * 3. Construct a new transaction using some of the queried outputs as inputs, including Beef validating all the inputs.
14
+ * 4. Receive new valid raw transaction after processing and Beef validating change outputs added to original inputs.
15
+ * 5. Return to step 1, continuing to build on old and new spendable outputs.
16
+ *
17
+ * By default, each Beef is required to be complete and valid: All transactions appear as full serialized bitcoin transactions and
18
+ * each transaction either has a merkle path proof (it has been mined) or all of its input transactions are included.
19
+ *
20
+ * The size and redundancy of these Beefs becomes a problem when chained transaction creation out-paces the block mining rate.
21
+ *
22
+ */
23
+ export class BeefParty extends Beef {
24
+ /**
25
+ * keys are party identifiers.
26
+ * values are records of txids with truthy value for which the party already has validity proof.
27
+ */
28
+ knownTo = {};
29
+ /**
30
+ *
31
+ * @param parties Optional array of initial unique party identifiers.
32
+ */
33
+ constructor(parties) {
34
+ super();
35
+ if (parties) {
36
+ for (const party of parties)
37
+ this.addParty(party);
38
+ }
39
+ }
40
+ /**
41
+ * @param party
42
+ * @returns `true` if `party` has already beed added to this `BeefParty`.
43
+ */
44
+ isParty(party) {
45
+ const r = Object.keys(this.knownTo).includes(party);
46
+ return r;
47
+ }
48
+ /**
49
+ * Adds a new unique party identifier to this `BeefParty`.
50
+ * @param party
51
+ */
52
+ addParty(party) {
53
+ if (this.isParty(party))
54
+ throw new Error(`Party ${party} already exists.`);
55
+ this.knownTo[party] = {};
56
+ }
57
+ /**
58
+ * @param party
59
+ * @returns Array of txids "known" to `party`.
60
+ */
61
+ getKnownTxidsForParty(party) {
62
+ const knownTxids = this.knownTo[party];
63
+ if (!knownTxids)
64
+ throw new Error(`Party ${party} is unknown.`);
65
+ return Object.keys(knownTxids);
66
+ }
67
+ /**
68
+ * @param party
69
+ * @returns trimmed beef of unknown transactions and proofs for `party`
70
+ */
71
+ getTrimmedBeefForParty(party) {
72
+ const knownTxids = this.getKnownTxidsForParty(party);
73
+ const prunedBeef = this.clone();
74
+ prunedBeef.trimKnownTxids(knownTxids);
75
+ return prunedBeef;
76
+ }
77
+ /**
78
+ * Make note of additional txids "known" to `party`.
79
+ * @param party unique identifier, added if new.
80
+ * @param knownTxids
81
+ */
82
+ addKnownTxidsForParty(party, knownTxids) {
83
+ if (!this.isParty(party))
84
+ this.addParty(party);
85
+ const kts = this.knownTo[party];
86
+ for (const txid of knownTxids) {
87
+ kts[txid] = true;
88
+ this.mergeTxidOnly(txid);
89
+ }
90
+ }
91
+ }
92
+ export default BeefParty;
93
+ //# sourceMappingURL=BeefParty.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BeefParty.js","sourceRoot":"","sources":["../../../../src/transaction/BeefParty.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,SAAU,SAAQ,IAAI;IAC/B;;;OAGG;IACH,OAAO,GAA4C,EAAE,CAAA;IAErD;;;OAGG;IACH,YAAY,OAAkB;QAC1B,KAAK,EAAE,CAAA;QACP,IAAI,OAAO,EAAE,CAAC;YACV,KAAK,MAAM,KAAK,IAAI,OAAO;gBACvB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,KAAa;QACjB,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACnD,OAAO,CAAC,CAAA;IACZ,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAa;QAClB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,kBAAkB,CAAC,CAAA;QACrD,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAA;IAC5B,CAAC;IAED;;;OAGG;IACH,qBAAqB,CAAC,KAAa;QAC/B,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACtC,IAAI,CAAC,UAAU;YACX,MAAM,IAAI,KAAK,CAAC,SAAS,KAAK,cAAc,CAAC,CAAA;QACjD,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAClC,CAAC;IAED;;;OAGG;IACH,sBAAsB,CAAC,KAAa;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAA;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QAC/B,UAAU,CAAC,cAAc,CAAC,UAAU,CAAC,CAAA;QACrC,OAAO,UAAU,CAAA;IACrB,CAAC;IAED;;;;OAIG;IACH,qBAAqB,CAAC,KAAa,EAAE,UAAoB;QACrD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YACpB,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC/B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC5B,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;YAChB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QAC5B,CAAC;IACL,CAAC;CACJ;AAED,eAAe,SAAS,CAAA"}