@bsv/sdk 1.1.26 → 1.1.28

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.
@@ -866,8 +866,8 @@ export default class BeefTx {
866
866
  get tx()
867
867
  get rawTx()
868
868
  constructor(tx: Transaction | number[] | string, bumpIndex?: number)
869
- toWriter(writer: Writer): void
870
- static fromReader(br: Reader): BeefTx
869
+ toWriter(writer: Writer, magic: number): void
870
+ static fromReader(br: Reader, magic: number): BeefTx
871
871
  }
872
872
  ```
873
873
 
@@ -899,8 +899,9 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
899
899
  export class Beef {
900
900
  bumps: MerklePath[] = [];
901
901
  txs: BeefTx[] = [];
902
- constructor()
903
- get version(): number
902
+ version: BeefVersion = undefined;
903
+ constructor(version?: BeefVersion)
904
+ get magic(): number
904
905
  findTxid(txid: string): BeefTx | undefined
905
906
  mergeBump(bump: MerklePath): number
906
907
  mergeRawTx(rawTx: number[], bumpIndex?: number): BeefTx
@@ -1869,6 +1870,7 @@ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](
1869
1870
 
1870
1871
  | |
1871
1872
  | --- |
1873
+ | [BeefVersion](#type-beefversion) |
1872
1874
  | [Fetch](#type-fetch) |
1873
1875
  | [HttpClientResponse](#type-httpclientresponse) |
1874
1876
 
@@ -1909,6 +1911,15 @@ export type Fetch = (url: string, options: FetchOptions) => Promise<Response>
1909
1911
 
1910
1912
  Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
1911
1913
 
1914
+ ---
1915
+ ### Type: BeefVersion
1916
+
1917
+ ```ts
1918
+ export type BeefVersion = undefined | "V1" | "V2"
1919
+ ```
1920
+
1921
+ Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables)
1922
+
1912
1923
  ---
1913
1924
  ## Variables
1914
1925
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bsv/sdk",
3
- "version": "1.1.26",
3
+ "version": "1.1.28",
4
4
  "type": "module",
5
5
  "description": "BSV Blockchain Software Development Kit",
6
6
  "main": "dist/cjs/mod.js",
@@ -133,6 +133,9 @@
133
133
  "import": "./dist/esm/src/totp/*.js",
134
134
  "require": "./dist/cjs/src/totp/*.js",
135
135
  "types": "./dist/types/src/totp/*.d.ts"
136
+ },
137
+ "./umd": {
138
+ "import": "./dist/umd/bundle.js"
136
139
  }
137
140
  },
138
141
  "scripts": {
@@ -140,7 +143,9 @@
140
143
  "test:watch": "npm run build && jest --watch",
141
144
  "test:coverage": "npm run build && jest --coverage",
142
145
  "lint": "ts-standard --fix src/**/*.ts",
143
- "build": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
146
+ "build": "npm run build:ts && npm run build:umd",
147
+ "build:ts": "tsc -b && tsconfig-to-dual-package tsconfig.cjs.json",
148
+ "build:umd": "webpack --config webpack.config.js",
144
149
  "dev": "tsc -b -w",
145
150
  "prepublish": "npm run build",
146
151
  "doc": "ts2md --inputFilename=src/script/index.ts --outputFilename=docs/script.md --filenameSubString=script --firstHeadingLevel=1 && ts2md --inputFilename=src/primitives/index.ts --outputFilename=docs/primitives.md --filenameSubString=primitives --firstHeadingLevel=1 && ts2md --inputFilename=src/transaction/index.ts --outputFilename=docs/transaction.md --filenameSubString=transaction --firstHeadingLevel=1 && ts2md --inputFilename=src/messages/index.ts --outputFilename=docs/messages.md --filenameSubString=messages --firstHeadingLevel=1 && ts2md --inputFilename=src/compat/index.ts --outputFilename=docs/compat.md --filenameSubString=compat --firstHeadingLevel=1"
@@ -166,9 +171,12 @@
166
171
  "@types/jest": "^29.5.5",
167
172
  "jest": "^29.7.0",
168
173
  "ts-jest": "^29.1.1",
174
+ "ts-loader": "^9.5.1",
169
175
  "ts-standard": "^12.0.2",
170
176
  "ts2md": "^0.2.0",
171
177
  "tsconfig-to-dual-package": "^1.2.0",
172
- "typescript": "^5.2.2"
178
+ "typescript": "^5.2.2",
179
+ "webpack": "^5.95.0",
180
+ "webpack-cli": "^5.1.4"
173
181
  }
174
182
  }
@@ -8,6 +8,8 @@ export const BEEF_MAGIC = 4022206465 // 0100BEEF in LE order
8
8
  export const BEEF_MAGIC_V2 = 4022206466 // 0200BEEF in LE order
9
9
  export const BEEF_MAGIC_TXID_ONLY_EXTENSION = 4022206465 // 0100BEEF in LE order
10
10
 
11
+ export type BeefVersion = undefined | 'V1' | 'V2'
12
+
11
13
  /*
12
14
  * BEEF standard: BRC-62: Background Evaluation Extended Format (BEEF) Transactions
13
15
  * https://github.com/bitcoin-sv/BRCs/blob/master/transactions/0062.md
@@ -50,21 +52,29 @@ export const BEEF_MAGIC_TXID_ONLY_EXTENSION = 4022206465 // 0100BEEF in LE order
50
52
  export class Beef {
51
53
  bumps: MerklePath[] = []
52
54
  txs: BeefTx[] = []
55
+ version: BeefVersion = undefined
53
56
 
54
- constructor() {
57
+ constructor(version?: BeefVersion) {
58
+ this.version = version
55
59
  }
56
60
 
57
61
  /**
58
62
  * BEEF_MAGIC is the original V1 version.
59
63
  * BEEF_MAGIC_V2 includes support for txidOnly transactions in serialized beefs.
60
- * @returns version based on current contents.
64
+ * @returns version magic value based on current contents and constructor version parameter.
61
65
  */
62
- get version(): number {
63
- const hasTxidOnly = !this.txs.every(tx => !tx.isTxidOnly)
66
+ get magic(): number {
67
+ if (this.version === 'V1')
68
+ return BEEF_MAGIC
69
+
70
+ if (this.version === 'V2')
71
+ return BEEF_MAGIC_V2
72
+
73
+ const hasTxidOnly = -1 < this.txs.findIndex(tx => tx.isTxidOnly)
64
74
  if (hasTxidOnly)
65
75
  return BEEF_MAGIC_V2
66
- else
67
- return BEEF_MAGIC
76
+
77
+ return BEEF_MAGIC
68
78
  }
69
79
 
70
80
  /**
@@ -184,6 +194,9 @@ export class Beef {
184
194
  }
185
195
 
186
196
  mergeTxidOnly(txid: string): BeefTx {
197
+ if (this.version === 'V1')
198
+ throw new Error(`BEEF V1 format does not support txid only transactions.`)
199
+
187
200
  let tx = this.txs.find(t => t.txid === txid)
188
201
  if (!tx) {
189
202
  tx = new BeefTx(txid)
@@ -317,7 +330,7 @@ export class Beef {
317
330
  toBinary(): number[] {
318
331
 
319
332
  const writer = new Writer()
320
- writer.writeUInt32LE(this.version)
333
+ writer.writeUInt32LE(this.magic)
321
334
 
322
335
  writer.writeVarIntNum(this.bumps.length)
323
336
  for (const b of this.bumps) {
@@ -326,7 +339,7 @@ export class Beef {
326
339
 
327
340
  writer.writeVarIntNum(this.txs.length)
328
341
  for (const tx of this.txs) {
329
- tx.toWriter(writer)
342
+ tx.toWriter(writer, this.magic)
330
343
  }
331
344
 
332
345
  return writer.toArray()
@@ -344,7 +357,7 @@ export class Beef {
344
357
  const version = br.readUInt32LE()
345
358
  if (version !== BEEF_MAGIC && version !== BEEF_MAGIC_V2)
346
359
  throw new Error(`Serialized BEEF must start with ${BEEF_MAGIC} or ${BEEF_MAGIC_V2} but starts with ${version}`)
347
- const beef = new Beef()
360
+ const beef = new Beef(version === BEEF_MAGIC_V2 ? 'V2' : undefined)
348
361
  const bumpsLength = br.readVarIntNum()
349
362
  for (let i = 0; i < bumpsLength; i++) {
350
363
  const bump = MerklePath.fromReader(br)
@@ -352,7 +365,7 @@ export class Beef {
352
365
  }
353
366
  const txsLength = br.readVarIntNum()
354
367
  for (let i = 0; i < txsLength; i++) {
355
- const beefTx = BeefTx.fromReader(br)
368
+ const beefTx = BeefTx.fromReader(br, version)
356
369
  beef.txs.push(beefTx)
357
370
  }
358
371
  return beef
@@ -1,7 +1,7 @@
1
1
  import { hash256 } from "../primitives/Hash.js"
2
2
  import { Reader, Writer, toHex, toArray } from "../primitives/utils.js"
3
3
  import Transaction from "./Transaction.js"
4
- import { BEEF_MAGIC_TXID_ONLY_EXTENSION } from "./Beef.js"
4
+ import { BEEF_MAGIC, BEEF_MAGIC_TXID_ONLY_EXTENSION } from "./Beef.js"
5
5
 
6
6
  /**
7
7
  * A single bitcoin transaction associated with a `Beef` validity proof set.
@@ -84,36 +84,77 @@ export default class BeefTx {
84
84
  }
85
85
  }
86
86
 
87
- toWriter(writer: Writer) : void {
88
- if (this.isTxidOnly) {
89
- // Encode just the txid of a known transaction using the txid
90
- writer.writeUInt32LE(BEEF_MAGIC_TXID_ONLY_EXTENSION)
91
- writer.writeReverse(toArray(this._txid, 'hex'))
92
- } else if (this._rawTx)
93
- writer.write(this._rawTx)
94
- else if (this._tx)
95
- writer.write(this._tx.toBinary())
96
- else
97
- throw new Error('a valid serialized Transaction is expected')
98
- if (this.bumpIndex === undefined) {
99
- writer.writeUInt8(0)
87
+ toWriter(writer: Writer, magic: number) : void {
88
+ if (magic === BEEF_MAGIC) {
89
+ // V1
90
+ if (this.isTxidOnly) {
91
+ // Encode just the txid of a known transaction using the txid
92
+ writer.writeUInt32LE(BEEF_MAGIC_TXID_ONLY_EXTENSION)
93
+ writer.writeReverse(toArray(this._txid, 'hex'))
94
+ } else if (this._rawTx)
95
+ writer.write(this._rawTx)
96
+ else if (this._tx)
97
+ writer.write(this._tx.toBinary())
98
+ else
99
+ throw new Error('a valid serialized Transaction is expected')
100
+ if (this.bumpIndex === undefined) {
101
+ writer.writeUInt8(0)
102
+ } else {
103
+ writer.writeUInt8(1)
104
+ writer.writeVarIntNum(this.bumpIndex)
105
+ }
100
106
  } else {
101
- writer.writeUInt8(1)
102
- writer.writeVarIntNum(this.bumpIndex)
107
+ // V2
108
+ if (this.isTxidOnly) {
109
+ // Encode just the txid of a known transaction using the txid
110
+ writer.writeUInt8(2)
111
+ writer.writeReverse(toArray(this._txid, 'hex'))
112
+ } else {
113
+ if (this.bumpIndex === undefined) {
114
+ writer.writeUInt8(0)
115
+ } else {
116
+ writer.writeUInt8(1)
117
+ writer.writeVarIntNum(this.bumpIndex)
118
+ }
119
+ if (this._rawTx)
120
+ writer.write(this._rawTx)
121
+ else if (this._tx)
122
+ writer.write(this._tx.toBinary())
123
+ else
124
+ throw new Error('a valid serialized Transaction is expected')
125
+ }
103
126
  }
104
127
  }
105
128
 
106
- static fromReader (br: Reader): BeefTx {
129
+ static fromReader (br: Reader, magic: number): BeefTx {
130
+
107
131
  let tx: Transaction | number[] | string | undefined = undefined
108
- const version = br.readUInt32LE()
109
- if (version === BEEF_MAGIC_TXID_ONLY_EXTENSION) {
110
- // This is the extension to support known transactions
111
- tx = toHex(br.readReverse(32))
132
+ let bumpIndex: number | undefined = undefined
133
+
134
+ if (magic === BEEF_MAGIC) {
135
+ // V1
136
+ const version = br.readUInt32LE()
137
+ if (version === BEEF_MAGIC_TXID_ONLY_EXTENSION) {
138
+ // This is the extension to support known transactions
139
+ tx = toHex(br.readReverse(32))
140
+ } else {
141
+ br.pos -= 4 // Unread the version...
142
+ tx = Transaction.fromReader(br)
143
+ }
144
+ bumpIndex = br.readUInt8() ? br.readVarIntNum() : undefined
112
145
  } else {
113
- br.pos -= 4 // Unread the version...
114
- tx = Transaction.fromReader(br)
146
+ // V2
147
+ const format = br.readUInt8()
148
+ if (format === 2) {
149
+ // txid only
150
+ tx = toHex(br.readReverse(32))
151
+ } else {
152
+ if (format === 1)
153
+ bumpIndex = br.readVarIntNum()
154
+ tx = Transaction.fromReader(br)
155
+ }
115
156
  }
116
- const bumpIndex = br.readUInt8() ? br.readVarIntNum() : undefined
157
+
117
158
  const beefTx = new BeefTx(tx, bumpIndex)
118
159
  return beefTx
119
160
  }