diff --git a/packages/cheqd/jest.config.ts b/packages/cheqd/jest.config.ts new file mode 100644 index 0000000000..93c0197296 --- /dev/null +++ b/packages/cheqd/jest.config.ts @@ -0,0 +1,13 @@ +import type { Config } from '@jest/types' + +import base from '../../jest.config.base' + +import packageJson from './package.json' + +const config: Config.InitialOptions = { + ...base, + displayName: packageJson.name, + setupFilesAfterEnv: ['./tests/setup.ts'], +} + +export default config diff --git a/packages/cheqd/package.json b/packages/cheqd/package.json new file mode 100644 index 0000000000..65a5feee4c --- /dev/null +++ b/packages/cheqd/package.json @@ -0,0 +1,45 @@ +{ + "name": "@aries-framework/cheqd", + "main": "build/index", + "types": "build/index", + "version": "0.3.3", + "files": [ + "build" + ], + "license": "Apache-2.0", + "publishConfig": { + "access": "public" + }, + "homepage": "https://github.com/hyperledger/aries-framework-javascript/tree/main/packages/cheqd", + "repository": { + "type": "git", + "url": "https://github.com/hyperledger/aries-framework-javascript", + "directory": "packages/cheqd" + }, + "scripts": { + "build": "yarn run clean && yarn run compile", + "clean": "rimraf ./build", + "compile": "tsc -p tsconfig.build.json", + "prepublishOnly": "yarn run build", + "test": "jest" + }, + "dependencies": { + "@aries-framework/anoncreds": "0.3.3", + "@aries-framework/core": "0.3.3", + "@cheqd/sdk": "cjs", + "@cheqd/ts-proto": "cjs", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", + "rxjs": "^7.2.0", + "tsyringe": "^4.7.0", + "@cosmjs/proto-signing": "^0.29.5", + "@cosmjs/crypto": "^0.29.5", + "@stablelib/ed25519": "^1.0.3" + }, + "devDependencies": { + "rimraf": "^4.0.7", + "typescript": "~4.9.4", + "@aries-framework/indy-sdk": "*", + "@types/indy-sdk": "*" + } +} diff --git a/packages/cheqd/src/CheqdModule.ts b/packages/cheqd/src/CheqdModule.ts new file mode 100644 index 0000000000..a52968f83c --- /dev/null +++ b/packages/cheqd/src/CheqdModule.ts @@ -0,0 +1,26 @@ +import type { CheqdModuleConfigOptions } from './CheqdModuleConfig' +import type { AgentContext, DependencyManager, Module } from '@aries-framework/core' + +import { CheqdModuleConfig } from './CheqdModuleConfig' +import { CheqdLedgerService } from './ledger' + +export class CheqdModule implements Module { + public readonly config: CheqdModuleConfig + + public constructor(config: CheqdModuleConfigOptions) { + this.config = new CheqdModuleConfig(config) + } + + public register(dependencyManager: DependencyManager) { + // Register config + dependencyManager.registerInstance(CheqdModuleConfig, this.config) + + dependencyManager.registerSingleton(CheqdLedgerService) + } + + public async initialize(agentContext: AgentContext): Promise { + // not required + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + await cheqdLedgerService.connect() + } +} diff --git a/packages/cheqd/src/CheqdModuleConfig.ts b/packages/cheqd/src/CheqdModuleConfig.ts new file mode 100644 index 0000000000..3d0077883c --- /dev/null +++ b/packages/cheqd/src/CheqdModuleConfig.ts @@ -0,0 +1,25 @@ +/** + * CheqdModuleConfigOptions defines the interface for the options of the CheqdModuleConfig class. + */ +export interface CheqdModuleConfigOptions { + networks: NetworkConfig[] +} + +export interface NetworkConfig { + rpcUrl?: string + cosmosPayerSeed: string + network: string +} + +export class CheqdModuleConfig { + private options: CheqdModuleConfigOptions + + public constructor(options: CheqdModuleConfigOptions) { + this.options = options + } + + /** See {@link CheqdModuleConfigOptions.networks} */ + public get networks() { + return this.options.networks + } +} diff --git a/packages/cheqd/src/anoncreds/index.ts b/packages/cheqd/src/anoncreds/index.ts new file mode 100644 index 0000000000..6a8bd47548 --- /dev/null +++ b/packages/cheqd/src/anoncreds/index.ts @@ -0,0 +1 @@ +export { CheqdAnonCredsRegistry } from './services/CheqdAnonCredsRegistry' diff --git a/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts b/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts new file mode 100644 index 0000000000..4b3d5db18c --- /dev/null +++ b/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts @@ -0,0 +1,340 @@ +import type { CheqdCreateResourceOptions } from '../../dids' +import type { + AnonCredsRegistry, + GetCredentialDefinitionReturn, + GetRevocationStatusListReturn, + GetRevocationRegistryDefinitionReturn, + GetSchemaReturn, + RegisterCredentialDefinitionOptions, + RegisterCredentialDefinitionReturn, + RegisterSchemaReturn, + RegisterSchemaOptions, +} from '@aries-framework/anoncreds' +import type { AgentContext } from '@aries-framework/core' + +import { AriesFrameworkError, JsonTransformer, utils } from '@aries-framework/core' + +import { CheqdDidResolver, CheqdDidRegistrar } from '../../dids' +import { cheqdSdkAnonCredsRegistryIdentifierRegex, parseCheqdDid } from '../utils/identifiers' +import { + CheqdCredentialDefinition, + CheqdRevocationRegistryDefinition, + CheqdRevocationStatusList, + CheqdSchema, +} from '../utils/transform' + +export class CheqdAnonCredsRegistry implements AnonCredsRegistry { + public methodName = 'cheqd' + + /** + * This class supports resolving and registering objects with cheqd identifiers. + * It needs to include support for the schema, credential definition, revocation registry as well + * as the issuer id (which is needed when registering objects). + */ + public readonly supportedIdentifier = cheqdSdkAnonCredsRegistryIdentifierRegex + + public async getSchema(agentContext: AgentContext, schemaId: string): Promise { + try { + const cheqdDidResolver = agentContext.dependencyManager.resolve(CheqdDidResolver) + const parsedDid = parseCheqdDid(schemaId) + if (!parsedDid) { + throw new Error(`Invalid schemaId: ${schemaId}`) + } + + agentContext.config.logger.trace(`Submitting get schema request for schema '${schemaId}' to ledger`) + + const response = await cheqdDidResolver.resolveResource(agentContext, schemaId) + const schema = JsonTransformer.fromJSON(response.resource, CheqdSchema) + + return { + schema: { + attrNames: schema.attrNames, + name: schema.name, + version: schema.version, + issuerId: parsedDid.did, + }, + schemaId, + resolutionMetadata: {}, + schemaMetadata: {}, + } + } catch (error) { + agentContext.config.logger.error(`Error retrieving schema '${schemaId}'`, { + error, + schemaId, + }) + + return { + schemaId, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve schema: ${error.message}`, + }, + schemaMetadata: {}, + } + } + } + + public async registerSchema( + agentContext: AgentContext, + options: RegisterSchemaOptions + ): Promise { + try { + const cheqdDidRegistrar = agentContext.dependencyManager.resolve(CheqdDidRegistrar) + + const schema = options.schema + const schemaResource = { + id: utils.uuid(), + name: `${schema.name}-Schema`, + resourceType: 'anonCredsSchema', + data: { + name: schema.name, + version: schema.version, + attrNames: schema.attrNames, + }, + version: schema.version, + } satisfies CheqdCreateResourceOptions + + const response = await cheqdDidRegistrar.createResource(agentContext, schema.issuerId, schemaResource) + if (response.resourceState.state !== 'finished') { + throw new Error(response.resourceState.reason) + } + + return { + schemaState: { + state: 'finished', + schema, + schemaId: `${schema.issuerId}/resources/${schemaResource.id}`, + }, + registrationMetadata: {}, + schemaMetadata: {}, + } + } catch (error) { + agentContext.config.logger.debug(`Error registering schema for did '${options.schema.issuerId}'`, { + error, + did: options.schema.issuerId, + schema: options, + }) + + return { + schemaMetadata: {}, + registrationMetadata: {}, + schemaState: { + state: 'failed', + schema: options.schema, + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async registerCredentialDefinition( + agentContext: AgentContext, + options: RegisterCredentialDefinitionOptions + ): Promise { + try { + const cheqdDidRegistrar = agentContext.dependencyManager.resolve(CheqdDidRegistrar) + const { credentialDefinition } = options + const schema = await this.getSchema(agentContext, credentialDefinition.schemaId) + const credDefResource = { + id: utils.uuid(), + name: `${schema.schema?.name}-${credentialDefinition.tag}-CredDef`, + resourceType: 'anonCredsCredDef', + data: { + type: credentialDefinition.type, + tag: credentialDefinition.tag, + value: credentialDefinition.value, + schemaId: credentialDefinition.schemaId, + }, + version: utils.uuid(), + } satisfies CheqdCreateResourceOptions + + const response = await cheqdDidRegistrar.createResource( + agentContext, + credentialDefinition.issuerId, + credDefResource + ) + if (response.resourceState.state !== 'finished') { + throw new Error(response.resourceState.reason) + } + + return { + credentialDefinitionState: { + state: 'finished', + credentialDefinition, + credentialDefinitionId: `${credentialDefinition.issuerId}/resources/${credDefResource.id}`, + }, + registrationMetadata: {}, + credentialDefinitionMetadata: {}, + } + } catch (error) { + agentContext.config.logger.error( + `Error registering credential definition for did '${options.credentialDefinition.issuerId}'`, + { + error, + did: options.credentialDefinition.issuerId, + schema: options, + } + ) + + return { + credentialDefinitionMetadata: {}, + registrationMetadata: {}, + credentialDefinitionState: { + state: 'failed', + credentialDefinition: options.credentialDefinition, + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async getCredentialDefinition( + agentContext: AgentContext, + credentialDefinitionId: string + ): Promise { + try { + const cheqdDidResolver = agentContext.dependencyManager.resolve(CheqdDidResolver) + const parsedDid = parseCheqdDid(credentialDefinitionId) + if (!parsedDid) { + throw new Error(`Invalid credentialDefinitionId: ${credentialDefinitionId}`) + } + + agentContext.config.logger.trace( + `Submitting get credential definition request for '${credentialDefinitionId}' to ledger` + ) + + const response = await cheqdDidResolver.resolveResource(agentContext, credentialDefinitionId) + const credentialDefinition = JsonTransformer.fromJSON(response.resource, CheqdCredentialDefinition) + return { + credentialDefinition: { + ...credentialDefinition, + issuerId: parsedDid.did, + }, + credentialDefinitionId, + resolutionMetadata: {}, + credentialDefinitionMetadata: (response.resourceMetadata ?? {}) as Record, + } + } catch (error) { + agentContext.config.logger.error(`Error retrieving credential definition '${credentialDefinitionId}'`, { + error, + credentialDefinitionId, + }) + + return { + credentialDefinitionId, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve credential definition: ${error.message}`, + }, + credentialDefinitionMetadata: {}, + } + } + } + + public async getRevocationRegistryDefinition( + agentContext: AgentContext, + revocationRegistryDefinitionId: string + ): Promise { + try { + const cheqdDidResolver = agentContext.dependencyManager.resolve(CheqdDidResolver) + const parsedDid = parseCheqdDid(revocationRegistryDefinitionId) + if (!parsedDid) { + throw new Error(`Invalid revocationRegistryDefinitionId: ${revocationRegistryDefinitionId}`) + } + + agentContext.config.logger.trace( + `Submitting get revocation registry definition request for '${revocationRegistryDefinitionId}' to ledger` + ) + + const response = await cheqdDidResolver.resolveResource( + agentContext, + `${revocationRegistryDefinitionId}&resourceType=anonCredsRevocRegDef` + ) + const revocationRegistryDefinition = JsonTransformer.fromJSON( + response.resource, + CheqdRevocationRegistryDefinition + ) + return { + revocationRegistryDefinition: { + ...revocationRegistryDefinition, + issuerId: parsedDid.did, + }, + revocationRegistryDefinitionId, + resolutionMetadata: {}, + revocationRegistryDefinitionMetadata: (response.resourceMetadata ?? {}) as Record, + } + } catch (error) { + agentContext.config.logger.error( + `Error retrieving revocation registry definition '${revocationRegistryDefinitionId}'`, + { + error, + revocationRegistryDefinitionId, + } + ) + + return { + revocationRegistryDefinitionId, + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve revocation registry definition: ${error.message}`, + }, + revocationRegistryDefinitionMetadata: {}, + } + } + } + + // FIXME: this method doesn't retrieve the revocation status list at a specified time, it just resolves the revocation registry definition + public async getRevocationStatusList( + agentContext: AgentContext, + revocationRegistryId: string, + timestamp: number + ): Promise { + try { + const cheqdDidResolver = agentContext.dependencyManager.resolve(CheqdDidResolver) + const parsedDid = parseCheqdDid(revocationRegistryId) + if (!parsedDid) { + throw new Error(`Invalid revocationRegistryId: ${revocationRegistryId}`) + } + + agentContext.config.logger.trace( + `Submitting get revocation status request for '${revocationRegistryId}' to ledger` + ) + + const response = await cheqdDidResolver.resolveResource( + agentContext, + `${revocationRegistryId}&resourceType=anonCredsStatusList&resourceVersionTime=${timestamp}` + ) + const revocationStatusList = JsonTransformer.fromJSON(response.resource, CheqdRevocationStatusList) + + const statusListTimestamp = response.resourceMetadata?.created?.getUTCSeconds() + if (!statusListTimestamp) { + throw new AriesFrameworkError( + `Unable to extract revocation status list timestamp from resource ${revocationRegistryId}` + ) + } + + return { + revocationStatusList: { + ...revocationStatusList, + issuerId: parsedDid.did, + timestamp: statusListTimestamp, + }, + resolutionMetadata: {}, + revocationStatusListMetadata: (response.resourceMetadata ?? {}) as Record, + } + } catch (error) { + agentContext.config.logger.error(`Error retrieving revocation registry status list '${revocationRegistryId}'`, { + error, + revocationRegistryId, + }) + + return { + resolutionMetadata: { + error: 'notFound', + message: `unable to resolve revocation registry status list: ${error.message}`, + }, + revocationStatusListMetadata: {}, + } + } + } +} diff --git a/packages/cheqd/src/anoncreds/utils/identifiers.ts b/packages/cheqd/src/anoncreds/utils/identifiers.ts new file mode 100644 index 0000000000..ff21b32065 --- /dev/null +++ b/packages/cheqd/src/anoncreds/utils/identifiers.ts @@ -0,0 +1,59 @@ +import type { ParsedDid } from '@aries-framework/core' + +import { TypedArrayEncoder, utils } from '@aries-framework/core' +import { isBase58 } from 'class-validator' + +const ID_CHAR = '([a-z,A-Z,0-9,-])' +const NETWORK = '(testnet|mainnet)' +const IDENTIFIER = `((?:${ID_CHAR}*:)*(${ID_CHAR}+))` +const PATH = `(/[^#?]*)?` +const QUERY = `([?][^#]*)?` +const VERSION_ID = `(.*?)` + +export const cheqdSdkAnonCredsRegistryIdentifierRegex = new RegExp( + `^did:cheqd:${NETWORK}:${IDENTIFIER}${PATH}${QUERY}$` +) + +export const cheqdDidRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}${QUERY}$`) +export const cheqdDidVersionRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/version/${VERSION_ID}${QUERY}$`) +export const cheqdDidVersionsRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/versions${QUERY}$`) +export const cheqdDidMetadataRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/metadata${QUERY}$`) +export const cheqdResourceRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}${QUERY}$`) +export const cheqdResourceMetadataRegex = new RegExp( + `^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}/metadata${QUERY}` +) + +export type ParsedCheqdDid = ParsedDid & { network: string } +export function parseCheqdDid(didUrl: string): ParsedCheqdDid | null { + if (didUrl === '' || !didUrl) return null + const sections = didUrl.match(cheqdSdkAnonCredsRegistryIdentifierRegex) + if (sections) { + if ( + !( + utils.isValidUuid(sections[2]) || + (isBase58(sections[2]) && TypedArrayEncoder.fromBase58(sections[2]).length == 16) + ) + ) { + return null + } + const parts: ParsedCheqdDid = { + did: `did:cheqd:${sections[1]}:${sections[2]}`, + method: 'cheqd', + network: sections[1], + id: sections[2], + didUrl, + } + if (sections[7]) { + const params = sections[7].slice(1).split('&') + parts.params = {} + for (const p of params) { + const kv = p.split('=') + parts.params[kv[0]] = kv[1] + } + } + if (sections[6]) parts.path = sections[6] + if (sections[8]) parts.fragment = sections[8].slice(1) + return parts + } + return null +} diff --git a/packages/cheqd/src/anoncreds/utils/transform.ts b/packages/cheqd/src/anoncreds/utils/transform.ts new file mode 100644 index 0000000000..47c7b076a7 --- /dev/null +++ b/packages/cheqd/src/anoncreds/utils/transform.ts @@ -0,0 +1,149 @@ +// These functions will throw an error if the JSON doesn't +// match the expected interface, even if the JSON is valid. + +import type { + AnonCredsCredentialDefinition, + AnonCredsRevocationRegistryDefinition, + AnonCredsRevocationStatusList, + AnonCredsSchema, +} from '@aries-framework/anoncreds' + +import { Type } from 'class-transformer' +import { + ArrayMinSize, + Contains, + IsArray, + IsInstance, + IsNumber, + IsObject, + IsOptional, + IsString, + ValidateNested, +} from 'class-validator' + +export class CheqdSchema { + public constructor(options: Omit) { + if (options) { + this.name = options.name + this.attrNames = options.attrNames + this.version = options.version + } + } + + @IsString() + public name!: string + + @IsArray() + @IsString({ each: true }) + @ArrayMinSize(1) + public attrNames!: string[] + + @IsString() + public version!: string +} + +export class CheqdCredentialDefinitionValue { + @IsObject() + public primary!: Record + + @IsObject() + @IsOptional() + public revocation?: unknown +} + +export class CheqdCredentialDefinition { + public constructor(options: Omit) { + if (options) { + this.schemaId = options.schemaId + this.type = options.type + this.tag = options.tag + this.value = options.value + } + } + + @IsString() + public schemaId!: string + + @Contains('CL') + public type!: 'CL' + + @IsString() + public tag!: string + + @ValidateNested() + @IsInstance(CheqdCredentialDefinitionValue) + @Type(() => CheqdCredentialDefinitionValue) + public value!: CheqdCredentialDefinitionValue +} + +export class AccumKey { + @IsString() + public z!: string +} + +export class PublicKeys { + @ValidateNested() + @IsInstance(AccumKey) + @Type(() => AccumKey) + public accumKey!: AccumKey +} + +export class CheqdRevocationRegistryDefinitionValue { + @ValidateNested() + @IsInstance(PublicKeys) + @Type(() => PublicKeys) + public publicKeys!: PublicKeys + + @IsNumber() + public maxCredNum!: number + + @IsString() + public tailsLocation!: string + + @IsString() + public tailsHash!: string +} + +export class CheqdRevocationRegistryDefinition { + public constructor(options: Omit) { + if (options) { + this.revocDefType = options.revocDefType + this.credDefId = options.credDefId + this.tag = options.tag + this.value = options.value + } + } + + @Contains('CL_ACCUM') + public revocDefType!: 'CL_ACCUM' + + @IsString() + public credDefId!: string + + @IsString() + public tag!: string + + @ValidateNested() + @IsInstance(CheqdRevocationRegistryDefinitionValue) + @Type(() => CheqdRevocationRegistryDefinitionValue) + public value!: CheqdRevocationRegistryDefinitionValue +} + +export class CheqdRevocationStatusList { + public constructor(options: Omit) { + if (options) { + this.revRegDefId = options.revRegDefId + this.revocationList = options.revocationList + this.currentAccumulator = options.currentAccumulator + } + } + + @IsString() + public revRegDefId!: string + + @IsNumber({}, { each: true }) + public revocationList!: number[] + + @IsString() + public currentAccumulator!: string +} diff --git a/packages/cheqd/src/dids/CheqdDidRegistrar.ts b/packages/cheqd/src/dids/CheqdDidRegistrar.ts new file mode 100644 index 0000000000..37de51ad1f --- /dev/null +++ b/packages/cheqd/src/dids/CheqdDidRegistrar.ts @@ -0,0 +1,406 @@ +import type { + AgentContext, + DidRegistrar, + DidCreateOptions, + DidCreateResult, + DidDeactivateResult, + DidUpdateResult, + DidDocument, + VerificationMethod, +} from '@aries-framework/core' +import type { CheqdNetwork, DIDDocument, DidStdFee, TVerificationKey, VerificationMethods } from '@cheqd/sdk' +import type { SignInfo } from '@cheqd/ts-proto/cheqd/did/v2' + +import { + DidDocumentRole, + DidRecord, + DidRepository, + KeyType, + Buffer, + isValidPrivateKey, + utils, + TypedArrayEncoder, + getKeyFromVerificationMethod, +} from '@aries-framework/core' +import { MethodSpecificIdAlgo, createDidVerificationMethod } from '@cheqd/sdk' +import { MsgCreateResourcePayload } from '@cheqd/ts-proto/cheqd/resource/v2' + +import { CheqdLedgerService } from '../ledger' + +import { + createMsgCreateDidDocPayloadToSign, + generateDidDoc, + validateSpecCompliantPayload, + createMsgDeactivateDidDocPayloadToSign, +} from './didCheqdUtil' + +export class CheqdDidRegistrar implements DidRegistrar { + public readonly supportedMethods = ['cheqd'] + + public async create(agentContext: AgentContext, options: CheqdDidCreateOptions): Promise { + const didRepository = agentContext.dependencyManager.resolve(DidRepository) + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + + const { methodSpecificIdAlgo, network, versionId = utils.uuid() } = options.options + const verificationMethod = options.secret?.verificationMethod + let didDocument: DidDocument + + try { + if (options.didDocument && validateSpecCompliantPayload(options.didDocument)) { + didDocument = options.didDocument + } else if (verificationMethod) { + const privateKey = verificationMethod.privateKey + if (privateKey && !isValidPrivateKey(privateKey, KeyType.Ed25519)) { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Invalid private key provided', + }, + } + } + + const key = await agentContext.wallet.createKey({ + keyType: KeyType.Ed25519, + privateKey: privateKey, + }) + didDocument = generateDidDoc({ + verificationMethod: verificationMethod.type as VerificationMethods, + verificationMethodId: verificationMethod.id || 'key-1', + methodSpecificIdAlgo: (methodSpecificIdAlgo as MethodSpecificIdAlgo) || MethodSpecificIdAlgo.Uuid, + network: network as CheqdNetwork, + publicKey: TypedArrayEncoder.toHex(key.publicKey), + }) satisfies DidDocument + } else { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Provide a didDocument or atleast one verificationMethod with seed in secret', + }, + } + } + + const payloadToSign = await createMsgCreateDidDocPayloadToSign(didDocument as DIDDocument, versionId) + const signInputs = await this.signPayload(agentContext, payloadToSign, didDocument.verificationMethod) + + const response = await cheqdLedgerService.create(didDocument as DIDDocument, signInputs, versionId) + if (response.code !== 0) { + throw new Error(`${response.rawLog}`) + } + + // Save the did so we know we created it and can issue with it + const didRecord = new DidRecord({ + did: didDocument.id, + role: DidDocumentRole.Created, + didDocument, + }) + await didRepository.save(agentContext, didRecord) + + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'finished', + did: didDocument.id, + didDocument, + secret: options.secret, + }, + } + } catch (error) { + agentContext.config.logger.error(`Error registering DID`, error) + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async update(agentContext: AgentContext, options: CheqdDidUpdateOptions): Promise { + const didRepository = agentContext.dependencyManager.resolve(DidRepository) + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + + const versionId = options.options?.versionId || utils.uuid() + const verificationMethod = options.secret?.verificationMethod + let didDocument: DidDocument + let didRecord: DidRecord | null + + try { + if (options.didDocument && validateSpecCompliantPayload(options.didDocument)) { + didDocument = options.didDocument + const resolvedDocument = await cheqdLedgerService.resolve(didDocument.id) + didRecord = await didRepository.findCreatedDid(agentContext, didDocument.id) + if (!resolvedDocument.didDocument || resolvedDocument.didDocumentMetadata.deactivated || !didRecord) { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Did not found', + }, + } + } + + if (verificationMethod) { + const privateKey = verificationMethod.privateKey + if (privateKey && !isValidPrivateKey(privateKey, KeyType.Ed25519)) { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Invalid private key provided', + }, + } + } + + const key = await agentContext.wallet.createKey({ + keyType: KeyType.Ed25519, + privateKey: privateKey, + }) + + didDocument.verificationMethod?.concat( + createDidVerificationMethod( + [verificationMethod.type as VerificationMethods], + [ + { + methodSpecificId: didDocument.id.split(':')[3], + didUrl: didDocument.id, + keyId: `${didDocument.id}#${verificationMethod.id}`, + publicKey: TypedArrayEncoder.toHex(key.publicKey), + }, + ] + ) + ) + } + } else { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Provide a valid didDocument', + }, + } + } + + const payloadToSign = await createMsgCreateDidDocPayloadToSign(didDocument as DIDDocument, versionId) + const signInputs = await this.signPayload(agentContext, payloadToSign, didDocument.verificationMethod) + + const response = await cheqdLedgerService.update(didDocument as DIDDocument, signInputs, versionId) + if (response.code !== 0) { + throw new Error(`${response.rawLog}`) + } + + // Save the did so we know we created it and can issue with it + didRecord.didDocument = didDocument + await didRepository.update(agentContext, didRecord) + + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'finished', + did: didDocument.id, + didDocument, + secret: options.secret, + }, + } + } catch (error) { + agentContext.config.logger.error(`Error updating DID`, error) + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async deactivate( + agentContext: AgentContext, + options: CheqdDidDeactivateOptions + ): Promise { + const didRepository = agentContext.dependencyManager.resolve(DidRepository) + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + + const did = options.did + const versionId = options.options?.versionId || utils.uuid() + + try { + const { didDocument, didDocumentMetadata } = await cheqdLedgerService.resolve(did) + const didRecord = await didRepository.findCreatedDid(agentContext, did) + if (!didDocument || didDocumentMetadata.deactivated || !didRecord) { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: 'Did not found', + }, + } + } + const payloadToSign = createMsgDeactivateDidDocPayloadToSign(didDocument, versionId) + const signInputs = await this.signPayload(agentContext, payloadToSign, didDocument.verificationMethod) + const response = await cheqdLedgerService.deactivate(didDocument, signInputs, versionId) + if (response.code !== 0) { + throw new Error(`${response.rawLog}`) + } + + await didRepository.update(agentContext, didRecord) + + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'finished', + did: didDocument.id, + didDocument: didDocument as DidDocument, + secret: options.secret, + }, + } + } catch (error) { + agentContext.config.logger.error(`Error deactivating DID`, error) + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'failed', + reason: `unknownError: ${error.message}`, + }, + } + } + } + + public async createResource(agentContext: AgentContext, did: string, resource: CheqdCreateResourceOptions) { + const didRepository = agentContext.dependencyManager.resolve(DidRepository) + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + const { didDocument, didDocumentMetadata } = await cheqdLedgerService.resolve(did) + const didRecord = await didRepository.findCreatedDid(agentContext, did) + if (!didDocument || didDocumentMetadata.deactivated || !didRecord) { + return { + resourceMetadata: {}, + resourceRegistrationMetadata: {}, + resourceState: { + state: 'failed', + reason: `DID: ${did} not found`, + }, + } + } + + try { + let data: Uint8Array + if (typeof resource.data === 'string') { + data = TypedArrayEncoder.fromBase64(resource.data) + } else if (typeof resource.data == 'object') { + data = TypedArrayEncoder.fromString(JSON.stringify(resource.data)) + } else { + data = resource.data + } + + const resourcePayload = MsgCreateResourcePayload.fromPartial({ + collectionId: did.split(':')[3], + id: resource.id, + resourceType: resource.resourceType, + name: resource.name, + version: resource.version, + alsoKnownAs: resource.alsoKnownAs, + data, + }) + const payloadToSign = MsgCreateResourcePayload.encode(resourcePayload).finish() + const signInputs = await this.signPayload(agentContext, payloadToSign, didDocument.verificationMethod) + const response = await cheqdLedgerService.createResource(did, resourcePayload, signInputs) + if (response.code !== 0) { + throw new Error(`${response.rawLog}`) + } + + return { + resourceMetadata: {}, + resourceRegistrationMetadata: {}, + resourceState: { + state: 'finished', + resourceId: resourcePayload.id, + resource: resourcePayload, + }, + } + } catch (error) { + return { + resourceMetadata: {}, + resourceRegistrationMetadata: {}, + resourceState: { + state: 'failed', + reason: `unknownError: ${error.message}`, + }, + } + } + } + + private async signPayload( + agentContext: AgentContext, + payload: Uint8Array, + verificationMethod: VerificationMethod[] = [] + ) { + return await Promise.all( + verificationMethod.map(async (method) => { + const key = getKeyFromVerificationMethod(method) + return { + verificationMethodId: method.id, + signature: await agentContext.wallet.sign({ data: Buffer.from(payload), key }), + } satisfies SignInfo + }) + ) + } +} + +export interface CheqdDidCreateOptions extends DidCreateOptions { + method: 'cheqd' + options: { + network: `${CheqdNetwork}` + fee?: DidStdFee + versionId?: string + methodSpecificIdAlgo?: `${MethodSpecificIdAlgo}` + } + secret: { + verificationMethod?: IVerificationMethod + } +} + +export interface CheqdDidUpdateOptions extends DidCreateOptions { + method: 'cheqd' + did: string + didDocument: DidDocument + options: { + fee?: DidStdFee + versionId?: string + } + secret?: { + verificationMethod: IVerificationMethod + } +} + +export interface CheqdDidDeactivateOptions extends DidCreateOptions { + method: 'cheqd' + did: string + options: { + fee?: DidStdFee + versionId?: string + } +} + +export interface CheqdCreateResourceOptions extends Omit, 'data'> { + data: string | Uint8Array | object +} + +interface IVerificationMethod { + type: `${VerificationMethods}` + id: TVerificationKey + privateKey?: Buffer +} diff --git a/packages/cheqd/src/dids/CheqdDidResolver.ts b/packages/cheqd/src/dids/CheqdDidResolver.ts new file mode 100644 index 0000000000..d599e8d596 --- /dev/null +++ b/packages/cheqd/src/dids/CheqdDidResolver.ts @@ -0,0 +1,192 @@ +import type { ParsedCheqdDid } from '../anoncreds/utils/identifiers' +import type { AgentContext, DidDocument, DidResolutionResult, DidResolver, ParsedDid } from '@aries-framework/core' +import type { Metadata } from '@cheqd/ts-proto/cheqd/resource/v2' + +import { AriesFrameworkError, utils } from '@aries-framework/core' + +import { + cheqdDidMetadataRegex, + cheqdDidRegex, + cheqdDidVersionRegex, + cheqdDidVersionsRegex, + cheqdResourceMetadataRegex, + cheqdResourceRegex, + parseCheqdDid, +} from '../anoncreds/utils/identifiers' +import { CheqdLedgerService } from '../ledger' + +import { filterResourcesByNameAndType, getClosestResourceVersion, renderResourceData } from './didCheqdUtil' + +export class CheqdDidResolver implements DidResolver { + public readonly supportedMethods = ['cheqd'] + + public async resolve(agentContext: AgentContext, did: string, parsed: ParsedDid): Promise { + const didDocumentMetadata = {} + + try { + const parsedDid = parseCheqdDid(parsed.didUrl) + if (!parsedDid) { + throw new Error('Invalid DID') + } + + switch (did) { + case did.match(cheqdDidRegex)?.input: + return await this.resolveDidDoc(agentContext, parsedDid.did) + case did.match(cheqdDidVersionRegex)?.input: { + const version = did.split('/')[2] + return await this.resolveDidDoc(agentContext, parsedDid.did, version) + } + case did.match(cheqdDidVersionsRegex)?.input: + return await this.resolveAllDidDocVersions(agentContext, parsedDid) + case did.match(cheqdDidMetadataRegex)?.input: + return await this.dereferenceCollectionResources(agentContext, parsedDid) + case did.match(cheqdResourceMetadataRegex)?.input: + return await this.dereferenceResourceMetadata(agentContext, parsedDid) + default: + return { + didDocument: null, + didDocumentMetadata, + didResolutionMetadata: { + error: 'Invalid request', + message: `Unsupported did Url: '${did}'`, + }, + } + } + } catch (error) { + return { + didDocument: null, + didDocumentMetadata, + didResolutionMetadata: { + error: 'notFound', + message: `resolver_error: Unable to resolve did '${did}': ${error}`, + }, + } + } + } + + public async resolveResource(agentContext: AgentContext, did: string) { + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + try { + const parsedDid = parseCheqdDid(did) + if (!parsedDid) { + throw new Error('Invalid DID') + } + + const { params, id } = parsedDid + let resourceId: string + if (did.match(cheqdResourceRegex)?.input) { + resourceId = did.split('/')[2] + } else if (params && params.resourceName && params.resourceType) { + let resources = (await cheqdLedgerService.resolveCollectionResources(parsedDid.did, id)).resources + resources = filterResourcesByNameAndType(resources, params.resourceName, params.resourceType) + if (!resources.length) { + throw new Error(`No resources found`) + } + + let resource: Metadata | undefined + if (params.version) { + resource = resources.find((resource) => resource.version == params.version) + } else { + const date = params.resourceVersionTime ? new Date(Number(params.resourceVersionTime) * 1000) : new Date() + // find the resourceId closest to the created time + resource = getClosestResourceVersion(resources, date) + } + + if (!resource) { + throw new Error(`No resources found`) + } + + resourceId = resource.id + } else { + return { + error: 'notFound', + message: `resolver_error: Invalid did url '${did}'`, + } + } + if (!utils.isValidUuid(resourceId)) { + throw new Error('Invalid resource Id') + } + + const { resource, metadata } = await cheqdLedgerService.resolveResource(parsedDid.did, id, resourceId) + if (!resource || !metadata) { + throw new Error('resolver_error: Unable to resolve resource, Please try again') + } + + const result = await renderResourceData(resource.data, metadata.mediaType) + return { + resource: result, + resourceMetadata: metadata, + resourceResolutionMetadata: {}, + } + } catch (error) { + return { + error: 'notFound', + message: `resolver_error: Unable to resolve resource '${did}': ${error}`, + } + } + } + + private async resolveAllDidDocVersions(agentContext: AgentContext, parsedDid: ParsedCheqdDid) { + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + const { did } = parsedDid + + const { didDocumentVersionsMetadata } = await cheqdLedgerService.resolveMetadata(did) + return { + didDocument: { id: did } as DidDocument, + didDocumentMetadata: didDocumentVersionsMetadata, + didResolutionMetadata: {}, + } + } + + private async dereferenceCollectionResources(agentContext: AgentContext, parsedDid: ParsedCheqdDid) { + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + const { did, id } = parsedDid + + const metadata = await cheqdLedgerService.resolveCollectionResources(did, id) + return { + didDocument: { id: did } as DidDocument, + didDocumentMetadata: { + linkedResourceMetadata: metadata, + }, + didResolutionMetadata: {}, + } + } + + private async dereferenceResourceMetadata(agentContext: AgentContext, parsedDid: ParsedCheqdDid) { + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + const { did, id } = parsedDid + + if (!parsedDid.path) { + throw new AriesFrameworkError(`Missing path in did ${parsedDid.did}`) + } + + const [, , resourceId] = parsedDid.path.split('/') + + if (!resourceId) { + throw new AriesFrameworkError(`Missing resource id in didUrl ${parsedDid.didUrl}`) + } + + const metadata = await cheqdLedgerService.resolveResourceMetadata(did, id, resourceId) + return { + didDocument: { id: did } as DidDocument, + didDocumentMetadata: { + linkedResourceMetadata: metadata, + }, + didResolutionMetadata: {}, + } + } + + private async resolveDidDoc(agentContext: AgentContext, did: string, version?: string): Promise { + const cheqdLedgerService = agentContext.dependencyManager.resolve(CheqdLedgerService) + + const { didDocument, didDocumentMetadata } = await cheqdLedgerService.resolve(did, version) + const { resources } = await cheqdLedgerService.resolveCollectionResources(did, did.split(':')[3]) + didDocumentMetadata.linkedResourceMetadata = resources + + return { + didDocument: didDocument as DidDocument, + didDocumentMetadata, + didResolutionMetadata: {}, + } + } +} diff --git a/packages/cheqd/src/dids/didCheqdUtil.ts b/packages/cheqd/src/dids/didCheqdUtil.ts new file mode 100644 index 0000000000..37a2c94ad1 --- /dev/null +++ b/packages/cheqd/src/dids/didCheqdUtil.ts @@ -0,0 +1,152 @@ +import type { DidDocument } from '@aries-framework/core' +import type { CheqdNetwork, DIDDocument, MethodSpecificIdAlgo, TVerificationKey } from '@cheqd/sdk' +import type { Metadata } from '@cheqd/ts-proto/cheqd/resource/v2' + +import { AriesFrameworkError, JsonEncoder, TypedArrayEncoder } from '@aries-framework/core' +import { + createDidPayload, + createDidVerificationMethod, + createVerificationKeys, + DIDModule, + VerificationMethods, +} from '@cheqd/sdk' +import { MsgCreateDidDocPayload, MsgDeactivateDidDocPayload } from '@cheqd/ts-proto/cheqd/did/v2' +import { EnglishMnemonic as _ } from '@cosmjs/crypto' +import { DirectSecp256k1HdWallet, DirectSecp256k1Wallet } from '@cosmjs/proto-signing' + +export function validateSpecCompliantPayload(didDocument: DidDocument): SpecValidationResult { + // id is required, validated on both compile and runtime + if (!didDocument.id && !didDocument.id.startsWith('did:cheqd:')) 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 must be not be empty + if (!didDocument.verificationMethod.length) return { valid: false, error: 'verificationMethod must be not be empty' } + + // verificationMethod types must be supported + const isValidVerificationMethod = didDocument.verificationMethod.every((vm) => { + switch (vm.type) { + case VerificationMethods.Ed255192020: + return vm.publicKeyMultibase != null + case VerificationMethods.JWK: + return vm.publicKeyJwk != null + case VerificationMethods.Ed255192018: + return vm.publicKeyBase58 != null + default: + return false + } + }) + + if (!isValidVerificationMethod) return { valid: false, error: 'verificationMethod publicKey is Invalid' } + + const isValidService = didDocument.service + ? didDocument?.service?.every((s) => { + return s?.serviceEndpoint && s?.id && s?.type + }) + : true + + if (!isValidService) return { valid: false, error: 'Service is Invalid' } + return { valid: true } as SpecValidationResult +} + +// Create helpers in sdk like MsgCreateDidDocPayload.fromDIDDocument to replace the below +export async function createMsgCreateDidDocPayloadToSign(didPayload: DIDDocument, versionId: string) { + didPayload.service = didPayload.service?.map((e) => { + return { + ...e, + serviceEndpoint: Array.isArray(e.serviceEndpoint) ? e.serviceEndpoint : [e.serviceEndpoint], + } + }) + const { protobufVerificationMethod, protobufService } = await DIDModule.validateSpecCompliantPayload(didPayload) + return MsgCreateDidDocPayload.encode( + 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() +} + +export function createMsgDeactivateDidDocPayloadToSign(didPayload: DIDDocument, versionId?: string) { + return MsgDeactivateDidDocPayload.encode( + MsgDeactivateDidDocPayload.fromPartial({ + id: didPayload.id, + versionId, + }) + ).finish() +} + +export type SpecValidationResult = { + valid: boolean + error?: string +} + +export function generateDidDoc(options: IDidDocOptions) { + const { verificationMethod, methodSpecificIdAlgo, verificationMethodId, network, publicKey } = options + const verificationKeys = createVerificationKeys(publicKey, methodSpecificIdAlgo, verificationMethodId, network) + if (!verificationKeys) { + throw new Error('Invalid DID options') + } + const verificationMethods = createDidVerificationMethod([verificationMethod], [verificationKeys]) + + return createDidPayload(verificationMethods, [verificationKeys]) as DidDocument +} + +export interface IDidDocOptions { + verificationMethod: VerificationMethods + verificationMethodId: TVerificationKey + methodSpecificIdAlgo: MethodSpecificIdAlgo + network: CheqdNetwork + publicKey: string +} + +export function getClosestResourceVersion(resources: Metadata[], date: Date) { + const result = resources.sort(function (a, b) { + if (!a.created || !b.created) throw new AriesFrameworkError("Missing required property 'created' on resource") + const distancea = Math.abs(date.getTime() - a.created.getTime()) + const distanceb = Math.abs(date.getTime() - b.created.getTime()) + return distancea - distanceb + }) + return result[0] +} + +export function filterResourcesByNameAndType(resources: Metadata[], name: string, type: string) { + return resources.filter((resource) => resource.name == name && resource.resourceType == type) +} + +export async function renderResourceData(data: Uint8Array, mimeType: string) { + if (mimeType == 'application/json') { + return await JsonEncoder.fromBuffer(data) + } else if (mimeType == 'text/plain') { + return TypedArrayEncoder.toUtf8String(data) + } else { + return TypedArrayEncoder.toBase64URL(data) + } +} + +export class EnglishMnemonic extends _ { + public static readonly _mnemonicMatcher = /^[a-z]+( [a-z]+)*$/ +} + +export function getCosmosPayerWallet(cosmosPayerSeed?: string) { + if (!cosmosPayerSeed || cosmosPayerSeed === '') { + return DirectSecp256k1HdWallet.generate() + } + return EnglishMnemonic._mnemonicMatcher.test(cosmosPayerSeed) + ? DirectSecp256k1HdWallet.fromMnemonic(cosmosPayerSeed, { prefix: 'cheqd' }) + : DirectSecp256k1Wallet.fromKey(TypedArrayEncoder.fromString(cosmosPayerSeed.replace(/^0x/, '')), 'cheqd') +} diff --git a/packages/cheqd/src/dids/index.ts b/packages/cheqd/src/dids/index.ts new file mode 100644 index 0000000000..315b1c0982 --- /dev/null +++ b/packages/cheqd/src/dids/index.ts @@ -0,0 +1,8 @@ +export { + CheqdDidRegistrar, + CheqdDidCreateOptions, + CheqdDidDeactivateOptions, + CheqdDidUpdateOptions, + CheqdCreateResourceOptions, +} from './CheqdDidRegistrar' +export { CheqdDidResolver } from './CheqdDidResolver' diff --git a/packages/cheqd/src/index.ts b/packages/cheqd/src/index.ts new file mode 100644 index 0000000000..4270e5c072 --- /dev/null +++ b/packages/cheqd/src/index.ts @@ -0,0 +1,17 @@ +// Dids +export { + CheqdDidRegistrar, + CheqdDidCreateOptions, + CheqdDidDeactivateOptions, + CheqdDidUpdateOptions, + CheqdDidResolver, +} from './dids' + +// AnonCreds +export { CheqdAnonCredsRegistry } from './anoncreds' + +export { CheqdLedgerService } from './ledger' + +export { CheqdModule } from './CheqdModule' + +export { CheqdModuleConfig, CheqdModuleConfigOptions } from './CheqdModuleConfig' diff --git a/packages/cheqd/src/ledger/CheqdLedgerService.ts b/packages/cheqd/src/ledger/CheqdLedgerService.ts new file mode 100644 index 0000000000..36adf6eb2a --- /dev/null +++ b/packages/cheqd/src/ledger/CheqdLedgerService.ts @@ -0,0 +1,123 @@ +import type { AbstractCheqdSDKModule, CheqdSDK, DidStdFee, DIDDocument } from '@cheqd/sdk' +import type { SignInfo } from '@cheqd/ts-proto/cheqd/did/v2' +import type { MsgCreateResourcePayload } from '@cheqd/ts-proto/cheqd/resource/v2' +import type { DirectSecp256k1HdWallet, DirectSecp256k1Wallet } from '@cosmjs/proto-signing' + +import { injectable } from '@aries-framework/core' +import { createCheqdSDK, DIDModule, ResourceModule, CheqdNetwork } from '@cheqd/sdk' + +import { CheqdModuleConfig } from '../CheqdModuleConfig' +import { parseCheqdDid } from '../anoncreds/utils/identifiers' +import { getCosmosPayerWallet } from '../dids/didCheqdUtil' + +export interface ICheqdLedgerConfig { + network: string + rpcUrl: string + readonly cosmosPayerWallet: Promise + sdk?: CheqdSDK +} + +export enum DefaultRPCUrl { + Mainnet = 'https://rpc.cheqd.net', + Testnet = 'https://rpc.cheqd.network', +} + +@injectable() +export class CheqdLedgerService { + private networks: ICheqdLedgerConfig[] + + public constructor(cheqdSdkModuleConfig: CheqdModuleConfig) { + this.networks = cheqdSdkModuleConfig.networks.map((config) => { + const { network, rpcUrl, cosmosPayerSeed } = config + return { + network, + rpcUrl: rpcUrl ? rpcUrl : network === CheqdNetwork.Mainnet ? DefaultRPCUrl.Mainnet : DefaultRPCUrl.Testnet, + cosmosPayerWallet: getCosmosPayerWallet(cosmosPayerSeed), + } + }) + } + + public async connect() { + for (const network of this.networks) { + network.sdk = await createCheqdSDK({ + modules: [DIDModule as unknown as AbstractCheqdSDKModule, ResourceModule as unknown as AbstractCheqdSDKModule], + rpcUrl: network.rpcUrl, + wallet: await network.cosmosPayerWallet.catch(() => { + throw new Error(`[did-provider-cheqd]: valid cosmosPayerSeed is required`) + }), + }) + } + } + + private getSdk(did: string) { + const parsedDid = parseCheqdDid(did) + if (!parsedDid) { + throw new Error('Invalid DID') + } + if (this.networks.length === 0) { + throw new Error('No cheqd networks configured') + } + + const network = this.networks.find((network) => network.network === parsedDid.network) + if (!network || !network.sdk) { + throw new Error('Network not configured') + } + return network.sdk + } + + public async create( + didPayload: DIDDocument, + signInputs: SignInfo[], + versionId?: string | undefined, + fee?: DidStdFee + ) { + return await this.getSdk(didPayload.id).createDidDocTx(signInputs, didPayload, '', fee, undefined, versionId) + } + + public async update( + didPayload: DIDDocument, + signInputs: SignInfo[], + versionId?: string | undefined, + fee?: DidStdFee + ) { + return await this.getSdk(didPayload.id).updateDidDocTx(signInputs, didPayload, '', fee, undefined, versionId) + } + + public async deactivate( + didPayload: DIDDocument, + signInputs: SignInfo[], + versionId?: string | undefined, + fee?: DidStdFee + ) { + return await this.getSdk(didPayload.id).deactivateDidDocTx(signInputs, didPayload, '', fee, undefined, versionId) + } + + public async resolve(did: string, version?: string) { + return version ? await this.getSdk(did).queryDidDocVersion(did, version) : await this.getSdk(did).queryDidDoc(did) + } + + public async resolveMetadata(did: string) { + return await this.getSdk(did).queryAllDidDocVersionsMetadata(did) + } + + public async createResource( + did: string, + resourcePayload: Partial, + signInputs: SignInfo[], + fee?: DidStdFee + ) { + return await this.getSdk(did).createLinkedResourceTx(signInputs, resourcePayload, '', fee, undefined) + } + + public async resolveResource(did: string, collectionId: string, resourceId: string) { + return await this.getSdk(did).queryLinkedResource(collectionId, resourceId) + } + + public async resolveCollectionResources(did: string, collectionId: string) { + return await this.getSdk(did).queryLinkedResources(collectionId) + } + + public async resolveResourceMetadata(did: string, collectionId: string, resourceId: string) { + return await this.getSdk(did).queryLinkedResourceMetadata(collectionId, resourceId) + } +} diff --git a/packages/cheqd/src/ledger/index.ts b/packages/cheqd/src/ledger/index.ts new file mode 100644 index 0000000000..db2eec776a --- /dev/null +++ b/packages/cheqd/src/ledger/index.ts @@ -0,0 +1 @@ +export { CheqdLedgerService } from './CheqdLedgerService' diff --git a/packages/cheqd/tests/cheqd-did-registrar.e2e.test.ts b/packages/cheqd/tests/cheqd-did-registrar.e2e.test.ts new file mode 100644 index 0000000000..e2b8e1dd1b --- /dev/null +++ b/packages/cheqd/tests/cheqd-did-registrar.e2e.test.ts @@ -0,0 +1,132 @@ +import type { CheqdDidCreateOptions } from '../src' +import type { DidDocument } from '@aries-framework/core' + +import { Agent, TypedArrayEncoder } from '@aries-framework/core' +import { generateKeyPairFromSeed } from '@stablelib/ed25519' + +import { getAgentOptions } from '../../core/tests/helpers' + +import { validService } from './setup' +import { getCheqdModules } from './setupCheqdModule' + +const agentOptions = getAgentOptions('Faber Dids Registrar', {}, getCheqdModules()) + +describe('Cheqd DID registrar', () => { + let agent: Agent> + + beforeAll(async () => { + agent = new Agent(agentOptions) + await agent.initialize() + }) + + afterAll(async () => { + await agent.shutdown() + await agent.wallet.delete() + }) + + it('should create a did:cheqd did', async () => { + // Generate a seed and the cheqd did. This allows us to create a new did every time + // but still check if the created output document is as expected. + const privateKey = TypedArrayEncoder.fromString( + Array(32 + 1) + .join((Math.random().toString(36) + '00000000000000000').slice(2, 18)) + .slice(0, 32) + ) + const publicKeyEd25519 = generateKeyPairFromSeed(privateKey).publicKey + const ed25519PublicKeyBase58 = TypedArrayEncoder.toBase58(publicKeyEd25519) + const did = await agent.dids.create({ + method: 'cheqd', + secret: { + verificationMethod: { + id: 'key-1', + type: 'Ed25519VerificationKey2018', + privateKey, + }, + }, + options: { + network: 'testnet', + methodSpecificIdAlgo: 'base58btc', + }, + }) + expect(did).toMatchObject({ + didState: { + state: 'finished', + didDocument: { + verificationMethod: [ + { + type: 'Ed25519VerificationKey2018', + publicKeyBase58: ed25519PublicKeyBase58, + }, + ], + }, + }, + }) + }) + + it('should create a did:cheqd using Ed25519VerificationKey2020', async () => { + const did = await agent.dids.create({ + method: 'cheqd', + secret: { + verificationMethod: { + id: 'key-1', + type: 'Ed25519VerificationKey2020', + }, + }, + options: { + network: 'testnet', + methodSpecificIdAlgo: 'uuid', + }, + }) + expect(did.didState).toMatchObject({ state: 'finished' }) + }) + + it('should create a did:cheqd using JsonWebKey2020', async () => { + const createResult = await agent.dids.create({ + method: 'cheqd', + secret: { + verificationMethod: { + id: 'key-11', + type: 'JsonWebKey2020', + }, + }, + options: { + network: 'testnet', + methodSpecificIdAlgo: 'base58btc', + }, + }) + expect(createResult).toMatchObject({ + didState: { + state: 'finished', + didDocument: { + verificationMethod: [{ type: 'JsonWebKey2020' }], + }, + }, + }) + expect(createResult.didState.did).toBeDefined() + const did = createResult.didState.did as string + const didDocument = createResult.didState.didDocument as DidDocument + didDocument.service = [validService(did)] + + const updateResult = await agent.dids.update({ + did, + didDocument, + }) + expect(updateResult).toMatchObject({ + didState: { + state: 'finished', + didDocument, + }, + }) + + const deactivateResult = await agent.dids.deactivate({ did }) + expect(deactivateResult).toMatchObject({ + didState: { + state: 'finished', + didDocument, + }, + }) + + const resolvedDocument = await agent.dids.resolve(did) + expect(resolvedDocument.didDocumentMetadata.deactivated).toBe(true) + }) +}) diff --git a/packages/cheqd/tests/cheqd-did-resolver.e2e.test.ts b/packages/cheqd/tests/cheqd-did-resolver.e2e.test.ts new file mode 100644 index 0000000000..b7778ec41c --- /dev/null +++ b/packages/cheqd/tests/cheqd-did-resolver.e2e.test.ts @@ -0,0 +1,69 @@ +import { Agent, JsonTransformer } from '@aries-framework/core' + +import { getAgentOptions } from '../../core/tests/helpers' +import { getClosestResourceVersion } from '../src/dids/didCheqdUtil' + +import { getCheqdModules } from './setupCheqdModule' + +const agent = new Agent(getAgentOptions('Indy SDK Sov DID resolver', {}, getCheqdModules())) + +describe('Cheqd DID resolver', () => { + beforeAll(async () => { + await agent.initialize() + }) + + afterAll(async () => { + await agent.shutdown() + await agent.wallet.delete() + }) + + it('should resolve a did:cheqd:testnet did', async () => { + const did = await agent.dids.resolve('did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8') + expect(JsonTransformer.toJSON(did)).toMatchObject({ + didDocument: { + '@context': ['https://www.w3.org/ns/did/v1', 'https://w3id.org/security/suites/ed25519-2020/v1'], + id: 'did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8', + controller: ['did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8'], + verificationMethod: [ + { + controller: 'did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8', + id: 'did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8#key-1', + publicKeyMultibase: 'z6MksPpyxgw5aFymMboa81CQ7h1kJJ9yehNzPgo714y1HrAA', + type: 'Ed25519VerificationKey2020', + }, + ], + authentication: ['did:cheqd:testnet:3053e034-8faa-458d-9f01-2e3e1e8b2ab8#key-1'], + }, + didDocumentMetadata: { + created: '2022-10-17T13:42:37.000Z', + updated: '0001-01-01T00:00:00.000Z', + deactivated: false, + versionId: '7314e3e5-f9cc-50e9-b249-348963937c96', + nextVersionId: '', + }, + didResolutionMetadata: {}, + }) + }) + + it('should getClosestResourceVersion', async () => { + const did = await agent.dids.resolve('did:cheqd:testnet:SiVQgrFZ7jFZFrTGstT4ZD') + let resource = getClosestResourceVersion(did.didDocumentMetadata.linkedResourceMetadata, new Date()) + expect(resource).toMatchObject({ + id: '0b02ebf4-07c4-4df7-9015-e93c21108240', + }) + resource = getClosestResourceVersion( + did.didDocumentMetadata.linkedResourceMetadata, + new Date('2022-11-16T10:56:34Z') + ) + expect(resource).toMatchObject({ + id: '8140ec3a-d8bb-4f59-9784-a1cbf91a4a35', + }) + resource = getClosestResourceVersion( + did.didDocumentMetadata.linkedResourceMetadata, + new Date('2022-11-16T11:41:48Z') + ) + expect(resource).toMatchObject({ + id: 'a20aa56a-a76f-4828-8a98-4c85d9494545', + }) + }) +}) diff --git a/packages/cheqd/tests/cheqd-did-utils.e2e.test.ts b/packages/cheqd/tests/cheqd-did-utils.e2e.test.ts new file mode 100644 index 0000000000..b5cc7b0401 --- /dev/null +++ b/packages/cheqd/tests/cheqd-did-utils.e2e.test.ts @@ -0,0 +1,48 @@ +import type { DIDDocument } from '@cheqd/sdk' + +import { DidDocument } from '@aries-framework/core' + +import { + createMsgCreateDidDocPayloadToSign, + createMsgDeactivateDidDocPayloadToSign, + validateSpecCompliantPayload, +} from '../src/dids/didCheqdUtil' + +import { validDid, validDidDoc } from './setup' + +describe('Test Cheqd Did Utils', () => { + it('should validate did spec compliant payload', () => { + const didDoc = validDidDoc() + const result = validateSpecCompliantPayload(didDoc) + expect(result.valid).toBe(true) + expect(result.error).toBeUndefined() + }) + + it('should detect invalid verification method', () => { + const result = validateSpecCompliantPayload( + new DidDocument({ + id: validDid, + verificationMethod: [ + { + id: validDid + '#key-1', + publicKeyBase58: 'asca12e3as', + type: 'JsonWebKey2020', + controller: validDid, + }, + ], + }) + ) + expect(result.valid).toBe(false) + expect(result.error).toBeDefined() + }) + + it('should create MsgCreateDidDocPayloadToSign', async () => { + const result = await createMsgCreateDidDocPayloadToSign(validDidDoc() as DIDDocument, '1.0') + expect(result).toBeDefined() + }) + + it('should create MsgDeactivateDidDocPayloadToSign', async () => { + const result = createMsgDeactivateDidDocPayloadToSign({ id: validDid }, '2.0') + expect(result).toBeDefined() + }) +}) diff --git a/packages/cheqd/tests/cheqd-sdk-anoncreds-registry.e2e.test.ts b/packages/cheqd/tests/cheqd-sdk-anoncreds-registry.e2e.test.ts new file mode 100644 index 0000000000..1f872e344b --- /dev/null +++ b/packages/cheqd/tests/cheqd-sdk-anoncreds-registry.e2e.test.ts @@ -0,0 +1,243 @@ +import type { CheqdDidCreateOptions } from '../src' + +import { Agent, JsonTransformer, TypedArrayEncoder } from '@aries-framework/core' + +import { agentDependencies, getAgentConfig } from '../../core/tests/helpers' +import { CheqdAnonCredsRegistry } from '../src/anoncreds' + +import { getCheqdModules } from './setupCheqdModule' + +const agentConfig = getAgentConfig('cheqdAnonCredsRegistry') + +const agent = new Agent({ + config: agentConfig, + dependencies: agentDependencies, + modules: getCheqdModules('000000000000000000000000000cheqd'), +}) + +const cheqdAnonCredsRegistry = new CheqdAnonCredsRegistry() + +let issuerId: string + +describe('cheqdAnonCredsRegistry', () => { + beforeAll(async () => { + await agent.initialize() + }) + + afterAll(async () => { + await agent.shutdown() + await agent.wallet.delete() + }) + + // One test as the credential definition depends on the schema + test('register and resolve a schema and credential definition', async () => { + const privateKey = TypedArrayEncoder.fromString('000000000000000000000000000cheqd') + + const did = await agent.dids.create({ + method: 'cheqd', + secret: { + verificationMethod: { + id: 'key-10', + type: 'Ed25519VerificationKey2020', + privateKey, + }, + }, + options: { + network: 'testnet', + methodSpecificIdAlgo: 'uuid', + }, + }) + expect(did.didState).toMatchObject({ state: 'finished' }) + issuerId = did.didState.did as string + + const dynamicVersion = `1.${Math.random() * 100}` + + const schemaResult = await cheqdAnonCredsRegistry.registerSchema(agent.context, { + schema: { + attrNames: ['name'], + issuerId, + name: 'test11', + version: dynamicVersion, + }, + options: {}, + }) + + expect(JsonTransformer.toJSON(schemaResult)).toMatchObject({ + schemaState: { + state: 'finished', + schema: { + attrNames: ['name'], + issuerId, + name: 'test11', + version: dynamicVersion, + }, + schemaId: `${schemaResult.schemaState.schemaId}`, + }, + registrationMetadata: {}, + schemaMetadata: {}, + }) + + const schemaResponse = await cheqdAnonCredsRegistry.getSchema(agent.context, `${schemaResult.schemaState.schemaId}`) + expect(schemaResponse).toMatchObject({ + schema: { + attrNames: ['name'], + name: 'test11', + version: dynamicVersion, + issuerId, + }, + schemaId: `${schemaResult.schemaState.schemaId}`, + resolutionMetadata: {}, + schemaMetadata: {}, + }) + + const credentialDefinitionResult = await cheqdAnonCredsRegistry.registerCredentialDefinition(agent.context, { + credentialDefinition: { + issuerId, + tag: 'TAG', + schemaId: `${schemaResult.schemaState.schemaId}`, + type: 'CL', + value: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + options: {}, + }) + + expect(credentialDefinitionResult).toMatchObject({ + credentialDefinitionState: { + credentialDefinition: { + issuerId, + tag: 'TAG', + schemaId: `${schemaResult.schemaState.schemaId}`, + type: 'CL', + value: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + credentialDefinitionId: `${credentialDefinitionResult.credentialDefinitionState.credentialDefinitionId}`, + state: 'finished', + }, + }) + + const credentialDefinitionResponse = await cheqdAnonCredsRegistry.getCredentialDefinition( + agent.context, + credentialDefinitionResult.credentialDefinitionState.credentialDefinitionId as string + ) + + expect(credentialDefinitionResponse).toMatchObject({ + credentialDefinitionId: `${credentialDefinitionResult.credentialDefinitionState.credentialDefinitionId}`, + credentialDefinition: { + issuerId, + schemaId: `${schemaResult.schemaState.schemaId}`, + tag: 'TAG', + type: 'CL', + value: { + primary: { + n: '92511867718854414868106363741369833735017762038454769060600859608405811709675033445666654908195955460485998711087020152978597220168927505650092431295783175164390266561239892662085428655566792056852960599485298025843840058914610127716620252006466964070280255168745873592143068949458568751438337748294055976926080232538440619420568859737673474560851456027625679328271511966332808025880807996449998057729417608399774744254122385012832309402226532031122728445959276178939234308090390331654445053482963947804769291501664200141562885660084823885847247231002821472258218384342423605116504024514572826071246440130942849549441', + r: { + age: '676933340341980399002624386891134393471002096508227567343731826159610079436978196421307099268754545293545727546242372579987825752872485684085629459107300175443328323289748793060894500514926703654606851666031895448970879827423190730510730624784665299646624113512701254199984520803796529034094958026048762178753193812250643294518237843809104055653333871102658177900702978008644780459400512716361564897282969982554031820285585105004870317861287847206222714589633178648982299799311192432563797220854755882933052881306804544233529886513105815543097685128456041780804442879272476590077760678785460726492895806240870944398', + master_secret: + '57770757113548032970308439965749734133430520933173186296299026579579930337912607419798836831937319372744879560676750427054135869214212225572618340088847222727882935159356459822445182287686057012197046378986248048722180093079919306125315662058290895629438767985427829790980355162853804522854494960613869765167538645624719923127052541372069255024631093663068055100579264049925388231368871107383977060590248865498902704546409806115171120555709438784189721957301548212242748685629860268468247494986146122636455769804467583612610341632602695197189514316033637331733820369170763954604394734655429769801516997967996980978751', + }, + rctxt: + '19574881057684356733946284215946569464410211018678168661028327420122678446653210056362495902735819742274128834330867933095119512313591151219353395069123546495720010325822330866859140765940839241212947354612836044244554152389691282543839111284006009168728161183863936810142428875817934316327118674532328892591410224676539770085459540786747902789677759379901079898127879301595929571621032704093287675668250862222728331030586585586110859977896767318814398026750215625180255041545607499673023585546720788973882263863911222208020438685873501025545464213035270207099419236974668665979962146355749687924650853489277747454993', + s: '80388543865249952799447792504739237616187770512259677275061283897050980768551818104137338144380636412773836688624071360386172349725818126495487584981520630638409717065318132420766896092370913800616033623618952639023946750307405126873476182540669638841562357523429245685476919178722373320218824590869735129801004394337640642997250464303104754942997839179333543643110326022824394934965538190976474473353762308333205671176627192797138375084260446324344637548455228161138089974447059481109651156379803576163576511072261388342837813901850712083922506433336723723235701670225584863772222447543742649328218950436824219992164', + z: '18569464356833363098514177097771727133940629758890641648661259687745137028161881113251218061243607037717553708179509640909238773964066423807945164288256211132195919975343578956381001087353353060599758005375631247614777454313440511375923345538396573548499287265163879524050255226779884271432737062283353279122281220812931572456820130441114446870167673796490210349453498315913599982158253821945225264065364670730546176140788405935081171854642125236557475395879246419105888077042924382595999612137336915304205628167917473420377397118829734604949103124514367857266518654728464539418834291071874052392799652266418817991437', + }, + }, + }, + }) + }) + + // Should not resolve invalid schema + test('false test cases', async () => { + const invalidSchemaResourceId = + 'did:cheqd:testnet:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c/resources/ffd001c2-1f80-4cd8-84b2-945fba309457' + const schemaResponse = await cheqdAnonCredsRegistry.getSchema(agent.context, `${invalidSchemaResourceId}`) + + expect(schemaResponse).toMatchObject({ + resolutionMetadata: { + error: 'notFound', + }, + schemaMetadata: {}, + }) + }) + + // Should resolve query based url + test('resolve query based url', async () => { + const schemaResourceId = + 'did:cheqd:testnet:d8ac0372-0d4b-413e-8ef5-8e8f07822b2c?resourceName=test - 11&resourceType=anonCredsSchema' + const schemaResponse = await cheqdAnonCredsRegistry.getSchema(agent.context, `${schemaResourceId}`) + + expect(schemaResponse).toMatchObject({ + schema: { + attrNames: ['name'], + name: 'test - 11', + }, + }) + }) + + // Should resolve revocationRegistryDefinition and statusList + test('resolve revocation registry definition and statusList', async () => { + const revocationRegistryId = 'did:cheqd:testnet:e42ccb8b-78e8-4e54-9d11-f375153d63f8?resourceName=universityDegree' + const revocationDefinitionResponse = await cheqdAnonCredsRegistry.getRevocationRegistryDefinition( + agent.context, + revocationRegistryId + ) + + expect(revocationDefinitionResponse.revocationRegistryDefinition).toMatchObject({ + revocDefType: 'CL_ACCUM', + credDefId: 'did:cheqd:mainnet:zF7rhDBfUt9d1gJPjx7s1J/resources/77465164-5646-42d9-9a0a-f7b2dcb855c0', + tag: '2.0', + value: { + publicKeys: { + accumKey: { + z: '1 08C6E71D1CE1D1690AED25BC769646538BEC69600829CE1FB7AA788479E0B878 1 026909513F9901655B3F9153071DB43A846418F00F305BA25FE851730ED41102 1 10E9D5438AE95AE2BED78A33716BFF923A0F4CA980A9A599C25A24A2295658DA 1 0A04C318A0DFD29ABB1F1D8DD697999F9B89D6682272C591B586D53F8A9D3DC4 1 0501E5FFCE863E08D209C2FA7B390A5AA91F462BB71957CF8DB41EACDC9EB222 1 14BED208817ACB398D8476212C987E7FF77265A72F145EF2853DDB631758AED4 1 180774B2F67179FB62BD452A15F6C034599DA7BF45CC15AA2138212B53A0C110 1 00A0B87DDFFC047BE07235DD11D31226A9F5FA1E03D49C03843AA36A8AF68194 1 10218703955E0B53DB93A8D2D593EB8120A9C9739F127325CB0865ECA4B2B42F 1 08685A263CD0A045FD845AAC6DAA0FDDAAD0EC222C1A0286799B69F37CD75919 1 1FA3D27E70C185C1A16D9A83D3EE7D8CACE727A99C882EE649F87BD52E9EEE47 1 054704706B95A154F5AFC3FBB536D38DC9DCB9702EA0BFDCCB2E36A3AA23F3EC', + }, + }, + maxCredNum: 666, + tailsLocation: 'https://my.revocations.tails/tailsfile.txt', + tailsHash: '91zvq2cFmBZmHCcLqFyzv7bfehHH5rMhdAG5wTjqy2PE', + }, + }) + + const revocationStatusListResponse = await cheqdAnonCredsRegistry.getRevocationStatusList( + agent.context, + revocationRegistryId, + 1680789403 + ) + + expect(revocationStatusListResponse.revocationStatusList).toMatchObject({ + revRegDefId: `${revocationRegistryId}&resourceType=anonCredsRevocRegDef`, + revocationList: [ + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ], + currentAccumulator: + '21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C', + }) + }) +}) diff --git a/packages/cheqd/tests/setup.ts b/packages/cheqd/tests/setup.ts new file mode 100644 index 0000000000..9af7086f02 --- /dev/null +++ b/packages/cheqd/tests/setup.ts @@ -0,0 +1,33 @@ +jest.setTimeout(60000) + +import { DidDocument, DidDocumentService, VerificationMethod } from '@aries-framework/core' + +export const validDid = 'did:cheqd:testnet:SiVQgrFZ7jFZFrTGstT4ZD' + +export function validVerificationMethod(did: string) { + return new VerificationMethod({ + id: did + '#key-1', + type: 'Ed25519VerificationKey2020', + controller: did, + publicKeyMultibase: 'z6MkkBaWtQKyx7Mr54XaXyMAEpNKqphK4x7ztuBpSfR6Wqwr', + }) +} + +export function validService(did: string) { + return new DidDocumentService({ + id: did + '#service-1', + type: 'DIDCommMessaging', + serviceEndpoint: 'https://rand.io', + }) +} + +export function validDidDoc() { + const service = [validService(validDid)] + const verificationMethod = [validVerificationMethod(validDid)] + + return new DidDocument({ + id: validDid, + verificationMethod, + service, + }) +} diff --git a/packages/cheqd/tests/setupCheqdModule.ts b/packages/cheqd/tests/setupCheqdModule.ts new file mode 100644 index 0000000000..0e095b3aa7 --- /dev/null +++ b/packages/cheqd/tests/setupCheqdModule.ts @@ -0,0 +1,33 @@ +import type { CheqdModuleConfigOptions } from '../src' + +import { DidsModule, KeyDidRegistrar, KeyDidResolver } from '@aries-framework/core' +import { IndySdkModule, IndySdkModuleConfig } from '@aries-framework/indy-sdk' +import indySdk from 'indy-sdk' + +import { CheqdModule, CheqdDidRegistrar, CheqdDidResolver } from '../src' + +export const getIndySdkModuleConfig = () => + new IndySdkModuleConfig({ + indySdk, + }) + +export const getCheqdModuleConfig = (seed?: string) => + ({ + networks: [ + { + network: 'testnet', + cosmosPayerSeed: + seed || + 'sketch mountain erode window enact net enrich smoke claim kangaroo another visual write meat latin bacon pulp similar forum guilt father state erase bright', + }, + ], + } satisfies CheqdModuleConfigOptions) + +export const getCheqdModules = (seed?: string) => ({ + cheqdSdk: new CheqdModule(getCheqdModuleConfig(seed)), + dids: new DidsModule({ + registrars: [new CheqdDidRegistrar(), new KeyDidRegistrar()], + resolvers: [new CheqdDidResolver(), new KeyDidResolver()], + }), + indySdk: new IndySdkModule(getIndySdkModuleConfig()), +}) diff --git a/packages/cheqd/tsconfig.build.json b/packages/cheqd/tsconfig.build.json new file mode 100644 index 0000000000..2b75d0adab --- /dev/null +++ b/packages/cheqd/tsconfig.build.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.build.json", + "compilerOptions": { + "outDir": "./build" + }, + "include": ["src/**/*"] +} diff --git a/packages/cheqd/tsconfig.json b/packages/cheqd/tsconfig.json new file mode 100644 index 0000000000..7958700c2b --- /dev/null +++ b/packages/cheqd/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "types": ["jest"], + "moduleResolution": "node", + "resolveJsonModule": true + } +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 3ffd7de1f4..9a159f0eb7 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -75,10 +75,11 @@ export { Hasher } from './utils/Hasher' export { MessageValidator } from './utils/MessageValidator' export { LinkedAttachment, LinkedAttachmentOptions } from './utils/LinkedAttachment' import { parseInvitationUrl } from './utils/parseInvitation' -import { uuid } from './utils/uuid' +import { uuid, isValidUuid } from './utils/uuid' const utils = { uuid, + isValidUuid, parseInvitationUrl, } diff --git a/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts b/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts index c66b4fc7aa..0b654c1a53 100644 --- a/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts +++ b/packages/core/src/modules/dids/domain/key-type/__tests__/ed25519.test.ts @@ -55,6 +55,7 @@ describe('ed25519', () => { expect(keyDidEd25519.supportedVerificationMethodTypes).toMatchObject([ 'Ed25519VerificationKey2018', 'Ed25519VerificationKey2020', + 'JsonWebKey2020', ]) }) diff --git a/packages/core/src/modules/dids/domain/key-type/ed25519.ts b/packages/core/src/modules/dids/domain/key-type/ed25519.ts index 5058accff3..cee29095e6 100644 --- a/packages/core/src/modules/dids/domain/key-type/ed25519.ts +++ b/packages/core/src/modules/dids/domain/key-type/ed25519.ts @@ -1,13 +1,14 @@ import type { KeyDidMapping } from './keyDidMapping' +import type { Jwk } from '../../../../crypto' import type { VerificationMethod } from '../verificationMethod' import { convertPublicKeyToX25519 } from '@stablelib/ed25519' -import { KeyType } from '../../../../crypto' -import { Key } from '../../../../crypto/Key' +import { Key, KeyType } from '../../../../crypto' export const VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018 = 'Ed25519VerificationKey2018' export const VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020 = 'Ed25519VerificationKey2020' +export const VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020 = 'JsonWebKey2020' export function getEd25519VerificationMethod({ key, id, controller }: { id: string; key: Key; controller: string }) { return { @@ -22,6 +23,7 @@ export const keyDidEd25519: KeyDidMapping = { supportedVerificationMethodTypes: [ VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2018, VERIFICATION_METHOD_TYPE_ED25519_VERIFICATION_KEY_2020, + VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020, ], getVerificationMethods: (did, key) => [ getEd25519VerificationMethod({ id: `${did}#${key.fingerprint}`, key, controller: did }), @@ -39,6 +41,9 @@ export const keyDidEd25519: KeyDidMapping = { ) { return Key.fromFingerprint(verificationMethod.publicKeyMultibase) } + if (verificationMethod.type === VERIFICATION_METHOD_TYPE_JSON_WEB_KEY_2020 && verificationMethod.publicKeyJwk) { + return Key.fromJwk(verificationMethod.publicKeyJwk as unknown as Jwk) + } throw new Error('Invalid verification method passed') }, diff --git a/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts b/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts index f8c2077310..a5ac4eff54 100644 --- a/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts +++ b/packages/core/src/modules/routing/services/__tests__/MediationRecipientService.test.ts @@ -13,7 +13,6 @@ import { ConnectionRepository } from '../../../connections/repository/Connection import { ConnectionService } from '../../../connections/services/ConnectionService' import { DidRepository } from '../../../dids/repository/DidRepository' import { DidRegistrarService } from '../../../dids/services/DidRegistrarService' -import { MediationRecipientModuleConfig } from '../../MediationRecipientModuleConfig' import { RoutingEventTypes } from '../../RoutingEvents' import { KeylistUpdateAction, diff --git a/packages/core/src/utils/TypedArrayEncoder.ts b/packages/core/src/utils/TypedArrayEncoder.ts index 83ee5d89ca..b98a5350c2 100644 --- a/packages/core/src/utils/TypedArrayEncoder.ts +++ b/packages/core/src/utils/TypedArrayEncoder.ts @@ -48,6 +48,24 @@ export class TypedArrayEncoder { return Buffer.from(decodeFromBase58(base58)) } + /** + * Encode buffer into base64 string. + * + * @param buffer the buffer to encode into base64 string + */ + public static toHex(buffer: Buffer | Uint8Array) { + return Buffer.from(buffer).toString('hex') + } + + /** + * Decode hex string into buffer + * + * @param hex the hex string to decode into buffer format + */ + public static fromHex(hex: string) { + return Buffer.from(hex, 'hex') + } + /** * Decode string into buffer. * diff --git a/packages/core/src/utils/uuid.ts b/packages/core/src/utils/uuid.ts index 77a29fd525..a6dd97a7f2 100644 --- a/packages/core/src/utils/uuid.ts +++ b/packages/core/src/utils/uuid.ts @@ -1,5 +1,9 @@ -import { v4 } from 'uuid' +import { v4, validate } from 'uuid' export function uuid() { return v4() } + +export function isValidUuid(id: string) { + return validate(id) +} diff --git a/yarn.lock b/yarn.lock index bbad52ea17..165f1ed715 100644 --- a/yarn.lock +++ b/yarn.lock @@ -750,6 +750,159 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== +"@cheqd/sdk@cjs": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@cheqd/sdk/-/sdk-3.3.1.tgz#6ca44df56b28e3f8a4918b49115de0f10c01eed7" + integrity sha512-8qPWGaD8Mc/pEFdJh/Tz9/YFbOvxFMpFKOI8xGalQAcv+KCIs/qKqPCkcxBNquqR4MAWe2ovCWOXGPmx0IrNxQ== + dependencies: + "@cheqd/ts-proto" cjs + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stargate" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + "@stablelib/ed25519" "^1.0.3" + cosmjs-types "^0.5.2" + did-jwt "^6.11.6" + did-resolver "^4.1.0" + multiformats "^9.9.0" + uuid "^9.0.0" + +"@cheqd/ts-proto@cjs": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cheqd/ts-proto/-/ts-proto-2.2.0.tgz#c296a9fff23f47fba84f9c3354439b8fc91129f4" + integrity sha512-COTDndE/haSUPndVYaJGAVT4OMIrVSibGfLrKol9CXZBasmUUJx5rVFOpL34wYq6VcOrfF2TN+63TRePRUBWpA== + dependencies: + long "^5.2.1" + protobufjs "^7.2.3" + +"@confio/ics23@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" + integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== + dependencies: + "@noble/hashes" "^1.0.0" + protobufjs "^6.8.8" + +"@cosmjs/amino@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.29.5.tgz#053b4739a90b15b9e2b781ccd484faf64bd49aec" + integrity sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + +"@cosmjs/crypto@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.29.5.tgz#ab99fc382b93d8a8db075780cf07487a0f9519fd" + integrity sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ== + dependencies: + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers "^0.7.6" + +"@cosmjs/encoding@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2" + integrity sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + +"@cosmjs/json-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz#5e483a9bd98a6270f935adf0dfd8a1e7eb777fe4" + integrity sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w== + dependencies: + "@cosmjs/stream" "^0.29.5" + xstream "^11.14.0" + +"@cosmjs/math@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.29.5.tgz#722c96e080d6c2b62215ce9f4c70da7625b241b6" + integrity sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q== + dependencies: + bn.js "^5.2.0" + +"@cosmjs/proto-signing@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz#af3b62a46c2c2f1d2327d678b13b7262db1fe87c" + integrity sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA== + dependencies: + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + +"@cosmjs/socket@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.29.5.tgz#a48df6b4c45dc6a6ef8e47232725dd4aa556ac2d" + integrity sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ== + dependencies: + "@cosmjs/stream" "^0.29.5" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + +"@cosmjs/stargate@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.29.5.tgz#d597af1c85a3c2af7b5bdbec34d5d40692cc09e4" + integrity sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + protobufjs "~6.11.3" + xstream "^11.14.0" + +"@cosmjs/stream@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.29.5.tgz#350981cac496d04939b92ee793b9b19f44bc1d4e" + integrity sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA== + dependencies: + xstream "^11.14.0" + +"@cosmjs/tendermint-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" + integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/json-rpc" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/socket" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + axios "^0.21.2" + readonly-date "^1.0.0" + xstream "^11.14.0" + +"@cosmjs/utils@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" + integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -1341,6 +1494,11 @@ resolved "https://registry.yarnpkg.com/@multiformats/base-x/-/base-x-4.0.1.tgz#95ff0fa58711789d53aefb2590a8b7a4e715d121" integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== +"@noble/hashes@^1", "@noble/hashes@^1.0.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" + integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1778,6 +1936,59 @@ tiny-glob "^0.2.9" tslib "^2.4.0" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + "@react-native-community/cli-clean@^10.1.1": version "10.1.1" resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz#4c73ce93a63a24d70c0089d4025daac8184ff504" @@ -2025,6 +2236,11 @@ dependencies: jwt-decode "^3.1.2" +"@stablelib/aead@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" + integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== + "@stablelib/binary@^1.0.0", "@stablelib/binary@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" @@ -2032,6 +2248,36 @@ dependencies: "@stablelib/int" "^1.0.1" +"@stablelib/bytes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== + +"@stablelib/chacha20poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" + integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== + dependencies: + "@stablelib/aead" "^1.0.1" + "@stablelib/binary" "^1.0.1" + "@stablelib/chacha" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/poly1305" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/chacha@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" + integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/constant-time@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== + "@stablelib/ed25519@^1.0.2", "@stablelib/ed25519@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" @@ -2051,6 +2297,21 @@ resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== +"@stablelib/keyagreement@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== + dependencies: + "@stablelib/bytes" "^1.0.1" + +"@stablelib/poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + "@stablelib/random@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.0.tgz#f441495075cdeaa45de16d7ddcc269c0b8edb16b" @@ -2090,6 +2351,35 @@ resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== +"@stablelib/x25519@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== + dependencies: + "@stablelib/keyagreement" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/xchacha20@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/xchacha20/-/xchacha20-1.0.1.tgz#e98808d1f7d8b20e3ff37c71a3062a2a955d9a8c" + integrity sha512-1YkiZnFF4veUwBVhDnDYwo6EHeKzQK4FnLiO7ezCl/zu64uG0bCCAUROJaBkaLH+5BEsO3W7BTXTguMbSLlWSw== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/chacha" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/xchacha20poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/xchacha20poly1305/-/xchacha20poly1305-1.0.1.tgz#addcaf30b92dd956f76b3357888e2f91b92e7a61" + integrity sha512-B1Abj0sMJ8h3HNmGnJ7vHBrAvxuNka6cJJoZ1ILN7iuacXp7sUYcgOVEOTLWj+rtQMpspY9tXSCRLPmN1mQNWg== + dependencies: + "@stablelib/aead" "^1.0.1" + "@stablelib/chacha20poly1305" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + "@stablelib/xchacha20" "^1.0.1" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -2240,7 +2530,7 @@ dependencies: "@types/node" "*" -"@types/indy-sdk@1.16.26", "@types/indy-sdk@^1.16.26": +"@types/indy-sdk@*", "@types/indy-sdk@1.16.26", "@types/indy-sdk@^1.16.26": version "1.16.26" resolved "https://registry.yarnpkg.com/@types/indy-sdk/-/indy-sdk-1.16.26.tgz#871f82c3f7d241d649aff5eb6800048890efb8f8" integrity sha512-KlnjsVsX/7yTmyyIlHWcytlBHoQ1vPGeiLnLv5y1vDftL6OQ5V+hebfAr7d3roMEsjCTH3qKkklwGcj1qS90YA== @@ -2292,6 +2582,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + "@types/luxon@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.2.0.tgz#99901b4ab29a5fdffc88fff59b3b47fbfbe0557b" @@ -2320,7 +2615,7 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@^16.11.7": +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^16.11.7": version "16.18.16" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.16.tgz#09ff98b144abae2d7cce3e9fe9040ab2bf73222c" integrity sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA== @@ -2961,6 +3256,13 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== +axios@^0.21.2: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + axios@^1.0.0: version "1.3.4" resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" @@ -3146,6 +3448,16 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bech32@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + +bech32@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-2.0.0.tgz#078d3686535075c8c79709f054b1b226a133b355" + integrity sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg== + before-after-hook@^2.2.0: version "2.2.3" resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" @@ -3184,7 +3496,12 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bn.js@^5.2.1: +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== @@ -3258,6 +3575,11 @@ braces@^3.0.2: dependencies: fill-range "^7.0.1" +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + browserslist@^4.21.3, browserslist@^4.21.5: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" @@ -3461,6 +3783,11 @@ canonicalize@^1.0.1: resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== +canonicalize@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-2.0.0.tgz#32be2cef4446d67fd5348027a384cae28f17226a" + integrity sha512-ulDEYPv7asdKvqahuAY35c1selLdzDwHqugK92hfkzvlDCwXRRelDkR+Er33md/PtnpqHemgkuDPanZ4fiYZ8w== + chalk@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -3536,7 +3863,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -class-validator@0.14.0: +class-validator@0.14.0, class-validator@^0.14.0: version "0.14.0" resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.0.tgz#40ed0ecf3c83b2a8a6a320f4edb607be0f0df159" integrity sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A== @@ -4009,6 +4336,14 @@ cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmjs-types@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.5.2.tgz#2d42b354946f330dfb5c90a87fdc2a36f97b965d" + integrity sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg== + dependencies: + long "^4.0.0" + protobufjs "~6.11.2" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -4252,6 +4587,24 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" +did-jwt@^6.11.6: + version "6.11.6" + resolved "https://registry.yarnpkg.com/did-jwt/-/did-jwt-6.11.6.tgz#3eeb30d6bd01f33bfa17089574915845802a7d44" + integrity sha512-OfbWknRxJuUqH6Lk0x+H1FsuelGugLbBDEwsoJnicFOntIG/A4y19fn0a8RLxaQbWQ5gXg0yDq5E2huSBiiXzw== + dependencies: + "@stablelib/ed25519" "^1.0.2" + "@stablelib/random" "^1.0.1" + "@stablelib/sha256" "^1.0.1" + "@stablelib/x25519" "^1.0.2" + "@stablelib/xchacha20poly1305" "^1.0.1" + bech32 "^2.0.0" + canonicalize "^2.0.0" + did-resolver "^4.0.0" + elliptic "^6.5.4" + js-sha3 "^0.8.0" + multiformats "^9.6.5" + uint8arrays "^3.0.0" + did-resolver@^4.0.0, did-resolver@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/did-resolver/-/did-resolver-4.1.0.tgz#740852083c4fd5bf9729d528eca5d105aff45eb6" @@ -4329,6 +4682,19 @@ electron-to-chromium@^1.4.284: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.333.tgz#ebb21f860f8a29923717b06ec0cb54e77ed34c04" integrity sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ== +elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + emittery@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" @@ -5149,7 +5515,7 @@ flow-parser@^0.185.0: resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.2.tgz#cb7ee57f77377d6c5d69a469e980f6332a15e492" integrity sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ== -follow-redirects@^1.15.0: +follow-redirects@^1.14.0, follow-redirects@^1.15.0: version "1.15.2" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== @@ -5534,7 +5900,7 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: +globalthis@^1.0.1, globalthis@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== @@ -5695,6 +6061,14 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + hermes-estree@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.8.0.tgz#530be27243ca49f008381c1f3e8b18fb26bf9ec0" @@ -5714,6 +6088,15 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -6363,6 +6746,11 @@ isomorphic-webcrypto@^2.3.8: expo-random "*" react-native-securerandom "^0.1.1" +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" @@ -6843,6 +7231,11 @@ js-sdsl@^4.1.4: resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== +js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -7156,6 +7549,18 @@ libphonenumber-js@^1.10.14: resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.24.tgz#a1744cf29df86d5a587562ea28dde12320eb6ab6" integrity sha512-3Dk8f5AmrcWqg+oHhmm9hwSTqpWHBdSqsHmjCJGroULFubi0+x7JEIGmRZCuL3TI8Tx39xaKqfnhsDQ4ALa/Nw== +libsodium-wrappers@^0.7.6: + version "0.7.11" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz#53bd20606dffcc54ea2122133c7da38218f575f7" + integrity sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q== + dependencies: + libsodium "^0.7.11" + +libsodium@^0.7.11: + version "0.7.11" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.11.tgz#cd10aae7bcc34a300cc6ad0ac88fcca674cfbc2e" + integrity sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A== + lines-and-columns@^1.1.6: version "1.2.4" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" @@ -7268,6 +7673,16 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@^5.0.0, long@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.1.tgz#e27595d0083d103d2fa2c20c7699f8e0c92b897f" + integrity sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A== + loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -7785,6 +8200,16 @@ min-indent@^1.0.0: resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + minimatch@3.0.5: version "3.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" @@ -7974,7 +8399,7 @@ msrcrypto@^1.5.6: resolved "https://registry.yarnpkg.com/msrcrypto/-/msrcrypto-1.5.8.tgz#be419be4945bf134d8af52e9d43be7fa261f4a1c" integrity sha512-ujZ0TRuozHKKm6eGbKHfXef7f+esIhEckmThVnz7RNyiOJd7a6MXj2JGBoL9cnPDW+JMG16MoTUh5X+XXjI66Q== -multiformats@^9.4.2: +multiformats@^9.4.2, multiformats@^9.6.5, multiformats@^9.9.0: version "9.9.0" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== @@ -9092,6 +9517,43 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== +protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + +protobufjs@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.3.tgz#01af019e40d9c6133c49acbb3ff9e30f4f0f70b2" + integrity sha512-TtpvOqwB5Gdz/PQmOjgsrGH1nHjAQVCN7JG4A6r1sXRWESL5rNMAiRcBQlCAdKxZcAbstExQePYG8xof/JVRgg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/node" ">=13.7.0" + long "^5.0.0" + protocols@^2.0.0, protocols@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" @@ -9428,6 +9890,11 @@ readline@^1.3.0: resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" integrity sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg== +readonly-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" + integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== + recast@^0.20.4: version "0.20.5" resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" @@ -9637,6 +10104,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^4.0.7: + version "4.4.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" + integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== + dependencies: + glob "^9.2.0" + rimraf@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.0.tgz#c7a9f45bb2ec058d2e60ef9aca5167974313d605" @@ -10287,6 +10761,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + synckit@^0.8.4: version "0.8.5" resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" @@ -10691,7 +11170,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -"typescript@^3 || ^4", typescript@~4.9.5: +"typescript@^3 || ^4", typescript@~4.9.4, typescript@~4.9.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== @@ -10719,7 +11198,7 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -uint8arrays@^3.1.1: +uint8arrays@^3.0.0, uint8arrays@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== @@ -11160,6 +11639,14 @@ ws@^8.13.0: resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== +xstream@^11.14.0: + version "11.14.0" + resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" + integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== + dependencies: + globalthis "^1.0.1" + symbol-observable "^2.0.3" + xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"