var antelope = require('@wharfkit/antelope'); var secp256k1 = require('@noble/curves/secp256k1'); var p256 = require('@noble/curves/p256'); var didJwt = require('did-jwt'); /** * Create a Antelope DID string * * @param account {NameType} the account name e.g. "myaccount" * @param chain {string} the chain name or chain id * @returns {string} the Antelope DID string * * @example createDid("myaccount", "telos") // returns "did:antelope:telos:myaccount" * @example createDid("myaccount", "eos:testnet:jungle") // returns "did:antelope:eos:testnet:jungle:myaccount" * @example createDid("myaccount", "2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a910746840") // returns "did:antelope:2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a910746840:myaccount" */ function createDid(account, chain) { return `did:antelope:${chain}:${account.toString()}`; } function createSigner(privateKey) { if (privateKey.type === antelope.KeyType.K1) { return didJwt.ES256KSigner(privateKey.data.array); } if (privateKey.type === antelope.KeyType.R1 || privateKey.type === antelope.KeyType.WA) { return didJwt.ES256Signer(privateKey.data.array); } throw new Error('Unsupported key type'); } function createIssuer(did, privateKey) { return { did, signer: createSigner(privateKey), alg: privateKey.type === antelope.KeyType.K1 ? 'ES256K' : 'ES256' }; } function toPublicKeyHex(publicKey) { return didJwt.bytesToHex(publicKey.data.array); } // Cannot import the following, so copying here // import { bigintToBytes } from '../node_modules/did-jwt/src/util'; function bigintToBytes(n, minLength) { return didJwt.hexToBytes(n.toString(16), minLength); } function createJWK(publicKey) { const { jwkCurve } = getCurveNamesFromType(publicKey); // copied from: // secp256k1 - https://github.com/decentralized-identity/did-jwt/pull/280/files#diff-c94d78b633b2fe38397047def271342090b3c8d81adf022a3a745af6d7b1c845R197 // P-256 - https://github.com/decentralized-identity/did-jwt/pull/280/files#diff-c94d78b633b2fe38397047def271342090b3c8d81adf022a3a745af6d7b1c845R57 const publicKeyPoint = toNobel(publicKey); return { crv: jwkCurve, kty: 'EC', x: didJwt.bytesToBase64url(bigintToBytes(publicKeyPoint.x)), y: didJwt.bytesToBase64url(bigintToBytes(publicKeyPoint.y)), kid: publicKey.toString() }; } function getCurveNamesFromType(key) { const type = key.type; switch (type) { case antelope.KeyType.K1: return { jwkCurve: 'secp256k1', verificationMethodType: 'EcdsaSecp256k1VerificationKey2019' }; case antelope.KeyType.R1: return { jwkCurve: 'P-256', verificationMethodType: 'JsonWebKey2020' }; case antelope.KeyType.WA: return { jwkCurve: 'P-256', verificationMethodType: 'JsonWebKey2020' }; default: throw new Error(`Unsupported key type: ${type}`); } } function toNobel(publicKey) { const { jwkCurve } = getCurveNamesFromType(publicKey); switch (jwkCurve) { case 'secp256k1': return secp256k1.secp256k1.ProjectivePoint.fromHex(publicKey.data.array); case 'P-256': return p256.p256.ProjectivePoint.fromHex(publicKey.data.array); default: throw new Error(`Unsupported curve: ${jwkCurve}`); } } var eos = { chainId: "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", service: [ { id: "https://eos.greymass.com", type: "LinkedDomains", serviceEndpoint: "https://eos.greymass.com" }, { id: "https://eos.dfuse.eosnation.io", type: "LinkedDomains", serviceEndpoint: "https://eos.dfuse.eosnation.io" } ] }; var telos = { chainId: "4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11", service: [ { id: "https://telos.greymass.com", type: "LinkedDomains", serviceEndpoint: "https://telos.greymass.com" } ] }; var europechain = { chainId: "f778f7d2f124b110e0a71245b310c1d0ac1a0edd21f131c5ecb2e2bc03e8fe2e", service: [ { id: "https://api.xec.cryptolions.io", type: "LinkedDomains", serviceEndpoint: "https://api.xec.cryptolions.io" } ] }; var pangea = { chainId: "66d565f72ac08f8321a3036e2d92eea7f96ddc90599bdbfc2d025d810c74c248", service: [ { id: "https://pangea.eosusa.io", type: "LinkedDomains", serviceEndpoint: "https://pangea.eosusa.io" } ] }; var antelopeChainRegistry = { eos: eos, "eos:testnet:jungle": { chainId: "2a02a0053e5a8cf73a56ba0fda11e4d92e0238a4a2aa74fccf46d5a910746840", service: [ { id: "https://jungle4.cryptolions.io", type: "LinkedDomains", serviceEndpoint: "https://jungle4.cryptolions.io" } ] }, telos: telos, europechain: europechain, pangea: pangea }; function getApi(options) { const provider = options.fetch ? new antelope.FetchProvider(options.url, { fetch: options.fetch }) : new antelope.FetchProvider(options.url); return new antelope.APIClient({ url: options.url, provider }); } const _iteratorSymbol = typeof Symbol !== "undefined" ? Symbol.iterator || (Symbol.iterator = Symbol("Symbol.iterator")) : "@@iterator"; function _settle(pact, state, value) { if (!pact.s) { if (value instanceof _Pact) { if (value.s) { if (state & 1) { state = value.s; } value = value.v; } else { value.o = _settle.bind(null, pact, state); return; } } if (value && value.then) { value.then(_settle.bind(null, pact, state), _settle.bind(null, pact, 2)); return; } pact.s = state; pact.v = value; const observer = pact.o; if (observer) { observer(pact); } } } const _Pact = /*#__PURE__*/function () { function _Pact() {} _Pact.prototype.then = function (onFulfilled, onRejected) { const result = new _Pact(); const state = this.s; if (state) { const callback = state & 1 ? onFulfilled : onRejected; if (callback) { try { _settle(result, 1, callback(this.v)); } catch (e) { _settle(result, 2, e); } return result; } else { return this; } } this.o = function (_this) { try { const value = _this.v; if (_this.s & 1) { _settle(result, 1, onFulfilled ? onFulfilled(value) : value); } else if (onRejected) { _settle(result, 1, onRejected(value)); } else { _settle(result, 2, value); } } catch (e) { _settle(result, 2, e); } }; return result; }; return _Pact; }(); function _isSettledPact(thenable) { return thenable instanceof _Pact && thenable.s & 1; } function _forTo(array, body, check) { var i = -1, pact, reject; function _cycle(result) { try { while (++i < array.length && (!check || !check())) { result = body(i); if (result && result.then) { if (_isSettledPact(result)) { result = result.v; } else { result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2))); return; } } } if (pact) { _settle(pact, 1, result); } else { pact = result; } } catch (e) { _settle(pact || (pact = new _Pact()), 2, e); } } _cycle(); return pact; } function _forOf(target, body, check) { if (typeof target[_iteratorSymbol] === "function") { var iterator = target[_iteratorSymbol](), step, pact, reject; function _cycle(result) { try { while (!(step = iterator.next()).done && (!check || !check())) { result = body(step.value); if (result && result.then) { if (_isSettledPact(result)) { result = result.v; } else { result.then(_cycle, reject || (reject = _settle.bind(null, pact = new _Pact(), 2))); return; } } } if (pact) { _settle(pact, 1, result); } else { pact = result; } } catch (e) { _settle(pact || (pact = new _Pact()), 2, e); } } _cycle(); if (iterator.return) { var _fixup = function (value) { try { if (!step.done) { iterator.return(); } } catch (e) {} return value; }; if (pact && pact.then) { return pact.then(_fixup, function (e) { throw _fixup(e); }); } _fixup(); } return pact; } // No support for Symbol.iterator if (!("length" in target)) { throw new TypeError("Object is not iterable"); } // Handle live collections properly var values = []; for (var i = 0; i < target.length; i++) { values.push(target[i]); } return _forTo(values, function (i) { return body(values[i]); }, check); } function _catch(body, recover) { try { var result = body(); } catch (e) { return recover(e); } if (result && result.then) { return result.then(void 0, recover); } return result; } const resolve = function (did, parsed, // @ts-ignore(TS6133 declared but never used) resolver, options) { try { const registry = { ...antelopeChainRegistry, ...options.antelopeChainRegistry }; let methodId = checkDID(parsed, registry); if (options.antelopeChainUrl) { const [chainId, subject] = parsed.id.split(':'); methodId = { chain: { chainId, service: [] }, subject }; } if (!methodId) { // invalid method-specific-id OR no matching chain in the registry return Promise.resolve(getResolutionError('invalidDid')); } return Promise.resolve(fetchAccount(methodId, did, parsed, options)).then(function (antelopeAccount) { if (!antelopeAccount) { return getResolutionError('notFound'); } const didDoc = createDIDDocument(methodId, parsed.did, antelopeAccount); return { didResolutionMetadata: { contentType: 'application/did+ld+json' }, didDocument: didDoc, didDocumentMetadata: {} }; }); } catch (e) { return Promise.reject(e); } }; const createRpcFetchAccount = function (methodId, options) { try { return Promise.resolve(_catch(function () { // @ts-expect-error AccountObject is not assignable to @wharfkit/antelope AccountObject return Promise.resolve(getApi(options).v1.chain.get_account(methodId.subject)); }, function (e) { if (e instanceof antelope.APIError && e.message.startsWith('Account Query Exception at /v1/chain/get_account')) { return null; } else { throw e; } })); } catch (e) { return Promise.reject(e); } }; const fetchAccount = function (methodId, _did, _parsed, options) { try { let _exit; function _temp3(_result) { let _exit2; if (_exit) return _result; const services = findServices(methodId.chain.service, serviceType); const _temp = _forOf(services, function (service) { return Promise.resolve(createRpcFetchAccount(methodId, { url: service.serviceEndpoint, fetch: options.fetch })).then(function (_await$createRpcFetch2) { _exit2 = 1; return _await$createRpcFetch2; }); }, function () { return _exit2; }); return _temp && _temp.then ? _temp.then(function (_result2) { return _exit2 ? _result2 : null; }) : _exit2 ? _temp : null; } const serviceType = 'LinkedDomains'; const _temp2 = function () { if (options.antelopeChainUrl) { return Promise.resolve(createRpcFetchAccount(methodId, { url: options.antelopeChainUrl, fetch: options.fetch })).then(function (_await$createRpcFetch) { _exit = 1; return _await$createRpcFetch; }); } }(); return Promise.resolve(_temp2 && _temp2.then ? _temp2.then(_temp3) : _temp3(_temp2)); } catch (e) { return Promise.reject(e); } }; const PATTERN_ACCOUNT_NAME = `([a-z1-5.]{0,12}[a-z1-5])`; const PATTERN_CHAIN_ID = `([A-Fa-f0-9]{64})`; const PATTERN_CHAIN_NAME = `(([a-z1-5.]{0,12}[a-z1-5])((:[a-z1-5.]{0,12}[a-z1-5])+)?)`; function toRegExp(pattern) { return new RegExp(`^${pattern}$`); } const REGEX_ACCOUNT_NAME = toRegExp(PATTERN_ACCOUNT_NAME); const REGEX_CHAIN_ID = toRegExp(PATTERN_CHAIN_ID); const REGEX_CHAIN_NAME = toRegExp(PATTERN_CHAIN_NAME); const REGEX_ID_AND_SUBJECT = toRegExp(`${PATTERN_CHAIN_ID}:${PATTERN_ACCOUNT_NAME}`); const REGEX_NAME_AND_SUBJECT = toRegExp(`${PATTERN_CHAIN_NAME}:${PATTERN_ACCOUNT_NAME}`); const CONDITIONAL_PROOF_2022 = 'ConditionalProof2022'; function getResolutionError(error) { return { didResolutionMetadata: { error }, didDocument: null, didDocumentMetadata: {} }; } function checkDID(parsed, registry) { // findChainByName const partsName = parsed.id.match(REGEX_NAME_AND_SUBJECT); if (partsName) { const entry = registry[partsName[1]]; if (entry) return { chain: entry, subject: partsName[partsName.length - 1] }; return undefined; } // findChainById const partsID = parsed.id.match(REGEX_ID_AND_SUBJECT); if (partsID) { for (const key of Object.keys(registry)) { const entry = registry[key]; if (entry.chainId === partsID[1]) return { chain: entry, subject: partsID[partsID.length - 1] }; } } return undefined; } function findServices(service, type) { return service.filter(s => Array.isArray(s.type) ? s.type.includes(type) : s.type === type); } function createKeyMethod(baseId, i, did, pubKey) { const { verificationMethodType } = getCurveNamesFromType(pubKey); return { id: baseId + '-' + i, controller: did, type: verificationMethodType, // NOTE: could also use `util.publicKeyHex(pubKey)` instead, but it is handy to have the kid property of the JWK for debugging publicKeyJwk: createJWK(pubKey) }; } function createAccountMethod(baseId, methodId, i, did, account) { const delegatedChain = baseId.slice(0, baseId.lastIndexOf(methodId.subject) - 1); const accountMethod = { id: baseId + '-' + i, controller: did, type: CONDITIONAL_PROOF_2022, conditionDelegated: delegatedChain + ':' + account.permission.actor + '#' + account.permission.permission }; return accountMethod; } function createDIDDocument(methodId, did, antelopeAccount) { const verificationMethod = []; for (const permission of antelopeAccount.permissions) { const baseId = did + '#' + permission.perm_name; permission.required_auth.accounts = permission.required_auth.accounts.filter(account => account.permission.permission.toString() !== 'eosio.code'); let method; if (permission.required_auth.keys.length === 1 && permission.required_auth.accounts.length === 0) { // @ts-expect-error PublicKey is not assignable to @wharfkit/antelope PublicKey method = createKeyMethod(baseId, 0, did, permission.required_auth.keys[0].key); method.id = baseId; } else { method = { id: baseId, controller: did, type: CONDITIONAL_PROOF_2022, threshold: permission.required_auth.threshold.toNumber(), conditionWeightedThreshold: [] }; if (permission.parent.toString() !== '') { method.relationshipParent = [did + '#' + permission.parent.toString()]; } let i = 0; for (const key of permission.required_auth.keys) { method.conditionWeightedThreshold.push({ // @ts-expect-error PublicKey is not assignable to @wharfkit/antelope PublicKey condition: createKeyMethod(baseId, i, did, key.key), weight: key.weight.toNumber() }); i++; } for (const account of permission.required_auth.accounts) { method.conditionWeightedThreshold.push({ condition: createAccountMethod(baseId, methodId, i, did, account), weight: account.weight.toNumber() }); i++; } } verificationMethod.push(method); } const doc = { '@context': ['https://www.w3.org/ns/did/v1', 'https://w3c-ccg.github.io/verifiable-conditions/contexts/verifiable-conditions-2021-v1.json'], id: did, verificationMethod, service: methodId.chain.service }; return doc; } function createResolver(options = {}) { return function (did, parsed, // @ts-ignore(TS6133 declared but never used) resolver, antelopeOptions) { return resolve(did, parsed, resolver, { ...antelopeOptions, ...options }); }; } function getResolver(options) { return { eosio: createResolver(options), antelope: createResolver(options) }; } exports.CONDITIONAL_PROOF_2022 = CONDITIONAL_PROOF_2022; exports.REGEX_ACCOUNT_NAME = REGEX_ACCOUNT_NAME; exports.REGEX_CHAIN_ID = REGEX_CHAIN_ID; exports.REGEX_CHAIN_NAME = REGEX_CHAIN_NAME; exports.antelopeChainRegistry = antelopeChainRegistry; exports.checkDID = checkDID; exports.createDIDDocument = createDIDDocument; exports.createDid = createDid; exports.createIssuer = createIssuer; exports.createJWK = createJWK; exports.createSigner = createSigner; exports.fetchAccount = fetchAccount; exports.getCurveNamesFromType = getCurveNamesFromType; exports.getResolver = getResolver; exports.toNobel = toNobel; exports.toPublicKeyHex = toPublicKeyHex; //# sourceMappingURL=index.cjs.map