Skip to content
Snippets Groups Projects
Commit 2d2e82c2 authored by Giuseppe Tropea's avatar Giuseppe Tropea
Browse files

sample code for ngsildproof

parent d84a514b
No related branches found
No related tags found
No related merge requests found
Pipeline #19740 passed
{
"id": "urn:ngsi-ld:Store:002",
"type": "Store",
"address": {
"type": "Property",
"value": {
"streetAddress": ["Tiger Street 4", "al"],
"addressRegion": "Metropolis",
"addressLocality": "Cat City",
"postalCode": "42420"
}
},
"location": {
"type": "GeoProperty",
"value": {
"type": "Point",
"coordinates": [57.5522, -20.3484]
}
},
"ngsildproof": {
"type": "Property",
"entityIdSealed": "urn:ngsi-ld:Store:002",
"entityTypeSealed": "Store",
"proof": {
"type": "DataIntegrityProof",
"created": "2024-12-09T16:37:48Z",
"verificationMethod": "https://example.edu/issuers/565049#z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z5bEiXJXYgCcEotho4K1i5bX8A8BUkQt2rRvLYSULM8P8nh4VQdkjSt9wm33p7PcPgJajBwsoiNarT9BTMXMPPTVr"
}
},
"@context": "https://roughly-cosmic-aardvark.ngrok-free.app/store-context.jsonld"
}
"ngsildproof": {
"type": "Property",
"entityIdSealed": "urn:ngsi-ld:Store:002",
"entityTypeSealed": "Store",
"proof": {
"type": "DataIntegrityProof",
"created": "2025-01-27T21:02:24Z",
"verificationMethod": "https://example.edu/issuers/565049#z6MkwXG2WjeQnNxSoynSGYU8V9j3QzP3JSqhdmkHc6SaVWoT",
"cryptosuite": "eddsa-rdfc-2022",
"proofPurpose": "assertionMethod",
"proofValue": "z3XrH3diVCqpVHXkE7WbnictqyQCkJBGTxHSqbCQvpXMw7o5UQqbNi67J15Q9tx7tvsNRTzmuoWU1Y2FyqGfSV9eS"
}
}
\ No newline at end of file
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));
{
"@context": {
"@version": 1.1,
"@protected": true,
"ngsi-ld": "https://uri.etsi.org/ngsi-ld/",
"geojson": "https://purl.org/geojson/vocab#",
"id": "@id",
"type": "@type",
"Attribute": "ngsi-ld:Attribute",
"AttributeList": "ngsi-ld:AttributeList",
"ContextSourceIdentity": "ngsi-ld:ContextSourceIdentity",
"ContextSourceNotification": "ngsi-ld:ContextSourceNotification",
"ContextSourceRegistration": "ngsi-ld:ContextSourceRegistration",
"Date": "ngsi-ld:Date",
"DateTime": "ngsi-ld:DateTime",
"EntityType": "ngsi-ld:EntityType",
"EntityTypeInfo": "ngsi-ld:EntityTypeInfo",
"EntityTypeList": "ngsi-ld:EntityTypeList",
"Feature": "geojson:Feature",
"FeatureCollection": "geojson:FeatureCollection",
"GeoProperty": "ngsi-ld:GeoProperty",
"GeometryCollection": "geojson:GeometryCollection",
"JsonProperty": "ngsi-ld:JsonProperty",
"LanguageProperty": "ngsi-ld:LanguageProperty",
"LineString": "geojson:LineString",
"ListProperty": "ngsi-ld:ListProperty",
"ListRelationship": "ngsi-ld:ListRelationship",
"MultiLineString": "geojson:MultiLineString",
"MultiPoint": "geojson:MultiPoint",
"MultiPolygon": "geojson:MultiPolygon",
"Notification": "ngsi-ld:Notification",
"Point": "geojson:Point",
"Polygon": "geojson:Polygon",
"Property": "ngsi-ld:Property",
"Relationship": "ngsi-ld:Relationship",
"Subscription": "ngsi-ld:Subscription",
"TemporalProperty": "ngsi-ld:TemporalProperty",
"Time": "ngsi-ld:Time",
"VocabProperty": "ngsi-ld:VocabProperty",
"accept": "ngsi-ld:accept",
"attributeCount": "attributeCount",
"attributeDetails": "attributeDetails",
"attributeList": {
"@id": "ngsi-ld:attributeList",
"@type": "@vocab"
},
"attributeName": {
"@id": "ngsi-ld:attributeName",
"@type": "@vocab"
},
"attributeNames": {
"@id": "ngsi-ld:attributeNames",
"@type": "@vocab"
},
"attributeTypes": {
"@id": "ngsi-ld:attributeTypes",
"@type": "@vocab"
},
"attributes": {
"@id": "ngsi-ld:attributes",
"@type": "@vocab"
},
"attrs": "ngsi-ld:attrs",
"avg": {
"@id": "ngsi-ld:avg",
"@container": "@list"
},
"bbox": {
"@container": "@list",
"@id": "geojson:bbox"
},
"cacheDuration": "ngsi-ld:cacheDuration",
"containedBy": "ngsi-ld:isContainedBy",
"contextSourceAlias": "ngsi-ld:contextSourceAlias",
"contextSourceExtras": {
"@id": "ngsi-ld:contextSourceExtras",
"@type": "@json"
},
"contextSourceInfo": "ngsi-ld:contextSourceInfo",
"contextSourceTimeAt": {
"@id": "ngsi-ld:contextSourceTimeAt",
"@type": "DateTime"
},
"contextSourceUptime": "ngsi-ld:contextSourceUptime",
"cooldown": "ngsi-ld:cooldown",
"coordinates": {
"@container": "@list",
"@id": "geojson:coordinates"
},
"createdAt": {
"@id": "ngsi-ld:createdAt",
"@type": "DateTime"
},
"csf": "ngsi-ld:csf",
"data": "ngsi-ld:data",
"dataset": {
"@id": "ngsi-ld:hasDataset",
"@container": "@index"
},
"datasetId": {
"@id": "ngsi-ld:datasetId",
"@type": "@id"
},
"deletedAt": {
"@id": "ngsi-ld:deletedAt",
"@type": "DateTime"
},
"description": "http://purl.org/dc/terms/description",
"detail": "ngsi-ld:detail",
"distinctCount": {
"@id": "ngsi-ld:distinctCount",
"@container": "@list"
},
"endAt": {
"@id": "ngsi-ld:endAt",
"@type": "DateTime"
},
"endTimeAt": {
"@id": "ngsi-ld:endTimeAt",
"@type": "DateTime"
},
"endpoint": "ngsi-ld:endpoint",
"entities": "ngsi-ld:entities",
"entity": "ngsi-ld:entity",
"entityCount": "ngsi-ld:entityCount",
"entityId": {
"@id": "ngsi-ld:entityId",
"@type": "@id"
},
"entityList": {
"@id": "ngsi-ld:entityList",
"@container": "@list"
},
"entityMap": "ngsi-ld:hasEntityMap",
"error": "ngsi-ld:error",
"errors": "ngsi-ld:errors",
"expandValues": "ngsi-ld:expandValues",
"expiresAt": {
"@id": "ngsi-ld:expiresAt",
"@type": "DateTime"
},
"features": {
"@container": "@set",
"@id": "geojson:features"
},
"format": "ngsi-ld:format",
"geoQ": "ngsi-ld:geoQ",
"geometry": "geojson:geometry",
"geometryProperty": "geojson:geometryProperty",
"geoproperty": "ngsi-ld:geoproperty",
"georel": "ngsi-ld:georel",
"idPattern": "ngsi-ld:idPattern",
"information": "ngsi-ld:information",
"instanceId": {
"@id": "ngsi-ld:instanceId",
"@type": "@id"
},
"isActive": "ngsi-ld:isActive",
"join": "ngsi-ld:join",
"joinLevel": "ngsi-ld:hasJoinLevel",
"json": {
"@id": "ngsi-ld:hasJSON",
"@type": "@json"
},
"jsonKeys": "ngsi-ld:jsonKeys",
"jsons": {
"@id": "ngsi-ld:jsons",
"@container": "@list"
},
"key": "ngsi-ld:hasKey",
"lang": "ngsi-ld:lang",
"languageMap": {
"@id": "ngsi-ld:hasLanguageMap",
"@container": "@language"
},
"languageMaps": {
"@id": "ngsi-ld:hasLanguageMaps",
"@container": "@list"
},
"lastFailure": {
"@id": "ngsi-ld:lastFailure",
"@type": "DateTime"
},
"lastNotification": {
"@id": "ngsi-ld:lastNotification",
"@type": "DateTime"
},
"lastSuccess": {
"@id": "ngsi-ld:lastSuccess",
"@type": "DateTime"
},
"linkedMaps": "ngsi-ld:linkedMaps",
"localOnly": "ngsi-ld:localOnly",
"location": "ngsi-ld:location",
"management": "ngsi-ld:management",
"managementInterval": "ngsi-ld:managementInterval",
"max": {
"@id": "ngsi-ld:max",
"@container": "@list"
},
"min": {
"@id": "ngsi-ld:min",
"@container": "@list"
},
"mode": "ngsi-ld:mode",
"modifiedAt": {
"@id": "ngsi-ld:modifiedAt",
"@type": "DateTime"
},
"ngsildproof": {
"@id": "ngsi-ld:ngsildproof",
"@context": [{
"entityIdSealed": "ngsi-ld:entityIdSealed",
"entityTypeSealed": {
"@id": "ngsi-ld:entityTypeSealed",
"@type": "@vocab"
}
},
"https://w3id.org/security/data-integrity/v2"
]
},
"notification": "ngsi-ld:notification",
"notificationTrigger": "ngsi-ld:notificationTrigger",
"notifiedAt": {
"@id": "ngsi-ld:notifiedAt",
"@type": "DateTime"
},
"notifierInfo": "ngsi-ld:notifierInfo",
"notUpdated": "ngsi-ld:notUpdated",
"object": {
"@id": "ngsi-ld:hasObject",
"@type": "@id"
},
"objectList": {
"@id": "ngsi-ld:hasObjectList",
"@container": "@list"
},
"objects": {
"@id": "ngsi-ld:hasObjects",
"@container": "@list"
},
"objectsLists": {
"@id": "ngsi-ld:hasObjectsLists",
"@container": "@list"
},
"objectType": {
"@id": "ngsi-ld:hasObjectType",
"@type": "@vocab"
},
"observationInterval": "ngsi-ld:observationInterval",
"observationSpace": "ngsi-ld:observationSpace",
"observedAt": {
"@id": "ngsi-ld:observedAt",
"@type": "DateTime"
},
"omit": "ngsi-ld:omit",
"operationSpace": "ngsi-ld:operationSpace",
"operations": "ngsi-ld:operations",
"pick": "ngsi-ld:pick",
"previousJson": {
"@id": "ngsi-ld:hasPreviousJson",
"@type": "@json"
},
"previousLanguageMap": {
"@id": "ngsi-ld:hasPreviousLanguageMap",
"@container": "@language"
},
"previousObject": {
"@id": "ngsi-ld:hasPreviousObject",
"@type": "@id"
},
"previousObjectList": {
"@id": "ngsi-ld:hasPreviousObjectList",
"@container": "@list"
},
"previousValue": "ngsi-ld:hasPreviousValue",
"previousValueList": {
"@id": "ngsi-ld:hasPreviousValueList",
"@container": "@list"
},
"previousVocab": {
"@id": "ngsi-ld:hasPreviousVocab",
"@type": "@vocab"
},
"properties": "geojson:properties",
"propertyNames": {
"@id": "ngsi-ld:propertyNames",
"@type": "@vocab"
},
"q": "ngsi-ld:q",
"reason": "ngsi-ld:reason",
"receiverInfo": "ngsi-ld:receiverInfo",
"refreshRate": "ngsi-ld:refreshRate",
"registrationId": "ngsi-ld:registrationId",
"registrationName": "ngsi-ld:registrationName",
"relationshipNames": {
"@id": "ngsi-ld:relationshipNames",
"@type": "@vocab"
},
"scope": "ngsi-ld:scope",
"scopeQ": "ngsi-ld:scopeQ",
"showChanges": "ngsi-ld:showChanges",
"startAt": {
"@id": "ngsi-ld:startAt",
"@type": "DateTime"
},
"status": "ngsi-ld:status",
"stddev": {
"@id": "ngsi-ld:stddev",
"@container": "@list"
},
"subscriptionId": {
"@id": "ngsi-ld:subscriptionId",
"@type": "@id"
},
"subscriptionName": "ngsi-ld:subscriptionName",
"success": {
"@id": "ngsi-ld:success",
"@type": "@id"
},
"sum": {
"@id": "ngsi-ld:sum",
"@container": "@list"
},
"sumsq": {
"@id": "ngsi-ld:sumsq",
"@container": "@list"
},
"sysAttrs": "ngsi-ld:sysAttrs",
"temporalQ": "ngsi-ld:temporalQ",
"tenant": {
"@id": "ngsi-ld:tenant",
"@type": "@id"
},
"throttling": "ngsi-ld:throttling",
"timeAt": {
"@id": "ngsi-ld:timeAt",
"@type": "DateTime"
},
"timeInterval": "ngsi-ld:timeInterval",
"timeout": "ngsi-ld:timeout",
"timeproperty": "ngsi-ld:timeproperty",
"timerel": "ngsi-ld:timerel",
"timesFailed": "ngsi-ld:timesFailed",
"timesSent": "ngsi-ld:timesSent",
"title": "http://purl.org/dc/terms/title",
"totalCount": {
"@id": "ngsi-ld:totalCount",
"@container": "@list"
},
"triggerReason": "ngsi-ld:triggerReason",
"typeList": {
"@id": "ngsi-ld:typeList",
"@type": "@vocab"
},
"typeName": {
"@id": "ngsi-ld:typeName",
"@type": "@vocab"
},
"typeNames": {
"@id": "ngsi-ld:typeNames",
"@type": "@vocab"
},
"unchanged": "ngsi-ld:unchanged",
"unitCode": "ngsi-ld:unitCode",
"updated": "ngsi-ld:updated",
"uri": "ngsi-ld:uri",
"value": "ngsi-ld:hasValue",
"valueList": {
"@id": "ngsi-ld:hasValueList",
"@container": "@list"
},
"valueLists": {
"@id": "ngsi-ld:hasValueLists",
"@container": "@list"
},
"values": {
"@id": "ngsi-ld:hasValues",
"@container": "@list"
},
"vocab": {
"@id": "ngsi-ld:hasVocab",
"@type": "@vocab"
},
"vocabs": {
"@id": "ngsi-ld:hasVocabs",
"@container": "@list"
},
"watchedAttributes": {
"@id": "ngsi-ld:watchedAttributes",
"@type": "@vocab"
},
"@vocab": "https://uri.etsi.org/ngsi-ld/default-context/"
}
}
\ No newline at end of file
{
"@context": [
{
"Customer": "https://uri.etsi.org/ngsi-ld/primer/Customer",
"InventoryItem": "https://uri.etsi.org/ngsi-ld/primer/InventoryItem",
"Product": "https://uri.etsi.org/ngsi-ld/primer/Product",
"Shelf": "https://uri.etsi.org/ngsi-ld/primer/Shelf",
"Store": "https://uri.etsi.org/ngsi-ld/primer/Store",
"Wine": "https://uri.etsi.org/ngsi-ld/primer/Wine",
"address": "https://uri.etsi.org/ngsi-ld/primer/address",
"addressLocality": "https://uri.etsi.org/ngsi-ld/primer/addressLocality",
"addressRegion": "https://uri.etsi.org/ngsi-ld/primer/addressRegion",
"brand": "https://uri.etsi.org/ngsi-ld/primer/brand",
"contains": "https://uri.etsi.org/ngsi-ld/primer/contains",
"customerName": "https://uri.etsi.org/ngsi-ld/primer/customerName",
"hasPurchased": "https://uri.etsi.org/ngsi-ld/primer/hasPurchased",
"hasPurchasedAt": "https://uri.etsi.org/ngsi-ld/primer/hasPurchasedAt",
"hasVisited": "https://uri.etsi.org/ngsi-ld/primer/hasVisited",
"holds": "https://uri.etsi.org/ngsi-ld/primer/holds",
"isContainedIn": "https://uri.etsi.org/ngsi-ld/primer/isContainedIn",
"isHeldIn": "https://uri.etsi.org/ngsi-ld/primer/isHeldIn",
"isInventoryOf": "https://uri.etsi.org/ngsi-ld/primer/isInventoryOf",
"isMeasuredBy": "https://uri.etsi.org/ngsi-ld/primer/isMeasuredBy",
"maxCapacity": "https://uri.etsi.org/ngsi-ld/primer/maxCapacity",
"minCapacity": "https://uri.etsi.org/ngsi-ld/primer/minCapacity",
"owner": "https://uri.etsi.org/ngsi-ld/primer/owner",
"postalCode": "https://uri.etsi.org/ngsi-ld/primer/postalCode",
"price": "https://uri.etsi.org/ngsi-ld/primer/price",
"productName": "https://uri.etsi.org/ngsi-ld/primer/productName",
"putBackOnShelf": "https://uri.etsi.org/ngsi-ld/primer/putBackOnShelf",
"quantity": "https://uri.etsi.org/ngsi-ld/primer/quantity",
"relatesTo": "https://uri.etsi.org/ngsi-ld/primer/relatesTo",
"shelfCount": "https://uri.etsi.org/ngsi-ld/primer/shelfCount",
"size": "https://uri.etsi.org/ngsi-ld/primer/size",
"stockCount": "https://uri.etsi.org/ngsi-ld/primer/stockCount",
"storeName": "https://uri.etsi.org/ngsi-ld/primer/storeName",
"streetAddress": "https://uri.etsi.org/ngsi-ld/primer/streetAddress"
},
"https://roughly-cosmic-aardvark.ngrok-free.app/ngsi-ld-core-context-v1.9.jsonld"
]
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment