UNPKG

@sphereon/ssi-sdk.ebsi-support

Version:

210 lines • 10.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EbsiDidProvider = void 0; const ssi_sdk_ext_did_utils_1 = require("@sphereon/ssi-sdk-ext.did-utils"); const ssi_sdk_ext_key_utils_1 = require("@sphereon/ssi-sdk-ext.key-utils"); const did_manager_1 = require("@veramo/did-manager"); const debug_1 = __importDefault(require("debug")); const functions_1 = require("./functions"); const types_1 = require("./types"); const debug = (0, debug_1.default)('sphereon:did-provider-ebsi'); class EbsiDidProvider extends did_manager_1.AbstractIdentifierProvider { constructor(options) { super(); this.defaultKms = options.defaultKms; this.apiOpts = options.apiOpts; } createIdentifier(args, context) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d; const { type, options, kms = this.defaultKms, alias } = args; const { notBefore, notAfter, secp256k1Key, secp256r1Key, keys, accessTokenOpts, executeLedgerOperation = !!((_a = args.options) === null || _a === void 0 ? void 0 : _a.accessTokenOpts), methodSpecificId = (0, functions_1.generateEbsiMethodSpecificId)(types_1.EBSI_DID_SPEC_INFOS.V1), baseDocument, services, } = Object.assign({}, options); if (executeLedgerOperation && !accessTokenOpts) { throw new Error('Access token options must be provided to execute ledger operation'); } const rpcId = (_b = options === null || options === void 0 ? void 0 : options.rpcId) !== null && _b !== void 0 ? _b : (0, functions_1.randomRpcId)(); if (type === types_1.EBSI_DID_SPEC_INFOS.KEY) { return Promise.reject(Error(`Type ${type} not supported. Please use @sphereon/ssi-sdk-ext.did-provider-key for Natural Person EBSI DIDs`)); } else if (!kms) { return Promise.reject(Error(`No KMS value provided`)); } else if (keys && keys.length > 0 && !executeLedgerOperation) { return Promise.reject(Error(`Cannot add additional keys if ledger operation is not enabled at creation. Please add the keys later yourself`)); } // CapabilityInvocation purpose const secp256k1ImportKey = yield (0, functions_1.ebsiGenerateOrUseKeyPair)({ keyOpts: secp256k1Key, keyType: 'Secp256k1', kms, controllerKey: true, }, context); const secp256k1ManagedKeyInfo = yield context.agent.keyManagerImport(secp256k1ImportKey); // Authentication, assertionMethod purpose const secp256r1ImportKey = yield (0, functions_1.ebsiGenerateOrUseKeyPair)({ keyOpts: secp256r1Key, keyType: 'Secp256r1', kms, }, context); const secp256r1ManagedKeyInfo = yield context.agent.keyManagerImport(secp256r1ImportKey); const identifier = { did: options.did && options.did.startsWith('did:ebsi:') ? options.did : `${types_1.EBSI_DID_SPEC_INFOS.V1.method}${methodSpecificId}`, controllerKeyId: secp256k1ManagedKeyInfo.kid, keys: [secp256k1ManagedKeyInfo, secp256r1ManagedKeyInfo], alias, services: services !== null && services !== void 0 ? services : [], provider: EbsiDidProvider.PROVIDER, }; const apiOpts = Object.assign({}, this.apiOpts); if (!apiOpts.environment) { apiOpts.environment = (_c = accessTokenOpts === null || accessTokenOpts === void 0 ? void 0 : accessTokenOpts.environment) !== null && _c !== void 0 ? _c : 'pilot'; } if (!apiOpts.version) { apiOpts.version = 'v5'; } if (executeLedgerOperation) { // This can only work if we enable global jwks hosting. DID JWK hosting will not work as the DID is not registered at this point yield (0, functions_1.ebsiCreateDidOnLedger)({ identifier, baseDocument, accessTokenOpts: accessTokenOpts, rpcId, notBefore, notAfter, }, context); if (keys && keys.length > 0) { for (const keyOpts of keys) { const key = yield (0, functions_1.ebsiGenerateOrUseKeyPair)({ keyOpts, keyType: (_d = keyOpts.type) !== null && _d !== void 0 ? _d : 'Secp256r1', kms, }, context); const managedKeyInfo = yield context.agent.keyManagerImport(key); console.warn(`FIXME: Anchor additional key on EBSI`, managedKeyInfo); } } } debug('Created', identifier.did); return identifier; }); } addKey(args, context) { return __awaiter(this, void 0, void 0, function* () { const { identifier, key, options } = args; const { accessToken, vmRelationships, apiOpts, rpcId = (0, functions_1.randomRpcId)() } = options; if (vmRelationships.length === 0) { return Promise.reject(Error(`No verification method relationship provided`)); } const controllerKey = (0, ssi_sdk_ext_did_utils_1.getControllerKey)({ identifier }); const from = (0, ssi_sdk_ext_did_utils_1.getEthereumAddressFromKey)({ key: controllerKey }); const kid = controllerKey.kid; const did = identifier.did; const addVerificationMethodRequest = { params: [ { from, did, isSecp256k1: true, vMethodId: (0, ssi_sdk_ext_key_utils_1.calculateJwkThumbprint)({ jwk: (0, ssi_sdk_ext_key_utils_1.toJwk)(key.publicKeyHex, key.type) }), publicKey: (0, functions_1.formatEbsiPublicKey)({ key: key, type: key.type }), }, ], rpcMethod: types_1.EbsiRpcMethod.ADD_VERIFICATION_METHOD, rpcId, apiOpts, accessToken, }; let rpcResponse = yield (0, functions_1.ebsiSignAndSendTransaction)({ rpcRequest: addVerificationMethodRequest, kid, accessToken: accessToken, apiOpts, }, context); const vMethodId = (0, ssi_sdk_ext_key_utils_1.calculateJwkThumbprintForKey)({ key }); for (const vmRelationshipsKey in vmRelationships) { const addVerificationMethodRelationshipRequest = { params: [ { from, did, vMethodId, name: vmRelationshipsKey, notAfter: Date.now() / 1000 - 60000, notBefore: Date.now() / 1000 + 5 * 365 * 24 * 60 * 60, }, ], rpcMethod: types_1.EbsiRpcMethod.ADD_VERIFICATION_RELATIONSHIP, rpcId, apiOpts, accessToken, }; rpcResponse = yield (0, functions_1.ebsiSignAndSendTransaction)({ rpcRequest: addVerificationMethodRelationshipRequest, previousTxResponse: rpcResponse, kid, accessToken, apiOpts, }, context); } }); } addService(args, context) { return __awaiter(this, void 0, void 0, function* () { const { identifier, service, options } = args; const { accessToken, apiOpts, rpcId = (0, functions_1.randomRpcId)() } = options; const controllerKey = (0, ssi_sdk_ext_did_utils_1.getControllerKey)({ identifier }); const from = (0, ssi_sdk_ext_did_utils_1.getEthereumAddressFromKey)({ key: controllerKey }); const did = identifier.did; const kid = controllerKey.kid; const addServiceRequest = { params: [ { from, did, service, }, ], rpcMethod: types_1.EbsiRpcMethod.ADD_SERVICE, rpcId, apiOpts, accessToken, }; return yield (0, functions_1.ebsiSignAndSendTransaction)({ rpcRequest: addServiceRequest, kid, accessToken, apiOpts, }, context); }); } deleteIdentifier(args, context) { return Promise.resolve(true); } removeKey(args, context) { throw new Error(`Not (yet) implemented for the EBSI did provider`); } removeService(args, context) { throw new Error(`Not (yet) implemented for the EBSI did provider`); } // TODO How does it work? Not inferable from the api: https://hub.ebsi.eu/apis/pilot/did-registry/v5/post-jsonrpc#updatebasedocument updateIdentifier(args, context) { return __awaiter(this, void 0, void 0, function* () { throw new Error(`Not (yet) implemented for the EBSI did provider`); }); } } exports.EbsiDidProvider = EbsiDidProvider; EbsiDidProvider.PROVIDER = 'did:ebsi'; //# sourceMappingURL=EbsiDidProvider.js.map