smartledger-bsv 3.2.1 → 3.3.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 +147 -0
- package/README.md +289 -55
- package/architecture_demo.js +247 -0
- package/bsv-covenant.min.js +10 -0
- package/bsv-gdaf.min.js +37 -0
- package/bsv-ltp.min.js +37 -0
- package/bsv-script-helper.min.js +10 -0
- package/bsv-security.min.js +31 -0
- package/bsv-shamir.min.js +12 -0
- package/bsv-smartcontract.min.js +37 -0
- package/bsv.bundle.js +9 -9
- package/bsv.min.js +3 -3
- package/build/bsv-covenant.min.js +10 -0
- package/build/bsv-script-helper.min.js +10 -0
- package/build/bsv-security.min.js +31 -0
- package/build/bsv-smartcontract.min.js +39 -0
- package/build/bsv.bundle.js +39 -0
- package/build/bsv.min.js +39 -0
- package/build/webpack.bundle.config.js +22 -0
- package/build/webpack.config.js +18 -0
- package/build/webpack.covenant.config.js +27 -0
- package/build/webpack.gdaf.config.js +54 -0
- package/build/webpack.ltp.config.js +17 -0
- package/build/webpack.script-helper.config.js +27 -0
- package/build/webpack.security.config.js +23 -0
- package/build/webpack.smartcontract.config.js +25 -0
- package/build/webpack.subproject.config.js +6 -0
- package/bundle-entry.js +341 -0
- package/complete_ltp_demo.js +511 -0
- package/covenant-entry.js +44 -0
- package/docs/pushtx-key-insights.md +106 -0
- package/gdaf-entry.js +54 -0
- package/index.js +272 -5
- package/lib/crypto/shamir.js +360 -0
- package/lib/gdaf/attestation-signer.js +461 -0
- package/lib/gdaf/attestation-verifier.js +600 -0
- package/lib/gdaf/did-resolver.js +382 -0
- package/lib/gdaf/index.js +471 -0
- package/lib/gdaf/schema-validator.js +682 -0
- package/lib/gdaf/smartledger-anchor.js +486 -0
- package/lib/gdaf/zk-prover.js +507 -0
- package/lib/ltp/anchor.js +438 -0
- package/lib/ltp/claim.js +1026 -0
- package/lib/ltp/index.js +470 -0
- package/lib/ltp/obligation.js +945 -0
- package/lib/ltp/proof.js +828 -0
- package/lib/ltp/registry.js +702 -0
- package/lib/ltp/right.js +765 -0
- package/lib/smart_contract/API_REFERENCE.md +1 -1
- package/lib/smart_contract/EXAMPLES.md +2 -2
- package/lib/smart_contract/QUICK_START.md +2 -2
- package/lib/smart_contract/README.md +1 -1
- package/lib/smart_contract/index.js +4 -0
- package/ltp-entry.js +92 -0
- package/package.json +91 -20
- package/script-helper-entry.js +49 -0
- package/security-entry.js +70 -0
- package/shamir-entry.js +173 -0
- package/shamir_demo.js +121 -0
- package/simple_demo.js +204 -0
- package/smartcontract-entry.js +133 -0
- package/test_shamir.js +221 -0
- package/test_standalone_shamir.html +83 -0
- package/tests/bundle-completeness-test.html +131 -0
- package/tests/bundle-demo.html +476 -0
- package/tests/smartcontract-test.html +239 -0
- package/tests/standalone-modules-test.html +260 -0
- package/tests/test.html +612 -0
- package/tests/unpkg-demo.html +194 -0
- package/docs/nchain.md +0 -958
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
var bsv = require('../../')
|
|
4
|
+
var DIDResolver = require('./did-resolver')
|
|
5
|
+
var PrivateKey = bsv.PrivateKey
|
|
6
|
+
var Hash = bsv.crypto.Hash
|
|
7
|
+
var ECDSA = bsv.crypto.ECDSA
|
|
8
|
+
var Signature = bsv.crypto.Signature
|
|
9
|
+
var $ = bsv.util.preconditions
|
|
10
|
+
var _ = require('../util/_')
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* AttestationSigner
|
|
14
|
+
*
|
|
15
|
+
* Creates and signs W3C Verifiable Credentials using SmartLedger cryptographic
|
|
16
|
+
* primitives. Supports JSON-LD format with embedded proofs compatible with
|
|
17
|
+
* the Global Digital Attestation Framework (GDAF).
|
|
18
|
+
*
|
|
19
|
+
* Features:
|
|
20
|
+
* - W3C VC Data Model 2.0 compliance
|
|
21
|
+
* - Deterministic JSON serialization
|
|
22
|
+
* - ECDSA signature proofs
|
|
23
|
+
* - Multiple credential types
|
|
24
|
+
* - Issuer DID integration
|
|
25
|
+
* - Schema validation
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* AttestationSigner constructor
|
|
30
|
+
* @param {PrivateKey|String} privateKey - Signing private key
|
|
31
|
+
* @param {Object} options - Configuration options
|
|
32
|
+
*/
|
|
33
|
+
function AttestationSigner(privateKey, options) {
|
|
34
|
+
if (!(this instanceof AttestationSigner)) {
|
|
35
|
+
return new AttestationSigner(privateKey, options)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (typeof privateKey === 'string') {
|
|
39
|
+
privateKey = PrivateKey.fromWIF(privateKey)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$.checkArgument(privateKey instanceof PrivateKey, 'Invalid private key')
|
|
43
|
+
|
|
44
|
+
this.privateKey = privateKey
|
|
45
|
+
this.publicKey = privateKey.toPublicKey()
|
|
46
|
+
this.options = options || {}
|
|
47
|
+
this.did = DIDResolver.fromPrivateKey(privateKey, this.options)
|
|
48
|
+
|
|
49
|
+
return this
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Create canonical JSON string for signing
|
|
54
|
+
* @param {Object} obj - Object to canonicalize
|
|
55
|
+
* @returns {String} Canonical JSON string
|
|
56
|
+
*/
|
|
57
|
+
AttestationSigner._canonicalizeJSON = function(obj) {
|
|
58
|
+
// Use deterministic JSON serialization
|
|
59
|
+
return JSON.stringify(obj, Object.keys(obj).sort())
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Create hash of credential for signing
|
|
64
|
+
* @param {Object} credential - Credential object
|
|
65
|
+
* @returns {Buffer} SHA256 hash
|
|
66
|
+
*/
|
|
67
|
+
AttestationSigner._hashCredential = function(credential) {
|
|
68
|
+
var canonical = AttestationSigner._canonicalizeJSON(credential)
|
|
69
|
+
return Hash.sha256(Buffer.from(canonical, 'utf8'))
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create base credential structure
|
|
74
|
+
* @param {Object} credentialSubject - Subject data
|
|
75
|
+
* @param {Object} options - Additional options
|
|
76
|
+
* @returns {Object} Base credential
|
|
77
|
+
*/
|
|
78
|
+
AttestationSigner.prototype.createCredential = function(credentialSubject, options) {
|
|
79
|
+
options = options || {}
|
|
80
|
+
|
|
81
|
+
$.checkArgument(credentialSubject && typeof credentialSubject === 'object', 'Invalid credential subject')
|
|
82
|
+
|
|
83
|
+
var now = new Date().toISOString()
|
|
84
|
+
var credentialId = options.id || 'urn:uuid:' + this._generateUUID()
|
|
85
|
+
|
|
86
|
+
var credential = {
|
|
87
|
+
'@context': [
|
|
88
|
+
'https://www.w3.org/2018/credentials/v1'
|
|
89
|
+
],
|
|
90
|
+
id: credentialId,
|
|
91
|
+
type: ['VerifiableCredential'],
|
|
92
|
+
issuer: this.did,
|
|
93
|
+
issuanceDate: now,
|
|
94
|
+
credentialSubject: credentialSubject
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Add additional types
|
|
98
|
+
if (options.type) {
|
|
99
|
+
if (Array.isArray(options.type)) {
|
|
100
|
+
credential.type = credential.type.concat(options.type)
|
|
101
|
+
} else {
|
|
102
|
+
credential.type.push(options.type)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Add additional contexts
|
|
107
|
+
if (options.context) {
|
|
108
|
+
if (Array.isArray(options.context)) {
|
|
109
|
+
credential['@context'] = credential['@context'].concat(options.context)
|
|
110
|
+
} else {
|
|
111
|
+
credential['@context'].push(options.context)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Add expiration date
|
|
116
|
+
if (options.expirationDate) {
|
|
117
|
+
credential.expirationDate = options.expirationDate
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Add terms of use
|
|
121
|
+
if (options.termsOfUse) {
|
|
122
|
+
credential.termsOfUse = options.termsOfUse
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Add evidence
|
|
126
|
+
if (options.evidence) {
|
|
127
|
+
credential.evidence = options.evidence
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Add refresh service
|
|
131
|
+
if (options.refreshService) {
|
|
132
|
+
credential.refreshService = options.refreshService
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return credential
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Sign credential with ECDSA proof
|
|
140
|
+
* @param {Object} credential - Credential to sign
|
|
141
|
+
* @param {Object} options - Signing options
|
|
142
|
+
* @returns {Object} Signed credential
|
|
143
|
+
*/
|
|
144
|
+
AttestationSigner.prototype.signCredential = function(credential, options) {
|
|
145
|
+
options = options || {}
|
|
146
|
+
|
|
147
|
+
$.checkArgument(credential && typeof credential === 'object', 'Invalid credential')
|
|
148
|
+
|
|
149
|
+
// Create a copy to avoid mutating original
|
|
150
|
+
var credentialCopy = JSON.parse(JSON.stringify(credential))
|
|
151
|
+
|
|
152
|
+
// Remove any existing proof
|
|
153
|
+
delete credentialCopy.proof
|
|
154
|
+
|
|
155
|
+
// Create canonical hash
|
|
156
|
+
var credentialHash = AttestationSigner._hashCredential(credentialCopy)
|
|
157
|
+
|
|
158
|
+
// Sign the hash
|
|
159
|
+
var ecdsa = new ECDSA()
|
|
160
|
+
ecdsa.hashbuf = credentialHash
|
|
161
|
+
ecdsa.privkey = this.privateKey
|
|
162
|
+
ecdsa.pubkey = this.publicKey
|
|
163
|
+
|
|
164
|
+
ecdsa.sign()
|
|
165
|
+
var signature = ecdsa.sig
|
|
166
|
+
|
|
167
|
+
var jwsSignature = this._createJWSSignature(credentialHash, signature)
|
|
168
|
+
|
|
169
|
+
// Create proof object
|
|
170
|
+
var proof = {
|
|
171
|
+
type: 'EcdsaSecp256k1Signature2019',
|
|
172
|
+
created: new Date().toISOString(),
|
|
173
|
+
verificationMethod: this.did + '#keys-1',
|
|
174
|
+
proofPurpose: options.proofPurpose || 'assertionMethod',
|
|
175
|
+
jws: jwsSignature
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Add challenge if provided
|
|
179
|
+
if (options.challenge) {
|
|
180
|
+
proof.challenge = options.challenge
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Add domain if provided
|
|
184
|
+
if (options.domain) {
|
|
185
|
+
proof.domain = options.domain
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Add proof to credential
|
|
189
|
+
var signedCredential = JSON.parse(JSON.stringify(credentialCopy))
|
|
190
|
+
signedCredential.proof = proof
|
|
191
|
+
|
|
192
|
+
// Add root hash for ZK proofs
|
|
193
|
+
signedCredential.rootHash = credentialHash.toString('hex')
|
|
194
|
+
|
|
195
|
+
return signedCredential
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Create JWS-style signature
|
|
200
|
+
* @private
|
|
201
|
+
*/
|
|
202
|
+
AttestationSigner.prototype._createJWSSignature = function(hash, signature) {
|
|
203
|
+
// Create minimal JWS header for ECDSA
|
|
204
|
+
var header = {
|
|
205
|
+
alg: 'ES256K',
|
|
206
|
+
typ: 'JWT'
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
var headerB64 = Buffer.from(JSON.stringify(header)).toString('base64url')
|
|
210
|
+
var payloadB64 = hash.toString('base64url')
|
|
211
|
+
var signatureB64 = signature.toDER().toString('base64url')
|
|
212
|
+
|
|
213
|
+
return headerB64 + '..' + signatureB64 // Empty payload for detached signature
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Create Email Verified Credential
|
|
218
|
+
* @param {String} email - Email address
|
|
219
|
+
* @param {Object} options - Additional options
|
|
220
|
+
* @returns {Object} Signed credential
|
|
221
|
+
*/
|
|
222
|
+
AttestationSigner.prototype.createEmailCredential = function(email, options) {
|
|
223
|
+
options = options || {}
|
|
224
|
+
|
|
225
|
+
$.checkArgument(typeof email === 'string' && email.includes('@'), 'Invalid email address')
|
|
226
|
+
|
|
227
|
+
var credentialSubject = {
|
|
228
|
+
id: options.subjectId || 'did:smartledger:' + Hash.sha256(Buffer.from(email)).toString('hex'),
|
|
229
|
+
email: email,
|
|
230
|
+
verified: true,
|
|
231
|
+
verificationMethod: 'email_verification',
|
|
232
|
+
verificationTimestamp: new Date().toISOString()
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
var credentialOptions = {
|
|
236
|
+
type: 'EmailVerifiedCredential',
|
|
237
|
+
context: 'https://smartledger.technology/contexts/email/v1',
|
|
238
|
+
...options
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
var credential = this.createCredential(credentialSubject, credentialOptions)
|
|
242
|
+
return this.signCredential(credential, options)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Create Age Verification Credential
|
|
247
|
+
* @param {Number} age - Age to verify
|
|
248
|
+
* @param {Date} birthDate - Birth date (optional, for ZK proofs)
|
|
249
|
+
* @param {Object} options - Additional options
|
|
250
|
+
* @returns {Object} Signed credential
|
|
251
|
+
*/
|
|
252
|
+
AttestationSigner.prototype.createAgeCredential = function(age, birthDate, options) {
|
|
253
|
+
options = options || {}
|
|
254
|
+
|
|
255
|
+
$.checkArgument(typeof age === 'number' && age > 0, 'Invalid age')
|
|
256
|
+
|
|
257
|
+
var credentialSubject = {
|
|
258
|
+
id: options.subjectId || 'urn:uuid:' + this._generateUUID(),
|
|
259
|
+
ageOver: age,
|
|
260
|
+
verified: true,
|
|
261
|
+
verificationMethod: 'age_verification'
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Include birth date hash for ZK proofs if provided
|
|
265
|
+
if (birthDate) {
|
|
266
|
+
credentialSubject.birthDateHash = Hash.sha256(Buffer.from(birthDate.toISOString())).toString('hex')
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
var credentialOptions = {
|
|
270
|
+
type: 'AgeVerifiedCredential',
|
|
271
|
+
context: 'https://smartledger.technology/contexts/age/v1',
|
|
272
|
+
...options
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
var credential = this.createCredential(credentialSubject, credentialOptions)
|
|
276
|
+
return this.signCredential(credential, options)
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Create KYC Verified Credential
|
|
281
|
+
* @param {Object} kycData - KYC verification data
|
|
282
|
+
* @param {Object} options - Additional options
|
|
283
|
+
* @returns {Object} Signed credential
|
|
284
|
+
*/
|
|
285
|
+
AttestationSigner.prototype.createKYCCredential = function(kycData, options) {
|
|
286
|
+
options = options || {}
|
|
287
|
+
|
|
288
|
+
$.checkArgument(kycData && typeof kycData === 'object', 'Invalid KYC data')
|
|
289
|
+
|
|
290
|
+
var credentialSubject = {
|
|
291
|
+
id: options.subjectId || 'urn:uuid:' + this._generateUUID(),
|
|
292
|
+
kycLevel: kycData.level || 'basic',
|
|
293
|
+
verified: true,
|
|
294
|
+
verificationMethod: 'kyc_verification',
|
|
295
|
+
verificationTimestamp: new Date().toISOString(),
|
|
296
|
+
verifyingAuthority: kycData.authority || this.did
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Add hashed PII for privacy
|
|
300
|
+
if (kycData.firstName) {
|
|
301
|
+
credentialSubject.firstNameHash = Hash.sha256(Buffer.from(kycData.firstName)).toString('hex')
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
if (kycData.lastName) {
|
|
305
|
+
credentialSubject.lastNameHash = Hash.sha256(Buffer.from(kycData.lastName)).toString('hex')
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (kycData.ssn) {
|
|
309
|
+
credentialSubject.ssnHash = Hash.sha256(Buffer.from(kycData.ssn)).toString('hex')
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
var credentialOptions = {
|
|
313
|
+
type: 'KYCVerifiedCredential',
|
|
314
|
+
context: 'https://smartledger.technology/contexts/kyc/v1',
|
|
315
|
+
...options
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
var credential = this.createCredential(credentialSubject, credentialOptions)
|
|
319
|
+
return this.signCredential(credential, options)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Create Organization Credential
|
|
324
|
+
* @param {Object} orgData - Organization data
|
|
325
|
+
* @param {Object} options - Additional options
|
|
326
|
+
* @returns {Object} Signed credential
|
|
327
|
+
*/
|
|
328
|
+
AttestationSigner.prototype.createOrganizationCredential = function(orgData, options) {
|
|
329
|
+
options = options || {}
|
|
330
|
+
|
|
331
|
+
$.checkArgument(orgData && typeof orgData === 'object', 'Invalid organization data')
|
|
332
|
+
|
|
333
|
+
var credentialSubject = {
|
|
334
|
+
id: options.subjectId || 'did:smartledger:org:' + Hash.sha256(Buffer.from(orgData.name || '')).toString('hex'),
|
|
335
|
+
name: orgData.name,
|
|
336
|
+
type: orgData.type || 'Organization',
|
|
337
|
+
verified: true,
|
|
338
|
+
verificationMethod: 'organization_verification',
|
|
339
|
+
verificationTimestamp: new Date().toISOString()
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Add additional org fields
|
|
343
|
+
if (orgData.taxId) {
|
|
344
|
+
credentialSubject.taxIdHash = Hash.sha256(Buffer.from(orgData.taxId)).toString('hex')
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (orgData.incorporationState) {
|
|
348
|
+
credentialSubject.incorporationState = orgData.incorporationState
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (orgData.industry) {
|
|
352
|
+
credentialSubject.industry = orgData.industry
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
var credentialOptions = {
|
|
356
|
+
type: 'OrganizationCredential',
|
|
357
|
+
context: 'https://smartledger.technology/contexts/organization/v1',
|
|
358
|
+
...options
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
var credential = this.createCredential(credentialSubject, credentialOptions)
|
|
362
|
+
return this.signCredential(credential, options)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Generate UUID v4
|
|
367
|
+
* @private
|
|
368
|
+
*/
|
|
369
|
+
AttestationSigner.prototype._generateUUID = function() {
|
|
370
|
+
var random = bsv.crypto.Random.getRandomBuffer(16)
|
|
371
|
+
|
|
372
|
+
// Set version (4) and variant bits
|
|
373
|
+
random[6] = (random[6] & 0x0f) | 0x40
|
|
374
|
+
random[8] = (random[8] & 0x3f) | 0x80
|
|
375
|
+
|
|
376
|
+
var hex = random.toString('hex')
|
|
377
|
+
return [
|
|
378
|
+
hex.substring(0, 8),
|
|
379
|
+
hex.substring(8, 12),
|
|
380
|
+
hex.substring(12, 16),
|
|
381
|
+
hex.substring(16, 20),
|
|
382
|
+
hex.substring(20, 32)
|
|
383
|
+
].join('-')
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Create presentation of multiple credentials
|
|
388
|
+
* @param {Array} credentials - Array of signed credentials
|
|
389
|
+
* @param {Object} options - Presentation options
|
|
390
|
+
* @returns {Object} Signed presentation
|
|
391
|
+
*/
|
|
392
|
+
AttestationSigner.prototype.createPresentation = function(credentials, options) {
|
|
393
|
+
options = options || {}
|
|
394
|
+
|
|
395
|
+
$.checkArgument(Array.isArray(credentials), 'Credentials must be an array')
|
|
396
|
+
|
|
397
|
+
var presentation = {
|
|
398
|
+
'@context': [
|
|
399
|
+
'https://www.w3.org/2018/credentials/v1'
|
|
400
|
+
],
|
|
401
|
+
type: ['VerifiablePresentation'],
|
|
402
|
+
id: options.id || 'urn:uuid:' + this._generateUUID(),
|
|
403
|
+
holder: this.did,
|
|
404
|
+
verifiableCredential: credentials
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Add additional contexts
|
|
408
|
+
if (options.context) {
|
|
409
|
+
if (Array.isArray(options.context)) {
|
|
410
|
+
presentation['@context'] = presentation['@context'].concat(options.context)
|
|
411
|
+
} else {
|
|
412
|
+
presentation['@context'].push(options.context)
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// Sign the presentation
|
|
417
|
+
var presentationHash = AttestationSigner._hashCredential(presentation)
|
|
418
|
+
|
|
419
|
+
var ecdsa = new ECDSA()
|
|
420
|
+
ecdsa.hashbuf = presentationHash
|
|
421
|
+
ecdsa.privkey = this.privateKey
|
|
422
|
+
ecdsa.pubkey = this.publicKey
|
|
423
|
+
|
|
424
|
+
ecdsa.sign()
|
|
425
|
+
var signature = ecdsa.sig
|
|
426
|
+
var jwsSignature = this._createJWSSignature(presentationHash, signature)
|
|
427
|
+
|
|
428
|
+
var proof = {
|
|
429
|
+
type: 'EcdsaSecp256k1Signature2019',
|
|
430
|
+
created: new Date().toISOString(),
|
|
431
|
+
verificationMethod: this.did + '#keys-1',
|
|
432
|
+
proofPurpose: 'authentication',
|
|
433
|
+
jws: jwsSignature
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (options.challenge) {
|
|
437
|
+
proof.challenge = options.challenge
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (options.domain) {
|
|
441
|
+
proof.domain = options.domain
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
presentation.proof = proof
|
|
445
|
+
|
|
446
|
+
return presentation
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Get issuer information
|
|
451
|
+
* @returns {Object} Issuer information
|
|
452
|
+
*/
|
|
453
|
+
AttestationSigner.prototype.getIssuerInfo = function() {
|
|
454
|
+
return {
|
|
455
|
+
did: this.did,
|
|
456
|
+
publicKey: this.publicKey.toString('hex'),
|
|
457
|
+
verificationMethod: this.did + '#keys-1'
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
module.exports = AttestationSigner
|