Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import jsigs from 'jsonld-signatures';
const {purposes: {AssertionProofPurpose}} = jsigs;
import * as Ed25519Multikey from '@digitalbazaar/ed25519-multikey';
import {DataIntegrityProof} from '@digitalbazaar/data-integrity';
import {cryptosuite as eddsaRdfc2022CryptoSuite} from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite';
import fetch from 'node-fetch';
// Create an in-memory map of documents keyed by their URLs
const documents = new Map();
// Define the addDocumentToLoader function
function addDocumentToLoader({url, document}) {
documents.set(url, {
documentUrl: url,
document,
contextUrl: null
});
}
// Define the documentLoader that uses this map
const documentLoader = async url => {
// If the document is known, return it
if (documents.has(url)) {
return {
contextUrl: null,
documentUrl: url,
document: documents.get(url).document
};
}
// Else, you may want to fallback to a default loader or throw an error
if (url.startsWith('https://www.w3.org/2018/credentials/v1')
|| url.startsWith('https://w3id.org/security/suites/ed25519-2020/v1')
|| url.startsWith('https://w3id.org/security/data-integrity/v2')
|| url.startsWith('https://forge.etsi.org/rep/cim/NGSI-LD/')
|| url.startsWith('https://uri.etsi.org/ngsi-ld')) {
return {
contextUrl: null, // this is for a context via a link header
document: await fetch(url).then(res => res.json()), // this is the actual document that was loaded
documentUrl: url // this is the actual context URL after redirects
};
}
// If no match is found, throw an error
throw new Error(`Document loader unable to load URL: ${url}`);
}
// create the JSON-LD document that should be signed
let ngsilddoc = {
"id": "urn:ngsi-ld:Store:002",
"type": "Store",
"address": {
"type": "Property",
"value": {
"streetAddress": ["Tiger Street 4", "al"],
"addressRegion": "Metropolis",
"addressLocality": "Cat City",
"postalCode": "42420"
}
},
"@context": "https://uri.etsi.org/ngsi-ld/primer/store-context.jsonld"
};
// create the keypair to use when signing
const controller = 'https://example.edu/issuers/565049';
const keyPair = await Ed25519Multikey.from({
'@context': 'https://w3id.org/security/multikey/v1',
type: 'Multikey',
controller,
id: controller + '#z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT',
publicKeyMultibase: 'z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT',
secretKeyMultibase: 'zrv3rbPamVDGvrm7LkYPLWYJ35P9audujKKsWn3x29EUiGwwhdZQd' +
'1iHhrsmZidtVALBQmhX3j9E5Fvx6Kr29DPt6LH'
});
// export public key and add to document loader
const publicKey = await keyPair.export({publicKey: true, includeContext: true});
addDocumentToLoader({url: publicKey.id, document: publicKey});
// create key's controller document
const controllerDoc = {
'@context': [
'https://www.w3.org/ns/did/v1',
'https://w3id.org/security/multikey/v1'
],
id: controller,
assertionMethod: [publicKey]
};
addDocumentToLoader({url: controllerDoc.id, document: controllerDoc});
// create suite
const suite = new DataIntegrityProof({
signer: keyPair.signer(), cryptosuite: eddsaRdfc2022CryptoSuite
});
// create signed credential
const signeddoc = await jsigs.sign(ngsilddoc, {
suite,
purpose: new AssertionProofPurpose(),
documentLoader
});
console.log(JSON.stringify(signeddoc));