@smartledger/bsv 3.3.5 → 3.4.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 +48 -0
- package/README.md +149 -20
- package/anchor-entry.js +1 -0
- package/bin/cli.js +349 -0
- package/bsv-anchor.min.js +12 -0
- package/bsv-covenant.min.js +8 -8
- package/bsv-didweb.min.js +12 -0
- package/bsv-gdaf.min.js +9 -9
- package/bsv-ltp.min.js +9 -9
- package/bsv-mnemonic.min.js +2 -2
- package/bsv-shamir.min.js +3 -3
- package/bsv-smartcontract.min.js +9 -9
- package/bsv-statuslist.min.js +18 -0
- package/bsv-vcjwt.min.js +12 -0
- package/bsv.bundle.js +9 -9
- package/bsv.min.js +8 -8
- package/build/webpack.anchor.config.js +17 -0
- package/build/webpack.didweb.config.js +17 -0
- package/build/webpack.statuslist.config.js +17 -0
- package/build/webpack.vcjwt.config.js +17 -0
- package/demos/browser-test.html +1 -1
- package/didweb-entry.js +1 -0
- package/docs/technical/roadmap.md +3 -3
- package/examples/legacy/README.md +11 -0
- package/index.js +39 -1
- package/lib/anchor/index.js +102 -0
- package/lib/browser-utxo-manager-es5.js +11 -4
- package/lib/browser-utxo-manager.js +15 -8
- package/lib/didweb/index.js +177 -0
- package/lib/ltp/claim.js +1 -0
- package/lib/ltp/obligation.js +1 -0
- package/lib/ltp/registry.js +2 -0
- package/lib/ltp/right.js +1 -0
- package/lib/statuslist/index.js +164 -0
- package/lib/transaction/transaction.js +1 -1
- package/lib/util/_.js +7 -1
- package/lib/vcjwt/index.js +189 -0
- package/package.json +19 -13
- package/statuslist-entry.js +1 -0
- package/vcjwt-entry.js +1 -0
- package/demos/gdaf_core_test.js +0 -131
- package/examples/scripts/custom_script_signature_test.js +0 -344
- package/tests/browser-compatibility/README.md +0 -35
- package/tests/browser-compatibility/test-cdn-vs-local.html +0 -186
- package/tests/browser-compatibility/test-pbkdf2.html +0 -51
- package/tests/bundle-completeness-test.html +0 -131
- package/tests/bundle-demo.html +0 -476
- package/tests/smartcontract-test.html +0 -239
- package/tests/standalone-modules-test.html +0 -260
- package/tests/test.html +0 -612
- package/tests/test_standalone_shamir.html +0 -83
- package/tests/unpkg-demo.html +0 -194
- package/utilities/blockchain-state.json +0 -118565
- /package/{lib/smart_contract/test_integration.js → examples/legacy/smart_contract_test_integration.js} +0 -0
- /package/{tests → examples/legacy}/test_builtin_verify.js +0 -0
- /package/{tests → examples/legacy}/test_debug_integration.js +0 -0
- /package/{tests → examples/legacy}/test_ecdsa_little.js +0 -0
- /package/{tests → examples/legacy}/test_shamir.js +0 -0
- /package/{tests → examples/legacy}/test_smartverify_der.js +0 -0
|
@@ -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
|
|
580
|
+
throw new errors.Transaction.Input.UnsupportedScript(utxo.script.toString())
|
|
581
581
|
}
|
|
582
582
|
this.addInput(new Clazz({
|
|
583
583
|
output: new Output({
|
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
|
|
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/package.json
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smartledger/bsv",
|
|
3
|
-
"version": "3.
|
|
4
|
-
"description": "🚀 Complete Bitcoin SV development framework with Legal Token Protocol (LTP), Global Digital Attestation Framework (GDAF),
|
|
3
|
+
"version": "3.4.1",
|
|
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
|
+
"bin": {
|
|
12
|
+
"smartledger-bsv": "./bin/cli.js"
|
|
13
|
+
},
|
|
11
14
|
"scripts": {
|
|
12
15
|
"lint": "standard",
|
|
13
16
|
"test": "mocha",
|
|
@@ -46,15 +49,20 @@
|
|
|
46
49
|
"build-covenant": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack covenant-entry.js --config build/webpack.covenant.config.js",
|
|
47
50
|
"build-script-helper": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack script-helper-entry.js --config build/webpack.script-helper.config.js",
|
|
48
51
|
"build-security": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack security-entry.js --config build/webpack.security.config.js",
|
|
52
|
+
"build-didweb": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack didweb-entry.js --config build/webpack.didweb.config.js",
|
|
53
|
+
"build-vcjwt": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack vcjwt-entry.js --config build/webpack.vcjwt.config.js",
|
|
54
|
+
"build-statuslist": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack statuslist-entry.js --config build/webpack.statuslist.config.js",
|
|
55
|
+
"build-anchor": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack anchor-entry.js --config build/webpack.anchor.config.js",
|
|
49
56
|
"build-bundle": "NODE_OPTIONS=\"--openssl-legacy-provider\" webpack bundle-entry.js --config build/webpack.bundle.config.js",
|
|
50
57
|
"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
58
|
"build-specialized": "npm run build-covenant && npm run build-script-helper && npm run build-security",
|
|
59
|
+
"build-credentials": "npm run build-didweb && npm run build-vcjwt && npm run build-statuslist && npm run build-anchor",
|
|
52
60
|
"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",
|
|
61
|
+
"build-all": "npm run build && npm run build-bundle && npm run build-specialized && npm run build-advanced && npm run build-credentials",
|
|
54
62
|
"test:browser": "echo 'Open tests/standalone-modules-test.html in browser for comprehensive testing'",
|
|
55
63
|
"test:bundle": "echo 'Open tests/bundle-completeness-test.html in browser to verify bundle completeness'",
|
|
56
64
|
"preimage:extract": "node examples/preimage/extract_preimage_bidirectional.js",
|
|
57
|
-
"prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build"
|
|
65
|
+
"prepublishOnly": "NODE_OPTIONS=\"--openssl-legacy-provider\" npm run build-all"
|
|
58
66
|
},
|
|
59
67
|
"unpkg": "bsv.min.js",
|
|
60
68
|
"jsdelivr": "bsv.min.js",
|
|
@@ -62,12 +70,13 @@
|
|
|
62
70
|
"files": [
|
|
63
71
|
"index.js",
|
|
64
72
|
"lib/",
|
|
65
|
-
"utilities
|
|
73
|
+
"utilities/*.js",
|
|
74
|
+
"utilities/README.md",
|
|
75
|
+
"utilities/wallet.json",
|
|
66
76
|
"ecies/",
|
|
67
77
|
"message/",
|
|
68
78
|
"mnemonic/",
|
|
69
79
|
"build/",
|
|
70
|
-
"tests/",
|
|
71
80
|
"*-entry.js",
|
|
72
81
|
"bsv.min.js",
|
|
73
82
|
"bsv.bundle.js",
|
|
@@ -81,14 +90,11 @@
|
|
|
81
90
|
"bsv-covenant.min.js",
|
|
82
91
|
"bsv-script-helper.min.js",
|
|
83
92
|
"bsv-security.min.js",
|
|
93
|
+
"bsv-didweb.min.js",
|
|
94
|
+
"bsv-vcjwt.min.js",
|
|
95
|
+
"bsv-statuslist.min.js",
|
|
96
|
+
"bsv-anchor.min.js",
|
|
84
97
|
"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
98
|
"docs/",
|
|
93
99
|
"demos/",
|
|
94
100
|
"examples/",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib/statuslist')
|
package/vcjwt-entry.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib/vcjwt')
|
package/demos/gdaf_core_test.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Simple GDAF Demo
|
|
3
|
-
*
|
|
4
|
-
* Tests core GDAF functionality without async verification issues
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const bsv = require('../index.js')
|
|
8
|
-
|
|
9
|
-
console.log('🌐 SmartLedger BSV GDAF - Core Components Test')
|
|
10
|
-
console.log('==============================================\n')
|
|
11
|
-
|
|
12
|
-
// Initialize GDAF
|
|
13
|
-
const gdaf = new bsv.GDAF()
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
// 1. Create test identities
|
|
17
|
-
console.log('🔑 Creating Test Identities')
|
|
18
|
-
const issuerPrivateKey = new bsv.PrivateKey()
|
|
19
|
-
const subjectPrivateKey = new bsv.PrivateKey()
|
|
20
|
-
|
|
21
|
-
const issuerDID = gdaf.createDID(issuerPrivateKey.toPublicKey())
|
|
22
|
-
const subjectDID = gdaf.createDID(subjectPrivateKey.toPublicKey())
|
|
23
|
-
|
|
24
|
-
console.log('✅ Issuer DID:', issuerDID)
|
|
25
|
-
console.log('✅ Subject DID:', subjectDID)
|
|
26
|
-
console.log()
|
|
27
|
-
|
|
28
|
-
// 2. Create credentials
|
|
29
|
-
console.log('📝 Creating Credentials')
|
|
30
|
-
|
|
31
|
-
const emailCredential = gdaf.createEmailCredential(
|
|
32
|
-
issuerDID,
|
|
33
|
-
subjectDID,
|
|
34
|
-
'user@example.com',
|
|
35
|
-
issuerPrivateKey
|
|
36
|
-
)
|
|
37
|
-
|
|
38
|
-
const ageCredential = gdaf.createAgeCredential(
|
|
39
|
-
issuerDID,
|
|
40
|
-
subjectDID,
|
|
41
|
-
21,
|
|
42
|
-
new Date('1995-06-15'),
|
|
43
|
-
issuerPrivateKey
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
console.log('✅ Email credential created with proof')
|
|
47
|
-
console.log('✅ Age credential created with proof')
|
|
48
|
-
console.log()
|
|
49
|
-
|
|
50
|
-
// 3. Schema validation
|
|
51
|
-
console.log('🔍 Schema Validation')
|
|
52
|
-
|
|
53
|
-
const emailValidation = gdaf.validateCredential(emailCredential, 'EmailVerifiedCredential')
|
|
54
|
-
const ageValidation = gdaf.validateCredential(ageCredential, 'AgeVerifiedCredential')
|
|
55
|
-
|
|
56
|
-
console.log('✅ Email validation:', emailValidation.valid ? 'PASSED' : 'FAILED')
|
|
57
|
-
console.log('✅ Age validation:', ageValidation.valid ? 'PASSED' : 'FAILED')
|
|
58
|
-
console.log()
|
|
59
|
-
|
|
60
|
-
// 4. Zero-knowledge proofs
|
|
61
|
-
console.log('🔒 Zero-Knowledge Proofs')
|
|
62
|
-
|
|
63
|
-
const nonce = gdaf.generateNonce()
|
|
64
|
-
|
|
65
|
-
// Selective disclosure proof
|
|
66
|
-
const selectiveProof = gdaf.generateSelectiveProof(
|
|
67
|
-
emailCredential,
|
|
68
|
-
['credentialSubject.verified'],
|
|
69
|
-
nonce
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
console.log('✅ Selective disclosure proof generated')
|
|
73
|
-
console.log(' - Proof type:', selectiveProof.type)
|
|
74
|
-
console.log(' - Disclosed fields:', selectiveProof.disclosedFields.length)
|
|
75
|
-
console.log(' - Merkle proofs:', selectiveProof.merkleProofs.length)
|
|
76
|
-
|
|
77
|
-
// Age proof
|
|
78
|
-
const ageProof = gdaf.generateAgeProof(ageCredential, 18, nonce)
|
|
79
|
-
|
|
80
|
-
console.log('✅ Age proof generated')
|
|
81
|
-
console.log(' - Minimum age:', ageProof.minimumAge)
|
|
82
|
-
console.log(' - Meets requirement:', ageProof.meetsRequirement)
|
|
83
|
-
|
|
84
|
-
// Verify age proof
|
|
85
|
-
const ageProofVerification = gdaf.verifyAgeProof(ageProof, 18, issuerDID)
|
|
86
|
-
console.log('✅ Age proof verification:', ageProofVerification ? 'PASSED' : 'FAILED')
|
|
87
|
-
console.log()
|
|
88
|
-
|
|
89
|
-
// 5. Available schemas
|
|
90
|
-
console.log('📚 Available Schema Types')
|
|
91
|
-
const allSchemas = gdaf.getAllSchemas()
|
|
92
|
-
const schemaNames = Object.keys(allSchemas)
|
|
93
|
-
|
|
94
|
-
console.log('✅ Schema count:', schemaNames.length)
|
|
95
|
-
console.log('✅ Available types:', schemaNames.join(', '))
|
|
96
|
-
console.log()
|
|
97
|
-
|
|
98
|
-
// 6. Template generation
|
|
99
|
-
console.log('📋 Template Generation')
|
|
100
|
-
|
|
101
|
-
const emailTemplate = gdaf.createTemplate('EmailVerifiedCredential')
|
|
102
|
-
const kycTemplate = gdaf.createTemplate('KYCVerifiedCredential')
|
|
103
|
-
|
|
104
|
-
console.log('✅ Email template generated')
|
|
105
|
-
console.log('✅ KYC template generated')
|
|
106
|
-
console.log()
|
|
107
|
-
|
|
108
|
-
// 7. Framework info
|
|
109
|
-
console.log('ℹ️ Framework Information')
|
|
110
|
-
const info = gdaf.getInfo()
|
|
111
|
-
console.log('✅ Name:', info.name)
|
|
112
|
-
console.log('✅ Version:', info.version)
|
|
113
|
-
console.log('✅ Standards:', info.standards.length, 'standards supported')
|
|
114
|
-
console.log('✅ Components:', Object.keys(info.components).length, 'components')
|
|
115
|
-
console.log()
|
|
116
|
-
|
|
117
|
-
console.log('🎉 GDAF Core Components Test: SUCCESS!')
|
|
118
|
-
console.log('\n✅ All tested components are working correctly:')
|
|
119
|
-
console.log(' ✓ DID Creation and Resolution')
|
|
120
|
-
console.log(' ✓ Credential Creation and Signing')
|
|
121
|
-
console.log(' ✓ Schema Validation')
|
|
122
|
-
console.log(' ✓ Zero-Knowledge Proof Generation')
|
|
123
|
-
console.log(' ✓ Age Proof Verification')
|
|
124
|
-
console.log(' ✓ Template Generation')
|
|
125
|
-
console.log(' ✓ Framework Information')
|
|
126
|
-
|
|
127
|
-
} catch (error) {
|
|
128
|
-
console.error('❌ GDAF Core Test failed:', error.message)
|
|
129
|
-
console.error('Stack trace:', error.stack)
|
|
130
|
-
process.exit(1)
|
|
131
|
-
}
|