@bsv/sdk 1.10.2 → 1.10.3

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 (63) hide show
  1. package/dist/cjs/package.json +1 -1
  2. package/dist/cjs/src/primitives/ReaderUint8Array.js +180 -0
  3. package/dist/cjs/src/primitives/ReaderUint8Array.js.map +1 -0
  4. package/dist/cjs/src/primitives/WriterUint8Array.js +173 -0
  5. package/dist/cjs/src/primitives/WriterUint8Array.js.map +1 -0
  6. package/dist/cjs/src/primitives/utils.js +20 -2
  7. package/dist/cjs/src/primitives/utils.js.map +1 -1
  8. package/dist/cjs/src/transaction/Beef.js +85 -27
  9. package/dist/cjs/src/transaction/Beef.js.map +1 -1
  10. package/dist/cjs/src/transaction/BeefTx.js +32 -14
  11. package/dist/cjs/src/transaction/BeefTx.js.map +1 -1
  12. package/dist/cjs/src/transaction/MerklePath.js +25 -6
  13. package/dist/cjs/src/transaction/MerklePath.js.map +1 -1
  14. package/dist/cjs/src/transaction/Transaction.js +77 -26
  15. package/dist/cjs/src/transaction/Transaction.js.map +1 -1
  16. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  17. package/dist/esm/src/primitives/ReaderUint8Array.js +176 -0
  18. package/dist/esm/src/primitives/ReaderUint8Array.js.map +1 -0
  19. package/dist/esm/src/primitives/WriterUint8Array.js +169 -0
  20. package/dist/esm/src/primitives/WriterUint8Array.js.map +1 -0
  21. package/dist/esm/src/primitives/utils.js +18 -1
  22. package/dist/esm/src/primitives/utils.js.map +1 -1
  23. package/dist/esm/src/transaction/Beef.js +86 -28
  24. package/dist/esm/src/transaction/Beef.js.map +1 -1
  25. package/dist/esm/src/transaction/BeefTx.js +33 -15
  26. package/dist/esm/src/transaction/BeefTx.js.map +1 -1
  27. package/dist/esm/src/transaction/MerklePath.js +26 -7
  28. package/dist/esm/src/transaction/MerklePath.js.map +1 -1
  29. package/dist/esm/src/transaction/Transaction.js +78 -27
  30. package/dist/esm/src/transaction/Transaction.js.map +1 -1
  31. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  32. package/dist/types/src/primitives/ReaderUint8Array.d.ts +32 -0
  33. package/dist/types/src/primitives/ReaderUint8Array.d.ts.map +1 -0
  34. package/dist/types/src/primitives/WriterUint8Array.d.ts +54 -0
  35. package/dist/types/src/primitives/WriterUint8Array.d.ts.map +1 -0
  36. package/dist/types/src/primitives/utils.d.ts +15 -3
  37. package/dist/types/src/primitives/utils.d.ts.map +1 -1
  38. package/dist/types/src/transaction/Beef.d.ts +24 -7
  39. package/dist/types/src/transaction/Beef.d.ts.map +1 -1
  40. package/dist/types/src/transaction/BeefTx.d.ts +13 -6
  41. package/dist/types/src/transaction/BeefTx.d.ts.map +1 -1
  42. package/dist/types/src/transaction/MerklePath.d.ts +16 -3
  43. package/dist/types/src/transaction/MerklePath.d.ts.map +1 -1
  44. package/dist/types/src/transaction/Transaction.d.ts +44 -7
  45. package/dist/types/src/transaction/Transaction.d.ts.map +1 -1
  46. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  47. package/dist/umd/bundle.js +3 -3
  48. package/dist/umd/bundle.js.map +1 -1
  49. package/docs/reference/primitives.md +167 -29
  50. package/docs/reference/script.md +1 -1
  51. package/docs/reference/transaction.md +177 -34
  52. package/package.json +1 -1
  53. package/src/overlay-tools/__tests/SHIPBroadcaster.test.ts +9 -0
  54. package/src/primitives/ReaderUint8Array.ts +196 -0
  55. package/src/primitives/WriterUint8Array.ts +195 -0
  56. package/src/primitives/__tests/ReaderUint8Array.test.ts +317 -0
  57. package/src/primitives/__tests/WriterUint8Array.test.ts +208 -0
  58. package/src/primitives/utils.ts +20 -2
  59. package/src/transaction/Beef.ts +103 -40
  60. package/src/transaction/BeefTx.ts +38 -19
  61. package/src/transaction/MerklePath.ts +30 -9
  62. package/src/transaction/Transaction.ts +91 -38
  63. package/src/transaction/__tests/Beef.test.ts +75 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.10.2",
3
+ "version": "1.10.3",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -339,8 +339,12 @@ describe('SHIPCast', () => {
339
339
  })
340
340
  const testTx = new Transaction(1, [], [], 0)
341
341
 
342
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { })
343
+
342
344
  const result = await b.broadcast(testTx)
343
345
 
346
+ expect(consoleErrorSpy).toHaveBeenCalled()
347
+
344
348
  expect(result).toEqual({
345
349
  status: 'error',
346
350
  code: 'ERR_ALL_HOSTS_REJECTED',
@@ -1076,8 +1080,13 @@ describe('SHIPCast', () => {
1076
1080
  resolver: mockResolver as unknown as LookupResolver
1077
1081
  })
1078
1082
  const testTx = new Transaction(1, [], [], 0)
1083
+
1084
+ const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => { })
1085
+
1079
1086
  const response = await b.broadcast(testTx)
1080
1087
 
1088
+ expect(consoleErrorSpy).toHaveBeenCalled()
1089
+
1081
1090
  // Since the host responded (successfully in terms of HTTP), but with invalid data, we should consider it a failure
1082
1091
  expect(response).toEqual({
1083
1092
  status: 'error',
@@ -0,0 +1,196 @@
1
+ import BigNumber from './BigNumber.js'
2
+ import { Reader } from './utils.js'
3
+
4
+ /**
5
+ * Reader for serialized Uint8Array binary data.
6
+ */
7
+ export class ReaderUint8Array {
8
+ public bin: Uint8Array
9
+ public pos: number
10
+ private readonly length: number
11
+
12
+ static makeReader (bin: Uint8Array | number[], pos: number = 0): Reader | ReaderUint8Array {
13
+ if (bin instanceof Uint8Array) {
14
+ return new ReaderUint8Array(bin, pos)
15
+ }
16
+ if (Array.isArray(bin)) {
17
+ return new Reader(bin, pos)
18
+ }
19
+ throw new Error('ReaderUint8Array.makeReader: bin must be Uint8Array or number[]')
20
+ }
21
+
22
+ constructor (bin: Uint8Array | number[] = new Uint8Array(0), pos: number = 0) {
23
+ if (bin instanceof Uint8Array) {
24
+ this.bin = bin
25
+ } else if (Array.isArray(bin)) {
26
+ this.bin = new Uint8Array(bin)
27
+ } else {
28
+ throw new Error('ReaderUint8Array constructor: bin must be Uint8Array or number[]')
29
+ }
30
+ this.pos = pos
31
+ this.length = this.bin.length
32
+ }
33
+
34
+ public eof (): boolean {
35
+ return this.pos >= this.length
36
+ }
37
+
38
+ public read (len = this.length): Uint8Array {
39
+ const start = this.pos
40
+ const end = this.pos + len
41
+ this.pos = end
42
+ return this.bin.slice(start, end)
43
+ }
44
+
45
+ public readReverse (len = this.length): Uint8Array {
46
+ const buf2 = new Uint8Array(len)
47
+ for (let i = 0; i < len; i++) {
48
+ buf2[i] = this.bin[this.pos + len - 1 - i]
49
+ }
50
+ this.pos += len
51
+ return buf2
52
+ }
53
+
54
+ public readUInt8 (): number {
55
+ const val = this.bin[this.pos]
56
+ this.pos += 1
57
+ return val
58
+ }
59
+
60
+ public readInt8 (): number {
61
+ const val = this.bin[this.pos]
62
+ this.pos += 1
63
+ // If the sign bit is set, convert to negative value
64
+ return (val & 0x80) !== 0 ? val - 0x100 : val
65
+ }
66
+
67
+ public readUInt16BE (): number {
68
+ const val = (this.bin[this.pos] << 8) | this.bin[this.pos + 1]
69
+ this.pos += 2
70
+ return val
71
+ }
72
+
73
+ public readInt16BE (): number {
74
+ const val = this.readUInt16BE()
75
+ // If the sign bit is set, convert to negative value
76
+ return (val & 0x8000) !== 0 ? val - 0x10000 : val
77
+ }
78
+
79
+ public readUInt16LE (): number {
80
+ const val = this.bin[this.pos] | (this.bin[this.pos + 1] << 8)
81
+ this.pos += 2
82
+ return val
83
+ }
84
+
85
+ public readInt16LE (): number {
86
+ const val = this.readUInt16LE()
87
+ // If the sign bit is set, convert to negative value
88
+ const x = (val & 0x8000) !== 0 ? val - 0x10000 : val
89
+ return x
90
+ }
91
+
92
+ public readUInt32BE (): number {
93
+ const val =
94
+ this.bin[this.pos] * 0x1000000 + // Shift the first byte by 24 bits
95
+ ((this.bin[this.pos + 1] << 16) | // Shift the second byte by 16 bits
96
+ (this.bin[this.pos + 2] << 8) | // Shift the third byte by 8 bits
97
+ this.bin[this.pos + 3]) // The fourth byte
98
+ this.pos += 4
99
+ return val
100
+ }
101
+
102
+ public readInt32BE (): number {
103
+ const val = this.readUInt32BE()
104
+ // If the sign bit is set, convert to negative value
105
+ return (val & 0x80000000) !== 0 ? val - 0x100000000 : val
106
+ }
107
+
108
+ public readUInt32LE (): number {
109
+ const val =
110
+ (this.bin[this.pos] |
111
+ (this.bin[this.pos + 1] << 8) |
112
+ (this.bin[this.pos + 2] << 16) |
113
+ (this.bin[this.pos + 3] << 24)) >>>
114
+ 0
115
+ this.pos += 4
116
+ return val
117
+ }
118
+
119
+ public readInt32LE (): number {
120
+ const val = this.readUInt32LE()
121
+ // Explicitly check if the sign bit is set and then convert to a negative value
122
+ return (val & 0x80000000) !== 0 ? val - 0x100000000 : val
123
+ }
124
+
125
+ public readUInt64BEBn (): BigNumber {
126
+ const bin = Array.from(this.bin.slice(this.pos, this.pos + 8))
127
+ const bn = new BigNumber(bin)
128
+ this.pos = this.pos + 8
129
+ return bn
130
+ }
131
+
132
+ public readUInt64LEBn (): BigNumber {
133
+ const bin = Array.from(this.readReverse(8))
134
+ const bn = new BigNumber(bin)
135
+ return bn
136
+ }
137
+
138
+ public readInt64LEBn (): BigNumber {
139
+ const OverflowInt64 = new BigNumber(2).pow(new BigNumber(63))
140
+ const OverflowUint64 = new BigNumber(2).pow(new BigNumber(64))
141
+ const bin = Array.from(this.readReverse(8))
142
+ let bn = new BigNumber(bin)
143
+ if (bn.gte(OverflowInt64)) {
144
+ bn = bn.sub(OverflowUint64) // Adjust for negative numbers
145
+ }
146
+ return bn
147
+ }
148
+
149
+ public readVarIntNum (signed: boolean = true): number {
150
+ const first = this.readUInt8()
151
+ let bn: BigNumber
152
+ switch (first) {
153
+ case 0xfd:
154
+ return this.readUInt16LE()
155
+ case 0xfe:
156
+ return this.readUInt32LE()
157
+ case 0xff:
158
+ bn = signed ? this.readInt64LEBn() : this.readUInt64LEBn()
159
+ if (bn.lte(new BigNumber(2).pow(new BigNumber(53)))) {
160
+ return bn.toNumber()
161
+ } else {
162
+ throw new Error('number too large to retain precision - use readVarIntBn')
163
+ }
164
+ default:
165
+ return first
166
+ }
167
+ }
168
+
169
+ public readVarInt (): Uint8Array {
170
+ const first = this.bin[this.pos]
171
+ switch (first) {
172
+ case 0xfd:
173
+ return this.read(1 + 2)
174
+ case 0xfe:
175
+ return this.read(1 + 4)
176
+ case 0xff:
177
+ return this.read(1 + 8)
178
+ default:
179
+ return this.read(1)
180
+ }
181
+ }
182
+
183
+ public readVarIntBn (): BigNumber {
184
+ const first = this.readUInt8()
185
+ switch (first) {
186
+ case 0xfd:
187
+ return new BigNumber(this.readUInt16LE())
188
+ case 0xfe:
189
+ return new BigNumber(this.readUInt32LE())
190
+ case 0xff:
191
+ return this.readUInt64LEBn()
192
+ default:
193
+ return new BigNumber(first)
194
+ }
195
+ }
196
+ }
@@ -0,0 +1,195 @@
1
+ import BigNumber from './BigNumber.js'
2
+ import { Writer } from './utils.js'
3
+
4
+ type WriterChunk = readonly number[] | Uint8Array
5
+
6
+ /**
7
+ * WriterUint8Array is a utility class for writing binary data into a dynamically
8
+ * growing Uint8Array buffer. It provides methods to write various integer types
9
+ * and variable-length integers, similar to the Writer class but optimized for
10
+ * Uint8Array usage.
11
+ */
12
+ export class WriterUint8Array {
13
+ private buffer: Uint8Array
14
+ private pos: number
15
+ private capacity: number
16
+
17
+ constructor (bufs?: WriterChunk[], initialCapacity: number = 256) {
18
+ if ((bufs != null) && bufs.length > 0) {
19
+ const totalLength = bufs.reduce((sum, buf) => sum + buf.length, 0)
20
+ initialCapacity = Math.max(initialCapacity, totalLength)
21
+ }
22
+ this.buffer = new Uint8Array(initialCapacity)
23
+ this.pos = 0
24
+ this.capacity = initialCapacity
25
+ if (bufs != null) {
26
+ for (const buf of bufs) {
27
+ this.write(buf)
28
+ }
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Returns the current length of written data
34
+ */
35
+ getLength (): number {
36
+ return this.pos
37
+ }
38
+
39
+ /**
40
+ * @return the written data as Uint8Array copy of the internal buffer
41
+ */
42
+ toUint8Array (): Uint8Array {
43
+ return this.buffer.slice(0, this.pos)
44
+ }
45
+
46
+ /**
47
+ * Legacy compatibility method – returns number[] (Byte[])
48
+ */
49
+ toArray (): number[] {
50
+ return Array.from(this.toUint8Array())
51
+ }
52
+
53
+ /**
54
+ * @return the written data as Uint8Array. CAUTION: This is zero-copy subarray of the internal buffer).
55
+ */
56
+ toUint8ArrayZeroCopy (): Uint8Array {
57
+ return this.buffer.subarray(0, this.pos)
58
+ }
59
+
60
+ private ensureCapacity (needed: number): void {
61
+ if (this.pos + needed > this.capacity) {
62
+ let newCapacity = this.capacity * 2
63
+ while (this.pos + needed > newCapacity) {
64
+ newCapacity *= 2
65
+ }
66
+ const newBuffer = new Uint8Array(newCapacity)
67
+ newBuffer.set(this.buffer)
68
+ this.buffer = newBuffer
69
+ this.capacity = newCapacity
70
+ }
71
+ }
72
+
73
+ write (bytes: WriterChunk): this {
74
+ const data = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)
75
+ this.ensureCapacity(data.length)
76
+ this.buffer.set(data, this.pos)
77
+ this.pos += data.length
78
+ return this
79
+ }
80
+
81
+ writeReverse (buf: WriterChunk): this {
82
+ const data = buf instanceof Uint8Array ? buf : new Uint8Array(buf)
83
+ this.ensureCapacity(data.length)
84
+ for (let i = data.length - 1; i >= 0; i--) {
85
+ this.buffer[this.pos] = data[i]
86
+ this.pos += 1
87
+ }
88
+ return this
89
+ }
90
+
91
+ writeUInt8 (value: number): this {
92
+ this.ensureCapacity(1)
93
+ this.buffer[this.pos] = value & 0xff
94
+ this.pos += 1
95
+ return this
96
+ }
97
+
98
+ writeInt8 (value: number): this {
99
+ this.writeUInt8(value)
100
+ return this
101
+ }
102
+
103
+ writeUInt16LE (value: number): this {
104
+ this.ensureCapacity(2)
105
+ this.buffer[this.pos] = value & 0xff
106
+ this.buffer[this.pos + 1] = (value >> 8) & 0xff
107
+ this.pos += 2
108
+ return this
109
+ }
110
+
111
+ writeUInt16BE (value: number): this {
112
+ this.ensureCapacity(2)
113
+ this.buffer[this.pos] = (value >> 8) & 0xff
114
+ this.buffer[this.pos + 1] = value & 0xff
115
+ this.pos += 2
116
+ return this
117
+ }
118
+
119
+ writeInt16LE (value: number): this {
120
+ this.writeUInt16LE(value & 0xffff)
121
+ return this
122
+ }
123
+
124
+ writeInt16BE (value: number): this {
125
+ this.writeUInt16BE(value & 0xffff)
126
+ return this
127
+ }
128
+
129
+ writeUInt32LE (value: number): this {
130
+ this.ensureCapacity(4)
131
+ this.buffer[this.pos] = value & 0xff
132
+ this.buffer[this.pos + 1] = (value >> 8) & 0xff
133
+ this.buffer[this.pos + 2] = (value >> 16) & 0xff
134
+ this.buffer[this.pos + 3] = (value >> 24) & 0xff
135
+ this.pos += 4
136
+ return this
137
+ }
138
+
139
+ writeUInt32BE (value: number): this {
140
+ this.ensureCapacity(4)
141
+ this.buffer[this.pos] = (value >> 24) & 0xff
142
+ this.buffer[this.pos + 1] = (value >> 16) & 0xff
143
+ this.buffer[this.pos + 2] = (value >> 8) & 0xff
144
+ this.buffer[this.pos + 3] = value & 0xff
145
+ this.pos += 4
146
+ return this
147
+ }
148
+
149
+ writeInt32LE (value: number): this {
150
+ this.writeUInt32LE(value >>> 0)
151
+ return this
152
+ }
153
+
154
+ writeInt32BE (value: number): this {
155
+ this.writeUInt32BE(value >>> 0)
156
+ return this
157
+ }
158
+
159
+ writeUInt64BEBn (bn: BigNumber): this {
160
+ const buf = bn.toArray('be', 8)
161
+ this.write(buf)
162
+ return this
163
+ }
164
+
165
+ writeUInt64LEBn (bn: BigNumber): this {
166
+ const buf = bn.toArray('be', 8)
167
+ this.writeReverse(buf)
168
+ return this
169
+ }
170
+
171
+ writeUInt64LE (n: number): this {
172
+ const buf = new BigNumber(n).toArray('be', 8)
173
+ this.writeReverse(buf)
174
+ return this
175
+ }
176
+
177
+ writeVarIntNum (n: number): this {
178
+ const buf = Writer.varIntNum(n)
179
+ this.write(buf)
180
+ return this
181
+ }
182
+
183
+ writeVarIntBn (bn: BigNumber): this {
184
+ const buf = Writer.varIntBn(bn)
185
+ this.write(buf)
186
+ return this
187
+ }
188
+
189
+ /**
190
+ * Resets the writer to empty state (reuses the buffer)
191
+ */
192
+ reset (): void {
193
+ this.pos = 0
194
+ }
195
+ }