@smartledger/bsv 9.15.0 → 9.16.1

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.
@@ -34,12 +34,12 @@ module sounds. That is a deliberate revision: an earlier version of this documen
34
34
  scoped Tier 1 as "the cryptographic core" and would have excluded four of the six real
35
35
  defects this codebase has produced. See §2.1.
36
36
 
37
- ### Tier 1 — 12,158 lines
37
+ ### Tier 1 — 12,181 lines
38
38
 
39
39
  | Module | Lines | Why it matters |
40
40
  | --- | ---: | --- |
41
41
  | `lib/transaction/` | 2,786 | Sighash construction and signing — both BIP-143 and the Original Transaction Digest Algorithm. |
42
- | `lib/script/interpreter.js` | 2,920 | **Scoped to the flag and era surface, not opcode execution.** Consensus-flag selection and defaults, era derivation (Genesis/Chronicle), the limits derived from them, and the semantics of the exported `verify()`. Opcode execution is excluded — see §2.2. |
42
+ | `lib/script/interpreter.js` | 2,943 | **Scoped to the flag and era surface, not opcode execution.** Consensus-flag selection and defaults, era derivation (Genesis/Chronicle), the limits derived from them, and the semantics of the exported `verify()`. Opcode execution is excluded — see §2.2. |
43
43
  | `lib/crypto/` | 2,519 | ECDSA, nonce derivation, signature encoding, the script-number type. **Scope this for an architectural judgement as well as for bugs** — see §2.3. |
44
44
  | `lib/notaryhash/` | 2,104 | BRC-220 signing and verification. Publicly reachable and relied on downstream. |
45
45
  | `lib/privatekey.js`, `lib/publickey.js` | 843 | Key construction, serialisation, WIF. Recent defects here produced a *different* key without error. |
@@ -150,14 +150,14 @@ this repository.
150
150
  | `lib/address.js`, `lib/networks.js`, `lib/opcode.js`, `lib/hdprivatekey.js`, `lib/hdpublickey.js` (2,391 lines) | Cut to pay for §2.1 | Formatting, network constants and BIP-32 derivation. No defect has originated here, and `networks.js` in particular defines addressing constants — pubkey hashes, xpub prefixes, ports, DNS seeds — and contains **no consensus-flag logic at all**. |
151
151
  | The rest of the application layer — `lib/gdaf/`, `lib/ltp/`, `lib/ordinals/`, `lib/block/`, `lib/didweb/`, `lib/vcjwt/`, `lib/statuslist/`, most of `lib/smart_contract/`, plus assorted top-level files | Excluded | ~26,000 lines. Worth a separate engagement; including it here would blur the question in §1. Note the parts of it with a demonstrated defect history have been pulled *into* Tier 1 rather than left here — see §2.1. |
152
152
 
153
- Totals reconcile against `lib/`, which is 40,181 lines across 131 files:
153
+ Totals reconcile against `lib/`, which is 40,204 lines across 131 files:
154
154
 
155
155
  ```
156
- tier 1 12,158
156
+ tier 1 12,181
157
157
  tier 2 1,607
158
158
  excluded 26,416
159
159
  ------
160
- total 40,181
160
+ total 40,204
161
161
  ```
162
162
 
163
163
  Measured 2026-08-29 at `a954c27`. These figures drift as the library changes — an
@@ -228,7 +228,7 @@ seeking a quote for an independent security review.
228
228
 
229
229
  Scope, and we would like these priced separately:
230
230
 
231
- Tier 1 — 12,158 lines. Sighash construction and signing; ECDSA, nonce
231
+ Tier 1 — 12,181 lines. Sighash construction and signing; ECDSA, nonce
232
232
  derivation and signature encoding; the consensus-flag and era-derivation
233
233
  surface of the script interpreter; BRC-220 signing and verification;
234
234
  key construction and serialisation; the covenant verification harness and
@@ -5,10 +5,22 @@ in a leaf. This proposes the definition, with the reasoning that led to it.
5
5
 
6
6
  Prepared 2026-08-17 while implementing BRC-220 in `@smartledger/bsv`.
7
7
 
8
- **Status: filed** as [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246)
9
- on 2026-09-11, together with a clarification of the ECDSA digest convention. Its review
10
- asked that `leafIndex` be stated as counted from 0 and that the vector say how `i` is
11
- written; both are in #246 and below. Before filing
8
+ **Status: MERGED** as [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246),
9
+ filed 2026-09-11 and merged **2026-09-18**, together with a clarification of the ECDSA digest
10
+ convention. Its review asked that `leafIndex` be stated as counted from 0 and that the vector say
11
+ how `i` is written; both are in #246 and below.
12
+
13
+ **The merged spec is the authority, not this document.** The maintainers reflowed the wording
14
+ before merging — denser sentences, `SHA256` rather than `SHA-256` — so the blockquotes below are
15
+ what was *proposed*, and ten of their fourteen lines no longer appear verbatim in
16
+ [`apps/0220.md`](https://github.com/bsv-blockchain/BRCs/blob/master/apps/0220.md). **The rule
17
+ merged unchanged in substance**, which was checked rather than assumed: this library reproduces
18
+ the merged spec's own published batch example exactly — root
19
+ `abb53eb3b2e3530d51685c6813bb85c85892d2f214c2dc504029d071434ac074` and leaf 4's audit path of a
20
+ single `left` sibling `060ca4e4…befd`, from `test/data/brc220-batch-vector.json` through
21
+ `lib/notaryhash/merkle.js`. Quote the merged text, not this.
22
+
23
+ Before filing
12
24
  it was checked against the BRC-220 reference implementation, whose batcher uses exactly
13
25
  this leaf (`leaves = batch.map(e => e.proofHash)`), and the vector below was rebuilt
14
26
  without any of this library's code — the root from the reference's own RFC 6962 tree.
@@ -6,10 +6,17 @@ implementation writes, and two rules for reading them. With both, any implementa
6
6
  produces certificates the reference verifies, and reads certificates the way the reference
7
7
  does.
8
8
 
9
- Prepared 2026-09-11, with the open points decided [below](#decisions). **Status: filed**
10
- as [bsv-blockchain/BRCs#247](https://github.com/bsv-blockchain/BRCs/pull/247) on 2026-09-11. It is meant to be a separate pull request from
11
- [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246), which is under
12
- review and deliberately narrow; this text builds on it for the batch leaf datum.
9
+ Prepared 2026-09-11, with the open points decided [below](#decisions). **Status: MERGED** as
10
+ [bsv-blockchain/BRCs#247](https://github.com/bsv-blockchain/BRCs/pull/247), filed 2026-09-11 and
11
+ merged **2026-09-18**. It was a separate pull request from
12
+ [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246), deliberately narrow
13
+ and merged the same day; this text builds on it for the batch leaf datum.
14
+
15
+ **The merged spec is the authority, not this document.** Eight of the sixty-nine lines quoted
16
+ below were reworded before merging. The substance is unchanged — the field values and the two
17
+ reading rules are as proposed — but quote
18
+ [`apps/0220.md`](https://github.com/bsv-blockchain/BRCs/blob/master/apps/0220.md) rather than
19
+ this file.
13
20
 
14
21
  ---
15
22
 
@@ -179,8 +179,11 @@ summarising rather than anything in the document.
179
179
  document, in the `proofHash` definition, and nowhere in the batch text. We read `d` as
180
180
  `proofHash`; so does the reference implementation's batcher, and given the same five
181
181
  proofs it builds the same root. Reading it as `canonicalBytes` is equally sound and
182
- produces a different root, so the two do not interoperate. Filed upstream as
183
- [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246); see
182
+ produces a different root, so the two do not interoperate. **Settled upstream: merged as
183
+ [bsv-blockchain/BRCs#246](https://github.com/bsv-blockchain/BRCs/pull/246) on 2026-09-18**, so
184
+ `d = proofHash` is now what BRC-220 says rather than how we read it. This library reproduces the
185
+ merged spec's own published example — root `abb53eb3…c074` and leaf 4's single `left` sibling
186
+ `060ca4e4…befd`. See
184
187
  [BRC220_BATCH_LEAF_AMENDMENT.md](BRC220_BATCH_LEAF_AMENDMENT.md), enforced in
185
188
  `test/notaryhash/batch_leaf.js`.
186
189
  - **`createdAt` is advisory for trust but load-bearing for the hash.** §Verification calls
@@ -55,19 +55,19 @@ Three advanced modules totaling **~2.7MB** of functionality:
55
55
  - **Purpose**: Threshold cryptography for secure secret distribution
56
56
  - **Use Cases**: Backup keys, multi-party security, key recovery
57
57
  - **Features**: Split secrets into N shares, require M to reconstruct
58
- - **CDN**: `unpkg.com/@smartledger/bsv@9.15.0/bsv-shamir.min.js`
58
+ - **CDN**: `unpkg.com/@smartledger/bsv@9.16.1/bsv-shamir.min.js`
59
59
 
60
60
  #### **🌐 Global Digital Attestation Framework - GDAF (1184KB)**
61
61
  - **Purpose**: W3C Verifiable Credentials and decentralized identity
62
62
  - **Use Cases**: Identity verification, attestations, zero-knowledge proofs
63
63
  - **Features**: DID creation, credential issuance, selective disclosure
64
- - **CDN**: `unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js`
64
+ - **CDN**: `unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js`
65
65
 
66
66
  #### **⚖️ Legal Token Protocol - LTP (1184KB)**
67
67
  - **Purpose**: Legal compliance framework for tokenized assets
68
68
  - **Use Cases**: Property rights, obligations, compliant tokenization
69
69
  - **Features**: Legal primitives, compliance checking, attestation anchoring
70
- - **CDN**: `unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js`
70
+ - **CDN**: `unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js`
71
71
 
72
72
  ### **2. Incorrect File Sizes in Documentation**
73
73
 
@@ -81,18 +81,18 @@ Three advanced modules totaling **~2.7MB** of functionality:
81
81
 
82
82
  | Module | Size | Use Case | CDN Link |
83
83
  |--------|------|----------|----------|
84
- | **bsv.min.js** | 937KB | Core BSV + SmartContract | `unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js` |
85
- | **bsv.bundle.js** | 937KB | Everything in one file | `unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js` |
86
- | **bsv-smartcontract.min.js** | 937KB | Covenant development | `unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js` |
87
- | **bsv-covenant.min.js** | 913KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.15.0/bsv-covenant.min.js` |
88
- | **bsv-script-helper.min.js** | 26KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.15.0/bsv-script-helper.min.js` |
89
- | **bsv-security.min.js** | 26KB | Security enhancements (opt-in helpers — see README › Security) | `unpkg.com/@smartledger/bsv@9.15.0/bsv-security.min.js` |
90
- | **bsv-ecies.min.js** | 71KB | Encryption | `unpkg.com/@smartledger/bsv@9.15.0/bsv-ecies.min.js` |
91
- | **bsv-message.min.js** | 26KB | Message signing | `unpkg.com/@smartledger/bsv@9.15.0/bsv-message.min.js` |
92
- | **bsv-mnemonic.min.js** | 681KB | HD wallets | `unpkg.com/@smartledger/bsv@9.15.0/bsv-mnemonic.min.js` |
93
- | **🆕 bsv-shamir.min.js** | 432KB | **Secret sharing** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-shamir.min.js` |
94
- | **🆕 bsv-gdaf.min.js** | 1184KB | **Digital attestation** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js` |
95
- | **🆕 bsv-ltp.min.js** | 1184KB | **Legal tokens** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js` |
84
+ | **bsv.min.js** | 937KB | Core BSV + SmartContract | `unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js` |
85
+ | **bsv.bundle.js** | 937KB | Everything in one file | `unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js` |
86
+ | **bsv-smartcontract.min.js** | 937KB | Covenant development | `unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js` |
87
+ | **bsv-covenant.min.js** | 913KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.16.1/bsv-covenant.min.js` |
88
+ | **bsv-script-helper.min.js** | 26KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.16.1/bsv-script-helper.min.js` |
89
+ | **bsv-security.min.js** | 26KB | Security enhancements (opt-in helpers — see README › Security) | `unpkg.com/@smartledger/bsv@9.16.1/bsv-security.min.js` |
90
+ | **bsv-ecies.min.js** | 71KB | Encryption | `unpkg.com/@smartledger/bsv@9.16.1/bsv-ecies.min.js` |
91
+ | **bsv-message.min.js** | 26KB | Message signing | `unpkg.com/@smartledger/bsv@9.16.1/bsv-message.min.js` |
92
+ | **bsv-mnemonic.min.js** | 681KB | HD wallets | `unpkg.com/@smartledger/bsv@9.16.1/bsv-mnemonic.min.js` |
93
+ | **🆕 bsv-shamir.min.js** | 432KB | **Secret sharing** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-shamir.min.js` |
94
+ | **🆕 bsv-gdaf.min.js** | 1184KB | **Digital attestation** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js` |
95
+ | **🆕 bsv-ltp.min.js** | 1184KB | **Legal tokens** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js` |
96
96
 
97
97
  ## 🎯 **Updated Usage Examples**
98
98
 
@@ -100,22 +100,22 @@ Three advanced modules totaling **~2.7MB** of functionality:
100
100
 
101
101
  #### **1. Basic Development (~963KB)**
102
102
  ```html
103
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
104
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-script-helper.min.js"></script>
103
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
104
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-script-helper.min.js"></script>
105
105
  ```
106
106
 
107
107
  #### **2. Smart Contract Development (~2.7MB — each bundle re-embeds core BSV)**
108
108
  ```html
109
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
110
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-covenant.min.js"></script>
111
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js"></script>
109
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
110
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-covenant.min.js"></script>
111
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js"></script>
112
112
  ```
113
113
 
114
114
  #### **3. 🆕 Legal & Compliance Development (~3.2MB — each bundle re-embeds core BSV)**
115
115
  ```html
116
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
117
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js"></script>
118
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js"></script>
116
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
117
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js"></script>
118
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js"></script>
119
119
  <script>
120
120
  // Legal Token Protocol
121
121
  const legalToken = bsv.createLegalToken({
@@ -132,9 +132,9 @@ Three advanced modules totaling **~2.7MB** of functionality:
132
132
 
133
133
  #### **4. 🆕 Security & Cryptography (~1.4MB)**
134
134
  ```html
135
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
136
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-security.min.js"></script>
137
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-shamir.min.js"></script>
135
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
136
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-security.min.js"></script>
137
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-shamir.min.js"></script>
138
138
  <script>
139
139
  // Shamir Secret Sharing
140
140
  const shares = bsv.splitSecret('my_secret_key', 5, 3); // 5 shares, 3 needed
@@ -146,7 +146,7 @@ Three advanced modules totaling **~2.7MB** of functionality:
146
146
 
147
147
  #### **5. Everything Bundle (937KB)**
148
148
  ```html
149
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js"></script>
149
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js"></script>
150
150
  <script>
151
151
  // Everything available immediately
152
152
  const shares = bsv.splitSecret('secret', 5, 3);
@@ -722,7 +722,7 @@ interface UTXO {
722
722
  <html>
723
723
  <head>
724
724
  <title>UTXO Manager Demo</title>
725
- <script src="https://cdn.jsdelivr.net/npm/@smartledger/bsv@9.15.0/bsv.min.js"></script>
725
+ <script src="https://cdn.jsdelivr.net/npm/@smartledger/bsv@9.16.1/bsv.min.js"></script>
726
726
  </head>
727
727
  <body>
728
728
  <script>
@@ -15,7 +15,7 @@ seeking a quote for an independent security review of its cryptographic core.
15
15
 
16
16
  Scope, and we would like these priced separately:
17
17
 
18
- Tier 1 — 12,158 lines. Sighash construction and signing; ECDSA, nonce
18
+ Tier 1 — 12,181 lines. Sighash construction and signing; ECDSA, nonce
19
19
  derivation and signature encoding; the consensus-flag and era surface of the
20
20
  script interpreter; BRC-220 signing; the covenant verification harness; RFC
21
21
  8785 canonicalization; and the covenant-facing entrypoints of the smart
@@ -15,7 +15,7 @@ seeking a quote for an independent security review of its cryptographic core.
15
15
 
16
16
  Scope, and we would like these priced separately:
17
17
 
18
- Tier 1 — 12,158 lines. Sighash construction and signing; ECDSA, nonce
18
+ Tier 1 — 12,181 lines. Sighash construction and signing; ECDSA, nonce
19
19
  derivation and signature encoding; the consensus-flag and era surface of the
20
20
  script interpreter; BRC-220 signing; the covenant verification harness; RFC
21
21
  8785 canonicalization; and the covenant-facing entrypoints of the smart
@@ -15,7 +15,7 @@ seeking a quote for an independent security review of its cryptographic core.
15
15
 
16
16
  Scope, and we would like these priced separately:
17
17
 
18
- Tier 1 — 12,158 lines. Sighash construction and signing; ECDSA, nonce
18
+ Tier 1 — 12,181 lines. Sighash construction and signing; ECDSA, nonce
19
19
  derivation and signature encoding; the consensus-flag and era surface of the
20
20
  script interpreter; BRC-220 signing; the covenant verification harness; RFC
21
21
  8785 canonicalization; and the covenant-facing entrypoints of the smart
@@ -48,7 +48,7 @@ const tx: Transaction = new Transaction();
48
48
  #### **Core Library Only (937KB)**
49
49
  For basic Bitcoin SV operations:
50
50
  ```html
51
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
51
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
52
52
  <script>
53
53
  const privateKey = new bsv.PrivateKey();
54
54
  const address = privateKey.toAddress();
@@ -58,7 +58,7 @@ For basic Bitcoin SV operations:
58
58
  #### **Complete Bundle (937KB)**
59
59
  Everything in one file:
60
60
  ```html
61
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js"></script>
61
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js"></script>
62
62
  <script>
63
63
  // All features available immediately
64
64
  const shares = bsv.splitSecret('secret', 5, 3);
@@ -71,9 +71,9 @@ Everything in one file:
71
71
 
72
72
  #### **Smart Contract Development (~2.7MB total — each bundle is self-contained and re-embeds core BSV)**
73
73
  ```html
74
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
75
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-covenant.min.js"></script>
76
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js"></script>
74
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
75
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-covenant.min.js"></script>
76
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js"></script>
77
77
  <script>
78
78
  const covenant = bsv.SmartContract.createCovenantBuilder()
79
79
  .extractField('amount').push(50000).greaterThanOrEqual().build();
@@ -82,9 +82,9 @@ Everything in one file:
82
82
 
83
83
  #### **Legal & Identity Development (~3.2MB total — each bundle is self-contained and re-embeds core BSV)**
84
84
  ```html
85
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
86
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js"></script>
87
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js"></script>
85
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
86
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js"></script>
87
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js"></script>
88
88
  <script>
89
89
  // Legal Token Protocol
90
90
  const propertyToken = bsv.createPropertyToken({
@@ -98,9 +98,9 @@ Everything in one file:
98
98
 
99
99
  #### **Security & Cryptography (~1.4MB total — each bundle is self-contained and re-embeds core BSV)**
100
100
  ```html
101
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
102
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-security.min.js"></script>
103
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-shamir.min.js"></script>
101
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
102
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-security.min.js"></script>
103
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-shamir.min.js"></script>
104
104
  <script>
105
105
  // Threshold Cryptography
106
106
  const shares = bsv.splitSecret('my_secret_key', 5, 3);
@@ -114,18 +114,18 @@ Everything in one file:
114
114
 
115
115
  | Module | Size | Purpose | CDN Link |
116
116
  |--------|------|---------|----------|
117
- | **bsv.min.js** | 937KB | Core BSV + SmartContract | `unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js` |
118
- | **bsv.bundle.js** | 937KB | Everything in one file | `unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js` |
119
- | **bsv-smartcontract.min.js** | 937KB | Complete covenant framework | `unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js` |
120
- | **bsv-ltp.min.js** | 1184KB | **Legal Token Protocol** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js` |
121
- | **bsv-gdaf.min.js** | 1184KB | **Digital Identity & Attestation** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js` |
122
- | **bsv-shamir.min.js** | 432KB | **Threshold Cryptography** | `unpkg.com/@smartledger/bsv@9.15.0/bsv-shamir.min.js` |
123
- | **bsv-security.min.js** | 26KB | Security enhancements (opt-in helpers — see README › Security) | `unpkg.com/@smartledger/bsv@9.15.0/bsv-security.min.js` |
124
- | **bsv-mnemonic.min.js** | 681KB | HD wallets | `unpkg.com/@smartledger/bsv@9.15.0/bsv-mnemonic.min.js` |
125
- | **bsv-ecies.min.js** | 71KB | Encryption | `unpkg.com/@smartledger/bsv@9.15.0/bsv-ecies.min.js` |
126
- | **bsv-covenant.min.js** | 913KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.15.0/bsv-covenant.min.js` |
127
- | **bsv-script-helper.min.js** | 26KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.15.0/bsv-script-helper.min.js` |
128
- | **bsv-message.min.js** | 26KB | Message signing | `unpkg.com/@smartledger/bsv@9.15.0/bsv-message.min.js` |
117
+ | **bsv.min.js** | 937KB | Core BSV + SmartContract | `unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js` |
118
+ | **bsv.bundle.js** | 937KB | Everything in one file | `unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js` |
119
+ | **bsv-smartcontract.min.js** | 937KB | Complete covenant framework | `unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js` |
120
+ | **bsv-ltp.min.js** | 1184KB | **Legal Token Protocol** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js` |
121
+ | **bsv-gdaf.min.js** | 1184KB | **Digital Identity & Attestation** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js` |
122
+ | **bsv-shamir.min.js** | 432KB | **Threshold Cryptography** | `unpkg.com/@smartledger/bsv@9.16.1/bsv-shamir.min.js` |
123
+ | **bsv-security.min.js** | 26KB | Security enhancements (opt-in helpers — see README › Security) | `unpkg.com/@smartledger/bsv@9.16.1/bsv-security.min.js` |
124
+ | **bsv-mnemonic.min.js** | 681KB | HD wallets | `unpkg.com/@smartledger/bsv@9.16.1/bsv-mnemonic.min.js` |
125
+ | **bsv-ecies.min.js** | 71KB | Encryption | `unpkg.com/@smartledger/bsv@9.16.1/bsv-ecies.min.js` |
126
+ | **bsv-covenant.min.js** | 913KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.16.1/bsv-covenant.min.js` |
127
+ | **bsv-script-helper.min.js** | 26KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.16.1/bsv-script-helper.min.js` |
128
+ | **bsv-message.min.js** | 26KB | Message signing | `unpkg.com/@smartledger/bsv@9.16.1/bsv-message.min.js` |
129
129
 
130
130
  ## ⚙️ **Development Environment Setup**
131
131
 
@@ -14,10 +14,10 @@ npm install @smartledger/bsv
14
14
  ### Browser CDN (Instant)
15
15
  ```html
16
16
  <!-- Core library (937KB) -->
17
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
17
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
18
18
 
19
19
  <!-- Everything included (937KB) -->
20
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js"></script>
20
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js"></script>
21
21
  ```
22
22
 
23
23
  ## 💰 **Your First Transaction (60 seconds)**
@@ -127,19 +127,19 @@ SmartLedger-BSV offers 12 different loading options - use only what you need:
127
127
 
128
128
  ```html
129
129
  <!-- Core BSV only (937KB) -->
130
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
130
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
131
131
 
132
132
  <!-- Smart contracts (937KB) -->
133
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js"></script>
133
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js"></script>
134
134
 
135
135
  <!-- Legal tokens (1.16MB) -->
136
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js"></script>
136
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js"></script>
137
137
 
138
138
  <!-- Digital identity (1.16MB) -->
139
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js"></script>
139
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js"></script>
140
140
 
141
141
  <!-- Everything (937KB) -->
142
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js"></script>
142
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js"></script>
143
143
  ```
144
144
 
145
145
  ## ⚡ **Key Advantages**
@@ -159,17 +159,17 @@ const recovered = bsv.reconstructSecret([shares[0], shares[2], shares[4]]);
159
159
  ### **New Modular Options**
160
160
  ```html
161
161
  <!-- Core compatibility (same size as bsv@1.5.6) -->
162
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.min.js"></script>
162
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.min.js"></script>
163
163
 
164
164
  <!-- Add smart contracts when ready -->
165
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-smartcontract.min.js"></script>
165
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-smartcontract.min.js"></script>
166
166
 
167
167
  <!-- Add advanced features as needed -->
168
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-ltp.min.js"></script>
169
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv-gdaf.min.js"></script>
168
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-ltp.min.js"></script>
169
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv-gdaf.min.js"></script>
170
170
 
171
171
  <!-- Everything in one file -->
172
- <script src="https://unpkg.com/@smartledger/bsv@9.15.0/bsv.bundle.js"></script>
172
+ <script src="https://unpkg.com/@smartledger/bsv@9.16.1/bsv.bundle.js"></script>
173
173
  ```
174
174
 
175
175
  ## 🔍 **Testing Your Migration**
@@ -1385,14 +1385,6 @@ Interpreter.prototype.checkSequence = function (nSequence) {
1385
1385
  return true
1386
1386
  }
1387
1387
 
1388
- function padBufferToSize (buf, len) {
1389
- let b = buf
1390
- while (b.length < len) {
1391
- b = Buffer.concat([Buffer.from([0x00]), b])
1392
- }
1393
- return b
1394
- }
1395
-
1396
1388
  /**
1397
1389
  * Based on the inner loop of bitcoind's EvalScript function
1398
1390
  * bitcoind commit: b5d1b1092998bc95313856d535c632ea5a8f9104
@@ -1415,27 +1407,40 @@ Interpreter.prototype.step = function () {
1415
1407
  switch (opcode) {
1416
1408
  case Opcode.OP_2MUL:
1417
1409
  case Opcode.OP_2DIV:
1418
- // Chronicle restores both. Until it is enabled they stay disabled, and
1419
- // "disabled" is stronger than "unimplemented": a disabled opcode fails the
1420
- // script even in an UNEXECUTED branch, which is why this lives in
1421
- // isOpcodeDisabled rather than in the evaluation switch.
1410
+ // Chronicle restores both; until the UTXO is post-Chronicle they stay disabled.
1411
+ //
1412
+ // "Disabled" is stronger than "unimplemented", but only before Genesis. The node reads
1413
+ //
1414
+ // if(IsOpcodeDisabled(opcode, utxoEra) && (!utxo_after_genesis || fExec))
1415
+ // return SCRIPT_ERR_DISABLED_OPCODE;
1416
+ //
1417
+ // so a disabled opcode in an UNEXECUTED branch fails a pre-Genesis spend and is harmless
1418
+ // in a post-Genesis one. That is why this lives in isOpcodeDisabled, which the caller
1419
+ // consults before testing fExec — the era decides, not the branch alone. An earlier
1420
+ // version of this comment said it fails unexecuted in every era, which is half the rule.
1422
1421
  if (!self.isAfterChronicle()) {
1423
1422
  return true
1424
1423
  }
1425
1424
  break
1426
1425
 
1426
+ // Restored on BSV and never gated by the node. Monolith came back in May 2018 and
1427
+ // Magnetic in November 2018, and IsOpcodeDisabled (src/script/interpreter.cpp) disables
1428
+ // OP_2MUL and OP_2DIV and nothing else — so every opcode below executes in every era the
1429
+ // node can validate, with no flag to enable.
1430
+ //
1431
+ // The four Magnetic ones used to be refused here unless SCRIPT_ENABLE_MAGNETIC_OPCODES
1432
+ // was set, "for backwards compatibility". That refused 77 rows of the node's own corpus
1433
+ // as DISABLED_OPCODE. Fail-closed, so nothing was at risk of being accepted wrongly, but
1434
+ // they were spends the network accepts. The Monolith group beside them had already made
1435
+ // the opposite call on identical reasoning, so the two halves of one 2018 upgrade
1436
+ // disagreed with each other.
1437
+ //
1438
+ // SCRIPT_ENABLE_MAGNETIC_OPCODES and SCRIPT_ENABLE_MONOLITH_OPCODES remain exported and
1439
+ // accepted — they are public API — and setting either is now simply redundant.
1427
1440
  case Opcode.OP_INVERT:
1428
1441
  case Opcode.OP_MUL:
1429
1442
  case Opcode.OP_LSHIFT:
1430
1443
  case Opcode.OP_RSHIFT:
1431
- // Magnetic opcodes - still require flag for backwards compatibility
1432
- if ((self.flags & Interpreter.SCRIPT_ENABLE_MAGNETIC_OPCODES) === 0) {
1433
- return true
1434
- }
1435
- break
1436
-
1437
- // Monolith opcodes are now enabled by default in SmartLedger BSV
1438
- // These were activated in May 2018 and are part of standard BSV consensus
1439
1444
  case Opcode.OP_DIV:
1440
1445
  case Opcode.OP_MOD:
1441
1446
  case Opcode.OP_SPLIT:
@@ -1445,7 +1450,6 @@ Interpreter.prototype.step = function () {
1445
1450
  case Opcode.OP_XOR:
1446
1451
  case Opcode.OP_BIN2NUM:
1447
1452
  case Opcode.OP_NUM2BIN:
1448
- // These opcodes are now always enabled - no flag required
1449
1453
  return false
1450
1454
 
1451
1455
  default:
@@ -2206,33 +2210,45 @@ Interpreter.prototype.step = function () {
2206
2210
  this.errstr = 'SCRIPT_ERR_INVALID_STACK_OPERATION'
2207
2211
  return false
2208
2212
  }
2213
+ // The node's order, from bitcoin-sv v1.2.2 interpreter.cpp: decode n with the era's
2214
+ // length and refuse a negative one BEFORE looking at the operand, then zero-fill when
2215
+ // n >= 8 * size, and otherwise shift bytes in place:
2216
+ //
2217
+ // CScriptNum n{top, requireMinimal, params.MaxScriptNumLength(), utxo_after_genesis};
2218
+ // if(n < 0) return SCRIPT_ERR_INVALID_NUMBER_RANGE;
2219
+ // if(n >= values.size() * bits_per_byte) fill(begin(values), end(values), 0);
2220
+ // else ... LShift(values, n.getint()) ...
2221
+ //
2222
+ // An empty operand is not a shortcut past the checks on n: `0 -1 LSHIFT` is
2223
+ // INVALID_NUMBER_RANGE. The result always has the operand's length, and the work is
2224
+ // proportional to that length, never to n.
2209
2225
  buf1 = stacktop(-2)
2210
- if (buf1.length === 0) {
2211
- this.stack.pop()
2212
- } else {
2213
- bn1 = new BN(buf1)
2214
- bn2 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, this.maxScriptNumLength())
2215
- n = bn2.toNumber()
2216
- if (n < 0) {
2217
- this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
2218
- return false
2219
- }
2220
- this.stack.pop()
2221
- this.stack.pop()
2222
- let shifted
2223
- if (opcodenum === Opcode.OP_LSHIFT) {
2224
- shifted = bn1.ushln(n)
2225
- }
2226
- if (opcodenum === Opcode.OP_RSHIFT) {
2227
- shifted = bn1.ushrn(n)
2226
+ bn2 = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, this.maxScriptNumLength())
2227
+ if (bn2.cmpn(0) < 0) {
2228
+ this.errstr = 'SCRIPT_ERR_INVALID_NUMBER_RANGE'
2229
+ return false
2230
+ }
2231
+ this.stack.pop()
2232
+ this.stack.pop()
2233
+ var shiftedBytes = Buffer.alloc(buf1.length)
2234
+ if (bn2.lt(new BN(buf1.length).muln(8))) {
2235
+ // n < 8 * size, so it fits a JS number exactly.
2236
+ var shiftBits = bn2.toNumber()
2237
+ var byteShift = Math.floor(shiftBits / 8)
2238
+ var bitShift = shiftBits % 8
2239
+ var left = opcodenum === Opcode.OP_LSHIFT
2240
+ // Big-endian bit string: bits leaving one end are dropped, zeros enter the other.
2241
+ for (var si = 0; si < buf1.length; si++) {
2242
+ var src = left ? si + byteShift : si - byteShift
2243
+ var near = src >= 0 && src < buf1.length ? buf1[src] : 0
2244
+ var farIdx = left ? src + 1 : src - 1
2245
+ var far = bitShift && farIdx >= 0 && farIdx < buf1.length ? buf1[farIdx] : 0
2246
+ shiftedBytes[si] = left
2247
+ ? ((near << bitShift) | (far >> (8 - bitShift))) & 0xff
2248
+ : ((near >> bitShift) | (far << (8 - bitShift))) & 0xff
2228
2249
  }
2229
- // bitcoin client implementation of l/rshift is unconventional, therefore this implementation is a bit unconventional
2230
- // bn library has shift functions however it expands the carried bits into a new byte
2231
- // in contrast to the bitcoin client implementation which drops off the carried bits
2232
- // in other words, if operand was 1 byte then we put 1 byte back on the stack instead of expanding to more shifted bytes
2233
- let bufShifted = padBufferToSize(Buffer.from(shifted.toArray().slice(buf1.length * -1)), buf1.length)
2234
- this.stack.push(bufShifted)
2235
2250
  }
2251
+ this.stack.push(shiftedBytes)
2236
2252
  break
2237
2253
 
2238
2254
  case Opcode.OP_EQUAL:
@@ -2555,7 +2571,17 @@ Interpreter.prototype.step = function () {
2555
2571
  return false
2556
2572
  }
2557
2573
 
2558
- var nKeysCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal, this.maxScriptNumLength()).toNumber()
2574
+ // FOUR bytes, not the era's length. The node hardcodes it and says why:
2575
+ //
2576
+ // // initialize to max size of CScriptNum::MAXIMUM_ELEMENT_SIZE (4 bytes)
2577
+ // // because only 4 byte integers are supported by OP_CHECKMULTISIG / OP_CHECKMULTISIGVERIFY
2578
+ // nKeysCountSigned = CScriptNum(stack.stacktop(-i).GetElement(), requireMinimal,
2579
+ // CScriptNum::MAXIMUM_ELEMENT_SIZE).getint();
2580
+ //
2581
+ // So it is era-independent, unlike every other operand decode in this file. Passing
2582
+ // maxScriptNumLength() here accepted a 5-byte count that the node refuses as
2583
+ // SCRIPTNUM_OVERFLOW in every era — a false accept, the direction that costs money.
2584
+ var nKeysCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal, 4).toNumber()
2559
2585
  // TODO: Keys and opcount are parameterized in client. No magic numbers!
2560
2586
  // Genesis raised this to UINT32_MAX rather than removing it.
2561
2587
  if (nKeysCount < 0 || nKeysCount > this.maxPubKeysPerMultisig()) {
@@ -2589,7 +2615,8 @@ Interpreter.prototype.step = function () {
2589
2615
  return false
2590
2616
  }
2591
2617
 
2592
- var nSigsCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal, this.maxScriptNumLength()).toNumber()
2618
+ // Four bytes, for the same reason as nKeysCount above.
2619
+ var nSigsCount = BN.fromScriptNumBuffer(stacktop(-i), fRequireMinimal, 4).toNumber()
2593
2620
  if (nSigsCount < 0 || nSigsCount > nKeysCount) {
2594
2621
  this.errstr = 'SCRIPT_ERR_SIG_COUNT'
2595
2622
  return false
@@ -2834,12 +2861,27 @@ Interpreter.prototype.step = function () {
2834
2861
  return false
2835
2862
  }
2836
2863
 
2837
- var size = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, this.maxScriptNumLength()).toNumber()
2838
2864
  // A negative size is a push size failure, not an encoding one. Without
2839
2865
  // the lower bound it fell through to the rawnum.length > size test,
2840
2866
  // which any number passes when size is negative, and reported
2841
2867
  // IMPOSSIBLE_ENCODING instead.
2842
- if (size < 0 || size > this.maxScriptElementSize()) {
2868
+ //
2869
+ // The node caps the size at INT32_MAX in every era, before the era's own limit,
2870
+ // and compares it as a script number, so nothing is allocated for a size it refuses:
2871
+ //
2872
+ // if(n < 0 || n > std::numeric_limits<int32_t>::max()) return SCRIPT_ERR_PUSH_SIZE;
2873
+ // if(!utxo_after_genesis && (size > MAX_SCRIPT_ELEMENT_SIZE_BEFORE_GENESIS)) ...
2874
+ //
2875
+ // Compared as a BN before narrowing, in the node's order: past 2^53 toNumber()
2876
+ // rounds, and past about 1024 bits it returns Infinity, so a bound checked on the
2877
+ // narrowed value is a bound on an approximation.
2878
+ var bnSize = BN.fromScriptNumBuffer(stacktop(-1), fRequireMinimal, this.maxScriptNumLength())
2879
+ if (bnSize.cmpn(0) < 0 || bnSize.gt(new BN(0x7fffffff))) {
2880
+ this.errstr = 'SCRIPT_ERR_PUSH_SIZE'
2881
+ return false
2882
+ }
2883
+ var size = bnSize.toNumber()
2884
+ if (size > this.maxScriptElementSize()) {
2843
2885
  this.errstr = 'SCRIPT_ERR_PUSH_SIZE'
2844
2886
  return false
2845
2887
  }