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
@@ -0,0 +1,164 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * StatusList2021 Module
5
+ * W3C StatusList2021 for credential revocation and suspension
6
+ */
7
+
8
+ var vcjwt = require('../vcjwt')
9
+ var crypto = require('crypto')
10
+
11
+ // Create a new status list
12
+ async function createStatusList(params) {
13
+ if (!params.issuerDid || !params.privateJwk) {
14
+ throw new Error('issuerDid and privateJwk are required')
15
+ }
16
+
17
+ var listId = params.listId || params.issuerDid + '/status/' + Date.now()
18
+
19
+ // Create a bitstring for 100,000 credentials (default size)
20
+ var listSize = params.listSize || 100000
21
+ var byteSize = Math.ceil(listSize / 8)
22
+ var bitstringBuffer = Buffer.alloc(byteSize, 0)
23
+
24
+ // Compress with gzip
25
+ var zlib = require('zlib')
26
+ var compressed = zlib.gzipSync(bitstringBuffer)
27
+ var encodedCompressed = compressed.toString('base64')
28
+
29
+ // Create StatusList2021 credential
30
+ var statusListCredential = {
31
+ '@context': [
32
+ 'https://www.w3.org/2018/credentials/v1',
33
+ 'https://w3id.org/vc/status-list/2021/v1'
34
+ ],
35
+ type: ['VerifiableCredential', 'StatusList2021Credential'],
36
+ issuer: params.issuerDid,
37
+ issuanceDate: new Date().toISOString(),
38
+ credentialSubject: {
39
+ id: listId,
40
+ type: 'StatusList2021',
41
+ statusPurpose: 'revocation',
42
+ encodedList: encodedCompressed
43
+ }
44
+ }
45
+
46
+ // Issue as JWT
47
+ var result = await vcjwt.issueVcJwt({
48
+ issuerDid: params.issuerDid,
49
+ subjectId: listId,
50
+ types: ['VerifiableCredential', 'StatusList2021Credential'],
51
+ credentialSubject: statusListCredential.credentialSubject,
52
+ privateJwk: params.privateJwk,
53
+ alg: params.privateJwk.alg || 'ES256'
54
+ })
55
+
56
+ return {
57
+ listVcJwt: result.jwt,
58
+ listId: listId
59
+ }
60
+ }
61
+
62
+ // Update status list (revoke/suspend/activate)
63
+ async function updateStatusList(params) {
64
+ if (!params.listVcJwt || params.index === undefined || !params.status || !params.privateJwk) {
65
+ throw new Error('listVcJwt, index, status, and privateJwk are required')
66
+ }
67
+
68
+ // Decode the existing status list JWT
69
+ var parts = params.listVcJwt.split('.')
70
+ if (parts.length !== 3) {
71
+ throw new Error('Invalid JWT format')
72
+ }
73
+
74
+ var payload = JSON.parse(vcjwt.base64UrlDecode(parts[1]).toString())
75
+ var encodedList = payload.vc.credentialSubject.encodedList
76
+
77
+ // Decompress
78
+ var zlib = require('zlib')
79
+ var compressed = Buffer.from(encodedList, 'base64')
80
+ var bitstring = zlib.gunzipSync(compressed)
81
+
82
+ // Update the bit at the given index
83
+ var byteIndex = Math.floor(params.index / 8)
84
+ var bitIndex = params.index % 8
85
+
86
+ if (byteIndex >= bitstring.length) {
87
+ throw new Error('Index out of range')
88
+ }
89
+
90
+ // StatusList2021 uses 2 bits per credential for 4 states
91
+ // For simplicity, we'll use single bit: 0=valid, 1=revoked/suspended
92
+ var statusBit = (params.status === 'revoked' || params.status === 'suspended') ? 1 : 0
93
+
94
+ if (statusBit === 1) {
95
+ bitstring[byteIndex] |= (1 << bitIndex)
96
+ } else {
97
+ bitstring[byteIndex] &= ~(1 << bitIndex)
98
+ }
99
+
100
+ // Recompress
101
+ var recompressed = zlib.gzipSync(bitstring)
102
+ var newEncodedList = recompressed.toString('base64')
103
+
104
+ // Create updated credential
105
+ var updatedCredentialSubject = {
106
+ id: payload.vc.credentialSubject.id,
107
+ type: 'StatusList2021',
108
+ statusPurpose: 'revocation',
109
+ encodedList: newEncodedList
110
+ }
111
+
112
+ // Re-issue as JWT
113
+ var result = await vcjwt.issueVcJwt({
114
+ issuerDid: payload.iss,
115
+ subjectId: payload.vc.credentialSubject.id,
116
+ types: ['VerifiableCredential', 'StatusList2021Credential'],
117
+ credentialSubject: updatedCredentialSubject,
118
+ privateJwk: params.privateJwk,
119
+ alg: params.privateJwk.alg || 'ES256'
120
+ })
121
+
122
+ return {
123
+ listVcJwt: result.jwt
124
+ }
125
+ }
126
+
127
+ // Get credential status entry
128
+ function getCredentialStatusEntry(params) {
129
+ if (!params.listVcJwt || params.index === undefined) {
130
+ throw new Error('listVcJwt and index are required')
131
+ }
132
+
133
+ // Decode the status list JWT
134
+ var parts = params.listVcJwt.split('.')
135
+ if (parts.length !== 3) {
136
+ throw new Error('Invalid JWT format')
137
+ }
138
+
139
+ var payload = JSON.parse(vcjwt.base64UrlDecode(parts[1]).toString())
140
+ var encodedList = payload.vc.credentialSubject.encodedList
141
+
142
+ // Decompress
143
+ var zlib = require('zlib')
144
+ var compressed = Buffer.from(encodedList, 'base64')
145
+ var bitstring = zlib.gunzipSync(compressed)
146
+
147
+ // Check the bit at the given index
148
+ var byteIndex = Math.floor(params.index / 8)
149
+ var bitIndex = params.index % 8
150
+
151
+ if (byteIndex >= bitstring.length) {
152
+ throw new Error('Index out of range')
153
+ }
154
+
155
+ var bit = (bitstring[byteIndex] >> bitIndex) & 1
156
+
157
+ return bit === 1 ? 'revoked' : 'valid'
158
+ }
159
+
160
+ module.exports = {
161
+ createStatusList: createStatusList,
162
+ updateStatusList: updateStatusList,
163
+ getCredentialStatusEntry: getCredentialStatusEntry
164
+ }
@@ -577,7 +577,7 @@ Transaction.prototype._fromMultisigUtxo = function (utxo, pubkeys, threshold) {
577
577
  } else if (utxo.script.isScriptHashOut()) {
578
578
  Clazz = MultiSigScriptHashInput
579
579
  } else {
580
- throw new Error('@TODO')
580
+ throw new errors.Transaction.Input.UnsupportedScript(utxo.script.toString())
581
581
  }
582
582
  this.addInput(new Clazz({
583
583
  output: new Output({
@@ -911,6 +911,13 @@ Transaction.prototype._getUnspentValue = function () {
911
911
 
912
912
  Transaction.prototype._clearSignatures = function () {
913
913
  _.each(this.inputs, function (input) {
914
+ // Custom-script inputs (bare Input base class — e.g. covenant or other
915
+ // non-standard locking scripts) have no library-managed signatures to
916
+ // clear; the caller owns input.script. Mirror the guard pattern used by
917
+ // Transaction.prototype.isFullySigned / isValidSignature below.
918
+ if (input.clearSignatures === Input.prototype.clearSignatures) {
919
+ return
920
+ }
914
921
  input.clearSignatures()
915
922
  })
916
923
  }
package/lib/util/_.js CHANGED
@@ -1,5 +1,7 @@
1
1
  'use strict'
2
2
 
3
+ var Random = require('../crypto/random')
4
+
3
5
  var _ = {}
4
6
 
5
7
  _.isArray = t => Array.isArray(t)
@@ -28,10 +30,14 @@ _.values = o => Object.values(o)
28
30
  _.filter = (a, f) => a.filter(f)
29
31
  _.reduce = (a, f, s) => a.reduce(f, s)
30
32
  _.without = (a, n) => a.filter(t => t !== n)
33
+ // CSPRNG-backed Fisher-Yates. Output-order shuffling is a privacy primitive
34
+ // (Transaction.shuffleOutputs); a predictable PRNG defeats the purpose.
31
35
  _.shuffle = a => {
32
36
  const result = a.slice(0)
33
37
  for (let i = result.length - 1; i > 0; i--) {
34
- const j = Math.floor(Math.random() * (i + 1));
38
+ const buf = Random.getRandomBuffer(4)
39
+ const r = buf.readUInt32BE(0) / 0x100000000
40
+ const j = Math.floor(r * (i + 1));
35
41
  [result[i], result[j]] = [result[j], result[i]]
36
42
  }
37
43
  return result
@@ -0,0 +1,189 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * VC-JWT Module
5
+ * W3C Verifiable Credentials using JWT/JWS
6
+ * Supports ES256 (P-256) and ES256K (secp256k1)
7
+ */
8
+
9
+ var crypto = require('crypto')
10
+
11
+ // Base64URL encoding
12
+ function base64UrlEncode(buffer) {
13
+ return buffer.toString('base64')
14
+ .replace(/\+/g, '-')
15
+ .replace(/\//g, '_')
16
+ .replace(/=/g, '')
17
+ }
18
+
19
+ // Base64URL decoding
20
+ function base64UrlDecode(str) {
21
+ str = str.replace(/-/g, '+').replace(/_/g, '/')
22
+ while (str.length % 4) {
23
+ str += '='
24
+ }
25
+ return Buffer.from(str, 'base64')
26
+ }
27
+
28
+ // Issue a Verifiable Credential as JWT
29
+ async function issueVcJwt(params) {
30
+ if (!params.issuerDid || !params.subjectId || !params.credentialSubject || !params.privateJwk) {
31
+ throw new Error('issuerDid, subjectId, credentialSubject, and privateJwk are required')
32
+ }
33
+
34
+ var alg = params.alg || 'ES256'
35
+ var kid = params.kid || params.privateJwk.kid
36
+ var types = params.types || ['VerifiableCredential']
37
+ var expSeconds = params.expSeconds || (365 * 24 * 60 * 60) // 1 year default
38
+
39
+ var now = Math.floor(Date.now() / 1000)
40
+ var issuedAt = new Date().toISOString()
41
+
42
+ // Build VC payload
43
+ var vcPayload = {
44
+ '@context': [
45
+ 'https://www.w3.org/2018/credentials/v1'
46
+ ],
47
+ type: types,
48
+ issuer: params.issuerDid,
49
+ issuanceDate: issuedAt,
50
+ credentialSubject: Object.assign({
51
+ id: params.subjectId
52
+ }, params.credentialSubject)
53
+ }
54
+
55
+ // Build JWT claims
56
+ var jwtPayload = {
57
+ iss: params.issuerDid,
58
+ sub: params.subjectId,
59
+ iat: now,
60
+ exp: now + expSeconds,
61
+ vc: vcPayload
62
+ }
63
+
64
+ // Build JWT header
65
+ var header = {
66
+ alg: alg,
67
+ typ: 'JWT',
68
+ kid: kid
69
+ }
70
+
71
+ // Encode header and payload
72
+ var headerB64 = base64UrlEncode(Buffer.from(JSON.stringify(header)))
73
+ var payloadB64 = base64UrlEncode(Buffer.from(JSON.stringify(jwtPayload)))
74
+ var signingInput = headerB64 + '.' + payloadB64
75
+
76
+ // Sign with private key
77
+ var privateKey = crypto.createPrivateKey({
78
+ key: params.privateJwk,
79
+ format: 'jwk'
80
+ })
81
+
82
+ var signature
83
+ if (alg === 'ES256') {
84
+ signature = crypto.sign('sha256', Buffer.from(signingInput), privateKey)
85
+ } else if (alg === 'ES256K') {
86
+ signature = crypto.sign('sha256', Buffer.from(signingInput), privateKey)
87
+ } else {
88
+ throw new Error('Unsupported algorithm: ' + alg)
89
+ }
90
+
91
+ var signatureB64 = base64UrlEncode(signature)
92
+ var jwt = signingInput + '.' + signatureB64
93
+
94
+ return { jwt: jwt }
95
+ }
96
+
97
+ // Verify a VC-JWT
98
+ async function verifyVcJwt(jwt, opts) {
99
+ opts = opts || {}
100
+
101
+ try {
102
+ // Parse JWT
103
+ var parts = jwt.split('.')
104
+ if (parts.length !== 3) {
105
+ return { valid: false, error: 'Invalid JWT format' }
106
+ }
107
+
108
+ var headerB64 = parts[0]
109
+ var payloadB64 = parts[1]
110
+ var signatureB64 = parts[2]
111
+
112
+ var header = JSON.parse(base64UrlDecode(headerB64).toString())
113
+ var payload = JSON.parse(base64UrlDecode(payloadB64).toString())
114
+ var signature = base64UrlDecode(signatureB64)
115
+
116
+ // Check expiration
117
+ var now = Math.floor(Date.now() / 1000)
118
+ var clockTolerance = opts.clockToleranceSec || 60
119
+
120
+ if (payload.exp && payload.exp < (now - clockTolerance)) {
121
+ return { valid: false, error: 'JWT expired', header: header, payload: payload }
122
+ }
123
+
124
+ // Check issuer if expected
125
+ if (opts.expectedIssuerDid && payload.iss !== opts.expectedIssuerDid) {
126
+ return { valid: false, error: 'Unexpected issuer', header: header, payload: payload }
127
+ }
128
+
129
+ // Get public key from DID resolver or use default resolver
130
+ var publicKey
131
+ if (opts.didResolver) {
132
+ var resolved = await opts.didResolver(payload.iss)
133
+ if (!resolved || !resolved.jwks || !resolved.jwks.keys) {
134
+ return { valid: false, error: 'Failed to resolve issuer DID', header: header, payload: payload }
135
+ }
136
+
137
+ // Find matching key by kid
138
+ var matchingKey = resolved.jwks.keys.find(function(k) {
139
+ return k.kid === header.kid
140
+ })
141
+
142
+ if (!matchingKey) {
143
+ return { valid: false, error: 'Key not found in JWKS', header: header, payload: payload }
144
+ }
145
+
146
+ publicKey = matchingKey
147
+ } else {
148
+ // Without resolver, verification cannot proceed
149
+ return { valid: false, error: 'DID resolver required for verification', header: header, payload: payload }
150
+ }
151
+
152
+ // Verify signature
153
+ var signingInput = headerB64 + '.' + payloadB64
154
+ var pubKey = crypto.createPublicKey({
155
+ key: publicKey,
156
+ format: 'jwk'
157
+ })
158
+
159
+ var isValid = crypto.verify(
160
+ 'sha256',
161
+ Buffer.from(signingInput),
162
+ pubKey,
163
+ signature
164
+ )
165
+
166
+ if (!isValid) {
167
+ return { valid: false, error: 'Invalid signature', header: header, payload: payload }
168
+ }
169
+
170
+ return {
171
+ valid: true,
172
+ header: header,
173
+ payload: payload
174
+ }
175
+
176
+ } catch (error) {
177
+ return {
178
+ valid: false,
179
+ error: error.message || 'Verification failed'
180
+ }
181
+ }
182
+ }
183
+
184
+ module.exports = {
185
+ issueVcJwt: issueVcJwt,
186
+ verifyVcJwt: verifyVcJwt,
187
+ base64UrlEncode: base64UrlEncode,
188
+ base64UrlDecode: base64UrlDecode
189
+ }
package/ltp-entry.js CHANGED
@@ -1,2 +1 @@
1
- // LTP module placeholder - will be implemented in future release
2
- module.exports = require('./lib/smart_contract');
1
+ module.exports = require('./lib/ltp')
package/package.json CHANGED
@@ -1,16 +1,21 @@
1
1
  {
2
2
  "name": "smartledger-bsv",
3
- "version": "3.3.5",
4
- "description": "🚀 Complete Bitcoin SV development framework with Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), Shamir Secret Sharing, and 12 flexible loading options. Includes primitives-only architecture for maximum integration flexibility, SmartContract framework, covenant builder, and comprehensive Bitcoin SV API. Perfect for legal tokens, DeFi, smart contracts, and secure Bitcoin applications.",
3
+ "version": "3.4.4",
4
+ "description": "🚀 Complete Bitcoin SV development framework with legally-recognizable DID:web + W3C VC-JWT toolkit, Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF), StatusList2021 revocation, and 16 flexible loading options. Standards-based credentials with ES256/ES256K support, on-chain BSV anchoring, and comprehensive Bitcoin SV API. Perfect for legal tokens, verifiable credentials, DeFi, smart contracts, and secure Bitcoin applications.",
5
5
  "author": "SmartLedger Technology <hello@smartledger.technology> (https://smartledger.technology)",
6
6
  "homepage": "https://github.com/codenlighten/smartledger-bsv#readme",
7
7
  "bugs": {
8
8
  "url": "https://github.com/codenlighten/smartledger-bsv/issues"
9
9
  },
10
10
  "main": "index.js",
11
+ "types": "bsv.d.ts",
12
+ "bin": {
13
+ "smartledger-bsv": "./bin/cli.js"
14
+ },
11
15
  "scripts": {
12
16
  "lint": "standard",
13
17
  "test": "mocha",
18
+ "test:cli": "mocha test/cli/smoke.js --timeout 25000",
14
19
  "test:ltp": "node complete_ltp_demo.js",
15
20
  "test:ltp-primitives": "node simple_demo.js",
16
21
  "test:architecture": "node architecture_demo.js",
@@ -46,15 +51,20 @@
46
51
  "build-covenant": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack covenant-entry.js --config build/webpack.covenant.config.js",
47
52
  "build-script-helper": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack script-helper-entry.js --config build/webpack.script-helper.config.js",
48
53
  "build-security": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack security-entry.js --config build/webpack.security.config.js",
54
+ "build-didweb": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack didweb-entry.js --config build/webpack.didweb.config.js",
55
+ "build-vcjwt": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack vcjwt-entry.js --config build/webpack.vcjwt.config.js",
56
+ "build-statuslist": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack statuslist-entry.js --config build/webpack.statuslist.config.js",
57
+ "build-anchor": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack anchor-entry.js --config build/webpack.anchor.config.js",
49
58
  "build-bundle": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack bundle-entry.js --config build/webpack.bundle.config.js",
50
59
  "build": "npm run build-bsv && npm run build-ecies && npm run build-message && npm run build-mnemonic && npm run build-shamir && npm run build-smartcontract",
51
60
  "build-specialized": "npm run build-covenant && npm run build-script-helper && npm run build-security",
61
+ "build-credentials": "npm run build-didweb && npm run build-vcjwt && npm run build-statuslist && npm run build-anchor",
52
62
  "build-advanced": "npm run build-ltp && npm run build-gdaf",
53
- "build-all": "npm run build && npm run build-bundle && npm run build-specialized && npm run build-advanced",
63
+ "build-all": "npm run build && npm run build-bundle && npm run build-specialized && npm run build-advanced && npm run build-credentials",
54
64
  "test:browser": "echo 'Open tests/standalone-modules-test.html in browser for comprehensive testing'",
55
65
  "test:bundle": "echo 'Open tests/bundle-completeness-test.html in browser to verify bundle completeness'",
56
66
  "preimage:extract": "node examples/preimage/extract_preimage_bidirectional.js",
57
- "prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build"
67
+ "prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build-all"
58
68
  },
59
69
  "unpkg": "bsv.min.js",
60
70
  "jsdelivr": "bsv.min.js",
@@ -62,12 +72,13 @@
62
72
  "files": [
63
73
  "index.js",
64
74
  "lib/",
65
- "utilities/",
75
+ "utilities/*.js",
76
+ "utilities/README.md",
77
+ "utilities/wallet.json",
66
78
  "ecies/",
67
79
  "message/",
68
80
  "mnemonic/",
69
81
  "build/",
70
- "tests/",
71
82
  "*-entry.js",
72
83
  "bsv.min.js",
73
84
  "bsv.bundle.js",
@@ -81,17 +92,12 @@
81
92
  "bsv-covenant.min.js",
82
93
  "bsv-script-helper.min.js",
83
94
  "bsv-security.min.js",
95
+ "bsv-didweb.min.js",
96
+ "bsv-vcjwt.min.js",
97
+ "bsv-statuslist.min.js",
98
+ "bsv-anchor.min.js",
84
99
  "bsv.d.ts",
85
- "validation_test.js",
86
- "test_shamir.js",
87
- "shamir_demo.js",
88
- "complete_ltp_demo.js",
89
- "simple_demo.js",
90
- "architecture_demo.js",
91
- "test_standalone_shamir.html",
92
100
  "docs/",
93
- "demos/",
94
- "examples/",
95
101
  "LICENSE",
96
102
  "README.md",
97
103
  "SECURITY.md",
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/statuslist')
@@ -5,6 +5,15 @@
5
5
  * Acts as the "blockchain database" for our miner simulator.
6
6
  */
7
7
 
8
+ // Set BSV_DEBUG=1 (Node) or window.BSV_DEBUG = true (browser) to surface
9
+ // info/warning narration from this module. Matches the gating pattern
10
+ // used by lib/browser-utxo-manager-es5.js since v3.4.1.
11
+ const debug = function () {
12
+ const enabled = (typeof process !== 'undefined' && process.env && process.env.BSV_DEBUG) ||
13
+ (typeof window !== 'undefined' && window.BSV_DEBUG)
14
+ if (enabled) console.log.apply(console, arguments)
15
+ }
16
+
8
17
  // Browser-compatible imports
9
18
  let bsv, fs, path, BLOCKCHAIN_STATE_PATH
10
19
 
@@ -16,7 +25,7 @@ if (typeof window === 'undefined' && typeof require === 'function') {
16
25
  path = require('path')
17
26
  BLOCKCHAIN_STATE_PATH = path.join(__dirname, 'blockchain-state.json')
18
27
  } catch (e) {
19
- console.warn('BlockchainState: Running in browser mode - persistence disabled')
28
+ debug('BlockchainState: Running in browser mode - persistence disabled')
20
29
  }
21
30
  } else {
22
31
  // In browser, try to get bsv from global scope or fallback
@@ -54,14 +63,14 @@ function loadBlockchainState () {
54
63
  }
55
64
 
56
65
  if (!fs.existsSync(BLOCKCHAIN_STATE_PATH)) {
57
- console.log('🆕 Creating new blockchain state...')
66
+ debug('🆕 Creating new blockchain state...')
58
67
  const initialState = initializeBlockchainState()
59
68
  saveBlockchainState(initialState)
60
69
  return initialState
61
70
  }
62
71
 
63
72
  const state = JSON.parse(fs.readFileSync(BLOCKCHAIN_STATE_PATH, 'utf8'))
64
- console.log('📖 Loaded existing blockchain state')
73
+ debug('📖 Loaded existing blockchain state')
65
74
  return state
66
75
  } catch (error) {
67
76
  console.error('❌ Error loading blockchain state:', error.message)
@@ -79,7 +88,7 @@ function saveBlockchainState (state) {
79
88
  // Only save to file in Node.js environment
80
89
  if (fs && BLOCKCHAIN_STATE_PATH) {
81
90
  fs.writeFileSync(BLOCKCHAIN_STATE_PATH, JSON.stringify(state, null, 2))
82
- console.log('💾 Blockchain state saved')
91
+ debug('💾 Blockchain state saved')
83
92
  }
84
93
  } catch (error) {
85
94
  console.error('❌ Error saving blockchain state:', error.message)
@@ -90,12 +99,12 @@ function saveBlockchainState (state) {
90
99
  * Register a new wallet in the blockchain state
91
100
  */
92
101
  function registerWallet (walletAddress, walletData) {
93
- console.log(`📝 Registering wallet: ${walletAddress}`)
102
+ debug(`📝 Registering wallet: ${walletAddress}`)
94
103
 
95
104
  const state = loadBlockchainState()
96
105
 
97
106
  if (state.wallets[walletAddress]) {
98
- console.log('â„šī¸ Wallet already exists, updating...')
107
+ debug('â„šī¸ Wallet already exists, updating...')
99
108
  }
100
109
 
101
110
  state.wallets[walletAddress] = {
@@ -122,7 +131,7 @@ function registerWallet (walletAddress, walletData) {
122
131
 
123
132
  saveBlockchainState(state)
124
133
 
125
- console.log(`✅ Wallet registered: ${walletAddress}`)
134
+ debug(`✅ Wallet registered: ${walletAddress}`)
126
135
  return state
127
136
  }
128
137
 
@@ -185,7 +194,7 @@ function spendUTXO (txid, vout, spentInTx) {
185
194
 
186
195
  updateBlockchainMetadata(state)
187
196
  saveBlockchainState(state)
188
- console.log(`❌ UTXO spent: ${utxoKey} in tx ${spentInTx}`)
197
+ debug(`❌ UTXO spent: ${utxoKey} in tx ${spentInTx}`)
189
198
  }
190
199
 
191
200
  /**
@@ -197,7 +206,7 @@ function addUTXO (utxo, ownerAddress) {
197
206
 
198
207
  // Check if UTXO already exists
199
208
  if (state.globalUTXOSet[utxoKey]) {
200
- console.log(`âš ī¸ UTXO ${utxoKey} already exists, skipping`)
209
+ debug(`âš ī¸ UTXO ${utxoKey} already exists, skipping`)
201
210
  return
202
211
  }
203
212
 
@@ -229,7 +238,7 @@ function addUTXO (utxo, ownerAddress) {
229
238
  updateBlockchainMetadata(state)
230
239
  saveBlockchainState(state)
231
240
 
232
- console.log(`✅ UTXO added: ${utxoKey} for ${ownerAddress}`)
241
+ debug(`✅ UTXO added: ${utxoKey} for ${ownerAddress}`)
233
242
  }
234
243
 
235
244
  /**
@@ -255,18 +264,18 @@ function updateBlockchainMetadata (state) {
255
264
  function getBlockchainStats () {
256
265
  const state = loadBlockchainState()
257
266
 
258
- console.log('🌐 Blockchain State Statistics:')
259
- console.log('═══════════════════════════════════════════')
260
- console.log(`📊 Total Wallets: ${state.metadata.totalWallets}`)
261
- console.log(`💰 Total UTXOs: ${state.metadata.totalUTXOs}`)
262
- console.log(`💎 Total Value: ${state.metadata.totalValue} satoshis`)
263
- console.log(`đŸ—ī¸ Block Height: ${state.metadata.blockHeight}`)
264
- console.log(`🕐 Last Updated: ${state.metadata.lastUpdated}\n`)
267
+ debug('🌐 Blockchain State Statistics:')
268
+ debug('═══════════════════════════════════════════')
269
+ debug(`📊 Total Wallets: ${state.metadata.totalWallets}`)
270
+ debug(`💰 Total UTXOs: ${state.metadata.totalUTXOs}`)
271
+ debug(`💎 Total Value: ${state.metadata.totalValue} satoshis`)
272
+ debug(`đŸ—ī¸ Block Height: ${state.metadata.blockHeight}`)
273
+ debug(`🕐 Last Updated: ${state.metadata.lastUpdated}\n`)
265
274
 
266
275
  if (Object.keys(state.wallets).length > 0) {
267
- console.log('👛 Registered Wallets:')
276
+ debug('👛 Registered Wallets:')
268
277
  Object.entries(state.wallets).forEach(([address, wallet]) => {
269
- console.log(` ${address}: ${wallet.utxos.length} UTXOs, ${wallet.totalValue} sats`)
278
+ debug(` ${address}: ${wallet.utxos.length} UTXOs, ${wallet.totalValue} sats`)
270
279
  })
271
280
  }
272
281
 
@@ -280,14 +289,14 @@ function importWalletFromFile () {
280
289
  const walletPath = path.join(__dirname, 'wallet.json')
281
290
 
282
291
  if (!fs.existsSync(walletPath)) {
283
- console.log('❌ No wallet.json found to import')
292
+ debug('❌ No wallet.json found to import')
284
293
  return false
285
294
  }
286
295
 
287
296
  try {
288
297
  const walletData = JSON.parse(fs.readFileSync(walletPath, 'utf8'))
289
298
 
290
- console.log('đŸ“Ĩ Importing wallet from wallet.json...')
299
+ debug('đŸ“Ĩ Importing wallet from wallet.json...')
291
300
 
292
301
  const walletInfo = {
293
302
  registeredAt: new Date().toISOString(),
@@ -296,7 +305,7 @@ function importWalletFromFile () {
296
305
 
297
306
  registerWallet(walletData.wallet.address, walletInfo)
298
307
 
299
- console.log('✅ Wallet imported successfully')
308
+ debug('✅ Wallet imported successfully')
300
309
  return true
301
310
  } catch (error) {
302
311
  console.error('❌ Error importing wallet:', error.message)
@@ -313,7 +322,7 @@ if (require.main === module) {
313
322
  } else if (args[0] === 'init') {
314
323
  const state = initializeBlockchainState()
315
324
  saveBlockchainState(state)
316
- console.log('🆕 Initialized new blockchain state')
325
+ debug('🆕 Initialized new blockchain state')
317
326
  }
318
327
 
319
328
  getBlockchainStats()
package/vcjwt-entry.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/vcjwt')