@smartledger/bsv 9.0.0 → 9.1.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.
- package/CHANGELOG.md +164 -0
- package/README.md +152 -1041
- package/STABILITY.md +134 -0
- package/bsv-gdaf.min.js +53 -48
- package/bsv-ltp.min.js +23 -18
- package/bsv-smartcontract.min.js +18 -18
- package/bsv.bundle.js +53 -48
- package/bsv.min.js +53 -48
- package/docs/MODULE_REFERENCE_COMPLETE.md +27 -27
- package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
- package/docs/getting-started/INSTALLATION.md +23 -23
- package/docs/getting-started/QUICK_START.md +7 -7
- package/docs/migration/FROM_BSV_1_5_6.md +5 -5
- package/docs/proposals/10.0.0-package-split.md +131 -0
- package/index.js +5 -0
- package/lib/block/merkleblock.js +53 -9
- package/lib/hdprivatekey.js +15 -0
- package/lib/script/interpreter.js +109 -1
- package/lib/smart_contract/builder.js +14 -0
- package/lib/util/deprecate.js +159 -0
- package/package.json +19 -82
- package/version.js +1 -1
- package/.mocharc.json +0 -5
- package/test/address.js +0 -629
- package/test/block/block.js +0 -239
- package/test/block/blockheader.js +0 -270
- package/test/block/merkleblock.js +0 -207
- package/test/build/bundle_crypto_shim.js +0 -104
- package/test/build/bundle_externals.js +0 -125
- package/test/build/bundle_smoke.js +0 -55
- package/test/build/esbuild_main.js +0 -65
- package/test/build/esm_wrapper.js +0 -97
- package/test/build/exports_resolution.js +0 -84
- package/test/build/version_sync.js +0 -14
- package/test/cli/smoke.js +0 -261
- package/test/consensus/base58-vectors.js +0 -120
- package/test/consensus/sv-script-vectors.js +0 -81
- package/test/consensus/sv-sighash-vectors.js +0 -51
- package/test/consensus/sv-tx-vectors.js +0 -48
- package/test/credentials-test.js +0 -332
- package/test/crypto/backend_selection.js +0 -126
- package/test/crypto/bn.js +0 -168
- package/test/crypto/ecdsa.js +0 -426
- package/test/crypto/elliptic-fixed.js +0 -61
- package/test/crypto/hash.browser.js +0 -121
- package/test/crypto/hash.js +0 -122
- package/test/crypto/point.js +0 -193
- package/test/crypto/random.js +0 -105
- package/test/crypto/security.js +0 -176
- package/test/crypto/shamir.js +0 -177
- package/test/crypto/shamir_rngcap.js +0 -29
- package/test/crypto/signature.js +0 -399
- package/test/data/bip69.json +0 -215
- package/test/data/bitcoin-sv/README.md +0 -170
- package/test/data/bitcoin-sv/base58_encode_decode.json +0 -14
- package/test/data/bitcoin-sv/base58_keys_invalid.json +0 -152
- package/test/data/bitcoin-sv/base58_keys_valid.json +0 -452
- package/test/data/bitcoin-sv/script_tests.json +0 -2591
- package/test/data/bitcoin-sv/sighash.json +0 -1003
- package/test/data/bitcoin-sv/tx_invalid.json +0 -285
- package/test/data/bitcoin-sv/tx_valid.json +0 -367
- package/test/data/bitcoind/base58_keys_invalid.json +0 -152
- package/test/data/bitcoind/base58_keys_valid.json +0 -452
- package/test/data/bitcoind/blocks.json +0 -27
- package/test/data/bitcoind/script_tests.json +0 -2244
- package/test/data/bitcoind/sig_canonical.json +0 -7
- package/test/data/bitcoind/sig_noncanonical.json +0 -22
- package/test/data/bitcoind/tx_invalid.json +0 -177
- package/test/data/bitcoind/tx_valid.json +0 -224
- package/test/data/blk86756-testnet.dat +0 -0
- package/test/data/blk86756-testnet.js +0 -12
- package/test/data/blk86756-testnet.json +0 -684
- package/test/data/brc220-batch-vector.json +0 -129
- package/test/data/ecdsa.json +0 -230
- package/test/data/merkleblocks.js +0 -486
- package/test/data/messages.json +0 -22
- package/test/data/sighash.json +0 -1004
- package/test/data/tx_creation.json +0 -85
- package/test/didweb/relationships.js +0 -144
- package/test/ecies/bitcore-ecies.js +0 -178
- package/test/ecies/electrum-ecies.js +0 -206
- package/test/encoding/base58.js +0 -131
- package/test/encoding/base58check.js +0 -145
- package/test/encoding/bufferreader.js +0 -328
- package/test/encoding/bufferwriter.js +0 -160
- package/test/encoding/varint.js +0 -104
- package/test/gdaf/anchor_no_key_leak.js +0 -146
- package/test/gdaf/anchor_spv.js +0 -163
- package/test/gdaf/canonicalization.js +0 -106
- package/test/gdaf/canonicalize.js +0 -140
- package/test/gdaf/zk_prover.js +0 -204
- package/test/hdkeys.js +0 -365
- package/test/hdprivatekey.js +0 -339
- package/test/hdpublickey.js +0 -293
- package/test/index.js +0 -16
- package/test/ltp/ids.js +0 -74
- package/test/ltp/right.js +0 -198
- package/test/ltp/verify_failclosed.js +0 -134
- package/test/message/message.js +0 -190
- package/test/mnemonic/data/fixtures.json +0 -300
- package/test/mnemonic/mnemonic.js +0 -277
- package/test/mnemonic/mocha.opts +0 -1
- package/test/mnemonic/pbkdf2.test.js +0 -43
- package/test/networks.js +0 -207
- package/test/notaryhash/batch_leaf.js +0 -140
- package/test/notaryhash/batch_vector.js +0 -282
- package/test/notaryhash/certificate.js +0 -249
- package/test/notaryhash/encoding.js +0 -186
- package/test/notaryhash/interop.js +0 -112
- package/test/notaryhash/merkle.js +0 -181
- package/test/notaryhash/script.js +0 -270
- package/test/notaryhash/verify.js +0 -342
- package/test/opcode.js +0 -186
- package/test/ordinals/bsv20.js +0 -337
- package/test/ordinals/inscription.js +0 -329
- package/test/ordinals/ordlock.js +0 -567
- package/test/privatekey.js +0 -540
- package/test/publickey.js +0 -411
- package/test/regressions.js +0 -215
- package/test/script/chronicle.js +0 -543
- package/test/script/defaults.js +0 -160
- package/test/script/genesis_limits.js +0 -203
- package/test/script/interpreter.js +0 -776
- package/test/script/script.js +0 -1259
- package/test/script/string_ops.js +0 -88
- package/test/security/fail_closed_contracts.js +0 -104
- package/test/security/threat_model_coverage.js +0 -31
- package/test/smart_contract/covenants.js +0 -207
- package/test/smart_contract/dsl_debugger.js +0 -92
- package/test/smart_contract/extract_field.js +0 -61
- package/test/smart_contract/nonenforcing_guard.js +0 -44
- package/test/smart_contract/ordinal_transfer.js +0 -71
- package/test/smart_contract/preimage.js +0 -98
- package/test/smart_contract/sighash_marketplace.js +0 -98
- package/test/smart_contract/token_generalized.js +0 -175
- package/test/spv/headerchain.js +0 -86
- package/test/spv/merkleproof.js +0 -133
- package/test/statuslist/failclosed.js +0 -78
- package/test/transaction/deserialize.js +0 -33
- package/test/transaction/input/input.js +0 -92
- package/test/transaction/input/multisig.js +0 -174
- package/test/transaction/input/multisigscripthash.js +0 -111
- package/test/transaction/input/publickey.js +0 -68
- package/test/transaction/input/publickeyhash.js +0 -59
- package/test/transaction/output.js +0 -185
- package/test/transaction/sighash.js +0 -91
- package/test/transaction/signature.js +0 -127
- package/test/transaction/transaction.js +0 -1299
- package/test/transaction/unspentoutput.js +0 -97
- package/test/types/dts_drift.js +0 -124
- package/test/types/surface_honesty.js +0 -102
- package/test/util/id.js +0 -72
- package/test/util/js.js +0 -76
- package/test/util/preconditions.js +0 -79
- package/test/vcjwt/interop.js +0 -126
package/README.md
CHANGED
|
@@ -1,1132 +1,243 @@
|
|
|
1
1
|
# SmartLedger-BSV
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Bitcoin SV library with an interpreter-verified script engine.
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@smartledger/bsv)
|
|
6
6
|
[](LICENSE)
|
|
7
|
-
[](#-16-loading-options---choose-your-approach)
|
|
9
|
-
[](#-legally-recognizable-credentials-v34x)
|
|
7
|
+
[](STABILITY.md)
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
reference node's own
|
|
14
|
-
rather than
|
|
15
|
-
|
|
9
|
+
Its defaults describe BSV as the network actually runs it. `verify()` with no
|
|
10
|
+
flags means current mainnet consensus, not "no rules"; the interpreter is
|
|
11
|
+
measured against the reference node's own vectors (1483/1483, zero false
|
|
12
|
+
accepts) rather than the Bitcoin Core vectors inherited from the upstream fork;
|
|
13
|
+
and all secp256k1 work runs on the audited, constant-time
|
|
16
14
|
[`@noble`](https://github.com/paulmillr/noble-curves) suite with `elliptic`
|
|
17
|
-
removed
|
|
18
|
-
ownership tokens), a legally-recognizable DID:web + VC-JWT toolkit, and 16
|
|
19
|
-
distribution methods.
|
|
15
|
+
removed.
|
|
20
16
|
|
|
21
|
-
> **
|
|
22
|
-
>
|
|
23
|
-
>
|
|
24
|
-
>
|
|
25
|
-
>
|
|
26
|
-
> **8.0.0 was a breaking release.** `verify()` with no flags now means BSV
|
|
27
|
-
> mainnet rather than "no rules", and two flag constants changed value. Read
|
|
28
|
-
> [Upgrading to v8.0.0](#upgrading-to-v800-breaking-changes) before moving from
|
|
29
|
-
> 7.x or earlier.
|
|
17
|
+
> **9.x will not break your code until at least 2027-09-01.** Patch and minor
|
|
18
|
+
> releases only. This library published six majors in the 82 days before that
|
|
19
|
+
> commitment; [STABILITY.md](STABILITY.md) explains what changed and how
|
|
20
|
+
> correctness fixes now ship without breaking callers.
|
|
30
21
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
The full covenant stack lives at `bsv.SmartContract` and verifies end-to-end
|
|
34
|
-
through `Script.Interpreter`. Every locking script has both a positive
|
|
35
|
-
(must-accept) and negative (must-reject) test.
|
|
36
|
-
|
|
37
|
-
```javascript
|
|
38
|
-
const bsv = require('@smartledger/bsv')
|
|
39
|
-
const SC = bsv.SmartContract
|
|
40
|
-
|
|
41
|
-
// Self-replicating covenant — every spend recreates the same script (value − fee).
|
|
42
|
-
const lock = SC.perpetualCovenant(500)
|
|
43
|
-
|
|
44
|
-
// Stateful ownership token (NFT) — transfer requires the owner's ECDSA signature
|
|
45
|
-
// over the spend, rewrites state, perpetuates the token code.
|
|
46
|
-
const token = SC.ownershipToken(500, ownerHash) // ownerHash = SC.Token.ownerId(ownerKey)
|
|
47
|
-
|
|
48
|
-
// Value covenant — forces spend outputs to match a specific hashOutputs.
|
|
49
|
-
const vlock = SC.valueCovenant(SC.PushTx.hashOutputs(requiredOutputs))
|
|
50
|
-
|
|
51
|
-
// Verify any locking script end-to-end through Script.Interpreter.
|
|
52
|
-
// Returns { ok, err } — `err` names the interpreter error when ok is false.
|
|
53
|
-
const { ok, err } = SC.verifyScript(unlockScript, lockingScript, { tx, inputIndex, satoshis })
|
|
22
|
+
```bash
|
|
23
|
+
npm install @smartledger/bsv
|
|
54
24
|
```
|
|
55
25
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
| Namespace | Purpose |
|
|
59
|
-
|---|---|
|
|
60
|
-
| `PushTx` | nChain WP1605 OP_PUSH_TX — `authenticator()`, `valueCovenant()`, `hashOutputs()`, `extractHashOutputs()`, `grind()` |
|
|
61
|
-
| `PELS` | Perpetually Enforcing Locking Scripts — `perpetualCovenant(fee)` |
|
|
62
|
-
| `Token` | Stateful ownership token (NFT) — `ownershipToken(fee, owner[, auth])`, `ownershipTokenMulti(owner[, auth])`, `ownerId(key)`, `unlockTransfer(...)`, `unlockTransferMulti(...)` |
|
|
63
|
-
| `Authorizers` | Pluggable token ownership — `singleKey()`, `multisig(m, n)`, `predicate({...})` |
|
|
64
|
-
| `Locks` | Hash-lock, P2PKH, m-of-n multisig. CLTV time-lock and HTLC were removed in 9.0.0 — see below |
|
|
65
|
-
| `CovenantHelpers` | Consensus-flag `verify()` harness, raw BIP-143 preimage, signing, fund/spend scaffolding |
|
|
66
|
-
|
|
67
|
-
> ⚠️ Research-grade. Review carefully before mainnet value: the OP_PUSH_TX key
|
|
68
|
-
> is the intentionally public `a=k=1` construction, and low-S malleability is
|
|
69
|
-
> left unenforced for the in-script signature.
|
|
70
|
-
>
|
|
71
|
-
> ℹ️ **CLTV-based time locks were removed in 9.0.0** (`Locks.timeLockCLTV`,
|
|
72
|
-
> `Locks.htlc`, `CustomScriptHelper.createTimelockScript`). Genesis reverted
|
|
73
|
-
> `OP_CHECKLOCKTIMEVERIFY` to an upgradable NOP for outputs created after it, so they
|
|
74
|
-
> enforced nothing on mainnet — the coins were spendable immediately. They appeared to
|
|
75
|
-
> work only because the harness verified under pre-Genesis flags.
|
|
76
|
-
|
|
77
|
-
## 🔏 NotaryHash (BRC-220)
|
|
26
|
+
## Covenants that actually enforce
|
|
78
27
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
against
|
|
84
|
-
|
|
85
|
-
Available as `bsv.NotaryHash`, or `require('@smartledger/bsv/lib/notaryhash')`.
|
|
28
|
+
A covenant constrains the transaction that spends it. The script has no opcode
|
|
29
|
+
for reading its own spend, so OP_PUSH_TX fixes the private key `a = 1` and
|
|
30
|
+
ephemeral key `k = 1`, collapsing ECDSA to `s = (z + Gx) mod n` — plain
|
|
31
|
+
arithmetic the script can do on a BIP-143 preimage sitting on the stack.
|
|
32
|
+
`OP_CHECKSIG` against the generator `G` then proves that data really is this
|
|
33
|
+
transaction's preimage. No trusted signer is involved.
|
|
86
34
|
|
|
87
35
|
```javascript
|
|
88
36
|
const bsv = require('@smartledger/bsv')
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
// 1. Hash the document. Only the hash is ever published.
|
|
92
|
-
const payloadHash = bsv.crypto.Hash.sha256(Buffer.from(documentBytes))
|
|
37
|
+
const { Script, Transaction, crypto } = bsv
|
|
38
|
+
const P = bsv.SmartContract.PushTx
|
|
93
39
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// BRC-220 verifier will accept.
|
|
99
|
-
const ecdsa = bsv.crypto.ECDSA().set({ hashbuf: payloadHash, privkey: key })
|
|
100
|
-
ecdsa.sign()
|
|
101
|
-
const signatureBuffer = Buffer.concat([ // 64 raw bytes, r || s
|
|
102
|
-
ecdsa.sig.r.toArrayLike(Buffer, 'be', 32),
|
|
103
|
-
ecdsa.sig.s.toArrayLike(Buffer, 'be', 32)
|
|
104
|
-
])
|
|
105
|
-
const publicKeyBuffer = key.toPublicKey().toBuffer()
|
|
40
|
+
// Commit to the only outputs this coin may ever be spent to.
|
|
41
|
+
const dest = Script.fromASM('OP_FALSE OP_RETURN 636f76656e616e74')
|
|
42
|
+
const allowed = [new Transaction.Output({ script: dest, satoshis: 99000 })]
|
|
43
|
+
const lock = P.valueCovenant(P.hashOutputs(allowed)) // ~419 bytes
|
|
106
44
|
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
const
|
|
111
|
-
mode: NotaryHash.MODE.FULL,
|
|
112
|
-
algorithm: 'ECDSA-secp256k1',
|
|
113
|
-
hashAlgorithm: 'SHA-256',
|
|
114
|
-
payloadHash: payloadHash,
|
|
115
|
-
publicKey: publicKeyBuffer,
|
|
116
|
-
signature: signatureBuffer,
|
|
117
|
-
createdAt: new Date().toISOString(),
|
|
118
|
-
anchor: { txid: txid, blockHeight: height }
|
|
119
|
-
})
|
|
45
|
+
// Spend it. `grind` nudges nLockTime until the script-derived signature is
|
|
46
|
+
// canonical (low-S); the cost falls on the spender, not on script size.
|
|
47
|
+
const g = P.grind(spendingTx, 0, lock, 100000)
|
|
48
|
+
const unlock = new Script().add(g.preimage) // the preimage IS the unlock
|
|
120
49
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
mode: NotaryHash.MODE.FULL,
|
|
124
|
-
algorithm: 'ECDSA-secp256k1',
|
|
125
|
-
hashAlgorithm: 'SHA-256',
|
|
126
|
-
payloadHash: payloadHash,
|
|
127
|
-
proofHash: Buffer.from(certificate.proofHash, 'hex'),
|
|
128
|
-
publicKey: publicKeyBuffer,
|
|
129
|
-
signature: signatureBuffer
|
|
130
|
-
})
|
|
131
|
-
|
|
132
|
-
// 5. Checks. Every verify entry point returns a STRICT boolean.
|
|
133
|
-
NotaryHash.Certificate.proofHashMatches(certificate) // proof integrity, offline
|
|
134
|
-
NotaryHash.Script.isNotaryHash(script) // is this a NotaryHash output
|
|
135
|
-
NotaryHash.isValid(certificate, options) // all three spec checks
|
|
50
|
+
new Script.Interpreter().verify(unlock, lock, spendingTx, 0, undefined, new crypto.BN(100000))
|
|
51
|
+
// => true, and false for any transaction that redirects the outputs
|
|
136
52
|
```
|
|
137
53
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
| Mode | On chain | Use when |
|
|
141
|
-
|---|---|---|
|
|
142
|
-
| `MODE.FULL` | public key and signature in full | ECDSA, where both are small |
|
|
143
|
-
| `MODE.HYBRID` | `sha256` of each instead | post-quantum signatures, which run to tens of KB |
|
|
144
|
-
| `MODE.BATCH` | a 32-byte Merkle root and a `u32be` leaf count | notarizing many documents in one output |
|
|
145
|
-
|
|
146
|
-
Batch mode uses **RFC 6962** Merkle trees — domain-separated leaves
|
|
147
|
-
(`sha256(0x00‖d)`), internal nodes (`sha256(0x01‖L‖R)`), and a rightmost leaf that
|
|
148
|
-
is *never* duplicated. This is deliberately not the Bitcoin tree in `lib/spv` nor
|
|
149
|
-
the one in `lib/gdaf`; reusing either would produce a root no other BRC-220
|
|
150
|
-
implementation computes. The batch leaf is a certificate's `proofHash` — see
|
|
151
|
-
[`docs/BRC220_BATCH_LEAF_AMENDMENT.md`](./docs/BRC220_BATCH_LEAF_AMENDMENT.md).
|
|
152
|
-
|
|
153
|
-
**Post-quantum signatures are supported but not bundled.** `ECDSA-secp256k1` is
|
|
154
|
-
registered by default; ML-DSA and SLH-DSA are reached by registering a suite, so
|
|
155
|
-
callers who do not need them pay nothing in bundle size or audit surface:
|
|
54
|
+
Every locking script in `bsv.SmartContract` ships with both a must-accept and a
|
|
55
|
+
must-reject test. Higher-level pieces built on the same core:
|
|
156
56
|
|
|
157
57
|
```javascript
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
58
|
+
const SC = bsv.SmartContract
|
|
59
|
+
SC.perpetualCovenant(500) // every spend recreates the same script (value − fee)
|
|
60
|
+
SC.ownershipToken(500, ownerHash) // NFT; transfer needs the owner's signature over the spend
|
|
61
|
+
SC.policy({ /* ... */ }) // declarative front-end over OP_PUSH_TX
|
|
161
62
|
```
|
|
162
63
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
## 🆕 **Legally-Recognizable Credentials (v3.4.x+)**
|
|
64
|
+
## The one thing that will bite you
|
|
166
65
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
- ✅ **Blockchain Native**: ES256K (secp256k1) for BSV integration
|
|
171
|
-
- ✅ **Revocation Built-in**: StatusList2021 standard for credential management
|
|
172
|
-
- ✅ **Privacy Preserving**: Hash-only BSV anchoring (no PII on-chain)
|
|
173
|
-
- ✅ **CLI Tools**: Complete command-line interface for credential operations
|
|
66
|
+
Flags and **limits** are separate mechanisms. The era bits (`SCRIPT_GENESIS`,
|
|
67
|
+
`SCRIPT_UTXO_AFTER_GENESIS`, and the Chronicle pair) are what the interpreter
|
|
68
|
+
derives its element-size, script-size, opcode-count and script-number caps from.
|
|
174
69
|
|
|
175
|
-
|
|
70
|
+
Hand-assemble a flag word out of named constants — the idiom every pre-Genesis
|
|
71
|
+
tutorial teaches — and you get the feature opcodes you asked for while silently
|
|
72
|
+
keeping the 2019 caps. The script *runs*, so nothing looks wrong until a
|
|
73
|
+
586-byte preimage is rejected against a 520-byte limit and the error blames the
|
|
74
|
+
push instead of the flags.
|
|
176
75
|
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
|
|
76
|
+
```javascript
|
|
77
|
+
// Correct — resolves to current mainnet:
|
|
78
|
+
interp.verify(unlock, lock, tx, 0, undefined, satoshisBN)
|
|
79
|
+
interp.verify(unlock, lock, tx, 0, Script.Interpreter.mainnetFlags(), satoshisBN)
|
|
180
80
|
|
|
181
|
-
|
|
182
|
-
|
|
81
|
+
// Silently pre-Genesis, and the reason your covenant "doesn't work":
|
|
82
|
+
interp.verify(unlock, lock, tx, 0, SCRIPT_ENABLE_MONOLITH_OPCODES | ..., satoshisBN)
|
|
83
|
+
```
|
|
183
84
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
--claims '{"licenseNumber":"DL123456","class":"C"}' \
|
|
190
|
-
> credential.jwt
|
|
85
|
+
Since 9.1.0 a failure caused this way sets `interp.eraHint` and prints one
|
|
86
|
+
explanatory warning per process. Deliberate pre-Genesis testing is legitimate
|
|
87
|
+
and stays silent unless it trips an era-derived limit; set
|
|
88
|
+
`Interpreter.eraDiagnostics = false` or `BSV_NO_ERA_HINT=1` to turn the notice
|
|
89
|
+
off entirely.
|
|
191
90
|
|
|
192
|
-
|
|
193
|
-
npx smartledger-bsv vc verify credential.jwt
|
|
91
|
+
## Core Bitcoin API
|
|
194
92
|
|
|
195
|
-
|
|
196
|
-
npx smartledger-bsv anchor hash credential.jwt
|
|
93
|
+
Drop-in compatible with the classic `bsv` 1.5.6 surface.
|
|
197
94
|
|
|
198
|
-
|
|
199
|
-
|
|
95
|
+
```javascript
|
|
96
|
+
const { PrivateKey, Transaction, Script, Address, HDPrivateKey } = require('@smartledger/bsv')
|
|
200
97
|
|
|
201
|
-
|
|
202
|
-
|
|
98
|
+
const key = PrivateKey.fromRandom()
|
|
99
|
+
const tx = new Transaction()
|
|
100
|
+
.from(utxos)
|
|
101
|
+
.to(address, 50000)
|
|
102
|
+
.change(key.toAddress())
|
|
103
|
+
.sign(key)
|
|
203
104
|
```
|
|
204
105
|
|
|
205
|
-
|
|
106
|
+
Custom locking scripts need the subscript and amount passed explicitly — BIP-143
|
|
107
|
+
signs both, and `tx.sign()` only knows P2PKH:
|
|
206
108
|
|
|
207
109
|
```javascript
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
// Build DID documents (.well-known/did.json and jwks.json)
|
|
214
|
-
const docs = bsv.DIDWeb.buildDidWebDocuments({
|
|
215
|
-
domain: 'example.com',
|
|
216
|
-
p256: { jwk: keys.publicJwk, kid: keys.kid },
|
|
217
|
-
controllerName: 'Example Corp'
|
|
218
|
-
})
|
|
219
|
-
// Deploy docs.didDocument to https://example.com/.well-known/did.json
|
|
220
|
-
// Deploy docs.jwks to https://example.com/.well-known/jwks.json
|
|
110
|
+
const sig = Transaction.sighash.sign(
|
|
111
|
+
tx, privateKey, sighashType, inputIndex, lockingScript, new crypto.BN(satoshis)
|
|
112
|
+
)
|
|
113
|
+
const push = Buffer.concat([sig.toDER(), Buffer.from([sighashType])]) // flag byte required
|
|
114
|
+
```
|
|
221
115
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
issuerDid: docs.did,
|
|
225
|
-
subjectId: 'did:example:alice',
|
|
226
|
-
types: ['VerifiableCredential', 'AgeCredential'],
|
|
227
|
-
credentialSubject: {
|
|
228
|
-
ageOver: 18,
|
|
229
|
-
country: 'US'
|
|
230
|
-
},
|
|
231
|
-
privateJwk: keys.privateJwk,
|
|
232
|
-
alg: 'ES256',
|
|
233
|
-
kid: keys.kid
|
|
234
|
-
})
|
|
116
|
+
Also included: `Block`, `MerkleBlock`, `SPV`, `Mnemonic` (BIP-39), `ECIES`,
|
|
117
|
+
`Message`, `Shamir`, `Ordinals`, `NotaryHash` (BRC-220).
|
|
235
118
|
|
|
236
|
-
|
|
119
|
+
## Credentials and legal tokens
|
|
237
120
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
didResolver: async (did) => {
|
|
241
|
-
// In production, fetch https://example.com/.well-known/jwks.json
|
|
242
|
-
return { jwks: docs.jwks }
|
|
243
|
-
},
|
|
244
|
-
expectedIssuerDid: docs.did
|
|
245
|
-
})
|
|
121
|
+
Standards-based issuance and verification, ES256/ES256K, with on-chain BSV
|
|
122
|
+
anchoring. These are substantial subsystems; each has its own guide.
|
|
246
123
|
|
|
247
|
-
|
|
124
|
+
```javascript
|
|
125
|
+
const { createDID, createEmailCredential, verifyCredential } = require('@smartledger/bsv')
|
|
126
|
+
```
|
|
248
127
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
128
|
+
| Area | Entry point | Guide |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| DID:web + VC-JWT | `bsv.DIDWeb`, `bsv.VcJwt` | [docs/technical/GDAF_DEVELOPER_INTERFACE.md](docs/technical/GDAF_DEVELOPER_INTERFACE.md) |
|
|
131
|
+
| Revocation (StatusList2021) | `bsv.StatusList` | [docs/MODULE_REFERENCE_COMPLETE.md](docs/MODULE_REFERENCE_COMPLETE.md) |
|
|
132
|
+
| Legal Token Protocol | `bsv.LTP` | [docs/advanced/LEGAL_TOKEN_PROTOCOL.md](docs/advanced/LEGAL_TOKEN_PROTOCOL.md) |
|
|
133
|
+
| Attestation (GDAF) | `bsv.GDAF` | [docs/technical/GDAF_IMPLEMENTATION_COMPLETE.md](docs/technical/GDAF_IMPLEMENTATION_COMPLETE.md) |
|
|
134
|
+
| Blockchain anchoring | `bsv.Anchor` | [docs/MODULE_REFERENCE_COMPLETE.md](docs/MODULE_REFERENCE_COMPLETE.md) |
|
|
256
135
|
|
|
257
|
-
|
|
258
|
-
// Later: verify with bsv.Anchor.verifyAnchorHash(originalData, anchorHash)
|
|
136
|
+
A CLI covers the common credential workflow end to end:
|
|
259
137
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
138
|
+
```bash
|
|
139
|
+
npx smartledger-bsv didweb:init --domain example.com
|
|
140
|
+
npx smartledger-bsv vc:issue --subject did:web:example.com:alice --type EmailCredential
|
|
141
|
+
npx smartledger-bsv vc:verify --token ./credential.jwt
|
|
142
|
+
```
|
|
265
143
|
|
|
266
|
-
|
|
267
|
-
const updated = await bsv.StatusList.updateStatusList({
|
|
268
|
-
listVcJwt: statusList.listVcJwt,
|
|
269
|
-
index: 42,
|
|
270
|
-
status: 'revoked',
|
|
271
|
-
privateJwk: keys.privateJwk
|
|
272
|
-
})
|
|
144
|
+
## Loading options
|
|
273
145
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
index: 42
|
|
278
|
-
})
|
|
146
|
+
Node and bundlers get tree-shakeable subpaths; browsers can take a single file
|
|
147
|
+
from a CDN. Importing the package root pulls in every subsystem, so prefer a
|
|
148
|
+
subpath when you only need part of it:
|
|
279
149
|
|
|
280
|
-
|
|
150
|
+
```javascript
|
|
151
|
+
const Script = require('@smartledger/bsv/lib/script') // 24 modules
|
|
152
|
+
const bsv = require('@smartledger/bsv') // 128 modules
|
|
281
153
|
```
|
|
282
154
|
|
|
283
|
-
## 🎯 **16 Loading Options - Choose Your Approach**
|
|
284
|
-
|
|
285
155
|
### **Core Modules**
|
|
286
156
|
| Module | Size | Use Case | CDN |
|
|
287
157
|
|--------|------|----------|-----|
|
|
288
|
-
| **bsv.min.js** |
|
|
289
|
-
| **bsv.bundle.js** |
|
|
158
|
+
| **bsv.min.js** | 1041KB | Core BSV + SmartContract | `unpkg.com/@smartledger/bsv@9.1.1/bsv.min.js` |
|
|
159
|
+
| **bsv.bundle.js** | 1041KB | Everything in one file | `unpkg.com/@smartledger/bsv@9.1.1/bsv.bundle.js` |
|
|
290
160
|
|
|
291
161
|
### **W3C Verifiable Credentials**
|
|
292
162
|
| Module | Size | Use Case | CDN |
|
|
293
163
|
|--------|------|----------|-----|
|
|
294
|
-
| **🟢 bsv-didweb.min.js** | 166KB | **DID:web generation** | `unpkg.com/@smartledger/bsv@9.
|
|
295
|
-
| **🟢 bsv-vcjwt.min.js** | 166KB | **VC-JWT issue/verify** | `unpkg.com/@smartledger/bsv@9.
|
|
296
|
-
| **🟢 bsv-statuslist.min.js** | 256KB | **StatusList2021 revocation** | `unpkg.com/@smartledger/bsv@9.
|
|
297
|
-
| **🟢 bsv-anchor.min.js** | 164KB | **BSV anchoring (hash-only)** | `unpkg.com/@smartledger/bsv@9.
|
|
164
|
+
| **🟢 bsv-didweb.min.js** | 166KB | **DID:web generation** | `unpkg.com/@smartledger/bsv@9.1.1/bsv-didweb.min.js` |
|
|
165
|
+
| **🟢 bsv-vcjwt.min.js** | 166KB | **VC-JWT issue/verify** | `unpkg.com/@smartledger/bsv@9.1.1/bsv-vcjwt.min.js` |
|
|
166
|
+
| **🟢 bsv-statuslist.min.js** | 256KB | **StatusList2021 revocation** | `unpkg.com/@smartledger/bsv@9.1.1/bsv-statuslist.min.js` |
|
|
167
|
+
| **🟢 bsv-anchor.min.js** | 164KB | **BSV anchoring (hash-only)** | `unpkg.com/@smartledger/bsv@9.1.1/bsv-anchor.min.js` |
|
|
298
168
|
|
|
299
169
|
### **Smart Contract & Development**
|
|
300
170
|
| Module | Size | Use Case | CDN |
|
|
301
171
|
|--------|------|----------|-----|
|
|
302
|
-
| **bsv-smartcontract.min.js** |
|
|
303
|
-
| **bsv-covenant.min.js** | 35KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.
|
|
304
|
-
| **bsv-script-helper.min.js** | 33KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.
|
|
305
|
-
| **bsv-security.min.js** | 32KB | Security enhancements | `unpkg.com/@smartledger/bsv@9.
|
|
172
|
+
| **bsv-smartcontract.min.js** | 140KB | Complete covenant framework | `unpkg.com/@smartledger/bsv@9.1.1/bsv-smartcontract.min.js` |
|
|
173
|
+
| **bsv-covenant.min.js** | 35KB | Covenant operations | `unpkg.com/@smartledger/bsv@9.1.1/bsv-covenant.min.js` |
|
|
174
|
+
| **bsv-script-helper.min.js** | 33KB | Custom script tools | `unpkg.com/@smartledger/bsv@9.1.1/bsv-script-helper.min.js` |
|
|
175
|
+
| **bsv-security.min.js** | 32KB | Security enhancements | `unpkg.com/@smartledger/bsv@9.1.1/bsv-security.min.js` |
|
|
306
176
|
|
|
307
177
|
### **Legal & Compliance**
|
|
308
178
|
| Module | Size | Use Case | CDN |
|
|
309
179
|
|--------|------|----------|-----|
|
|
310
|
-
| **bsv-ltp.min.js** |
|
|
311
|
-
| **bsv-gdaf.min.js** |
|
|
180
|
+
| **bsv-ltp.min.js** | 535KB | Legal Token Protocol | `unpkg.com/@smartledger/bsv@9.1.1/bsv-ltp.min.js` |
|
|
181
|
+
| **bsv-gdaf.min.js** | 1041KB | Digital Identity & Attestation | `unpkg.com/@smartledger/bsv@9.1.1/bsv-gdaf.min.js` |
|
|
312
182
|
|
|
313
183
|
### **Advanced Cryptography**
|
|
314
184
|
| Module | Size | Use Case | CDN |
|
|
315
185
|
|--------|------|----------|-----|
|
|
316
|
-
| **bsv-shamir.min.js** | 177KB | Threshold Cryptography | `unpkg.com/@smartledger/bsv@9.
|
|
186
|
+
| **bsv-shamir.min.js** | 177KB | Threshold Cryptography | `unpkg.com/@smartledger/bsv@9.1.1/bsv-shamir.min.js` |
|
|
317
187
|
|
|
318
188
|
### **Utilities**
|
|
319
189
|
| Module | Size | Use Case | CDN |
|
|
320
190
|
|--------|------|----------|-----|
|
|
321
|
-
| **bsv-ecies.min.js** | 137KB | Encryption | `unpkg.com/@smartledger/bsv@9.
|
|
322
|
-
| **bsv-message.min.js** | 34KB | Message signing | `unpkg.com/@smartledger/bsv@9.
|
|
323
|
-
| **bsv-mnemonic.min.js** | 320KB | HD wallets | `unpkg.com/@smartledger/bsv@9.
|
|
324
|
-
|
|
325
|
-
## ⚡ **2-Minute Quick Start**
|
|
326
|
-
|
|
327
|
-
Get started with Bitcoin SV development in under 2 minutes:
|
|
328
|
-
|
|
329
|
-
```bash
|
|
330
|
-
# Install via npm
|
|
331
|
-
npm install @smartledger/bsv
|
|
332
|
-
|
|
333
|
-
# Or include in HTML
|
|
334
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
> **🔒 Upgrading?** 8.0.0 changed what `verify()` means with no flags, and moved
|
|
338
|
-
> two flag constants. Read [Upgrading to v8.0.0](#upgrading-to-v800-breaking-changes)
|
|
339
|
-
> before moving from 7.x or earlier; the older
|
|
340
|
-
> [v5.0.0 notes](#upgrading-to-v500-breaking-changes) still apply if you are coming
|
|
341
|
-
> from 4.x.
|
|
342
|
-
|
|
343
|
-
**Basic Transaction (30 seconds):**
|
|
344
|
-
```javascript
|
|
345
|
-
const bsv = require('@smartledger/bsv'); // Node.js
|
|
346
|
-
// const bsv = window.bsv; // Browser
|
|
347
|
-
|
|
348
|
-
// 1. Generate keys
|
|
349
|
-
const privateKey = new bsv.PrivateKey();
|
|
350
|
-
const address = privateKey.toAddress();
|
|
351
|
-
|
|
352
|
-
// 2. Create transaction
|
|
353
|
-
const tx = new bsv.Transaction()
|
|
354
|
-
.from(utxo) // Add input
|
|
355
|
-
.to(targetAddress, 50000) // Send 50,000 satoshis
|
|
356
|
-
.change(address) // Send change back
|
|
357
|
-
.sign(privateKey); // Sign transaction
|
|
358
|
-
|
|
359
|
-
console.log('Transaction ID:', tx.id);
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
**🆕 Legal Token Development (60 seconds):**
|
|
363
|
-
```javascript
|
|
364
|
-
// Create a legal property-title token
|
|
365
|
-
const result = bsv.LTP.createRightToken({
|
|
366
|
-
type: bsv.LTP.Right.RightTypes.PROPERTY_TITLE,
|
|
367
|
-
owner: ownerDID,
|
|
368
|
-
jurisdiction: 'us_delaware',
|
|
369
|
-
legalDescription: 'Lot 15, Block 3, Subdivision ABC'
|
|
370
|
-
}, issuerPrivateKey);
|
|
371
|
-
console.log(result.success, result.token.tokenHash);
|
|
372
|
-
|
|
373
|
-
// Generate W3C Verifiable Credential
|
|
374
|
-
const credential = bsv.createEmailCredential(
|
|
375
|
-
issuerDID, subjectDID, 'user@example.com', issuerPrivateKey
|
|
376
|
-
);
|
|
377
|
-
|
|
378
|
-
// Threshold cryptography — split(secret, threshold, shares)
|
|
379
|
-
const shares = bsv.Shamir.split('private_key_backup', 3, 5); // 3 of 5 needed
|
|
380
|
-
```
|
|
381
|
-
|
|
382
|
-
**🆕 Smart Contract Development (90 seconds):**
|
|
383
|
-
```javascript
|
|
384
|
-
// Generate authentic UTXOs for testing
|
|
385
|
-
const utxoGenerator = new bsv.SmartContract.UTXOGenerator();
|
|
386
|
-
const utxos = utxoGenerator.createRealUTXOs(2, 100000);
|
|
387
|
-
|
|
388
|
-
// Create BIP-143 preimage and extract fields
|
|
389
|
-
const preimage = new bsv.SmartContract.Preimage(preimageHex);
|
|
390
|
-
const amount = preimage.getField('amount');
|
|
391
|
-
|
|
392
|
-
// Build covenant with JavaScript-to-Script translation
|
|
393
|
-
const covenant = bsv.SmartContract.createCovenantBuilder()
|
|
394
|
-
.extractField('amount')
|
|
395
|
-
.push(50000)
|
|
396
|
-
.greaterThanOrEqual()
|
|
397
|
-
.verify()
|
|
398
|
-
.build();
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
**Next Steps:**
|
|
402
|
-
- 📖 [SmartContract Guide](docs/advanced/SMART_CONTRACT_GUIDE.md)
|
|
403
|
-
- ⚖️ [Legal Token Protocol Guide](docs/advanced/LEGAL_TOKEN_PROTOCOL.md)
|
|
404
|
-
- 🌐 [Digital Identity Guide](docs/technical/GDAF_DEVELOPER_INTERFACE.md)
|
|
405
|
-
- 🔐 [Threshold Cryptography Guide](docs/technical/SHAMIR_INTEGRATION_SUMMARY.md)
|
|
406
|
-
- 🗃️ [UTXO Manager Guide](docs/advanced/UTXO_MANAGER_GUIDE.md)
|
|
407
|
-
- 💡 [Examples Directory](https://github.com/codenlighten/smartledger-bsv/tree/main/examples)
|
|
408
|
-
|
|
409
|
-
## 🔧 **API Reference**
|
|
410
|
-
|
|
411
|
-
| Component | Method | Purpose | Example |
|
|
412
|
-
|-----------|--------|---------|---------|
|
|
413
|
-
| **Core** | `new PrivateKey()` | Generate private key | `const key = new bsv.PrivateKey()` |
|
|
414
|
-
| | `new Transaction()` | Create transaction | `const tx = new bsv.Transaction()` |
|
|
415
|
-
| | `Script.fromASM()` | Parse script | `const script = bsv.Script.fromASM('OP_DUP')` |
|
|
416
|
-
| **Covenant** | `SmartContract.perpetualCovenant()` | Self-replicating covenant | `SC.perpetualCovenant(500)` |
|
|
417
|
-
| | `SmartContract.verifyScript()` | Verify a script pair; returns `{ ok, err }` | `SC.verifyScript(unlock, lock, { tx, satoshis })` |
|
|
418
|
-
| | `CustomScriptHelper.getPreimage()` | BIP143 preimage | `bsv.CustomScriptHelper.getPreimage(tx, 0, script, sats)` |
|
|
419
|
-
| **Custom Scripts** | `CustomScriptHelper` | Script utilities — **all methods are static**, do not instantiate | `bsv.CustomScriptHelper.createDataScript(data)` |
|
|
420
|
-
| | `createSignature()` | Manual signature | `bsv.CustomScriptHelper.createSignature(tx, key, 0, script, sats)` |
|
|
421
|
-
| | `createMultisigScript()` | Multi-signature | `bsv.CustomScriptHelper.createMultisigScript(2, [pk1, pk2])` |
|
|
422
|
-
| **Debug Tools** | `SmartContract.examineStack()` | Analyze script | `SmartContract.examineStack(script)` |
|
|
423
|
-
| | `interpretScript()` | Execute script | `SmartContract.interpretScript(script)` |
|
|
424
|
-
| | `getScriptMetrics()` | Performance data | `SmartContract.getScriptMetrics(script)` |
|
|
425
|
-
| **Security (opt-in)** | `SmartVerify.smartVerify()` | Hardened verify with strict input validation — call explicitly; default `signature.verify()` does NOT route through this | `bsv.SmartVerify.smartVerify(msgHash, sig, pubkey)` |
|
|
426
|
-
| | `EllipticFixed.sign()` | Canonicalized signing wrapper over the `@noble` secp256k1 backend | `bsv.EllipticFixed.sign(hash, privateKey)` |
|
|
427
|
-
|
|
428
|
-
> 💡 **Tip:** All methods include comprehensive error handling and validation. See [documentation links](#documentation) for detailed guides.
|
|
429
|
-
|
|
430
|
-
## 📚 **Quick Start Examples**
|
|
431
|
-
|
|
432
|
-
### 🔧 **Basic Development** (~1.05MB total)
|
|
191
|
+
| **bsv-ecies.min.js** | 137KB | Encryption | `unpkg.com/@smartledger/bsv@9.1.1/bsv-ecies.min.js` |
|
|
192
|
+
| **bsv-message.min.js** | 34KB | Message signing | `unpkg.com/@smartledger/bsv@9.1.1/bsv-message.min.js` |
|
|
193
|
+
| **bsv-mnemonic.min.js** | 320KB | HD wallets | `unpkg.com/@smartledger/bsv@9.1.1/bsv-mnemonic.min.js` |
|
|
433
194
|
```html
|
|
434
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.
|
|
435
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-script-helper.min.js"></script>
|
|
195
|
+
<script src="https://unpkg.com/@smartledger/bsv@9.1.1/bsv.min.js"></script>
|
|
436
196
|
<script>
|
|
437
|
-
const
|
|
438
|
-
const utxos = new bsv.SmartContract.UTXOGenerator().createRealUTXOs(2, 100000);
|
|
197
|
+
const key = bsv.PrivateKey.fromRandom()
|
|
439
198
|
</script>
|
|
440
199
|
```
|
|
441
200
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
445
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-covenant.min.js"></script>
|
|
446
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-smartcontract.min.js"></script>
|
|
447
|
-
<script>
|
|
448
|
-
const covenant = bsv.SmartContract.createCovenantBuilder()
|
|
449
|
-
.extractField('amount').push(50000).greaterThanOrEqual().verify().build();
|
|
450
|
-
const debugInfo = bsv.SmartContract.examineStack(script);
|
|
451
|
-
</script>
|
|
452
|
-
```
|
|
453
|
-
|
|
454
|
-
### 🆕 **Legal & Identity Development** (~2.55MB total — each bundle re-embeds core BSV)
|
|
455
|
-
```html
|
|
456
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
457
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-ltp.min.js"></script>
|
|
458
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-gdaf.min.js"></script>
|
|
459
|
-
<script>
|
|
460
|
-
// Legal Token Protocol
|
|
461
|
-
const result = bsv.LTP.createRightToken({
|
|
462
|
-
type: bsv.LTP.Right.RightTypes.PROPERTY_TITLE,
|
|
463
|
-
owner: ownerDID, jurisdiction: 'us_delaware'
|
|
464
|
-
}, key);
|
|
465
|
-
|
|
466
|
-
// Digital Identity
|
|
467
|
-
const credential = bsv.createEmailCredential(issuerDID, subjectDID, 'user@example.com', key);
|
|
468
|
-
</script>
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
### 🆕 **Security & Cryptography** (~1.22MB total)
|
|
472
|
-
```html
|
|
473
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
474
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-security.min.js"></script>
|
|
475
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-shamir.min.js"></script>
|
|
476
|
-
<script>
|
|
477
|
-
// Threshold Cryptography
|
|
478
|
-
const shares = bsv.Shamir.split('my_secret_key', 3, 5); // 5 shares, any 3 recover
|
|
479
|
-
|
|
480
|
-
// Enhanced Security
|
|
481
|
-
const verified = bsvSecurity.SmartVerify.smartVerify(hash, signature, publicKey);
|
|
482
|
-
</script>
|
|
483
|
-
```
|
|
484
|
-
|
|
485
|
-
### 🎯 **Everything Bundle** (~1.02MB)
|
|
486
|
-
```html
|
|
487
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.bundle.js"></script>
|
|
488
|
-
<script>
|
|
489
|
-
// Everything available immediately
|
|
490
|
-
const shares = bsv.Shamir.split('secret', 3, 5); // Shamir Secret Sharing
|
|
491
|
-
const did = bsv.createDID(publicKey); // Digital Identity
|
|
492
|
-
const token = bsv.LTP.createRightToken({ /* ... */ }, key); // Legal Tokens
|
|
493
|
-
const covenant = bsv.SmartContract.createCovenantBuilder(); // Smart Contracts
|
|
494
|
-
</script>
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
## 🎯 **Key Features**
|
|
498
|
-
|
|
499
|
-
### 🚀 **Unique Capabilities** (Only Bitcoin Library with These Features)
|
|
500
|
-
- ✅ **Legal Token Protocol**: Compliant tokenization of real-world assets → [Legal Guide](docs/advanced/LEGAL_TOKEN_PROTOCOL.md)
|
|
501
|
-
- ✅ **Digital Identity Framework**: W3C Verifiable Credentials and DIDs → [Identity Guide](docs/technical/GDAF_DEVELOPER_INTERFACE.md)
|
|
502
|
-
- ✅ **Threshold Cryptography**: Shamir Secret Sharing for secure key management → [Cryptography Guide](docs/technical/SHAMIR_INTEGRATION_SUMMARY.md)
|
|
503
|
-
- ✅ **Complete Smart Contract Suite**: 23+ production-ready covenant features → [SmartContract Guide](docs/advanced/SMART_CONTRACT_GUIDE.md)
|
|
504
|
-
|
|
505
|
-
### 💼 **Core Library Excellence**
|
|
506
|
-
- ✅ **Complete BSV API**: Full Bitcoin SV blockchain operations → [API Reference](#-api-reference)
|
|
507
|
-
- ✅ **Opt-in security helpers**: `bsv.SmartVerify` and `bsv.EllipticFixed` add input validation and low-`s` canonicalization on top of standard verification — **not on the default verify path**, see [Security](#-security)
|
|
508
|
-
- ✅ **Browser + Node.js**: Universal compatibility with proper polyfills → [Loading Options](#-16-loading-options---choose-your-approach)
|
|
509
|
-
- ✅ **TypeScript Ready**: Complete type definitions included
|
|
510
|
-
- ✅ **Ultra-Low Fees**: 0.01 sats/byte configuration (91% fee reduction)
|
|
511
|
-
|
|
512
|
-
### 🛠️ **Advanced Development Tools**
|
|
513
|
-
- 🔧 **JavaScript-to-Script**: High-level covenant development with 121 opcode mapping → [Covenant Guide](docs/advanced/ADVANCED_COVENANT_DEVELOPMENT.md)
|
|
514
|
-
- 🔧 **UTXO Generator**: Create authentic test UTXOs for development → [UTXO Guide](docs/advanced/UTXO_MANAGER_GUIDE.md)
|
|
515
|
-
- 🔧 **Preimage Parser**: Complete BIP-143 field extraction and manipulation → [Preimage Tools](https://github.com/codenlighten/smartledger-bsv/tree/main/examples/preimage)
|
|
516
|
-
- 🔧 **Debug Framework**: Script interpreter, stack examiner, and optimizer → [Debug Examples](https://github.com/codenlighten/smartledger-bsv/blob/main/tests/smartcontract-test.html)
|
|
517
|
-
- 🔧 **PUSHTX Integration**: nChain techniques for advanced covenant patterns → [PUSHTX Insights](docs/pushtx-key-insights.md)
|
|
518
|
-
|
|
519
|
-
### 📦 **Flexible Architecture**
|
|
520
|
-
- 📦 **16 Modular Options**: Load only what you need (32KB to 1039KB) → [Loading Strategy](#-16-loading-options---choose-your-approach)
|
|
521
|
-
- 📦 **Standalone Modules**: Independent legal, identity, and crypto modules → [Standalone Test](https://github.com/codenlighten/smartledger-bsv/blob/main/tests/standalone-modules-test.html)
|
|
522
|
-
- 📦 **Complete Bundle**: Everything in one file for convenience → [Bundle Demo](https://github.com/codenlighten/smartledger-bsv/blob/main/tests/bundle-demo.html)
|
|
523
|
-
- 📦 **CDN Ready**: All modules available via unpkg and jsDelivr
|
|
524
|
-
- 📦 **Webpack Optimized**: Tree-shakeable and build-tool friendly
|
|
525
|
-
|
|
526
|
-
## ⚡ **Installation & Usage**
|
|
527
|
-
|
|
528
|
-
> 💡 **Quick Start**: Jump to [2-Minute Quick Start](#-2-minute-quick-start) for instant setup examples
|
|
529
|
-
|
|
530
|
-
### NPM Installation
|
|
531
|
-
```bash
|
|
532
|
-
npm install @smartledger/bsv
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
> 📖 **Next Steps**: After installation, see [Loading Options](#-16-loading-options---choose-your-approach) to choose your distribution method
|
|
536
|
-
|
|
537
|
-
### Upgrading to v8.0.0 (Breaking Changes)
|
|
538
|
-
|
|
539
|
-
8.0.0 moved the defaults onto BSV as the network actually runs it. Two changes
|
|
540
|
-
need action.
|
|
541
|
-
|
|
542
|
-
**1. `verify()` with no flags now means BSV mainnet, not "no rules".**
|
|
543
|
-
|
|
544
|
-
```javascript
|
|
545
|
-
interp.verify(sig, pubkey, tx, nin) // was: Bitcoin 2015; now: current mainnet
|
|
546
|
-
interp.verify(sig, pubkey, tx, nin, 0) // the old behaviour, stated explicitly
|
|
547
|
-
|
|
548
|
-
// Spending a pre-Chronicle output — state the era of the output being spent,
|
|
549
|
-
// because that is the input the caller knows and the library cannot infer.
|
|
550
|
-
bsv.Script.Interpreter.mainnetFlags({ afterChronicle: false })
|
|
551
|
-
```
|
|
552
|
-
|
|
553
|
-
**2. Two flag constants changed numeric value.** The node assigns `1<<18` and
|
|
554
|
-
`1<<19` to `SCRIPT_GENESIS` and `SCRIPT_UTXO_AFTER_GENESIS`, so ours had to move:
|
|
555
|
-
|
|
556
|
-
```
|
|
557
|
-
SCRIPT_ENABLE_MONOLITH_OPCODES 1<<18 → 1<<11
|
|
558
|
-
SCRIPT_ENABLE_MAGNETIC_OPCODES 1<<19 → 1<<12
|
|
559
|
-
```
|
|
560
|
-
|
|
561
|
-
Code using the **named constants** is unaffected. Code that **persisted or
|
|
562
|
-
hardcoded the numbers** must be updated: `262144` no longer means "Monolith
|
|
563
|
-
opcodes", it now means `SCRIPT_GENESIS`, so a stored value silently selects a
|
|
564
|
-
different era model.
|
|
565
|
-
|
|
566
|
-
Also in 8.0.0: a signature carrying `SIGHASH_CHRONICLE` outside Chronicle is
|
|
567
|
-
rejected rather than reinterpreted, and `MAX_OPS_PER_SCRIPT` is BSV's 500 rather
|
|
568
|
-
than Bitcoin Core's 201. Full details in the
|
|
569
|
-
[CHANGELOG](./CHANGELOG.md#800---2026-08-13).
|
|
570
|
-
|
|
571
|
-
### Upgrading to v5.0.0 (Breaking Changes)
|
|
572
|
-
|
|
573
|
-
v5.0.0 hardens the cryptography. Most apps need **no code changes** — the
|
|
574
|
-
breaking changes only affect data produced by older versions:
|
|
575
|
-
|
|
576
|
-
- **Shamir shares.** `Shamir.split()` now returns the **v2 share format**
|
|
577
|
-
(backed by a vetted GF(2⁸) engine). Shares created with ≤ 4.x still
|
|
578
|
-
reconstruct — `Shamir.combine()` and `Shamir.verifyShare()` auto-detect and
|
|
579
|
-
accept legacy shares for recovery. No flag needed.
|
|
580
|
-
- **VC-JWT signatures.** Tokens are now signed and verified as JOSE-standard
|
|
581
|
-
**IEEE P1363** (`r||s`) instead of DER, so they interoperate with `jose`,
|
|
582
|
-
`jsonwebtoken`, etc. Tokens **issued by ≤ 4.6.0 are DER-encoded** and will
|
|
583
|
-
fail verification by default — pass `{ allowLegacyDER: true }` while you
|
|
584
|
-
re-issue:
|
|
585
|
-
```javascript
|
|
586
|
-
const result = await bsv.VcJwt.verifyVcJwt(oldToken, {
|
|
587
|
-
didResolver,
|
|
588
|
-
allowLegacyDER: true // accept ≤ 4.6.0 DER-signed tokens during migration
|
|
589
|
-
});
|
|
590
|
-
```
|
|
591
|
-
- **VC-JWT algorithm pinning.** `verifyVcJwt` rejects any token whose `alg` is
|
|
592
|
-
outside `['ES256','ES256K']` (override via `opts.allowedAlgs`) and binds the
|
|
593
|
-
key's curve to the algorithm — defense against alg-substitution attacks.
|
|
594
|
-
- **Browser bundles changed size.** The full bundles ship a real `crypto`
|
|
595
|
-
polyfill so Shamir can source a CSPRNG. Sizes have moved since; `bsv.min.js` is
|
|
596
|
-
~1039KB at 8.3.0, after the ~20% reduction in 8.0.0. The dedicated
|
|
597
|
-
single-feature module bundles are unaffected.
|
|
201
|
+
Pin the version in CDN URLs. A floating `@latest` will move under you even
|
|
202
|
+
within 9.x.
|
|
598
203
|
|
|
599
|
-
|
|
204
|
+
## Documentation
|
|
600
205
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
const metrics = bsv.SmartContract.getScriptMetrics(script);
|
|
613
|
-
const stackInfo = bsv.SmartContract.examineStack(script);
|
|
614
|
-
|
|
615
|
-
// Covenant development — see bsv.SmartContract for the covenant stack
|
|
616
|
-
const lock = bsv.SmartContract.perpetualCovenant(500);
|
|
617
|
-
const { ok, err } = bsv.SmartContract.verifyScript(unlockScript, lock, { tx, satoshis });
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
### Browser CDN (Choose Your Loading Strategy)
|
|
621
|
-
|
|
622
|
-
#### 1. **Minimal Setup** - Core + Script Helper (~1.05MB)
|
|
623
|
-
```html
|
|
624
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
625
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-script-helper.min.js"></script>
|
|
626
|
-
<script>
|
|
627
|
-
const tx = new bsv.Transaction();
|
|
628
|
-
const sig = bsvScriptHelper.createSignature(tx, privateKey, 0, script, satoshis);
|
|
629
|
-
</script>
|
|
630
|
-
```
|
|
631
|
-
|
|
632
|
-
#### 2. **DeFi Development** - Core + Covenants + Debug (~1.2MB — each bundle re-embeds core BSV)
|
|
633
|
-
```html
|
|
634
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
635
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-covenant.min.js"></script>
|
|
636
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-smartcontract.min.js"></script>
|
|
637
|
-
<script>
|
|
638
|
-
const lock = bsv.SmartContract.perpetualCovenant(500);
|
|
639
|
-
const debugInfo = bsv.SmartContract.interpretScript(script);
|
|
640
|
-
const optimized = bsv.SmartContract.optimizeScript(script);
|
|
641
|
-
</script>
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
#### 3. **Security First** - Core + Enhanced Security (~1.05MB)
|
|
645
|
-
```html
|
|
646
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.min.js"></script>
|
|
647
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv-security.min.js"></script>
|
|
648
|
-
<script>
|
|
649
|
-
const verified = bsvSecurity.SmartVerify.smartVerify(hash, signature, publicKey);
|
|
650
|
-
const enhanced = bsvSecurity.EllipticFixed.sign(hash, privateKey);
|
|
651
|
-
</script>
|
|
652
|
-
```
|
|
653
|
-
|
|
654
|
-
#### 4. **Everything Bundle** - One File Solution (~1.02MB)
|
|
655
|
-
```html
|
|
656
|
-
<script src="https://unpkg.com/@smartledger/bsv@9.0.0/bsv.bundle.js"></script>
|
|
657
|
-
<script>
|
|
658
|
-
// Everything available under the bsv namespace
|
|
659
|
-
const key = bsv.PrivateKey.fromRandom();
|
|
660
|
-
const lock = bsv.SmartContract.perpetualCovenant(500);
|
|
661
|
-
const message = new bsv.Message('Hello BSV');
|
|
662
|
-
const encrypted = new bsv.ECIES()
|
|
663
|
-
.privateKey(key)
|
|
664
|
-
.publicKey(recipientPublicKey)
|
|
665
|
-
.encrypt('secret');
|
|
666
|
-
</script>
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
## 🔨 Basic Usage
|
|
670
|
-
|
|
671
|
-
### Creating Transactions
|
|
672
|
-
```javascript
|
|
673
|
-
const bsv = require('@smartledger/bsv');
|
|
674
|
-
|
|
675
|
-
// Create transaction with optimized fees
|
|
676
|
-
const transaction = new bsv.Transaction()
|
|
677
|
-
.from({
|
|
678
|
-
txId: 'prev_tx_id',
|
|
679
|
-
outputIndex: 0,
|
|
680
|
-
script: 'prev_locking_script',
|
|
681
|
-
satoshis: 100000
|
|
682
|
-
})
|
|
683
|
-
.to('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa', 95000)
|
|
684
|
-
.feePerKb(10) // Ultra-low fee: 0.01 sats/byte
|
|
685
|
-
.sign(privateKey);
|
|
686
|
-
|
|
687
|
-
console.log('Transaction ID:', transaction.id);
|
|
688
|
-
console.log('Fee rate: 0.01 sats/byte (91% reduction)');
|
|
689
|
-
```
|
|
690
|
-
|
|
691
|
-
### UTXO Management
|
|
692
|
-
```javascript
|
|
693
|
-
// Advanced UTXO state management
|
|
694
|
-
const utxoManager = {
|
|
695
|
-
createWithChange: (inputs, outputs, changeAddress) => {
|
|
696
|
-
const tx = new bsv.Transaction()
|
|
697
|
-
.from(inputs)
|
|
698
|
-
.to(outputs.address, outputs.amount)
|
|
699
|
-
.change(changeAddress)
|
|
700
|
-
.feePerKb(10);
|
|
701
|
-
|
|
702
|
-
// Automatic change output creation and UTXO state update
|
|
703
|
-
return tx;
|
|
704
|
-
}
|
|
705
|
-
};
|
|
706
|
-
```
|
|
707
|
-
|
|
708
|
-
## 🆕 **Advanced Features** (Unique to SmartLedger-BSV)
|
|
709
|
-
|
|
710
|
-
### ⚖️ Legal Token Protocol (LTP)
|
|
711
|
-
```javascript
|
|
712
|
-
const bsv = require('@smartledger/bsv');
|
|
713
|
-
|
|
714
|
-
// Create a property-rights token. `type` must be one of LTP.Right.RightTypes —
|
|
715
|
-
// an unrecognized type is rejected rather than silently accepted.
|
|
716
|
-
const result = bsv.LTP.createRightToken({
|
|
717
|
-
type: bsv.LTP.Right.RightTypes.PROPERTY_TITLE,
|
|
718
|
-
owner: ownerDID,
|
|
719
|
-
jurisdiction: 'us_delaware',
|
|
720
|
-
legalDescription: 'Lot 15, Block 3, Subdivision ABC'
|
|
721
|
-
}, issuerPrivateKey);
|
|
722
|
-
|
|
723
|
-
console.log(result.success); // true
|
|
724
|
-
console.log(result.token.tokenHash); // hash committed by the token's proof
|
|
725
|
-
|
|
726
|
-
// Obligation tokens
|
|
727
|
-
const obligation = bsv.LTP.Obligation.prepareObligationToken({
|
|
728
|
-
obligationType: 'payment',
|
|
729
|
-
amount: 100000, // satoshis
|
|
730
|
-
dueDate: '2026-12-31',
|
|
731
|
-
creditor: creditorDID,
|
|
732
|
-
debtor: debtorDID
|
|
733
|
-
});
|
|
734
|
-
|
|
735
|
-
// Validate claim data against a registered schema
|
|
736
|
-
// (schema names come from bsv.LTP.Claim.getSchemaNames())
|
|
737
|
-
const validation = bsv.validateLegalClaim(claimData, schemaType);
|
|
738
|
-
```
|
|
739
|
-
|
|
740
|
-
### 🌐 Global Digital Attestation Framework (GDAF)
|
|
741
|
-
```javascript
|
|
742
|
-
// Simple Interface - Direct from bsv object
|
|
743
|
-
const issuerDID = bsv.createDID(privateKey.toPublicKey());
|
|
744
|
-
|
|
745
|
-
// Create W3C Verifiable Credentials
|
|
746
|
-
const emailCredential = bsv.createEmailCredential(
|
|
747
|
-
issuerDID, subjectDID, 'user@example.com', issuerPrivateKey
|
|
748
|
-
);
|
|
749
|
-
|
|
750
|
-
// Generate zero-knowledge proofs
|
|
751
|
-
const proof = bsv.generateSelectiveProof(
|
|
752
|
-
emailCredential,
|
|
753
|
-
['credentialSubject.verified'],
|
|
754
|
-
nonce
|
|
755
|
-
);
|
|
756
|
-
|
|
757
|
-
// Verify age without revealing exact age
|
|
758
|
-
const ageProof = bsv.generateAgeProof(credential, 18);
|
|
759
|
-
const isAdult = bsv.verifyAgeProof(ageProof, 18, issuerDID);
|
|
760
|
-
|
|
761
|
-
// Advanced Interface for complex applications
|
|
762
|
-
const gdaf = new bsv.GDAF({
|
|
763
|
-
anchor: { network: 'mainnet' },
|
|
764
|
-
attestationSigner: { customConfig: true }
|
|
765
|
-
});
|
|
766
|
-
```
|
|
767
|
-
|
|
768
|
-
### 🔐 Shamir Secret Sharing
|
|
769
|
-
```javascript
|
|
770
|
-
// Split a secret into threshold shares.
|
|
771
|
-
// Signature is split(secret, threshold, shares) — THRESHOLD FIRST.
|
|
772
|
-
const secret = 'my_private_key_backup';
|
|
773
|
-
const shares = bsv.Shamir.split(secret, 3, 5); // 5 shares, any 3 reconstruct
|
|
774
|
-
|
|
775
|
-
console.log('Generated', shares.length, 'shares');
|
|
776
|
-
|
|
777
|
-
// Reconstruct from any 3 shares
|
|
778
|
-
const reconstructed = bsv.Shamir.combine([shares[0], shares[2], shares[4]]);
|
|
779
|
-
console.log('Secret recovered:', reconstructed === secret); // true
|
|
780
|
-
|
|
781
|
-
// Validate share integrity
|
|
782
|
-
shares.forEach((share, i) => {
|
|
783
|
-
console.log(`Share ${i + 1} valid:`, bsv.Shamir.verifyShare(share));
|
|
784
|
-
});
|
|
785
|
-
|
|
786
|
-
// Use cases: Key backup, multi-party security, recovery systems
|
|
787
|
-
```
|
|
788
|
-
|
|
789
|
-
## 🔒 Covenant Framework
|
|
790
|
-
|
|
791
|
-
### JavaScript-to-Bitcoin Script Translation
|
|
792
|
-
```javascript
|
|
793
|
-
const { CovenantBuilder, CovenantTemplates } = require('@smartledger/bsv/lib/smart_contract');
|
|
794
|
-
|
|
795
|
-
// Write covenant logic in JavaScript
|
|
796
|
-
const valueLock = CovenantTemplates.valueLock('50c3000000000000');
|
|
797
|
-
const script = valueLock.build();
|
|
798
|
-
console.log(script.cleanedASM);
|
|
799
|
-
// Output: OP_SIZE 34 OP_SUB OP_SPLIT OP_DROP OP_8 OP_SPLIT OP_DROP 50c3000000000000 OP_EQUALVERIFY OP_1
|
|
800
|
-
|
|
801
|
-
// Custom covenant builder
|
|
802
|
-
const custom = new CovenantBuilder()
|
|
803
|
-
.comment('Validate preimage value field')
|
|
804
|
-
.extractField('value')
|
|
805
|
-
.push('50c3000000000000')
|
|
806
|
-
.equalVerify()
|
|
807
|
-
.push(1);
|
|
808
|
-
```
|
|
809
|
-
|
|
810
|
-
### Complete Opcode Mapping (116 Opcodes)
|
|
811
|
-
```javascript
|
|
812
|
-
const SmartContract = require('@smartledger/bsv/lib/smart_contract');
|
|
813
|
-
|
|
814
|
-
// Simulate script execution in JavaScript
|
|
815
|
-
const result = SmartContract.simulateScript(['OP_1', 'OP_2', 'OP_ADD', 'OP_3', 'OP_EQUAL']);
|
|
816
|
-
console.log(result.finalStack); // ['01'] - TRUE
|
|
817
|
-
|
|
818
|
-
// Get comprehensive opcode information
|
|
819
|
-
const opcodes = SmartContract.getOpcodeMap();
|
|
820
|
-
console.log(Object.keys(opcodes).length); // 116 opcodes mapped
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
### BIP143 Preimage Parsing
|
|
824
|
-
```javascript
|
|
825
|
-
const { CovenantPreimage } = require('@smartledger/bsv/lib/covenant-interface');
|
|
826
|
-
|
|
827
|
-
// Enhanced preimage parsing with field-by-field access
|
|
828
|
-
const preimage = new CovenantPreimage(preimageHex);
|
|
829
|
-
|
|
830
|
-
console.log('Version:', preimage.nVersionValue); // uint32 accessor
|
|
831
|
-
console.log('Amount:', preimage.amountValue); // BigInt accessor
|
|
832
|
-
console.log('Valid structure:', preimage.isValid); // Boolean validation
|
|
833
|
-
```
|
|
834
|
-
|
|
835
|
-
### PUSHTX Covenants (nChain WP1605)
|
|
836
|
-
```javascript
|
|
837
|
-
const bsv = require('@smartledger/bsv')
|
|
838
|
-
const SC = bsv.SmartContract
|
|
839
|
-
|
|
840
|
-
// Bare OP_PUSH_TX authenticator: unlocks only with the (grindable) preimage of
|
|
841
|
-
// THIS transaction. Built from the nChain `a=k=1` public-key construction —
|
|
842
|
-
// the script generates an ECDSA signature in-script from the pushed preimage
|
|
843
|
-
// (r=Gx, s=(e+Gx) mod n) and verifies it with OP_CHECKSIG, which only passes
|
|
844
|
-
// if the preimage matches this very spend.
|
|
845
|
-
const authLock = SC.PushTx.authenticator()
|
|
846
|
-
|
|
847
|
-
// Value covenant — force spend outputs to match a specific hashOutputs.
|
|
848
|
-
const requiredOutputs = [/* bsv.Transaction.Output objects */]
|
|
849
|
-
const valueLock = SC.PushTx.valueCovenant(SC.PushTx.hashOutputs(requiredOutputs))
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
### Perpetually Enforcing Locking Scripts (PELS)
|
|
853
|
-
```javascript
|
|
854
|
-
// Self-replicating covenant: every spend must recreate the same script
|
|
855
|
-
// (value − fee), reading its own code out of the authenticated preimage's
|
|
856
|
-
// scriptCode field. No self-hash circularity.
|
|
857
|
-
const pels = SC.perpetualCovenant(500) // fee in satoshis deducted each hop
|
|
858
|
-
```
|
|
859
|
-
|
|
860
|
-
### Ownership Tokens (NFT)
|
|
861
|
-
```javascript
|
|
862
|
-
// Stateful ownership token. Owner is carried as on-chain state (HASH160 of the
|
|
863
|
-
// owner's public key); transfer requires the current owner's ECDSA SIGNATURE over
|
|
864
|
-
// the spend (OP_CHECKSIG) and rewrites state, perpetuating the token code across
|
|
865
|
-
// the chain of spends. The signature commits to the chosen next owner, so a
|
|
866
|
-
// mempool watcher cannot redirect a pending transfer (no hash-lock front-running).
|
|
867
|
-
const ownerHash = SC.Token.ownerId(currentOwnerKey) // = HASH160(pubkey)
|
|
868
|
-
const token = SC.ownershipToken(500, ownerHash)
|
|
869
|
-
// To spend it forward to `nextOwnerHash`, the current owner signs:
|
|
870
|
-
// tokenInput.setScript(SC.Token.unlockTransfer(currentOwnerKey, nextOwnerHash, spendTx, sats, token))
|
|
871
|
-
|
|
872
|
-
// Pluggable ownership — the SAME covenant, owned by an m-of-n group. Ownership is
|
|
873
|
-
// committed as a 20-byte hash either way, so the transfer plumbing is identical.
|
|
874
|
-
const ms = SC.Authorizers.multisig(2, 3)
|
|
875
|
-
const groupToken = SC.Token.ownershipToken(500, ms.commit([pkA, pkB, pkC]), ms)
|
|
876
|
-
// transfer requires any 2 of the 3 keys:
|
|
877
|
-
// SC.Token.unlockTransfer({ keys: [pkA, pkB, pkC], signWith: [skA, skC] },
|
|
878
|
-
// nextOwnerHash, spendTx, sats, groupToken, { auth: ms })
|
|
879
|
-
// Custom schemes: SC.Authorizers.predicate({ commit, emit, unlockArgs }).
|
|
880
|
-
|
|
881
|
-
// N-output: recreate the token alongside other outputs (payments, change, data).
|
|
882
|
-
// The spender reveals the surrounding output bytes; the covenant binds them all.
|
|
883
|
-
const multi = SC.Token.ownershipTokenMulti(ownerHash)
|
|
884
|
-
// SC.Token.unlockTransferMulti(currentOwnerKey, nextOwnerHash, spendTx, sats, multi,
|
|
885
|
-
// { before: serializedOutputsBeforeToken, after: serializedOutputsAfterToken, tokenValue: le8(value) })
|
|
886
|
-
```
|
|
887
|
-
|
|
888
|
-
### End-to-end verification
|
|
889
|
-
|
|
890
|
-
```javascript
|
|
891
|
-
// Any locking script can be verified end-to-end through Script.Interpreter,
|
|
892
|
-
// with the consensus flags this library was tested against.
|
|
893
|
-
const ok = SC.verifyScript(unlockScript, lockingScript, tx, inputIndex, satoshis)
|
|
894
|
-
```
|
|
895
|
-
|
|
896
|
-
### Consensus defaults — BSV mainnet, no flags required (8.0.0+)
|
|
897
|
-
|
|
898
|
-
**Since 8.0.0 you do not opt in to BSV.** `verify()` with no flags means
|
|
899
|
-
current BSV mainnet consensus, and `MAX_OPS_PER_SCRIPT` is BSV's 500 rather
|
|
900
|
-
than Bitcoin Core's 201. Earlier versions defaulted to a 2015-era Bitcoin
|
|
901
|
-
rule set and required an explicit call to reach post-Genesis behaviour; that
|
|
902
|
-
is no longer the case.
|
|
903
|
-
|
|
904
|
-
```javascript
|
|
905
|
-
const bsv = require('@smartledger/bsv');
|
|
906
|
-
const interp = new bsv.Script.Interpreter();
|
|
907
|
-
|
|
908
|
-
// Current BSV mainnet — this is the default.
|
|
909
|
-
const ok = interp.verify(unlockScript, lockScript, tx, 0, undefined, satoshisBN);
|
|
910
|
-
|
|
911
|
-
// Spending a pre-Chronicle output: state the era of the output you are spending,
|
|
912
|
-
// because the library cannot infer it.
|
|
913
|
-
const flags = bsv.Script.Interpreter.mainnetFlags({ afterChronicle: false });
|
|
914
|
-
const ok2 = interp.verify(unlockScript, lockScript, tx, 0, flags, satoshisBN);
|
|
915
|
-
|
|
916
|
-
// The pre-8.0.0 "no rules" behaviour, if you genuinely want it, is now explicit:
|
|
917
|
-
const ok3 = interp.verify(unlockScript, lockScript, tx, 0, 0, satoshisBN);
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
**Covenants need no special setup.** The element and script-number caps are
|
|
921
|
-
derived from the era flags, not from the `MAX_SCRIPT_ELEMENT_SIZE` static — which
|
|
922
|
-
still reads 520 because it is only the pre-Genesis fallback. An OP_PUSH_TX
|
|
923
|
-
covenant pushing a ~585-byte preimage verifies under the defaults:
|
|
924
|
-
|
|
925
|
-
```javascript
|
|
926
|
-
const interp = new bsv.Script.Interpreter();
|
|
927
|
-
const ok = interp.verify(unlockScript, lockScript, tx, 0, undefined, satoshisBN);
|
|
928
|
-
```
|
|
929
|
-
|
|
930
|
-
> ⚠️ **You no longer need to opt in to anything.** Since 8.4.0 the covenant harness
|
|
931
|
-
> verifies under `Interpreter.mainnetFlags()`, whose era bits lift the pre-Genesis
|
|
932
|
-
> element, opcode and script-size caps. `SmartContract.enableGenesis()` was removed in
|
|
933
|
-
> 9.0.0 and can be deleted from your code.
|
|
934
|
-
>
|
|
935
|
-
> **`Interpreter.useGenesisLimits()` remains available but should not be used to
|
|
936
|
-
> enable covenants.** It cannot enable post-Genesis arithmetic — that comes from the
|
|
937
|
-
> era flags — and because it mutates process-wide statics it *weakens* pre-Genesis
|
|
938
|
-
> validation: raising `MAXIMUM_ELEMENT_SIZE` turns 15 of the reference node's 22
|
|
939
|
-
> `SCRIPTNUM_OVERFLOW` vectors into false accepts. If you must call it, capture and
|
|
940
|
-
> restore the caps with `Interpreter.getLimits()` / `Interpreter.setLimits()`.
|
|
941
|
-
|
|
942
|
-
## 🛠️ Custom Scripts
|
|
943
|
-
|
|
944
|
-
### Multi-signature Scripts
|
|
945
|
-
```javascript
|
|
946
|
-
// The module exports the class itself, and every method is STATIC — do not
|
|
947
|
-
// destructure a named export and do not instantiate.
|
|
948
|
-
const CustomScriptHelper = require('@smartledger/bsv/lib/custom-script-helper');
|
|
949
|
-
|
|
950
|
-
// Create 2-of-3 multisig script — signature is (m, publicKeys)
|
|
951
|
-
const multisigScript = CustomScriptHelper.createMultisigScript(2, [
|
|
952
|
-
publicKey1, publicKey2, publicKey3
|
|
953
|
-
]);
|
|
954
|
-
```
|
|
955
|
-
|
|
956
|
-
### Timelock Contracts
|
|
957
|
-
|
|
958
|
-
**Not supported.** `CustomScriptHelper.createTimelockScript`, `Locks.timeLockCLTV` and
|
|
959
|
-
`Locks.htlc` were removed in 9.0.0. All three were built on
|
|
960
|
-
`OP_CHECKLOCKTIMEVERIFY`, which Genesis reverted to an upgradable NOP for outputs
|
|
961
|
-
created after it — so on current BSV mainnet they enforced nothing and the coins were
|
|
962
|
-
spendable immediately by the key holder.
|
|
963
|
-
|
|
964
|
-
They looked correct because this library's covenant harness verified them under
|
|
965
|
-
pre-Genesis flags; that was fixed in the same release. If you need time-based
|
|
966
|
-
conditions on BSV, enforce them off-chain or with `nLockTime` at the transaction
|
|
967
|
-
level, and be aware that neither is equivalent to a script-enforced lock.
|
|
968
|
-
|
|
969
|
-
## 📁 Examples
|
|
970
|
-
|
|
971
|
-
### Basic Examples
|
|
972
|
-
- **[Advanced Covenant Demo](advanced_covenant_demo.js)**: Complete covenant showcase
|
|
973
|
-
- **[Custom Script Tests](test/custom_script_signature_test.js)**: Script development examples
|
|
974
|
-
- **[Covenant Resolution](covenant_manual_signature_resolved.js)**: Working covenant patterns
|
|
975
|
-
|
|
976
|
-
### Documentation
|
|
977
|
-
- **[Advanced Covenant Development](ADVANCED_COVENANT_DEVELOPMENT.md)**: Complete BIP143 + PUSHTX guide
|
|
978
|
-
- **[Custom Script Development](CUSTOM_SCRIPT_DEVELOPMENT.md)**: Script creation patterns
|
|
979
|
-
- **[Covenant Development Resolved](COVENANT_DEVELOPMENT_RESOLVED.md)**: Problem solutions
|
|
980
|
-
|
|
981
|
-
## 🔧 CDN Bundles
|
|
982
|
-
|
|
983
|
-
See the **[16 Loading Options](#-16-loading-options---choose-your-approach)**
|
|
984
|
-
table near the top for the full list of bundles with current sizes and
|
|
985
|
-
canonical `unpkg.com/@smartledger/bsv@9.0.0/...` URLs.
|
|
986
|
-
|
|
987
|
-
## 🔐 Security
|
|
988
|
-
|
|
989
|
-
### What's actually in the box
|
|
990
|
-
|
|
991
|
-
| Surface | Status | Notes |
|
|
992
|
-
|---------|--------|-------|
|
|
993
|
-
| secp256k1 primitives | `@noble/curves` | `elliptic` was removed entirely — it is not a dependency and is not in the bundles. The Noble suite carries a published Cure53 audit. |
|
|
994
|
-
| Default `transaction.verify()` / `signature.verify()` / `Message().verify()` | uses BSV's own `lib/crypto/ecdsa.js` | This path does **not** import elliptic and is **not** routed through `SmartVerify` or `EllipticFixed`. |
|
|
995
|
-
| `bsv.SmartVerify` (opt-in helper) | available | Hardened standalone verify: rejects `r=0`, `s=0`, `r≥n`, `s≥n`; canonicalizes `s` to low half. Built on BSV's own `BN`/`ECDSA`. You must call it explicitly. |
|
|
996
|
-
| `bsv.EllipticFixed` (opt-in helper) | available | An elliptic-*compatible* secp256k1 surface — the name is kept for API compatibility, but it is backed by `@noble/curves`. Adds the same input checks plus low-`s` on sign. |
|
|
997
|
-
| `signature.validate()` / `isCanonical()` / `toCanonical()` | available | Real methods on `bsv.Signature`. |
|
|
998
|
-
| DER canonicalization on TX signing | available | BSV's signature path produces low-`s` DER by default. |
|
|
999
|
-
| BIP143 preimage utilities | available | `lib/smart_contract/preimage.js` and `examples/preimage/`. |
|
|
1000
|
-
|
|
1001
|
-
### Using the opt-in helpers
|
|
1002
|
-
|
|
1003
|
-
```js
|
|
1004
|
-
const bsv = require('@smartledger/bsv')
|
|
1005
|
-
|
|
1006
|
-
// Hardened verify (recommended if you accept signatures from untrusted sources):
|
|
1007
|
-
const ok = bsv.SmartVerify.smartVerify(msgHashBuffer, derSigBuffer, publicKey)
|
|
1008
|
-
|
|
1009
|
-
// Or call BSV's own ECDSA via the standard API (no SmartVerify hardening):
|
|
1010
|
-
const okDefault = bsv.crypto.ECDSA.verify(msgHashBuffer, signature, publicKey)
|
|
1011
|
-
```
|
|
1012
|
-
|
|
1013
|
-
### What this library does **not** claim
|
|
1014
|
-
|
|
1015
|
-
- It does not silently route every `verify()` call through `SmartVerify`. If you want the strict input validation on every verification, call `SmartVerify` explicitly or wrap `bsv.crypto.ECDSA.prototype.verify`.
|
|
1016
|
-
- It no longer depends on `elliptic` at all. `lib/crypto/elliptic-fixed.js` keeps the name for API compatibility but is backed by `@noble/curves`; it adds input validation and low-`s` canonicalization on top of that.
|
|
1017
|
-
- It does not turn `bsv.isHardened = true` into an automatic guarantee. That property indicates the hardening helpers ship; whether they're used is up to your code.
|
|
1018
|
-
|
|
1019
|
-
v4.0.0 fixed three critical, exploitable vulnerabilities in the GDAF
|
|
1020
|
-
credential-verification path (`_canonicalizeJSON` excluded nested claims
|
|
1021
|
-
from the signed hash; `_verifySignature` always returned truthy regardless
|
|
1022
|
-
of validity; `verificationMethod` was not bound to the credential issuer)
|
|
1023
|
-
and removed a live mainnet WIF that had been shipping inside the
|
|
1024
|
-
package. **All ≤ 3.4.5 releases should be considered untrustworthy for
|
|
1025
|
-
credential verification and must be upgraded to 4.x.** See
|
|
1026
|
-
[CHANGELOG `## [4.0.0]`](./CHANGELOG.md#400---2026-05-31) for details
|
|
1027
|
-
and [SECURITY.md](./SECURITY.md) for the supported-versions policy.
|
|
1028
|
-
|
|
1029
|
-
## 📝 Changelog
|
|
1030
|
-
|
|
1031
|
-
The authoritative version history lives in [CHANGELOG.md](./CHANGELOG.md).
|
|
1032
|
-
Highlights of the current line:
|
|
1033
|
-
|
|
1034
|
-
- **[8.3.0](./CHANGELOG.md#830---2026-08-16)** — BRC-220 **NotaryHash**:
|
|
1035
|
-
signed-hash notarization, SPV-verifiable certificates, a pluggable signature
|
|
1036
|
-
suite registry, and RFC 6962 Merkle trees for batch mode.
|
|
1037
|
-
- **[8.2.0](./CHANGELOG.md#820---2026-08-15)** — RFC 8785 (JCS) canonical JSON
|
|
1038
|
-
extracted to `lib/util/jcs.js`, so GDAF signatures verify under other
|
|
1039
|
-
implementations.
|
|
1040
|
-
- **[8.1.0](./CHANGELOG.md#810---2026-08-13)** — `useGenesisLimits()` edge-case
|
|
1041
|
-
fix.
|
|
1042
|
-
- **[8.0.0](./CHANGELOG.md#800---2026-08-13)** — **breaking.** Measured against
|
|
1043
|
-
the reference node's own consensus vectors (1483/1483, from an initial
|
|
1044
|
-
1426/1483 with 21 false accepts). `verify()` with no flags now means BSV
|
|
1045
|
-
mainnet; `SCRIPT_ENABLE_MONOLITH_OPCODES` and `SCRIPT_ENABLE_MAGNETIC_OPCODES`
|
|
1046
|
-
changed numeric value. See [Upgrading](#upgrading-to-v800-breaking-changes).
|
|
1047
|
-
- **[4.0.0](./CHANGELOG.md#400---2026-05-31)** — **security release.** Fixed
|
|
1048
|
-
three exploitable credential-verification flaws in GDAF/VC-JWT and removed a
|
|
1049
|
-
live mainnet WIF that shipped inside prior versions. All ≤ 3.4.5 should be
|
|
1050
|
-
considered untrustworthy.
|
|
1051
|
-
|
|
1052
|
-
Earlier entries are preserved in `CHANGELOG.md`.
|
|
1053
|
-
|
|
1054
|
-
---
|
|
1055
|
-
|
|
1056
|
-
## 📚 **Complete Documentation**
|
|
1057
|
-
|
|
1058
|
-
### 🚀 Getting Started
|
|
1059
|
-
- **[2-Minute Quick Start](#-2-minute-quick-start)** — npm, CDN, browser setup
|
|
1060
|
-
- **[16 Loading Options](#-16-loading-options---choose-your-approach)** — pick the bundles you need
|
|
1061
|
-
- **[API Reference](#-api-reference)** — quick method lookup
|
|
1062
|
-
- **[CHANGELOG](./CHANGELOG.md)** — version history (current line: 4.x)
|
|
1063
|
-
- **[SECURITY.md](./SECURITY.md)** — supported-versions policy + how to report
|
|
1064
|
-
|
|
1065
|
-
### 🔒 Smart Contracts & Covenants
|
|
1066
|
-
- **[Smart Contract Guide](docs/advanced/SMART_CONTRACT_GUIDE.md)** — comprehensive covenant development
|
|
1067
|
-
- **[Advanced Covenant Development](docs/advanced/ADVANCED_COVENANT_DEVELOPMENT.md)** — full BIP-143 + OP_PUSH_TX guide
|
|
1068
|
-
- **[Custom Script Development](docs/advanced/CUSTOM_SCRIPT_DEVELOPMENT.md)** — multi-sig, timelock, conditional patterns
|
|
1069
|
-
- **[UTXO Manager Guide](docs/advanced/UTXO_MANAGER_GUIDE.md)** — UTXO management + mock generation
|
|
1070
|
-
- **[Covenant Development Resolved](docs/COVENANT_DEVELOPMENT_RESOLVED.md)** — solutions to common issues
|
|
1071
|
-
- **[PUSHTX Key Insights](docs/pushtx-key-insights.md)** — nChain WP1605 implementation notes
|
|
1072
|
-
- **[SmartContract Development Guide](docs/SMART_CONTRACT_DEVELOPMENT_GUIDE.md)** — end-to-end workflow
|
|
1073
|
-
|
|
1074
|
-
### 🆕 Advanced Features
|
|
1075
|
-
- **[Legal Token Protocol](docs/advanced/LEGAL_TOKEN_PROTOCOL.md)** — property rights & obligation tokens (LTP)
|
|
1076
|
-
- **[GDAF Developer Interface](docs/technical/GDAF_DEVELOPER_INTERFACE.md)** — Global Digital Attestation Framework
|
|
1077
|
-
- **[Shamir Integration Summary](docs/technical/SHAMIR_INTEGRATION_SUMMARY.md)** — threshold cryptography & key backup
|
|
1078
|
-
|
|
1079
|
-
### 📊 Technical References
|
|
1080
|
-
- **[Module Reference](docs/MODULE_REFERENCE_COMPLETE.md)** — every shipped module
|
|
1081
|
-
- **[Documentation Review Report](docs/DOCUMENTATION_REVIEW_REPORT.md)** — internal doc audit (historical)
|
|
1082
|
-
- **[API Reference (docs/api/)](https://github.com/codenlighten/smartledger-bsv/tree/main/docs/api)** — per-module API docs
|
|
206
|
+
| | |
|
|
207
|
+
|---|---|
|
|
208
|
+
| [STABILITY.md](STABILITY.md) | release policy, deprecation process, what's covered |
|
|
209
|
+
| [docs/advanced/ADVANCED_COVENANT_DEVELOPMENT.md](docs/advanced/ADVANCED_COVENANT_DEVELOPMENT.md) | covenant patterns beyond the basics |
|
|
210
|
+
| [docs/advanced/CUSTOM_SCRIPT_DEVELOPMENT.md](docs/advanced/CUSTOM_SCRIPT_DEVELOPMENT.md) | signing arbitrary locking scripts |
|
|
211
|
+
| [docs/preimage.md](docs/preimage.md) | BIP-143 preimage field layout |
|
|
212
|
+
| [docs/pushtx-key-insights.md](docs/pushtx-key-insights.md) | the nChain OP_PUSH_TX construction and its security claims |
|
|
213
|
+
| [docs/api/SCRIPTS.md](docs/api/SCRIPTS.md) | script API reference |
|
|
214
|
+
| [docs/migration/FROM_BSV_1_5_6.md](docs/migration/FROM_BSV_1_5_6.md) | migrating from classic `bsv` |
|
|
215
|
+
| [SECURITY.md](SECURITY.md) | reporting vulnerabilities |
|
|
216
|
+
| [CHANGELOG.md](CHANGELOG.md) | release history |
|
|
1083
217
|
|
|
1084
|
-
|
|
1085
|
-
- **[Examples Directory](https://github.com/codenlighten/smartledger-bsv/tree/main/examples)** — runnable code samples
|
|
1086
|
-
- **[Demos Directory](https://github.com/codenlighten/smartledger-bsv/tree/main/demos)** — interactive HTML & Node demos
|
|
1087
|
-
- **[Test Suite](https://github.com/codenlighten/smartledger-bsv/tree/main/test)** — covenant verification specs, CLI smoke, full mocha suite
|
|
218
|
+
## Verifying this library yourself
|
|
1088
219
|
|
|
1089
|
-
|
|
1090
|
-
|
|
220
|
+
Consensus behavior is pinned by vectors generated against the reference
|
|
221
|
+
implementation, not by this library's own opinion:
|
|
1091
222
|
|
|
1092
223
|
```bash
|
|
1093
|
-
#
|
|
1094
|
-
npm run
|
|
1095
|
-
npm run
|
|
1096
|
-
npm run demo:covenant # covenant builder example
|
|
224
|
+
npm test # unit + integration
|
|
225
|
+
npm run conformance # 452 cases against the reference corpus
|
|
226
|
+
npm run vectors:sv # SV consensus vector report
|
|
1097
227
|
```
|
|
1098
228
|
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
1. **Start** — [2-Minute Quick Start](#-2-minute-quick-start)
|
|
1102
|
-
2. **Practice** — [Examples Directory](https://github.com/codenlighten/smartledger-bsv/tree/main/examples)
|
|
1103
|
-
3. **Build** — [Custom Script Development](docs/advanced/CUSTOM_SCRIPT_DEVELOPMENT.md)
|
|
1104
|
-
4. **Advanced** — [Advanced Covenant Development](docs/advanced/ADVANCED_COVENANT_DEVELOPMENT.md)
|
|
1105
|
-
5. **Production** — [SECURITY.md](./SECURITY.md) + [v4.0.0 CHANGELOG](./CHANGELOG.md#400---2026-05-31) (mandatory read before mainnet credentials)
|
|
1106
|
-
|
|
1107
|
-
---
|
|
1108
|
-
|
|
1109
|
-
## 📄 **License**
|
|
229
|
+
## Contributing
|
|
1110
230
|
|
|
1111
|
-
|
|
231
|
+
Issues and pull requests: <https://github.com/codenlighten/smartledger-bsv>
|
|
1112
232
|
|
|
1113
|
-
|
|
233
|
+
Two rules matter more than the rest. Consensus changes need a conformance vector
|
|
234
|
+
in the same commit. Removing or breaking a public API needs a deprecation notice
|
|
235
|
+
that has shipped in an earlier minor — see [STABILITY.md](STABILITY.md).
|
|
1114
236
|
|
|
1115
|
-
|
|
1116
|
-
[github.com/codenlighten/smartledger-bsv](https://github.com/codenlighten/smartledger-bsv).
|
|
1117
|
-
For security vulnerabilities, follow the disclosure process in
|
|
1118
|
-
[SECURITY.md](./SECURITY.md) rather than opening a public issue.
|
|
237
|
+
## License
|
|
1119
238
|
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
- **GitHub**: [github.com/codenlighten/smartledger-bsv](https://github.com/codenlighten/smartledger-bsv)
|
|
1123
|
-
- **NPM (scoped)**: [@smartledger/bsv](https://www.npmjs.com/package/@smartledger/bsv)
|
|
1124
|
-
- **NPM (unscoped)**: [smartledger-bsv](https://www.npmjs.com/package/smartledger-bsv)
|
|
1125
|
-
- **Issues**: [GitHub Issues](https://github.com/codenlighten/smartledger-bsv/issues)
|
|
1126
|
-
- **Security**: [SECURITY.md](./SECURITY.md)
|
|
239
|
+
MIT
|
|
1127
240
|
|
|
1128
241
|
---
|
|
1129
242
|
|
|
1130
|
-
**SmartLedger-BSV v9.
|
|
1131
|
-
|
|
1132
|
-
Built with ❤️ for the Bitcoin SV ecosystem • 16 Loading Options • Interpreter-Verified Covenants
|
|
243
|
+
**SmartLedger-BSV v9.1.1**
|