@bsv/sdk 1.1.23 → 1.1.25
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.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/primitives/Curve.js +7 -7
- package/dist/cjs/src/primitives/Curve.js.map +1 -1
- package/dist/cjs/src/primitives/ECDSA.js +394 -71
- package/dist/cjs/src/primitives/ECDSA.js.map +1 -1
- package/dist/cjs/src/primitives/Point.js +103 -23
- package/dist/cjs/src/primitives/Point.js.map +1 -1
- package/dist/cjs/src/primitives/TransactionSignature.js +4 -3
- package/dist/cjs/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +14 -15
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/script/Spend.js +4 -4
- package/dist/cjs/src/script/Spend.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +1 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +492 -0
- package/dist/cjs/src/transaction/Beef.js.map +1 -0
- package/dist/cjs/src/transaction/BeefParty.js +97 -0
- package/dist/cjs/src/transaction/BeefParty.js.map +1 -0
- package/dist/cjs/src/transaction/BeefTx.js +123 -0
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -0
- package/dist/cjs/src/transaction/Transaction.js +81 -66
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/index.js +7 -1
- package/dist/cjs/src/transaction/index.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/Curve.js +7 -7
- package/dist/esm/src/primitives/Curve.js.map +1 -1
- package/dist/esm/src/primitives/ECDSA.js +394 -71
- package/dist/esm/src/primitives/ECDSA.js.map +1 -1
- package/dist/esm/src/primitives/Point.js +103 -23
- package/dist/esm/src/primitives/Point.js.map +1 -1
- package/dist/esm/src/primitives/TransactionSignature.js +4 -3
- package/dist/esm/src/primitives/TransactionSignature.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +14 -15
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/script/Spend.js +4 -4
- package/dist/esm/src/script/Spend.js.map +1 -1
- package/dist/esm/src/totp/totp.js +1 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +485 -0
- package/dist/esm/src/transaction/Beef.js.map +1 -0
- package/dist/esm/src/transaction/BeefParty.js +93 -0
- package/dist/esm/src/transaction/BeefParty.js.map +1 -0
- package/dist/esm/src/transaction/BeefTx.js +121 -0
- package/dist/esm/src/transaction/BeefTx.js.map +1 -0
- package/dist/esm/src/transaction/Transaction.js +81 -66
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/index.js +3 -0
- package/dist/esm/src/transaction/index.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/ECDSA.d.ts.map +1 -1
- package/dist/types/src/primitives/Point.d.ts +5 -0
- package/dist/types/src/primitives/Point.d.ts.map +1 -1
- package/dist/types/src/primitives/TransactionSignature.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +143 -0
- package/dist/types/src/transaction/Beef.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefParty.d.ts +62 -0
- package/dist/types/src/transaction/BeefParty.d.ts.map +1 -0
- package/dist/types/src/transaction/BeefTx.d.ts +35 -0
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -0
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts +1 -1
- package/dist/types/src/transaction/TransactionInput.d.ts.map +1 -1
- package/dist/types/src/transaction/index.d.ts +3 -0
- package/dist/types/src/transaction/index.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/primitives.md +373 -55
- package/docs/transaction.md +467 -1
- package/package.json +1 -1
- package/src/primitives/Curve.ts +7 -7
- package/src/primitives/ECDSA.ts +485 -75
- package/src/primitives/Point.ts +110 -25
- package/src/primitives/TransactionSignature.ts +4 -3
- package/src/primitives/utils.ts +15 -11
- package/src/script/Spend.ts +4 -4
- package/src/totp/totp.ts +1 -1
- package/src/transaction/Beef.ts +533 -0
- package/src/transaction/BeefParty.ts +100 -0
- package/src/transaction/BeefTx.ts +121 -0
- package/src/transaction/Transaction.ts +95 -69
- package/src/transaction/TransactionInput.ts +1 -1
- package/src/transaction/__tests/Beef.test.ts +290 -0
- package/src/transaction/__tests/Transaction.benchmarks.test.ts +222 -0
- package/src/transaction/index.ts +3 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Beef = exports.BEEF_MAGIC_TXID_ONLY_EXTENSION = exports.BEEF_MAGIC_V2 = exports.BEEF_MAGIC = void 0;
|
|
7
|
+
const MerklePath_js_1 = __importDefault(require("./MerklePath.js"));
|
|
8
|
+
const BeefTx_js_1 = __importDefault(require("./BeefTx.js"));
|
|
9
|
+
const utils_js_1 = require("../primitives/utils.js");
|
|
10
|
+
exports.BEEF_MAGIC = 4022206465; // 0100BEEF in LE order
|
|
11
|
+
exports.BEEF_MAGIC_V2 = 4022206466; // 0200BEEF in LE order
|
|
12
|
+
exports.BEEF_MAGIC_TXID_ONLY_EXTENSION = 4022206465; // 0100BEEF in LE order
|
|
13
|
+
/*
|
|
14
|
+
* BEEF standard: BRC-62: Background Evaluation Extended Format (BEEF) Transactions
|
|
15
|
+
* https://github.com/bitcoin-sv/BRCs/blob/master/transactions/0062.md
|
|
16
|
+
*
|
|
17
|
+
* BUMP standard: BRC-74: BSV Unified Merkle Path (BUMP) Format
|
|
18
|
+
* https://github.com/bitcoin-sv/BRCs/blob/master/transactions/0074.md
|
|
19
|
+
*
|
|
20
|
+
* A valid serialized BEEF is the cornerstone of Simplified Payment Validation (SPV)
|
|
21
|
+
* where they are exchanged between two non-trusting parties to establish the
|
|
22
|
+
* validity of a newly constructed bitcoin transaction and its inputs from prior
|
|
23
|
+
* transactions.
|
|
24
|
+
*
|
|
25
|
+
* A `Beef` is fundamentally an list of `BUMP`s and a list of transactions.
|
|
26
|
+
*
|
|
27
|
+
* A `BUMP` is a partial merkle tree for a 'mined' bitcoin block.
|
|
28
|
+
* It can therefore be used to prove the validity of transaction data
|
|
29
|
+
* for each transaction txid whose merkle path is included in the tree.
|
|
30
|
+
*
|
|
31
|
+
* To be valid, the list of transactions must be sorted in dependency order:
|
|
32
|
+
* oldest transaction first;
|
|
33
|
+
* and each transaction must either
|
|
34
|
+
* have a merkle path in one of the BUMPs, or
|
|
35
|
+
* have all of its input transactions included in the list of transactions.
|
|
36
|
+
*
|
|
37
|
+
* The `Beef` class supports the construction of valid BEEFs by allowing BUMPs
|
|
38
|
+
* (merkle paths) and transactions to be merged sequentially.
|
|
39
|
+
*
|
|
40
|
+
* The `Beef` class also extends the standard by supporting 'known' transactions.
|
|
41
|
+
* A 'known' transaction is represented solely by its txid.
|
|
42
|
+
* To become valid, all the 'known' transactions in a `Beef` must be replaced by full
|
|
43
|
+
* transactions and merkle paths, if they are mined.
|
|
44
|
+
*
|
|
45
|
+
* The purpose of supporting 'known' transactions is that one or both parties
|
|
46
|
+
* generating and exchanging BEEFs often possess partial knowledge of valid transactions
|
|
47
|
+
* due to their history.
|
|
48
|
+
*
|
|
49
|
+
* A valid `Beef` is only required when sent to a party with no shared history,
|
|
50
|
+
* such as a transaction processor.
|
|
51
|
+
*/
|
|
52
|
+
class Beef {
|
|
53
|
+
constructor() {
|
|
54
|
+
this.bumps = [];
|
|
55
|
+
this.txs = [];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* BEEF_MAGIC is the original V1 version.
|
|
59
|
+
* BEEF_MAGIC_V2 includes support for txidOnly transactions in serialized beefs.
|
|
60
|
+
* @returns version based on current contents.
|
|
61
|
+
*/
|
|
62
|
+
get version() {
|
|
63
|
+
const hasTxidOnly = !this.txs.every(tx => !tx.isTxidOnly);
|
|
64
|
+
if (hasTxidOnly)
|
|
65
|
+
return exports.BEEF_MAGIC_V2;
|
|
66
|
+
else
|
|
67
|
+
return exports.BEEF_MAGIC;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* @param txid of `beefTx` to find
|
|
71
|
+
* @returns `BeefTx` in `txs` with `txid`.
|
|
72
|
+
*/
|
|
73
|
+
findTxid(txid) {
|
|
74
|
+
return this.txs.find(tx => tx.txid === txid);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Merge a MerklePath that is assumed to be fully valid.
|
|
78
|
+
* @param bump
|
|
79
|
+
* @returns index of merged bump
|
|
80
|
+
*/
|
|
81
|
+
mergeBump(bump) {
|
|
82
|
+
let bumpIndex = undefined;
|
|
83
|
+
// 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.
|
|
84
|
+
for (let i = 0; i < this.bumps.length; i++) {
|
|
85
|
+
const b = this.bumps[i];
|
|
86
|
+
if (b === bump) { // Literally the same
|
|
87
|
+
return i;
|
|
88
|
+
}
|
|
89
|
+
if (b.blockHeight === bump.blockHeight) {
|
|
90
|
+
// Probably the same...
|
|
91
|
+
const rootA = b.computeRoot();
|
|
92
|
+
const rootB = bump.computeRoot();
|
|
93
|
+
if (rootA === rootB) {
|
|
94
|
+
// Definitely the same... combine them to save space
|
|
95
|
+
b.combine(bump);
|
|
96
|
+
bumpIndex = i;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// if the proof is not yet added, add a new path.
|
|
102
|
+
if (bumpIndex === undefined) {
|
|
103
|
+
bumpIndex = this.bumps.length;
|
|
104
|
+
this.bumps.push(bump);
|
|
105
|
+
}
|
|
106
|
+
// review if any transactions are proven by this bump
|
|
107
|
+
const b = this.bumps[bumpIndex];
|
|
108
|
+
for (const tx of this.txs) {
|
|
109
|
+
const txid = tx.txid;
|
|
110
|
+
if (!tx.bumpIndex) {
|
|
111
|
+
for (const n of b.path[0]) {
|
|
112
|
+
if (n.hash === txid) {
|
|
113
|
+
tx.bumpIndex = bumpIndex;
|
|
114
|
+
n.txid = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return bumpIndex;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Merge a serialized transaction.
|
|
124
|
+
*
|
|
125
|
+
* Checks that a transaction with the same txid hasn't already been merged.
|
|
126
|
+
*
|
|
127
|
+
* Replaces existing transaction with same txid.
|
|
128
|
+
*
|
|
129
|
+
* @param rawTx
|
|
130
|
+
* @param bumpIndex Optional. If a number, must be valid index into bumps array.
|
|
131
|
+
* @returns txid of rawTx
|
|
132
|
+
*/
|
|
133
|
+
mergeRawTx(rawTx, bumpIndex) {
|
|
134
|
+
const newTx = new BeefTx_js_1.default(rawTx, bumpIndex);
|
|
135
|
+
this.removeExistingTxid(newTx.txid);
|
|
136
|
+
this.txs.push(newTx);
|
|
137
|
+
this.tryToValidateBumpIndex(newTx);
|
|
138
|
+
return newTx;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Merge a `Transaction` and any referenced `merklePath` and `sourceTransaction`, recursifely.
|
|
142
|
+
*
|
|
143
|
+
* Replaces existing transaction with same txid.
|
|
144
|
+
*
|
|
145
|
+
* Attempts to match an existing bump to the new transaction.
|
|
146
|
+
*
|
|
147
|
+
* @param tx
|
|
148
|
+
* @returns txid of tx
|
|
149
|
+
*/
|
|
150
|
+
mergeTransaction(tx) {
|
|
151
|
+
const txid = tx.id('hex');
|
|
152
|
+
this.removeExistingTxid(txid);
|
|
153
|
+
let bumpIndex = undefined;
|
|
154
|
+
if (tx.merklePath)
|
|
155
|
+
bumpIndex = this.mergeBump(tx.merklePath);
|
|
156
|
+
const newTx = new BeefTx_js_1.default(tx, bumpIndex);
|
|
157
|
+
this.txs.push(newTx);
|
|
158
|
+
this.tryToValidateBumpIndex(newTx);
|
|
159
|
+
bumpIndex = newTx.bumpIndex;
|
|
160
|
+
if (bumpIndex === undefined) {
|
|
161
|
+
for (const input of tx.inputs) {
|
|
162
|
+
if (input.sourceTransaction)
|
|
163
|
+
this.mergeTransaction(input.sourceTransaction);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return newTx;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Removes an existing transaction from the BEEF, given its TXID
|
|
170
|
+
* @param txid TXID of the transaction to remove
|
|
171
|
+
*/
|
|
172
|
+
removeExistingTxid(txid) {
|
|
173
|
+
const existingTxIndex = this.txs.findIndex(t => t.txid === txid);
|
|
174
|
+
if (existingTxIndex >= 0)
|
|
175
|
+
this.txs.splice(existingTxIndex, 1);
|
|
176
|
+
}
|
|
177
|
+
mergeTxidOnly(txid) {
|
|
178
|
+
let tx = this.txs.find(t => t.txid === txid);
|
|
179
|
+
if (!tx) {
|
|
180
|
+
tx = new BeefTx_js_1.default(txid);
|
|
181
|
+
this.txs.push(tx);
|
|
182
|
+
this.tryToValidateBumpIndex(tx);
|
|
183
|
+
}
|
|
184
|
+
return tx;
|
|
185
|
+
}
|
|
186
|
+
mergeBeefTx(btx) {
|
|
187
|
+
let beefTx = this.findTxid(btx.txid);
|
|
188
|
+
if (!beefTx && btx.isTxidOnly)
|
|
189
|
+
beefTx = this.mergeTxidOnly(btx.txid);
|
|
190
|
+
else if (!beefTx || beefTx.isTxidOnly) {
|
|
191
|
+
if (btx._tx)
|
|
192
|
+
beefTx = this.mergeTransaction(btx._tx);
|
|
193
|
+
else
|
|
194
|
+
beefTx = this.mergeRawTx(btx._rawTx);
|
|
195
|
+
}
|
|
196
|
+
return beefTx;
|
|
197
|
+
}
|
|
198
|
+
mergeBeef(beef) {
|
|
199
|
+
const b = Array.isArray(beef) ? Beef.fromBinary(beef) : beef;
|
|
200
|
+
for (const bump of b.bumps)
|
|
201
|
+
this.mergeBump(bump);
|
|
202
|
+
for (const tx of b.txs)
|
|
203
|
+
this.mergeBeefTx(tx);
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Sorts `txs` and checks structural validity of beef.
|
|
207
|
+
*
|
|
208
|
+
* Does NOT verify merkle roots.
|
|
209
|
+
*
|
|
210
|
+
* Validity requirements:
|
|
211
|
+
* 1. No 'known' txids, unless `allowTxidOnly` is true.
|
|
212
|
+
* 2. All transactions have bumps or their inputs chain back to bumps (or are known).
|
|
213
|
+
* 3. Order of transactions satisfies dependencies before dependents.
|
|
214
|
+
* 4. No transactions with duplicate txids.
|
|
215
|
+
*
|
|
216
|
+
* @param allowTxidOnly optional. If true, transaction txid only is assumed valid
|
|
217
|
+
*/
|
|
218
|
+
isValid(allowTxidOnly) {
|
|
219
|
+
return this.verifyValid(allowTxidOnly).valid;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Sorts `txs` and confirms validity of transaction data contained in beef
|
|
223
|
+
* by validating structure of this beef and confirming computed merkle roots
|
|
224
|
+
* using `chainTracker`.
|
|
225
|
+
*
|
|
226
|
+
* Validity requirements:
|
|
227
|
+
* 1. No 'known' txids, unless `allowTxidOnly` is true.
|
|
228
|
+
* 2. All transactions have bumps or their inputs chain back to bumps (or are known).
|
|
229
|
+
* 3. Order of transactions satisfies dependencies before dependents.
|
|
230
|
+
* 4. No transactions with duplicate txids.
|
|
231
|
+
*
|
|
232
|
+
* @param chainTracker Used to verify computed merkle path roots for all bump txids.
|
|
233
|
+
* @param allowTxidOnly optional. If true, transaction txid is assumed valid
|
|
234
|
+
*/
|
|
235
|
+
async verify(chainTracker, allowTxidOnly) {
|
|
236
|
+
const r = this.verifyValid(allowTxidOnly);
|
|
237
|
+
if (!r.valid)
|
|
238
|
+
return false;
|
|
239
|
+
for (const height of Object.keys(r.roots)) {
|
|
240
|
+
const isValid = await chainTracker.isValidRootForHeight(r.roots[height], Number(height));
|
|
241
|
+
if (!isValid)
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
verifyValid(allowTxidOnly) {
|
|
247
|
+
const r = { valid: false, roots: {} };
|
|
248
|
+
this.sortTxs();
|
|
249
|
+
// valid txids: only txids if allowed, bump txids, then txids with input's in txids
|
|
250
|
+
const txids = {};
|
|
251
|
+
for (const tx of this.txs) {
|
|
252
|
+
if (tx.isTxidOnly) {
|
|
253
|
+
if (!allowTxidOnly)
|
|
254
|
+
return r;
|
|
255
|
+
txids[tx.txid] = true;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const confirmComputedRoot = (b, txid) => {
|
|
259
|
+
const root = b.computeRoot(txid);
|
|
260
|
+
if (!r.roots[b.blockHeight]) {
|
|
261
|
+
// accept the root as valid for this block and reuse for subsequent txids
|
|
262
|
+
r.roots[b.blockHeight] = root;
|
|
263
|
+
}
|
|
264
|
+
if (r.roots[b.blockHeight] !== root)
|
|
265
|
+
return false;
|
|
266
|
+
return true;
|
|
267
|
+
};
|
|
268
|
+
for (const b of this.bumps) {
|
|
269
|
+
for (const n of b.path[0]) {
|
|
270
|
+
if (n.txid && n.hash) {
|
|
271
|
+
txids[n.hash] = true;
|
|
272
|
+
// all txid hashes in all bumps must have agree on computed merkle path roots
|
|
273
|
+
if (!confirmComputedRoot(b, n.hash))
|
|
274
|
+
return r;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
for (const t of this.txs) {
|
|
279
|
+
for (const i of t.inputTxids)
|
|
280
|
+
// all input txids must be included before they are referenced
|
|
281
|
+
if (!txids[i])
|
|
282
|
+
return r;
|
|
283
|
+
txids[t.txid] = true;
|
|
284
|
+
}
|
|
285
|
+
r.valid = true;
|
|
286
|
+
return r;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Returns a binary array representing the serialized BEEF
|
|
290
|
+
* @returns A binary array representing the BEEF
|
|
291
|
+
*/
|
|
292
|
+
toBinary() {
|
|
293
|
+
const writer = new utils_js_1.Writer();
|
|
294
|
+
writer.writeUInt32LE(this.version);
|
|
295
|
+
writer.writeVarIntNum(this.bumps.length);
|
|
296
|
+
for (const b of this.bumps) {
|
|
297
|
+
writer.write(b.toBinary());
|
|
298
|
+
}
|
|
299
|
+
writer.writeVarIntNum(this.txs.length);
|
|
300
|
+
for (const tx of this.txs) {
|
|
301
|
+
tx.toWriter(writer);
|
|
302
|
+
}
|
|
303
|
+
return writer.toArray();
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Returns a hex string representing the serialized BEEF
|
|
307
|
+
* @returns A hex string representing the BEEF
|
|
308
|
+
*/
|
|
309
|
+
toHex() {
|
|
310
|
+
return (0, utils_js_1.toHex)(this.toBinary());
|
|
311
|
+
}
|
|
312
|
+
static fromReader(br) {
|
|
313
|
+
const version = br.readUInt32LE();
|
|
314
|
+
if (version !== exports.BEEF_MAGIC && version !== exports.BEEF_MAGIC_V2)
|
|
315
|
+
throw new Error(`Serialized BEEF must start with ${exports.BEEF_MAGIC} or ${exports.BEEF_MAGIC_V2} but starts with ${version}`);
|
|
316
|
+
const beef = new Beef();
|
|
317
|
+
const bumpsLength = br.readVarIntNum();
|
|
318
|
+
for (let i = 0; i < bumpsLength; i++) {
|
|
319
|
+
const bump = MerklePath_js_1.default.fromReader(br);
|
|
320
|
+
beef.bumps.push(bump);
|
|
321
|
+
}
|
|
322
|
+
const txsLength = br.readVarIntNum();
|
|
323
|
+
for (let i = 0; i < txsLength; i++) {
|
|
324
|
+
const beefTx = BeefTx_js_1.default.fromReader(br);
|
|
325
|
+
beef.txs.push(beefTx);
|
|
326
|
+
}
|
|
327
|
+
return beef;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Constructs an instance of the Beef class based on the provided binary array
|
|
331
|
+
* @param bin The binary array from which to construct BEEF
|
|
332
|
+
* @returns An instance of the Beef class constructed from the binary data
|
|
333
|
+
*/
|
|
334
|
+
static fromBinary(bin) {
|
|
335
|
+
const br = new utils_js_1.Reader(bin);
|
|
336
|
+
return Beef.fromReader(br);
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Constructs an instance of the Beef class based on the provided string
|
|
340
|
+
* @param s The string value from which to construct BEEF
|
|
341
|
+
* @param enc The encoding of the string value from which BEEF should be constructed
|
|
342
|
+
* @returns An instance of the Beef class constructed from the string
|
|
343
|
+
*/
|
|
344
|
+
static fromString(s, enc) {
|
|
345
|
+
enc || (enc = 'hex');
|
|
346
|
+
const bin = (0, utils_js_1.toArray)(s, enc);
|
|
347
|
+
const br = new utils_js_1.Reader(bin);
|
|
348
|
+
return Beef.fromReader(br);
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Try to validate newTx.bumpIndex by looking for an existing bump
|
|
352
|
+
* that proves newTx.txid
|
|
353
|
+
*
|
|
354
|
+
* @param newTx A new `BeefTx` that has been added to this.txs
|
|
355
|
+
* @returns true if a bump was found, false otherwise
|
|
356
|
+
*/
|
|
357
|
+
tryToValidateBumpIndex(newTx) {
|
|
358
|
+
if (newTx.bumpIndex !== undefined)
|
|
359
|
+
return true;
|
|
360
|
+
const txid = newTx.txid;
|
|
361
|
+
for (let i = 0; i < this.bumps.length; i++) {
|
|
362
|
+
const j = this.bumps[i].path[0].findIndex(b => b.hash === txid);
|
|
363
|
+
if (j >= 0) {
|
|
364
|
+
newTx.bumpIndex = i;
|
|
365
|
+
this.bumps[i].path[0][j].txid = true;
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Sort the `txs` by input txid dependency order.
|
|
373
|
+
* @returns array of input txids of unproven transactions that aren't included in txs.
|
|
374
|
+
*/
|
|
375
|
+
sortTxs() {
|
|
376
|
+
const missingInputs = {};
|
|
377
|
+
const txidToTx = {};
|
|
378
|
+
for (const tx of this.txs) {
|
|
379
|
+
txidToTx[tx.txid] = tx;
|
|
380
|
+
// All transactions in this beef start at degree zero.
|
|
381
|
+
tx.degree = 0;
|
|
382
|
+
}
|
|
383
|
+
for (const tx of this.txs) {
|
|
384
|
+
if (tx.bumpIndex === undefined) {
|
|
385
|
+
// For all the unproven transactions,
|
|
386
|
+
// link their inputs that exist in this beef,
|
|
387
|
+
// make a note of missing inputs.
|
|
388
|
+
for (const inputTxid of tx.inputTxids) {
|
|
389
|
+
if (!txidToTx[inputTxid])
|
|
390
|
+
missingInputs[inputTxid] = true;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
// queue of transactions that no unsorted transactions depend upon...
|
|
395
|
+
const queue = [];
|
|
396
|
+
// sorted transactions
|
|
397
|
+
const result = [];
|
|
398
|
+
// Increment each txid's degree for every input reference to it by another txid
|
|
399
|
+
for (const tx of this.txs) {
|
|
400
|
+
for (const inputTxid of tx.inputTxids) {
|
|
401
|
+
const tx = txidToTx[inputTxid];
|
|
402
|
+
if (tx)
|
|
403
|
+
tx.degree++;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
// Since circular dependencies aren't possible, start with the txids no one depends on.
|
|
407
|
+
// These are the transactions that should be sent last...
|
|
408
|
+
for (const tx of this.txs) {
|
|
409
|
+
if (tx.degree === 0) {
|
|
410
|
+
queue.push(tx);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// As long as we have transactions to send...
|
|
414
|
+
while (queue.length) {
|
|
415
|
+
let tx = queue.shift();
|
|
416
|
+
// Add it as new first to send
|
|
417
|
+
result.unshift(tx);
|
|
418
|
+
// And remove its impact on degree
|
|
419
|
+
// noting that any tx achieving a
|
|
420
|
+
// value of zero can be sent...
|
|
421
|
+
for (const inputTxid of tx.inputTxids) {
|
|
422
|
+
const inputTx = txidToTx[inputTxid];
|
|
423
|
+
if (inputTx) {
|
|
424
|
+
inputTx.degree--;
|
|
425
|
+
if (inputTx.degree === 0) {
|
|
426
|
+
queue.push(inputTx);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
this.txs = result;
|
|
432
|
+
return Object.keys(missingInputs);
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* @returns a shallow copy of this beef
|
|
436
|
+
*/
|
|
437
|
+
clone() {
|
|
438
|
+
const c = new Beef();
|
|
439
|
+
c.bumps = Array.from(this.bumps);
|
|
440
|
+
c.txs = Array.from(this.txs);
|
|
441
|
+
return c;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Ensure that all the txids in `knownTxids` are txidOnly
|
|
445
|
+
* @param knownTxids
|
|
446
|
+
*/
|
|
447
|
+
trimKnownTxids(knownTxids) {
|
|
448
|
+
for (let i = 0; i < this.txs.length;) {
|
|
449
|
+
const tx = this.txs[i];
|
|
450
|
+
if (tx.isTxidOnly && -1 < knownTxids.indexOf(tx.txid)) {
|
|
451
|
+
this.txs.splice(i, 1);
|
|
452
|
+
}
|
|
453
|
+
else {
|
|
454
|
+
i++;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// TODO: bumps could be trimmed to eliminate unreferenced proofs.
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* @returns Summary of `Beef` contents as multi-line string.
|
|
461
|
+
*/
|
|
462
|
+
toLogString() {
|
|
463
|
+
let log = '';
|
|
464
|
+
log += `BEEF with ${this.bumps.length} BUMPS and ${this.txs.length} Transactions, isValid ${this.isValid()}\n`;
|
|
465
|
+
let i = -1;
|
|
466
|
+
for (const b of this.bumps) {
|
|
467
|
+
i++;
|
|
468
|
+
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`;
|
|
469
|
+
}
|
|
470
|
+
i = -1;
|
|
471
|
+
for (const t of this.txs) {
|
|
472
|
+
i++;
|
|
473
|
+
log += ` TX ${i}\n txid: ${t.txid}\n`;
|
|
474
|
+
if (t.bumpIndex !== undefined) {
|
|
475
|
+
log += ` bumpIndex: ${t.bumpIndex}\n`;
|
|
476
|
+
}
|
|
477
|
+
if (t.isTxidOnly) {
|
|
478
|
+
log += ` txidOnly\n`;
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
log += ` rawTx length=${t.rawTx.length}\n`;
|
|
482
|
+
}
|
|
483
|
+
if (t.inputTxids.length > 0) {
|
|
484
|
+
log += ` inputs: [\n${t.inputTxids.map(it => ` '${it}'`).join(',\n')}\n ]\n`;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return log;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
exports.Beef = Beef;
|
|
491
|
+
exports.default = Beef;
|
|
492
|
+
//# sourceMappingURL=Beef.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Beef.js","sourceRoot":"","sources":["../../../../src/transaction/Beef.ts"],"names":[],"mappings":";;;;;;AAAA,oEAAyC;AAGzC,4DAAiC;AACjC,qDAAuE;AAE1D,QAAA,UAAU,GAAG,UAAU,CAAA,CAAI,uBAAuB;AAClD,QAAA,aAAa,GAAG,UAAU,CAAA,CAAC,uBAAuB;AAClD,QAAA,8BAA8B,GAAG,UAAU,CAAA,CAAC,uBAAuB;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAa,IAAI;IAIb;QAHA,UAAK,GAAiB,EAAE,CAAA;QACxB,QAAG,GAAa,EAAE,CAAA;IAGlB,CAAC;IAED;;;;OAIG;IACH,IAAI,OAAO;QACP,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAA;QACzD,IAAI,WAAW;YACX,OAAO,qBAAa,CAAA;;YAEpB,OAAO,kBAAU,CAAA;IACzB,CAAC;IAED;;;OAGG;IACH,QAAQ,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;IAChD,CAAC;IAED;;;;OAIG;IACH,SAAS,CAAC,IAAgB;QACtB,IAAI,SAAS,GAAuB,SAAS,CAAA;QAC7C,gJAAgJ;QAChJ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;YACvB,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,qBAAqB;gBACnC,OAAO,CAAC,CAAA;YACZ,CAAC;YACD,IAAI,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBACrC,uBAAuB;gBACvB,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,EAAE,CAAA;gBAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;gBAChC,IAAI,KAAK,KAAK,KAAK,EAAE,CAAC;oBAClB,oDAAoD;oBACpD,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;oBACf,SAAS,GAAG,CAAC,CAAA;oBACb,MAAK;gBACT,CAAC;YACL,CAAC;QACL,CAAC;QAED,iDAAiD;QACjD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1B,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;YAC7B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;QAED,qDAAqD;QACrD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;QAC/B,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAA;YACpB,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC;gBAChB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxB,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;wBAClB,EAAE,CAAC,SAAS,GAAG,SAAS,CAAA;wBACxB,CAAC,CAAC,IAAI,GAAG,IAAI,CAAA;wBACb,MAAK;oBACT,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,SAAS,CAAA;IACpB,CAAC;IAED;;;;;;;;;;OAUG;IACH,UAAU,CAAC,KAAe,EAAE,SAAkB;QAC1C,MAAM,KAAK,GAAW,IAAI,mBAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAClD,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QACnC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAClC,OAAO,KAAK,CAAA;IAChB,CAAC;IAED;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAe;QAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAA;QACzB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QAC7B,IAAI,SAAS,GAAuB,SAAS,CAAA;QAC7C,IAAI,EAAE,CAAC,UAAU;YACb,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,UAAU,CAAC,CAAA;QAC7C,MAAM,KAAK,GAAG,IAAI,mBAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAA;QACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAA;QAClC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAA;QAC3B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC1B,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,iBAAiB;oBACvB,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;YACtD,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAA;IAChB,CAAC;IAED;;;OAGG;IACH,kBAAkB,CAAC,IAAY;QAC3B,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QAChE,IAAI,eAAe,IAAI,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,CAAA;IAC3C,CAAC;IAED,aAAa,CAAC,IAAY;QACtB,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;QAC5C,IAAI,CAAC,EAAE,EAAE,CAAC;YACN,EAAE,GAAG,IAAI,mBAAM,CAAC,IAAI,CAAC,CAAA;YACrB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YACjB,IAAI,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAA;QACnC,CAAC;QACD,OAAO,EAAE,CAAA;IACb,CAAC;IAED,WAAW,CAAC,GAAW;QACnB,IAAI,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACpC,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU;YACzB,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;aACpC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,IAAI,GAAG,CAAC,GAAG;gBACP,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;;gBAEvC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,MAAO,CAAC,CAAA;QAC7C,CAAC;QACD,OAAO,MAAM,CAAA;IACjB,CAAC;IAED,SAAS,CAAC,IAAqB;QAC3B,MAAM,CAAC,GAAS,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAElE,KAAK,MAAM,IAAI,IAAI,CAAC,CAAC,KAAK;YACtB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;QAExB,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG;YAClB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;IAC5B,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,aAAuB;QAC3B,OAAO,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,KAAK,CAAA;IAChD,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,KAAK,CAAC,MAAM,CAAC,YAA0B,EAAE,aAAuB;QAC5D,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,aAAa,CAAC,CAAA;QACzC,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO,KAAK,CAAA;QAE1B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;YACxF,IAAI,CAAC,OAAO;gBACR,OAAO,KAAK,CAAA;QACpB,CAAC;QAED,OAAO,IAAI,CAAA;IACf,CAAC;IAEO,WAAW,CAAC,aAAuB;QAGvC,MAAM,CAAC,GAAsD,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAExF,IAAI,CAAC,OAAO,EAAE,CAAA;QAEd,mFAAmF;QACnF,MAAM,KAAK,GAA4B,EAAE,CAAA;QAEzC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;gBAChB,IAAI,CAAC,aAAa;oBAAE,OAAO,CAAC,CAAA;gBAC5B,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;YACzB,CAAC;QACL,CAAC;QAED,MAAM,mBAAmB,GAAG,CAAC,CAAa,EAAE,IAAY,EAAW,EAAE;YACjE,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAChC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1B,yEAAyE;gBACzE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,IAAI,CAAA;YACjC,CAAC;YACD,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI;gBAC/B,OAAO,KAAK,CAAA;YAChB,OAAO,IAAI,CAAA;QACf,CAAC,CAAA;QAED,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;oBACnB,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;oBACpB,6EAA6E;oBAC7E,IAAI,CAAC,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;wBAC/B,OAAO,CAAC,CAAA;gBAChB,CAAC;YACL,CAAC;QACL,CAAC;QAED,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU;gBACxB,8DAA8D;gBAC9D,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;oBAAE,OAAO,CAAC,CAAA;YAC3B,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;QACxB,CAAC;QAED,CAAC,CAAC,KAAK,GAAG,IAAI,CAAA;QACd,OAAO,CAAC,CAAA;IACZ,CAAC;IAED;;;OAGG;IACH,QAAQ;QAEJ,MAAM,MAAM,GAAG,IAAI,iBAAM,EAAE,CAAA;QAC3B,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAElC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QACxC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC9B,CAAC;QAED,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QACtC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC;QAED,OAAO,MAAM,CAAC,OAAO,EAAE,CAAA;IAC3B,CAAC;IAED;;;OAGG;IACH,KAAK;QACD,OAAO,IAAA,gBAAK,EAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;IACjC,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,EAAU;QACxB,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,EAAE,CAAA;QACjC,IAAI,OAAO,KAAK,kBAAU,IAAI,OAAO,KAAK,qBAAa;YACnD,MAAM,IAAI,KAAK,CAAC,mCAAmC,kBAAU,OAAO,qBAAa,oBAAoB,OAAO,EAAE,CAAC,CAAA;QACnH,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAA;QACvB,MAAM,WAAW,GAAG,EAAE,CAAC,aAAa,EAAE,CAAA;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,uBAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;YACtC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACzB,CAAC;QACD,MAAM,SAAS,GAAG,EAAE,CAAC,aAAa,EAAE,CAAA;QACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,mBAAM,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;YACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QACzB,CAAC;QACD,OAAO,IAAI,CAAA;IACf,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,UAAU,CAAC,GAAa;QAC3B,MAAM,EAAE,GAAG,IAAI,iBAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,UAAU,CAAC,CAAS,EAAE,GAA+B;QACxD,GAAG,KAAH,GAAG,GAAK,KAAK,EAAA;QACb,MAAM,GAAG,GAAG,IAAA,kBAAO,EAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC3B,MAAM,EAAE,GAAG,IAAI,iBAAM,CAAC,GAAG,CAAC,CAAA;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED;;;;;;OAMG;IACK,sBAAsB,CAAC,KAAa;QACxC,IAAI,KAAK,CAAC,SAAS,KAAK,SAAS;YAC7B,OAAO,IAAI,CAAA;QACf,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAA;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACzC,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAA;YAC/D,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACT,KAAK,CAAC,SAAS,GAAG,CAAC,CAAA;gBACnB,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAA;gBACpC,OAAO,IAAI,CAAA;YACf,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAA;IAChB,CAAC;IAED;;;OAGG;IACH,OAAO;QACH,MAAM,aAAa,GAA4B,EAAE,CAAA;QAEjD,MAAM,QAAQ,GAA2B,EAAE,CAAA;QAE3C,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAA;YACtB,sDAAsD;YACtD,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;QACjB,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,IAAI,EAAE,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC7B,qCAAqC;gBACrC,6CAA6C;gBAC7C,iCAAiC;gBACjC,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;oBACpC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;wBACpB,aAAa,CAAC,SAAS,CAAC,GAAG,IAAI,CAAA;gBACvC,CAAC;YACL,CAAC;QACL,CAAC;QAED,qEAAqE;QACrE,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,sBAAsB;QACtB,MAAM,MAAM,GAAa,EAAE,CAAA;QAE3B,+EAA+E;QAC/E,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;gBACpC,MAAM,EAAE,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;gBAC9B,IAAI,EAAE;oBACF,EAAE,CAAC,MAAM,EAAE,CAAA;YACnB,CAAC;QACL,CAAC;QACD,uFAAuF;QACvF,yDAAyD;QACzD,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;YAClB,CAAC;QACL,CAAC;QACD,6CAA6C;QAC7C,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,EAAG,CAAA;YACvB,8BAA8B;YAC9B,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;YAClB,kCAAkC;YAClC,iCAAiC;YACjC,+BAA+B;YAC/B,KAAK,MAAM,SAAS,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;gBACpC,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAA;gBACnC,IAAI,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,MAAM,EAAE,CAAA;oBAChB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACvB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;oBACvB,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QACD,IAAI,CAAC,GAAG,GAAG,MAAM,CAAA;QAEjB,OAAO,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;IACrC,CAAC;IAED;;OAEG;IACH,KAAK;QACD,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAA;QACpB,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC5B,OAAO,CAAC,CAAA;IACZ,CAAC;IAED;;;OAGG;IACH,cAAc,CAAC,UAAoB;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC;YACnC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YACtB,IAAI,EAAE,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACJ,CAAC,EAAE,CAAA;YACP,CAAC;QACL,CAAC;QACD,iEAAiE;IACrE,CAAC;IAED;;OAEG;IACH,WAAW;QACP,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,GAAG,IAAI,aAAa,IAAI,CAAC,KAAK,CAAC,MAAM,cAAc,IAAI,CAAC,GAAG,CAAC,MAAM,0BAA0B,IAAI,CAAC,OAAO,EAAE,IAAI,CAAA;QAC9G,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QACV,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,CAAC,EAAE,CAAA;YACH,GAAG,IAAI,UAAU,CAAC,gBAAgB,CAAC,CAAC,WAAW,mBAAmB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAA;QAC1J,CAAC;QACD,CAAC,GAAG,CAAC,CAAC,CAAA;QACN,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,CAAC,EAAE,CAAA;YACH,GAAG,IAAI,QAAQ,CAAC,eAAe,CAAC,CAAC,IAAI,IAAI,CAAA;YACzC,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC5B,GAAG,IAAI,kBAAkB,CAAC,CAAC,SAAS,IAAI,CAAA;YAC5C,CAAC;YACD,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;gBACf,GAAG,IAAI,gBAAgB,CAAA;YAC3B,CAAC;iBAAM,CAAC;gBACJ,GAAG,IAAI,oBAAoB,CAAC,CAAC,KAAM,CAAC,MAAM,IAAI,CAAA;YAClD,CAAC;YACD,IAAI,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,GAAG,IAAI,kBAAkB,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAA;YAC3F,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAA;IACd,CAAC;CACJ;AAjeD,oBAieC;AAED,kBAAe,IAAI,CAAA"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BeefParty = void 0;
|
|
4
|
+
const Beef_js_1 = require("./Beef.js");
|
|
5
|
+
/**
|
|
6
|
+
* Extends `Beef` that is used to exchange transaction validity data with more than one external party.
|
|
7
|
+
*
|
|
8
|
+
* Use `addKnownTxidsForParty` to keep track of who knows what to reduce re-transmission of potentially large transactions.
|
|
9
|
+
*
|
|
10
|
+
* Use `getTrimmedBeefForParty` to obtain a `Beef` trimmed of transaction validity data known to a specific party.
|
|
11
|
+
*
|
|
12
|
+
* Typical usage scenario:
|
|
13
|
+
*
|
|
14
|
+
* 1. Query a wallet storage provider for spendable outputs.
|
|
15
|
+
* 2. The provider replies with a Beef validating the returned outputs.
|
|
16
|
+
* 3. Construct a new transaction using some of the queried outputs as inputs, including Beef validating all the inputs.
|
|
17
|
+
* 4. Receive new valid raw transaction after processing and Beef validating change outputs added to original inputs.
|
|
18
|
+
* 5. Return to step 1, continuing to build on old and new spendable outputs.
|
|
19
|
+
*
|
|
20
|
+
* By default, each Beef is required to be complete and valid: All transactions appear as full serialized bitcoin transactions and
|
|
21
|
+
* each transaction either has a merkle path proof (it has been mined) or all of its input transactions are included.
|
|
22
|
+
*
|
|
23
|
+
* The size and redundancy of these Beefs becomes a problem when chained transaction creation out-paces the block mining rate.
|
|
24
|
+
*
|
|
25
|
+
*/
|
|
26
|
+
class BeefParty extends Beef_js_1.Beef {
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param parties Optional array of initial unique party identifiers.
|
|
30
|
+
*/
|
|
31
|
+
constructor(parties) {
|
|
32
|
+
super();
|
|
33
|
+
/**
|
|
34
|
+
* keys are party identifiers.
|
|
35
|
+
* values are records of txids with truthy value for which the party already has validity proof.
|
|
36
|
+
*/
|
|
37
|
+
this.knownTo = {};
|
|
38
|
+
if (parties) {
|
|
39
|
+
for (const party of parties)
|
|
40
|
+
this.addParty(party);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* @param party
|
|
45
|
+
* @returns `true` if `party` has already beed added to this `BeefParty`.
|
|
46
|
+
*/
|
|
47
|
+
isParty(party) {
|
|
48
|
+
const r = Object.keys(this.knownTo).includes(party);
|
|
49
|
+
return r;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Adds a new unique party identifier to this `BeefParty`.
|
|
53
|
+
* @param party
|
|
54
|
+
*/
|
|
55
|
+
addParty(party) {
|
|
56
|
+
if (this.isParty(party))
|
|
57
|
+
throw new Error(`Party ${party} already exists.`);
|
|
58
|
+
this.knownTo[party] = {};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @param party
|
|
62
|
+
* @returns Array of txids "known" to `party`.
|
|
63
|
+
*/
|
|
64
|
+
getKnownTxidsForParty(party) {
|
|
65
|
+
const knownTxids = this.knownTo[party];
|
|
66
|
+
if (!knownTxids)
|
|
67
|
+
throw new Error(`Party ${party} is unknown.`);
|
|
68
|
+
return Object.keys(knownTxids);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* @param party
|
|
72
|
+
* @returns trimmed beef of unknown transactions and proofs for `party`
|
|
73
|
+
*/
|
|
74
|
+
getTrimmedBeefForParty(party) {
|
|
75
|
+
const knownTxids = this.getKnownTxidsForParty(party);
|
|
76
|
+
const prunedBeef = this.clone();
|
|
77
|
+
prunedBeef.trimKnownTxids(knownTxids);
|
|
78
|
+
return prunedBeef;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Make note of additional txids "known" to `party`.
|
|
82
|
+
* @param party unique identifier, added if new.
|
|
83
|
+
* @param knownTxids
|
|
84
|
+
*/
|
|
85
|
+
addKnownTxidsForParty(party, knownTxids) {
|
|
86
|
+
if (!this.isParty(party))
|
|
87
|
+
this.addParty(party);
|
|
88
|
+
const kts = this.knownTo[party];
|
|
89
|
+
for (const txid of knownTxids) {
|
|
90
|
+
kts[txid] = true;
|
|
91
|
+
this.mergeTxidOnly(txid);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
exports.BeefParty = BeefParty;
|
|
96
|
+
exports.default = BeefParty;
|
|
97
|
+
//# sourceMappingURL=BeefParty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BeefParty.js","sourceRoot":"","sources":["../../../../src/transaction/BeefParty.ts"],"names":[],"mappings":";;;AAAA,uCAAiC;AAEjC;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAa,SAAU,SAAQ,cAAI;IAO/B;;;OAGG;IACH,YAAY,OAAkB;QAC1B,KAAK,EAAE,CAAA;QAXX;;;WAGG;QACH,YAAO,GAA4C,EAAE,CAAA;QAQjD,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;AA1ED,8BA0EC;AAED,kBAAe,SAAS,CAAA"}
|