@cheqd/sdk
Version:
A TypeScript SDK built with CosmJS to interact with the cheqd network ledger
404 lines • 18.1 kB
JavaScript
;
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