Commit 2d2e82c2 authored by Giuseppe Tropea's avatar Giuseppe Tropea
Browse files

sample code for ngsildproof

parent d84a514b
Loading
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
{
  "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
+104 −0
Original line number Original line Diff line number Diff line
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));

+395 −0
Original line number Original line Diff line number Diff line
{
  "@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
+41 −0
Original line number Original line Diff line number Diff line
{
    "@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