@bsv/sdk 1.2.17 → 1.2.19
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/BigNumber.js +85 -89
- package/dist/cjs/src/primitives/BigNumber.js.map +1 -1
- package/dist/cjs/src/primitives/PublicKey.js +5 -2
- package/dist/cjs/src/primitives/PublicKey.js.map +1 -1
- package/dist/cjs/src/primitives/Random.js +3 -2
- package/dist/cjs/src/primitives/Random.js.map +1 -1
- package/dist/cjs/src/primitives/utils.js +71 -62
- package/dist/cjs/src/primitives/utils.js.map +1 -1
- package/dist/cjs/src/totp/totp.js +0 -1
- package/dist/cjs/src/totp/totp.js.map +1 -1
- package/dist/cjs/src/transaction/Beef.js +26 -40
- package/dist/cjs/src/transaction/Beef.js.map +1 -1
- package/dist/cjs/src/transaction/BeefParty.js +1 -1
- package/dist/cjs/src/transaction/BeefTx.js +75 -73
- package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
- package/dist/cjs/src/transaction/MerklePath.js +12 -1
- package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
- package/dist/cjs/src/transaction/Transaction.js +70 -96
- package/dist/cjs/src/transaction/Transaction.js.map +1 -1
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js +20 -2
- package/dist/cjs/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/primitives/BigNumber.js +85 -89
- package/dist/esm/src/primitives/BigNumber.js.map +1 -1
- package/dist/esm/src/primitives/PublicKey.js +5 -2
- package/dist/esm/src/primitives/PublicKey.js.map +1 -1
- package/dist/esm/src/primitives/Random.js +2 -2
- package/dist/esm/src/primitives/Random.js.map +1 -1
- package/dist/esm/src/primitives/utils.js +70 -61
- package/dist/esm/src/primitives/utils.js.map +1 -1
- package/dist/esm/src/totp/totp.js +0 -1
- package/dist/esm/src/totp/totp.js.map +1 -1
- package/dist/esm/src/transaction/Beef.js +25 -39
- package/dist/esm/src/transaction/Beef.js.map +1 -1
- package/dist/esm/src/transaction/BeefParty.js +1 -1
- package/dist/esm/src/transaction/BeefTx.js +76 -74
- package/dist/esm/src/transaction/BeefTx.js.map +1 -1
- package/dist/esm/src/transaction/MerklePath.js +12 -1
- package/dist/esm/src/transaction/MerklePath.js.map +1 -1
- package/dist/esm/src/transaction/Transaction.js +71 -97
- package/dist/esm/src/transaction/Transaction.js.map +1 -1
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js +20 -2
- package/dist/esm/src/transaction/chaintrackers/WhatsOnChain.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/primitives/BigNumber.d.ts +24 -22
- package/dist/types/src/primitives/BigNumber.d.ts.map +1 -1
- package/dist/types/src/primitives/PublicKey.d.ts.map +1 -1
- package/dist/types/src/primitives/utils.d.ts +17 -17
- package/dist/types/src/primitives/utils.d.ts.map +1 -1
- package/dist/types/src/transaction/Beef.d.ts +9 -12
- package/dist/types/src/transaction/Beef.d.ts.map +1 -1
- package/dist/types/src/transaction/BeefParty.d.ts +1 -1
- package/dist/types/src/transaction/BeefTx.d.ts +5 -2
- package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
- package/dist/types/src/transaction/ChainTracker.d.ts +6 -0
- package/dist/types/src/transaction/ChainTracker.d.ts.map +1 -1
- package/dist/types/src/transaction/MerklePath.d.ts +1 -0
- package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
- package/dist/types/src/transaction/Transaction.d.ts +6 -0
- package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
- package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts +2 -1
- package/dist/types/src/transaction/chaintrackers/WhatsOnChain.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +1 -1
- package/docs/compat.md +13 -11
- package/docs/primitives.md +152 -188
- package/docs/transaction.md +78 -76
- package/package.json +1 -1
- package/src/primitives/BigNumber.ts +111 -111
- package/src/primitives/PublicKey.ts +5 -2
- package/src/primitives/Random.ts +2 -2
- package/src/primitives/utils.ts +92 -77
- package/src/totp/totp.ts +0 -1
- package/src/transaction/Beef.ts +20 -43
- package/src/transaction/BeefParty.ts +1 -1
- package/src/transaction/BeefTx.ts +89 -57
- package/src/transaction/ChainTracker.ts +6 -0
- package/src/transaction/MerklePath.ts +13 -1
- package/src/transaction/Transaction.ts +77 -100
- package/src/transaction/__tests/Beef.test.ts +9 -9
- package/src/transaction/__tests/MerklePath.test.ts +23 -2
- package/src/transaction/__tests/Transaction.benchmarks.test.ts +1 -1
- package/src/transaction/__tests/Transaction.test.ts +3 -3
- package/src/transaction/broadcasters/__tests/WhatsOnChainBroadcaster.test.ts +2 -2
- package/src/transaction/chaintrackers/WhatsOnChain.ts +20 -2
- package/src/transaction/chaintrackers/__tests/WhatsOnChainChainTracker.test.ts +32 -1
package/src/primitives/utils.ts
CHANGED
|
@@ -21,8 +21,8 @@ export const zero2 = (word: string): string => {
|
|
|
21
21
|
*/
|
|
22
22
|
export const toHex = (msg: number[]): string => {
|
|
23
23
|
let res = ''
|
|
24
|
-
for (
|
|
25
|
-
res += zero2(
|
|
24
|
+
for (const num of msg) {
|
|
25
|
+
res += zero2(num.toString(16))
|
|
26
26
|
}
|
|
27
27
|
return res
|
|
28
28
|
}
|
|
@@ -36,59 +36,63 @@ export const toHex = (msg: number[]): string => {
|
|
|
36
36
|
* @returns {any[]} - Array representation of the input.
|
|
37
37
|
*/
|
|
38
38
|
export const toArray = (msg: any, enc?: 'hex' | 'utf8' | 'base64'): any[] => {
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
// Return empty array for falsy values
|
|
43
|
-
if (!(msg as boolean)) { return [] }
|
|
44
|
-
const res: any[] = []
|
|
39
|
+
if (Array.isArray(msg)) return msg.slice()
|
|
40
|
+
if (!msg) return []
|
|
45
41
|
|
|
46
|
-
// Convert non-string messages to numbers
|
|
47
42
|
if (typeof msg !== 'string') {
|
|
48
|
-
|
|
49
|
-
return res
|
|
43
|
+
return Array.from(msg, (item: any) => item | 0)
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
46
|
+
switch (enc) {
|
|
47
|
+
case 'hex':
|
|
48
|
+
return hexToArray(msg)
|
|
49
|
+
case 'base64':
|
|
50
|
+
return base64ToArray(msg)
|
|
51
|
+
default:
|
|
52
|
+
return utf8ToArray(msg)
|
|
53
|
+
}
|
|
54
|
+
}
|
|
61
55
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
const hexToArray = (msg: string): number[] => {
|
|
57
|
+
msg = msg.replace(/[^a-z0-9]+/ig, '')
|
|
58
|
+
if (msg.length % 2 !== 0) msg = '0' + msg
|
|
59
|
+
const res: number[] = []
|
|
60
|
+
for (let i = 0; i < msg.length; i += 2) {
|
|
61
|
+
res.push(parseInt(msg[i] + msg[i + 1], 16))
|
|
62
|
+
}
|
|
63
|
+
return res
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const base64ToArray = (msg: string): number[] => {
|
|
67
|
+
const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
|
68
|
+
const result: number[] = []
|
|
69
|
+
let currentBit = 0
|
|
70
|
+
let currentByte = 0
|
|
71
|
+
|
|
72
|
+
for (const char of msg.replace(/=+$/, '')) {
|
|
73
|
+
currentBit = (currentBit << 6) | base64Chars.indexOf(char)
|
|
74
|
+
currentByte += 6
|
|
75
|
+
|
|
76
|
+
if (currentByte >= 8) {
|
|
77
|
+
currentByte -= 8
|
|
78
|
+
result.push((currentBit >> currentByte) & 0xFF)
|
|
79
|
+
currentBit &= (1 << currentByte) - 1
|
|
78
80
|
}
|
|
81
|
+
}
|
|
79
82
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
83
|
+
return result
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const utf8ToArray = (msg: string): number[] => {
|
|
87
|
+
const res: number[] = []
|
|
88
|
+
for (let i = 0; i < msg.length; i++) {
|
|
89
|
+
const c = msg.charCodeAt(i)
|
|
90
|
+
const hi = c >> 8
|
|
91
|
+
const lo = c & 0xff
|
|
92
|
+
if (hi) {
|
|
93
|
+
res.push(hi, lo)
|
|
94
|
+
} else {
|
|
95
|
+
res.push(lo)
|
|
92
96
|
}
|
|
93
97
|
}
|
|
94
98
|
return res
|
|
@@ -101,32 +105,43 @@ export const toArray = (msg: any, enc?: 'hex' | 'utf8' | 'base64'): any[] => {
|
|
|
101
105
|
*/
|
|
102
106
|
export const toUTF8 = (arr: number[]): string => {
|
|
103
107
|
let result = ''
|
|
108
|
+
let skip = 0
|
|
104
109
|
|
|
105
110
|
for (let i = 0; i < arr.length; i++) {
|
|
106
111
|
const byte = arr[i]
|
|
107
112
|
|
|
113
|
+
// this byte is part of a multi-byte sequence, skip it
|
|
114
|
+
// added to avoid modifying i within the loop which is considered unsafe.
|
|
115
|
+
if (skip > 0) {
|
|
116
|
+
skip--
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
|
|
108
120
|
// 1-byte sequence (0xxxxxxx)
|
|
109
121
|
if (byte <= 0x7F) {
|
|
110
122
|
result += String.fromCharCode(byte)
|
|
111
123
|
}
|
|
112
124
|
// 2-byte sequence (110xxxxx 10xxxxxx)
|
|
113
125
|
else if (byte >= 0xC0 && byte <= 0xDF) {
|
|
114
|
-
const byte2 = arr[
|
|
126
|
+
const byte2 = arr[i + 1]
|
|
127
|
+
skip = 1
|
|
115
128
|
const codePoint = ((byte & 0x1F) << 6) | (byte2 & 0x3F)
|
|
116
129
|
result += String.fromCharCode(codePoint)
|
|
117
130
|
}
|
|
118
131
|
// 3-byte sequence (1110xxxx 10xxxxxx 10xxxxxx)
|
|
119
132
|
else if (byte >= 0xE0 && byte <= 0xEF) {
|
|
120
|
-
const byte2 = arr[
|
|
121
|
-
const byte3 = arr[
|
|
133
|
+
const byte2 = arr[i + 1]
|
|
134
|
+
const byte3 = arr[i + 2]
|
|
135
|
+
skip = 2
|
|
122
136
|
const codePoint = ((byte & 0x0F) << 12) | ((byte2 & 0x3F) << 6) | (byte3 & 0x3F)
|
|
123
137
|
result += String.fromCharCode(codePoint)
|
|
124
138
|
}
|
|
125
139
|
// 4-byte sequence (11110xxx 10xxxxxx 10xxxxxx 10xxxxxx)
|
|
126
140
|
else if (byte >= 0xF0 && byte <= 0xF7) {
|
|
127
|
-
const byte2 = arr[
|
|
128
|
-
const byte3 = arr[
|
|
129
|
-
const byte4 = arr[
|
|
141
|
+
const byte2 = arr[i + 1]
|
|
142
|
+
const byte3 = arr[i + 2]
|
|
143
|
+
const byte4 = arr[i + 3]
|
|
144
|
+
skip = 3
|
|
130
145
|
const codePoint = ((byte & 0x07) << 18) | ((byte2 & 0x3F) << 12) | ((byte3 & 0x3F) << 6) | (byte4 & 0x3F)
|
|
131
146
|
|
|
132
147
|
// Convert to UTF-16 surrogate pair
|
|
@@ -212,7 +227,7 @@ export const fromBase58 = (str: string): number[] => {
|
|
|
212
227
|
const uint8 = new Uint8Array([
|
|
213
228
|
...new Uint8Array(psz),
|
|
214
229
|
...str
|
|
215
|
-
.match(
|
|
230
|
+
.match(/./gmu)
|
|
216
231
|
.map((i) => base58chars.indexOf(i))
|
|
217
232
|
.reduce((acc, i) => {
|
|
218
233
|
acc = acc.map((j) => {
|
|
@@ -324,19 +339,19 @@ export class Writer {
|
|
|
324
339
|
const ret = new Array(totalLength)
|
|
325
340
|
let offset = 0
|
|
326
341
|
for (const buf of this.bufs) {
|
|
327
|
-
for (
|
|
328
|
-
ret[offset++] =
|
|
342
|
+
for (const value of buf) {
|
|
343
|
+
ret[offset++] = value
|
|
329
344
|
}
|
|
330
345
|
}
|
|
331
346
|
return ret
|
|
332
347
|
}
|
|
333
348
|
|
|
334
|
-
write (buf: number[]):
|
|
349
|
+
write (buf: number[]): this {
|
|
335
350
|
this.bufs.push(buf)
|
|
336
351
|
return this
|
|
337
352
|
}
|
|
338
353
|
|
|
339
|
-
writeReverse (buf: number[]):
|
|
354
|
+
writeReverse (buf: number[]): this {
|
|
340
355
|
const buf2: number[] = new Array(buf.length)
|
|
341
356
|
for (let i = 0; i < buf2.length; i++) {
|
|
342
357
|
buf2[i] = buf[buf.length - 1 - i]
|
|
@@ -345,21 +360,21 @@ export class Writer {
|
|
|
345
360
|
return this
|
|
346
361
|
}
|
|
347
362
|
|
|
348
|
-
writeUInt8 (n: number):
|
|
363
|
+
writeUInt8 (n: number): this {
|
|
349
364
|
const buf = new Array(1)
|
|
350
365
|
buf[0] = n
|
|
351
366
|
this.write(buf)
|
|
352
367
|
return this
|
|
353
368
|
}
|
|
354
369
|
|
|
355
|
-
writeInt8 (n: number):
|
|
370
|
+
writeInt8 (n: number): this {
|
|
356
371
|
const buf = new Array(1)
|
|
357
372
|
buf[0] = n & 0xFF
|
|
358
373
|
this.write(buf)
|
|
359
374
|
return this
|
|
360
375
|
}
|
|
361
376
|
|
|
362
|
-
writeUInt16BE (n: number):
|
|
377
|
+
writeUInt16BE (n: number): this {
|
|
363
378
|
this.bufs.push([
|
|
364
379
|
(n >> 8) & 0xFF, // shift right 8 bits to get the high byte
|
|
365
380
|
n & 0xFF // low byte is just the last 8 bits
|
|
@@ -367,11 +382,11 @@ export class Writer {
|
|
|
367
382
|
return this
|
|
368
383
|
}
|
|
369
384
|
|
|
370
|
-
writeInt16BE (n: number):
|
|
385
|
+
writeInt16BE (n: number): this {
|
|
371
386
|
return this.writeUInt16BE(n & 0xFFFF) // Mask with 0xFFFF to get the lower 16 bits
|
|
372
387
|
}
|
|
373
388
|
|
|
374
|
-
writeUInt16LE (n: number):
|
|
389
|
+
writeUInt16LE (n: number): this {
|
|
375
390
|
this.bufs.push([
|
|
376
391
|
n & 0xFF, // low byte is just the last 8 bits
|
|
377
392
|
(n >> 8) & 0xFF // shift right 8 bits to get the high byte
|
|
@@ -379,11 +394,11 @@ export class Writer {
|
|
|
379
394
|
return this
|
|
380
395
|
}
|
|
381
396
|
|
|
382
|
-
writeInt16LE (n: number):
|
|
397
|
+
writeInt16LE (n: number): this {
|
|
383
398
|
return this.writeUInt16LE(n & 0xFFFF) // Mask with 0xFFFF to get the lower 16 bits
|
|
384
399
|
}
|
|
385
400
|
|
|
386
|
-
writeUInt32BE (n: number):
|
|
401
|
+
writeUInt32BE (n: number): this {
|
|
387
402
|
this.bufs.push([
|
|
388
403
|
(n >> 24) & 0xFF, // highest byte
|
|
389
404
|
(n >> 16) & 0xFF,
|
|
@@ -393,11 +408,11 @@ export class Writer {
|
|
|
393
408
|
return this
|
|
394
409
|
}
|
|
395
410
|
|
|
396
|
-
writeInt32BE (n: number):
|
|
411
|
+
writeInt32BE (n: number): this {
|
|
397
412
|
return this.writeUInt32BE(n >>> 0) // Using unsigned right shift to handle negative numbers
|
|
398
413
|
}
|
|
399
414
|
|
|
400
|
-
writeUInt32LE (n: number):
|
|
415
|
+
writeUInt32LE (n: number): this {
|
|
401
416
|
this.bufs.push([
|
|
402
417
|
n & 0xFF, // lowest byte
|
|
403
418
|
(n >> 8) & 0xFF,
|
|
@@ -407,35 +422,35 @@ export class Writer {
|
|
|
407
422
|
return this
|
|
408
423
|
}
|
|
409
424
|
|
|
410
|
-
writeInt32LE (n: number):
|
|
425
|
+
writeInt32LE (n: number): this {
|
|
411
426
|
return this.writeUInt32LE(n >>> 0) // Using unsigned right shift to handle negative numbers
|
|
412
427
|
}
|
|
413
428
|
|
|
414
|
-
writeUInt64BEBn (bn: BigNumber):
|
|
429
|
+
writeUInt64BEBn (bn: BigNumber): this {
|
|
415
430
|
const buf = bn.toArray('be', 8)
|
|
416
431
|
this.write(buf)
|
|
417
432
|
return this
|
|
418
433
|
}
|
|
419
434
|
|
|
420
|
-
writeUInt64LEBn (bn: BigNumber):
|
|
435
|
+
writeUInt64LEBn (bn: BigNumber): this {
|
|
421
436
|
const buf = bn.toArray('be', 8)
|
|
422
437
|
this.writeReverse(buf)
|
|
423
438
|
return this
|
|
424
439
|
}
|
|
425
440
|
|
|
426
|
-
writeUInt64LE (n: number):
|
|
441
|
+
writeUInt64LE (n: number): this {
|
|
427
442
|
const buf = new BigNumber(n).toArray('be', 8)
|
|
428
443
|
this.writeReverse(buf)
|
|
429
444
|
return this
|
|
430
445
|
}
|
|
431
446
|
|
|
432
|
-
writeVarIntNum (n: number):
|
|
447
|
+
writeVarIntNum (n: number): this {
|
|
433
448
|
const buf = Writer.varIntNum(n)
|
|
434
449
|
this.write(buf)
|
|
435
450
|
return this
|
|
436
451
|
}
|
|
437
452
|
|
|
438
|
-
writeVarIntBn (bn: BigNumber):
|
|
453
|
+
writeVarIntBn (bn: BigNumber): this {
|
|
439
454
|
const buf = Writer.varIntBn(bn)
|
|
440
455
|
this.write(buf)
|
|
441
456
|
return this
|
|
@@ -696,13 +711,13 @@ export const minimallyEncode = (buf: number[]): number[] => {
|
|
|
696
711
|
if ((buf[i - 1] & 0x80) !== 0) {
|
|
697
712
|
// We found a byte with it sign bit set so we need one more
|
|
698
713
|
// byte.
|
|
699
|
-
buf[i
|
|
714
|
+
buf[i] = last
|
|
715
|
+
return buf.slice(0, i + 1)
|
|
700
716
|
} else {
|
|
701
717
|
// the sign bit is clear, we can use it.
|
|
702
718
|
buf[i - 1] |= last
|
|
719
|
+
return buf.slice(0, i)
|
|
703
720
|
}
|
|
704
|
-
|
|
705
|
-
return buf.slice(0, i)
|
|
706
721
|
}
|
|
707
722
|
}
|
|
708
723
|
|
package/src/totp/totp.ts
CHANGED
|
@@ -106,7 +106,6 @@ function generateHOTP (
|
|
|
106
106
|
options: Required<TOTPOptions>
|
|
107
107
|
): string {
|
|
108
108
|
const timePad = new BigNumber(counter).toArray('be', 8)
|
|
109
|
-
// console.log({ timePad })
|
|
110
109
|
const hmac = calcHMAC(secret, timePad, options.algorithm)
|
|
111
110
|
const signature = hmac.digest()
|
|
112
111
|
|
package/src/transaction/Beef.ts
CHANGED
|
@@ -5,12 +5,14 @@ import BeefTx from './BeefTx.js'
|
|
|
5
5
|
import { Reader, Writer, toHex, toArray } from '../primitives/utils.js'
|
|
6
6
|
import { hash256 } from '../primitives/Hash.js'
|
|
7
7
|
|
|
8
|
-
export const
|
|
9
|
-
export const
|
|
10
|
-
export const
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
export const BEEF_V1 = 4022206465 // 0100BEEF in LE order
|
|
9
|
+
export const BEEF_V2 = 4022206466 // 0200BEEF in LE order
|
|
10
|
+
export const ATOMIC_BEEF = 0x01010101 // 01010101
|
|
11
|
+
export enum TX_DATA_FORMAT {
|
|
12
|
+
RAWTX = 0, // rawtx without BUMP
|
|
13
|
+
RAWTX_AND_BUMP_INDEX = 1, // rawtx with bump index
|
|
14
|
+
TXID_ONLY = 2, // txid only
|
|
15
|
+
}
|
|
14
16
|
|
|
15
17
|
/*
|
|
16
18
|
* BEEF standard: BRC-62: Background Evaluation Extended Format (BEEF) Transactions
|
|
@@ -68,29 +70,13 @@ export type BeefVersion = undefined | 'V1' | 'V2'
|
|
|
68
70
|
export class Beef {
|
|
69
71
|
bumps: MerklePath[] = []
|
|
70
72
|
txs: BeefTx[] = []
|
|
71
|
-
version:
|
|
73
|
+
version: number = BEEF_V2
|
|
72
74
|
atomicTxid: string | undefined = undefined
|
|
73
75
|
|
|
74
|
-
constructor (version
|
|
76
|
+
constructor (version: number = BEEF_V2) {
|
|
75
77
|
this.version = version
|
|
76
78
|
}
|
|
77
79
|
|
|
78
|
-
/**
|
|
79
|
-
* BEEF_MAGIC is the original V1 version.
|
|
80
|
-
* BEEF_MAGIC_V2 includes support for txidOnly transactions in serialized beefs.
|
|
81
|
-
* @returns version magic value based on current contents and constructor version parameter.
|
|
82
|
-
*/
|
|
83
|
-
get magic (): number {
|
|
84
|
-
if (this.version === 'V1') { return BEEF_MAGIC }
|
|
85
|
-
|
|
86
|
-
if (this.version === 'V2') { return BEEF_MAGIC_V2 }
|
|
87
|
-
|
|
88
|
-
const hasTxidOnly = this.txs.findIndex(tx => tx.isTxidOnly) > -1
|
|
89
|
-
if (hasTxidOnly) { return BEEF_MAGIC_V2 }
|
|
90
|
-
|
|
91
|
-
return BEEF_MAGIC
|
|
92
|
-
}
|
|
93
|
-
|
|
94
80
|
/**
|
|
95
81
|
* @param txid of `beefTx` to find
|
|
96
82
|
* @returns `BeefTx` in `txs` with `txid`.
|
|
@@ -114,7 +100,7 @@ export class Beef {
|
|
|
114
100
|
if (i === -1) return undefined
|
|
115
101
|
let btx = this.txs[i]
|
|
116
102
|
if (btx.isTxidOnly) { return btx }
|
|
117
|
-
this.txs.
|
|
103
|
+
this.txs.splice(i, 1)
|
|
118
104
|
btx = this.mergeTxidOnly(txid)
|
|
119
105
|
return btx
|
|
120
106
|
}
|
|
@@ -296,8 +282,6 @@ export class Beef {
|
|
|
296
282
|
}
|
|
297
283
|
|
|
298
284
|
mergeTxidOnly (txid: string): BeefTx {
|
|
299
|
-
if (this.version === 'V1') { throw new Error('BEEF V1 format does not support txid only transactions.') }
|
|
300
|
-
|
|
301
285
|
let tx = this.txs.find(t => t.txid === txid)
|
|
302
286
|
if (!tx) {
|
|
303
287
|
tx = new BeefTx(txid)
|
|
@@ -309,12 +293,7 @@ export class Beef {
|
|
|
309
293
|
|
|
310
294
|
mergeBeefTx (btx: BeefTx): BeefTx {
|
|
311
295
|
let beefTx = this.findTxid(btx.txid)
|
|
312
|
-
if (btx.isTxidOnly && !beefTx)
|
|
313
|
-
beefTx = this.mergeTxidOnly(btx.txid)
|
|
314
|
-
else if (btx._tx && (!beefTx || beefTx.isTxidOnly))
|
|
315
|
-
beefTx = this.mergeTransaction(btx._tx)
|
|
316
|
-
else if (btx._rawTx && (!beefTx || beefTx.isTxidOnly))
|
|
317
|
-
beefTx = this.mergeRawTx(btx._rawTx)
|
|
296
|
+
if (btx.isTxidOnly && !beefTx) { beefTx = this.mergeTxidOnly(btx.txid) } else if (btx._tx && (!beefTx || beefTx.isTxidOnly)) { beefTx = this.mergeTransaction(btx._tx) } else if (btx._rawTx && (!beefTx || beefTx.isTxidOnly)) { beefTx = this.mergeRawTx(btx._rawTx) }
|
|
318
297
|
return beefTx
|
|
319
298
|
}
|
|
320
299
|
|
|
@@ -420,7 +399,7 @@ export class Beef {
|
|
|
420
399
|
* @param writer
|
|
421
400
|
*/
|
|
422
401
|
toWriter (writer: Writer) {
|
|
423
|
-
writer.writeUInt32LE(this.
|
|
402
|
+
writer.writeUInt32LE(this.version)
|
|
424
403
|
|
|
425
404
|
writer.writeVarIntNum(this.bumps.length)
|
|
426
405
|
for (const b of this.bumps) {
|
|
@@ -429,7 +408,7 @@ export class Beef {
|
|
|
429
408
|
|
|
430
409
|
writer.writeVarIntNum(this.txs.length)
|
|
431
410
|
for (const tx of this.txs) {
|
|
432
|
-
tx.toWriter(writer, this.
|
|
411
|
+
tx.toWriter(writer, this.version)
|
|
433
412
|
}
|
|
434
413
|
}
|
|
435
414
|
|
|
@@ -447,7 +426,7 @@ export class Beef {
|
|
|
447
426
|
* Serialize this Beef as AtomicBEEF.
|
|
448
427
|
*
|
|
449
428
|
* `txid` must exist
|
|
450
|
-
*
|
|
429
|
+
*
|
|
451
430
|
* after sorting, if txid is not last txid, creates a clone and removes newer txs
|
|
452
431
|
*
|
|
453
432
|
* @param txid
|
|
@@ -486,8 +465,8 @@ export class Beef {
|
|
|
486
465
|
atomicTxid = toHex(br.read(32))
|
|
487
466
|
version = br.readUInt32LE()
|
|
488
467
|
}
|
|
489
|
-
if (version !==
|
|
490
|
-
const beef = new Beef(version
|
|
468
|
+
if (version !== BEEF_V1 && version !== BEEF_V2) { throw new Error(`Serialized BEEF must start with ${BEEF_V1} or ${BEEF_V2} but starts with ${version}`) }
|
|
469
|
+
const beef = new Beef(version)
|
|
491
470
|
const bumpsLength = br.readVarIntNum()
|
|
492
471
|
for (let i = 0; i < bumpsLength; i++) {
|
|
493
472
|
const bump = MerklePath.fromReader(br, false)
|
|
@@ -518,8 +497,7 @@ export class Beef {
|
|
|
518
497
|
* @param enc The encoding of the string value from which BEEF should be constructed
|
|
519
498
|
* @returns An instance of the Beef class constructed from the string
|
|
520
499
|
*/
|
|
521
|
-
static fromString (s: string, enc
|
|
522
|
-
enc ||= 'hex'
|
|
500
|
+
static fromString (s: string, enc: 'hex' | 'utf8' | 'base64' = 'hex'): Beef {
|
|
523
501
|
const bin = toArray(s, enc)
|
|
524
502
|
const br = new Reader(bin)
|
|
525
503
|
return Beef.fromReader(br)
|
|
@@ -712,7 +690,7 @@ export class Beef {
|
|
|
712
690
|
* In some circumstances it may be helpful for the BUMP MerkePaths to include
|
|
713
691
|
* leaves that can be computed from row zero.
|
|
714
692
|
*/
|
|
715
|
-
addComputedLeaves() {
|
|
693
|
+
addComputedLeaves () {
|
|
716
694
|
const beef = this
|
|
717
695
|
const hash = (m: string): string => toHex((
|
|
718
696
|
hash256(toArray(m, 'hex').reverse())
|
|
@@ -724,7 +702,7 @@ export class Beef {
|
|
|
724
702
|
if (leafL.hash && (leafL.offset & 1) === 0) {
|
|
725
703
|
const leafR = bump.path[row - 1].find(l => l.offset === leafL.offset + 1)
|
|
726
704
|
const offsetOnRow = leafL.offset >> 1
|
|
727
|
-
if (leafR && leafR.hash &&
|
|
705
|
+
if (leafR && leafR.hash && bump.path[row].findIndex(l => l.offset === offsetOnRow) === -1) {
|
|
728
706
|
// computable leaf is missing... add it.
|
|
729
707
|
bump.path[row].push({
|
|
730
708
|
offset: offsetOnRow,
|
|
@@ -737,7 +715,6 @@ export class Beef {
|
|
|
737
715
|
}
|
|
738
716
|
}
|
|
739
717
|
}
|
|
740
|
-
|
|
741
718
|
}
|
|
742
719
|
|
|
743
720
|
export default Beef
|
|
@@ -41,7 +41,7 @@ export class BeefParty extends Beef {
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* @param party
|
|
44
|
-
* @returns `true` if `party` has already
|
|
44
|
+
* @returns `true` if `party` has already been added to this `BeefParty`.
|
|
45
45
|
*/
|
|
46
46
|
isParty (party: string) {
|
|
47
47
|
const r = Object.keys(this.knownTo).includes(party)
|