diff --git a/.gitmodules b/.gitmodules index f5d600a..09d131f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "packages/circuit/lib/forge-std"] path = packages/circuit/lib/forge-std url = https://github.com/foundry-rs/forge-std +[submodule "vendors/trust402"] + path = vendors/trust402 + url = https://github.com/lemmaoracle/trust402.git diff --git a/packages/agent/.env.example b/packages/agent/.env.example new file mode 100644 index 0000000..2e43627 --- /dev/null +++ b/packages/agent/.env.example @@ -0,0 +1,19 @@ +# Example x402 Agent Environment Variables +# Copy this file to .env and fill in your values + +# Private key for signing x402 payments (0x-prefixed hex) +# Must have USDC on Base Sepolia testnet +PRIVATE_KEY=0x... + +# Resource server URL (the x402-enabled worker) +RESOURCE_SERVER_URL=http://localhost:8787 + +# Lemma API credentials (for identity proof generation) +LEMMA_API_BASE=https://api.lemma.frame00.com +LEMMA_API_KEY=your-api-key-here + +# Optional: Issuer keys for identity proof generation +ISSUER_SECRET_KEY=... +ISSUER_PUBLIC_KEY=... +ISSUER_MAC=... +HOLDER_KEY=... diff --git a/packages/agent/package.json b/packages/agent/package.json index bc98420..6bc526b 100644 --- a/packages/agent/package.json +++ b/packages/agent/package.json @@ -9,6 +9,11 @@ "test": "vitest run" }, "dependencies": { + "@lemmaoracle/agent": "^0.0.24-alpha.1", + "@lemmaoracle/sdk": "^0.0.23", + "@trust402/identity": "workspace:*", + "@trust402/protocol": "workspace:*", + "@trust402/roles": "workspace:*", "@x402/core": "^2.10.0", "@x402/evm": "^2.10.0", "@x402/fetch": "^2.10.0", @@ -18,10 +23,12 @@ "cli-spinners": "^3.4.0", "dotenv": "^16.6.1", "ora": "^9.4.0", + "ramda": "^0.30.0", "viem": "^2.48.4" }, "devDependencies": { "@types/node": "^22.19.17", + "@types/ramda": "^0.30.0", "tsx": "^4.21.0", "typescript": "^5.9.3", "vitest": "^3.2.4" diff --git a/packages/agent/src/kyc/artifact.test.ts b/packages/agent/src/kyc/artifact.test.ts new file mode 100644 index 0000000..8e445a6 --- /dev/null +++ b/packages/agent/src/kyc/artifact.test.ts @@ -0,0 +1,202 @@ +/** + * KYC module tests — Identity artifact creation and verification. + */ + +import { describe, it, expect, vi, beforeEach } from "vitest"; +import { + buildKycCredential, + type BuildCredentialInput, +} from "./artifact.js"; +import type { KycRole, KycScope, KycPermission, KycCredential } from "./types.js"; +import type { AgentCredential } from "@lemmaoracle/agent"; + +// --------------------------------------------------------------------------- +// Test fixtures +// --------------------------------------------------------------------------- + +const sampleKycCredential: KycCredential = { + roles: [{ name: "kyc-verified" }, { name: "aml-cleared" }], + scopes: [{ name: "payment:stablecoin" }], + permissions: [{ resource: "stablecoin:transfer", action: "execute" }], +}; + +const sampleCredentialInput: BuildCredentialInput = { + agentId: "agent-001", + subjectId: "subject-001", + issuerId: "issuer-001", + kyc: sampleKycCredential, + spendLimit: 1000, + currency: "USDC", + validForSeconds: 3600, +}; + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe("KYC Artifact Builder", () => { + describe("buildKycCredential", () => { + it("should build an AgentCredential from KYC credential input", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.schema).toBe("agent-credential-v1"); + expect(result.identity.agentId).toBe("agent-001"); + expect(result.identity.subjectId).toBe("subject-001"); + }); + + it("should map KYC roles to authority.roles", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.authority.roles).toHaveLength(2); + expect(result.authority.roles[0].name).toBe("kyc-verified"); + expect(result.authority.roles[1].name).toBe("aml-cleared"); + }); + + it("should map KYC scopes to authority.scopes", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.authority.scopes).toHaveLength(1); + expect(result.authority.scopes[0].name).toBe("payment:stablecoin"); + }); + + it("should map KYC permissions to authority.permissions", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.authority.permissions).toHaveLength(1); + expect(result.authority.permissions[0].resource).toBe("stablecoin:transfer"); + expect(result.authority.permissions[0].action).toBe("execute"); + }); + + it("should include financial data when provided", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.financial).toBeDefined(); + expect(result.financial?.spendLimit).toBe(1000); + expect(result.financial?.currency).toBe("USDC"); + }); + + it("should not include financial data when not provided", () => { + const input: BuildCredentialInput = { + ...sampleCredentialInput, + spendLimit: undefined, + currency: undefined, + }; + + const result = buildKycCredential(input); + expect(result.financial).toBeUndefined(); + }); + + it("should set lifecycle timestamps correctly", () => { + const before = Math.floor(Date.now() / 1000); + const result = buildKycCredential({ + ...sampleCredentialInput, + validForSeconds: 3600, + }); + const after = Math.floor(Date.now() / 1000); + + expect(result.lifecycle.issuedAt).toBeGreaterThanOrEqual(before); + expect(result.lifecycle.issuedAt).toBeLessThanOrEqual(after); + expect(result.lifecycle.expiresAt).toBe(result.lifecycle.issuedAt + 3600); + }); + + it("should not set expiresAt when validForSeconds is not provided", () => { + const input: BuildCredentialInput = { + ...sampleCredentialInput, + validForSeconds: undefined, + }; + + const result = buildKycCredential(input); + expect(result.lifecycle.expiresAt).toBeUndefined(); + }); + + it("should set revoked to false by default", () => { + const result = buildKycCredential(sampleCredentialInput); + expect(result.lifecycle.revoked).toBe(false); + }); + + it("should include provenance information", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.provenance.issuerId).toBe("issuer-001"); + expect(result.provenance.sourceSystem).toBe("trust402-kyc"); + }); + + it("should include controllerId and orgId when provided", () => { + const input: BuildCredentialInput = { + ...sampleCredentialInput, + controllerId: "controller-001", + orgId: "org-001", + }; + + const result = buildKycCredential(input); + expect(result.identity.controllerId).toBe("controller-001"); + expect(result.identity.orgId).toBe("org-001"); + }); + + it("should not include controllerId and orgId when not provided", () => { + const result = buildKycCredential(sampleCredentialInput); + + expect(result.identity.controllerId).toBeUndefined(); + expect(result.identity.orgId).toBeUndefined(); + }); + }); + + describe("KYC role types", () => { + it("should accept standard KYC role names", () => { + const roles: ReadonlyArray = [ + { name: "kyc-verified" }, + { name: "aml-cleared" }, + { name: "sanctions-clear" }, + { name: "accredited-investor" }, + { name: "institutional" }, + ]; + + const input: BuildCredentialInput = { + ...sampleCredentialInput, + kyc: { ...sampleKycCredential, roles }, + }; + + const result = buildKycCredential(input); + expect(result.authority.roles).toHaveLength(5); + }); + }); + + describe("KYC scope types", () => { + it("should accept standard KYC scope names", () => { + const scopes: ReadonlyArray = [ + { name: "payment:stablecoin" }, + { name: "payment:fiat" }, + { name: "payment:crypto" }, + { name: "payment:cross-border" }, + ]; + + const input: BuildCredentialInput = { + ...sampleCredentialInput, + kyc: { ...sampleKycCredential, scopes }, + }; + + const result = buildKycCredential(input); + expect(result.authority.scopes).toHaveLength(4); + }); + }); + + describe("KYC permission types", () => { + it("should accept standard KYC permission combinations", () => { + const permissions: ReadonlyArray = [ + { resource: "stablecoin:issue", action: "execute" }, + { resource: "stablecoin:redeem", action: "execute" }, + { resource: "stablecoin:transfer", action: "read" }, + { resource: "fiat:on-ramp", action: "write" }, + { resource: "fiat:off-ramp", action: "execute" }, + ]; + + const input: BuildCredentialInput = { + ...sampleCredentialInput, + kyc: { ...sampleKycCredential, permissions }, + }; + + const result = buildKycCredential(input); + expect(result.authority.permissions).toHaveLength(5); + }); + }); +}); diff --git a/packages/agent/src/kyc/artifact.ts b/packages/agent/src/kyc/artifact.ts new file mode 100644 index 0000000..2ad13d2 --- /dev/null +++ b/packages/agent/src/kyc/artifact.ts @@ -0,0 +1,184 @@ +/** + * KYC Identity Artifact creation utilities. + * + * Builds IdentityArtifact from AgentCredential with KYC roles/scopes/permissions. + * Uses real @trust402/identity package for proof generation. + */ + +import * as R from "ramda"; +import type { AgentCredential } from "@lemmaoracle/agent"; +import { + register, + prove, + type RegisterOutput, + type CommitOutput, +} from "@trust402/identity"; +import type { ProveOutput } from "@lemmaoracle/sdk"; +import type { IdentityArtifact } from "@trust402/protocol"; +import type { KycCredential, KycRole, KycScope, KycPermission } from "./types.js"; + +// Import LemmaClient type for function signatures +import type { LemmaClient } from "@lemmaoracle/sdk"; + +// ── Helpers ─────────────────────────────────────────────────────────────── + +/** + * Convert KYC roles to AgentCredential authority format. + */ +const rolesToAuthorityRoles = ( + roles: ReadonlyArray, +): ReadonlyArray<{ name: string }> => + R.map((r) => ({ name: r.name }), roles); + +/** + * Convert KYC scopes to AgentCredential authority format. + */ +const scopesToAuthorityScopes = ( + scopes: ReadonlyArray, +): ReadonlyArray<{ name: string }> => + R.map((s) => ({ name: s.name }), scopes); + +/** + * Convert KYC permissions to AgentCredential authority format. + */ +const permissionsToAuthorityPermissions = ( + permissions: ReadonlyArray, +): ReadonlyArray<{ resource: string; action: string }> => + R.map((p) => ({ resource: p.resource, action: p.action }), permissions); + +// ── AgentCredential Builder ────────────────────────────────────────────── + +/** + * Input for building an AgentCredential with KYC attributes. + */ +export type BuildCredentialInput = Readonly<{ + agentId: string; + subjectId: string; + issuerId: string; + kyc: KycCredential; + spendLimit?: number; + currency?: string; + validForSeconds?: number; + controllerId?: string; + orgId?: string; +}>; + +/** + * Current Unix timestamp in seconds. + */ +const nowSeconds = (): number => Math.floor(Date.now() / 1000); + +/** + * Build an AgentCredential with KYC roles/scopes/permissions. + */ +export const buildKycCredential = (input: BuildCredentialInput): AgentCredential => { + const issuedAt = nowSeconds(); + const expiresAt = input.validForSeconds + ? issuedAt + input.validForSeconds + : undefined; + + return { + schema: "agent-credential-v1", + identity: { + agentId: input.agentId, + subjectId: input.subjectId, + ...(input.controllerId ? { controllerId: input.controllerId } : {}), + ...(input.orgId ? { orgId: input.orgId } : {}), + }, + authority: { + roles: rolesToAuthorityRoles(input.kyc.roles), + scopes: scopesToAuthorityScopes(input.kyc.scopes), + permissions: permissionsToAuthorityPermissions(input.kyc.permissions), + }, + ...(input.spendLimit !== undefined || input.currency !== undefined + ? { + financial: { + ...(input.spendLimit !== undefined ? { spendLimit: input.spendLimit } : {}), + ...(input.currency ? { currency: input.currency } : {}), + }, + } + : {}), + lifecycle: { + issuedAt, + ...(expiresAt ? { expiresAt } : {}), + revoked: false, + }, + provenance: { + issuerId: input.issuerId, + sourceSystem: "trust402-kyc", + }, + }; +}; + +// ── Identity Artifact Builder ───────────────────────────────────────────── + +/** + * Input for creating an IdentityArtifact. + */ +export type BuildArtifactInput = Readonly<{ + credential: AgentCredential; + issuerSecretKey: string; + mac: string; + issuerPublicKey: string; + holderKey: string; +}>; + +/** + * Result of building an identity artifact. + */ +export type BuildArtifactResult = Readonly<{ + artifact: IdentityArtifact; + registerOutput: RegisterOutput; + proveOutput: ProveOutput; +}>; + +/** + * Build an IdentityArtifact from a credential. + * + * This performs: + * 1. register() - Creates the commitment structure and encrypts the credential + * 2. prove() - Generates the ZK identity proof + * 3. Returns the IdentityArtifact + */ +export const buildIdentityArtifact = async ( + lemmaClient: LemmaClient, + input: BuildArtifactInput, +): Promise => { + // Step 1: Register the credential (commit + encrypt) + const registerOutput = await register(lemmaClient, { + credential: input.credential, + holderKey: input.holderKey, + }); + + // Step 2: Generate the identity proof + const proveOutput = await prove(lemmaClient, { + commitOutput: registerOutput.commitOutput, + issuerSecretKey: input.issuerSecretKey, + mac: input.mac, + issuerPublicKey: input.issuerPublicKey, + // Default 'nowSec' to current time + nowSec: Math.floor(Date.now() / 1000).toString(), + }); + + // Step 3: Build the IdentityArtifact + const artifact: IdentityArtifact = { + commitOutput: registerOutput.commitOutput, + identityProof: proveOutput, + docHash: registerOutput.docHash, + credential: input.credential, + }; + + return { + artifact, + registerOutput, + proveOutput, + }; +}; + +// ── Re-exports for convenience ──────────────────────────────────────────── + +// Re-export IdentityArtifact type from @trust402/protocol +export type { IdentityArtifact } from "@trust402/protocol"; + +// Re-export LemmaClient type for convenience +export type { LemmaClient } from "@lemmaoracle/sdk"; diff --git a/packages/agent/src/kyc/index.ts b/packages/agent/src/kyc/index.ts new file mode 100644 index 0000000..190ed1a --- /dev/null +++ b/packages/agent/src/kyc/index.ts @@ -0,0 +1,36 @@ +/** + * KYC attribute proof system for Trust402. + * + * Provides utilities for: + * - Building AgentCredentials with KYC roles/scopes/permissions + * - Creating IdentityArtifacts for proof attachment + * - Verifying KYC attributes on the worker side + */ + +// Types +export type { + KycRole, + KycRoles, + KycScope, + KycScopes, + KycPermission, + KycPermissions, + KycCredential, + KycVerificationResult, + KycGateConfig, +} from "./types.js"; + +// Artifact building +export { + buildKycCredential, + buildIdentityArtifact, + type BuildCredentialInput, + type BuildArtifactInput, + type BuildArtifactResult, +} from "./artifact.js"; + +// Re-export IdentityArtifact type from @trust402/protocol +export type { IdentityArtifact } from "@trust402/protocol"; + +// Re-export LemmaClient for convenience +export type { LemmaClient } from "@lemmaoracle/sdk"; diff --git a/packages/agent/src/kyc/types.ts b/packages/agent/src/kyc/types.ts new file mode 100644 index 0000000..375322b --- /dev/null +++ b/packages/agent/src/kyc/types.ts @@ -0,0 +1,106 @@ +/** + * KYC-specific types for Trust402 identity proof system. + * + * These types encode KYC attributes as roles, scopes, and permissions + * within the AgentCredential structure. + */ + +import type { ReadonlyDeep } from "type-fest"; + +// ── KYC Roles ───────────────────────────────────────────────────────────── + +/** + * Standard KYC verification roles. + * + * These roles indicate the level of identity verification the agent has completed. + */ +export type KycRole = Readonly<{ + name: + | "kyc-verified" + | "aml-cleared" + | "sanctions-clear" + | "accredited-investor" + | "institutional"; +}>; + +/** + * Array of KYC roles. + */ +export type KycRoles = ReadonlyArray; + +// ── KYC Scopes ──────────────────────────────────────────────────────────── + +/** + * KYC scopes define the operational boundaries for payments. + */ +export type KycScope = Readonly<{ + name: + | "payment:stablecoin" + | "payment:fiat" + | "payment:crypto" + | "payment:cross-border"; +}>; + +/** + * Array of KYC scopes. + */ +export type KycScopes = ReadonlyArray; + +// ── KYC Permissions ─────────────────────────────────────────────────────── + +/** + * KYC permissions define specific actions the agent can perform. + */ +export type KycPermission = Readonly<{ + resource: + | "stablecoin:issue" + | "stablecoin:redeem" + | "stablecoin:transfer" + | "fiat:on-ramp" + | "fiat:off-ramp"; + action: "execute" | "read" | "write"; +}>; + +/** + * Array of KYC permissions. + */ +export type KycPermissions = ReadonlyArray; + +// ── KYC Credential ──────────────────────────────────────────────────────── + +/** + * Full KYC credential structure for an agent. + */ +export type KycCredential = ReadonlyDeep<{ + roles: KycRoles; + scopes: KycScopes; + permissions: KycPermissions; +}>; + +// ── KYC Verification Result ─────────────────────────────────────────────── + +/** + * Result of KYC verification on the worker side. + */ +export type KycVerificationResult = Readonly<{ + verified: boolean; + agentId?: string; + roles: ReadonlyArray; + scopes: ReadonlyArray; + permissions: ReadonlyArray; + missingRoles?: ReadonlyArray; + reason?: string; +}>; + +// ── KYC Gate Configuration ─────────────────────────────────────────────── + +/** + * Configuration for KYC gate requirements. + * Defines which roles/scopes/permissions are required to access a resource. + */ +export type KycGateConfig = Readonly<{ + requiredRoles?: ReadonlyArray; + requiredScopes?: ReadonlyArray; + requiredPermissions?: ReadonlyArray<{ resource: string; action: string }>; + requireAll?: boolean; // If true, all requirements must be met. If false, any one is sufficient. +}>; diff --git a/packages/worker/package.json b/packages/worker/package.json index 65a2e97..83ff094 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -11,13 +11,18 @@ }, "dependencies": { "@coinbase/x402": "^2.1.0", + "@lemmaoracle/agent": "^0.0.24-alpha.1", "@lemmaoracle/sdk": "^0.0.21", "@lemmaoracle/spec": "^0.0.21", "@lemmaoracle/x402": "^0.1.6", - "hono": "^4.12.15" + "@trust402/identity": "workspace:*", + "@trust402/protocol": "workspace:*", + "hono": "^4.12.15", + "ramda": "^0.30.0" }, "devDependencies": { "@cloudflare/workers-types": "^4.20260426.1", + "@types/ramda": "^0.30.0", "typescript": "^5.9.3", "vitest": "^3.2.4", "wrangler": "^4.85.0" diff --git a/packages/worker/src/index.ts b/packages/worker/src/index.ts index 46270e5..b8ad55f 100644 --- a/packages/worker/src/index.ts +++ b/packages/worker/src/index.ts @@ -8,6 +8,7 @@ * Endpoints: * GET /example/verify/:hash -- Provenance verification ($0.001 USDC) * POST /example/query -- Full BBS+ selective disclosure ($0.001 USDC) + * GET /example/kyc-check -- KYC attribute verification ($0.001 USDC) * GET / -- Health check * * Content is free. Trust costs $0.001. @@ -21,6 +22,13 @@ import { ExactEvmScheme, } from "@lemmaoracle/x402"; import { createFacilitatorConfig } from "@coinbase/x402"; +import { + verifyKycGate, + KycGates, + extractCredential, + type KycVerificationResult, + type KycGateConfig, +} from "./kyc/index.js"; // --------------------------------------------------------------------------- // Types @@ -177,6 +185,23 @@ const staticRoutes = { mimeType: "application/json", extensions: { lemma: {} }, }, + "GET /example/kyc-check": { + accepts: [ + { + scheme: "exact" as const, + price: "$0.001", + network: "eip155:84532" as const, + payTo: "", // resolved dynamically below + extra: { + name: "USDC", + version: "2", + }, + }, + ], + description: "KYC attribute verification from identity proof", + mimeType: "application/json", + extensions: { lemma: { requiresIdentity: true } }, + }, }; // --------------------------------------------------------------------------- @@ -238,6 +263,12 @@ app.use("*", async (c, next) => { (accept) => ({ ...accept, payTo }), ), }, + "GET /example/kyc-check": { + ...staticRoutes["GET /example/kyc-check"], + accepts: staticRoutes["GET /example/kyc-check"].accepts.map( + (accept) => ({ ...accept, payTo }), + ), + }, }; const middleware = paymentMiddleware(routes, resourceServer); @@ -296,6 +327,43 @@ app.post("/example/query", async (c) => { }); }); +// --------------------------------------------------------------------------- +// GET /example/kyc-check -- KYC attribute verification endpoint +// --------------------------------------------------------------------------- +app.get("/example/kyc-check", async (c) => { + // Extract credential from payment headers + const headers: Record = {}; + c.req.raw.headers.forEach((v, k) => { + headers[k] = v; + }); + + const credential = extractCredential(headers); + + if (!credential) { + return c.json( + { + verified: false, + roles: [], + scopes: [], + permissions: [], + reason: "No credential found in payment headers", + }, + 403, + ); + } + + // Use basic KYC gate by default, but allow customization via query params + const gateParam = c.req.query("gate"); + const gate: KycGateConfig = + gateParam && gateParam in KycGates + ? KycGates[gateParam as keyof typeof KycGates] + : KycGates.basic; + + const result = verifyKycGate(credential, gate); + + return c.json(result, result.verified ? 200 : 403); +}); + // --------------------------------------------------------------------------- // Health check // --------------------------------------------------------------------------- @@ -307,6 +375,7 @@ app.get("/", (c) => endpoints: { verify: "GET /example/verify/:hash (provenance verification)", query: "POST /example/query (BBS+ selective disclosure)", + kycCheck: "GET /example/kyc-check (KYC attribute verification)", health: "GET /", }, }), diff --git a/packages/worker/src/kyc/index.ts b/packages/worker/src/kyc/index.ts new file mode 100644 index 0000000..8a1387d --- /dev/null +++ b/packages/worker/src/kyc/index.ts @@ -0,0 +1,21 @@ +/** + * KYC verification module for worker-side enforcement. + */ + +export { + IDENTITY_ARTIFACT_HEADER, + IDENTITY_PROOF_HEADER, + CREDENTIAL_HEADER, + extractIdentityArtifact, + extractIdentityProof, + extractCredential, + hasRole, + hasScope, + hasPermission, + isExpired, + isRevoked, + verifyKycGate, + KycGates, +} from "./verify.js"; + +export type { KycVerificationResult, KycGateConfig } from "./verify.js"; diff --git a/packages/worker/src/kyc/verify.test.ts b/packages/worker/src/kyc/verify.test.ts new file mode 100644 index 0000000..104f371 --- /dev/null +++ b/packages/worker/src/kyc/verify.test.ts @@ -0,0 +1,488 @@ +/** + * KYC verification tests — Worker-side enforcement. + */ + +import { describe, it, expect } from "vitest"; +import { + verifyKycGate, + hasRole, + hasScope, + hasPermission, + isExpired, + isRevoked, + KycGates, + extractCredential, + extractIdentityArtifact, + type KycVerificationResult, +} from "./verify.js"; +import type { AgentCredential } from "@lemmaoracle/agent"; +import type { IdentityArtifact } from "@trust402/protocol"; + +// --------------------------------------------------------------------------- +// Test fixtures +// --------------------------------------------------------------------------- + +const createCredential = ( + overrides: Partial = {}, +): AgentCredential => ({ + schema: "agent-credential-v1", + identity: { + agentId: "agent-001", + subjectId: "subject-001", + }, + authority: { + roles: [{ name: "kyc-verified" }], + scopes: [{ name: "payment:stablecoin" }], + permissions: [{ resource: "stablecoin:transfer", action: "execute" }], + }, + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000), + revoked: false, + }, + provenance: { + issuerId: "issuer-001", + sourceSystem: "trust402-kyc", + }, + ...overrides, +}); + +const createIdentityArtifact = ( + credential: AgentCredential = createCredential(), + overrides: Partial = {}, +): IdentityArtifact => ({ + commitOutput: { + root: "1234567890123456789012345678901234567890123456789012345678901234", + salt: "0".repeat(64), + sectionHashes: { + identityHash: "a".repeat(64), + authorityHash: "b".repeat(64), + financialHash: "c".repeat(64), + lifecycleHash: "d".repeat(64), + provenanceHash: "e".repeat(64), + }, + normalized: { + schema: "agent-identity-authority-v1", + identity: { + agentId: credential.identity.agentId, + subjectId: credential.identity.subjectId, + controllerId: credential.identity.controllerId ?? "", + orgId: credential.identity.orgId ?? "", + }, + authority: { + roles: credential.authority.roles.map((r) => r.name).join(","), + scopes: credential.authority.scopes.map((s) => s.name).join(","), + permissions: credential.authority.permissions.map((p) => `${p.resource}:${p.action}`).join(","), + }, + financial: { + spendLimit: "1000", + currency: "USDC", + paymentPolicy: "", + }, + lifecycle: { + issuedAt: String(credential.lifecycle.issuedAt), + expiresAt: String(credential.lifecycle.expiresAt ?? 0), + revoked: "false", + revocationRef: "", + }, + provenance: { + issuerId: credential.provenance.issuerId, + sourceSystem: credential.provenance.sourceSystem ?? "", + generatorId: credential.provenance.generatorId ?? "", + chainId: "84532", + network: "base-sepolia", + }, + }, + }, + identityProof: { + proof: "test-proof", + inputs: ["input1", "input2"], + }, + docHash: "test-doc-hash", + credential, + ...overrides, +}); + +// --------------------------------------------------------------------------- +// Tests +// --------------------------------------------------------------------------- + +describe("KYC Verification", () => { + describe("hasRole", () => { + it("should return true when credential has the role", () => { + const cred = createCredential(); + expect(hasRole(cred, "kyc-verified")).toBe(true); + }); + + it("should return false when credential lacks the role", () => { + const cred = createCredential(); + expect(hasRole(cred, "aml-cleared")).toBe(false); + }); + + it("should check multiple roles correctly", () => { + const cred = createCredential({ + authority: { + roles: [ + { name: "kyc-verified" }, + { name: "aml-cleared" }, + { name: "sanctions-clear" }, + ], + scopes: [], + permissions: [], + }, + }); + + expect(hasRole(cred, "kyc-verified")).toBe(true); + expect(hasRole(cred, "aml-cleared")).toBe(true); + expect(hasRole(cred, "sanctions-clear")).toBe(true); + expect(hasRole(cred, "institutional")).toBe(false); + }); + }); + + describe("hasScope", () => { + it("should return true when credential has the scope", () => { + const cred = createCredential(); + expect(hasScope(cred, "payment:stablecoin")).toBe(true); + }); + + it("should return false when credential lacks the scope", () => { + const cred = createCredential(); + expect(hasScope(cred, "payment:fiat")).toBe(false); + }); + }); + + describe("hasPermission", () => { + it("should return true when credential has the permission", () => { + const cred = createCredential(); + expect(hasPermission(cred, "stablecoin:transfer", "execute")).toBe(true); + }); + + it("should return false when action does not match", () => { + const cred = createCredential(); + expect(hasPermission(cred, "stablecoin:transfer", "read")).toBe(false); + }); + + it("should return false when resource does not match", () => { + const cred = createCredential(); + expect(hasPermission(cred, "stablecoin:issue", "execute")).toBe(false); + }); + }); + + describe("isExpired", () => { + it("should return false for credential without expiry", () => { + const cred = createCredential(); + expect(isExpired(cred)).toBe(false); + }); + + it("should return false for non-expired credential", () => { + const cred = createCredential({ + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000) - 3600, + expiresAt: Math.floor(Date.now() / 1000) + 3600, + revoked: false, + }, + }); + expect(isExpired(cred)).toBe(false); + }); + + it("should return true for expired credential", () => { + const cred = createCredential({ + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000) - 7200, + expiresAt: Math.floor(Date.now() / 1000) - 3600, + revoked: false, + }, + }); + expect(isExpired(cred)).toBe(true); + }); + }); + + describe("isRevoked", () => { + it("should return false for non-revoked credential", () => { + const cred = createCredential(); + expect(isRevoked(cred)).toBe(false); + }); + + it("should return true for revoked credential", () => { + const cred = createCredential({ + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000), + revoked: true, + }, + }); + expect(isRevoked(cred)).toBe(true); + }); + }); + + describe("verifyKycGate", () => { + it("should verify basic KYC gate with matching role", () => { + const cred = createCredential(); + const result = verifyKycGate(cred, KycGates.basic); + + expect(result.verified).toBe(true); + expect(result.agentId).toBe("agent-001"); + expect(result.roles).toContain("kyc-verified"); + }); + + it("should reject when missing required role", () => { + const cred = createCredential({ + authority: { + roles: [], + scopes: [], + permissions: [], + }, + }); + + const result = verifyKycGate(cred, KycGates.basic); + + expect(result.verified).toBe(false); + expect(result.reason).toBe("Missing required KYC attributes"); + expect(result.missingRoles).toContain("kyc-verified"); + }); + + it("should verify AML compliance gate with all required roles", () => { + const cred = createCredential({ + authority: { + roles: [ + { name: "kyc-verified" }, + { name: "aml-cleared" }, + { name: "sanctions-clear" }, + ], + scopes: [], + permissions: [], + }, + }); + + const result = verifyKycGate(cred, KycGates.amlCompliance); + + expect(result.verified).toBe(true); + }); + + it("should reject AML compliance gate with missing role", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "kyc-verified" }, { name: "aml-cleared" }], + scopes: [], + permissions: [], + }, + }); + + const result = verifyKycGate(cred, KycGates.amlCompliance); + + expect(result.verified).toBe(false); + expect(result.missingRoles).toContain("sanctions-clear"); + }); + + it("should verify stablecoin payment gate with matching scope", () => { + const cred = createCredential(); + const result = verifyKycGate(cred, KycGates.stablecoinPayment); + + expect(result.verified).toBe(true); + expect(result.scopes).toContain("payment:stablecoin"); + }); + + it("should reject stablecoin payment gate without scope", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "kyc-verified" }], + scopes: [], + permissions: [], + }, + }); + + const result = verifyKycGate(cred, KycGates.stablecoinPayment); + + expect(result.verified).toBe(false); + }); + + it("should verify issuance gate with matching permission", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "kyc-verified" }], + scopes: [], + permissions: [{ resource: "stablecoin:issue", action: "execute" }], + }, + }); + + const result = verifyKycGate(cred, KycGates.stablecoinIssuance); + + expect(result.verified).toBe(true); + }); + + it("should verify institutional gate for institutional role", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "institutional" }], + scopes: [], + permissions: [], + }, + }); + + const result = verifyKycGate(cred, KycGates.institutional); + + expect(result.verified).toBe(true); + }); + + it("should reject expired credential", () => { + const cred = createCredential({ + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000) - 7200, + expiresAt: Math.floor(Date.now() / 1000) - 3600, + revoked: false, + }, + }); + + const result = verifyKycGate(cred, KycGates.basic); + + expect(result.verified).toBe(false); + expect(result.reason).toBe("Credential expired"); + }); + + it("should reject revoked credential", () => { + const cred = createCredential({ + lifecycle: { + issuedAt: Math.floor(Date.now() / 1000), + revoked: true, + }, + }); + + const result = verifyKycGate(cred, KycGates.basic); + + expect(result.verified).toBe(false); + expect(result.reason).toBe("Credential revoked"); + }); + + it("should support requireAll: false for any-one semantics", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "aml-cleared" }], + scopes: [], + permissions: [], + }, + }); + + const gate = { + requiredRoles: ["kyc-verified", "aml-cleared", "sanctions-clear"], + requireAll: false, + }; + + const result = verifyKycGate(cred, gate); + + expect(result.verified).toBe(true); + }); + + it("should reject all-requireAll: false when no requirements are met", () => { + const cred = createCredential({ + authority: { + roles: [{ name: "some-other-role" }], + scopes: [], + permissions: [], + }, + }); + + const gate = { + requiredRoles: ["kyc-verified", "aml-cleared"], + requireAll: false, + }; + + const result = verifyKycGate(cred, gate); + + expect(result.verified).toBe(false); + }); + }); + + describe("extractIdentityArtifact", () => { + it("should extract valid IdentityArtifact from X-PAYMENT-IDENTITY header", () => { + const credential = createCredential(); + const artifact = createIdentityArtifact(credential); + const encoded = btoa(JSON.stringify(artifact)); + const headers = { "X-PAYMENT-IDENTITY": encoded }; + + const result = extractIdentityArtifact(headers); + + expect(result).not.toBeNull(); + expect(result?.docHash).toBe("test-doc-hash"); + expect(result?.credential.identity.agentId).toBe("agent-001"); + }); + + it("should return null for missing header", () => { + const headers = {}; + const result = extractIdentityArtifact(headers); + expect(result).toBeNull(); + }); + + it("should return null for invalid base64", () => { + const headers = { "X-PAYMENT-IDENTITY": "not-valid-base64!!!" }; + const result = extractIdentityArtifact(headers); + expect(result).toBeNull(); + }); + + it("should return null for invalid JSON", () => { + const headers = { "X-PAYMENT-IDENTITY": btoa("not json") }; + const result = extractIdentityArtifact(headers); + expect(result).toBeNull(); + }); + }); + + describe("extractCredential", () => { + it("should extract credential from X-PAYMENT-IDENTITY header", () => { + const credential = createCredential(); + const artifact = createIdentityArtifact(credential); + const encoded = btoa(JSON.stringify(artifact)); + const headers = { "X-PAYMENT-IDENTITY": encoded }; + + const result = extractCredential(headers); + + expect(result).not.toBeNull(); + expect(result?.identity.agentId).toBe("agent-001"); + }); + + it("should fallback to X-Lemma-Credential header for backward compatibility", () => { + const cred = createCredential(); + const encoded = btoa(JSON.stringify(cred)); + const headers = { "X-Lemma-Credential": encoded }; + + const result = extractCredential(headers); + + expect(result).not.toBeNull(); + expect(result?.identity.agentId).toBe("agent-001"); + }); + + it("should prefer X-PAYMENT-IDENTITY over X-Lemma-Credential", () => { + const cred1 = createCredential({ + identity: { agentId: "agent-001", subjectId: "subject-001" }, + }); + const cred2 = createCredential({ + identity: { agentId: "agent-002", subjectId: "subject-002" }, + }); + + const artifact = createIdentityArtifact(cred1); + const headers = { + "X-PAYMENT-IDENTITY": btoa(JSON.stringify(artifact)), + "X-Lemma-Credential": btoa(JSON.stringify(cred2)), + }; + + const result = extractCredential(headers); + + // Should use X-PAYMENT-IDENTITY + expect(result?.identity.agentId).toBe("agent-001"); + }); + + it("should return null for missing headers", () => { + const headers: Record = {}; + const result = extractCredential(headers); + expect(result).toBeNull(); + }); + + it("should return null for invalid base64", () => { + const headers = { "X-Lemma-Credential": "not-valid-base64!!!" }; + const result = extractCredential(headers); + expect(result).toBeNull(); + }); + + it("should return null for invalid JSON", () => { + const headers = { "X-Lemma-Credential": btoa("not json") }; + const result = extractCredential(headers); + expect(result).toBeNull(); + }); + }); +}); diff --git a/packages/worker/src/kyc/verify.ts b/packages/worker/src/kyc/verify.ts new file mode 100644 index 0000000..3170f2b --- /dev/null +++ b/packages/worker/src/kyc/verify.ts @@ -0,0 +1,331 @@ +/** + * KYC verification utilities for worker-side enforcement. + * + * Verifies identity proofs from x402 payment headers and checks KYC attributes. + * Reads from X-PAYMENT-IDENTITY header (Base64-encoded JSON IdentityArtifact). + */ + +import * as R from "ramda"; +import type { AgentCredential } from "@lemmaoracle/agent"; +import type { IdentityArtifact } from "@trust402/protocol"; + +// ── Types (defined locally to avoid cross-package imports) ───────────────────── + +export type KycVerificationResult = Readonly<{ + verified: boolean; + agentId?: string; + roles: ReadonlyArray; + scopes: ReadonlyArray; + permissions: ReadonlyArray; + missingRoles?: ReadonlyArray; + reason?: string; +}>; + +export type KycGateConfig = Readonly<{ + requiredRoles?: ReadonlyArray; + requiredScopes?: ReadonlyArray; + requiredPermissions?: ReadonlyArray<{ resource: string; action: string }>; + requireAll?: boolean; +}>; + +// ── Constants ───────────────────────────────────────────────────────────── + +/** + * Header name for identity artifact in x402 payment. + * Contains Base64-encoded JSON IdentityArtifact. + */ +export const IDENTITY_ARTIFACT_HEADER = "X-PAYMENT-IDENTITY"; + +/** + * Legacy header names (for backward compatibility). + */ +export const IDENTITY_PROOF_HEADER = "X-Lemma-Identity-Proof"; +export const CREDENTIAL_HEADER = "X-Lemma-Credential"; + +// ── Header Extraction ─────────────────────────────────────────────────────── + +/** + * Extract IdentityArtifact from X-PAYMENT-IDENTITY header. + * + * The header contains Base64-encoded JSON with structure: + * { + * commitOutput: { ... }, + * identityProof: { proof: string, inputs: string[] }, + * docHash: string, + * credential: AgentCredential + * } + */ +export const extractIdentityArtifact = ( + headers: Record, +): IdentityArtifact | null => { + const artifactHeader = headers[IDENTITY_ARTIFACT_HEADER]; + if (!artifactHeader) return null; + + try { + return JSON.parse(atob(artifactHeader)) as IdentityArtifact; + } catch { + return null; + } +}; + +/** + * Extract credential from X-PAYMENT-IDENTITY header. + * This is the primary method for KYC verification. + */ +export const extractCredential = ( + headers: Record, +): AgentCredential | null => { + // Primary path: extract from X-PAYMENT-IDENTITY header + const artifact = extractIdentityArtifact(headers); + if (artifact) { + return artifact.credential; + } + + // Fallback: legacy X-Lemma-Credential header (for backward compatibility) + const credHeader = headers[CREDENTIAL_HEADER]; + if (!credHeader) return null; + + try { + return JSON.parse(atob(credHeader)) as AgentCredential; + } catch { + return null; + } +}; + +/** + * Extract identity proof from payment headers. + * Returns the identityProof from the IdentityArtifact. + */ +export const extractIdentityProof = ( + headers: Record, +): Readonly> | null => { + // Primary path: extract from X-PAYMENT-IDENTITY header + const artifact = extractIdentityArtifact(headers); + if (artifact) { + return artifact.identityProof as unknown as Record; + } + + // Fallback: legacy X-Lemma-Identity-Proof header + const proofHeader = headers[IDENTITY_PROOF_HEADER]; + if (!proofHeader) return null; + + try { + return JSON.parse(atob(proofHeader)) as Record; + } catch { + return null; + } +}; + +// ── KYC Verification ────────────────────────────────────────────────────── + +/** + * Extract role names from credential. + */ +const extractRoleNames = (cred: AgentCredential): ReadonlyArray => + R.map((r) => r.name, cred.authority.roles); + +/** + * Extract scope names from credential. + */ +const extractScopeNames = (cred: AgentCredential): ReadonlyArray => + R.map((s) => s.name, cred.authority.scopes); + +/** + * Extract permission strings from credential. + */ +const extractPermissionStrings = (cred: AgentCredential): ReadonlyArray => + R.map((p) => `${p.resource}:${p.action}`, cred.authority.permissions); + +/** + * Check if credential has a specific role. + */ +export const hasRole = (cred: AgentCredential, roleName: string): boolean => + R.any((r) => r.name === roleName, cred.authority.roles); + +/** + * Check if credential has a specific scope. + */ +export const hasScope = (cred: AgentCredential, scopeName: string): boolean => + R.any((s) => s.name === scopeName, cred.authority.scopes); + +/** + * Check if credential has a specific permission. + */ +export const hasPermission = ( + cred: AgentCredential, + resource: string, + action: string, +): boolean => + R.any( + (p) => p.resource === resource && p.action === action, + cred.authority.permissions, + ); + +/** + * Check if credential is expired. + */ +export const isExpired = (cred: AgentCredential): boolean => { + if (!cred.lifecycle.expiresAt) return false; + return cred.lifecycle.expiresAt < Math.floor(Date.now() / 1000); +}; + +/** + * Check if credential is revoked. + */ +export const isRevoked = (cred: AgentCredential): boolean => + cred.lifecycle.revoked === true; + +/** + * Verify KYC gate requirements against a credential. + */ +export const verifyKycGate = ( + cred: AgentCredential, + gate: KycGateConfig, +): KycVerificationResult => { + // Check expiration and revocation + if (isExpired(cred)) { + return { + verified: false, + agentId: cred.identity.agentId, + roles: extractRoleNames(cred), + scopes: extractScopeNames(cred), + permissions: extractPermissionStrings(cred), + reason: "Credential expired", + }; + } + + if (isRevoked(cred)) { + return { + verified: false, + agentId: cred.identity.agentId, + roles: extractRoleNames(cred), + scopes: extractScopeNames(cred), + permissions: extractPermissionStrings(cred), + reason: "Credential revoked", + }; + } + + const requiredRoles = gate.requiredRoles ?? []; + const requiredScopes = gate.requiredScopes ?? []; + const requiredPermissions = gate.requiredPermissions ?? []; + const requireAll = gate.requireAll ?? true; + + // Collect missing requirements + const missingRoles = R.filter( + (name: string) => !hasRole(cred, name), + requiredRoles, + ); + + const missingScopes = R.filter( + (name: string) => !hasScope(cred, name), + requiredScopes, + ); + + const missingPermissions = R.filter( + (req: { resource: string; action: string }) => + !hasPermission(cred, req.resource, req.action), + requiredPermissions, + ); + + // Determine if verified based on requireAll flag + let verified: boolean; + let missingRolesList: ReadonlyArray; + + if (requireAll) { + // All requirements must be met + verified = + missingRoles.length === 0 && + missingScopes.length === 0 && + missingPermissions.length === 0; + missingRolesList = [ + ...missingRoles, + ...missingScopes, + ...R.map( + (p: { resource: string; action: string }) => `${p.resource}:${p.action}`, + missingPermissions, + ), + ]; + } else { + // Any one requirement being met is sufficient + const hasAnyRole = + requiredRoles.length > 0 && + R.any((name: string) => hasRole(cred, name), requiredRoles); + const hasAnyScope = + requiredScopes.length > 0 && + R.any((name: string) => hasScope(cred, name), requiredScopes); + const hasAnyPermission = + requiredPermissions.length > 0 && + R.any( + (req: { resource: string; action: string }) => + hasPermission(cred, req.resource, req.action), + requiredPermissions, + ); + + verified = + hasAnyRole || hasAnyScope || hasAnyPermission || + (requiredRoles.length === 0 && requiredScopes.length === 0 && requiredPermissions.length === 0); + + missingRolesList = verified + ? [] + : [...requiredRoles, ...requiredScopes, ...R.map((p) => `${p.resource}:${p.action}`, requiredPermissions)]; + } + + return { + verified, + agentId: cred.identity.agentId, + roles: extractRoleNames(cred), + scopes: extractScopeNames(cred), + permissions: extractPermissionStrings(cred), + ...(missingRolesList.length > 0 ? { missingRoles: missingRolesList } : {}), + ...(verified ? {} : { reason: "Missing required KYC attributes" }), + }; +}; + +// ── Predefined KYC Gates ───────────────────────────────────────────────── + +/** + * Standard KYC gates for common use cases. + */ +export const KycGates = { + /** + * Basic KYC verification - requires kyc-verified role. + */ + basic: { + requiredRoles: ["kyc-verified"], + requireAll: true, + } as const satisfies KycGateConfig, + + /** + * AML/CFT compliance - requires KYC + sanctions + AML clearance. + */ + amlCompliance: { + requiredRoles: ["kyc-verified", "aml-cleared", "sanctions-clear"], + requireAll: true, + } as const satisfies KycGateConfig, + + /** + * Stablecoin operations - requires KYC + stablecoin scope. + */ + stablecoinPayment: { + requiredRoles: ["kyc-verified"], + requiredScopes: ["payment:stablecoin"], + requireAll: true, + } as const satisfies KycGateConfig, + + /** + * Issuance operations - requires specific permissions. + */ + stablecoinIssuance: { + requiredRoles: ["kyc-verified"], + requiredPermissions: [{ resource: "stablecoin:issue", action: "execute" }], + requireAll: true, + } as const satisfies KycGateConfig, + + /** + * High-value payments - requires institutional KYC level. + */ + institutional: { + requiredRoles: ["institutional"], + requireAll: true, + } as const satisfies KycGateConfig, +} as const; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 987f0b3..16dd8da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -42,6 +42,21 @@ importers: packages/agent: dependencies: + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@trust402/identity': + specifier: workspace:* + version: link:../../vendors/trust402/packages/identity + '@trust402/protocol': + specifier: workspace:* + version: link:../../vendors/trust402/packages/protocol + '@trust402/roles': + specifier: workspace:* + version: link:../../vendors/trust402/packages/roles '@x402/core': specifier: ^2.10.0 version: 2.10.0 @@ -69,6 +84,9 @@ importers: ora: specifier: ^9.4.0 version: 9.4.0 + ramda: + specifier: ^0.30.0 + version: 0.30.1 viem: specifier: ^2.48.4 version: 2.48.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) @@ -76,6 +94,9 @@ importers: '@types/node': specifier: ^22.19.17 version: 22.19.17 + '@types/ramda': + specifier: ^0.30.0 + version: 0.30.2 tsx: specifier: ^4.21.0 version: 4.21.0 @@ -111,6 +132,9 @@ importers: '@coinbase/x402': specifier: ^2.1.0 version: 2.1.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 '@lemmaoracle/sdk': specifier: ^0.0.21 version: 0.0.21 @@ -120,13 +144,25 @@ importers: '@lemmaoracle/x402': specifier: ^0.1.6 version: 0.1.6(@lemmaoracle/sdk@0.0.21)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(utf-8-validate@5.0.10) + '@trust402/identity': + specifier: workspace:* + version: link:../../vendors/trust402/packages/identity + '@trust402/protocol': + specifier: workspace:* + version: link:../../vendors/trust402/packages/protocol hono: specifier: ^4.12.15 version: 4.12.15 + ramda: + specifier: ^0.30.0 + version: 0.30.1 devDependencies: '@cloudflare/workers-types': specifier: ^4.20260426.1 version: 4.20260426.1 + '@types/ramda': + specifier: ^0.30.0 + version: 0.30.2 typescript: specifier: ^5.9.3 version: 5.9.3 @@ -137,6 +173,224 @@ importers: specifier: ^4.85.0 version: 4.85.0(@cloudflare/workers-types@4.20260426.1)(bufferutil@4.1.0)(utf-8-validate@5.0.10) + vendors/trust402/packages/cli: + dependencies: + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@lemmaoracle/spec': + specifier: ^0.0.22 + version: 0.0.22 + '@trust402/identity': + specifier: workspace:* + version: link:../identity + commander: + specifier: ^13.0.0 + version: 13.1.0 + ramda: + specifier: ^0.30.0 + version: 0.30.1 + devDependencies: + '@eslint/js': + specifier: ^9.0.0 + version: 9.39.4 + '@types/node': + specifier: ^22.0.0 + version: 22.19.17 + '@types/ramda': + specifier: ^0.30.0 + version: 0.30.2 + eslint: + specifier: ^9.0.0 + version: 9.39.4 + eslint-config-prettier: + specifier: ^10.0.0 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-functional: + specifier: ^7.0.0 + version: 7.3.1(eslint@9.39.4)(typescript@5.9.3) + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + typescript-eslint: + specifier: ^8.0.0 + version: 8.59.2(eslint@9.39.4)(typescript@5.9.3) + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@22.19.17)(tsx@4.21.0) + + vendors/trust402/packages/demo: + dependencies: + poseidon-lite: + specifier: ^0.3.0 + version: 0.3.0 + devDependencies: + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@lemmaoracle/spec': + specifier: ^0.0.22 + version: 0.0.22 + '@types/ramda': + specifier: ^0.30.0 + version: 0.30.2 + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + ramda: + specifier: ^0.30.0 + version: 0.30.1 + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + + vendors/trust402/packages/identity: + dependencies: + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@lemmaoracle/spec': + specifier: ^0.0.22 + version: 0.0.22 + devDependencies: + '@eslint/js': + specifier: ^9.0.0 + version: 9.39.4 + '@types/node': + specifier: ^22.0.0 + version: 22.19.17 + eslint: + specifier: ^9.0.0 + version: 9.39.4 + eslint-config-prettier: + specifier: ^10.0.0 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-functional: + specifier: ^7.0.0 + version: 7.3.1(eslint@9.39.4)(typescript@5.9.3) + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + typescript-eslint: + specifier: ^8.0.0 + version: 8.59.2(eslint@9.39.4)(typescript@5.9.3) + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@22.19.17)(tsx@4.21.0) + + vendors/trust402/packages/protocol: + dependencies: + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@lemmaoracle/spec': + specifier: ^0.0.22 + version: 0.0.22 + '@trust402/identity': + specifier: workspace:* + version: link:../identity + '@trust402/roles': + specifier: workspace:* + version: link:../roles + ramda: + specifier: ^0.30.0 + version: 0.30.1 + devDependencies: + '@eslint/js': + specifier: ^9.0.0 + version: 9.39.4 + '@types/node': + specifier: ^22.0.0 + version: 22.19.17 + '@types/ramda': + specifier: ^0.30.0 + version: 0.30.2 + eslint: + specifier: ^9.0.0 + version: 9.39.4 + eslint-config-prettier: + specifier: ^10.0.0 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-functional: + specifier: ^7.0.0 + version: 7.3.1(eslint@9.39.4)(typescript@5.9.3) + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + typescript-eslint: + specifier: ^8.0.0 + version: 8.59.2(eslint@9.39.4)(typescript@5.9.3) + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@22.19.17)(tsx@4.21.0) + + vendors/trust402/packages/roles: + dependencies: + '@lemmaoracle/agent': + specifier: ^0.0.24-alpha.1 + version: 0.0.24-alpha.1 + '@lemmaoracle/sdk': + specifier: ^0.0.23 + version: 0.0.23 + '@lemmaoracle/spec': + specifier: ^0.0.22 + version: 0.0.22 + devDependencies: + '@eslint/js': + specifier: ^9.0.0 + version: 9.39.4 + '@types/node': + specifier: ^22.0.0 + version: 22.19.17 + dotenv: + specifier: ^16.4.7 + version: 16.6.1 + eslint: + specifier: ^9.0.0 + version: 9.39.4 + eslint-config-prettier: + specifier: ^10.0.0 + version: 10.1.8(eslint@9.39.4) + eslint-plugin-functional: + specifier: ^7.0.0 + version: 7.3.1(eslint@9.39.4)(typescript@5.9.3) + poseidon-lite: + specifier: 0.3.0 + version: 0.3.0 + tsx: + specifier: ^4.19.0 + version: 4.21.0 + typescript: + specifier: ^5.8.0 + version: 5.9.3 + typescript-eslint: + specifier: ^8.0.0 + version: 8.59.2(eslint@9.39.4)(typescript@5.9.3) + vitest: + specifier: ^3.0.0 + version: 3.2.4(@types/node@22.19.17)(tsx@4.21.0) + packages: '@adraffy/ens-normalize@1.10.1': @@ -520,6 +774,64 @@ packages: cpu: [x64] os: [win32] + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@iden3/bigarray@0.0.2': resolution: {integrity: sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g==} @@ -689,12 +1001,24 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@lemmaoracle/agent@0.0.24-alpha.1': + resolution: {integrity: sha512-e9M3vHwn1iV7PcBUMh/PeLMYMnkR2GMCaAH4y1rLGZCwTnpbeBDLyDey+Fw9FDrNZ8eaoDzEWoS1DwR3qRZJBg==} + '@lemmaoracle/sdk@0.0.21': resolution: {integrity: sha512-7v5QVlt33ecWzKfE20XYI+y7ed8OOd6YAybtmDa/uQHHBlzNqFGi4XFBB6f5YZyuXBZ0NDKSGGtyrbmRJEi6sg==} + '@lemmaoracle/sdk@0.0.23': + resolution: {integrity: sha512-4R+OtIRO618EhuumG0uNRH0airN8i7jsnYJgD1sq0vfNWm5GGwNHl36+Lk9IKTQ2rMLRgDD9YgyppdDPPxCXpQ==} + '@lemmaoracle/spec@0.0.21': resolution: {integrity: sha512-6jEORWeNZh4J2HD+IvjYkf0BpEPscbS6vxjY5JhX9Q6aTh716ZhmWAdMxPRFMfFHDlTkibSSnd/p6AYPCGFWow==} + '@lemmaoracle/spec@0.0.22': + resolution: {integrity: sha512-MDFoBjzEWZCYgCMWqYHzNn4BpI7dSDOhLHRQX+VVWkK9+9sg36cjU6jshzzuuGjS+ZCPCb28WjhQ8RqwPByevA==} + + '@lemmaoracle/spec@0.0.23': + resolution: {integrity: sha512-/46I22Y3M6+yTDA5Y0rIbuCNpEZ68IRQzZlLZQoJptHIxsoWigwtP2P8nuI4Pw4onGLeraAtw3oc+3OCKQALbg==} + '@lemmaoracle/x402@0.1.6': resolution: {integrity: sha512-YK2U3pFAtKEcdPezmFR8C6HNHqJyi+Psd6/qO1MJSi4JKNpPB3yM6M3AWO1NSp03JTJHFtd1GaHniIbdgN1cTw==} peerDependencies: @@ -1288,12 +1612,77 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/node@22.19.17': resolution: {integrity: sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==} '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/ramda@0.30.2': + resolution: {integrity: sha512-PyzHvjCalm2BRYjAU6nIB3TprYwMNOUY/7P/N8bSzp9W/yM2YrtGtAnnVtaCNSeOZ8DzKyFDvaqQs7LnWwwmBA==} + + '@typescript-eslint/eslint-plugin@8.59.2': + resolution: {integrity: sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.59.2 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.59.2': + resolution: {integrity: sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.59.2': + resolution: {integrity: sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.59.2': + resolution: {integrity: sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.59.2': + resolution: {integrity: sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.59.2': + resolution: {integrity: sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.59.2': + resolution: {integrity: sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.59.2': + resolution: {integrity: sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.59.2': + resolution: {integrity: sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.59.2': + resolution: {integrity: sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@vitest/expect@3.2.4': resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} @@ -1392,9 +1781,22 @@ packages: zod: optional: true + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + aes-js@4.0.0-beta.5: resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} @@ -1402,9 +1804,16 @@ packages: resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + apg-js@4.4.0: resolution: {integrity: sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==} + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -1430,6 +1839,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + bfj@7.1.0: resolution: {integrity: sha512-I6MMLkn+anzNdCUp9hMRyui1HaNEUCco50lxbvNS4+EyXg8lN3nJ48PjPWtbH8UVS9CuMoaKE9U2V3l29DaRQw==} engines: {node: '>= 8.0.0'} @@ -1440,9 +1853,16 @@ packages: bluebird@3.7.2: resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + brace-expansion@2.1.0: resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + browser-process-hrtime@1.0.0: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} @@ -1469,10 +1889,18 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} @@ -1507,14 +1935,28 @@ packages: resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} engines: {node: '>=18.20'} + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + commander@14.0.2: resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} engines: {node: '>=20'} + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + cookie@1.1.1: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} @@ -1539,6 +1981,13 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge-ts@7.1.5: + resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==} + engines: {node: '>=16.0.0'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1608,11 +2057,66 @@ packages: engines: {node: '>=18'} hasBin: true + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} hasBin: true + eslint-config-prettier@10.1.8: + resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-functional@7.3.1: + resolution: {integrity: sha512-f7pa83aVW20RCu5k9xNE929QQ1N+yOt1csoHcEhkG4HLoERk7grroRxK8qginCSS4EOq0KcdyqpB1cHKQTxNQQ==} + engines: {node: '>=v18.18.0'} + deprecated: wrong semantic version number + peerDependencies: + eslint: ^9.0.0 + typescript: '>=4.7.4' + peerDependenciesMeta: + typescript: + optional: true + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + esprima@1.2.5: resolution: {integrity: sha512-S9VbPDU0adFErpDai3qDkjq8+G05ONtKzcyNrPKg/ZKa+tf879nX2KexNU95b31UoTJjRLInNBHHHjFPoCd7lQ==} engines: {node: '>=0.4.0'} @@ -1623,6 +2127,14 @@ packages: engines: {node: '>=4'} hasBin: true + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + estraverse@5.3.0: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} @@ -1648,6 +2160,12 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-uri@3.1.0: resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} @@ -1669,9 +2187,24 @@ packages: ffjavascript@0.3.1: resolution: {integrity: sha512-4PbK1WYodQtuF47D4pRI5KUg3Q392vuP5WjE1THSnceHdXwU3ijaoS0OqxTzLknCtz4Z2TtABzkBdBdMn3B/Aw==} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + filelist@1.0.6: resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + follow-redirects@1.16.0: resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} engines: {node: '>=4.0'} @@ -1712,10 +2245,22 @@ packages: get-tsconfig@4.14.0: resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -1739,6 +2284,22 @@ packages: resolution: {integrity: sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==} engines: {node: '>= 6.0.0'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + is-buffer@1.1.6: resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} @@ -1746,6 +2307,20 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-immutable-type@5.0.1: + resolution: {integrity: sha512-LkHEOGVZZXxGl8vDs+10k3DvP++SEoYEAJLRk6buTFi6kD7QekThV7xHS0j6gpnUCQ0zpud/gMDGiV4dQneLTg==} + peerDependencies: + eslint: '*' + typescript: '>=4.7.4' + is-interactive@2.0.0: resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} engines: {node: '>=12'} @@ -1784,16 +2359,43 @@ packages: js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + jsonpath@1.3.0: resolution: {integrity: sha512-0kjkYHJBkAy50Z5QzArZ7udmvxrJzkpKYW27fiF//BrMY7TQibYLl+FYIXN2BiYmwMIVzSfD8aDRj6IzgBX2/w==} + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kleur@4.1.5: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + log-symbols@7.0.1: resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} engines: {node: '>=18'} @@ -1831,6 +2433,13 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + minimatch@5.1.9: resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} engines: {node: '>=10'} @@ -1846,6 +2455,9 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -1854,6 +2466,10 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + ora@9.4.0: resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==} engines: {node: '>=20'} @@ -1866,9 +2482,25 @@ packages: typescript: optional: true + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} @@ -1904,9 +2536,17 @@ packages: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + r1csfile@0.0.48: resolution: {integrity: sha512-kHRkKUJNaor31l05f2+RFzvcH5XSa7OfEfd/l4hzjte6NL6fjRkSMfZ4BjySW9wmfdwPOtq3mXurzPvPGEf5Tw==} @@ -1923,6 +2563,10 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -1999,6 +2643,10 @@ packages: resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -2006,6 +2654,10 @@ packages: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -2031,6 +2683,20 @@ packages: tryer@1.0.1: resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-declaration-location@1.0.7: + resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} + peerDependencies: + typescript: '>=4.0.0' + + ts-toolbelt@9.6.0: + resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} @@ -2045,6 +2711,20 @@ packages: tweetnacl@1.0.3: resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + types-ramda@0.30.1: + resolution: {integrity: sha512-1HTsf5/QVRmLzcGfldPFvkVsAdi1db1BBKzi7iW3KBUlOICg/nKnFS+jGqDJS3YD8VsWbAh7JiHeBvbsw8RPxA==} + + typescript-eslint@8.59.2: + resolution: {integrity: sha512-pJw051uomb3ZeCzGTpRb8RbEqB5Y4WWet8gl/GcTlU35BSx0PVdZ86/bqkQCyKKuraVQEK7r6kBHQXF+fBhkoQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} @@ -2072,6 +2752,9 @@ packages: unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + utf-8-validate@5.0.10: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} @@ -2180,6 +2863,10 @@ packages: engines: {node: '>=8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + workerd@1.20260424.1: resolution: {integrity: sha512-oKsB0Xo/mfkYMdSACoS06XZg09VUK4rXwHfF/1t3P++sMbwzf4UHQvMO57+zxpEB2nVrY/ZkW0bYFGq4GdAFSQ==} engines: {node: '>=16'} @@ -2243,6 +2930,10 @@ packages: utf-8-validate: optional: true + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} @@ -2491,6 +3182,68 @@ snapshots: '@esbuild/win32-x64@0.27.7': optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + '@iden3/bigarray@0.0.2': {} '@iden3/binfileutils@0.0.12': @@ -2603,6 +3356,13 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@lemmaoracle/agent@0.0.24-alpha.1': + dependencies: + '@lemmaoracle/sdk': 0.0.23 + '@lemmaoracle/spec': 0.0.23 + poseidon-lite: 0.3.0 + ramda: 0.30.1 + '@lemmaoracle/sdk@0.0.21': dependencies: '@docknetwork/crypto-wasm': 0.35.0 @@ -2614,8 +3374,23 @@ snapshots: ramda: 0.30.1 snarkjs: 0.7.6 + '@lemmaoracle/sdk@0.0.23': + dependencies: + '@docknetwork/crypto-wasm': 0.35.0 + '@lemmaoracle/spec': 0.0.23 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + poseidon-lite: 0.2.1 + ramda: 0.30.1 + snarkjs: 0.7.6 + '@lemmaoracle/spec@0.0.21': {} + '@lemmaoracle/spec@0.0.22': {} + + '@lemmaoracle/spec@0.0.23': {} + '@lemmaoracle/x402@0.1.6(@lemmaoracle/sdk@0.0.21)(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: '@lemmaoracle/sdk': 0.0.21 @@ -3226,6 +4001,8 @@ snapshots: '@types/estree@1.0.9': {} + '@types/json-schema@7.0.15': {} + '@types/node@22.19.17': dependencies: undici-types: 6.21.0 @@ -3235,6 +4012,101 @@ snapshots: undici-types: 6.19.8 optional: true + '@types/ramda@0.30.2': + dependencies: + types-ramda: 0.30.1 + + '@typescript-eslint/eslint-plugin@8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.2 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.59.2(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.2 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.59.2(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.59.2': + dependencies: + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 + + '@typescript-eslint/tsconfig-utils@8.59.2(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.59.2(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.59.2': {} + + '@typescript-eslint/typescript-estree@8.59.2(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.2(typescript@5.9.3) + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/visitor-keys': 8.59.2 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.59.2(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.59.2 + '@typescript-eslint/types': 8.59.2 + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.59.2': + dependencies: + '@typescript-eslint/types': 8.59.2 + eslint-visitor-keys: 5.0.1 + '@vitest/expect@3.2.4': dependencies: '@types/chai': 5.2.3 @@ -3405,9 +4277,22 @@ snapshots: typescript: 5.9.3 zod: 4.3.6 + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + aes-js@4.0.0-beta.5: optional: true + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 @@ -3417,8 +4302,14 @@ snapshots: ansi-regex@6.2.2: {} + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + apg-js@4.4.0: {} + argparse@2.0.1: {} + assertion-error@2.0.1: {} async@3.2.6: {} @@ -3444,6 +4335,8 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + bfj@7.1.0: dependencies: bluebird: 3.7.2 @@ -3456,10 +4349,19 @@ snapshots: bluebird@3.7.2: {} + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + brace-expansion@2.1.0: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + browser-process-hrtime@1.0.0: {} buffer-es6@4.9.3: {} @@ -3488,6 +4390,8 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 + callsites@3.1.0: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -3496,6 +4400,11 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@5.6.2: {} charenc@0.0.2: {} @@ -3522,12 +4431,22 @@ snapshots: cli-spinners@3.4.0: {} + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 + commander@13.1.0: {} + commander@14.0.2: {} + concat-map@0.0.1: {} + cookie@1.1.1: {} cross-spawn@7.0.6: @@ -3544,6 +4463,10 @@ snapshots: deep-eql@5.0.2: {} + deep-is@0.1.4: {} + + deepmerge-ts@7.1.5: {} + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -3656,6 +4579,10 @@ snapshots: '@esbuild/win32-ia32': 0.27.7 '@esbuild/win32-x64': 0.27.7 + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -3664,10 +4591,92 @@ snapshots: optionalDependencies: source-map: 0.6.1 + eslint-config-prettier@10.1.8(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-functional@7.3.1(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + deepmerge-ts: 7.1.5 + escape-string-regexp: 5.0.0 + eslint: 9.39.4 + is-immutable-type: 5.0.1(eslint@9.39.4)(typescript@5.9.3) + ts-api-utils: 2.5.0(typescript@5.9.3) + ts-declaration-location: 1.0.7(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + esprima@1.2.5: {} esprima@4.0.1: {} + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + estraverse@5.3.0: {} estree-walker@3.0.3: @@ -3696,6 +4705,10 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + fast-uri@3.1.0: {} fastfile@0.0.20: {} @@ -3716,10 +4729,26 @@ snapshots: wasmcurves: 0.2.2 web-worker: 1.2.0 + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + filelist@1.0.6: dependencies: minimatch: 5.1.9 + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + follow-redirects@1.16.0: {} for-each@0.3.5: @@ -3763,8 +4792,16 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + gopd@1.2.0: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 @@ -3783,10 +4820,37 @@ snapshots: hoopy@0.1.4: {} + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + is-buffer@1.1.6: {} is-callable@1.2.7: {} + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-immutable-type@5.0.1(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/type-utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + ts-declaration-location: 1.0.7(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + is-interactive@2.0.0: {} is-retry-allowed@2.2.0: {} @@ -3815,16 +4879,41 @@ snapshots: js-tokens@9.0.1: {} + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + json-schema-traverse@1.0.0: {} + json-stable-stringify-without-jsonify@1.0.1: {} + jsonpath@1.3.0: dependencies: esprima: 1.2.5 static-eval: 2.1.1 underscore: 1.13.6 + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + kleur@4.1.5: {} + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + log-symbols@7.0.1: dependencies: is-unicode-supported: 2.1.0 @@ -3866,6 +4955,14 @@ snapshots: - bufferutil - utf-8-validate + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + minimatch@5.1.9: dependencies: brace-expansion: 2.1.0 @@ -3876,6 +4973,8 @@ snapshots: nanoid@3.3.12: {} + natural-compare@1.4.0: {} + node-gyp-build@4.8.4: optional: true @@ -3883,6 +4982,15 @@ snapshots: dependencies: mimic-function: 5.0.1 + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + ora@9.4.0: dependencies: chalk: 5.6.2 @@ -3924,8 +5032,22 @@ snapshots: transitivePeerDependencies: - zod + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + path-browserify@1.0.1: {} + path-exists@4.0.0: {} + path-key@3.1.1: {} path-to-regexp@6.3.0: {} @@ -3950,8 +5072,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prelude-ls@1.2.1: {} + proxy-from-env@1.1.0: {} + punycode@2.3.1: {} + r1csfile@0.0.48: dependencies: '@iden3/bigarray': 0.0.2 @@ -3972,6 +5098,8 @@ snapshots: require-from-string@2.0.2: {} + resolve-from@4.0.0: {} + resolve-pkg-maps@1.0.0: {} restore-cursor@5.1.0: @@ -4100,12 +5228,18 @@ snapshots: dependencies: ansi-regex: 6.2.2 + strip-json-comments@3.1.1: {} + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 supports-color@10.2.2: {} + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + tinybench@2.9.0: {} tinyexec@0.3.2: {} @@ -4123,6 +5257,17 @@ snapshots: tryer@1.0.1: {} + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-declaration-location@1.0.7(typescript@5.9.3): + dependencies: + picomatch: 4.0.4 + typescript: 5.9.3 + + ts-toolbelt@9.6.0: {} + tslib@2.7.0: optional: true @@ -4138,6 +5283,25 @@ snapshots: tweetnacl@1.0.3: {} + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + types-ramda@0.30.1: + dependencies: + ts-toolbelt: 9.6.0 + + typescript-eslint@8.59.2(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.59.2(@typescript-eslint/parser@8.59.2(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.59.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.2(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + typescript@5.9.3: {} uncrypto@0.1.3: {} @@ -4157,6 +5321,10 @@ snapshots: dependencies: pathe: 2.0.3 + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + utf-8-validate@5.0.10: dependencies: node-gyp-build: 4.8.4 @@ -4298,6 +5466,8 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 + word-wrap@1.2.5: {} + workerd@1.20260424.1: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20260424.1 @@ -4344,6 +5514,8 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 5.0.10 + yocto-queue@0.1.0: {} + yoctocolors@2.1.2: {} youch-core@0.3.3: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index dee51e9..f822adc 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,2 +1,3 @@ packages: - "packages/*" + - "vendors/trust402/packages/*" diff --git a/vendors/trust402 b/vendors/trust402 new file mode 160000 index 0000000..a4e0797 --- /dev/null +++ b/vendors/trust402 @@ -0,0 +1 @@ +Subproject commit a4e07973e18702273c84f91ff7de0c9a591cebfe