smartledger-bsv 3.3.5 → 3.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +400 -0
  2. package/README.md +235 -80
  3. package/SECURITY.md +88 -0
  4. package/anchor-entry.js +1 -0
  5. package/bin/cli.js +354 -0
  6. package/bsv-anchor.min.js +12 -0
  7. package/bsv-covenant.min.js +8 -8
  8. package/bsv-didweb.min.js +12 -0
  9. package/bsv-gdaf.min.js +9 -9
  10. package/bsv-ltp.min.js +9 -9
  11. package/bsv-mnemonic.min.js +2 -2
  12. package/bsv-shamir.min.js +3 -3
  13. package/bsv-smartcontract.min.js +9 -9
  14. package/bsv-statuslist.min.js +18 -0
  15. package/bsv-vcjwt.min.js +12 -0
  16. package/bsv.bundle.js +9 -9
  17. package/bsv.d.ts +486 -9
  18. package/bsv.min.js +8 -8
  19. package/build/webpack.anchor.config.js +17 -0
  20. package/build/webpack.didweb.config.js +17 -0
  21. package/build/webpack.statuslist.config.js +17 -0
  22. package/build/webpack.vcjwt.config.js +17 -0
  23. package/didweb-entry.js +1 -0
  24. package/docs/COVENANT_DEVELOPMENT_RESOLVED.md +2 -2
  25. package/docs/MODULE_REFERENCE_COMPLETE.md +61 -58
  26. package/docs/advanced/LEGAL_TOKEN_PROTOCOL.md +3 -3
  27. package/docs/advanced/UTXO_MANAGER_GUIDE.md +1 -1
  28. package/docs/getting-started/INSTALLATION.md +30 -30
  29. package/docs/getting-started/QUICK_START.md +18 -18
  30. package/docs/migration/FROM_BSV_1_5_6.md +16 -10
  31. package/docs/technical/roadmap.md +3 -3
  32. package/gdaf-entry.js +1 -2
  33. package/index.js +68 -9
  34. package/lib/anchor/index.js +102 -0
  35. package/lib/browser-utxo-manager-es5.js +11 -4
  36. package/lib/browser-utxo-manager.js +15 -8
  37. package/lib/didweb/index.js +177 -0
  38. package/lib/ltp/claim.js +1 -0
  39. package/lib/ltp/obligation.js +1 -0
  40. package/lib/ltp/registry.js +2 -0
  41. package/lib/ltp/right.js +1 -0
  42. package/lib/smart_contract/covenant.js +10 -1
  43. package/lib/smartutxo.js +20 -12
  44. package/lib/statuslist/index.js +164 -0
  45. package/lib/transaction/transaction.js +8 -1
  46. package/lib/util/_.js +7 -1
  47. package/lib/vcjwt/index.js +189 -0
  48. package/ltp-entry.js +1 -2
  49. package/package.json +21 -15
  50. package/statuslist-entry.js +1 -0
  51. package/utilities/blockchain-state.js +32 -23
  52. package/vcjwt-entry.js +1 -0
  53. package/demos/README.md +0 -188
  54. package/demos/architecture_demo.js +0 -247
  55. package/demos/browser-test.html +0 -1208
  56. package/demos/bsv_wallet_demo.js +0 -242
  57. package/demos/complete_ltp_demo.js +0 -511
  58. package/demos/debug_tools_demo.js +0 -87
  59. package/demos/demo_features.js +0 -123
  60. package/demos/easy_interface_demo.js +0 -109
  61. package/demos/ecies_demo.js +0 -182
  62. package/demos/gdaf_core_test.js +0 -131
  63. package/demos/gdaf_demo.js +0 -237
  64. package/demos/ltp_demo.js +0 -361
  65. package/demos/ltp_primitives_demo.js +0 -403
  66. package/demos/message_demo.js +0 -209
  67. package/demos/preimage_separation_demo.js +0 -383
  68. package/demos/script_helper_demo.js +0 -289
  69. package/demos/security_demo.js +0 -287
  70. package/demos/shamir_demo.js +0 -121
  71. package/demos/simple_demo.js +0 -204
  72. package/demos/simple_p2pkh_demo.js +0 -169
  73. package/demos/simple_utxo_preimage_demo.js +0 -196
  74. package/demos/smart_contract_demo.html +0 -1347
  75. package/demos/smart_contract_demo.js +0 -910
  76. package/demos/utxo_generator_demo.js +0 -244
  77. package/demos/validation_pipeline_demo.js +0 -155
  78. package/demos/web3keys.html +0 -740
  79. package/examples/README.md +0 -200
  80. package/examples/basic/transaction-creation.js +0 -534
  81. package/examples/basic/transaction_signature_api_gap.js +0 -178
  82. package/examples/complete_workflow_demo.js +0 -783
  83. package/examples/covenants/advanced_covenant_demo.js +0 -219
  84. package/examples/covenants/covenant_interface_demo.js +0 -270
  85. package/examples/covenants/covenant_manual_signature_resolved.js +0 -212
  86. package/examples/covenants/covenant_signature_template.js +0 -117
  87. package/examples/covenants2/covenant_bidirectional_example.js +0 -262
  88. package/examples/covenants2/covenant_utils_demo.js +0 -120
  89. package/examples/covenants2/preimage_covenant_utils.js +0 -287
  90. package/examples/covenants2/production_integration.js +0 -256
  91. package/examples/data/covenant_utxos.json +0 -28
  92. package/examples/data/utxos.json +0 -26
  93. package/examples/definitive_working_demo.js +0 -261
  94. package/examples/final_working_contracts.js +0 -338
  95. package/examples/preimage/README.md +0 -178
  96. package/examples/preimage/extract_preimage_bidirectional.js +0 -421
  97. package/examples/preimage/generate_sample_preimage.js +0 -208
  98. package/examples/preimage/generate_sighash_examples.js +0 -152
  99. package/examples/preimage/parse_preimage.js +0 -117
  100. package/examples/preimage/test_preimage_extractor.js +0 -53
  101. package/examples/preimage/test_varint_extraction.js +0 -95
  102. package/examples/scripts/custom_script_helper_example.js +0 -273
  103. package/examples/scripts/custom_script_signature_test.js +0 -344
  104. package/examples/scripts/script_interpreter.js +0 -193
  105. package/examples/smart_contract/complete_workflow_demo.js +0 -343
  106. package/examples/smart_contract/covenant_builder_demo.js +0 -176
  107. package/examples/smart_contract/script_testing_integration.js +0 -198
  108. package/examples/smart_contract_templates.js +0 -718
  109. package/examples/working_smart_contracts.js +0 -348
  110. package/lib/smart_contract/test_integration.js +0 -269
  111. package/tests/browser-compatibility/README.md +0 -35
  112. package/tests/browser-compatibility/test-cdn-vs-local.html +0 -186
  113. package/tests/browser-compatibility/test-pbkdf2.html +0 -51
  114. package/tests/bundle-completeness-test.html +0 -131
  115. package/tests/bundle-demo.html +0 -476
  116. package/tests/smartcontract-test.html +0 -239
  117. package/tests/standalone-modules-test.html +0 -260
  118. package/tests/test.html +0 -612
  119. package/tests/test_builtin_verify.js +0 -117
  120. package/tests/test_debug_integration.js +0 -71
  121. package/tests/test_ecdsa_little.js +0 -70
  122. package/tests/test_shamir.js +0 -221
  123. package/tests/test_smartverify_der.js +0 -110
  124. package/tests/test_standalone_shamir.html +0 -83
  125. package/tests/unpkg-demo.html +0 -194
  126. package/utilities/blockchain-state.json +0 -118565
package/bin/cli.js ADDED
@@ -0,0 +1,354 @@
1
+ #!/usr/bin/env node
2
+ 'use strict'
3
+
4
+ /**
5
+ * SmartLedger BSV CLI
6
+ * Command-line tools for DID:web, VC-JWT, and StatusList2021
7
+ */
8
+
9
+ var fs = require('fs')
10
+ var path = require('path')
11
+ var pkg = require('../package.json')
12
+ var didweb = require('../lib/didweb')
13
+ var vcjwt = require('../lib/vcjwt')
14
+ var statuslist = require('../lib/statuslist')
15
+ var anchor = require('../lib/anchor')
16
+
17
+ var args = process.argv.slice(2)
18
+ var command = args[0]
19
+ var subcommand = args[1]
20
+
21
+ // Helper to parse command-line arguments
22
+ function parseArgs(args) {
23
+ var opts = {}
24
+ for (var i = 0; i < args.length; i++) {
25
+ if (args[i].startsWith('--')) {
26
+ var key = args[i].slice(2)
27
+ var value = args[i + 1]
28
+ opts[key] = value
29
+ i++
30
+ }
31
+ }
32
+ return opts
33
+ }
34
+
35
+ // Helper to read JSON file
36
+ function readJsonFile(filepath) {
37
+ var content = fs.readFileSync(filepath, 'utf8')
38
+ return JSON.parse(content)
39
+ }
40
+
41
+ // Helper to write JSON file
42
+ function writeJsonFile(filepath, data) {
43
+ fs.writeFileSync(filepath, JSON.stringify(data, null, 2))
44
+ }
45
+
46
+ async function main() {
47
+ if (command === '--version' || command === '-v') {
48
+ console.log(pkg.version)
49
+ process.exit(0)
50
+ }
51
+
52
+ if (!command || command === '--help' || command === '-h' || command === 'help') {
53
+ console.log('SmartLedger BSV CLI v' + pkg.version)
54
+ console.log('')
55
+ console.log('Usage:')
56
+ console.log(' smartledger-bsv didweb <subcommand> [options]')
57
+ console.log(' smartledger-bsv vc <subcommand> [options]')
58
+ console.log(' smartledger-bsv status <subcommand> [options]')
59
+ console.log(' smartledger-bsv anchor <subcommand> [options]')
60
+ console.log('')
61
+ console.log('DID:web Commands:')
62
+ console.log(' didweb init --domain <domain> [--alg ES256|ES256K]')
63
+ console.log(' didweb rotate --domain <domain> --key <key-file>')
64
+ console.log('')
65
+ console.log('VC Commands:')
66
+ console.log(' vc issue --issuer <did> --subject <did> --types <types> --claims <json>')
67
+ console.log(' vc verify <jwt-file>')
68
+ console.log('')
69
+ console.log('Status List Commands:')
70
+ console.log(' status create --issuer <did>')
71
+ console.log(' status set --list <file> --index <n> --status <revoked|suspended|valid>')
72
+ console.log(' status check --list <file> --index <n>')
73
+ console.log('')
74
+ console.log('Anchor Commands:')
75
+ console.log(' anchor hash <data-file>')
76
+ console.log(' anchor build --kind <type> --hash <hash> --issuer <did>')
77
+ process.exit(0)
78
+ }
79
+
80
+ var opts = parseArgs(args.slice(2))
81
+
82
+ try {
83
+ if (command === 'didweb') {
84
+ await handleDidWeb(subcommand, opts)
85
+ } else if (command === 'vc') {
86
+ await handleVc(subcommand, opts)
87
+ } else if (command === 'status') {
88
+ await handleStatus(subcommand, opts)
89
+ } else if (command === 'anchor') {
90
+ await handleAnchor(subcommand, opts)
91
+ } else {
92
+ console.error('Unknown command:', command)
93
+ process.exit(1)
94
+ }
95
+ } catch (error) {
96
+ console.error('Error:', error.message)
97
+ process.exit(1)
98
+ }
99
+ }
100
+
101
+ async function handleDidWeb(subcommand, opts) {
102
+ if (subcommand === 'init') {
103
+ if (!opts.domain) {
104
+ console.error('--domain is required')
105
+ process.exit(1)
106
+ }
107
+
108
+ var alg = opts.alg || 'ES256'
109
+ console.error('Generating ' + alg + ' keys for domain: ' + opts.domain)
110
+
111
+ // Generate keys
112
+ var keys = await didweb.generateIssuerKeys({ alg: alg })
113
+
114
+ // Build DID documents
115
+ var docs = didweb.buildDidWebDocuments({
116
+ domain: opts.domain,
117
+ p256: alg === 'ES256' ? { jwk: keys.publicJwk, kid: keys.kid } : undefined,
118
+ k1: alg === 'ES256K' ? { jwk: keys.publicJwk, kid: keys.kid } : undefined,
119
+ controllerName: opts.name || 'SmartLedger Issuer'
120
+ })
121
+
122
+ // Create .well-known directory
123
+ var wellKnownDir = path.join(process.cwd(), '.well-known')
124
+ if (!fs.existsSync(wellKnownDir)) {
125
+ fs.mkdirSync(wellKnownDir, { recursive: true })
126
+ }
127
+
128
+ // Write did.json
129
+ var didPath = path.join(wellKnownDir, 'did.json')
130
+ writeJsonFile(didPath, docs.didDocument)
131
+ console.error('✅ Created:', didPath)
132
+
133
+ // Write jwks.json
134
+ var jwksPath = path.join(wellKnownDir, 'jwks.json')
135
+ writeJsonFile(jwksPath, docs.jwks)
136
+ console.error('✅ Created:', jwksPath)
137
+
138
+ // Write private key to secure file
139
+ var keyPath = path.join(process.cwd(), 'issuer-key-' + keys.kid + '.json')
140
+ writeJsonFile(keyPath, {
141
+ kid: keys.kid,
142
+ alg: keys.alg,
143
+ privateJwk: keys.privateJwk,
144
+ publicJwk: keys.publicJwk,
145
+ did: docs.did
146
+ })
147
+ console.error('✅ Created private key:', keyPath)
148
+ console.error('⚠️ KEEP THIS FILE SECURE AND ENCRYPTED!')
149
+
150
+ console.error('')
151
+ console.error('DID:', docs.did)
152
+ console.error('')
153
+ console.error('Next steps:')
154
+ console.error('1. Host .well-known/did.json and .well-known/jwks.json at https://' + opts.domain)
155
+ console.error('2. Encrypt and securely store ' + keyPath)
156
+ console.error('3. Issue credentials with: smartledger-bsv vc issue ...')
157
+
158
+ } else if (subcommand === 'rotate') {
159
+ console.error('Key rotation coming soon')
160
+ } else {
161
+ console.error('Unknown didweb subcommand:', subcommand)
162
+ process.exit(1)
163
+ }
164
+ }
165
+
166
+ async function handleVc(subcommand, opts) {
167
+ if (subcommand === 'issue') {
168
+ if (!opts.issuer || !opts.subject || !opts.claims) {
169
+ console.error('--issuer, --subject, and --claims are required')
170
+ process.exit(1)
171
+ }
172
+
173
+ // Load issuer key
174
+ var keyFile = opts.key || 'issuer-key.json'
175
+ if (!fs.existsSync(keyFile)) {
176
+ console.error('Issuer key file not found:', keyFile)
177
+ console.error('Use --key to specify the key file')
178
+ process.exit(1)
179
+ }
180
+
181
+ var keyData = readJsonFile(keyFile)
182
+ var claims = JSON.parse(opts.claims)
183
+ var types = opts.types ? opts.types.split(',') : ['VerifiableCredential']
184
+
185
+ console.error('Issuing credential...')
186
+ console.error(' Issuer:', opts.issuer)
187
+ console.error(' Subject:', opts.subject)
188
+ console.error(' Types:', types.join(', '))
189
+
190
+ var result = await vcjwt.issueVcJwt({
191
+ issuerDid: opts.issuer,
192
+ subjectId: opts.subject,
193
+ types: types,
194
+ credentialSubject: claims,
195
+ privateJwk: keyData.privateJwk,
196
+ alg: keyData.alg || 'ES256',
197
+ kid: keyData.kid
198
+ })
199
+
200
+ console.log(result.jwt)
201
+ console.error('✅ Credential issued successfully')
202
+
203
+ } else if (subcommand === 'verify') {
204
+ var jwtFile = opts.jwt || args[2]
205
+ if (!jwtFile) {
206
+ console.error('JWT file required')
207
+ process.exit(1)
208
+ }
209
+
210
+ var jwt = fs.readFileSync(jwtFile, 'utf8').trim()
211
+
212
+ console.error('Verifying credential...')
213
+
214
+ // Simple resolver that reads from .well-known. lib/vcjwt expects
215
+ // `{ jwks: { keys: [...] } }`; jwks.json on disk is the raw JWKS,
216
+ // so wrap it.
217
+ var didResolver = async function (did) {
218
+ var jwksPath = path.join(process.cwd(), '.well-known', 'jwks.json')
219
+ if (fs.existsSync(jwksPath)) {
220
+ return { jwks: readJsonFile(jwksPath) }
221
+ }
222
+ throw new Error('Cannot resolve DID: ' + did)
223
+ }
224
+
225
+ var result = await vcjwt.verifyVcJwt(jwt, { didResolver: didResolver })
226
+
227
+ if (result.valid) {
228
+ console.error('✅ Credential is VALID')
229
+ console.log(JSON.stringify(result.payload, null, 2))
230
+ } else {
231
+ console.error('❌ Credential is INVALID')
232
+ console.error('Error:', result.error)
233
+ process.exit(1)
234
+ }
235
+
236
+ } else {
237
+ console.error('Unknown vc subcommand:', subcommand)
238
+ process.exit(1)
239
+ }
240
+ }
241
+
242
+ async function handleStatus(subcommand, opts) {
243
+ if (subcommand === 'create') {
244
+ if (!opts.issuer) {
245
+ console.error('--issuer is required')
246
+ process.exit(1)
247
+ }
248
+
249
+ var keyFile = opts.key || 'issuer-key.json'
250
+ if (!fs.existsSync(keyFile)) {
251
+ console.error('Issuer key file not found:', keyFile)
252
+ process.exit(1)
253
+ }
254
+
255
+ var keyData = readJsonFile(keyFile)
256
+
257
+ console.error('Creating status list...')
258
+
259
+ var result = await statuslist.createStatusList({
260
+ issuerDid: opts.issuer,
261
+ privateJwk: keyData.privateJwk
262
+ })
263
+
264
+ console.log(result.listVcJwt)
265
+ console.error('✅ Status list created')
266
+ console.error('List ID:', result.listId)
267
+
268
+ } else if (subcommand === 'set') {
269
+ if (!opts.list || opts.index === undefined || !opts.status) {
270
+ console.error('--list, --index, and --status are required')
271
+ process.exit(1)
272
+ }
273
+
274
+ var listJwt = fs.readFileSync(opts.list, 'utf8').trim()
275
+ var keyFile = opts.key || 'issuer-key.json'
276
+ var keyData = readJsonFile(keyFile)
277
+
278
+ console.error('Updating status list...')
279
+ console.error(' Index:', opts.index)
280
+ console.error(' Status:', opts.status)
281
+
282
+ var result = await statuslist.updateStatusList({
283
+ listVcJwt: listJwt,
284
+ index: parseInt(opts.index),
285
+ status: opts.status,
286
+ privateJwk: keyData.privateJwk
287
+ })
288
+
289
+ console.log(result.listVcJwt)
290
+ console.error('✅ Status list updated')
291
+
292
+ } else if (subcommand === 'check') {
293
+ if (!opts.list || opts.index === undefined) {
294
+ console.error('--list and --index are required')
295
+ process.exit(1)
296
+ }
297
+
298
+ var listJwt = fs.readFileSync(opts.list, 'utf8').trim()
299
+
300
+ var status = statuslist.getCredentialStatusEntry({
301
+ listVcJwt: listJwt,
302
+ index: parseInt(opts.index)
303
+ })
304
+
305
+ console.log(status)
306
+ console.error('Status at index', opts.index + ':', status)
307
+
308
+ } else {
309
+ console.error('Unknown status subcommand:', subcommand)
310
+ process.exit(1)
311
+ }
312
+ }
313
+
314
+ async function handleAnchor(subcommand, opts) {
315
+ if (subcommand === 'hash') {
316
+ var dataFile = args[2]
317
+ if (!dataFile) {
318
+ console.error('Data file required')
319
+ process.exit(1)
320
+ }
321
+
322
+ var data = fs.readFileSync(dataFile)
323
+ var hash = anchor.sha256Hex(data)
324
+
325
+ console.log(hash)
326
+ console.error('SHA-256 hash:', hash)
327
+
328
+ } else if (subcommand === 'build') {
329
+ if (!opts.kind || !opts.hash || !opts.issuer) {
330
+ console.error('--kind, --hash, and --issuer are required')
331
+ process.exit(1)
332
+ }
333
+
334
+ var payload = anchor.buildAnchorPayload({
335
+ kind: opts.kind,
336
+ hash: opts.hash,
337
+ issuerDid: opts.issuer,
338
+ issuedAt: opts.timestamp
339
+ })
340
+
341
+ console.log(payload.json)
342
+ console.error('✅ Anchor payload created')
343
+ console.error('Size:', payload.json.length, 'bytes')
344
+
345
+ } else {
346
+ console.error('Unknown anchor subcommand:', subcommand)
347
+ process.exit(1)
348
+ }
349
+ }
350
+
351
+ main().catch(function(error) {
352
+ console.error('Fatal error:', error)
353
+ process.exit(1)
354
+ })