From 4d389f7aa83af98c1cbf7b6b61ed60aae667f187 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Fri, 27 Jun 2025 18:01:40 +0700 Subject: [PATCH 01/22] spike: Feasibility of generating Signify types from Python type hints via OpenAI --- .gitignore | 3 + README.md | 6 ++ package.json | 3 +- scripts/generate-types.js | 32 +++++++ test-integration/openapi-type.test.ts | 125 ++++++++++++++++++++++++++ 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 scripts/generate-types.js create mode 100644 test-integration/openapi-type.test.ts diff --git a/.gitignore b/.gitignore index 421b39a5..ace817e0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ dist # IntelliJ Project Files .idea coverage/* + +# Keria API types +src/types \ No newline at end of file diff --git a/README.md b/README.md index e5b5dd67..fee4e067 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,12 @@ Typescript source files needs to be transpiled before running scripts or integra npm run build ``` + To build and generate TypeScript types from KERIA OpenAPI docs dynamically + + ``` + SPEC_URL=http://localhost:3902/spec.yaml npm run build + ``` + - ready() must be called before library is useable. Example minimum viable client code. ```javascript diff --git a/package.json b/package.json index e7feae32..fc2ae03c 100644 --- a/package.json +++ b/package.json @@ -31,7 +31,8 @@ ], "scripts": { "start": "npm run build -- --watch", - "build": "tsc -p tsconfig.build.json && tsc -p tsconfig.json --noEmit", + "generate:types": "node scripts/generate-types.js", + "build": "npm run generate:types && tsc -p tsconfig.build.json && tsc -p tsconfig.json --noEmit", "test": "vitest", "prepare": "tsc -p tsconfig.build.json", "test:integration": "vitest -c vitest.integration.ts", diff --git a/scripts/generate-types.js b/scripts/generate-types.js new file mode 100644 index 00000000..19706401 --- /dev/null +++ b/scripts/generate-types.js @@ -0,0 +1,32 @@ +import { execSync } from "child_process"; +import fs from "fs"; +import path from "path"; + +const specUrl = process.env.SPEC_URL; +const outputFile = path.resolve("src/types/keria-api-schema.ts"); + +if (!specUrl) { + console.log("⚠️ Skipping OpenAPI type generation: SPEC_URL is not set."); + process.exit(0); +} + +console.log(`📦 Generating types from ${specUrl}`); +execSync(`npx openapi-typescript "${specUrl}" --output ${outputFile}`, { + stdio: "inherit", +}); + +// Read the full file +const fullContent = fs.readFileSync(outputFile, "utf8"); + +// Extract only the `export interface components { ... }` block +const match = fullContent.match(/export interface components \{[\s\S]+?\n\}/); + +if (!match) { + console.error("❌ Could not find 'export interface components' block."); + process.exit(1); +} + +// Add comment header +const cleaned = `// AUTO-GENERATED: Only components retained from OpenAPI schema\n\n${match[0]}\n`; + +fs.writeFileSync(outputFile, cleaned, "utf8"); diff --git a/test-integration/openapi-type.test.ts b/test-integration/openapi-type.test.ts new file mode 100644 index 00000000..cb77ca2a --- /dev/null +++ b/test-integration/openapi-type.test.ts @@ -0,0 +1,125 @@ +import { assert, describe, test } from 'vitest'; +import { EventResult, SignifyClient } from 'signify-ts'; +import { + getOrCreateClients, + waitOperation, +} from './utils/test-util.ts'; +import { resolveEnvironment } from './utils/resolve-env.ts'; +import { components } from '../src/types/keria-api-schema.ts'; + + +type IdentifierCreateResponse = components["schemas"]["IdentifierCreateResponse"]; +type ResponseUnion = components["schemas"]["ResponseUnion"]; +type OpMetadata = components["schemas"]["OpMetadata"]; +type OpResponseKel = components["schemas"]["OpResponseKel"]; + + +function isOpResponseKel(obj: any): obj is OpResponseKel { + return ( + typeof obj === "object" && + obj !== null && + (obj.a === undefined || Array.isArray(obj.a)) && + Array.isArray(obj.b) && + typeof obj.bt === "string" && + (obj.c === undefined || Array.isArray(obj.c)) && + typeof obj.d === "string" && + typeof obj.i === "string" && + Array.isArray(obj.k) && + typeof obj.kt === "string" && + Array.isArray(obj.n) && + typeof obj.nt === "string" && + typeof obj.s === "string" && + typeof obj.t === "string" && + typeof obj.v === "string" + ); +} + +function isResponseUnion(obj: any): obj is ResponseUnion { + if (obj === null) return true; + if (typeof obj === "object") { + if (isOpResponseKel(obj)) return true; + if (Object.keys(obj).length === 0) return true; // empty object + } + return false; +} + +function isIdentifierCreateResponse(obj: any): obj is IdentifierCreateResponse { + if ( + typeof obj !== "object" || + obj === null || + typeof obj.done !== "boolean" || + typeof obj.name !== "string" + ) { + return false; + } + // Check optional metadata + if ("metadata" in obj && obj.metadata !== undefined && typeof obj.metadata !== "object") { + return false; + } + // Check optional response + if ("response" in obj && obj.response !== undefined && !isResponseUnion(obj.response)) { + return false; + } + // Only allow expected keys + const allowedKeys = ["done", "metadata", "name", "response"]; + for (const key of Object.keys(obj)) { + if (!allowedKeys.includes(key)) { + return false; + } + } + return true; +} + +let client: SignifyClient; + +describe('test-setup-clients', async () => { + [client] = await getOrCreateClients(1); + + const env = resolveEnvironment(); + const kargs = { + toad: env.witnessIds.length, + wits: env.witnessIds, + }; + + test('should return IdentifierCreateResponse from waitOperation', async () => { + const result: EventResult = await client + .identifiers() + .create("name", kargs); + let op = await result.op(); + op = await waitOperation(client, op); + + console.log('Operation result:', op); + + if (!isIdentifierCreateResponse(op)) { + let errors: string[] = []; + if (typeof op !== "object" || op === null) { + errors.push(`op is not an object: ${JSON.stringify(op)}`); + } else { + if (typeof op.done !== "boolean") { + errors.push(`op.done is not boolean: ${JSON.stringify(op.done)}`); + } + if (typeof op.name !== "string") { + errors.push(`op.name is not string: ${JSON.stringify(op.name)}`); + } + if ("metadata" in op && op.metadata !== undefined && typeof op.metadata !== "object") { + errors.push(`op.metadata is not object or undefined: ${JSON.stringify(op.metadata)}`); + } + if ("response" in op && op.response !== undefined && !isResponseUnion(op.response)) { + errors.push(`op.response is not ResponseUnion: ${JSON.stringify(op.response)}`); + } + const allowedKeys = ["done", "metadata", "name", "response"]; + for (const key of Object.keys(op)) { + if (!allowedKeys.includes(key)) { + errors.push(`Unexpected key in op: ${key}`); + } + } + } + throw new Error("IdentifierCreateResponse check failed:\n" + errors.join("\n")); + } + + assert.equal(isIdentifierCreateResponse(op), true); + assert.typeOf(op.done, 'boolean'); + assert.typeOf(op.name, 'string'); + + }); +}); From 56a35f52c0e1c821456f549a35526f37da222eef Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Mon, 7 Jul 2025 17:55:43 +0700 Subject: [PATCH 02/22] add and use generated TS types --- src/keri/app/coring.ts | 10 +-- src/types/keria-api-schema.ts | 28 ++++++ test-integration/openapi-type.test.ts | 125 -------------------------- 3 files changed, 33 insertions(+), 130 deletions(-) create mode 100644 src/types/keria-api-schema.ts delete mode 100644 test-integration/openapi-type.test.ts diff --git a/src/keri/app/coring.ts b/src/keri/app/coring.ts index 6f7daaf4..987fc1cf 100644 --- a/src/keri/app/coring.ts +++ b/src/keri/app/coring.ts @@ -2,6 +2,9 @@ import { SignifyClient } from './clienting.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { Salter } from '../core/salter.ts'; import { Matter, MtrDex } from '../core/matter.ts'; +import { components } from '../../types/keria-api-schema.ts'; + +type OperationBase = components['schemas']['OperationBase']; export function randomPasscode(): string { const raw = libsodium.randombytes_buf(16); @@ -61,15 +64,12 @@ export class Oobis { } } -export interface Operation { - name: string; +export type Operation = OperationBase & { + response?: T; metadata?: { depends?: Operation; [property: string]: any; }; - done?: boolean; - error?: any; - response?: T; } export interface OperationsDeps { diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts new file mode 100644 index 00000000..21769e0e --- /dev/null +++ b/src/types/keria-api-schema.ts @@ -0,0 +1,28 @@ +// AUTO-GENERATED: Only components retained from OpenAPI schema + +export interface components { + schemas: { + StatusSchema: { + code: number; + message: string; + /** @default null */ + details: { + [key: string]: unknown; + } | null; + }; + OperationBase: { + name: string; + done?: boolean; + error?: boolean; + }; + Operation: components["schemas"]["OperationBase"] & { + metadata?: Record; + response?: Record; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; +} diff --git a/test-integration/openapi-type.test.ts b/test-integration/openapi-type.test.ts deleted file mode 100644 index cb77ca2a..00000000 --- a/test-integration/openapi-type.test.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { assert, describe, test } from 'vitest'; -import { EventResult, SignifyClient } from 'signify-ts'; -import { - getOrCreateClients, - waitOperation, -} from './utils/test-util.ts'; -import { resolveEnvironment } from './utils/resolve-env.ts'; -import { components } from '../src/types/keria-api-schema.ts'; - - -type IdentifierCreateResponse = components["schemas"]["IdentifierCreateResponse"]; -type ResponseUnion = components["schemas"]["ResponseUnion"]; -type OpMetadata = components["schemas"]["OpMetadata"]; -type OpResponseKel = components["schemas"]["OpResponseKel"]; - - -function isOpResponseKel(obj: any): obj is OpResponseKel { - return ( - typeof obj === "object" && - obj !== null && - (obj.a === undefined || Array.isArray(obj.a)) && - Array.isArray(obj.b) && - typeof obj.bt === "string" && - (obj.c === undefined || Array.isArray(obj.c)) && - typeof obj.d === "string" && - typeof obj.i === "string" && - Array.isArray(obj.k) && - typeof obj.kt === "string" && - Array.isArray(obj.n) && - typeof obj.nt === "string" && - typeof obj.s === "string" && - typeof obj.t === "string" && - typeof obj.v === "string" - ); -} - -function isResponseUnion(obj: any): obj is ResponseUnion { - if (obj === null) return true; - if (typeof obj === "object") { - if (isOpResponseKel(obj)) return true; - if (Object.keys(obj).length === 0) return true; // empty object - } - return false; -} - -function isIdentifierCreateResponse(obj: any): obj is IdentifierCreateResponse { - if ( - typeof obj !== "object" || - obj === null || - typeof obj.done !== "boolean" || - typeof obj.name !== "string" - ) { - return false; - } - // Check optional metadata - if ("metadata" in obj && obj.metadata !== undefined && typeof obj.metadata !== "object") { - return false; - } - // Check optional response - if ("response" in obj && obj.response !== undefined && !isResponseUnion(obj.response)) { - return false; - } - // Only allow expected keys - const allowedKeys = ["done", "metadata", "name", "response"]; - for (const key of Object.keys(obj)) { - if (!allowedKeys.includes(key)) { - return false; - } - } - return true; -} - -let client: SignifyClient; - -describe('test-setup-clients', async () => { - [client] = await getOrCreateClients(1); - - const env = resolveEnvironment(); - const kargs = { - toad: env.witnessIds.length, - wits: env.witnessIds, - }; - - test('should return IdentifierCreateResponse from waitOperation', async () => { - const result: EventResult = await client - .identifiers() - .create("name", kargs); - let op = await result.op(); - op = await waitOperation(client, op); - - console.log('Operation result:', op); - - if (!isIdentifierCreateResponse(op)) { - let errors: string[] = []; - if (typeof op !== "object" || op === null) { - errors.push(`op is not an object: ${JSON.stringify(op)}`); - } else { - if (typeof op.done !== "boolean") { - errors.push(`op.done is not boolean: ${JSON.stringify(op.done)}`); - } - if (typeof op.name !== "string") { - errors.push(`op.name is not string: ${JSON.stringify(op.name)}`); - } - if ("metadata" in op && op.metadata !== undefined && typeof op.metadata !== "object") { - errors.push(`op.metadata is not object or undefined: ${JSON.stringify(op.metadata)}`); - } - if ("response" in op && op.response !== undefined && !isResponseUnion(op.response)) { - errors.push(`op.response is not ResponseUnion: ${JSON.stringify(op.response)}`); - } - const allowedKeys = ["done", "metadata", "name", "response"]; - for (const key of Object.keys(op)) { - if (!allowedKeys.includes(key)) { - errors.push(`Unexpected key in op: ${key}`); - } - } - } - throw new Error("IdentifierCreateResponse check failed:\n" + errors.join("\n")); - } - - assert.equal(isIdentifierCreateResponse(op), true); - assert.typeOf(op.done, 'boolean'); - assert.typeOf(op.name, 'string'); - - }); -}); From c003c1bd7d398b4a96ed19faae2656e02afab89b Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Tue, 8 Jul 2025 18:06:43 +0700 Subject: [PATCH 03/22] demo generated types for credentials().get() --- .gitignore | 2 - src/keri/app/credentialing.ts | 16 ++++- src/types/keria-api-schema.ts | 99 ++++++++++++++++++++++++++++ test-integration/credentials.test.ts | 13 +++- 4 files changed, 124 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index ace817e0..c659f56c 100644 --- a/.gitignore +++ b/.gitignore @@ -8,5 +8,3 @@ dist .idea coverage/* -# Keria API types -src/types \ No newline at end of file diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 9c342da0..6f802925 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -22,6 +22,10 @@ import { import { Operation } from './coring.ts'; import { HabState } from '../core/keyState.ts'; +import { components } from '../../types/keria-api-schema.ts'; + +type CredentialResult = components['schemas']['CredentialSchema']; + /** Types of credentials */ export class CredentialTypes { static issued = 'issued'; @@ -287,6 +291,8 @@ export class Credentials { return await res.json(); } + + /** * Get a credential * @async @@ -294,7 +300,7 @@ export class Credentials { * @param {boolean} [includeCESR=false] - Optional flag export the credential in CESR format * @returns {Promise} A promise to the credential */ - async get(said: string, includeCESR: boolean = false): Promise { + async get(said: string, includeCESR: boolean = false): Promise { const path = `/credentials/${said}`; const method = 'GET'; const headers = includeCESR @@ -302,7 +308,13 @@ export class Credentials { : new Headers({ Accept: 'application/json' }); const res = await this.client.fetch(path, method, null, headers); - return includeCESR ? await res.text() : await res.json(); + if (includeCESR) { + const text = await res.text(); + // If CESR is JSON, parse it: + return JSON.parse(text) as CredentialResult; + } else { + return await res.json(); + } } /** diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 21769e0e..a6bcf3fd 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -2,6 +2,105 @@ export interface components { schemas: { + SADAttributes: { + d: string; + i: string; + LEI: string; + dt: string; + }; + SADSchema: { + v: string; + d: string; + i: string; + ri: string; + s: string; + a: components["schemas"]["SADAttributes"]; + u?: boolean; + e?: boolean; + r?: boolean; + }; + SADAttributesSchema: { + d: string; + i: string; + LEI: string; + dt: string; + }; + ISSSchema: { + v: string; + t: string; + d: string; + i: string; + s: string; + ri: string; + dt: string; + }; + SchemaSchema: { + $id: string; + $schema: string; + title: string; + description: string; + type: string; + credentialType: string; + version: string; + properties: { + [key: string]: unknown; + }; + additionalProperties: boolean; + required: string[]; + }; + StatusAnchorSchema: { + s: number; + d: string; + }; + CredentialStatusSchema: { + vn: number[]; + i: string; + s: string; + d: string; + ri: string; + ra: { + [key: string]: unknown; + }; + a: components["schemas"]["StatusAnchorSchema"]; + dt: string; + et: string; + }; + AnchorSchema: { + pre: string; + sn: number; + d: string; + }; + SealSchema: { + i: string; + s: string; + d: string; + t?: boolean; + p?: boolean; + }; + ANCSchema: { + v: string; + t: string; + d: string; + i: string; + s: string; + p: string; + a: components["schemas"]["SealSchema"][]; + }; + CredentialSchema: { + sad: components["schemas"]["SADSchema"]; + atc: string; + iss: components["schemas"]["ISSSchema"]; + issAtc: string; + pre: string; + schema: components["schemas"]["SchemaSchema"]; + chains: { + [key: string]: unknown; + }[]; + status: components["schemas"]["CredentialStatusSchema"]; + anchor: components["schemas"]["AnchorSchema"]; + anc: components["schemas"]["ANCSchema"]; + ancAttachment: string; + }; StatusSchema: { code: number; message: string; diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index 42e5d04e..16ead390 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -138,6 +138,8 @@ test('single signature credentials', { timeout: 90000 }, async () => { const issuerLeSchema = await issuerClient.schemas().get(LE_SCHEMA_SAID); + console.log('issuerLeSchema', issuerLeSchema); + assert.equal(issuerLeSchema.$id, LE_SCHEMA_SAID); }); @@ -427,7 +429,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { anc: new Serder(holderCredential.anc), iss: new Serder(holderCredential.iss), acdcAttachment: holderCredential.atc, - ancAttachment: holderCredential.ancatc, + ancAttachment: holderCredential.ancAttachment, issAttachment: holderCredential.issAtc, agreeSaid: agreeSaid, datetime: createTimestamp(), @@ -474,6 +476,8 @@ test('single signature credentials', { timeout: 90000 }, async () => { verifierClient.credentials().get(qviCredentialId) ); + console.log('verifierCredential from credentials().get', verifierCredential); + assert.equal(verifierCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(verifierCredential.sad.i, issuerAid.prefix); assert.equal(verifierCredential.status.s, '0'); // 0 = issued @@ -607,11 +611,16 @@ test('single signature credentials', { timeout: 90000 }, async () => { legalEntityClient.credentials().get(leCredentialId) ); + console.log('legalEntityCredential from credentials().get', legalEntityCredential); + assert.equal(legalEntityCredential.sad.s, LE_SCHEMA_SAID); assert.equal(legalEntityCredential.sad.i, holderAid.prefix); assert.equal(legalEntityCredential.sad.a.i, legalEntityAid.prefix); assert.equal(legalEntityCredential.status.s, '0'); - assert.equal(legalEntityCredential.chains[0].sad.d, qviCredentialId); + assert(Array.isArray(legalEntityCredential.chains)); + assert(legalEntityCredential.chains.length > 0); + const firstChain = legalEntityCredential.chains[0] as { sad: { d: string } }; + assert.equal(firstChain.sad.d, qviCredentialId); assert(legalEntityCredential.atc !== undefined); }); From 8016535d3b5878829212bb814731c861cbf0c9c8 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Wed, 9 Jul 2025 18:32:36 +0700 Subject: [PATCH 04/22] update types for CredentialState --- src/keri/app/credentialing.ts | 24 +++-------- src/types/keria-api-schema.ts | 64 +++++++++++++++++++++------- test-integration/credentials.test.ts | 5 ++- 3 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 6f802925..2ce57f48 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -25,6 +25,8 @@ import { HabState } from '../core/keyState.ts'; import { components } from '../../types/keria-api-schema.ts'; type CredentialResult = components['schemas']['CredentialSchema']; +type CredentialStateIssOrRev = components['schemas']['CredentialStateIssOrRevSchema']; +type CredentialStateBisOrBrv = components['schemas']['CredentialStateBisOrBrvSchema']; /** Types of credentials */ export class CredentialTypes { @@ -233,25 +235,9 @@ export interface IpexAdmitArgs { datetime?: string; } -export type CredentialState = { - vn: [number, number]; - i: string; - s: string; - d: string; - ri: string; - a: { s: number; d: string }; - dt: string; - et: string; -} & ( - | { - et: 'iss' | 'rev'; - ra: Record; - } - | { - et: 'bis' | 'brv'; - ra: { i: string; s: string; d: string }; - } -); + +export type CredentialState = CredentialStateIssOrRev | CredentialStateBisOrBrv; + /** * Credentials diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index a6bcf3fd..8074b1af 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -2,28 +2,24 @@ export interface components { schemas: { - SADAttributes: { - d: string; - i: string; - LEI: string; - dt: string; - }; SADSchema: { v: string; d: string; i: string; - ri: string; s: string; - a: components["schemas"]["SADAttributes"]; - u?: boolean; - e?: boolean; - r?: boolean; + ri?: string; + a?: { + [key: string]: unknown; + }; + u?: string; + e?: unknown[]; + r?: unknown[]; }; SADAttributesSchema: { d: string; - i: string; LEI: string; dt: string; + i?: string; }; ISSSchema: { v: string; @@ -71,11 +67,11 @@ export interface components { d: string; }; SealSchema: { - i: string; s: string; d: string; - t?: boolean; - p?: boolean; + i?: string; + t?: string; + p?: string; }; ANCSchema: { v: string; @@ -96,11 +92,16 @@ export interface components { chains: { [key: string]: unknown; }[]; - status: components["schemas"]["CredentialStatusSchema"]; + status: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; anchor: components["schemas"]["AnchorSchema"]; anc: components["schemas"]["ANCSchema"]; ancAttachment: string; }; + OperationBaseSchema: { + name: string; + done?: boolean; + error?: boolean; + }; StatusSchema: { code: number; message: string; @@ -114,6 +115,37 @@ export interface components { done?: boolean; error?: boolean; }; + CredentialStateIssOrRevSchema: { + vn: unknown; + i: string; + s: string; + d: string; + ri: string; + a: components["schemas"]["SealSchema"]; + dt: string; + /** @enum {unknown} */ + et: "iss" | "rev"; + ra: { + [key: string]: unknown; + }; + }; + RaFields: { + i: string; + s: string; + d: string; + }; + CredentialStateBisOrBrvSchema: { + vn: unknown; + i: string; + s: string; + d: string; + ri: string; + a: components["schemas"]["SealSchema"]; + dt: string; + /** @enum {unknown} */ + et: "bis" | "brv"; + ra: components["schemas"]["RaFields"]; + }; Operation: components["schemas"]["OperationBase"] & { metadata?: Record; response?: Record; diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index 16ead390..767afe9a 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -615,7 +615,10 @@ test('single signature credentials', { timeout: 90000 }, async () => { assert.equal(legalEntityCredential.sad.s, LE_SCHEMA_SAID); assert.equal(legalEntityCredential.sad.i, holderAid.prefix); - assert.equal(legalEntityCredential.sad.a.i, legalEntityAid.prefix); + assert.equal(legalEntityCredential.sad.a !== undefined, true); + if (legalEntityCredential.sad.a) { + assert.equal(legalEntityCredential.sad.a.i, legalEntityAid.prefix); + } assert.equal(legalEntityCredential.status.s, '0'); assert(Array.isArray(legalEntityCredential.chains)); assert(legalEntityCredential.chains.length > 0); From 1679dc679af29d9d41d6d094063fe15f1d80edbb Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Thu, 10 Jul 2025 15:28:58 +0700 Subject: [PATCH 05/22] resolve review comments --- scripts/generate-types.js | 22 ++++++------ src/keri/app/coring.ts | 2 +- src/keri/app/credentialing.ts | 27 ++++++--------- src/types/keria-api-schema.ts | 5 ++- test-integration/credentials.test.ts | 52 ++++++++++++++++------------ 5 files changed, 55 insertions(+), 53 deletions(-) diff --git a/scripts/generate-types.js b/scripts/generate-types.js index 19706401..037e5187 100644 --- a/scripts/generate-types.js +++ b/scripts/generate-types.js @@ -1,32 +1,32 @@ -import { execSync } from "child_process"; -import fs from "fs"; -import path from "path"; +import { execSync } from 'child_process'; +import fs from 'fs'; +import path from 'path'; const specUrl = process.env.SPEC_URL; -const outputFile = path.resolve("src/types/keria-api-schema.ts"); +const outputFile = path.resolve('src/types/keria-api-schema.ts'); if (!specUrl) { - console.log("⚠️ Skipping OpenAPI type generation: SPEC_URL is not set."); - process.exit(0); + console.log('⚠️ Skipping OpenAPI type generation: SPEC_URL is not set.'); + process.exit(0); } console.log(`📦 Generating types from ${specUrl}`); execSync(`npx openapi-typescript "${specUrl}" --output ${outputFile}`, { - stdio: "inherit", + stdio: 'inherit', }); // Read the full file -const fullContent = fs.readFileSync(outputFile, "utf8"); +const fullContent = fs.readFileSync(outputFile, 'utf8'); // Extract only the `export interface components { ... }` block const match = fullContent.match(/export interface components \{[\s\S]+?\n\}/); if (!match) { - console.error("❌ Could not find 'export interface components' block."); - process.exit(1); + console.error("❌ Could not find 'export interface components' block."); + process.exit(1); } // Add comment header const cleaned = `// AUTO-GENERATED: Only components retained from OpenAPI schema\n\n${match[0]}\n`; -fs.writeFileSync(outputFile, cleaned, "utf8"); +fs.writeFileSync(outputFile, cleaned, 'utf8'); diff --git a/src/keri/app/coring.ts b/src/keri/app/coring.ts index 987fc1cf..6eafd9e0 100644 --- a/src/keri/app/coring.ts +++ b/src/keri/app/coring.ts @@ -70,7 +70,7 @@ export type Operation = OperationBase & { depends?: Operation; [property: string]: any; }; -} +}; export interface OperationsDeps { fetch( diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 2ce57f48..d616f3a2 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -24,9 +24,11 @@ import { HabState } from '../core/keyState.ts'; import { components } from '../../types/keria-api-schema.ts'; -type CredentialResult = components['schemas']['CredentialSchema']; -type CredentialStateIssOrRev = components['schemas']['CredentialStateIssOrRevSchema']; -type CredentialStateBisOrBrv = components['schemas']['CredentialStateBisOrBrvSchema']; +export type CredentialResult = components['schemas']['CredentialSchema']; +type CredentialStateIssOrRev = + components['schemas']['CredentialStateIssOrRevSchema']; +type CredentialStateBisOrBrv = + components['schemas']['CredentialStateBisOrBrvSchema']; /** Types of credentials */ export class CredentialTypes { @@ -235,10 +237,8 @@ export interface IpexAdmitArgs { datetime?: string; } - export type CredentialState = CredentialStateIssOrRev | CredentialStateBisOrBrv; - /** * Credentials */ @@ -277,8 +277,6 @@ export class Credentials { return await res.json(); } - - /** * Get a credential * @async @@ -286,7 +284,10 @@ export class Credentials { * @param {boolean} [includeCESR=false] - Optional flag export the credential in CESR format * @returns {Promise} A promise to the credential */ - async get(said: string, includeCESR: boolean = false): Promise { + async get( + said: string, + includeCESR: boolean = false + ): Promise { const path = `/credentials/${said}`; const method = 'GET'; const headers = includeCESR @@ -294,13 +295,7 @@ export class Credentials { : new Headers({ Accept: 'application/json' }); const res = await this.client.fetch(path, method, null, headers); - if (includeCESR) { - const text = await res.text(); - // If CESR is JSON, parse it: - return JSON.parse(text) as CredentialResult; - } else { - return await res.json(); - } + return includeCESR ? await res.text() : await res.json(); } /** @@ -435,7 +430,7 @@ export class Credentials { const dt = datetime ?? new Date().toISOString().replace('Z', '000+00:00'); - const cred = await this.get(said); + const cred = (await this.get(said)) as CredentialResult; // Create rev const _rev = { diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 8074b1af..63c06e51 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -115,6 +115,7 @@ export interface components { done?: boolean; error?: boolean; }; + EmptyDict: Record; CredentialStateIssOrRevSchema: { vn: unknown; i: string; @@ -125,9 +126,7 @@ export interface components { dt: string; /** @enum {unknown} */ et: "iss" | "rev"; - ra: { - [key: string]: unknown; - }; + ra: components["schemas"]["EmptyDict"]; }; RaFields: { i: string; diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index 767afe9a..d89d98e2 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -15,7 +15,7 @@ import { import { retry } from './utils/retry.ts'; import { randomUUID } from 'node:crypto'; import { step } from './utils/test-step.ts'; - +import { CredentialResult } from '../src/keri/app/credentialing.ts'; const { vleiServerUrl } = resolveEnvironment(); const QVI_SCHEMA_SAID = 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao'; @@ -228,9 +228,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { }); await step('issuer get credential by id', async () => { - const issuerCredential = await issuerClient + const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; assert.equal(issuerCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(issuerCredential.sad.i, issuerAid.prefix); assert.equal(issuerCredential.status.s, '0'); @@ -238,9 +238,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('issuer IPEX grant', async () => { const dt = createTimestamp(); - const issuerCredential = await issuerClient + const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; assert(issuerCredential !== undefined); const [grant, gsigs, gend] = await issuerClient.ipex().grant({ @@ -305,9 +305,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('holder has credential', async () => { const holderCredential = await retry(async () => { - const result = await holderClient + const result = (await holderClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; assert(result !== undefined); return result; }); @@ -418,9 +418,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { await markAndRemoveNotification(holderClient, holderAgreeNote); - const holderCredential = await holderClient + const holderCredential = (await holderClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; const [grant2, gsigs2, gend2] = await holderClient.ipex().grant({ senderName: holderAid.name, @@ -472,11 +472,14 @@ test('single signature credentials', { timeout: 90000 }, async () => { await markAndRemoveNotification(verifierClient, verifierGrantNote); - const verifierCredential = await retry(async () => + const verifierCredential = (await retry(async () => verifierClient.credentials().get(qviCredentialId) - ); + )) as CredentialResult; - console.log('verifierCredential from credentials().get', verifierCredential); + console.log( + 'verifierCredential from credentials().get', + verifierCredential + ); assert.equal(verifierCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(verifierCredential.sad.i, issuerAid.prefix); @@ -512,9 +515,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { const leCredentialId = await step( 'holder create LE (chained) credential', async () => { - const qviCredential = await holderClient + const qviCredential = (await holderClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; const result = await holderClient .credentials() @@ -550,9 +553,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('LE credential IPEX grant', async () => { const dt = createTimestamp(); - const leCredential = await holderClient + const leCredential = (await holderClient .credentials() - .get(leCredentialId); + .get(leCredentialId)) as CredentialResult; assert(leCredential !== undefined); const [grant, gsigs, gend] = await holderClient.ipex().grant({ @@ -607,11 +610,14 @@ test('single signature credentials', { timeout: 90000 }, async () => { }); await step('Legal Entity has chained credential', async () => { - const legalEntityCredential = await retry(async () => + const legalEntityCredential = (await retry(async () => legalEntityClient.credentials().get(leCredentialId) - ); + )) as CredentialResult; - console.log('legalEntityCredential from credentials().get', legalEntityCredential); + console.log( + 'legalEntityCredential from credentials().get', + legalEntityCredential + ); assert.equal(legalEntityCredential.sad.s, LE_SCHEMA_SAID); assert.equal(legalEntityCredential.sad.i, holderAid.prefix); @@ -622,7 +628,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { assert.equal(legalEntityCredential.status.s, '0'); assert(Array.isArray(legalEntityCredential.chains)); assert(legalEntityCredential.chains.length > 0); - const firstChain = legalEntityCredential.chains[0] as { sad: { d: string } }; + const firstChain = legalEntityCredential.chains[0] as { + sad: { d: string }; + }; assert.equal(firstChain.sad.d, qviCredentialId); assert(legalEntityCredential.atc !== undefined); }); @@ -633,9 +641,9 @@ test('single signature credentials', { timeout: 90000 }, async () => { .revoke(issuerAid.name, qviCredentialId); await waitOperation(issuerClient, revokeOperation.op); - const issuerCredential = await issuerClient + const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId); + .get(qviCredentialId)) as CredentialResult; assert.equal(issuerCredential.status.s, '1'); }); From 98b637f85814ae8c18bb52ddf085a3e448c00aa6 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Fri, 11 Jul 2025 18:06:41 +0700 Subject: [PATCH 06/22] fix credentials types + add registries's types --- src/keri/app/credentialing.ts | 9 +++++---- src/types/keria-api-schema.ts | 6 ++++++ test-integration/credentials.test.ts | 6 +----- test-integration/multisig-vlei-issuance.test.ts | 3 +++ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index d616f3a2..bd006fd2 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -25,6 +25,7 @@ import { HabState } from '../core/keyState.ts'; import { components } from '../../types/keria-api-schema.ts'; export type CredentialResult = components['schemas']['CredentialSchema']; +export type Registry = components['schemas']['RegistrySchema']; type CredentialStateIssOrRev = components['schemas']['CredentialStateIssOrRevSchema']; type CredentialStateBisOrBrv = @@ -258,7 +259,7 @@ export class Credentials { * @param {CredentialFilter} [kargs] Optional parameters to filter the credentials * @returns {Promise} A promise to the list of credentials */ - async list(kargs: CredentialFilter = {}): Promise { + async list(kargs: CredentialFilter = {}): Promise { const path = `/credentials/query`; const filtr = kargs.filter === undefined ? {} : kargs.filter; const sort = kargs.sort === undefined ? [] : kargs.sort; @@ -545,7 +546,7 @@ export class RegistryResult { return this._sigs; } - async op(): Promise { + async op(): Promise { const res = await this.promise; return await res.json(); } @@ -570,7 +571,7 @@ export class Registries { * @param {string} name Name or alias of the identifier * @returns {Promise} A promise to the list of registries */ - async list(name: string): Promise { + async list(name: string): Promise { const path = `/identifiers/${name}/registries`; const method = 'GET'; const res = await this.client.fetch(path, method, null); @@ -679,7 +680,7 @@ export class Registries { name: string, registryName: string, newName: string - ): Promise { + ): Promise { const path = `/identifiers/${name}/registries/${registryName}`; const method = 'PUT'; const data = { diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 63c06e51..3c813aec 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -149,6 +149,12 @@ export interface components { metadata?: Record; response?: Record; }; + RegistrySchema: { + name: string; + regk: string; + pre: string; + state: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; + }; }; responses: never; parameters: never; diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index d89d98e2..20907dfe 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -170,6 +170,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('issuer list credentials', async () => { const issuerCredentials = await issuerClient.credentials().list(); + assertLength(issuerCredentials, 1); assert(issuerCredentials.length >= 1); assert.equal(issuerCredentials[0].sad.s, QVI_SCHEMA_SAID); assert.equal(issuerCredentials[0].sad.i, issuerAid.prefix); @@ -476,11 +477,6 @@ test('single signature credentials', { timeout: 90000 }, async () => { verifierClient.credentials().get(qviCredentialId) )) as CredentialResult; - console.log( - 'verifierCredential from credentials().get', - verifierCredential - ); - assert.equal(verifierCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(verifierCredential.sad.i, issuerAid.prefix); assert.equal(verifierCredential.status.s, '0'); // 0 = issued diff --git a/test-integration/multisig-vlei-issuance.test.ts b/test-integration/multisig-vlei-issuance.test.ts index c1775279..662fea4f 100644 --- a/test-integration/multisig-vlei-issuance.test.ts +++ b/test-integration/multisig-vlei-issuance.test.ts @@ -609,6 +609,7 @@ test('multisig-vlei-issuance', async function run() { assert.equal(qviCredbyGAR1.sad.d, qviCredbyGAR2.sad.d); assert.equal(qviCredbyGAR1.sad.s, QVI_SCHEMA_SAID); assert.equal(qviCredbyGAR1.sad.i, aidGEDA.prefix); + assert(qviCredbyGAR1.sad.a !== undefined, "qviCredbyGAR1.sad.a is undefined"); assert.equal(qviCredbyGAR1.sad.a.i, aidQVI.prefix); assert.equal(qviCredbyGAR1.status.s, '0'); assert(qviCredbyGAR1.atc !== undefined); @@ -986,6 +987,7 @@ test('multisig-vlei-issuance', async function run() { assert.equal(leCredbyQAR1.sad.d, leCredbyQAR3.sad.d); assert.equal(leCredbyQAR1.sad.s, LE_SCHEMA_SAID); assert.equal(leCredbyQAR1.sad.i, aidQVI.prefix); + assert(leCredbyQAR1.sad.a !== undefined, "leCredbyQAR1.sad.a is undefined"); assert.equal(leCredbyQAR1.sad.a.i, aidLE.prefix); assert.equal(leCredbyQAR1.status.s, '0'); assert(leCredbyQAR1.atc !== undefined); @@ -1234,6 +1236,7 @@ test('multisig-vlei-issuance', async function run() { assert.equal(ecrCredbyLAR1.sad.d, ecrCredbyLAR3.sad.d); assert.equal(ecrCredbyLAR1.sad.s, ECR_SCHEMA_SAID); assert.equal(ecrCredbyLAR1.sad.i, aidLE.prefix); + assert(ecrCredbyLAR1.sad.a !== undefined, "ecrCredbyLAR1.sad.a is undefined"); assert.equal(ecrCredbyLAR1.sad.a.i, aidECR.prefix); assert.equal(ecrCredbyLAR1.status.s, '0'); assert(ecrCredbyLAR1.atc !== undefined); From 508b1eb88b8a131382e33ff7e334505d32cddf88 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Mon, 14 Jul 2025 17:25:54 +0700 Subject: [PATCH 07/22] Add more types for credentialing --- src/keri/app/credentialing.ts | 25 +++++++++++-------------- src/types/keria-api-schema.ts | 3 ++- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index bd006fd2..6fb0376a 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -26,10 +26,7 @@ import { components } from '../../types/keria-api-schema.ts'; export type CredentialResult = components['schemas']['CredentialSchema']; export type Registry = components['schemas']['RegistrySchema']; -type CredentialStateIssOrRev = - components['schemas']['CredentialStateIssOrRevSchema']; -type CredentialStateBisOrBrv = - components['schemas']['CredentialStateBisOrBrvSchema']; +export type Schema = components['schemas']['SchemaSchema']; /** Types of credentials */ export class CredentialTypes { @@ -238,7 +235,7 @@ export interface IpexAdmitArgs { datetime?: string; } -export type CredentialState = CredentialStateIssOrRev | CredentialStateBisOrBrv; +export type CredentialState = components['schemas']['CredentialStateSchema']; /** * Credentials @@ -257,7 +254,7 @@ export class Credentials { * List credentials * @async * @param {CredentialFilter} [kargs] Optional parameters to filter the credentials - * @returns {Promise} A promise to the list of credentials + * @returns {Promise} A promise to the list of credentials */ async list(kargs: CredentialFilter = {}): Promise { const path = `/credentials/query`; @@ -283,7 +280,7 @@ export class Credentials { * @async * @param {string} said - SAID of the credential * @param {boolean} [includeCESR=false] - Optional flag export the credential in CESR format - * @returns {Promise} A promise to the credential + * @returns {Promise} A promise to the credential */ async get( said: string, @@ -417,7 +414,7 @@ export class Credentials { * @param {string} name Name or alias of the identifier * @param {string} said SAID of the credential * @param {string} datetime date time of revocation - * @returns {Promise} A promise to the long-running operation + * @returns {Promise} A promise to the long-running operation */ async revoke( name: string, @@ -569,7 +566,7 @@ export class Registries { * List registries * @async * @param {string} name Name or alias of the identifier - * @returns {Promise} A promise to the list of registries + * @returns {Promise} A promise to the list of registries */ async list(name: string): Promise { const path = `/identifiers/${name}/registries`; @@ -674,7 +671,7 @@ export class Registries { * @param {string} name Name or alias of the identifier * @param {string} registryName Current registry name * @param {string} newName New registry name - * @returns {Promise} A promise to the registry record + * @returns {Promise} A promise to the registry record */ async rename( name: string, @@ -707,9 +704,9 @@ export class Schemas { * Get a schema * @async * @param {string} said SAID of the schema - * @returns {Promise} A promise to the schema + * @returns {Promise} A promise to the schema */ - async get(said: string): Promise { + async get(said: string): Promise { const path = `/schema/${said}`; const method = 'GET'; const res = await this.client.fetch(path, method, null); @@ -719,9 +716,9 @@ export class Schemas { /** * List schemas * @async - * @returns {Promise} A promise to the list of schemas + * @returns {Promise} A promise to the list of schemas */ - async list(): Promise { + async list(): Promise { const path = `/schema`; const method = 'GET'; const res = await this.client.fetch(path, method, null); diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 3c813aec..bbdc9450 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -149,11 +149,12 @@ export interface components { metadata?: Record; response?: Record; }; + CredentialStateSchema: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; RegistrySchema: { name: string; regk: string; pre: string; - state: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; + state: components["schemas"]["CredentialStateSchema"]; }; }; responses: never; From 0663bbe615a414f10ee652ed2c23a327eb01290f Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Wed, 16 Jul 2025 15:09:54 +0700 Subject: [PATCH 08/22] resolve review comments --- src/keri/app/credentialing.ts | 8 +-- src/types/keria-api-schema.ts | 85 +++++++++++++++------------- test-integration/credentials.test.ts | 9 +-- 3 files changed, 55 insertions(+), 47 deletions(-) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 6fb0376a..062f25f9 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -24,9 +24,9 @@ import { HabState } from '../core/keyState.ts'; import { components } from '../../types/keria-api-schema.ts'; -export type CredentialResult = components['schemas']['CredentialSchema']; -export type Registry = components['schemas']['RegistrySchema']; -export type Schema = components['schemas']['SchemaSchema']; +export type CredentialResult = components['schemas']['Credential']; +export type Registry = components['schemas']['Registry']; +export type Schema = components['schemas']['Schema']; /** Types of credentials */ export class CredentialTypes { @@ -235,7 +235,7 @@ export interface IpexAdmitArgs { datetime?: string; } -export type CredentialState = components['schemas']['CredentialStateSchema']; +export type CredentialState = components['schemas']['CredentialState']; /** * Credentials diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index bbdc9450..af3ee722 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -2,7 +2,7 @@ export interface components { schemas: { - SADSchema: { + ACDC: { v: string; d: string; i: string; @@ -15,13 +15,14 @@ export interface components { e?: unknown[]; r?: unknown[]; }; - SADAttributesSchema: { - d: string; - LEI: string; - dt: string; + ACDCAttributes: { + dt?: string; i?: string; + u?: string; + } & { + [key: string]: unknown; }; - ISSSchema: { + IssEvt: { v: string; t: string; d: string; @@ -30,7 +31,7 @@ export interface components { ri: string; dt: string; }; - SchemaSchema: { + Schema: { $id: string; $schema: string; title: string; @@ -44,11 +45,11 @@ export interface components { additionalProperties: boolean; required: string[]; }; - StatusAnchorSchema: { + StatusAnchor: { s: number; d: string; }; - CredentialStatusSchema: { + CredentialStatus: { vn: number[]; i: string; s: string; @@ -57,50 +58,61 @@ export interface components { ra: { [key: string]: unknown; }; - a: components["schemas"]["StatusAnchorSchema"]; + a: components["schemas"]["StatusAnchor"]; dt: string; et: string; }; - AnchorSchema: { + Anchor: { pre: string; sn: number; d: string; }; - SealSchema: { + Seal: { s: string; d: string; i?: string; - t?: string; - p?: string; }; - ANCSchema: { + ANC: { v: string; t: string; d: string; i: string; s: string; p: string; - a: components["schemas"]["SealSchema"][]; + di?: string; + a?: unknown[]; + }; + CredentialStateBase: { + vn: unknown; + i: string; + s: string; + d: string; + ri: string; + a: components["schemas"]["Seal"]; + dt: string; + et: string; }; - CredentialSchema: { - sad: components["schemas"]["SADSchema"]; + Credential: { + sad: components["schemas"]["ACDC"]; atc: string; - iss: components["schemas"]["ISSSchema"]; - issAtc: string; + iss: components["schemas"]["IssEvt"]; + issatc: string; pre: string; - schema: components["schemas"]["SchemaSchema"]; + schema: components["schemas"]["Schema"]; chains: { [key: string]: unknown; }[]; - status: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; - anchor: components["schemas"]["AnchorSchema"]; - anc: components["schemas"]["ANCSchema"]; - ancAttachment: string; + status: components["schemas"]["CredentialState"]; + anchor: components["schemas"]["Anchor"]; + anc: components["schemas"]["ANC"]; + ancatc: string; }; - OperationBaseSchema: { + OperationBase: { name: string; done?: boolean; - error?: boolean; + error?: { + [key: string]: unknown; + }; }; StatusSchema: { code: number; @@ -110,19 +122,14 @@ export interface components { [key: string]: unknown; } | null; }; - OperationBase: { - name: string; - done?: boolean; - error?: boolean; - }; EmptyDict: Record; - CredentialStateIssOrRevSchema: { + CredentialStateIssOrRev: { vn: unknown; i: string; s: string; d: string; ri: string; - a: components["schemas"]["SealSchema"]; + a: components["schemas"]["Seal"]; dt: string; /** @enum {unknown} */ et: "iss" | "rev"; @@ -133,28 +140,28 @@ export interface components { s: string; d: string; }; - CredentialStateBisOrBrvSchema: { + CredentialStateBisOrBrv: { vn: unknown; i: string; s: string; d: string; ri: string; - a: components["schemas"]["SealSchema"]; + a: components["schemas"]["Seal"]; dt: string; /** @enum {unknown} */ et: "bis" | "brv"; ra: components["schemas"]["RaFields"]; }; + CredentialState: components["schemas"]["CredentialStateIssOrRev"] | components["schemas"]["CredentialStateBisOrBrv"]; Operation: components["schemas"]["OperationBase"] & { metadata?: Record; response?: Record; }; - CredentialStateSchema: components["schemas"]["CredentialStateIssOrRevSchema"] | components["schemas"]["CredentialStateBisOrBrvSchema"]; - RegistrySchema: { + Registry: { name: string; regk: string; pre: string; - state: components["schemas"]["CredentialStateSchema"]; + state: components["schemas"]["CredentialState"]; }; }; responses: never; diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index 20907dfe..c01fd3a6 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -232,6 +232,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const issuerCredential = (await issuerClient .credentials() .get(qviCredentialId)) as CredentialResult; + assert(issuerCredential !== undefined); assert.equal(issuerCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(issuerCredential.sad.i, issuerAid.prefix); assert.equal(issuerCredential.status.s, '0'); @@ -249,7 +250,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { acdc: new Serder(issuerCredential.sad), anc: new Serder(issuerCredential.anc), iss: new Serder(issuerCredential.iss), - ancAttachment: issuerCredential.ancAttachment, + ancAttachment: issuerCredential.ancatc, recipient: holderAid.prefix, datetime: dt, }); @@ -430,8 +431,8 @@ test('single signature credentials', { timeout: 90000 }, async () => { anc: new Serder(holderCredential.anc), iss: new Serder(holderCredential.iss), acdcAttachment: holderCredential.atc, - ancAttachment: holderCredential.ancAttachment, - issAttachment: holderCredential.issAtc, + ancAttachment: holderCredential.ancatc, + issAttachment: holderCredential.issatc, agreeSaid: agreeSaid, datetime: createTimestamp(), }); @@ -559,7 +560,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { acdc: new Serder(leCredential.sad), anc: new Serder(leCredential.anc), iss: new Serder(leCredential.iss), - ancAttachment: leCredential.ancAttachment, + ancAttachment: leCredential.ancatc, recipient: legalEntityAid.prefix, datetime: dt, }); From 025ed27c3051eff23a84d3a4b5cd715a03789f0e Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Wed, 16 Jul 2025 17:42:24 +0700 Subject: [PATCH 09/22] fix errors/warning for swagger validator --- src/types/keria-api-schema.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index af3ee722..c07b6f0a 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -117,8 +117,7 @@ export interface components { StatusSchema: { code: number; message: string; - /** @default null */ - details: { + details?: { [key: string]: unknown; } | null; }; From 63ed79945f3246470b6f0c1e28cdeb3b80150182 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Thu, 17 Jul 2025 17:29:31 +0700 Subject: [PATCH 10/22] re-generate types --- src/types/keria-api-schema.ts | 37 +++++++++++++++++------------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index c07b6f0a..ad80eb95 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -24,7 +24,8 @@ export interface components { }; IssEvt: { v: string; - t: string; + /** @enum {unknown} */ + t: "iss" | "bis"; d: string; i: string; s: string; @@ -82,16 +83,6 @@ export interface components { di?: string; a?: unknown[]; }; - CredentialStateBase: { - vn: unknown; - i: string; - s: string; - d: string; - ri: string; - a: components["schemas"]["Seal"]; - dt: string; - et: string; - }; Credential: { sad: components["schemas"]["ACDC"]; atc: string; @@ -107,20 +98,18 @@ export interface components { anc: components["schemas"]["ANC"]; ancatc: string; }; - OperationBase: { - name: string; - done?: boolean; - error?: { - [key: string]: unknown; - }; - }; - StatusSchema: { + OperationStatus: { code: number; message: string; details?: { [key: string]: unknown; } | null; }; + OperationBase: { + name: string; + error?: components["schemas"]["OperationStatus"]; + done?: boolean; + }; EmptyDict: Record; CredentialStateIssOrRev: { vn: unknown; @@ -156,6 +145,16 @@ export interface components { metadata?: Record; response?: Record; }; + CredentialStateBase: { + vn: unknown; + i: string; + s: string; + d: string; + ri: string; + a: components["schemas"]["Seal"]; + dt: string; + et: string; + }; Registry: { name: string; regk: string; From 8b4c712af452814b01500cfd45286e4f9390e44e Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Fri, 18 Jul 2025 11:25:15 +0700 Subject: [PATCH 11/22] re-generate types --- src/types/keria-api-schema.ts | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index ad80eb95..3b3df4bd 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -2,26 +2,24 @@ export interface components { schemas: { + ACDCAttributes: { + dt?: string; + i?: string; + u?: string; + } & { + [key: string]: unknown; + }; ACDC: { v: string; d: string; i: string; s: string; ri?: string; - a?: { - [key: string]: unknown; - }; + a?: components["schemas"]["ACDCAttributes"]; u?: string; e?: unknown[]; r?: unknown[]; }; - ACDCAttributes: { - dt?: string; - i?: string; - u?: string; - } & { - [key: string]: unknown; - }; IssEvt: { v: string; /** @enum {unknown} */ @@ -81,7 +79,7 @@ export interface components { s: string; p: string; di?: string; - a?: unknown[]; + a?: components["schemas"]["Seal"][]; }; Credential: { sad: components["schemas"]["ACDC"]; @@ -145,16 +143,6 @@ export interface components { metadata?: Record; response?: Record; }; - CredentialStateBase: { - vn: unknown; - i: string; - s: string; - d: string; - ri: string; - a: components["schemas"]["Seal"]; - dt: string; - et: string; - }; Registry: { name: string; regk: string; From 911318dfe2fa49ba2af70a00d62e5d78ec7acd54 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Fri, 18 Jul 2025 15:36:25 +0700 Subject: [PATCH 12/22] remove debug logs and add multiple overload signatures --- src/keri/app/credentialing.ts | 5 ++++- test-integration/credentials.test.ts | 26 +++++++++----------------- 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 062f25f9..cdb7d184 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -282,6 +282,9 @@ export class Credentials { * @param {boolean} [includeCESR=false] - Optional flag export the credential in CESR format * @returns {Promise} A promise to the credential */ + async get(said: string): Promise; + async get(said: string, includeCESR: false): Promise; + async get(said: string, includeCESR: true): Promise; async get( said: string, includeCESR: boolean = false @@ -428,7 +431,7 @@ export class Credentials { const dt = datetime ?? new Date().toISOString().replace('Z', '000+00:00'); - const cred = (await this.get(said)) as CredentialResult; + const cred = (await this.get(said)); // Create rev const _rev = { diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index c01fd3a6..37a45ad6 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -138,8 +138,6 @@ test('single signature credentials', { timeout: 90000 }, async () => { const issuerLeSchema = await issuerClient.schemas().get(LE_SCHEMA_SAID); - console.log('issuerLeSchema', issuerLeSchema); - assert.equal(issuerLeSchema.$id, LE_SCHEMA_SAID); }); @@ -231,7 +229,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('issuer get credential by id', async () => { const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); assert(issuerCredential !== undefined); assert.equal(issuerCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(issuerCredential.sad.i, issuerAid.prefix); @@ -242,7 +240,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const dt = createTimestamp(); const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); assert(issuerCredential !== undefined); const [grant, gsigs, gend] = await issuerClient.ipex().grant({ @@ -309,7 +307,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const holderCredential = await retry(async () => { const result = (await holderClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); assert(result !== undefined); return result; }); @@ -422,7 +420,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const holderCredential = (await holderClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); const [grant2, gsigs2, gend2] = await holderClient.ipex().grant({ senderName: holderAid.name, @@ -476,7 +474,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const verifierCredential = (await retry(async () => verifierClient.credentials().get(qviCredentialId) - )) as CredentialResult; + )); assert.equal(verifierCredential.sad.s, QVI_SCHEMA_SAID); assert.equal(verifierCredential.sad.i, issuerAid.prefix); @@ -514,7 +512,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { async () => { const qviCredential = (await holderClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); const result = await holderClient .credentials() @@ -552,7 +550,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { const dt = createTimestamp(); const leCredential = (await holderClient .credentials() - .get(leCredentialId)) as CredentialResult; + .get(leCredentialId)); assert(leCredential !== undefined); const [grant, gsigs, gend] = await holderClient.ipex().grant({ @@ -609,13 +607,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { await step('Legal Entity has chained credential', async () => { const legalEntityCredential = (await retry(async () => legalEntityClient.credentials().get(leCredentialId) - )) as CredentialResult; - - console.log( - 'legalEntityCredential from credentials().get', - legalEntityCredential - ); - + )); assert.equal(legalEntityCredential.sad.s, LE_SCHEMA_SAID); assert.equal(legalEntityCredential.sad.i, holderAid.prefix); assert.equal(legalEntityCredential.sad.a !== undefined, true); @@ -640,7 +632,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { await waitOperation(issuerClient, revokeOperation.op); const issuerCredential = (await issuerClient .credentials() - .get(qviCredentialId)) as CredentialResult; + .get(qviCredentialId)); assert.equal(issuerCredential.status.s, '1'); }); From 84d5c3d57b0aea3e64475084c102511d329b0322 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Thu, 7 Aug 2025 18:25:44 +0700 Subject: [PATCH 13/22] aiding.py type hints and auto-generated OpenAPI specs --- scripts/generate-types.js | 16 +- src/keri/app/aiding.ts | 2 +- src/keri/app/clienting.ts | 7 +- src/keri/app/contacting.ts | 13 +- src/keri/app/controller.ts | 3 +- src/keri/app/coring.ts | 3 +- src/keri/app/escrowing.ts | 7 +- src/keri/core/keeping.ts | 2 +- src/keri/core/keyState.ts | 84 +----- src/keri/core/manager.ts | 3 +- src/keri/core/salter.ts | 9 +- src/types/keria-api-schema.ts | 380 +++++++++++++++++++++++- test-integration/challenge.test.ts | 5 +- test-integration/delegation.test.ts | 5 +- test-integration/externalModule.test.ts | 3 +- test-integration/randy.test.ts | 3 +- test-integration/salty.test.ts | 3 +- test-integration/utils/test-setup.ts | 2 +- test-integration/utils/test-util.ts | 2 +- test-integration/witness.test.ts | 3 +- test/app/aiding.test.ts | 2 +- test/app/clienting.test.ts | 2 +- test/app/contacting.test.ts | 2 +- test/app/controller.test.ts | 3 +- test/app/coring.test.ts | 2 +- test/app/credentialing.test.ts | 2 +- test/app/delegating.test.ts | 2 +- test/app/escrowing.test.ts | 2 +- test/app/exchanging.test.ts | 2 +- test/app/grouping.test.ts | 2 +- test/app/notifying.test.ts | 2 +- test/app/test-utils.ts | 2 +- test/core/manager.test.ts | 3 +- test/core/serder.test.ts | 3 +- test/end/ending.test.ts | 3 +- 35 files changed, 458 insertions(+), 131 deletions(-) diff --git a/scripts/generate-types.js b/scripts/generate-types.js index 037e5187..33a88671 100644 --- a/scripts/generate-types.js +++ b/scripts/generate-types.js @@ -11,22 +11,26 @@ if (!specUrl) { } console.log(`📦 Generating types from ${specUrl}`); -execSync(`npx openapi-typescript "${specUrl}" --output ${outputFile}`, { +execSync(`npx openapi-typescript "${specUrl}" --output ${outputFile} --enum`, { stdio: 'inherit', }); // Read the full file const fullContent = fs.readFileSync(outputFile, 'utf8'); -// Extract only the `export interface components { ... }` block -const match = fullContent.match(/export interface components \{[\s\S]+?\n\}/); +// Extract the `export interface components { ... }` block +const componentsMatch = fullContent.match(/export interface components \{[\s\S]+?\n\}/); -if (!match) { +// Extract all `export enum ... { ... }` blocks +const enumMatches = [...fullContent.matchAll(/export enum [\w\d_]+ \{[\s\S]+?\n\}/g)]; + +if (!componentsMatch) { console.error("❌ Could not find 'export interface components' block."); process.exit(1); } -// Add comment header -const cleaned = `// AUTO-GENERATED: Only components retained from OpenAPI schema\n\n${match[0]}\n`; +// Combine the interface and enums +const enumsText = enumMatches.map(m => m[0]).join('\n\n'); +const cleaned = `// AUTO-GENERATED: Only components and enums retained from OpenAPI schema\n\n${enumsText}\n\n${componentsMatch[0]}\n`; fs.writeFileSync(outputFile, cleaned, 'utf8'); diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index 6cfa9300..a39920a4 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -1,4 +1,4 @@ -import { Tier } from '../core/salter.ts'; +import { Tier} from '../../types/keria-api-schema.ts'; import { Algos } from '../core/manager.ts'; import { incept, interact, reply, rotate } from '../core/eventing.ts'; import { b, Ilks, Serials, Vrsn_1_0 } from '../core/core.ts'; diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index add940ba..8a3c8553 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -1,7 +1,7 @@ +import { components, Tier } from '../../types/keria-api-schema.ts'; import { Authenticater } from '../core/authing.ts'; import { HEADER_SIG_TIME } from '../core/httping.ts'; import { ExternalModule, IdentifierManagerFactory } from '../core/keeping.ts'; -import { Tier } from '../core/salter.ts'; import { Identifier } from './aiding.ts'; import { Contacts, Challenges } from './contacting.ts'; @@ -16,6 +16,9 @@ import { Notifications } from './notifying.ts'; const DEFAULT_BOOT_URL = 'http://localhost:3903'; +// Export type outside the class +export type AgentResourceResult = components["schemas"]["AgentResourceResult"]; + class State { agent: any | null; controller: any | null; @@ -117,7 +120,7 @@ export class SignifyClient { throw new Error(`agent does not exist for controller ${caid}`); } - const data = await res.json(); + const data = await res.json() as AgentResourceResult; const state = new State(); state.agent = data.agent ?? {}; state.controller = data.controller ?? {}; diff --git a/src/keri/app/contacting.ts b/src/keri/app/contacting.ts index 2af3e1ec..eecfdb09 100644 --- a/src/keri/app/contacting.ts +++ b/src/keri/app/contacting.ts @@ -1,12 +1,9 @@ import { SignifyClient } from './clienting.ts'; import { Operation } from './coring.ts'; +import { components } from '../../types/keria-api-schema.ts'; -export interface Contact { - alias: string; - oobi: string; - id: string; - [key: string]: unknown; -} + +export type Contact = components['schemas']['Contact']; export interface ContactInfo { [key: string]: unknown; @@ -111,9 +108,7 @@ export class Contacts { } } -export interface Challenge { - words: string[]; -} +export type Challenge = components['schemas']['Challenge']; /** * Challenges diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index 2495ee9e..d209e1de 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -1,5 +1,6 @@ import { SaltyCreator } from '../core/manager.ts'; -import { Salter, Tier } from '../core/salter.ts'; +import { Salter } from '../core/salter.ts'; +import { Tier} from '../../types/keria-api-schema.ts'; import { MtrDex } from '../core/matter.ts'; import { Diger } from '../core/diger.ts'; import { incept, rotate, interact } from '../core/eventing.ts'; diff --git a/src/keri/app/coring.ts b/src/keri/app/coring.ts index 6eafd9e0..c6070da0 100644 --- a/src/keri/app/coring.ts +++ b/src/keri/app/coring.ts @@ -5,6 +5,7 @@ import { Matter, MtrDex } from '../core/matter.ts'; import { components } from '../../types/keria-api-schema.ts'; type OperationBase = components['schemas']['OperationBase']; +type OOBI = components['schemas']['OOBI']; export function randomPasscode(): string { const raw = libsodium.randombytes_buf(16); @@ -36,7 +37,7 @@ export class Oobis { * @param {string} role Authorized role * @returns {Promise} A promise to the OOBI(s) */ - async get(name: string, role: string = 'agent'): Promise { + async get(name: string, role: string = 'agent'): Promise { const path = `/identifiers/${name}/oobis?role=${role}`; const method = 'GET'; const res = await this.client.fetch(path, method, null); diff --git a/src/keri/app/escrowing.ts b/src/keri/app/escrowing.ts index a72fbc02..bdfe4c86 100644 --- a/src/keri/app/escrowing.ts +++ b/src/keri/app/escrowing.ts @@ -1,5 +1,8 @@ import { SignifyClient } from './clienting.ts'; +import { components } from '../../types/keria-api-schema.ts'; + +export type Rpy = components['schemas']['Rpy']; /** * Escrows */ @@ -18,9 +21,9 @@ export class Escrows { * List replay messages * @async * @param {string} [route] Optional route in the replay message - * @returns {Promise} A promise to the list of replay messages + * @returns {Promise} A promise to the list of replay messages */ - async listReply(route?: string): Promise { + async listReply(route?: string): Promise { const params = new URLSearchParams(); if (route !== undefined) { params.append('route', route); diff --git a/src/keri/core/keeping.ts b/src/keri/core/keeping.ts index f1f669b4..0c2ff343 100644 --- a/src/keri/core/keeping.ts +++ b/src/keri/core/keeping.ts @@ -1,7 +1,7 @@ import { Salter } from './salter.ts'; import { Algos, SaltyCreator, RandyCreator } from './manager.ts'; import { MtrDex } from './matter.ts'; -import { Tier } from './salter.ts'; +import { Tier} from '../../types/keria-api-schema.ts'; import { Encrypter } from '../core/encrypter.ts'; import { Decrypter } from './decrypter.ts'; import { b } from './core.ts'; diff --git a/src/keri/core/keyState.ts b/src/keri/core/keyState.ts index f94e5a94..3d6c10da 100644 --- a/src/keri/core/keyState.ts +++ b/src/keri/core/keyState.ts @@ -1,30 +1,9 @@ -import { Algos } from './manager.ts'; -import { Tier } from './salter.ts'; +import { components } from '../../types/keria-api-schema.ts'; -export interface KeyState { - vn: [number, number]; - i: string; - s: string; - p?: string; - d: string; - f: string; - dt: string; - et: string; - kt: string | string[]; - k: string[]; - nt: string | string[]; - n: string[]; - bt: string; - b: string[]; - c: string[]; - ee: EstablishmentState; - di?: string; -} -export interface EstablishmentState { - d: string; - s: string; -} +export type KeyState = components['schemas']['KeyStateRecord']; + +export type EstablishmentState = components['schemas']['StateEERecord']; /** * Marker interface for state configuring an IdentifierManager. @@ -33,61 +12,26 @@ export interface EstablishmentState { export interface IdentifierManagerState {} /** - * Interface defining configuration parameters for a specified, deterministic salt of an IdentifierManager. + * Defining configuration parameters for a specified, deterministic salt of an IdentifierManager. */ -export interface SaltyKeyState extends IdentifierManagerState { - /** - * Encrypted - */ - sxlt: string; - pidx: number; - kidx: number; - stem: string; - tier: Tier; - dcode: string; - icodes: string[]; - ncodes: string[]; - transferable: boolean; -} +export type SaltyKeyState = components['schemas']['SaltyState']; /** - * Interface defining configuration parameters for a random seed identifier manager. + * Defining configuration parameters for a random seed identifier manager. */ -export interface RandyKeyState extends IdentifierManagerState { - prxs: string[]; - nxts: string[]; -} +export type RandyKeyState = components['schemas']['RandyKeyState']; /** - * Interface defining properties a multi-signature group identifier manager. + * Defining properties a multi-signature group identifier manager. */ -export interface GroupKeyState extends IdentifierManagerState { - mhab: HabState; - keys: string[]; - ndigs: string[]; -} +export type GroupKeyState = components['schemas']['GroupKeyState']; /** - * Interface defining properties for an external module identifier manager that uses externally managed keys such as in an HSM or a KMS system. + * Defining properties for an external module identifier manager that uses externally managed keys such as in an HSM or a KMS system. */ -export interface ExternState extends IdentifierManagerState { - extern_type: string; - pidx: number; - [key: string]: unknown; -} +export type ExternState = components['schemas']['ExternState']; /** - * Interface defining properties of an identifier habitat, know as a Hab in KERIpy. + * Defining properties of an identifier habitat, know as a Hab in KERIpy. */ -export interface HabState { - name: string; - prefix: string; - transferable: boolean; - state: KeyState; - windexes: unknown[]; - icp_dt: string; - [Algos.salty]?: SaltyKeyState; - [Algos.randy]?: RandyKeyState; - [Algos.group]?: GroupKeyState; - [Algos.extern]?: ExternState; -} +export type HabState = components['schemas']['Identifier']; diff --git a/src/keri/core/manager.ts b/src/keri/core/manager.ts index 59ccd440..68fef4a6 100644 --- a/src/keri/core/manager.ts +++ b/src/keri/core/manager.ts @@ -1,6 +1,7 @@ import { Encrypter } from './encrypter.ts'; import { Decrypter } from './decrypter.ts'; -import { Salter, Tier } from './salter.ts'; +import { Salter } from './salter.ts'; +import { Tier} from '../../types/keria-api-schema.ts'; import { Signer } from './signer.ts'; import { Verfer } from './verfer.ts'; import { MtrDex } from './matter.ts'; diff --git a/src/keri/core/salter.ts b/src/keri/core/salter.ts index 46134d2d..ec94624c 100644 --- a/src/keri/core/salter.ts +++ b/src/keri/core/salter.ts @@ -3,15 +3,8 @@ import { Signer } from './signer.ts'; import { Matter, MtrDex } from './matter.ts'; import { EmptyMaterialError } from './kering.ts'; import libsodium from 'libsodium-wrappers-sumo'; +import { Tier} from '../../types/keria-api-schema.ts'; -/** - * Secret derivation security tier. - */ -export enum Tier { - low = 'low', - med = 'med', - high = 'high', -} interface SalterArgs { raw?: Uint8Array | undefined; diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 3b3df4bd..b2d9a08f 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -1,4 +1,37 @@ -// AUTO-GENERATED: Only components retained from OpenAPI schema +// AUTO-GENERATED: Only components and enums retained from OpenAPI schema + +export enum IssEvtT { + iss = "iss", + bis = "bis" +} + +export enum CredentialStateIssOrRevEt { + iss = "iss", + rev = "rev" +} + +export enum CredentialStateBisOrBrvEt { + bis = "bis", + brv = "brv" +} + +export enum Tier { + low = "low", + med = "med", + high = "high" +} + +export enum OOBIRole { + controller = "controller", + witness = "witness", + registrar = "registrar", + watcher = "watcher", + judge = "judge", + juror = "juror", + peer = "peer", + mailbox = "mailbox", + agent = "agent" +} export interface components { schemas: { @@ -23,7 +56,7 @@ export interface components { IssEvt: { v: string; /** @enum {unknown} */ - t: "iss" | "bis"; + t: IssEvtT; d: string; i: string; s: string; @@ -118,7 +151,7 @@ export interface components { a: components["schemas"]["Seal"]; dt: string; /** @enum {unknown} */ - et: "iss" | "rev"; + et: CredentialStateIssOrRevEt; ra: components["schemas"]["EmptyDict"]; }; RaFields: { @@ -135,7 +168,7 @@ export interface components { a: components["schemas"]["Seal"]; dt: string; /** @enum {unknown} */ - et: "bis" | "brv"; + et: CredentialStateBisOrBrvEt; ra: components["schemas"]["RaFields"]; }; CredentialState: components["schemas"]["CredentialStateIssOrRev"] | components["schemas"]["CredentialStateBisOrBrv"]; @@ -149,6 +182,345 @@ export interface components { pre: string; state: components["schemas"]["CredentialState"]; }; + Icp: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + c?: string[]; + a?: unknown; + }; + RotV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + a?: unknown; + }; + RotV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + c?: string[]; + a?: unknown; + }; + Dip: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + c?: string[]; + a?: unknown; + /** @default */ + di: string; + }; + DrtV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + a?: unknown; + }; + DrtV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + c?: string[]; + a?: unknown; + }; + Vcp: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + ii: string; + /** @default 0 */ + s: string; + c?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + /** @default */ + n: string; + }; + Vrt: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + p: string; + /** @default 0 */ + s: string; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + }; + StateEERecord: { + /** @default 0 */ + s: string; + /** @default */ + d: string; + br?: unknown[]; + ba?: unknown[]; + }; + KeyStateRecord: { + vn?: number[]; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + /** @default */ + d: string; + /** @default 0 */ + f: string; + /** @default */ + dt: string; + /** @default */ + et: string; + /** @default 0 */ + kt: string; + k: string[]; + /** @default 0 */ + nt: string; + n: string[]; + /** @default 0 */ + bt: string; + b: string[]; + c: string[]; + ee: components["schemas"]["StateEERecord"]; + /** @default */ + di: string; + }; + Controller: { + state: components["schemas"]["KeyStateRecord"]; + ee: components["schemas"]["Icp"] | components["schemas"]["RotV1"] | components["schemas"]["RotV2"] | components["schemas"]["Dip"] | components["schemas"]["DrtV1"] | components["schemas"]["DrtV2"] | components["schemas"]["Vcp"] | components["schemas"]["Vrt"]; + }; + AgentResourceResult: { + agent: components["schemas"]["KeyStateRecord"]; + controller: components["schemas"]["Controller"]; + pidx: number; + /** @default null */ + ridx: number | null; + /** @default null */ + sxlt: string | null; + }; + SaltyState: { + tier: components["schemas"]["Tier"]; + /** @default */ + sxlt: string; + /** @default 0 */ + pidx: number; + /** @default 0 */ + kidx: number; + /** @default */ + stem: string; + /** @default */ + dcode: string; + icodes: string[]; + ncodes: string[]; + /** @default false */ + transferable: boolean; + }; + RandyKeyState: { + prxs: string[]; + nxts: string[]; + }; + GroupKeyState: { + mhab: components["schemas"]["Identifier"]; + keys: string[]; + ndigs: string[]; + }; + ExternState: { + extern_type: string; + pidx: number; + } & { + [key: string]: unknown; + }; + Identifier: { + name: string; + prefix: string; + icp_dt: string; + state: components["schemas"]["KeyStateRecord"]; + /** @default null */ + transferable: boolean | null; + /** @default null */ + windexes: string[] | null; + salty?: components["schemas"]["SaltyState"]; + randy?: components["schemas"]["RandyKeyState"]; + group?: components["schemas"]["GroupKeyState"]; + extern?: components["schemas"]["ExternState"]; + }; + /** + * @description Tier of key material + * @enum {string} + */ + Tier: Tier; + OOBI: { + /** @enum {string} */ + role: OOBIRole; + oobis: string[]; + }; + EndRole: { + cid: string; + role: string; + eid: string; + }; + RpyV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + RpyV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + Rpy: components["schemas"]["RpyV1"] | components["schemas"]["RpyV2"]; + Challenge: { + words: string[]; + }; + Contact: { + id: string; + alias: string; + oobi: string; + } & { + [key: string]: unknown; + }; }; responses: never; parameters: never; diff --git a/test-integration/challenge.test.ts b/test-integration/challenge.test.ts index e065a1f8..592f3c30 100644 --- a/test-integration/challenge.test.ts +++ b/test-integration/challenge.test.ts @@ -1,5 +1,6 @@ import { assert, test } from 'vitest'; import signify, { Serder } from 'signify-ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, @@ -16,13 +17,13 @@ test('challenge', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl ); const client2 = new signify.SignifyClient( url, bran2, - signify.Tier.low, + Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/delegation.test.ts b/test-integration/delegation.test.ts index 726b9910..6c97641a 100644 --- a/test-integration/delegation.test.ts +++ b/test-integration/delegation.test.ts @@ -9,6 +9,7 @@ import { } from './utils/test-util.ts'; import { retry } from './utils/retry.ts'; import { step } from './utils/test-step.ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -20,13 +21,13 @@ test('delegation', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl ); const client2 = new signify.SignifyClient( url, bran2, - signify.Tier.low, + Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/externalModule.test.ts b/test-integration/externalModule.test.ts index 7d31dc4a..97aad7f1 100644 --- a/test-integration/externalModule.test.ts +++ b/test-integration/externalModule.test.ts @@ -3,6 +3,7 @@ import signify from 'signify-ts'; import { BIP39Shim } from './modules/bip39_shim.ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -17,7 +18,7 @@ test('bip39_shim', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl, [externalModule] ); diff --git a/test-integration/randy.test.ts b/test-integration/randy.test.ts index 0b0f3e37..6cd9f0b7 100644 --- a/test-integration/randy.test.ts +++ b/test-integration/randy.test.ts @@ -2,6 +2,7 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -12,7 +13,7 @@ test('randy', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/salty.test.ts b/test-integration/salty.test.ts index 83c8a379..c00ab4d3 100644 --- a/test-integration/salty.test.ts +++ b/test-integration/salty.test.ts @@ -2,6 +2,7 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -12,7 +13,7 @@ test('salty', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/utils/test-setup.ts b/test-integration/utils/test-setup.ts index 71cf6ada..65a0034a 100644 --- a/test-integration/utils/test-setup.ts +++ b/test-integration/utils/test-setup.ts @@ -2,12 +2,12 @@ import { CreateIdentiferArgs, EventResult, SignifyClient, - Tier, randomPasscode, ready, } from 'signify-ts'; import { resolveEnvironment } from './resolve-env.ts'; import { waitOperation } from './test-util.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; /** * Connect or boot a SignifyClient instance diff --git a/test-integration/utils/test-util.ts b/test-integration/utils/test-util.ts index 5178b158..0189d27d 100644 --- a/test-integration/utils/test-util.ts +++ b/test-integration/utils/test-util.ts @@ -6,13 +6,13 @@ import signify, { ready, Salter, SignifyClient, - Tier, HabState, } from 'signify-ts'; import { RetryOptions, retry } from './retry.ts'; import assert from 'assert'; import { resolveEnvironment } from './resolve-env.ts'; import { expect } from 'vitest'; +import { Tier } from '../../src/types/keria-api-schema.ts'; export interface Aid { name: string; diff --git a/test-integration/witness.test.ts b/test-integration/witness.test.ts index 821a16b8..19c5d488 100644 --- a/test-integration/witness.test.ts +++ b/test-integration/witness.test.ts @@ -3,6 +3,7 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { resolveOobi, waitOperation } from './utils/test-util.ts'; +import { Tier } from '../src/types/keria-api-schema.ts'; const WITNESS_AID = 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha'; const { url, bootUrl, witnessUrls } = resolveEnvironment(); @@ -14,7 +15,7 @@ test('test witness', async () => { const client1 = new signify.SignifyClient( url, bran1, - signify.Tier.low, + Tier.low, bootUrl ); await client1.boot(); diff --git a/test/app/aiding.test.ts b/test/app/aiding.test.ts index 4569c272..6f659605 100644 --- a/test/app/aiding.test.ts +++ b/test/app/aiding.test.ts @@ -11,10 +11,10 @@ import { Identifier, IdentifierDeps, IdentifierManagerFactory, - Tier, randomPasscode, } from '../../src/index.ts'; import { createMockIdentifierState } from './test-utils.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; const bran = '0123456789abcdefghijk'; diff --git a/test/app/clienting.test.ts b/test/app/clienting.test.ts index b969ba7b..34dd7c9b 100644 --- a/test/app/clienting.test.ts +++ b/test/app/clienting.test.ts @@ -22,7 +22,7 @@ import { HEADER_SIG_INPUT, HEADER_SIG_TIME, } from '../../src/keri/core/httping.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/contacting.test.ts b/test/app/contacting.test.ts index c4ff45ee..c0110bca 100644 --- a/test/app/contacting.test.ts +++ b/test/app/contacting.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/controller.test.ts b/test/app/controller.test.ts index a4c814a3..426837ca 100644 --- a/test/app/controller.test.ts +++ b/test/app/controller.test.ts @@ -4,7 +4,8 @@ import libsodium from 'libsodium-wrappers-sumo'; import { openManager } from '../../src/keri/core/manager.ts'; import { Signer } from '../../src/keri/core/signer.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; -import { Tier, randomPasscode } from '../../src/index.ts'; +import { randomPasscode } from '../../src/index.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; describe('Controller', () => { it('manage account AID signing and agent verification', async () => { diff --git a/test/app/coring.test.ts b/test/app/coring.test.ts index 53be7043..6e6c25a1 100644 --- a/test/app/coring.test.ts +++ b/test/app/coring.test.ts @@ -7,7 +7,7 @@ import { OperationsDeps, } from '../../src/keri/app/coring.ts'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { randomUUID } from 'node:crypto'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index e298fba2..6ea5eafc 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -1,7 +1,7 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { d, diff --git a/test/app/delegating.test.ts b/test/app/delegating.test.ts index 48bff125..dd34afdd 100644 --- a/test/app/delegating.test.ts +++ b/test/app/delegating.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from 'vitest'; -import { Tier } from '../../src/index.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/escrowing.test.ts b/test/app/escrowing.test.ts index 9150e9cf..354754b5 100644 --- a/test/app/escrowing.test.ts +++ b/test/app/escrowing.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/exchanging.test.ts b/test/app/exchanging.test.ts index 9b79b53e..b14faace 100644 --- a/test/app/exchanging.test.ts +++ b/test/app/exchanging.test.ts @@ -8,8 +8,8 @@ import { MtrDex, Salter, Serder, - Tier, } from '../../src/index.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/grouping.test.ts b/test/app/grouping.test.ts index 197da9ad..bbb8df92 100644 --- a/test/app/grouping.test.ts +++ b/test/app/grouping.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/notifying.test.ts b/test/app/notifying.test.ts index 885abf20..bae6c595 100644 --- a/test/app/notifying.test.ts +++ b/test/app/notifying.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from 'vitest'; -import { Tier } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index e1f1cf3a..79c4466f 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -9,10 +9,10 @@ import { MtrDex, Salter, Serials, - Tier, Vrsn_1_0, incept, } from '../../src/index.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { EstablishmentState, HabState, diff --git a/test/core/manager.test.ts b/test/core/manager.test.ts index fef02f14..0cc7533a 100644 --- a/test/core/manager.test.ts +++ b/test/core/manager.test.ts @@ -9,7 +9,8 @@ import { } from '../../src/keri/core/manager.ts'; import { assert, describe, it, expect, vitest, Mocked } from 'vitest'; import { MtrDex } from '../../src/keri/core/matter.ts'; -import { Salter, Tier } from '../../src/keri/core/salter.ts'; +import { Salter } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { Signer } from '../../src/keri/core/signer.ts'; import { Encrypter } from '../../src/keri/core/encrypter.ts'; import { Decrypter } from '../../src/keri/core/decrypter.ts'; diff --git a/test/core/serder.test.ts b/test/core/serder.test.ts index 75f1d127..d6f15a77 100644 --- a/test/core/serder.test.ts +++ b/test/core/serder.test.ts @@ -1,6 +1,7 @@ import { deversify, Ilks, Serials, Version } from '../../src/keri/core/core.ts'; import { assert, describe, it } from 'vitest'; -import { Salter, Tier } from '../../src/keri/core/salter.ts'; +import { Salter } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; import { Diger } from '../../src/keri/core/diger.ts'; import { Serder } from '../../src/keri/core/serder.ts'; diff --git a/test/end/ending.test.ts b/test/end/ending.test.ts index c9f31bf3..65986d75 100644 --- a/test/end/ending.test.ts +++ b/test/end/ending.test.ts @@ -1,6 +1,7 @@ import { assert, describe, it, beforeAll, beforeEach } from 'vitest'; import libsodium from 'libsodium-wrappers-sumo'; -import { Salter, Tier } from '../../src/keri/core/salter.ts'; +import { Salter } from '../../src/keri/core/salter.ts'; +import { Tier } from '../../src/types/keria-api-schema.ts'; import { b } from '../../src/keri/core/core.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; import { designature, Signage, signature } from '../../src/keri/end/ending.ts'; From 82d077ecc83ed4ac4e32bdbda87db1cb36b02008 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Fri, 8 Aug 2025 18:37:50 +0700 Subject: [PATCH 14/22] Generate types for Group Member --- src/keri/app/aiding.ts | 7 ++++-- src/types/keria-api-schema.ts | 45 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index a39920a4..42b5cfaf 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -8,6 +8,7 @@ import { Serder } from '../core/serder.ts'; import { parseRangeHeaders } from '../core/httping.ts'; import { IdentifierManagerFactory } from '../core/keeping.ts'; import { HabState } from '../core/keyState.ts'; +import { components } from '../../types/keria-api-schema.ts'; /** Arguments required to create an identfier */ export interface CreateIdentiferArgs { @@ -73,6 +74,8 @@ export interface IdentifierInfo { name: string; } +export type GroupMember = components['schemas']['GroupMember']; + /** Identifier */ export class Identifier { public client: IdentifierDeps; @@ -487,9 +490,9 @@ export class Identifier { * Get the members of a group identifier * @async * @param {string} name - Name or alias of the identifier - * @returns {Promise} - A promise to the list of members + * @returns {Promise} - A promise to the list of members */ - async members(name: string): Promise { + async members(name: string): Promise { const res = await this.client.fetch( '/identifiers/' + name + '/members', 'GET', diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index b2d9a08f..9c33071d 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -521,6 +521,51 @@ export interface components { } & { [key: string]: unknown; }; + MemberEnds: { + agent: { + [key: string]: string; + }; + /** @default null */ + controller: { + [key: string]: string; + } | null; + /** @default null */ + witness: { + [key: string]: string; + } | null; + /** @default null */ + registrar: { + [key: string]: string; + } | null; + /** @default null */ + watcher: { + [key: string]: string; + } | null; + /** @default null */ + judge: { + [key: string]: string; + } | null; + /** @default null */ + juror: { + [key: string]: string; + } | null; + /** @default null */ + peer: { + [key: string]: string; + } | null; + /** @default null */ + mailbox: { + [key: string]: string; + } | null; + }; + AidRecord: { + aid: string; + ends: components["schemas"]["MemberEnds"]; + }; + GroupMember: { + signing: components["schemas"]["AidRecord"][]; + rotation: components["schemas"]["AidRecord"][]; + }; }; responses: never; parameters: never; From 7c9bcd72995f100b73dde2de3786e907fa0f6abb Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Thu, 14 Aug 2025 15:27:59 +0700 Subject: [PATCH 15/22] resolve review comments --- src/keri/app/aiding.ts | 2 +- src/keri/app/clienting.ts | 3 +- src/keri/app/controller.ts | 3 +- src/keri/core/keeping.ts | 30 +++-- src/keri/core/keyState.ts | 14 +- src/keri/core/manager.ts | 3 +- src/keri/core/salter.ts | 4 +- src/types/keria-api-schema.ts | 106 ++++++++++++--- test-integration/challenge.test.ts | 5 +- test-integration/delegation.test.ts | 5 +- test-integration/externalModule.test.ts | 3 +- test-integration/randy.test.ts | 3 +- test-integration/salty.test.ts | 3 +- test-integration/utils/multisig-utils.ts | 6 +- test-integration/utils/resolve-env.ts | 2 +- test-integration/utils/test-setup.ts | 2 +- test-integration/utils/test-util.ts | 2 +- test-integration/witness.test.ts | 3 +- test/app/aiding.test.ts | 2 +- test/app/clienting.test.ts | 2 +- test/app/contacting.test.ts | 2 +- test/app/controller.test.ts | 3 +- test/app/coring.test.ts | 2 +- test/app/credentialing.test.ts | 2 +- test/app/delegating.test.ts | 2 +- test/app/escrowing.test.ts | 2 +- test/app/exchanging.test.ts | 2 +- test/app/grouping.test.ts | 2 +- test/app/notifying.test.ts | 2 +- test/app/registry.test.ts | 8 +- test/app/test-utils.ts | 164 +++++++++++++++++++---- test/core/manager.test.ts | 13 +- test/core/serder.test.ts | 3 +- test/end/ending.test.ts | 3 +- 34 files changed, 305 insertions(+), 108 deletions(-) diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index 42b5cfaf..1d40d6cd 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -1,4 +1,4 @@ -import { Tier} from '../../types/keria-api-schema.ts'; +import { Tier } from '../core/salter.ts'; import { Algos } from '../core/manager.ts'; import { incept, interact, reply, rotate } from '../core/eventing.ts'; import { b, Ilks, Serials, Vrsn_1_0 } from '../core/core.ts'; diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index 8a3c8553..3541d81d 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -1,7 +1,8 @@ -import { components, Tier } from '../../types/keria-api-schema.ts'; +import { components } from '../../types/keria-api-schema.ts'; import { Authenticater } from '../core/authing.ts'; import { HEADER_SIG_TIME } from '../core/httping.ts'; import { ExternalModule, IdentifierManagerFactory } from '../core/keeping.ts'; +import { Tier } from '../core/salter.ts'; import { Identifier } from './aiding.ts'; import { Contacts, Challenges } from './contacting.ts'; diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index d209e1de..2495ee9e 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -1,6 +1,5 @@ import { SaltyCreator } from '../core/manager.ts'; -import { Salter } from '../core/salter.ts'; -import { Tier} from '../../types/keria-api-schema.ts'; +import { Salter, Tier } from '../core/salter.ts'; import { MtrDex } from '../core/matter.ts'; import { Diger } from '../core/diger.ts'; import { incept, rotate, interact } from '../core/eventing.ts'; diff --git a/src/keri/core/keeping.ts b/src/keri/core/keeping.ts index 0c2ff343..fb520c4e 100644 --- a/src/keri/core/keeping.ts +++ b/src/keri/core/keeping.ts @@ -1,7 +1,7 @@ import { Salter } from './salter.ts'; import { Algos, SaltyCreator, RandyCreator } from './manager.ts'; import { MtrDex } from './matter.ts'; -import { Tier} from '../../types/keria-api-schema.ts'; +import { Tier } from './salter.ts'; import { Encrypter } from '../core/encrypter.ts'; import { Decrypter } from './decrypter.ts'; import { b } from './core.ts'; @@ -177,19 +177,25 @@ export class IdentifierManagerFactory { * @returns IdentifierManager instance */ get(aid: HabState): IdentifierManager { - const algo = aid[Algos.salty] - ? Algos.salty - : aid[Algos.randy] - ? Algos.randy - : aid[Algos.group] - ? Algos.group - : aid[Algos.extern] - ? Algos.extern - : undefined; - if (!algo) { + let algo: Algos | undefined; + let kargs: any; + + if (Algos.salty in aid) { + algo = Algos.salty; + kargs = aid.salty; + } else if (Algos.randy in aid) { + algo = Algos.randy; + kargs = aid.randy; + } else if (Algos.group in aid) { + algo = Algos.group; + kargs = aid.group; + } else if (Algos.extern in aid) { + algo = Algos.extern; + kargs = aid.extern; + } else { throw new Error('No algo specified'); } - let kargs = aid[algo]; + if (!kargs) { throw new Error('No kargs found in HabState'); } diff --git a/src/keri/core/keyState.ts b/src/keri/core/keyState.ts index 3d6c10da..aa232c47 100644 --- a/src/keri/core/keyState.ts +++ b/src/keri/core/keyState.ts @@ -34,4 +34,16 @@ export type ExternState = components['schemas']['ExternState']; /** * Defining properties of an identifier habitat, know as a Hab in KERIpy. */ -export type HabState = components['schemas']['Identifier']; +// export type HabState = components['schemas']['Identifier']; + +export type HabStateBase = components['schemas']['HabState']; +export type SaltyHabState = HabStateBase & SaltyKeyState; +export type RandyHabState = HabStateBase & RandyKeyState; +export type GroupHabState = HabStateBase & GroupKeyState; +export type ExternHabState = HabStateBase & ExternState; +export type HabState = + | SaltyHabState + | RandyHabState + | GroupHabState + | ExternHabState; + diff --git a/src/keri/core/manager.ts b/src/keri/core/manager.ts index 68fef4a6..59ccd440 100644 --- a/src/keri/core/manager.ts +++ b/src/keri/core/manager.ts @@ -1,7 +1,6 @@ import { Encrypter } from './encrypter.ts'; import { Decrypter } from './decrypter.ts'; -import { Salter } from './salter.ts'; -import { Tier} from '../../types/keria-api-schema.ts'; +import { Salter, Tier } from './salter.ts'; import { Signer } from './signer.ts'; import { Verfer } from './verfer.ts'; import { MtrDex } from './matter.ts'; diff --git a/src/keri/core/salter.ts b/src/keri/core/salter.ts index ec94624c..bfb563a1 100644 --- a/src/keri/core/salter.ts +++ b/src/keri/core/salter.ts @@ -3,9 +3,11 @@ import { Signer } from './signer.ts'; import { Matter, MtrDex } from './matter.ts'; import { EmptyMaterialError } from './kering.ts'; import libsodium from 'libsodium-wrappers-sumo'; -import { Tier} from '../../types/keria-api-schema.ts'; +import { Tier } from '../../types/keria-api-schema.ts'; +export { Tier } from '../../types/keria-api-schema.ts'; + interface SalterArgs { raw?: Uint8Array | undefined; code?: string; diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index 9c33071d..e7c24c40 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -182,7 +182,30 @@ export interface components { pre: string; state: components["schemas"]["CredentialState"]; }; - Icp: { + IcpV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + c?: string[]; + a?: unknown; + }; + IcpV2: { /** @default */ v: string; /** @default */ @@ -256,7 +279,32 @@ export interface components { c?: string[]; a?: unknown; }; - Dip: { + DipV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default 0 */ + kt: string; + k?: string[]; + /** @default 0 */ + nt: string; + n?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + c?: string[]; + a?: unknown; + /** @default */ + di: string; + }; + DipV2: { /** @default */ v: string; /** @default */ @@ -332,7 +380,7 @@ export interface components { c?: string[]; a?: unknown; }; - Vcp: { + VcpV1: { /** @default */ v: string; /** @default */ @@ -352,7 +400,7 @@ export interface components { /** @default */ n: string; }; - Vrt: { + VrtV1: { /** @default */ v: string; /** @default */ @@ -410,7 +458,7 @@ export interface components { }; Controller: { state: components["schemas"]["KeyStateRecord"]; - ee: components["schemas"]["Icp"] | components["schemas"]["RotV1"] | components["schemas"]["RotV2"] | components["schemas"]["Dip"] | components["schemas"]["DrtV1"] | components["schemas"]["DrtV2"] | components["schemas"]["Vcp"] | components["schemas"]["Vrt"]; + ee: components["schemas"]["IcpV1"] | components["schemas"]["IcpV2"] | components["schemas"]["RotV1"] | components["schemas"]["RotV2"] | components["schemas"]["DipV1"] | components["schemas"]["DipV2"] | components["schemas"]["DrtV1"] | components["schemas"]["DrtV2"] | components["schemas"]["VcpV1"] | components["schemas"]["VrtV1"]; }; AgentResourceResult: { agent: components["schemas"]["KeyStateRecord"]; @@ -442,6 +490,16 @@ export interface components { prxs: string[]; nxts: string[]; }; + HabState: { + name: string; + prefix: string; + icp_dt: string; + state: components["schemas"]["KeyStateRecord"]; + /** @default null */ + transferable: boolean | null; + /** @default null */ + windexes: string[] | null; + }; GroupKeyState: { mhab: components["schemas"]["Identifier"]; keys: string[]; @@ -462,11 +520,15 @@ export interface components { transferable: boolean | null; /** @default null */ windexes: string[] | null; - salty?: components["schemas"]["SaltyState"]; - randy?: components["schemas"]["RandyKeyState"]; - group?: components["schemas"]["GroupKeyState"]; - extern?: components["schemas"]["ExternState"]; - }; + } & ({ + salty: components["schemas"]["SaltyState"]; + } | { + randy: components["schemas"]["RandyKeyState"]; + } | { + group: components["schemas"]["GroupKeyState"]; + } | { + extern: components["schemas"]["ExternState"]; + }); /** * @description Tier of key material * @enum {string} @@ -513,13 +575,9 @@ export interface components { Rpy: components["schemas"]["RpyV1"] | components["schemas"]["RpyV2"]; Challenge: { words: string[]; - }; - Contact: { - id: string; - alias: string; - oobi: string; - } & { - [key: string]: unknown; + dt?: string; + said?: string; + authenticated?: boolean; }; MemberEnds: { agent: { @@ -558,6 +616,20 @@ export interface components { [key: string]: string; } | null; }; + WellKnown: { + url: string; + dt: string; + }; + Contact: { + id: string; + alias: string; + oobi: string; + end?: components["schemas"]["MemberEnds"]; + challenges?: components["schemas"]["Challenge"][]; + wellKnowns?: components["schemas"]["WellKnown"][]; + } & { + [key: string]: unknown; + }; AidRecord: { aid: string; ends: components["schemas"]["MemberEnds"]; diff --git a/test-integration/challenge.test.ts b/test-integration/challenge.test.ts index 592f3c30..e065a1f8 100644 --- a/test-integration/challenge.test.ts +++ b/test-integration/challenge.test.ts @@ -1,6 +1,5 @@ import { assert, test } from 'vitest'; import signify, { Serder } from 'signify-ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, @@ -17,13 +16,13 @@ test('challenge', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl ); const client2 = new signify.SignifyClient( url, bran2, - Tier.low, + signify.Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/delegation.test.ts b/test-integration/delegation.test.ts index 6c97641a..726b9910 100644 --- a/test-integration/delegation.test.ts +++ b/test-integration/delegation.test.ts @@ -9,7 +9,6 @@ import { } from './utils/test-util.ts'; import { retry } from './utils/retry.ts'; import { step } from './utils/test-step.ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -21,13 +20,13 @@ test('delegation', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl ); const client2 = new signify.SignifyClient( url, bran2, - Tier.low, + signify.Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/externalModule.test.ts b/test-integration/externalModule.test.ts index 97aad7f1..7d31dc4a 100644 --- a/test-integration/externalModule.test.ts +++ b/test-integration/externalModule.test.ts @@ -3,7 +3,6 @@ import signify from 'signify-ts'; import { BIP39Shim } from './modules/bip39_shim.ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -18,7 +17,7 @@ test('bip39_shim', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl, [externalModule] ); diff --git a/test-integration/randy.test.ts b/test-integration/randy.test.ts index 6cd9f0b7..0b0f3e37 100644 --- a/test-integration/randy.test.ts +++ b/test-integration/randy.test.ts @@ -2,7 +2,6 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -13,7 +12,7 @@ test('randy', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/salty.test.ts b/test-integration/salty.test.ts index c00ab4d3..83c8a379 100644 --- a/test-integration/salty.test.ts +++ b/test-integration/salty.test.ts @@ -2,7 +2,6 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, waitOperation } from './utils/test-util.ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; const { url, bootUrl } = resolveEnvironment(); @@ -13,7 +12,7 @@ test('salty', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl ); await client1.boot(); diff --git a/test-integration/utils/multisig-utils.ts b/test-integration/utils/multisig-utils.ts index fe3b1a6e..542d0d71 100644 --- a/test-integration/utils/multisig-utils.ts +++ b/test-integration/utils/multisig-utils.ts @@ -8,6 +8,10 @@ import signify, { d, messagize, HabState, + SaltyHabState, + GroupHabState, + ExternHabState, + RandyHabState, } from 'signify-ts'; import { getStates, waitAndMarkNotification } from './test-util.ts'; import assert from 'assert'; @@ -85,7 +89,7 @@ export async function acceptMultisigIncept( export async function addEndRoleMultisig( client: SignifyClient, groupName: string, - aid: HabState, + aid: SaltyHabState | GroupHabState | ExternHabState | RandyHabState, otherMembersAIDs: HabState[], multisigAID: HabState, timestamp: string, diff --git a/test-integration/utils/resolve-env.ts b/test-integration/utils/resolve-env.ts index d41ce4d1..767f24fd 100644 --- a/test-integration/utils/resolve-env.ts +++ b/test-integration/utils/resolve-env.ts @@ -16,7 +16,7 @@ const WES = 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX'; export function resolveEnvironment( input?: TestEnvironmentPreset ): TestEnvironment { - const preset = input ?? process.env.TEST_ENVIRONMENT ?? 'docker'; + const preset = input ?? process.env.TEST_ENVIRONMENT ?? 'local'; const url = 'http://127.0.0.1:3901'; const bootUrl = 'http://127.0.0.1:3903'; diff --git a/test-integration/utils/test-setup.ts b/test-integration/utils/test-setup.ts index 65a0034a..71cf6ada 100644 --- a/test-integration/utils/test-setup.ts +++ b/test-integration/utils/test-setup.ts @@ -2,12 +2,12 @@ import { CreateIdentiferArgs, EventResult, SignifyClient, + Tier, randomPasscode, ready, } from 'signify-ts'; import { resolveEnvironment } from './resolve-env.ts'; import { waitOperation } from './test-util.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; /** * Connect or boot a SignifyClient instance diff --git a/test-integration/utils/test-util.ts b/test-integration/utils/test-util.ts index 0189d27d..5178b158 100644 --- a/test-integration/utils/test-util.ts +++ b/test-integration/utils/test-util.ts @@ -6,13 +6,13 @@ import signify, { ready, Salter, SignifyClient, + Tier, HabState, } from 'signify-ts'; import { RetryOptions, retry } from './retry.ts'; import assert from 'assert'; import { resolveEnvironment } from './resolve-env.ts'; import { expect } from 'vitest'; -import { Tier } from '../../src/types/keria-api-schema.ts'; export interface Aid { name: string; diff --git a/test-integration/witness.test.ts b/test-integration/witness.test.ts index 19c5d488..821a16b8 100644 --- a/test-integration/witness.test.ts +++ b/test-integration/witness.test.ts @@ -3,7 +3,6 @@ import { assert, test } from 'vitest'; import signify from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { resolveOobi, waitOperation } from './utils/test-util.ts'; -import { Tier } from '../src/types/keria-api-schema.ts'; const WITNESS_AID = 'BBilc4-L3tFUnfM_wJr4S4OJanAv_VmF_dJNN6vkf2Ha'; const { url, bootUrl, witnessUrls } = resolveEnvironment(); @@ -15,7 +14,7 @@ test('test witness', async () => { const client1 = new signify.SignifyClient( url, bran1, - Tier.low, + signify.Tier.low, bootUrl ); await client1.boot(); diff --git a/test/app/aiding.test.ts b/test/app/aiding.test.ts index 6f659605..bcc7527b 100644 --- a/test/app/aiding.test.ts +++ b/test/app/aiding.test.ts @@ -12,9 +12,9 @@ import { IdentifierDeps, IdentifierManagerFactory, randomPasscode, + Tier, } from '../../src/index.ts'; import { createMockIdentifierState } from './test-utils.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; const bran = '0123456789abcdefghijk'; diff --git a/test/app/clienting.test.ts b/test/app/clienting.test.ts index 34dd7c9b..b969ba7b 100644 --- a/test/app/clienting.test.ts +++ b/test/app/clienting.test.ts @@ -22,7 +22,7 @@ import { HEADER_SIG_INPUT, HEADER_SIG_TIME, } from '../../src/keri/core/httping.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/contacting.test.ts b/test/app/contacting.test.ts index c0110bca..c4ff45ee 100644 --- a/test/app/contacting.test.ts +++ b/test/app/contacting.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/controller.test.ts b/test/app/controller.test.ts index 426837ca..a4c814a3 100644 --- a/test/app/controller.test.ts +++ b/test/app/controller.test.ts @@ -4,8 +4,7 @@ import libsodium from 'libsodium-wrappers-sumo'; import { openManager } from '../../src/keri/core/manager.ts'; import { Signer } from '../../src/keri/core/signer.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; -import { randomPasscode } from '../../src/index.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier, randomPasscode } from '../../src/index.ts'; describe('Controller', () => { it('manage account AID signing and agent verification', async () => { diff --git a/test/app/coring.test.ts b/test/app/coring.test.ts index 6e6c25a1..53be7043 100644 --- a/test/app/coring.test.ts +++ b/test/app/coring.test.ts @@ -7,7 +7,7 @@ import { OperationsDeps, } from '../../src/keri/app/coring.ts'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import { randomUUID } from 'node:crypto'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index 6ea5eafc..e298fba2 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -1,7 +1,7 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { d, diff --git a/test/app/delegating.test.ts b/test/app/delegating.test.ts index dd34afdd..db886b01 100644 --- a/test/app/delegating.test.ts +++ b/test/app/delegating.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from 'vitest'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/escrowing.test.ts b/test/app/escrowing.test.ts index 354754b5..9150e9cf 100644 --- a/test/app/escrowing.test.ts +++ b/test/app/escrowing.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/exchanging.test.ts b/test/app/exchanging.test.ts index b14faace..9b79b53e 100644 --- a/test/app/exchanging.test.ts +++ b/test/app/exchanging.test.ts @@ -8,8 +8,8 @@ import { MtrDex, Salter, Serder, + Tier, } from '../../src/index.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/grouping.test.ts b/test/app/grouping.test.ts index bbb8df92..197da9ad 100644 --- a/test/app/grouping.test.ts +++ b/test/app/grouping.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from 'vitest'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/notifying.test.ts b/test/app/notifying.test.ts index bae6c595..885abf20 100644 --- a/test/app/notifying.test.ts +++ b/test/app/notifying.test.ts @@ -1,5 +1,5 @@ import { assert, describe, it } from 'vitest'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Tier } from '../../src/keri/core/salter.ts'; import { SignifyClient } from '../../src/keri/app/clienting.ts'; import libsodium from 'libsodium-wrappers-sumo'; import { createMockFetch } from './test-utils.ts'; diff --git a/test/app/registry.test.ts b/test/app/registry.test.ts index 32dd7d20..cff65027 100644 --- a/test/app/registry.test.ts +++ b/test/app/registry.test.ts @@ -67,14 +67,18 @@ describe('registry', () => { const mockedClient = mock(SignifyClient); const mockedIdentifiers = mock(Identifier); - const hab = { + const hab = ({ prefix: 'hab prefix', state: { s: 0, d: 'a digest', c: ['EO'] } as unknown as KeyState, name: 'a name', transferable: true, windexes: [], icp_dt: '2023-12-01T10:05:25.062609+00:00', - } as HabState; + randy: { + prxs: [], + nxts: [], + }, + } as unknown) as HabState; when(mockedIdentifiers.get('a name')).thenResolve(hab); when(mockedClient.identifiers()).thenReturn( diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index 79c4466f..982406bc 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -9,10 +9,10 @@ import { MtrDex, Salter, Serials, + Tier, Vrsn_1_0, incept, } from '../../src/index.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; import { EstablishmentState, HabState, @@ -96,33 +96,141 @@ export async function createMockIdentifierState( ...(delpre ? { delpre } : {}), }); - return { - name: name, - prefix: serder.pre, - [algo]: keeper.params(), - transferable, - windexes: [], - state: { - vn: [serder.version.major, serder.version.minor], - s: serder.sad.s, - d: serder.sad.d, - i: serder.pre, - ee: serder.sad as EstablishmentState, - kt: serder.sad.kt, - k: serder.sad.k, - nt: serder.sad.nt, - n: serder.sad.n, - bt: serder.sad.bt, - b: serder.sad.b, - p: serder.sad.p ?? '', - f: '', - dt: new Date().toISOString().replace('Z', '000+00:00'), - et: '', - c: [], - di: serder.sad.di ?? '', - } as KeyState, - icp_dt: '2023-12-01T10:05:25.062609+00:00', - }; + // Mock for each algo type + if (algo === Algos.salty) { + return ({ + name, + prefix: serder.pre, + salty: { + tier: tier ?? Tier.low, + sxlt: bran, + pidx: 0, + kidx: 0, + stem: 'signify:aid', + dcode: dcode, + icodes: ['A'], + ncodes: ['A'], + transferable, + }, + transferable, + windexes: [], + state: { + vn: [serder.version.major, serder.version.minor], + s: serder.sad.s, + d: serder.sad.d, + i: serder.pre, + ee: serder.sad as EstablishmentState, + kt: serder.sad.kt, + k: serder.sad.k, + nt: serder.sad.nt, + n: serder.sad.n, + bt: serder.sad.bt, + b: serder.sad.b, + p: serder.sad.p ?? '', + f: '', + dt: new Date().toISOString().replace('Z', '000+00:00'), + et: '', + c: [], + di: serder.sad.di ?? '', + } as KeyState, + icp_dt: '2023-12-01T10:05:25.062609+00:00', + } as unknown) as HabState; + } else if (algo === Algos.randy) { + return ({ + name, + prefix: serder.pre, + randy: { + prxs: prxs ?? [], + nxts: nxts ?? [], + }, + transferable, + windexes: [], + state: { + vn: [serder.version.major, serder.version.minor], + s: serder.sad.s, + d: serder.sad.d, + i: serder.pre, + ee: serder.sad as EstablishmentState, + kt: serder.sad.kt, + k: serder.sad.k, + nt: serder.sad.nt, + n: serder.sad.n, + bt: serder.sad.bt, + b: serder.sad.b, + p: serder.sad.p ?? '', + f: '', + dt: new Date().toISOString().replace('Z', '000+00:00'), + et: '', + c: [], + di: serder.sad.di ?? '', + } as KeyState, + icp_dt: '2023-12-01T10:05:25.062609+00:00', + } as unknown) as HabState; + } else if (algo === Algos.group) { + return ({ + name, + prefix: serder.pre, + group: { + mhab: mhab ?? {}, + keys: _keys ?? [], + ndigs: _ndigs ?? [], + }, + transferable, + windexes: [], + state: { + vn: [serder.version.major, serder.version.minor], + s: serder.sad.s, + d: serder.sad.d, + i: serder.pre, + ee: serder.sad as EstablishmentState, + kt: serder.sad.kt, + k: serder.sad.k, + nt: serder.sad.nt, + n: serder.sad.n, + bt: serder.sad.bt, + b: serder.sad.b, + p: serder.sad.p ?? '', + f: '', + dt: new Date().toISOString().replace('Z', '000+00:00'), + et: '', + c: [], + di: serder.sad.di ?? '', + } as KeyState, + icp_dt: '2023-12-01T10:05:25.062609+00:00', + } as unknown) as HabState; + } else if (algo === Algos.extern) { + return ({ + name, + prefix: serder.pre, + extern: extern ?? {}, + extern_type: extern_type ?? 'mock', + pidx: 0, + transferable, + windexes: [], + state: { + vn: [serder.version.major, serder.version.minor], + s: serder.sad.s, + d: serder.sad.d, + i: serder.pre, + ee: serder.sad as EstablishmentState, + kt: serder.sad.kt, + k: serder.sad.k, + nt: serder.sad.nt, + n: serder.sad.n, + bt: serder.sad.bt, + b: serder.sad.b, + p: serder.sad.p ?? '', + f: '', + dt: new Date().toISOString().replace('Z', '000+00:00'), + et: '', + c: [], + di: serder.sad.di ?? '', + } as KeyState, + icp_dt: '2023-12-01T10:05:25.062609+00:00', + } as unknown) as HabState; + } else { + throw new Error('Unknown algo type'); + } } export const mockConnect = { diff --git a/test/core/manager.test.ts b/test/core/manager.test.ts index 0cc7533a..f0aa6417 100644 --- a/test/core/manager.test.ts +++ b/test/core/manager.test.ts @@ -9,8 +9,7 @@ import { } from '../../src/keri/core/manager.ts'; import { assert, describe, it, expect, vitest, Mocked } from 'vitest'; import { MtrDex } from '../../src/keri/core/matter.ts'; -import { Salter } from '../../src/keri/core/salter.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Salter, Tier } from '../../src/keri/core/salter.ts'; import { Signer } from '../../src/keri/core/signer.ts'; import { Encrypter } from '../../src/keri/core/encrypter.ts'; import { Decrypter } from '../../src/keri/core/decrypter.ts'; @@ -27,7 +26,7 @@ import { Prefixer, RandyIdentifierManager, } from '../../src/index.ts'; -import { RandyKeyState, KeyState } from '../../src/keri/core/keyState.ts'; +import { RandyKeyState, KeyState, RandyHabState, ExternHabState, HabState } from '../../src/keri/core/keyState.ts'; import { randomUUID } from 'node:crypto'; describe('RandyCreator', () => { @@ -728,7 +727,7 @@ describe('Manager', () => { transferable: false, windexes: [], icp_dt: '2023-12-01T10:05:25.062609+00:00', - }); + } as unknown as RandyHabState); assert(keeper0 instanceof RandyIdentifierManager); assert(keeper1 instanceof RandyIdentifierManager); @@ -751,7 +750,7 @@ describe('Manager', () => { transferable: false, windexes: [], icp_dt: '2023-12-01T10:05:25.062609+00:00', - }) + } as unknown as HabState) ).toThrow('No algo specified'); }); @@ -829,7 +828,7 @@ describe('Manager', () => { }, transferable: true, icp_dt: '2023-12-01T10:05:25.062609+00:00', - }); + } as unknown as ExternHabState); assert(keeper instanceof MockModule); expect(keeper.params()).toMatchObject({ param, pidx: 3 }); @@ -856,7 +855,7 @@ describe('Manager', () => { }, transferable: true, icp_dt: '2023-12-01T10:05:25.062609+00:00', - }) + } as unknown as ExternHabState) ).toThrow('unsupported external module type mock'); }); }); diff --git a/test/core/serder.test.ts b/test/core/serder.test.ts index d6f15a77..75f1d127 100644 --- a/test/core/serder.test.ts +++ b/test/core/serder.test.ts @@ -1,7 +1,6 @@ import { deversify, Ilks, Serials, Version } from '../../src/keri/core/core.ts'; import { assert, describe, it } from 'vitest'; -import { Salter } from '../../src/keri/core/salter.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Salter, Tier } from '../../src/keri/core/salter.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; import { Diger } from '../../src/keri/core/diger.ts'; import { Serder } from '../../src/keri/core/serder.ts'; diff --git a/test/end/ending.test.ts b/test/end/ending.test.ts index 65986d75..c9f31bf3 100644 --- a/test/end/ending.test.ts +++ b/test/end/ending.test.ts @@ -1,7 +1,6 @@ import { assert, describe, it, beforeAll, beforeEach } from 'vitest'; import libsodium from 'libsodium-wrappers-sumo'; -import { Salter } from '../../src/keri/core/salter.ts'; -import { Tier } from '../../src/types/keria-api-schema.ts'; +import { Salter, Tier } from '../../src/keri/core/salter.ts'; import { b } from '../../src/keri/core/core.ts'; import { MtrDex } from '../../src/keri/core/matter.ts'; import { designature, Signage, signature } from '../../src/keri/end/ending.ts'; From 9acdffe10e8c0f6287ff4e03716d64af5e5f7374 Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Tue, 19 Aug 2025 15:43:26 +0700 Subject: [PATCH 16/22] fix mock data for aiding test --- test-integration/utils/resolve-env.ts | 2 +- test/app/test-utils.ts | 23 +++-------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/test-integration/utils/resolve-env.ts b/test-integration/utils/resolve-env.ts index 767f24fd..d41ce4d1 100644 --- a/test-integration/utils/resolve-env.ts +++ b/test-integration/utils/resolve-env.ts @@ -16,7 +16,7 @@ const WES = 'BIKKuvBwpmDVA4Ds-EpL5bt9OqPzWPja2LigFYZN2YfX'; export function resolveEnvironment( input?: TestEnvironmentPreset ): TestEnvironment { - const preset = input ?? process.env.TEST_ENVIRONMENT ?? 'local'; + const preset = input ?? process.env.TEST_ENVIRONMENT ?? 'docker'; const url = 'http://127.0.0.1:3901'; const bootUrl = 'http://127.0.0.1:3903'; diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index 982406bc..653678d0 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -101,17 +101,7 @@ export async function createMockIdentifierState( return ({ name, prefix: serder.pre, - salty: { - tier: tier ?? Tier.low, - sxlt: bran, - pidx: 0, - kidx: 0, - stem: 'signify:aid', - dcode: dcode, - icodes: ['A'], - ncodes: ['A'], - transferable, - }, + salty: keeper.params(), transferable, windexes: [], state: { @@ -139,10 +129,7 @@ export async function createMockIdentifierState( return ({ name, prefix: serder.pre, - randy: { - prxs: prxs ?? [], - nxts: nxts ?? [], - }, + randy: keeper.params(), transferable, windexes: [], state: { @@ -170,11 +157,7 @@ export async function createMockIdentifierState( return ({ name, prefix: serder.pre, - group: { - mhab: mhab ?? {}, - keys: _keys ?? [], - ndigs: _ndigs ?? [], - }, + group: keeper.params(), transferable, windexes: [], state: { From 2756a67b898e065b8d7e26c826548a04a43c4c9e Mon Sep 17 00:00:00 2001 From: Patrick Vu Date: Thu, 14 Aug 2025 18:21:46 +0700 Subject: [PATCH 17/22] feat: agenting.py type hints and OpenAPI specs #377 --- src/keri/app/contacting.ts | 6 +- src/keri/app/coring.ts | 25 +- src/types/keria-api-schema.ts | 424 +++++++++++++++++++++---- test-integration/singlesig-ixn.test.ts | 21 +- test-integration/singlesig-rot.test.ts | 24 +- 5 files changed, 392 insertions(+), 108 deletions(-) diff --git a/src/keri/app/contacting.ts b/src/keri/app/contacting.ts index eecfdb09..5deb6d5c 100644 --- a/src/keri/app/contacting.ts +++ b/src/keri/app/contacting.ts @@ -184,15 +184,15 @@ export class Challenges { * Mark challenge response as signed and accepted * @param source Prefix of the identifier that was challenged * @param said qb64 AID of exn message representing the signed response - * @returns {Promise} A promise to the result + * @returns {Promise>} A promise to the result */ - async responded(source: string, said: string): Promise { + async responded(source: string, said: string): Promise> { const path = `/challenges_verify/${source}`; const method = 'PUT'; const data = { said: said, }; const res = await this.client.fetch(path, method, data); - return res; + return await res.json() as Operation; } } diff --git a/src/keri/app/coring.ts b/src/keri/app/coring.ts index c6070da0..a6df21c7 100644 --- a/src/keri/app/coring.ts +++ b/src/keri/app/coring.ts @@ -6,6 +6,9 @@ import { components } from '../../types/keria-api-schema.ts'; type OperationBase = components['schemas']['OperationBase']; type OOBI = components['schemas']['OOBI']; +type KeyState = components['schemas']['KeyStateRecord']; +type KeyEventRecord = components['schemas']['KeyEventRecord']; +type AgentConfig = components['schemas']['AgentConfig']; export function randomPasscode(): string { const raw = libsodium.randombytes_buf(16); @@ -49,9 +52,9 @@ export class Oobis { * @async * @param {string} oobi The OOBI to be resolver * @param {string} [alias] Optional name or alias to link the OOBI resolution to a contact - * @returns {Promise} A promise to the long-running operation + * @returns {Promise>} A promise to the long-running operation */ - async resolve(oobi: string, alias?: string): Promise { + async resolve(oobi: string, alias?: string): Promise> { const path = `/oobis`; const data: any = { url: oobi, @@ -82,10 +85,6 @@ export interface OperationsDeps { ): Promise; } -export interface AgentConfig { - iurls?: string[]; -} - /** * Operations * @remarks @@ -205,9 +204,9 @@ export class KeyEvents { * Retrieve key events for an identifier * @async * @param {string} pre Identifier prefix - * @returns {Promise} A promise to the key events + * @returns {Promise} A promise to the key events */ - async get(pre: string): Promise { + async get(pre: string): Promise { const path = `/events?pre=${pre}`; const data = null; const method = 'GET'; @@ -233,9 +232,9 @@ export class KeyStates { * Retriene the key state for an identifier * @async * @param {string} pre Identifier prefix - * @returns {Promise} A promise to the key states + * @returns {Promise} A promise to the key states */ - async get(pre: string): Promise { + async get(pre: string): Promise { const path = `/states?pre=${pre}`; const data = null; const method = 'GET'; @@ -249,7 +248,7 @@ export class KeyStates { * @param {Array} pres List of identifier prefixes * @returns {Promise} A promise to the key states */ - async list(pres: string[]): Promise { + async list(pres: string[]): Promise { const path = `/states?${pres.map((pre) => `pre=${pre}`).join('&')}`; const data = null; const method = 'GET'; @@ -263,9 +262,9 @@ export class KeyStates { * @param {string} pre Identifier prefix * @param {number} [sn] Optional sequence number * @param {any} [anchor] Optional anchor - * @returns {Promise} A promise to the long-running operation + * @returns {Promise>} A promise to the long-running operation */ - async query(pre: string, sn?: string, anchor?: any): Promise { + async query(pre: string, sn?: string, anchor?: any): Promise> { const path = `/queries`; const data: any = { pre: pre, diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index e7c24c40..bb96c0aa 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -205,7 +205,7 @@ export interface components { c?: string[]; a?: unknown; }; - IcpV2: { + RotV1: { /** @default */ v: string; /** @default */ @@ -216,6 +216,8 @@ export interface components { i: string; /** @default 0 */ s: string; + /** @default */ + p: string; /** @default 0 */ kt: string; k?: string[]; @@ -224,11 +226,11 @@ export interface components { n?: string[]; /** @default 0 */ bt: string; - b?: string[]; - c?: string[]; + br?: string[]; + ba?: string[]; a?: unknown; }; - RotV1: { + DipV1: { /** @default */ v: string; /** @default */ @@ -239,8 +241,6 @@ export interface components { i: string; /** @default 0 */ s: string; - /** @default */ - p: string; /** @default 0 */ kt: string; k?: string[]; @@ -249,11 +249,13 @@ export interface components { n?: string[]; /** @default 0 */ bt: string; - br?: string[]; - ba?: string[]; + b?: string[]; + c?: string[]; a?: unknown; + /** @default */ + di: string; }; - RotV2: { + DrtV1: { /** @default */ v: string; /** @default */ @@ -276,10 +278,231 @@ export interface components { bt: string; br?: string[]; ba?: string[]; + a?: unknown; + }; + VcpV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + ii: string; + /** @default 0 */ + s: string; c?: string[]; + /** @default 0 */ + bt: string; + b?: string[]; + /** @default */ + n: string; + }; + VrtV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + p: string; + /** @default 0 */ + s: string; + /** @default 0 */ + bt: string; + br?: string[]; + ba?: string[]; + }; + IxnV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; a?: unknown; }; - DipV1: { + RctV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + }; + QryV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + dt: string; + /** @default */ + r: string; + /** @default */ + rr: string; + q?: { + [key: string]: unknown; + }; + }; + RpyV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + ProV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + dt: string; + /** @default */ + r: string; + /** @default */ + rr: string; + q?: { + [key: string]: unknown; + }; + }; + BarV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + ExnV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + rp: string; + /** @default */ + p: string; + /** @default */ + dt: string; + /** @default */ + r: string; + q?: { + [key: string]: unknown; + }; + a?: unknown; + e?: { + [key: string]: unknown; + }; + }; + IssV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + ri: string; + /** @default */ + dt: string; + }; + RevV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + ri: string; + /** @default */ + p: string; + /** @default */ + dt: string; + }; + BisV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + ii: string; + /** @default 0 */ + s: string; + ra?: { + [key: string]: unknown; + }; + /** @default */ + dt: string; + }; + BrvV1: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default 0 */ + s: string; + /** @default */ + p: string; + ra?: { + [key: string]: unknown; + }; + /** @default */ + dt: string; + }; + IcpV2: { /** @default */ v: string; /** @default */ @@ -301,10 +524,8 @@ export interface components { b?: string[]; c?: string[]; a?: unknown; - /** @default */ - di: string; }; - DipV2: { + RotV2: { /** @default */ v: string; /** @default */ @@ -315,6 +536,8 @@ export interface components { i: string; /** @default 0 */ s: string; + /** @default */ + p: string; /** @default 0 */ kt: string; k?: string[]; @@ -323,13 +546,12 @@ export interface components { n?: string[]; /** @default 0 */ bt: string; - b?: string[]; + br?: string[]; + ba?: string[]; c?: string[]; a?: unknown; - /** @default */ - di: string; }; - DrtV1: { + DipV2: { /** @default */ v: string; /** @default */ @@ -340,8 +562,6 @@ export interface components { i: string; /** @default 0 */ s: string; - /** @default */ - p: string; /** @default 0 */ kt: string; k?: string[]; @@ -350,9 +570,11 @@ export interface components { n?: string[]; /** @default 0 */ bt: string; - br?: string[]; - ba?: string[]; + b?: string[]; + c?: string[]; a?: unknown; + /** @default */ + di: string; }; DrtV2: { /** @default */ @@ -380,7 +602,7 @@ export interface components { c?: string[]; a?: unknown; }; - VcpV1: { + IxnV2: { /** @default */ v: string; /** @default */ @@ -389,18 +611,44 @@ export interface components { d: string; /** @default */ i: string; - /** @default */ - ii: string; /** @default 0 */ s: string; - c?: string[]; + /** @default */ + p: string; + a?: unknown; + }; + RctV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; /** @default 0 */ - bt: string; - b?: string[]; + s: string; + }; + QryV2: { /** @default */ - n: string; + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + dt: string; + /** @default */ + r: string; + /** @default */ + rr: string; + q?: { + [key: string]: unknown; + }; }; - VrtV1: { + RpyV2: { /** @default */ v: string; /** @default */ @@ -410,13 +658,84 @@ export interface components { /** @default */ i: string; /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + ProV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + dt: string; + /** @default */ + r: string; + /** @default */ + rr: string; + q?: { + [key: string]: unknown; + }; + }; + BarV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + dt: string; + /** @default */ + r: string; + a?: unknown; + }; + XipV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + dt: string; + /** @default */ + r: string; + q?: { + [key: string]: unknown; + }; + a?: unknown; + }; + ExnV2: { + /** @default */ + v: string; + /** @default */ + t: string; + /** @default */ + d: string; + /** @default */ + i: string; + /** @default */ + x: string; + /** @default */ p: string; - /** @default 0 */ - s: string; - /** @default 0 */ - bt: string; - br?: string[]; - ba?: string[]; + /** @default */ + dt: string; + /** @default */ + r: string; + q?: { + [key: string]: unknown; + }; + a?: unknown; }; StateEERecord: { /** @default 0 */ @@ -544,34 +863,6 @@ export interface components { role: string; eid: string; }; - RpyV1: { - /** @default */ - v: string; - /** @default */ - t: string; - /** @default */ - d: string; - /** @default */ - dt: string; - /** @default */ - r: string; - a?: unknown; - }; - RpyV2: { - /** @default */ - v: string; - /** @default */ - t: string; - /** @default */ - d: string; - /** @default */ - i: string; - /** @default */ - dt: string; - /** @default */ - r: string; - a?: unknown; - }; Rpy: components["schemas"]["RpyV1"] | components["schemas"]["RpyV2"]; Challenge: { words: string[]; @@ -638,6 +929,13 @@ export interface components { signing: components["schemas"]["AidRecord"][]; rotation: components["schemas"]["AidRecord"][]; }; + KeyEventRecord: { + ked: components["schemas"]["IcpV1"] | components["schemas"]["RotV1"] | components["schemas"]["IxnV1"] | components["schemas"]["DipV1"] | components["schemas"]["DrtV1"] | components["schemas"]["RctV1"] | components["schemas"]["QryV1"] | components["schemas"]["RpyV1"] | components["schemas"]["ProV1"] | components["schemas"]["BarV1"] | components["schemas"]["ExnV1"] | components["schemas"]["VcpV1"] | components["schemas"]["VrtV1"] | components["schemas"]["IssV1"] | components["schemas"]["RevV1"] | components["schemas"]["BisV1"] | components["schemas"]["BrvV1"] | components["schemas"]["IcpV2"] | components["schemas"]["RotV2"] | components["schemas"]["IxnV2"] | components["schemas"]["DipV2"] | components["schemas"]["DrtV2"] | components["schemas"]["RctV2"] | components["schemas"]["QryV2"] | components["schemas"]["RpyV2"] | components["schemas"]["ProV2"] | components["schemas"]["BarV2"] | components["schemas"]["XipV2"] | components["schemas"]["ExnV2"]; + atc: string; + }; + AgentConfig: { + iurls?: string[]; + }; }; responses: never; parameters: never; diff --git a/test-integration/singlesig-ixn.test.ts b/test-integration/singlesig-ixn.test.ts index aa7513c1..fbb2eb76 100644 --- a/test-integration/singlesig-ixn.test.ts +++ b/test-integration/singlesig-ixn.test.ts @@ -1,4 +1,4 @@ -import { EventResult, SignifyClient } from 'signify-ts'; +import signify, { EventResult, SignifyClient } from 'signify-ts'; import { assertOperations, getOrCreateClients, @@ -25,11 +25,6 @@ afterAll(async () => { await assertOperations(client1, client2); }); -interface KeyState { - i: string; - s: string; - [property: string]: any; -} describe('singlesig-ixn', () => { test('step1', async () => { @@ -46,9 +41,9 @@ describe('singlesig-ixn', () => { }); test('ixn1', async () => { // local keystate before ixn - const keystate0: KeyState = ( + const keystate0: signify.KeyState = ( await client1.keyStates().get(name1_id) - ).at(0); + ).at(0)!; expect(keystate0).not.toBeNull(); // ixn @@ -58,17 +53,17 @@ describe('singlesig-ixn', () => { await waitOperation(client1, await result.op()); // local keystate after ixn - const keystate1: KeyState = ( + const keystate1: signify.KeyState = ( await client1.keyStates().get(name1_id) - ).at(0); + ).at(0)!; expect(parseInt(keystate1.s)).toBeGreaterThan(0); // sequence has incremented assert.equal(parseInt(keystate1.s), parseInt(keystate0.s) + 1); // remote keystate after ixn - const keystate2: KeyState = ( + const keystate2: signify.KeyState = ( await client2.keyStates().get(contact1_id) - ).at(0); + ).at(0)!; // remote keystate is one behind assert.equal(parseInt(keystate2.s), parseInt(keystate1.s) - 1); @@ -77,7 +72,7 @@ describe('singlesig-ixn', () => { .keyStates() .query(contact1_id, keystate1.s, undefined); op = await waitOperation(client2, op); - const keystate3: KeyState = op.response; + const keystate3: signify.KeyState = op.response; // local and remote keystate match assert.equal(keystate3.s, keystate1.s); }); diff --git a/test-integration/singlesig-rot.test.ts b/test-integration/singlesig-rot.test.ts index cf07b070..4f439d88 100644 --- a/test-integration/singlesig-rot.test.ts +++ b/test-integration/singlesig-rot.test.ts @@ -1,5 +1,5 @@ import { afterAll, assert, beforeAll, describe, expect, test } from 'vitest'; -import { EventResult, RotateIdentifierArgs, SignifyClient } from 'signify-ts'; +import signify, { EventResult, RotateIdentifierArgs, SignifyClient } from 'signify-ts'; import { assertOperations, getOrCreateClients, @@ -25,14 +25,6 @@ afterAll(async () => { await assertOperations(client1, client2); }); -interface KeyState { - i: string; - s: string; - k: string[]; - n: string[]; - [property: string]: any; -} - describe('singlesig-rot', () => { test('step1', async () => { assert.equal(name1_id, contact1_id); @@ -48,9 +40,9 @@ describe('singlesig-rot', () => { }); test('rot1', async () => { // local keystate before rot - const keystate0: KeyState = ( + const keystate0: signify.KeyState = ( await client1.keyStates().get(name1_id) - ).at(0); + ).at(0)!; expect(keystate0).not.toBeNull(); assert.strictEqual(keystate0.k.length, 1); assert.strictEqual(keystate0.n.length, 1); @@ -63,9 +55,9 @@ describe('singlesig-rot', () => { await waitOperation(client1, await result.op()); // local keystate after rot - const keystate1: KeyState = ( + const keystate1: signify.KeyState = ( await client1.keyStates().get(name1_id) - ).at(0); + ).at(0)!; expect(parseInt(keystate1.s)).toBeGreaterThan(0); // sequence has incremented assert.equal(parseInt(keystate1.s), parseInt(keystate0.s) + 1); @@ -75,9 +67,9 @@ describe('singlesig-rot', () => { expect(keystate1.n[0]).not.toEqual(keystate0.n[0]); // remote keystate after rot - const keystate2: KeyState = ( + const keystate2: signify.KeyState = ( await client2.keyStates().get(contact1_id) - ).at(0); + ).at(0)!; // remote keystate is one behind assert.equal(parseInt(keystate2.s), parseInt(keystate1.s) - 1); @@ -86,7 +78,7 @@ describe('singlesig-rot', () => { .keyStates() .query(contact1_id, keystate1.s, undefined); op = await waitOperation(client2, op); - const keystate3: KeyState = op.response; + const keystate3: signify.KeyState = op.response; // local and remote keystate match assert.equal(keystate3.s, keystate1.s); assert.equal(keystate3.k[0], keystate1.k[0]); From 7a0e185f296b5eeadea87bb2695291b59bde15cd Mon Sep 17 00:00:00 2001 From: Vu Van Duc Date: Wed, 6 Aug 2025 15:53:56 +0700 Subject: [PATCH 18/22] chore: remove any type for decrypter, encrypter and utils --- src/keri/core/utils.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/keri/core/utils.ts b/src/keri/core/utils.ts index 6e1cf980..4f10669f 100644 --- a/src/keri/core/utils.ts +++ b/src/keri/core/utils.ts @@ -3,9 +3,8 @@ import { Seqner } from './seqner.ts'; import { Prefixer } from './prefixer.ts'; import { Saider } from './saider.ts'; import { Serder } from './serder.ts'; -import { b } from './core.ts'; -export function pad(n: any, width = 3, z = 0) { +export function pad(n: string, width = 3, z = 0) { return (String(z).repeat(width) + String(n)).slice(String(n).length); } @@ -16,8 +15,8 @@ export function pad(n: any, width = 3, z = 0) { * @param {*} ked ked is key event dict * @param {*} labels labels is list of element labels in ked from which to extract values */ -export function extractValues(ked: any, labels: any) { - let values = []; +export function extractValues(ked: Record, labels: string[]) { + let values: unknown[] = []; for (const label of labels) { values = extractElementValues(ked[label], values); } @@ -41,7 +40,7 @@ export function arrayEquals(ar1: Uint8Array, ar2: Uint8Array) { * @param {*} values */ -function extractElementValues(element: any, values: any) { +function extractElementValues(element: unknown, values: unknown[]) { let data = []; try { From cfd92272f242ff87b7b4d148b0c21fe485339668 Mon Sep 17 00:00:00 2001 From: Vu Van Duc Date: Fri, 8 Aug 2025 17:37:20 +0700 Subject: [PATCH 19/22] feat(ui): replace any type --- src/keri/app/aiding.ts | 16 ++-- src/keri/app/clienting.ts | 8 +- src/keri/app/controller.ts | 21 ++-- src/keri/app/credentialing.ts | 28 +++--- src/keri/app/delegating.ts | 5 +- src/keri/app/exchanging.ts | 4 +- src/keri/app/habery.ts | 8 +- src/keri/core/authing.ts | 4 +- src/keri/core/decrypter.ts | 4 +- src/keri/core/encrypter.ts | 4 +- src/keri/core/eventing.ts | 116 ++++++++++++++++++----- src/keri/core/httping.ts | 20 ++-- src/keri/core/keeping.ts | 96 ++++++++++++------- src/keri/core/manager.ts | 38 ++++---- src/keri/core/pather.ts | 2 +- src/keri/core/prefixer.ts | 68 ++++++------- src/keri/core/saider.ts | 46 +++++---- src/keri/core/serder.ts | 45 +++++---- src/keri/core/tholder.ts | 65 +++++++------ src/keri/core/vdring.ts | 16 +++- test-integration/challenge.test.ts | 8 +- test-integration/credentials.test.ts | 2 +- test-integration/delegation.test.ts | 4 +- test-integration/multisig-holder.test.ts | 11 ++- test-integration/multisig.test.ts | 3 +- test-integration/utils/multisig-utils.ts | 23 +++-- test-integration/utils/test-util.ts | 2 +- test/app/clienting.test.ts | 9 +- test/app/credentialing.test.ts | 11 ++- test/app/test-utils.ts | 32 +++---- test/core/decrypter.test.ts | 6 +- test/core/eventing.test.ts | 4 +- test/core/manager.test.ts | 13 +-- test/core/vdring.test.ts | 2 +- 34 files changed, 452 insertions(+), 292 deletions(-) diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index 1d40d6cd..f08e2c27 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -1,14 +1,14 @@ -import { Tier } from '../core/salter.ts'; -import { Algos } from '../core/manager.ts'; -import { incept, interact, reply, rotate } from '../core/eventing.ts'; +import { components } from '../../types/keria-api-schema.ts'; import { b, Ilks, Serials, Vrsn_1_0 } from '../core/core.ts'; -import { Tholder } from '../core/tholder.ts'; -import { MtrDex } from '../core/matter.ts'; -import { Serder } from '../core/serder.ts'; +import { incept, interact, reply, ReplyData, rotate } from '../core/eventing.ts'; import { parseRangeHeaders } from '../core/httping.ts'; import { IdentifierManagerFactory } from '../core/keeping.ts'; import { HabState } from '../core/keyState.ts'; -import { components } from '../../types/keria-api-schema.ts'; +import { Algos } from '../core/manager.ts'; +import { MtrDex } from '../core/matter.ts'; +import { Tier } from '../core/salter.ts'; +import { Serder } from '../core/serder.ts'; +import { Tholder } from '../core/tholder.ts'; /** Arguments required to create an identfier */ export interface CreateIdentiferArgs { @@ -475,7 +475,7 @@ export class Identifier { eid?: string, stamp?: string ): Serder { - const data: any = { + const data: ReplyData = { cid: pre, role: role, }; diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index 3541d81d..56b321b8 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -5,9 +5,9 @@ import { ExternalModule, IdentifierManagerFactory } from '../core/keeping.ts'; import { Tier } from '../core/salter.ts'; import { Identifier } from './aiding.ts'; -import { Contacts, Challenges } from './contacting.ts'; +import { Challenges, Contacts } from './contacting.ts'; import { Agent, Controller } from './controller.ts'; -import { Oobis, Operations, KeyEvents, KeyStates, Config } from './coring.ts'; +import { Config, KeyEvents, KeyStates, Oobis, Operations } from './coring.ts'; import { Credentials, Ipex, Registries, Schemas } from './credentialing.ts'; import { Delegations } from './delegating.ts'; import { Escrows } from './escrowing.ts'; @@ -176,14 +176,14 @@ export class SignifyClient { async fetch( path: string, method: string, - data: any, + data: Record | null | undefined, extraHeaders?: Headers ): Promise { const headers = new Headers(); let signed_headers = new Headers(); const final_headers = new Headers(); - headers.set('Signify-Resource', this.controller.pre); + headers.set('Signify-Resource', String(this.controller.pre)); headers.set( HEADER_SIG_TIME, new Date().toISOString().replace('Z', '000+00:00') diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index 2495ee9e..8a52606c 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -3,7 +3,7 @@ import { Salter, Tier } from '../core/salter.ts'; import { MtrDex } from '../core/matter.ts'; import { Diger } from '../core/diger.ts'; import { incept, rotate, interact } from '../core/eventing.ts'; -import { Serder } from '../core/serder.ts'; +import { Serder, SerderSAD } from '../core/serder.ts'; import { Tholder } from '../core/tholder.ts'; import { Ilks, b, Serials, Vrsn_1_0 } from '../core/core.ts'; import { Verfer } from '../core/verfer.ts'; @@ -12,6 +12,7 @@ import { Decrypter } from '../core/decrypter.ts'; import { Cipher } from '../core/cipher.ts'; import { Seqner } from '../core/seqner.ts'; import { CesrNumber } from '../core/number.ts'; +import { Signer } from '../core/signer.ts'; /** * Agent is a custodial entity that can be used in conjuntion with a local Client to establish the @@ -227,11 +228,12 @@ export class Controller { approveDelegation(_agent: Agent) { const seqner = new Seqner({ sn: _agent.sn }); - const anchor = { i: _agent.pre, s: seqner.snh, d: _agent.said }; - const sn = new CesrNumber({}, undefined, this.serder.sad['s']).num + 1; + const anchor = { i: _agent.pre, s: seqner.snh, d: _agent.said! }; + const sn = + new CesrNumber({}, undefined, String(this.serder.sad['s'])).num + 1; this.serder = interact({ - pre: this.serder.pre, - dig: this.serder.sad['d'], + pre: this.serder.pre || '', + dig: this.serder.sad['d'] || '', sn: sn, data: [anchor], version: Vrsn_1_0, @@ -240,7 +242,7 @@ export class Controller { return [this.signer.sign(this.serder.raw, 0).qb64]; } - get pre(): string { + get pre(): string | undefined { return this.serder.pre; } @@ -265,7 +267,10 @@ export class Controller { wits: [], }); } else { - return new Serder({ sad: state.controller['ee'] }); + return new Serder({ + sad: state.controller['ee'], + d: '', + } as SerderSAD); } } @@ -386,7 +391,7 @@ export class Controller { const signers = []; for (const prx of prxs) { const cipher = new Cipher({ qb64: prx }); - const dsigner = decrypter.decrypt(null, cipher, true); + const dsigner = decrypter.decrypt(null, cipher, true) as Signer; signers.push(dsigner); nprxs.push(encrypter.encrypt(b(dsigner.qb64)).qb64); } diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index cdb7d184..3e67c224 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -1,26 +1,26 @@ -import { SignifyClient } from './clienting.ts'; -import { interact, messagize } from '../core/eventing.ts'; -import { vdr } from '../core/vdring.ts'; import { b, d, Dict, - Protocols, Ilks, + Protocols, Serials, versify, Vrsn_1_0, } from '../core/core.ts'; -import { Saider } from '../core/saider.ts'; +import { interact, InteractEventData, messagize } from '../core/eventing.ts'; +import { HabState } from '../core/keyState.ts'; +import { BaseSAD, Saider } from '../core/saider.ts'; import { Serder } from '../core/serder.ts'; import { Siger } from '../core/siger.ts'; -import { TraitDex } from './habery.ts'; import { serializeACDCAttachment, serializeIssExnAttachment, } from '../core/utils.ts'; +import { vdr } from '../core/vdring.ts'; +import { SignifyClient } from './clienting.ts'; import { Operation } from './coring.ts'; -import { HabState } from '../core/keyState.ts'; +import { TraitDex } from './habery.ts'; import { components } from '../../types/keria-api-schema.ts'; @@ -431,7 +431,7 @@ export class Credentials { const dt = datetime ?? new Date().toISOString().replace('Z', '000+00:00'); - const cred = (await this.get(said)); + const cred = await this.get(said); // Create rev const _rev = { @@ -448,20 +448,16 @@ export class Credentials { const [, rev] = Saider.saidify(_rev); // create ixn - let ixn = {}; + let ixn: BaseSAD; let sigs = []; const state = hab.state; - if (state.c !== undefined && state.c.includes('EO')) { - var estOnly = true; - } else { - var estOnly = false; - } + const estOnly = state.c !== undefined && state.c.includes('EO'); const sn = parseInt(state.s, 16); const dig = state.d; - const data: any = [ + const data: InteractEventData[] = [ { i: rev.i, s: rev.s, @@ -501,7 +497,7 @@ export class Credentials { return { rev: new Serder(rev), - anc: new Serder(ixn), + anc: new Serder(ixn || {}), op, }; } diff --git a/src/keri/app/delegating.ts b/src/keri/app/delegating.ts index cccb30d9..31efffcf 100644 --- a/src/keri/app/delegating.ts +++ b/src/keri/app/delegating.ts @@ -18,7 +18,10 @@ export class Delegations { * @param {any} [data] The anchoring interaction event * @returns {Promise} A promise to the delegated approval result */ - async approve(name: string, data?: any): Promise { + async approve( + name: string, + data?: { i: string; s: string; d: string } + ): Promise { const { serder, sigs, jsondata } = await this.client .identifiers() .createInteract(name, data); diff --git a/src/keri/app/exchanging.ts b/src/keri/app/exchanging.ts index 94946649..1faf43cc 100644 --- a/src/keri/app/exchanging.ts +++ b/src/keri/app/exchanging.ts @@ -4,7 +4,7 @@ import { Serder } from '../core/serder.ts'; import { nowUTC } from '../core/utils.ts'; import { Pather } from '../core/pather.ts'; import { Counter, CtrDex } from '../core/counter.ts'; -import { Saider } from '../core/saider.ts'; +import { BaseSAD, Saider } from '../core/saider.ts'; import { HabState } from '../core/keyState.ts'; /** @@ -165,7 +165,7 @@ export function exchange( const q = modifiers !== undefined ? modifiers : {}; const ems = embeds != undefined ? embeds : {}; - let e = {} as Dict; + let e = {} as BaseSAD; let end = ''; Object.entries(ems).forEach(([key, value]) => { const serder = value[0]; diff --git a/src/keri/app/habery.ts b/src/keri/app/habery.ts index eeacadfd..d6b4a5ba 100644 --- a/src/keri/app/habery.ts +++ b/src/keri/app/habery.ts @@ -1,10 +1,10 @@ +import { Diger } from '../core/diger.ts'; +import { incept } from '../core/eventing.ts'; import { Algos, Manager } from '../core/manager.ts'; import { MtrDex } from '../core/matter.ts'; import { Salter } from '../core/salter.ts'; -import { Verfer } from '../core/verfer.ts'; -import { Diger } from '../core/diger.ts'; -import { incept } from '../core/eventing.ts'; import { Serder } from '../core/serder.ts'; +import { Verfer } from '../core/verfer.ts'; export class TraitCodex { EstOnly: string = 'EO'; // Only allow establishment events @@ -48,7 +48,7 @@ export class Hab { this.serder = icp; } - get pre(): string { + get pre(): string | undefined { return this.serder.sad['i']; } } diff --git a/src/keri/core/authing.ts b/src/keri/core/authing.ts index 424979ea..3cc086d9 100644 --- a/src/keri/core/authing.ts +++ b/src/keri/core/authing.ts @@ -41,7 +41,9 @@ export class Authenticater { } inputs.forEach((input) => { const items = new Array(); - input.fields!.forEach((field: string) => { + input.fields!.forEach((field) => { + if (typeof field !== 'string') return; + if (field.startsWith('@')) { if (field == '@method') { items.push(`"${field}": ${method}`); diff --git a/src/keri/core/decrypter.ts b/src/keri/core/decrypter.ts index 4e5f04db..6ad83cb0 100644 --- a/src/keri/core/decrypter.ts +++ b/src/keri/core/decrypter.ts @@ -7,7 +7,7 @@ import { EmptyMaterialError } from './kering.ts'; import { Salter } from './salter.ts'; export class Decrypter extends Matter { - private readonly _decrypt: any; + private readonly _decrypt: typeof this._x25519; constructor( { raw, code = MtrDex.X25519_Private, qb64, qb64b, qb2 }: MatterArgs, seed: Uint8Array | undefined = undefined @@ -59,7 +59,7 @@ export class Decrypter extends Matter { cipher = new Cipher({ qb64b: ser }); } - return this._decrypt(cipher, this.raw, transferable); + return this._decrypt(cipher!, this.raw, transferable); } _x25519(cipher: Cipher, prikey: Uint8Array, transferable: boolean = false) { diff --git a/src/keri/core/encrypter.ts b/src/keri/core/encrypter.ts index 825b9fc0..dfa3a3ad 100644 --- a/src/keri/core/encrypter.ts +++ b/src/keri/core/encrypter.ts @@ -7,7 +7,7 @@ import { Cipher } from './cipher.ts'; import { arrayEquals } from './utils.ts'; export class Encrypter extends Matter { - private _encrypt: any; + private _encrypt: typeof this._x25519; constructor( { raw, code = MtrDex.X25519, qb64, qb64b, qb2 }: MatterArgs, verkey: Uint8Array | null = null @@ -60,7 +60,7 @@ export class Encrypter extends Matter { code = MtrDex.X25519_Cipher_Seed; } - return this._encrypt(matter!.qb64, this.raw, code); + return this._encrypt(matter!.qb64b, this.raw, code); } _x25519(ser: Uint8Array, pubkey: Uint8Array, code: string) { diff --git a/src/keri/core/eventing.ts b/src/keri/core/eventing.ts index 6d14101d..22aaf3a0 100644 --- a/src/keri/core/eventing.ts +++ b/src/keri/core/eventing.ts @@ -1,24 +1,23 @@ +import { Cigar } from './cigar.ts'; import { b, concat, - Dict, - Protocols, Ilks, + Protocols, Serials, versify, Version, Vrsn_1_0, } from './core.ts'; -import { Tholder } from './tholder.ts'; +import { Counter, CtrDex } from './counter.ts'; +import { MtrDex, NonTransDex } from './matter.ts'; import { CesrNumber } from './number.ts'; import { Prefixer } from './prefixer.ts'; +import { BaseSAD, Saider } from './saider.ts'; +import { Seqner } from './seqner.ts'; import { Serder } from './serder.ts'; -import { MtrDex, NonTransDex } from './matter.ts'; -import { Saider } from './saider.ts'; import { Siger } from './siger.ts'; -import { Cigar } from './cigar.ts'; -import { Counter, CtrDex } from './counter.ts'; -import { Seqner } from './seqner.ts'; +import { Tholder } from './tholder.ts'; const MaxIntThold = 2 ** 32 - 1; @@ -28,9 +27,9 @@ export interface RotateArgs { dig?: string; ilk?: string; sn?: number; - isith?: number | string | Array; + isith?: number | string | Array | string[][]; ndigs?: Array; - nsith?: number | string | Array; + nsith?: number | string | Array | string[][]; toad?: number; wits?: Array; cuts?: Array; @@ -43,6 +42,72 @@ export interface RotateArgs { intive?: boolean; } +export interface ReplyData { + cid?: string; + role?: string; + eid?: string; +} + +export interface RotateEventSAD extends BaseSAD, Record { + v: string; + t: string; + d: string; + i: string; + s: string; + p?: string; + kt: number | string | string[] | string[][]; + k: string[]; + nt: number | string | string[] | string[][]; + n: string[]; + bt: number | string; + br?: string[]; + ba?: string[]; + a: Record[]; +} + +export interface InceptEventSAD extends BaseSAD, Record { + v: string; + t: string; + d: string; + i: string; + s: string; + kt: number | string | string[] | string[][]; + k: string[]; + nt?: number | string | string[] | string[][]; + n?: string[]; + bt: number | string; + b: string[]; + c: string[]; + a: Record[]; +} + +export interface InteractEventData { + i: string; + s: string; + d: string; +} +export interface InteractEventSAD extends BaseSAD { + i: string; + t: string; + p: string; + a: InteractEventData[]; +} + +export interface ReplyEventSAD extends BaseSAD { + t: string; + dt: string; + r: string; + a: ReplyData; +} + +export interface SealData { + i: string; + s: string; + d: string; +} + +export type Seal = [string, SealData]; + export function rotate({ pre = undefined, keys, @@ -198,11 +263,11 @@ export function rotate({ throw new Error(`Invalid toad = ${_toad} for wit = ${wits}`); } } - const _sad = { + const _sad: RotateEventSAD = { v: vs, t: _ilk, d: '', - i: pre, + i: String(pre), s: sner.numh, p: dig, kt: @@ -227,7 +292,7 @@ export function rotate({ : _toad.toString(16), br: cuts, ba: adds, - a: data != undefined ? data : [], + a: data != undefined ? (data as Record[]) : [], }; const [, sad] = Saider.saidify(_sad); return new Serder(sad); @@ -358,7 +423,7 @@ export function incept({ cnfg = cnfg == undefined ? new Array() : cnfg; data = data == undefined ? new Array() : data; - let sad = { + let sad: InceptEventSAD = { v: vs, t: ilk, d: '', @@ -371,8 +436,8 @@ export function incept({ bt: intive ? toader.num : toader.numh, b: wits, c: cnfg, - a: data, - } as Dict; + a: data as Record[], + }; if (delpre != undefined) { sad['di'] = delpre; @@ -413,7 +478,7 @@ export function incept({ export function messagize( serder: Serder, sigers?: Array, - seal?: any, + seal?: Seal, wigers?: Array, cigars?: Array, pipelined: boolean = false @@ -525,13 +590,14 @@ interface InteractArgs { pre: string; dig: string; sn: number; - data: Array; + data: InteractEventSAD['a']; version: Version | undefined; kind: Serials | undefined; } -export function interact(args: InteractArgs): Serder { - let { pre, dig, sn, data, version, kind } = args; +export function interact(args: InteractArgs): Serder { + const { pre, dig, sn, version, kind } = args; + let { data } = args; const vs = versify(Protocols.KERI, version, kind, 0); const ilk = Ilks.ixn; const sner = new CesrNumber({}, sn); @@ -540,9 +606,9 @@ export function interact(args: InteractArgs): Serder { throw new Error(`Invalid sn = 0x${sner.numh} for ixn.`); } - data = data == undefined ? new Array() : data; + data = data == undefined ? new Array() : data; - let sad = { + let sad: InteractEventSAD = { v: vs, t: ilk, d: '', @@ -550,7 +616,7 @@ export function interact(args: InteractArgs): Serder { s: sner.numh, p: dig, a: data, - } as Dict; + }; [, sad] = Saider.saidify(sad); @@ -559,7 +625,7 @@ export function interact(args: InteractArgs): Serder { export function reply( route: string = '', - data: any | undefined, + data: ReplyData | undefined, stamp: string | undefined, version: Version | undefined, kind: Serials = Serials.JSON @@ -568,7 +634,7 @@ export function reply( if (data == undefined) { data = {}; } - const _sad = { + const _sad: ReplyEventSAD = { v: vs, t: Ilks.rpy, d: '', diff --git a/src/keri/core/httping.ts b/src/keri/core/httping.ts index b0a881c5..93344ca2 100644 --- a/src/keri/core/httping.ts +++ b/src/keri/core/httping.ts @@ -138,14 +138,14 @@ export class Unqualified { } export class Inputage { - public name: any; - public fields: any; - public created: any; - public expires: any; - public nonce: any; - public alg: any; - public keyid: any; - public context: any; + public name: string = ""; + public fields: Item[0][] = []; + public created?: Item[0]; + public expires?: Item[0]; + public nonce?: Item[0]; + public alg?: Item[0]; + public keyid?: Item[0]; + public context?: Item[0]; } export function desiginput(value: string): Array { @@ -155,9 +155,7 @@ export function desiginput(value: string): Array { sid.forEach((value, key) => { const siginput = new Inputage(); siginput.name = key; - let list: Item[]; - let params; - [list, params] = value as [Item[], Parameters]; + const [list, params] = value as [Item[], Parameters]; siginput.fields = list.map((item) => item[0]); if (!params.has('created')) { diff --git a/src/keri/core/keeping.ts b/src/keri/core/keeping.ts index fb520c4e..c902ed2a 100644 --- a/src/keri/core/keeping.ts +++ b/src/keri/core/keeping.ts @@ -1,22 +1,21 @@ -import { Salter } from './salter.ts'; -import { Algos, SaltyCreator, RandyCreator } from './manager.ts'; -import { MtrDex } from './matter.ts'; -import { Tier } from './salter.ts'; import { Encrypter } from '../core/encrypter.ts'; -import { Decrypter } from './decrypter.ts'; -import { b } from './core.ts'; import { Cipher } from './cipher.ts'; +import { b } from './core.ts'; +import { Decrypter } from './decrypter.ts'; import { Diger } from './diger.ts'; -import { Prefixer } from './prefixer.ts'; -import { Signer } from './signer.ts'; import { ExternState, GroupKeyState, HabState, + KeyState, RandyKeyState, SaltyKeyState, - KeyState, } from './keyState.ts'; +import { Algos, RandyCreator, SaltyCreator } from './manager.ts'; +import { MtrDex } from './matter.ts'; +import { Prefixer } from './prefixer.ts'; +import { Salter, Tier } from './salter.ts'; +import { Signer } from './signer.ts'; /** External module definition */ export interface ExternalModuleType { @@ -83,6 +82,33 @@ export interface IdentifierManager< ): Promise; } +export interface KArgs + extends IdentifierManagerParams, + Record { + pidx?: number; + kidx?: number; + tier?: Tier; + stem?: string | undefined; + transferable?: boolean; + code?: string; + count?: number; + icodes?: string[]; + ncode?: string; + ncount?: number; + ncodes?: string[]; + dcode?: string; + bran?: string | undefined; + sxlt?: string; + prxs?: string[] | undefined; + nxts?: string[] | undefined; + mhab?: HabState; + states?: KeyState[] | undefined; + rstates?: KeyState[] | undefined; + keys?: string[]; + ndigs?: string[]; + extern_type?: string; +} + /** * Creates IdentifierManager instances based on the algorithm and key indexes. */ @@ -112,7 +138,7 @@ export class IdentifierManagerFactory { * @param pidx * @param kargs */ - new(algo: Algos, pidx: number, kargs: any) { + new(algo: Algos, pidx: number, kargs: KArgs) { switch (algo) { case Algos.salty: return new SaltyIdentifierManager( @@ -141,7 +167,7 @@ export class IdentifierManagerFactory { kargs['transferable'], kargs['ncode'], kargs['ncount'], - kargs['ncodes'], + kargs['ncodes']!, kargs['dcode'], kargs['prxs'], kargs['nxts'] @@ -149,21 +175,24 @@ export class IdentifierManagerFactory { case Algos.group: return new GroupIdentifierManager( this, - kargs['mhab'], + kargs['mhab']!, kargs['states'], kargs['rstates'], kargs['keys'], kargs['ndigs'] ); case Algos.extern: { - const ModuleConstructor = this.modules[kargs.extern_type]; + const ModuleConstructor = this.modules[kargs.extern_type!]; if (!ModuleConstructor) { throw new Error( `unsupported external module type ${kargs.extern_type}` ); } - return new ModuleConstructor(pidx, kargs); + return new ModuleConstructor( + pidx, + kargs as IdentifierManagerParams + ); } default: throw new Error('Unknown algo'); @@ -563,12 +592,13 @@ export class RandyIdentifierManager implements IdentifierManager { this.creator = new RandyCreator(); - this.signers = this.prxs.map((prx) => - this.decrypter.decrypt( - new Cipher({ qb64: prx }).qb64b, - undefined, - this.transferable - ) + this.signers = this.prxs.map( + (prx) => + this.decrypter.decrypt( + new Cipher({ qb64: prx }).qb64b, + undefined, + this.transferable + ) as Signer ); } @@ -622,12 +652,13 @@ export class RandyIdentifierManager implements IdentifierManager { this.transferable = transferable; this.prxs = this.nxts; - const signers = this.nxts!.map((nxt) => - this.decrypter.decrypt( - undefined, - new Cipher({ qb64: nxt }), - this.transferable - ) + const signers = this.nxts!.map( + (nxt) => + this.decrypter.decrypt( + undefined, + new Cipher({ qb64: nxt }), + this.transferable + ) as Signer ); const verfers = signers.map((signer) => signer.verfer.qb64); const nsigners = this.creator.create( @@ -655,12 +686,13 @@ export class RandyIdentifierManager implements IdentifierManager { indices: number[] | undefined = undefined, ondices: number[] | undefined = undefined ): Promise { - const signers = this.prxs!.map((prx) => - this.decrypter.decrypt( - new Cipher({ qb64: prx }).qb64b, - undefined, - this.transferable - ) + const signers = this.prxs!.map( + (prx) => + this.decrypter.decrypt( + new Cipher({ qb64: prx }).qb64b, + undefined, + this.transferable + ) as Signer ); if (indexed) { diff --git a/src/keri/core/manager.ts b/src/keri/core/manager.ts index 59ccd440..0503093b 100644 --- a/src/keri/core/manager.ts +++ b/src/keri/core/manager.ts @@ -1,13 +1,13 @@ -import { Encrypter } from './encrypter.ts'; +import { Cigar } from './cigar.ts'; +import { b } from './core.ts'; import { Decrypter } from './decrypter.ts'; +import { Diger } from './diger.ts'; +import { Encrypter } from './encrypter.ts'; +import { MtrDex } from './matter.ts'; import { Salter, Tier } from './salter.ts'; +import { Siger } from './siger.ts'; import { Signer } from './signer.ts'; import { Verfer } from './verfer.ts'; -import { MtrDex } from './matter.ts'; -import { Diger } from './diger.ts'; -import { Cigar } from './cigar.ts'; -import { Siger } from './siger.ts'; -import { b } from './core.ts'; /** * Kinds of key pair generation algorithms. @@ -310,7 +310,11 @@ export class SaltyCreator implements Creator { } export class Creatory { - private readonly _make: any; + private readonly _make: ( + salt?: string, + tier?: Tier, + stem?: string + ) => Creator; constructor(algo: Algos = Algos.salty) { switch (algo) { case Algos.randy: @@ -324,16 +328,16 @@ export class Creatory { } } - make(...args: any[]): Creator { - return this._make(...args); + make(salt?: string, tier?: string, stem?: string): Creator { + return this._make(salt, tier as Tier, stem); } _makeRandy(): Creator { return new RandyCreator(); } - _makeSalty(...args: any[]): Creator { - return new SaltyCreator(...args); + _makeSalty(salt?: string, tier?: Tier, stem?: string): Creator { + return new SaltyCreator(salt, tier, stem); } } @@ -373,10 +377,10 @@ export interface ManagerArgs { } export interface ManagerInceptArgs { - icodes?: any | undefined; + icodes?: string[] | undefined; icount?: number; icode?: string; - ncodes?: any | undefined; + ncodes?: string[] | undefined; ncount?: number; ncode?: string; dcode?: string; @@ -391,7 +395,7 @@ export interface ManagerInceptArgs { interface RotateArgs { pre: string; - ncodes?: any | undefined; + ncodes?: string[] | undefined; ncount?: number; ncode?: string; dcode?: string; @@ -564,7 +568,7 @@ export class Manager { data.salt = this._encrypter == undefined ? salter.qb64 - : this._encrypter.encrypt(null, salter); + : this._encrypter.encrypt(null, salter).qb64; this.ks.pinPrms(keys, data); } } @@ -1218,7 +1222,7 @@ class Keeper implements KeyStore { const out = new Array<[string, Signer]>(); this._pris.forEach(function (val, pubKey) { const verfer = new Verfer({ qb64: pubKey }); - const signer = decrypter.decrypt(val, null, verfer.transferable); + const signer = decrypter.decrypt(val, null, verfer.transferable) as Signer; out.push([pubKey, signer]); }); return out; @@ -1245,7 +1249,7 @@ class Keeper implements KeyStore { } const verfer = new Verfer({ qb64: pubKey }); - return decrypter.decrypt(val, null, verfer.transferable); + return decrypter.decrypt(val, null, verfer.transferable) as Signer; } pinPths(pubKey: string, val: PubPath): boolean { diff --git a/src/keri/core/pather.ts b/src/keri/core/pather.ts index 7bd2d4e3..91d0693b 100644 --- a/src/keri/core/pather.ts +++ b/src/keri/core/pather.ts @@ -76,7 +76,7 @@ export class Pather extends Bexter { } } - static _bextify(path: any[]): string { + static _bextify(path: (number | string)[]): string { const vath = []; for (const p of path) { let sp = ''; diff --git a/src/keri/core/prefixer.ts b/src/keri/core/prefixer.ts index 27abd039..a1fe123f 100644 --- a/src/keri/core/prefixer.ts +++ b/src/keri/core/prefixer.ts @@ -1,19 +1,28 @@ -import { Matter, MatterArgs, MtrDex } from './matter.ts'; +import { blake3 } from '@noble/hashes/blake3'; +import { Ilks } from './core.ts'; import { EmptyMaterialError } from './kering.ts'; -import { Dict, Ilks } from './core.ts'; +import { Matter, MatterArgs, MtrDex } from './matter.ts'; +import { BaseSAD } from './saider.ts'; import { sizeify } from './serder.ts'; import { Verfer } from './verfer.ts'; -import { blake3 } from '@noble/hashes/blake3'; const Dummy: string = '#'; -export class Prefixer extends Matter { +export interface PrefixerSAD extends BaseSAD { + k?: string[]; + n?: string | string[]; + b?: string[]; + a?: Record[]; + i?: string; +} + +export class Prefixer extends Matter { // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type private readonly _derive: Function | undefined; // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type private readonly _verify: Function | undefined; - constructor({ raw, code, qb64b, qb64, qb2 }: MatterArgs, ked?: Dict) { + constructor({ raw, code, qb64b, qb64, qb2 }: MatterArgs, ked?: T) { try { super({ raw, code, qb64b, qb64, qb2 }); } catch (e) { @@ -23,7 +32,7 @@ export class Prefixer extends Matter { } if (code == undefined) { - super({ qb64: ked['i'], code: code }); + super({ qb64: String(ked['i']), code: code }); code = this.code; } @@ -57,7 +66,7 @@ export class Prefixer extends Matter { } } - derive(sad: Dict): [Uint8Array, string] { + derive(sad: BaseSAD): [Uint8Array, string] { if (sad['i'] != Ilks.icp) { throw new Error( `Non-incepting ilk ${sad['i']} for prefix derivation` @@ -66,7 +75,7 @@ export class Prefixer extends Matter { return this._derive!(sad); } - verify(sad: Dict, prefixed: boolean = false): boolean { + verify(sad: BaseSAD, prefixed: boolean = false): boolean { if (sad['i'] != Ilks.icp) { throw new Error( `Non-incepting ilk ${sad['i']} for prefix derivation` @@ -75,12 +84,12 @@ export class Prefixer extends Matter { return this._verify!(sad, this.qb64, prefixed); } - static _derive_ed25519N(sad: Dict): [Uint8Array, string] { + static _derive_ed25519N(sad: PrefixerSAD): [Uint8Array, string] { let verfer; const keys = sad['k']; - if (keys.length != 1) { + if (keys?.length != 1) { throw new Error( - `Basic derivation needs at most 1 key got ${keys.length} keys instead` + `Basic derivation needs at most 1 key got ${keys?.length} keys instead` ); } try { @@ -93,21 +102,22 @@ export class Prefixer extends Matter { throw new Error(`Mismatch derivation code = ${verfer.code}`); } - const next = 'n' in sad ? sad['n'] : []; + const next = 'n' in sad && sad['n'] ? sad['n'] : []; if (verfer.code == MtrDex.Ed25519N && next.length > 0) { throw new Error( `Non-empty nxt = ${next} for non-transferable code = ${verfer.code}` ); } - const backers = 'b' in sad ? sad['b'] : []; + const backers = 'b' in sad && sad['b'] ? sad['b'] : []; if (verfer.code == MtrDex.Ed25519N && backers.length > 0) { throw new Error( `Non-empty b =${backers} for non-transferable code = ${verfer.code}` ); } - const anchor = 'a' in sad ? sad['a'] : []; + const anchor = + 'a' in sad && sad['a'] && Array.isArray(sad['a']) ? sad['a'] : []; if (verfer.code == MtrDex.Ed25519N && anchor.length > 0) { throw new Error( `Non-empty a = ${verfer.code} for non-transferable code = ${verfer.code}` @@ -117,12 +127,12 @@ export class Prefixer extends Matter { return [verfer.raw, verfer.code]; } - static _derive_ed25519(sad: Dict): [Uint8Array, string] { + static _derive_ed25519(sad: PrefixerSAD): [Uint8Array, string] { let verfer; const keys = sad['k']; - if (keys.length != 1) { + if (keys?.length != 1) { throw new Error( - `Basic derivation needs at most 1 key got ${keys.length} keys instead` + `Basic derivation needs at most 1 key got ${keys?.length} keys instead` ); } @@ -139,9 +149,9 @@ export class Prefixer extends Matter { return [verfer.raw, verfer.code]; } - static _derive_blake3_256(sad: Dict): [Uint8Array, string] { + static _derive_blake3_256(sad: PrefixerSAD): [Uint8Array, string] { const ilk = sad['t']; - if (![Ilks.icp, Ilks.dip, Ilks.vcp, Ilks.dip].includes(ilk)) { + if (!ilk || ![Ilks.icp, Ilks.dip, Ilks.vcp, Ilks.dip].includes(ilk)) { throw new Error(`Invalid ilk = ${ilk} to derive pre.`); } @@ -152,14 +162,10 @@ export class Prefixer extends Matter { return [dig, MtrDex.Blake3_256]; } - _verify_ed25519N( - sad: Dict, - pre: string, - prefixed: boolean = false - ): boolean { + _verify_ed25519N(sad: T, pre: string, prefixed: boolean = false): boolean { try { const keys = sad['k']; - if (keys.length != 1) { + if (keys?.length != 1) { return false; } @@ -171,7 +177,7 @@ export class Prefixer extends Matter { return false; } - const next = 'n' in sad ? sad['n'] : []; + const next = 'n' in sad && sad['n'] ? sad['n'] : []; if (next.length > 0) { // must be empty return false; @@ -183,14 +189,10 @@ export class Prefixer extends Matter { return true; } - _verify_ed25519( - sad: Dict, - pre: string, - prefixed: boolean = false - ): boolean { + _verify_ed25519(sad: T, pre: string, prefixed: boolean = false): boolean { try { const keys = sad['k']; - if (keys.length != 1) { + if (keys?.length != 1) { return false; } @@ -209,7 +211,7 @@ export class Prefixer extends Matter { } _verify_blake3_256( - sad: Dict, + sad: T, pre: string, prefixed: boolean = false ): boolean { diff --git a/src/keri/core/saider.ts b/src/keri/core/saider.ts index 479d6b5b..24df0991 100644 --- a/src/keri/core/saider.ts +++ b/src/keri/core/saider.ts @@ -1,8 +1,8 @@ -import { DigiDex, Matter, MatterArgs, MtrDex } from './matter.ts'; -import { deversify, Dict, Serials } from './core.ts'; +import { blake3 } from '@noble/hashes/blake3'; +import { deversify, Serials } from './core.ts'; import { EmptyMaterialError } from './kering.ts'; +import { DigiDex, Matter, MatterArgs, MtrDex } from './matter.ts'; import { dumps, sizeify } from './serder.ts'; -import { blake3 } from '@noble/hashes/blake3'; const Dummy = '#'; @@ -10,10 +10,16 @@ export enum Ids { d = 'd', } -export class Saider extends Matter { +export interface BaseSAD extends Record { + d?: string; + v?: string; + t?: string; +} + +export class Saider extends Matter { constructor( { raw, code, qb64b, qb64, qb2 }: MatterArgs, - sad?: Dict, + sad?: T, kind?: Serials, label: string = Ids.d ) { @@ -27,7 +33,7 @@ export class Saider extends Matter { if (code == undefined) { if (sad[label] != '') { - super({ qb64: sad[label], code: code }); + super({ qb64: String(sad[label]), code: code }); code = this.code; } else { code = MtrDex.Blake3_256; @@ -51,11 +57,11 @@ export class Saider extends Matter { } private static _derive( - sad: Dict, + sad: BaseSAD, code: string, kind: Serials | undefined, label: string - ): [Uint8Array, Dict] { + ): [Uint8Array, BaseSAD] { if (!DigiDex.has(code)) { throw new Error(`Unsupported digest code = ${code}.`); } @@ -79,17 +85,17 @@ export class Saider extends Matter { } public derive( - sad: Dict, + sad: BaseSAD, code: string, kind: Serials | undefined, label: string - ): [Uint8Array, Dict] { + ): [Uint8Array, BaseSAD] { code = code != undefined ? code : this.code; return Saider._derive(sad, code, kind, label); } public verify( - sad: Dict, + sad: BaseSAD, prefixed: boolean = false, versioned: boolean = false, kind?: Serials, @@ -118,10 +124,10 @@ export class Saider extends Matter { return true; } - private static _serialze(sad: Dict, kind?: Serials): string { + private static _serialze(sad: BaseSAD, kind?: Serials): string { let knd = Serials.JSON; if ('v' in sad) { - [, knd] = deversify(sad['v']); + [, knd] = deversify(sad['v']!); } if (kind == undefined) { @@ -131,24 +137,24 @@ export class Saider extends Matter { return dumps(sad, kind); } - public static saidify( - sad: Dict, + public static saidify( + sad: T, code: string = MtrDex.Blake3_256, kind: Serials = Serials.JSON, label: string = Ids.d - ): [Saider, Dict] { + ): [Saider, T] { if (!(label in sad)) { throw new Error(`Missing id field labeled=${label} in sad.`); } - let raw; - [raw, sad] = Saider._derive(sad, code, kind, label); + + const [raw, derivedSad] = Saider._derive(sad, code, kind, label); const saider = new Saider( { raw: raw, code: code }, undefined, kind, label ); - sad[label] = saider.qb64; - return [saider, sad]; + derivedSad[label] = saider.qb64; + return [saider, derivedSad as T]; } } diff --git a/src/keri/core/serder.ts b/src/keri/core/serder.ts index d5995aa5..433d2cc4 100644 --- a/src/keri/core/serder.ts +++ b/src/keri/core/serder.ts @@ -1,21 +1,28 @@ -import { MtrDex } from './matter.ts'; import { deversify, - Dict, Protocols, Serials, versify, Version, Vrsn_1_0, } from './core.ts'; -import { Verfer } from './verfer.ts'; import { Diger } from './diger.ts'; +import { MtrDex } from './matter.ts'; import { CesrNumber } from './number.ts'; +import { BaseSAD } from './saider.ts'; +import { Verfer } from './verfer.ts'; + +export interface SerderSAD extends BaseSAD { + i?: string; + k?: string[]; + n?: string[] | string; + s?: string | number; +} -export class Serder { +export class Serder { private _kind: Serials; private _raw: string = ''; - private _sad: Dict = {}; + private _sad: T; private _proto: Protocols = Protocols.KERI; private _size: number = 0; private _version: Version = Vrsn_1_0; @@ -28,7 +35,7 @@ export class Serder { * @param code derivation code for the prefix */ constructor( - sad: Dict, + sad: T, kind: Serials = Serials.JSON, code: string = MtrDex.Blake3_256 ) { @@ -42,11 +49,11 @@ export class Serder { this._size = raw.length; } - get sad(): Dict { + get sad(): T { return this._sad; } - get pre(): string { + get pre(): string | undefined { return this._sad['i']; } @@ -58,12 +65,12 @@ export class Serder { return this._raw; } - get said(): string { + get said(): string | undefined { return this._sad['d']; } get sner(): CesrNumber { - return new CesrNumber({}, this.sad['s']); + return new CesrNumber({}, String(this.sad['s'])); } get sn(): number { @@ -82,9 +89,9 @@ export class Serder { * @private */ private _exhale( - sad: Dict, + sad: T, kind: Serials - ): [string, Protocols, Serials, Dict, Version] { + ): [string, Protocols, Serials, T, Version] { return sizeify(sad, kind); } @@ -100,10 +107,10 @@ export class Serder { return this._version; } get verfers(): Verfer[] { - let keys: any = []; + let keys: string[] = []; if ('k' in this._sad) { // establishment event - keys = this._sad['k']; + keys = this._sad['k'] || []; } else { // non-establishment event keys = []; @@ -117,10 +124,10 @@ export class Serder { } get digers(): Diger[] { - let keys: any = []; + let keys: string[] | string = []; if ('n' in this._sad) { // establishment event - keys = this._sad['n']; + keys = this._sad['n'] || []; } else { // non-establishment event keys = []; @@ -146,10 +153,10 @@ export function dumps(sad: object, kind: Serials.JSON): string { } } -export function sizeify( - ked: Dict, +export function sizeify( + ked: T, kind?: Serials -): [string, Protocols, Serials, Dict, Version] { +): [string, Protocols, Serials, T, Version] { if (!('v' in ked)) { throw new Error('Missing or empty version string'); } diff --git a/src/keri/core/tholder.ts b/src/keri/core/tholder.ts index 745ea915..3a4ff330 100644 --- a/src/keri/core/tholder.ts +++ b/src/keri/core/tholder.ts @@ -1,17 +1,23 @@ +import { Fraction, format, fraction, sum } from 'mathjs'; import { BexDex, Matter, NumDex } from './matter.ts'; import { CesrNumber } from './number.ts'; -import { Fraction, format, sum, fraction } from 'mathjs'; + +interface Thold { + thold?: number | Array>; + limen?: string; + sith?: number | string | string[] | (string | string[])[]; +} export class Tholder { private _weighted: boolean = false; - private _thold: any = undefined; + private _thold: number | Array> = 0; private _size: number = 0; private _number: CesrNumber | undefined = undefined; - private _satisfy: any = undefined; + private _satisfy: ((indices: number[]) => boolean) | undefined = undefined; // private _bexter: any - constructor(kargs: { thold?: any; limen?: any; sith?: any }) { + constructor(kargs: Thold) { if (kargs.thold !== undefined) { this._processThold(kargs.thold); } else if (kargs.limen != undefined) { @@ -27,7 +33,7 @@ export class Tholder { return this._weighted; } - get thold(): any { + get thold(): number | Array> { return this._thold; } @@ -35,13 +41,13 @@ export class Tholder { return this._size; } - get limen(): any { + get limen() { return this._number?.qb64b; } - get sith(): string { - if (this.weighted) { - let sith = this.thold.map((clause: Fraction[]) => { + get sith(): string | string[] | string[][] { + if (this.weighted && Array.isArray(this.thold)) { + const sith = this.thold.map((clause: Fraction[]) => { return clause.map((c) => { if (0 < Number(c) && Number(c) < 1) { return format(c, { fraction: 'ratio' }); @@ -50,11 +56,8 @@ export class Tholder { } }); }); - if (sith.length == 1) { - sith = sith[0]; - } - return sith; + return sith.length == 1 ? sith[0] : sith; } else { return this.thold.toString(16); } @@ -65,7 +68,7 @@ export class Tholder { } get num(): number | undefined { - return this._weighted ? undefined : this._thold; + return this._weighted ? undefined : (this._thold as number); } private _processThold(thold: number | Array>) { @@ -91,31 +94,34 @@ export class Tholder { } } - private _processSith(sith: string | number | Array) { + private _processSith( + sith: string | number | Array | (string | string[])[] + ) { if (typeof sith == 'number') { this._processUnweighted(sith); } else if (typeof sith == 'string' && sith.indexOf('[') == -1) { this._processUnweighted(parseInt(sith, 16)); } else { - let _sith: any = sith; + let _sith: string | string[] | string[][] | (string | string[])[] = + sith; if (typeof sith == 'string') { _sith = JSON.parse(sith); } - if (_sith.length == 0) { + if (!Array.isArray(_sith) || _sith.length == 0) { throw new Error('Empty weight list'); } - const mask = _sith.map((x: any) => { + const mask = _sith.map((x) => { return typeof x !== 'string'; }); if (mask.length > 0 && !mask.every((x: boolean) => x)) { - _sith = [_sith]; + _sith = [_sith] as string[][]; } - for (const c of _sith) { - const mask = c.map((x: any) => { + for (const c of _sith as string[][]) { + const mask = c.map((x) => { return typeof x === 'string'; }); if (mask.length > 0 && !mask.every((x: boolean) => x)) { @@ -127,7 +133,7 @@ export class Tholder { } } - const thold = this._processClauses(_sith); + const thold = this._processClauses(_sith as string[][]); this._processWeighted(thold); } } @@ -180,11 +186,14 @@ export class Tholder { return fraction(w); } - private _satisfy_numeric(indices: any[]) { - return this.thold > 0 && indices.length >= this.thold; // at least one + private _satisfy_numeric(indices: number[]) { + return ( + (this.thold as number) > 0 && + indices.length >= (this.thold as number) + ); // at least one } - private _satisfy_weighted(indices: any) { + private _satisfy_weighted(indices: number[]) { if (indices.length === 0) { return false; } @@ -195,7 +204,7 @@ export class Tholder { sats[idx] = true; } let wio = 0; - for (const clause of this.thold) { + for (const clause of this.thold as Array>) { let cw = 0; for (const w of clause) { if (sats[wio]) { @@ -211,7 +220,7 @@ export class Tholder { return true; } - public satisfy(indices: any): boolean { - return this._satisfy(indices); + public satisfy(indices: number[]): boolean { + return !!this._satisfy?.(indices); } } diff --git a/src/keri/core/vdring.ts b/src/keri/core/vdring.ts index 8ce5836a..9ba74abd 100644 --- a/src/keri/core/vdring.ts +++ b/src/keri/core/vdring.ts @@ -11,6 +11,7 @@ import { import { ample } from './eventing.ts'; import { MtrDex } from './matter.ts'; import { Prefixer } from './prefixer.ts'; +import { BaseSAD } from './saider.ts'; import { Serder } from './serder.ts'; namespace vdr { @@ -25,6 +26,19 @@ namespace vdr { code?: string; } + export interface VDRInceptSAD extends BaseSAD { + v: string; + t: string; + d: string; + i: string; + ii: string; + s: string; + c: string[]; + bt: string; + b: string[]; + n: string; + } + export function incept({ pre, toad, @@ -70,7 +84,7 @@ namespace vdr { } } - const sad = { + const sad: VDRInceptSAD = { v: vs, t: ilk, d: '', diff --git a/test-integration/challenge.test.ts b/test-integration/challenge.test.ts index e065a1f8..cf8380f6 100644 --- a/test-integration/challenge.test.ts +++ b/test-integration/challenge.test.ts @@ -1,5 +1,5 @@ import { assert, test } from 'vitest'; -import signify, { Serder } from 'signify-ts'; +import signify, { Serder, SerderSAD } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, @@ -115,11 +115,11 @@ test('challenge', async () => { //Alice mark response as accepted const verifyResponse = verifyOperation.response as { - exn: Record; + exn: SerderSAD; }; - const exn = new Serder(verifyResponse.exn); + const exn = new Serder(verifyResponse.exn as SerderSAD); - await client1.challenges().responded(aid2.i, exn.sad.d); + await client1.challenges().responded(aid2.i, exn.sad.d!); console.log('Alice marked challenge response as accepted'); // Check Bob's challenge in conctats diff --git a/test-integration/credentials.test.ts b/test-integration/credentials.test.ts index 37a45ad6..80f3697f 100644 --- a/test-integration/credentials.test.ts +++ b/test-integration/credentials.test.ts @@ -542,7 +542,7 @@ test('single signature credentials', { timeout: 90000 }, async () => { }); await waitOperation(holderClient, result.op); - return result.acdc.sad.d; + return result.acdc.sad.d!; } ); diff --git a/test-integration/delegation.test.ts b/test-integration/delegation.test.ts index 726b9910..b15717f0 100644 --- a/test-integration/delegation.test.ts +++ b/test-integration/delegation.test.ts @@ -97,7 +97,9 @@ test('delegation', async () => { return apprDelRes; }); assert.equal( - JSON.stringify(result.serder.sad.a[0]), + JSON.stringify( + (result.serder.sad.a as Record[])[0] + ), JSON.stringify(anchor) ); }); diff --git a/test-integration/multisig-holder.test.ts b/test-integration/multisig-holder.test.ts index 46db7629..87186964 100644 --- a/test-integration/multisig-holder.test.ts +++ b/test-integration/multisig-holder.test.ts @@ -1,5 +1,10 @@ import { assert, test } from 'vitest'; -import signify, { SignifyClient, Operation, CredentialData } from 'signify-ts'; +import signify, { + SignifyClient, + Operation, + CredentialData, + Seal, +} from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { assertOperations, @@ -145,7 +150,7 @@ test('multisig', async function run() { let rpy = endRoleRes.serder; let sigs = endRoleRes.sigs; let ghabState1 = ghab1['state']; - let seal = [ + let seal: Seal = [ 'SealEvent', { i: ghab1['prefix'], @@ -523,7 +528,7 @@ async function multisigAdmitCredential( .submitAdmit(groupName, admit, sigs, end, [issuerPrefix]); const mstate = gHab['state']; - const seal = [ + const seal: Seal = [ 'SealEvent', { i: gHab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] }, ]; diff --git a/test-integration/multisig.test.ts b/test-integration/multisig.test.ts index 78d93bd5..dd6670d1 100644 --- a/test-integration/multisig.test.ts +++ b/test-integration/multisig.test.ts @@ -3,6 +3,7 @@ import signify, { SignifyClient, Serder, IssueCredentialResult, + Seal, } from 'signify-ts'; import { resolveEnvironment } from './utils/resolve-env.ts'; import { @@ -319,7 +320,7 @@ test('multisig', async function run() { let rpy = endRoleRes.serder; sigs = endRoleRes.sigs; let mstate = hab['state']; - let seal = [ + let seal: Seal = [ 'SealEvent', { i: hab['prefix'], s: mstate['ee']['s'], d: mstate['ee']['d'] }, ]; diff --git a/test-integration/utils/multisig-utils.ts b/test-integration/utils/multisig-utils.ts index 542d0d71..dc5563a6 100644 --- a/test-integration/utils/multisig-utils.ts +++ b/test-integration/utils/multisig-utils.ts @@ -1,20 +1,21 @@ +import assert from 'assert'; import signify, { Algos, CreateIdentiferArgs, CredentialData, + ExternHabState, + GroupHabState, + HabState, + RandyHabState, + SaltyHabState, + Seal, Serder, Siger, SignifyClient, d, messagize, - HabState, - SaltyHabState, - GroupHabState, - ExternHabState, - RandyHabState, } from 'signify-ts'; import { getStates, waitAndMarkNotification } from './test-util.ts'; -import assert from 'assert'; export interface AcceptMultisigInceptArgs { groupName: string; @@ -112,7 +113,7 @@ export async function addEndRoleMultisig( const rpy = endRoleResult.serder; const sigs = endRoleResult.sigs; const ghabState1 = multisigAID.state; - const seal = [ + const seal: Seal = [ 'SealEvent', { i: multisigAID.prefix, @@ -174,7 +175,7 @@ export async function admitMultisig( .submitAdmit(multisigAID.name, admit, sigs, end, [recipientAID.prefix]); const mstate = multisigAID.state; - const seal = [ + const seal: Seal = [ 'SealEvent', { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, ]; @@ -315,7 +316,9 @@ export async function delegateMultisig( ); assert.equal( - JSON.stringify(delResult.serder.sad.a[0]), + JSON.stringify( + (delResult.serder.sad.a as Record[])[0] + ), JSON.stringify(anchor) ); @@ -379,7 +382,7 @@ export async function grantMultisig( .submitGrant(multisigAID.name, grant, sigs, end, [recipientAID.prefix]); const mstate = multisigAID.state; - const seal = [ + const seal: Seal = [ 'SealEvent', { i: multisigAID.prefix, s: mstate['ee']['s'], d: mstate['ee']['d'] }, ]; diff --git a/test-integration/utils/test-util.ts b/test-integration/utils/test-util.ts index 5178b158..f8e883d3 100644 --- a/test-integration/utils/test-util.ts +++ b/test-integration/utils/test-util.ts @@ -334,7 +334,7 @@ export async function getOrIssueCredential( await waitOperation(issuerClient, issResult.op); const credential = await issuerClient .credentials() - .get(issResult.acdc.sad.d); + .get(issResult.acdc.sad.d!); return credential; } diff --git a/test/app/clienting.test.ts b/test/app/clienting.test.ts index b969ba7b..a7fc7af4 100644 --- a/test/app/clienting.test.ts +++ b/test/app/clienting.test.ts @@ -97,14 +97,17 @@ describe('SignifyClient', () => { assert.equal(client.controller.serder.sad.s, '1'); assert.equal(client.controller.serder.sad.t, 'ixn'); assert.equal( - client.controller.serder.sad.a[0].i, + (client.controller.serder.sad.a as Record[])[0].i, 'EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei' ); assert.equal( - client.controller.serder.sad.a[0].d, + (client.controller.serder.sad.a as Record[])[0].d, 'EEXekkGu9IAzav6pZVJhkLnjtjM5v3AcyA-pdKUcaGei' ); - assert.equal(client.controller.serder.sad.a[0].s, '0'); + assert.equal( + (client.controller.serder.sad.a as Record[])[0].s, + '0' + ); const data = client.data; assert(data[0], url); diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index e298fba2..8475ca27 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -14,6 +14,7 @@ import { serializeIssExnAttachment, Serials, versify, + InteractEventData, } from '../../src/index.ts'; import { createMockFetch, mockCredential } from './test-utils.ts'; @@ -169,7 +170,7 @@ describe('Ipex', () => { const anc = interact({ pre: mockCredential.sad.i, sn: 1, - data: [{}], + data: [{}] as InteractEventData[], dig: mockCredential.sad.d, version: undefined, kind: undefined, @@ -271,7 +272,7 @@ describe('Ipex', () => { const [admit, asigs, aend] = await ipex.admit({ senderName: 'holder', message: '', - grantSaid: grant.sad.d, + grantSaid: grant.sad.d!, recipient: holder, datetime: mockCredential.sad.a.dt, }); @@ -337,7 +338,7 @@ describe('Ipex', () => { const anc = interact({ pre: mockCredential.sad.i, sn: 1, - data: [{}], + data: [{}] as InteractEventData[], dig: mockCredential.sad.d, version: undefined, kind: undefined, @@ -445,7 +446,7 @@ describe('Ipex', () => { recipient: holder, message: 'OK!', datetime: mockCredential.sad.a.dt, - offerSaid: offer.sad.d, + offerSaid: offer.sad.d!, }); assert.deepStrictEqual(agree.sad, { @@ -576,7 +577,7 @@ describe('Ipex', () => { senderName: 'holder', message: '', recipient: holder, - grantSaid: grant.sad.d, + grantSaid: grant.sad.d!, datetime: mockCredential.sad.a.dt, }); diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index 653678d0..0b7b57e5 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -98,7 +98,7 @@ export async function createMockIdentifierState( // Mock for each algo type if (algo === Algos.salty) { - return ({ + return { name, prefix: serder.pre, salty: keeper.params(), @@ -116,17 +116,17 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: serder.sad.p ?? '', + p: (serder.sad.p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: serder.sad.di ?? '', + di: (serder.sad.di as string) ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', - } as unknown) as HabState; + } as unknown as HabState; } else if (algo === Algos.randy) { - return ({ + return { name, prefix: serder.pre, randy: keeper.params(), @@ -144,17 +144,17 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: serder.sad.p ?? '', + p: (serder.sad.p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: serder.sad.di ?? '', + di: (serder.sad.di as string) ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', - } as unknown) as HabState; + } as unknown as HabState; } else if (algo === Algos.group) { - return ({ + return { name, prefix: serder.pre, group: keeper.params(), @@ -172,17 +172,17 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: serder.sad.p ?? '', + p: (serder.sad.p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: serder.sad.di ?? '', + di: (serder.sad.di as string) ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', - } as unknown) as HabState; + } as unknown as HabState; } else if (algo === Algos.extern) { - return ({ + return { name, prefix: serder.pre, extern: extern ?? {}, @@ -202,15 +202,15 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: serder.sad.p ?? '', + p: (serder.sad.p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: serder.sad.di ?? '', + di: (serder.sad.di as string) ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', - } as unknown) as HabState; + } as unknown as HabState; } else { throw new Error('Unknown algo type'); } diff --git a/test/core/decrypter.test.ts b/test/core/decrypter.test.ts index ec4ea2a2..bedb32c9 100644 --- a/test/core/decrypter.test.ts +++ b/test/core/decrypter.test.ts @@ -99,7 +99,7 @@ describe('Decrypter', () => { seedcipher.qb64b, null, signer.verfer.transferable - ); + ) as Signer; assert.deepStrictEqual(designer.qb64b, seedqb64b); assert.equal(designer.code, MtrDex.Ed25519_Seed); assert.equal(designer.verfer.code, MtrDex.Ed25519); @@ -110,7 +110,7 @@ describe('Decrypter', () => { null, seedcipher, signer.verfer.transferable - ); + ) as Signer; assert.deepStrictEqual(designer.qb64b, seedqb64b); assert.equal(designer.code, MtrDex.Ed25519_Seed); assert.equal(designer.verfer.code, MtrDex.Ed25519); @@ -139,7 +139,7 @@ describe('Decrypter', () => { b(cipherseed), null, signer.verfer.transferable - ); + ) as Signer; assert.deepStrictEqual(designer.qb64b, seedqb64b); assert.equal(designer.code, MtrDex.Ed25519_Seed); assert.equal(designer.verfer.code, MtrDex.Ed25519); diff --git a/test/core/eventing.test.ts b/test/core/eventing.test.ts index 267ae080..def98431 100644 --- a/test/core/eventing.test.ts +++ b/test/core/eventing.test.ts @@ -2,7 +2,7 @@ import libsodium from 'libsodium-wrappers-sumo'; import { Signer } from '../../src/keri/core/signer.ts'; import { assert, describe, it } from 'vitest'; import { MtrDex } from '../../src/keri/core/matter.ts'; -import { incept, messagize, rotate } from '../../src/keri/core/eventing.ts'; +import { incept, messagize, rotate, Seal } from '../../src/keri/core/eventing.ts'; import { Saider } from '../../src/keri/core/saider.ts'; import { Diger } from '../../src/keri/core/diger.ts'; import { b, d, Ilks } from '../../src/keri/core/core.ts'; @@ -172,7 +172,7 @@ describe('key event function', () => { '"nt":1,"n":["EIf-ENw7PrM52w4H-S7NGU2qVIfraXVIlV9hEAaMHg7W"],"bt":0,"b":[],"c":[],"a":[]}' + '-AABAABB3MJGmBXxSEryNHw3YwZZLRl_6Ws4Me2WFq8PrQ6WlluSOpPqbwXuiG9RvNWZkqeW8A_0VRjokGMVRZ3m-c0I' ); - const seal = [ + const seal:Seal = [ 'SealEvent', { i: 'EIflL4H4134zYoRM6ls6Q086RLC_BhfNFh5uk-WxvhsL', diff --git a/test/core/manager.test.ts b/test/core/manager.test.ts index f0aa6417..ca2fe32c 100644 --- a/test/core/manager.test.ts +++ b/test/core/manager.test.ts @@ -25,6 +25,7 @@ import { IdentifierManagerFactory, Prefixer, RandyIdentifierManager, + KArgs, } from '../../src/index.ts'; import { RandyKeyState, KeyState, RandyHabState, ExternHabState, HabState } from '../../src/keri/core/keyState.ts'; import { randomUUID } from 'node:crypto'; @@ -714,7 +715,7 @@ describe('Manager', () => { const keeper0 = manager.new( Algos.randy, 0, - {} + {} as KArgs ) as RandyIdentifierManager; const [keys] = await keeper0.incept(false); const prefixes = new Prefixer({ qb64: keys[0] }); @@ -739,9 +740,9 @@ describe('Manager', () => { const manager = new IdentifierManagerFactory(salter, []); - expect(() => manager.new(randomUUID() as Algos, 0, {})).toThrow( - 'Unknown algo' - ); + expect(() => + manager.new(randomUUID() as Algos, 0, {} as KArgs) + ).toThrow('Unknown algo'); expect(() => manager.get({ prefix: '', @@ -785,7 +786,7 @@ describe('Manager', () => { const keeper = manager.new(Algos.extern, 0, { extern_type: 'mock', param, - }); + } as KArgs); assert(keeper instanceof MockModule); expect(keeper.params()).toMatchObject({ param }); @@ -802,7 +803,7 @@ describe('Manager', () => { manager.new(Algos.extern, 0, { extern_type: 'mock', param, - }) + } as KArgs) ).toThrow('unsupported external module type mock'); }); diff --git a/test/core/vdring.test.ts b/test/core/vdring.test.ts index be83defb..cb19193c 100644 --- a/test/core/vdring.test.ts +++ b/test/core/vdring.test.ts @@ -9,7 +9,7 @@ describe('vdr', () => { pre: 'ECJIoBpEcCWMzvquk861dXP8JJZ-vbmJczlDR-NYcE3g', toad: 0, }); - assert.equal(actual.pre.length, 44); + assert.equal(actual.pre?.length, 44); actual = vdr.incept({ pre: 'ECJIoBpEcCWMzvquk861dXP8JJZ-vbmJczlDR-NYcE3g', From d74ba14275f83861f23594f4f4548505965e20a8 Mon Sep 17 00:00:00 2001 From: Vu Van Duc Date: Fri, 8 Aug 2025 17:45:05 +0700 Subject: [PATCH 20/22] chore: remove cast string --- src/keri/app/clienting.ts | 2 +- src/keri/app/controller.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index 56b321b8..020a8c5e 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -183,7 +183,7 @@ export class SignifyClient { let signed_headers = new Headers(); const final_headers = new Headers(); - headers.set('Signify-Resource', String(this.controller.pre)); + headers.set('Signify-Resource', this.controller.pre!); headers.set( HEADER_SIG_TIME, new Date().toISOString().replace('Z', '000+00:00') diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index 8a52606c..ac4a9c4e 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -232,8 +232,8 @@ export class Controller { const sn = new CesrNumber({}, undefined, String(this.serder.sad['s'])).num + 1; this.serder = interact({ - pre: this.serder.pre || '', - dig: this.serder.sad['d'] || '', + pre: this.serder.pre!, + dig: this.serder.sad['d']!, sn: sn, data: [anchor], version: Vrsn_1_0, From 50384d414d3ce3b66e8833aee9a078e7eb745419 Mon Sep 17 00:00:00 2001 From: Vu Van Duc Date: Mon, 11 Aug 2025 16:44:46 +0700 Subject: [PATCH 21/22] chore: update type --- src/keri/app/aiding.ts | 4 ++-- src/keri/app/clienting.ts | 4 ++-- src/keri/app/controller.ts | 30 +++++++++++++-------------- src/keri/app/credentialing.ts | 2 +- src/keri/app/delegating.ts | 2 +- src/keri/app/habery.ts | 10 ++++----- src/keri/core/authing.ts | 4 +++- src/keri/core/eventing.ts | 38 +++++++++++++++-------------------- src/keri/core/prefixer.ts | 7 +++++-- src/keri/core/saider.ts | 2 +- src/keri/core/serder.ts | 4 ++-- test/app/delegating.test.ts | 15 +++++++++----- 12 files changed, 63 insertions(+), 59 deletions(-) diff --git a/src/keri/app/aiding.ts b/src/keri/app/aiding.ts index f08e2c27..b4b13324 100644 --- a/src/keri/app/aiding.ts +++ b/src/keri/app/aiding.ts @@ -1,6 +1,6 @@ import { components } from '../../types/keria-api-schema.ts'; import { b, Ilks, Serials, Vrsn_1_0 } from '../core/core.ts'; -import { incept, interact, reply, ReplyData, rotate } from '../core/eventing.ts'; +import { incept, interact, reply, EndRoleAddAttributes, rotate } from '../core/eventing.ts'; import { parseRangeHeaders } from '../core/httping.ts'; import { IdentifierManagerFactory } from '../core/keeping.ts'; import { HabState } from '../core/keyState.ts'; @@ -475,7 +475,7 @@ export class Identifier { eid?: string, stamp?: string ): Serder { - const data: ReplyData = { + const data: EndRoleAddAttributes = { cid: pre, role: role, }; diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index 020a8c5e..fd9995de 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -176,14 +176,14 @@ export class SignifyClient { async fetch( path: string, method: string, - data: Record | null | undefined, + data: unknown | null | undefined, extraHeaders?: Headers ): Promise { const headers = new Headers(); let signed_headers = new Headers(); const final_headers = new Headers(); - headers.set('Signify-Resource', this.controller.pre!); + headers.set('Signify-Resource', this.controller.pre); headers.set( HEADER_SIG_TIME, new Date().toISOString().replace('Z', '000+00:00') diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index ac4a9c4e..4deb6f09 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -1,18 +1,18 @@ -import { SaltyCreator } from '../core/manager.ts'; -import { Salter, Tier } from '../core/salter.ts'; -import { MtrDex } from '../core/matter.ts'; +import { Cipher } from '../core/cipher.ts'; +import { b, Ilks, Serials, Vrsn_1_0 } from '../core/core.ts'; +import { Decrypter } from '../core/decrypter.ts'; import { Diger } from '../core/diger.ts'; -import { incept, rotate, interact } from '../core/eventing.ts'; -import { Serder, SerderSAD } from '../core/serder.ts'; -import { Tholder } from '../core/tholder.ts'; -import { Ilks, b, Serials, Vrsn_1_0 } from '../core/core.ts'; -import { Verfer } from '../core/verfer.ts'; import { Encrypter } from '../core/encrypter.ts'; -import { Decrypter } from '../core/decrypter.ts'; -import { Cipher } from '../core/cipher.ts'; -import { Seqner } from '../core/seqner.ts'; +import { incept, InceptEventSAD, interact, InteractEventSAD, rotate } from '../core/eventing.ts'; +import { SaltyCreator } from '../core/manager.ts'; +import { MtrDex } from '../core/matter.ts'; import { CesrNumber } from '../core/number.ts'; +import { Salter, Tier } from '../core/salter.ts'; +import { Seqner } from '../core/seqner.ts'; +import { Serder } from '../core/serder.ts'; import { Signer } from '../core/signer.ts'; +import { Tholder } from '../core/tholder.ts'; +import { Verfer } from '../core/verfer.ts'; /** * Agent is a custodial entity that can be used in conjuntion with a local Client to establish the @@ -129,7 +129,7 @@ export class Controller { /** * Either the current establishment event, inception or rotation, or the interaction event used for delegation approval. */ - public serder: Serder; + public serder: Serder; /** * Current public keys formatted in fully-qualified Base64. * @private @@ -232,7 +232,7 @@ export class Controller { const sn = new CesrNumber({}, undefined, String(this.serder.sad['s'])).num + 1; this.serder = interact({ - pre: this.serder.pre!, + pre: this.serder.pre, dig: this.serder.sad['d']!, sn: sn, data: [anchor], @@ -242,7 +242,7 @@ export class Controller { return [this.signer.sign(this.serder.raw, 0).qb64]; } - get pre(): string | undefined { + get pre(): string { return this.serder.pre; } @@ -270,7 +270,7 @@ export class Controller { return new Serder({ sad: state.controller['ee'], d: '', - } as SerderSAD); + }); } } diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index 3e67c224..ad11edda 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -497,7 +497,7 @@ export class Credentials { return { rev: new Serder(rev), - anc: new Serder(ixn || {}), + anc: new Serder(ixn), op, }; } diff --git a/src/keri/app/delegating.ts b/src/keri/app/delegating.ts index 31efffcf..7ceaca24 100644 --- a/src/keri/app/delegating.ts +++ b/src/keri/app/delegating.ts @@ -20,7 +20,7 @@ export class Delegations { */ async approve( name: string, - data?: { i: string; s: string; d: string } + data: { i: string; s: string; d: string } ): Promise { const { serder, sigs, jsondata } = await this.client .identifiers() diff --git a/src/keri/app/habery.ts b/src/keri/app/habery.ts index d6b4a5ba..b21beca9 100644 --- a/src/keri/app/habery.ts +++ b/src/keri/app/habery.ts @@ -3,7 +3,7 @@ import { incept } from '../core/eventing.ts'; import { Algos, Manager } from '../core/manager.ts'; import { MtrDex } from '../core/matter.ts'; import { Salter } from '../core/salter.ts'; -import { Serder } from '../core/serder.ts'; +import { Serder, SerderSAD } from '../core/serder.ts'; import { Verfer } from '../core/verfer.ts'; export class TraitCodex { @@ -39,16 +39,16 @@ export interface MakeHabArgs { data?: any; } -export class Hab { +export class Hab { public name: string; - public serder: Serder; + public serder: Serder; - constructor(name: string, icp: Serder) { + constructor(name: string, icp: Serder) { this.name = name; this.serder = icp; } - get pre(): string | undefined { + get pre(): T['i'] { return this.serder.sad['i']; } } diff --git a/src/keri/core/authing.ts b/src/keri/core/authing.ts index 3cc086d9..92e55c98 100644 --- a/src/keri/core/authing.ts +++ b/src/keri/core/authing.ts @@ -42,7 +42,9 @@ export class Authenticater { inputs.forEach((input) => { const items = new Array(); input.fields!.forEach((field) => { - if (typeof field !== 'string') return; + if (typeof field !== 'string') { + throw new Error("Invalid siginput field type"); + } if (field.startsWith('@')) { if (field == '@method') { diff --git a/src/keri/core/eventing.ts b/src/keri/core/eventing.ts index 22aaf3a0..93a6d4bc 100644 --- a/src/keri/core/eventing.ts +++ b/src/keri/core/eventing.ts @@ -1,3 +1,4 @@ +import { components } from '../../types/keria-api-schema.ts'; import { Cigar } from './cigar.ts'; import { b, @@ -42,9 +43,9 @@ export interface RotateArgs { intive?: boolean; } -export interface ReplyData { - cid?: string; - role?: string; +export interface EndRoleAddAttributes extends Record { + cid: string; + role: string; eid?: string; } @@ -55,9 +56,9 @@ export interface RotateEventSAD extends BaseSAD, Record { i: string; s: string; p?: string; - kt: number | string | string[] | string[][]; + kt: string | string[] | string[][]; k: string[]; - nt: number | string | string[] | string[][]; + nt: string | string[] | string[][]; n: string[]; bt: number | string; br?: string[]; @@ -81,11 +82,8 @@ export interface InceptEventSAD extends BaseSAD, Record { a: Record[]; } -export interface InteractEventData { - i: string; - s: string; - d: string; -} +export type InteractEventData = components['schemas']['Seal']; + export interface InteractEventSAD extends BaseSAD { i: string; t: string; @@ -96,17 +94,13 @@ export interface InteractEventSAD extends BaseSAD { export interface ReplyEventSAD extends BaseSAD { t: string; dt: string; - r: string; - a: ReplyData; -} - -export interface SealData { - i: string; - s: string; - d: string; + r: '/end/role/add'; + a: EndRoleAddAttributes; } -export type Seal = [string, SealData]; +export type Seal< + T extends components['schemas']['Seal'] = components['schemas']['Seal'], +> = ['SealEvent', T]; export function rotate({ pre = undefined, @@ -624,15 +618,15 @@ export function interact(args: InteractArgs): Serder { } export function reply( - route: string = '', - data: ReplyData | undefined, + route: '/end/role/add', + data: EndRoleAddAttributes | undefined, stamp: string | undefined, version: Version | undefined, kind: Serials = Serials.JSON ) { const vs = versify(Protocols.KERI, version, kind, 0); if (data == undefined) { - data = {}; + data = {} as EndRoleAddAttributes; } const _sad: ReplyEventSAD = { v: vs, diff --git a/src/keri/core/prefixer.ts b/src/keri/core/prefixer.ts index a1fe123f..2bbc09fc 100644 --- a/src/keri/core/prefixer.ts +++ b/src/keri/core/prefixer.ts @@ -8,7 +8,10 @@ import { Verfer } from './verfer.ts'; const Dummy: string = '#'; -export interface PrefixerSAD extends BaseSAD { +export interface PrefixerSAD extends Omit { + d?: string; + t?: string; + v: string; k?: string[]; n?: string | string[]; b?: string[]; @@ -157,7 +160,7 @@ export class Prefixer extends Matter { sad['i'] = ''.padStart(Matter.Sizes.get(MtrDex.Blake3_256)!.fs!, Dummy); sad['d'] = sad['i']; - const [raw] = sizeify(sad); + const [raw] = sizeify(sad as BaseSAD); const dig = blake3.create({ dkLen: 32 }).update(raw).digest(); return [dig, MtrDex.Blake3_256]; } diff --git a/src/keri/core/saider.ts b/src/keri/core/saider.ts index 24df0991..71bc0987 100644 --- a/src/keri/core/saider.ts +++ b/src/keri/core/saider.ts @@ -11,7 +11,7 @@ export enum Ids { } export interface BaseSAD extends Record { - d?: string; + d: string; v?: string; t?: string; } diff --git a/src/keri/core/serder.ts b/src/keri/core/serder.ts index 433d2cc4..df2091eb 100644 --- a/src/keri/core/serder.ts +++ b/src/keri/core/serder.ts @@ -53,7 +53,7 @@ export class Serder { return this._sad; } - get pre(): string | undefined { + get pre(): T['i'] { return this._sad['i']; } @@ -65,7 +65,7 @@ export class Serder { return this._raw; } - get said(): string | undefined { + get said(): T["d"] { return this._sad['d']; } diff --git a/test/app/delegating.test.ts b/test/app/delegating.test.ts index db886b01..d306fc0f 100644 --- a/test/app/delegating.test.ts +++ b/test/app/delegating.test.ts @@ -18,7 +18,12 @@ describe('delegate', () => { await client.connect(); const delegations = client.delegations(); await delegations.approve( - 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao' + 'EBfdlu8R27Fbx-ehrqwImnK-8Cm79sqbAQ4MmvEAYqao', + { + s: '', + i: '', + d: '', + } ); const lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1]!; assert.equal( @@ -29,16 +34,16 @@ describe('delegate', () => { assert.equal(lastCall[1]!.method, 'POST'); const expectedBody = { ixn: { - v: 'KERI10JSON0000cf_', + v: 'KERI10JSON0000e1_', t: 'ixn', - d: 'EBPt7hivibUQN-dlRyE9x_Y5LgFCGJ8QoNLSJrIkBYIg', + d: 'EPe2DWvz02_iuMWAZSoV380_EFi3yvdRuKU7xjEvRMkG', i: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', s: '1', p: 'ELUvZ8aJEHAQE-0nsevyYTP98rBbGJUrTj5an-pCmwrK', - a: [null], + a: [{ s: '', i: '', d: '' }], }, sigs: [ - 'AAC4StAw-0IiV_LujceAXB3tnkaK011rPYPBKLgz-u6jI7hwfWGTCu5LDvBUsON4CqXbZAwPgIv6JqYjIusWKv0G', + 'AADY_50NnRkdv92XNzAYTdMVT7wLNVKuRfla9cgJK1xHlM6Ea-8pbTIjQ8k7Sn_j9AOOTUgVwqTOGBhagzmWAnkK', ], salty: { sxlt: '1AAHnNQTkD0yxOC9tSz_ukbB2e-qhDTStH18uCsi5PCwOyXLONDR3MeKwWv_AVJKGKGi6xiBQH25_R1RXLS2OuK3TN3ovoUKH7-A', From 7656c87de03a8257c1c9fdcd2ae2484473e2624b Mon Sep 17 00:00:00 2001 From: Sotatek-DucVu Date: Tue, 26 Aug 2025 16:06:12 +0700 Subject: [PATCH 22/22] chore: update review comments --- src/keri/app/clienting.ts | 2 +- src/keri/app/controller.ts | 4 +-- src/keri/app/credentialing.ts | 4 +-- src/keri/app/delegating.ts | 6 ++-- src/keri/core/eventing.ts | 51 +++++++++++++++------------------- src/keri/core/prefixer.ts | 4 +-- src/keri/core/serder.ts | 2 +- src/types/keria-api-schema.ts | 6 ++-- test/app/credentialing.test.ts | 6 ++-- test/app/test-utils.ts | 17 ++++++------ 10 files changed, 47 insertions(+), 55 deletions(-) diff --git a/src/keri/app/clienting.ts b/src/keri/app/clienting.ts index fd9995de..789836d9 100644 --- a/src/keri/app/clienting.ts +++ b/src/keri/app/clienting.ts @@ -151,7 +151,7 @@ export class SignifyClient { 'commitment to controller AID missing in agent inception event' ); } - if (this.controller.serder.sad.s == 0) { + if (Number(this.controller.serder.sad.s) == 0) { await this.approveDelegation(); } this.manager = new IdentifierManagerFactory( diff --git a/src/keri/app/controller.ts b/src/keri/app/controller.ts index 4deb6f09..7c8f36dd 100644 --- a/src/keri/app/controller.ts +++ b/src/keri/app/controller.ts @@ -230,10 +230,10 @@ export class Controller { const seqner = new Seqner({ sn: _agent.sn }); const anchor = { i: _agent.pre, s: seqner.snh, d: _agent.said! }; const sn = - new CesrNumber({}, undefined, String(this.serder.sad['s'])).num + 1; + new CesrNumber({}, undefined, this.serder.sad['s']).num + 1; this.serder = interact({ pre: this.serder.pre, - dig: this.serder.sad['d']!, + dig: this.serder.sad['d'], sn: sn, data: [anchor], version: Vrsn_1_0, diff --git a/src/keri/app/credentialing.ts b/src/keri/app/credentialing.ts index ad11edda..8b94a769 100644 --- a/src/keri/app/credentialing.ts +++ b/src/keri/app/credentialing.ts @@ -8,7 +8,7 @@ import { versify, Vrsn_1_0, } from '../core/core.ts'; -import { interact, InteractEventData, messagize } from '../core/eventing.ts'; +import { interact, SealSourceTriple, messagize } from '../core/eventing.ts'; import { HabState } from '../core/keyState.ts'; import { BaseSAD, Saider } from '../core/saider.ts'; import { Serder } from '../core/serder.ts'; @@ -457,7 +457,7 @@ export class Credentials { const sn = parseInt(state.s, 16); const dig = state.d; - const data: InteractEventData[] = [ + const data: SealSourceTriple[] = [ { i: rev.i, s: rev.s, diff --git a/src/keri/app/delegating.ts b/src/keri/app/delegating.ts index 7ceaca24..3840401d 100644 --- a/src/keri/app/delegating.ts +++ b/src/keri/app/delegating.ts @@ -1,3 +1,4 @@ +import { SealSourceTriple } from '../core/eventing.ts'; import { EventResult } from './aiding.ts'; import { SignifyClient } from './clienting.ts'; @@ -18,10 +19,7 @@ export class Delegations { * @param {any} [data] The anchoring interaction event * @returns {Promise} A promise to the delegated approval result */ - async approve( - name: string, - data: { i: string; s: string; d: string } - ): Promise { + async approve(name: string, data: SealSourceTriple): Promise { const { serder, sigs, jsondata } = await this.client .identifiers() .createInteract(name, data); diff --git a/src/keri/core/eventing.ts b/src/keri/core/eventing.ts index 93a6d4bc..9b324921 100644 --- a/src/keri/core/eventing.ts +++ b/src/keri/core/eventing.ts @@ -66,31 +66,20 @@ export interface RotateEventSAD extends BaseSAD, Record { a: Record[]; } -export interface InceptEventSAD extends BaseSAD, Record { - v: string; - t: string; - d: string; - i: string; - s: string; - kt: number | string | string[] | string[][]; - k: string[]; - nt?: number | string | string[] | string[][]; - n?: string[]; - bt: number | string; - b: string[]; - c: string[]; - a: Record[]; -} +export type DelegateInceptEventSAD = + | components['schemas']['DipV1'] + | components['schemas']['DipV2']; -export type InteractEventData = components['schemas']['Seal']; +export type InceptEventSAD = + | components['schemas']['IcpV1'] + | components['schemas']['IcpV2'] + | DelegateInceptEventSAD; -export interface InteractEventSAD extends BaseSAD { - i: string; - t: string; - p: string; - a: InteractEventData[]; -} +export type SealSourceTriple = components['schemas']['Seal']; +export type InteractEventSAD = + | components['schemas']['IxnV1'] + | components['schemas']['IxnV2']; export interface ReplyEventSAD extends BaseSAD { t: string; dt: string; @@ -98,9 +87,10 @@ export interface ReplyEventSAD extends BaseSAD { a: EndRoleAddAttributes; } -export type Seal< - T extends components['schemas']['Seal'] = components['schemas']['Seal'], -> = ['SealEvent', T]; +export type Seal = SealSourceTriple> = [ + 'SealEvent', + T, +]; export function rotate({ pre = undefined, @@ -261,7 +251,7 @@ export function rotate({ v: vs, t: _ilk, d: '', - i: String(pre), + i: pre || '', s: sner.numh, p: dig, kt: @@ -425,7 +415,10 @@ export function incept({ s: sner.numh, kt: intive && tholder.num != undefined ? tholder.num : tholder.sith, k: keys, - nt: intive && tholder.num != undefined ? ntholder.num : ntholder.sith, + nt: + intive && tholder.num != undefined && ntholder.num + ? ntholder.num + : ntholder.sith, n: ndigs, bt: intive ? toader.num : toader.numh, b: wits, @@ -434,7 +427,7 @@ export function incept({ }; if (delpre != undefined) { - sad['di'] = delpre; + (sad as DelegateInceptEventSAD)['di'] = delpre; if (code == undefined) { code = MtrDex.Blake3_256; } @@ -600,7 +593,7 @@ export function interact(args: InteractArgs): Serder { throw new Error(`Invalid sn = 0x${sner.numh} for ixn.`); } - data = data == undefined ? new Array() : data; + data = data == undefined ? new Array() : data; let sad: InteractEventSAD = { v: vs, diff --git a/src/keri/core/prefixer.ts b/src/keri/core/prefixer.ts index 2bbc09fc..a2a9d219 100644 --- a/src/keri/core/prefixer.ts +++ b/src/keri/core/prefixer.ts @@ -15,7 +15,7 @@ export interface PrefixerSAD extends Omit { k?: string[]; n?: string | string[]; b?: string[]; - a?: Record[]; + a?: unknown; i?: string; } @@ -35,7 +35,7 @@ export class Prefixer extends Matter { } if (code == undefined) { - super({ qb64: String(ked['i']), code: code }); + super({ qb64: ked['i'], code: code }); code = this.code; } diff --git a/src/keri/core/serder.ts b/src/keri/core/serder.ts index df2091eb..40c704c4 100644 --- a/src/keri/core/serder.ts +++ b/src/keri/core/serder.ts @@ -70,7 +70,7 @@ export class Serder { } get sner(): CesrNumber { - return new CesrNumber({}, String(this.sad['s'])); + return new CesrNumber({}, this.sad['s']); } get sn(): number { diff --git a/src/types/keria-api-schema.ts b/src/types/keria-api-schema.ts index bb96c0aa..ef63c4f4 100644 --- a/src/types/keria-api-schema.ts +++ b/src/types/keria-api-schema.ts @@ -514,13 +514,13 @@ export interface components { /** @default 0 */ s: string; /** @default 0 */ - kt: string; + kt: number | string | string[] | string[][]; k?: string[]; /** @default 0 */ - nt: string; + nt: number | string | string[] | string[][]; n?: string[]; /** @default 0 */ - bt: string; + bt: number | string; b?: string[]; c?: string[]; a?: unknown; diff --git a/test/app/credentialing.test.ts b/test/app/credentialing.test.ts index 8475ca27..c9a51621 100644 --- a/test/app/credentialing.test.ts +++ b/test/app/credentialing.test.ts @@ -14,7 +14,7 @@ import { serializeIssExnAttachment, Serials, versify, - InteractEventData, + SealSourceTriple, } from '../../src/index.ts'; import { createMockFetch, mockCredential } from './test-utils.ts'; @@ -170,7 +170,7 @@ describe('Ipex', () => { const anc = interact({ pre: mockCredential.sad.i, sn: 1, - data: [{}] as InteractEventData[], + data: [{}] as SealSourceTriple[], dig: mockCredential.sad.d, version: undefined, kind: undefined, @@ -338,7 +338,7 @@ describe('Ipex', () => { const anc = interact({ pre: mockCredential.sad.i, sn: 1, - data: [{}] as InteractEventData[], + data: [{}] as SealSourceTriple[], dig: mockCredential.sad.d, version: undefined, kind: undefined, diff --git a/test/app/test-utils.ts b/test/app/test-utils.ts index 0b7b57e5..93529c16 100644 --- a/test/app/test-utils.ts +++ b/test/app/test-utils.ts @@ -4,6 +4,7 @@ import { Authenticater, Controller, CreateIdentiferArgs, + DelegateInceptEventSAD, HEADER_SIG_TIME, IdentifierManagerFactory, MtrDex, @@ -116,12 +117,12 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: (serder.sad.p as string) ?? '', + p: ((serder.sad as Record).p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: (serder.sad.di as string) ?? '', + di: (serder.sad as DelegateInceptEventSAD).di ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', } as unknown as HabState; @@ -144,12 +145,12 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: (serder.sad.p as string) ?? '', + p: ((serder.sad as Record).p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: (serder.sad.di as string) ?? '', + di: (serder.sad as DelegateInceptEventSAD).di ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', } as unknown as HabState; @@ -172,12 +173,12 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: (serder.sad.p as string) ?? '', + p: ((serder.sad as Record).p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: (serder.sad.di as string) ?? '', + di: (serder.sad as DelegateInceptEventSAD).di ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', } as unknown as HabState; @@ -202,12 +203,12 @@ export async function createMockIdentifierState( n: serder.sad.n, bt: serder.sad.bt, b: serder.sad.b, - p: (serder.sad.p as string) ?? '', + p: ((serder.sad as Record).p as string) ?? '', f: '', dt: new Date().toISOString().replace('Z', '000+00:00'), et: '', c: [], - di: (serder.sad.di as string) ?? '', + di: (serder.sad as DelegateInceptEventSAD).di ?? '', } as KeyState, icp_dt: '2023-12-01T10:05:25.062609+00:00', } as unknown as HabState;