smartledger-bsv 3.3.5 → 3.4.0

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.
@@ -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.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.0",
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,11 +49,16 @@
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",
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/statuslist')
package/vcjwt-entry.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/vcjwt')