UNPKG

@cheqd/sdk

Version:

A TypeScript SDK built with CosmJS to interact with the cheqd network ledger

404 lines 18.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultBackoffOptions = exports.createMsgUpdateDidDocPayloadToSign = exports.EnglishMnemonic = exports.TImportableEd25519Key = void 0; exports.isEqualKeyValuePair = isEqualKeyValuePair; exports.createSignInputsFromImportableEd25519Key = createSignInputsFromImportableEd25519Key; exports.createKeyPairRaw = createKeyPairRaw; exports.createKeyPairBase64 = createKeyPairBase64; exports.createKeyPairHex = createKeyPairHex; exports.createVerificationKeys = createVerificationKeys; exports.createDidVerificationMethod = createDidVerificationMethod; exports.createDidPayload = createDidPayload; exports.validateSpecCompliantPayload = validateSpecCompliantPayload; exports.createCosmosPayerWallet = createCosmosPayerWallet; exports.toMultibaseRaw = toMultibaseRaw; exports.createMsgCreateDidDocPayloadToSign = createMsgCreateDidDocPayloadToSign; exports.createMsgDeactivateDidDocPayloadToSign = createMsgDeactivateDidDocPayloadToSign; exports.createMsgResourcePayloadToSign = createMsgResourcePayloadToSign; exports.getCosmosAccount = getCosmosAccount; exports.checkBalance = checkBalance; exports.isJSON = isJSON; exports.retry = retry; exports.normalizeAuthentication = normalizeAuthentication; exports.normalizeController = normalizeController; exports.normalizeService = normalizeService; exports.denormalizeService = denormalizeService; const types_1 = require("./types"); const uint8arrays_cjs_1 = require("uint8arrays-cjs"); const basics_1 = require("multiformats-cjs/basics"); const did_jwt_cjs_1 = require("did-jwt-cjs"); const ed25519_cjs_1 = require("@stablelib/ed25519-cjs"); const proto_signing_cjs_1 = require("@cosmjs/proto-signing-cjs"); const crypto_cjs_1 = require("@cosmjs/crypto-cjs"); const amino_cjs_1 = require("@cosmjs/amino-cjs"); const secp256k1_cjs_1 = __importDefault(require("secp256k1-cjs")); const uuid_cjs_1 = require("uuid-cjs"); const v2_1 = require("@cheqd/ts-proto-cjs/cheqd/did/v2"); const did_1 = require("./modules/did"); const v2_2 = require("@cheqd/ts-proto-cjs/cheqd/resource/v2"); const encoding_cjs_1 = require("@cosmjs/encoding-cjs"); const stargate_cjs_1 = require("@cosmjs/stargate-cjs"); const exponential_backoff_cjs_1 = require("exponential-backoff-cjs"); exports.TImportableEd25519Key = { isValid(key) { return (typeof key === 'object' && key !== null && typeof key.publicKeyHex === 'string' && isHex(key.publicKeyHex) && typeof key.privateKeyHex === 'string' && isHex(key.privateKeyHex) && typeof key.kid === 'string' && key.type === 'Ed25519'); }, }; const MULTICODEC_ED25519_HEADER = new Uint8Array([0xed, 0x01]); function isEqualKeyValuePair(kv1, kv2) { return kv1.every((item, index) => item.key === kv2[index].key && item.value === kv2[index].value); } class EnglishMnemonic extends crypto_cjs_1.EnglishMnemonic { static _mnemonicMatcher = /^[a-z]+( [a-z]+)*$/; } exports.EnglishMnemonic = EnglishMnemonic; function createSignInputsFromImportableEd25519Key(key, verificationMethod) { if (!exports.TImportableEd25519Key.isValid(key)) throw new Error(`Key validation failed. Expected ${Object.values(exports.TImportableEd25519Key).join(', ')}`); const publicKey = (0, uint8arrays_cjs_1.fromString)(key.publicKeyHex, 'hex'); for (const method of verificationMethod) { switch (method.type) { case types_1.VerificationMethods.Ed255192020: const publicKeyMultibase = toMultibaseRaw(publicKey); if (method.publicKeyMultibase === publicKeyMultibase) { return { verificationMethodId: method.id, privateKeyHex: key.privateKeyHex, }; } case types_1.VerificationMethods.Ed255192018: const publicKeyBase58 = basics_1.bases['base58btc'].encode(publicKey).slice(1); if (method.publicKeyBase58 === publicKeyBase58) { return { verificationMethodId: method.id, privateKeyHex: key.privateKeyHex, }; } case types_1.VerificationMethods.JWK: const publicKeyJwk = { crv: 'Ed25519', kty: 'OKP', x: (0, uint8arrays_cjs_1.toString)(publicKey, 'base64url'), }; if (JSON.stringify(method.publicKeyJwk) === JSON.stringify(publicKeyJwk)) { return { verificationMethodId: method.id, privateKeyHex: key.privateKeyHex, }; } } throw new Error(`Unsupported verification method type: ${method.type}. Expected one of: ${Object.values(types_1.VerificationMethods).join(', ')}`); } throw new Error(`No verification method type provided. Expected one of: ${Object.values(types_1.VerificationMethods).join(', ')}`); } function createKeyPairRaw(seed) { return seed ? (0, ed25519_cjs_1.generateKeyPairFromSeed)((0, uint8arrays_cjs_1.fromString)(seed)) : (0, ed25519_cjs_1.generateKeyPair)(); } function createKeyPairBase64(seed) { const keyPair = seed ? (0, ed25519_cjs_1.generateKeyPairFromSeed)((0, uint8arrays_cjs_1.fromString)(seed)) : (0, ed25519_cjs_1.generateKeyPair)(); return { publicKey: (0, uint8arrays_cjs_1.toString)(keyPair.publicKey, 'base64'), privateKey: (0, uint8arrays_cjs_1.toString)(keyPair.secretKey, 'base64'), }; } function createKeyPairHex(seed) { const keyPair = createKeyPairRaw(seed); return { publicKey: (0, uint8arrays_cjs_1.toString)(keyPair.publicKey, 'hex'), privateKey: (0, uint8arrays_cjs_1.toString)(keyPair.secretKey, 'hex'), }; } function createVerificationKeys(publicKey, algo, keyFragment, network = types_1.CheqdNetwork.Testnet, methodSpecificId, didUrl) { if (isHex(publicKey)) { publicKey = (0, uint8arrays_cjs_1.toString)((0, uint8arrays_cjs_1.fromString)(publicKey, 'hex'), 'base64'); } else if (!isBase64(publicKey)) { throw new Error('publicKey validation failed. PublicKey should be in base64 or hex format'); } switch (algo) { case types_1.MethodSpecificIdAlgo.Base58: methodSpecificId ||= basics_1.bases['base58btc'].encode((0, did_jwt_cjs_1.base64ToBytes)(publicKey)); didUrl ||= `did:cheqd:${network}:${basics_1.bases['base58btc'] .encode((0, crypto_cjs_1.sha256)((0, did_jwt_cjs_1.base64ToBytes)(publicKey)).slice(0, 16)) .slice(1)}`; return { methodSpecificId, didUrl, keyId: `${didUrl}#${keyFragment}`, publicKey, }; case types_1.MethodSpecificIdAlgo.Uuid: methodSpecificId ||= (0, uuid_cjs_1.v4)(); didUrl ||= `did:cheqd:${network}:${methodSpecificId}`; return { methodSpecificId, didUrl, keyId: `${didUrl}#${keyFragment}`, publicKey, }; } } function createDidVerificationMethod(verificationMethodTypes, verificationKeys) { return (verificationMethodTypes.map((type, _) => { switch (type) { case types_1.VerificationMethods.Ed255192020: return { id: verificationKeys[_].keyId, type, controller: verificationKeys[_].didUrl, publicKeyMultibase: toMultibaseRaw((0, did_jwt_cjs_1.base64ToBytes)(verificationKeys[_].publicKey)), }; case types_1.VerificationMethods.Ed255192018: return { id: verificationKeys[_].keyId, type, controller: verificationKeys[_].didUrl, publicKeyBase58: basics_1.bases['base58btc'] .encode((0, did_jwt_cjs_1.base64ToBytes)(verificationKeys[_].publicKey)) .slice(1), }; case types_1.VerificationMethods.JWK: return { id: verificationKeys[_].keyId, type, controller: verificationKeys[_].didUrl, publicKeyJwk: { crv: 'Ed25519', kty: 'OKP', x: (0, uint8arrays_cjs_1.toString)((0, uint8arrays_cjs_1.fromString)(verificationKeys[_].publicKey, 'base64pad'), 'base64url'), }, }; } }) ?? []); } function createDidPayload(verificationMethods, verificationKeys, controller = []) { if (!verificationMethods || verificationMethods.length === 0) throw new Error('No verification methods provided'); if (!verificationKeys || verificationKeys.length === 0) throw new Error('No verification keys provided'); const did = verificationKeys[0].didUrl; return { id: did, controller: controller.length ? controller : Array.from(new Set(verificationKeys.map((key) => key.didUrl))), verificationMethod: verificationMethods, authentication: verificationKeys.map((key) => key.keyId), }; } function validateSpecCompliantPayload(didDocument) { // id is required, validated on both compile and runtime if (!didDocument?.id) return { valid: false, error: 'id is required' }; // verificationMethod is required if (!didDocument?.verificationMethod) return { valid: false, error: 'verificationMethod is required' }; // verificationMethod must be an array if (!Array.isArray(didDocument?.verificationMethod)) return { valid: false, error: 'verificationMethod must be an array' }; // verificationMethod types must be supported const protoVerificationMethod = didDocument.verificationMethod.map((vm) => { switch (vm?.type) { case types_1.VerificationMethods.Ed255192020: if (!vm.publicKeyMultibase) throw new Error('publicKeyMultibase is required'); return v2_1.VerificationMethod.fromPartial({ id: vm.id, controller: vm.controller, verificationMethodType: types_1.VerificationMethods.Ed255192020, verificationMaterial: vm.publicKeyMultibase, }); case types_1.VerificationMethods.JWK: if (!vm.publicKeyJwk) throw new Error('publicKeyJwk is required'); return v2_1.VerificationMethod.fromPartial({ id: vm.id, controller: vm.controller, verificationMethodType: types_1.VerificationMethods.JWK, verificationMaterial: JSON.stringify(vm.publicKeyJwk), }); case types_1.VerificationMethods.Ed255192018: if (!vm.publicKeyBase58) throw new Error('publicKeyBase58 is required'); return v2_1.VerificationMethod.fromPartial({ id: vm.id, controller: vm.controller, verificationMethodType: types_1.VerificationMethods.Ed255192018, verificationMaterial: vm.publicKeyBase58, }); default: throw new Error(`Unsupported verificationMethod type: ${vm?.type}`); } }); const protoService = normalizeService(didDocument); return { valid: true, protobufVerificationMethod: protoVerificationMethod, protobufService: protoService, }; } function createCosmosPayerWallet(cosmosPayerSeed) { return EnglishMnemonic._mnemonicMatcher.test(cosmosPayerSeed) ? proto_signing_cjs_1.DirectSecp256k1HdWallet.fromMnemonic(cosmosPayerSeed, { prefix: 'cheqd' }) : proto_signing_cjs_1.DirectSecp256k1Wallet.fromKey((0, uint8arrays_cjs_1.fromString)(cosmosPayerSeed.replace(/^0x/, ''), 'hex'), 'cheqd'); } function toMultibaseRaw(key) { const multibase = new Uint8Array(MULTICODEC_ED25519_HEADER.length + key.length); multibase.set(MULTICODEC_ED25519_HEADER); multibase.set(key, MULTICODEC_ED25519_HEADER.length); return basics_1.bases['base58btc'].encode(multibase); } async function createMsgCreateDidDocPayloadToSign(didPayload, versionId) { const { protobufVerificationMethod, protobufService } = await did_1.DIDModule.validateSpecCompliantPayload(didPayload); return v2_1.MsgCreateDidDocPayload.encode(v2_1.MsgCreateDidDocPayload.fromPartial({ context: didPayload?.['@context'], id: didPayload.id, controller: didPayload.controller, verificationMethod: protobufVerificationMethod, authentication: didPayload.authentication, assertionMethod: didPayload.assertionMethod, capabilityInvocation: didPayload.capabilityInvocation, capabilityDelegation: didPayload.capabilityDelegation, keyAgreement: didPayload.keyAgreement, service: protobufService, alsoKnownAs: didPayload.alsoKnownAs, versionId, })).finish(); } exports.createMsgUpdateDidDocPayloadToSign = createMsgCreateDidDocPayloadToSign; function createMsgDeactivateDidDocPayloadToSign(didPayload, versionId) { return v2_1.MsgDeactivateDidDocPayload.encode(v2_1.MsgDeactivateDidDocPayload.fromPartial({ id: didPayload.id, versionId, })).finish(); } function createMsgResourcePayloadToSign(payload) { return v2_2.MsgCreateResourcePayload.encode(v2_2.MsgCreateResourcePayload.fromPartial(payload)).finish(); } function getCosmosAccount(publicKeyHex) { const { publicKeyConvert } = secp256k1_cjs_1.default; return (0, encoding_cjs_1.toBech32)('cheqd', (0, amino_cjs_1.rawSecp256k1PubkeyToRawAddress)(publicKeyConvert((0, uint8arrays_cjs_1.fromString)(publicKeyHex, 'hex'), true))); } async function checkBalance(address, rpcAddress) { const client = await stargate_cjs_1.StargateClient.connect(rpcAddress); return await client.getAllBalances(address); } function isJSON(input) { if (typeof input !== 'string') return false; try { JSON.parse(input); return true; } catch (e) { return false; } } exports.DefaultBackoffOptions = { jitter: 'full', timeMultiple: 1, delayFirstAttempt: false, maxDelay: 100, startingDelay: 100, numOfAttempts: 3, }; async function retry(fn, options) { // set default options if (!options) { options = exports.DefaultBackoffOptions; } else { // overwrite defaults with user supplied options options = { ...exports.DefaultBackoffOptions, ...options }; } let result; try { result = await (0, exponential_backoff_cjs_1.backOff)(fn, options); } catch (e) { console.error(e); } return result; } function isBase64(str) { // Quick pattern check to filter obvious non-base64 strings const base64Pattern = /^[A-Za-z0-9+/]*={0,3}$/; if (!base64Pattern.test(str)) { return false; } try { return (0, uint8arrays_cjs_1.toString)((0, uint8arrays_cjs_1.fromString)(str, 'base64'), 'base64') === str; } catch (e) { return false; } } function isHex(str) { // Quick pattern check to filter obvious non-hex strings const hexPattern = /^[0-9a-fA-F]*$/; if (!hexPattern.test(str)) { return false; } try { return (0, uint8arrays_cjs_1.toString)((0, uint8arrays_cjs_1.fromString)(str, 'hex'), 'hex') === str; } catch { return false; } } function normalizeAuthentication(didDocument) { if (!didDocument.authentication) throw new Error('Invalid DID Document: Authentication section is required in DID Document'); const authArray = Array.isArray(didDocument.authentication) ? didDocument.authentication : [didDocument.authentication]; return authArray.map((a) => (typeof a === 'string' ? a : a.id)); } function normalizeController(didDocument) { if (!didDocument.controller) return [didDocument.id]; return Array.isArray(didDocument.controller) ? didDocument.controller : [didDocument.controller]; } function normalizeService(didDocument) { return didDocument.service?.map((s) => { return v2_1.Service.fromPartial({ id: s?.id, serviceType: s?.type, serviceEndpoint: s ? (Array.isArray(s.serviceEndpoint) ? s.serviceEndpoint : [s.serviceEndpoint]) : [], ...(s?.recipientKeys && { recipientKeys: s.recipientKeys }), ...(s?.routingKeys && { routingKeys: s.routingKeys }), ...(s?.accept && { accept: s.accept }), ...(s?.priority !== undefined && { priority: s.priority }), }); }); } function denormalizeService(didDocument) { return didDocument.service.map((s) => { if (s.serviceType === types_1.ServiceType.LinkedDomains) { const updatedContext = [...didDocument.context, did_1.contexts.LinkedDomainsContext]; didDocument = { ...didDocument, context: updatedContext }; } return { id: s.id, type: s.serviceType, serviceEndpoint: Array.isArray(s?.serviceEndpoint) ? s.serviceEndpoint.length === 1 ? s.serviceEndpoint[0] : s.serviceEndpoint : s?.serviceEndpoint, ...(s.recipientKeys && { recipientKeys: s.recipientKeys }), ...(s.routingKeys && { routingKeys: s.routingKeys }), ...(s.accept && { accept: s.accept }), ...(s.priority !== undefined && { priority: s.priority }), }; }); } //# sourceMappingURL=utils.js.map