@sphereon/ssi-sdk.ebsi-support
Version:
210 lines • 10.6 kB
JavaScript
;
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