@wlfi-agent/cli 1.4.17 → 1.4.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +5 -0
- package/README.md +61 -28
- package/crates/vault-cli-admin/src/io_utils.rs +149 -1
- package/crates/vault-cli-admin/src/main.rs +639 -16
- package/crates/vault-cli-admin/src/shared_config.rs +18 -18
- package/crates/vault-cli-admin/src/tui/token_rpc.rs +190 -3
- package/crates/vault-cli-admin/src/tui/utils.rs +59 -0
- package/crates/vault-cli-admin/src/tui.rs +1205 -120
- package/crates/vault-cli-agent/Cargo.toml +1 -0
- package/crates/vault-cli-agent/src/io_utils.rs +163 -2
- package/crates/vault-cli-agent/src/main.rs +648 -32
- package/crates/vault-cli-daemon/Cargo.toml +4 -0
- package/crates/vault-cli-daemon/src/main.rs +617 -67
- package/crates/vault-cli-daemon/src/relay_sync.rs +776 -4
- package/crates/vault-cli-daemon/tests/system_keychain_helper_acl.rs +5 -0
- package/crates/vault-daemon/src/daemon_parts/api_impl_and_utils.rs +32 -1
- package/crates/vault-daemon/src/persistence.rs +637 -100
- package/crates/vault-daemon/src/tests.rs +1013 -3
- package/crates/vault-daemon/src/tests_parts/part2.rs +99 -0
- package/crates/vault-daemon/src/tests_parts/part4.rs +11 -7
- package/crates/vault-domain/src/nonce.rs +4 -0
- package/crates/vault-domain/src/tests.rs +616 -0
- package/crates/vault-policy/src/engine.rs +55 -32
- package/crates/vault-policy/src/tests.rs +195 -0
- package/crates/vault-sdk-agent/src/lib.rs +415 -22
- package/crates/vault-signer/Cargo.toml +3 -0
- package/crates/vault-signer/src/lib.rs +266 -40
- package/crates/vault-transport-unix/src/lib.rs +653 -5
- package/crates/vault-transport-xpc/src/tests.rs +531 -3
- package/crates/vault-transport-xpc/tests/e2e_flow.rs +3 -0
- package/dist/cli.cjs +663 -190
- package/dist/cli.cjs.map +1 -1
- package/package.json +5 -2
- package/packages/cache/.turbo/turbo-build.log +20 -20
- package/packages/cache/coverage/clover.xml +529 -394
- package/packages/cache/coverage/coverage-final.json +2 -2
- package/packages/cache/coverage/index.html +21 -21
- package/packages/cache/coverage/src/client/index.html +1 -1
- package/packages/cache/coverage/src/client/index.ts.html +1 -1
- package/packages/cache/coverage/src/errors/index.html +1 -1
- package/packages/cache/coverage/src/errors/index.ts.html +12 -12
- package/packages/cache/coverage/src/index.html +1 -1
- package/packages/cache/coverage/src/index.ts.html +1 -1
- package/packages/cache/coverage/src/service/index.html +21 -21
- package/packages/cache/coverage/src/service/index.ts.html +769 -313
- package/packages/cache/dist/{chunk-QNK6GOTI.js → chunk-KC53LH5Z.js} +35 -2
- package/packages/cache/dist/chunk-KC53LH5Z.js.map +1 -0
- package/packages/cache/dist/{chunk-QF4XKEIA.cjs → chunk-UVU7VFE3.cjs} +35 -2
- package/packages/cache/dist/chunk-UVU7VFE3.cjs.map +1 -0
- package/packages/cache/dist/index.cjs +2 -2
- package/packages/cache/dist/index.js +1 -1
- package/packages/cache/dist/service/index.cjs +2 -2
- package/packages/cache/dist/service/index.js +1 -1
- package/packages/cache/node_modules/.bin/tsc +2 -2
- package/packages/cache/node_modules/.bin/tsserver +2 -2
- package/packages/cache/node_modules/.bin/tsup +2 -2
- package/packages/cache/node_modules/.bin/tsup-node +2 -2
- package/packages/cache/node_modules/.bin/vitest +4 -4
- package/packages/cache/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -1
- package/packages/cache/src/service/index.test.ts +165 -19
- package/packages/cache/src/service/index.ts +38 -1
- package/packages/config/.turbo/turbo-build.log +4 -4
- package/packages/config/dist/index.cjs +0 -17
- package/packages/config/dist/index.cjs.map +1 -1
- package/packages/config/src/index.ts +0 -17
- package/packages/rpc/.turbo/turbo-build.log +11 -11
- package/packages/rpc/dist/index.cjs +0 -17
- package/packages/rpc/dist/index.cjs.map +1 -1
- package/packages/rpc/src/index.js +1 -0
- package/packages/ui/node_modules/.bin/tsc +2 -2
- package/packages/ui/node_modules/.bin/tsserver +2 -2
- package/packages/ui/node_modules/.bin/tsup +2 -2
- package/packages/ui/node_modules/.bin/tsup-node +2 -2
- package/scripts/install-cli-launcher.mjs +37 -0
- package/scripts/install-rust-binaries.mjs +47 -0
- package/scripts/run-tests-isolated.mjs +210 -0
- package/src/cli.ts +310 -50
- package/src/lib/admin-reset.ts +15 -30
- package/src/lib/admin-setup.ts +246 -55
- package/src/lib/agent-auth-migrate.ts +5 -1
- package/src/lib/asset-broadcast.ts +15 -4
- package/src/lib/config-amounts.ts +6 -4
- package/src/lib/hidden-tty-prompt.js +1 -0
- package/src/lib/hidden-tty-prompt.ts +105 -0
- package/src/lib/keychain.ts +1 -0
- package/src/lib/local-admin-access.ts +4 -29
- package/src/lib/rust.ts +129 -33
- package/src/lib/signed-tx.ts +1 -0
- package/src/lib/sudo.ts +15 -5
- package/src/lib/wallet-profile.ts +3 -0
- package/src/lib/wallet-setup.ts +52 -0
- package/packages/cache/dist/chunk-QF4XKEIA.cjs.map +0 -1
- package/packages/cache/dist/chunk-QNK6GOTI.js.map +0 -1
|
@@ -101,6 +101,9 @@ var RelayCacheService = class {
|
|
|
101
101
|
await this.writeJson(this.daemonAgentKeysKey(profile.daemonId), agentKeys);
|
|
102
102
|
}
|
|
103
103
|
if (input.approvalRequests) {
|
|
104
|
+
const approvalIndexKey = this.daemonApprovalsKey(profile.daemonId);
|
|
105
|
+
const existingApprovalIds = new Set(await this.client.zrange(approvalIndexKey, 0, -1));
|
|
106
|
+
const nextApprovalIds = /* @__PURE__ */ new Set();
|
|
104
107
|
for (const approvalRequest of input.approvalRequests) {
|
|
105
108
|
const existing = await this.readJson(
|
|
106
109
|
this.approvalKey(approvalRequest.approvalRequestId)
|
|
@@ -109,13 +112,25 @@ var RelayCacheService = class {
|
|
|
109
112
|
{ ...approvalRequest, daemonId: profile.daemonId },
|
|
110
113
|
existing
|
|
111
114
|
);
|
|
115
|
+
nextApprovalIds.add(normalized.approvalRequestId);
|
|
112
116
|
await this.writeJson(this.approvalKey(normalized.approvalRequestId), normalized);
|
|
113
117
|
await this.client.zadd(
|
|
114
|
-
|
|
118
|
+
approvalIndexKey,
|
|
115
119
|
Date.parse(normalized.requestedAt),
|
|
116
120
|
normalized.approvalRequestId
|
|
117
121
|
);
|
|
118
122
|
}
|
|
123
|
+
const staleApprovalIds = [...existingApprovalIds].filter(
|
|
124
|
+
(approvalRequestId) => !nextApprovalIds.has(approvalRequestId)
|
|
125
|
+
);
|
|
126
|
+
if (staleApprovalIds.length > 0) {
|
|
127
|
+
await this.client.zrem(approvalIndexKey, ...staleApprovalIds);
|
|
128
|
+
for (const approvalRequestId of staleApprovalIds) {
|
|
129
|
+
await this.client.del(this.approvalKey(approvalRequestId));
|
|
130
|
+
await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));
|
|
131
|
+
await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
119
134
|
}
|
|
120
135
|
return {
|
|
121
136
|
agentKeyCount: input.agentKeys?.length ?? 0,
|
|
@@ -438,6 +453,7 @@ var RelayCacheService = class {
|
|
|
438
453
|
async submitUpdateFeedback(input) {
|
|
439
454
|
const key = this.updateKey(input.updateId);
|
|
440
455
|
const record = await this.readJson(key);
|
|
456
|
+
const nowMs = Date.now();
|
|
441
457
|
if (!record || record.daemonId !== input.daemonId) {
|
|
442
458
|
throw new CacheError({
|
|
443
459
|
code: cacheErrorCodes.notFound,
|
|
@@ -446,6 +462,23 @@ var RelayCacheService = class {
|
|
|
446
462
|
operation: "submitUpdateFeedback"
|
|
447
463
|
});
|
|
448
464
|
}
|
|
465
|
+
if (record.status !== "inflight") {
|
|
466
|
+
throw new CacheError({
|
|
467
|
+
code: cacheErrorCodes.invalidPayload,
|
|
468
|
+
key,
|
|
469
|
+
message: `Update '${input.updateId}' is '${record.status}' and is not currently claimed`,
|
|
470
|
+
operation: "submitUpdateFeedback"
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
const claimUntilMs = record.claimUntil ? Date.parse(record.claimUntil) : Number.NaN;
|
|
474
|
+
if (!Number.isFinite(claimUntilMs) || claimUntilMs <= nowMs) {
|
|
475
|
+
throw new CacheError({
|
|
476
|
+
code: cacheErrorCodes.invalidPayload,
|
|
477
|
+
key,
|
|
478
|
+
message: `Claim for update '${input.updateId}' has expired`,
|
|
479
|
+
operation: "submitUpdateFeedback"
|
|
480
|
+
});
|
|
481
|
+
}
|
|
449
482
|
if (!record.claimToken || record.claimToken !== input.claimToken) {
|
|
450
483
|
throw new CacheError({
|
|
451
484
|
code: cacheErrorCodes.invalidPayload,
|
|
@@ -545,4 +578,4 @@ export {
|
|
|
545
578
|
RelayCacheService,
|
|
546
579
|
createRelayCacheService
|
|
547
580
|
};
|
|
548
|
-
//# sourceMappingURL=chunk-
|
|
581
|
+
//# sourceMappingURL=chunk-KC53LH5Z.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/service/index.ts"],"sourcesContent":["import { createHash, randomBytes, randomUUID } from 'node:crypto';\nimport type Redis from 'ioredis';\nimport { getCacheClient } from '../client/index.js';\nimport { CacheError, cacheErrorCodes, toCacheError } from '../errors/index.js';\n\nexport const relayApprovalStatuses = [\n 'pending',\n 'approved',\n 'rejected',\n 'completed',\n 'expired',\n] as const;\nexport type RelayApprovalStatus = (typeof relayApprovalStatuses)[number];\n\nexport const relayUpdateStatuses = [\n 'pending',\n 'inflight',\n 'applied',\n 'rejected',\n 'failed',\n] as const;\nexport type RelayUpdateStatus = (typeof relayUpdateStatuses)[number];\n\nexport interface RelayDaemonProfile {\n daemonId: string;\n daemonPublicKey: string;\n ethereumAddress: string;\n label?: string;\n lastSeenAt: string;\n registeredAt: string;\n relayUrl?: string;\n signerBackend?: string;\n status: 'active' | 'paused';\n updatedAt: string;\n version?: string;\n}\n\nexport interface RelayPolicyRecord {\n action: string;\n amountMaxWei?: string;\n amountMinWei?: string;\n chainId?: number;\n daemonId: string;\n destination: string;\n metadata?: Record<string, string>;\n policyId: string;\n requiresManualApproval: boolean;\n scope: 'default' | 'override';\n tokenAddress?: string;\n updatedAt: string;\n}\n\nexport interface RelayAgentKeyRecord {\n agentKeyId: string;\n createdAt?: string;\n daemonId: string;\n label?: string;\n metadata?: Record<string, string>;\n status: 'active' | 'revoked';\n updatedAt: string;\n}\n\nexport interface RelayApprovalRequestRecord {\n agentKeyId?: string;\n amountWei?: string;\n approvalRequestId: string;\n chainId?: number;\n daemonId: string;\n destination: string;\n metadata?: Record<string, string>;\n network?: string;\n reason?: string;\n requestedAt: string;\n status: RelayApprovalStatus;\n tokenAddress?: string;\n transactionType: string;\n updatedAt: string;\n}\n\nexport interface RelayEncryptedPayload {\n aadBase64?: string;\n algorithm: string;\n ciphertextBase64: string;\n contentSha256Hex?: string;\n encapsulatedKeyBase64: string;\n nonceBase64: string;\n schemaVersion: number;\n}\n\nexport interface RelayUpdateFeedbackRecord {\n daemonId: string;\n details?: Record<string, string>;\n feedbackAt: string;\n message?: string;\n status: Extract<RelayUpdateStatus, 'applied' | 'failed' | 'rejected'>;\n updateId: string;\n}\n\nexport interface RelayEncryptedUpdateRecord {\n claimToken?: string;\n claimUntil?: string;\n createdAt: string;\n daemonId: string;\n feedback?: RelayUpdateFeedbackRecord;\n lastDeliveredAt?: string;\n metadata?: Record<string, string>;\n payload: RelayEncryptedPayload;\n status: RelayUpdateStatus;\n targetApprovalRequestId?: string;\n type: string;\n updateId: string;\n updatedAt: string;\n}\n\nexport interface SyncDaemonRegistrationInput {\n agentKeys?: RelayAgentKeyRecord[];\n approvalRequests?: RelayApprovalRequestRecord[];\n daemon: RelayDaemonProfile;\n policies?: RelayPolicyRecord[];\n}\n\nexport interface ApprovalRequestFilters {\n daemonId?: string;\n destination?: string;\n limit?: number;\n status?: RelayApprovalStatus;\n tokenAddress?: string;\n}\n\nexport interface CreateEncryptedUpdateInput {\n daemonId: string;\n metadata?: Record<string, string>;\n payload: RelayEncryptedPayload;\n targetApprovalRequestId?: string;\n type: string;\n updateId?: string;\n}\n\nexport interface ClaimEncryptedUpdatesInput {\n daemonId: string;\n leaseSeconds?: number;\n limit?: number;\n}\n\nexport interface SubmitUpdateFeedbackInput {\n claimToken: string;\n daemonId: string;\n details?: Record<string, string>;\n message?: string;\n status: Extract<RelayUpdateStatus, 'applied' | 'failed' | 'rejected'>;\n updateId: string;\n}\n\nexport interface ApprovalCapabilityFailureRecord {\n attempts: number;\n blockedUntil?: string;\n firstFailedAt: string;\n lastFailedAt: string;\n}\n\nexport interface RecordApprovalCapabilityFailureResult {\n attempts: number;\n blocked: boolean;\n blockedUntil: string | null;\n}\n\ninterface JsonCache {\n del(key: string): Promise<number>;\n get(key: string): Promise<string | null>;\n ping(): Promise<string>;\n quit(): Promise<string>;\n sadd(key: string, ...members: string[]): Promise<number>;\n set(key: string, value: string, mode?: 'NX' | 'XX'): Promise<'OK' | null>;\n smembers(key: string): Promise<string[]>;\n zadd(key: string, ...args: (string | number)[]): Promise<number>;\n zrange(key: string, start: number, stop: number, ...args: string[]): Promise<string[]>;\n zrem(key: string, ...members: string[]): Promise<number>;\n}\n\nconst defaultNamespace = 'wlfi:relay';\nconst approvalCapabilityFailureWindowMs = 5 * 60 * 1000;\nconst approvalCapabilityMaxFailures = 5;\nconst approvalCapabilityBlockWindowMs = 10 * 60 * 1000;\n\nconst toIsoTimestamp = (value = new Date()): string => value.toISOString();\n\nconst dedupe = <T>(values: T[]): T[] => [...new Set(values)];\n\nconst matchesOptionalFilter = (\n value: string | undefined,\n expected: string | undefined,\n): boolean => {\n if (!expected) {\n return true;\n }\n\n return value?.toLowerCase() === expected.toLowerCase();\n};\n\nconst clampLimit = (limit: number | undefined, fallback: number, max: number): number => {\n if (!limit || Number.isNaN(limit)) {\n return fallback;\n }\n\n return Math.max(1, Math.min(limit, max));\n};\n\nconst createApprovalCapabilityToken = (): string => randomBytes(32).toString('hex');\n\nconst approvalCapabilityHash = (token: string): string =>\n createHash('sha256').update(token, 'utf8').digest('hex');\n\nconst isActiveApprovalUpdateRecord = (\n record: RelayEncryptedUpdateRecord | null | undefined,\n approvalRequestId: string,\n): record is RelayEncryptedUpdateRecord =>\n Boolean(\n record &&\n record.type === 'manual_approval_decision' &&\n record.targetApprovalRequestId === approvalRequestId &&\n (record.status === 'pending' || record.status === 'inflight'),\n );\n\nconst preserveRotatedApprovalCapability = (\n incoming: RelayApprovalRequestRecord,\n existing: RelayApprovalRequestRecord | null,\n): RelayApprovalRequestRecord => {\n const existingMetadata = existing?.metadata;\n const incomingMetadata = incoming.metadata;\n const preservedCapabilityToken = existingMetadata?.approvalCapabilityToken?.trim();\n const preservedCapabilityHash = existingMetadata?.approvalCapabilityHash?.trim();\n\n if (!preservedCapabilityToken && !preservedCapabilityHash) {\n return incoming;\n }\n\n return {\n ...incoming,\n metadata: {\n ...(incomingMetadata ?? {}),\n ...(preservedCapabilityToken\n ? { approvalCapabilityToken: preservedCapabilityToken }\n : {}),\n ...(preservedCapabilityHash ? { approvalCapabilityHash: preservedCapabilityHash } : {}),\n },\n };\n};\n\nexport class RelayCacheService {\n private readonly client: JsonCache;\n private readonly namespace: string;\n\n constructor(options: { client?: Redis; namespace?: string } = {}) {\n this.client = (options.client ?? getCacheClient()) as unknown as JsonCache;\n this.namespace = options.namespace ?? defaultNamespace;\n }\n\n async ping(): Promise<string> {\n try {\n return await this.client.ping();\n } catch (error) {\n throw toCacheError(error, { operation: 'ping' });\n }\n }\n\n async syncDaemonRegistration(input: SyncDaemonRegistrationInput): Promise<{\n agentKeyCount: number;\n approvalRequestCount: number;\n policyCount: number;\n }> {\n const profile = {\n ...input.daemon,\n lastSeenAt: input.daemon.lastSeenAt || toIsoTimestamp(),\n updatedAt: input.daemon.updatedAt || toIsoTimestamp(),\n } satisfies RelayDaemonProfile;\n\n try {\n await this.writeJson(this.daemonProfileKey(profile.daemonId), profile);\n await this.client.sadd(this.daemonIndexKey(), profile.daemonId);\n\n if (input.policies) {\n const policies = input.policies.map((policy) => ({\n ...policy,\n daemonId: profile.daemonId,\n }));\n await this.writeJson(this.daemonPoliciesKey(profile.daemonId), policies);\n }\n\n if (input.agentKeys) {\n const agentKeys = input.agentKeys.map((agentKey) => ({\n ...agentKey,\n daemonId: profile.daemonId,\n }));\n await this.writeJson(this.daemonAgentKeysKey(profile.daemonId), agentKeys);\n }\n\n if (input.approvalRequests) {\n const approvalIndexKey = this.daemonApprovalsKey(profile.daemonId);\n const existingApprovalIds = new Set(await this.client.zrange(approvalIndexKey, 0, -1));\n const nextApprovalIds = new Set<string>();\n\n for (const approvalRequest of input.approvalRequests) {\n const existing = await this.readJson<RelayApprovalRequestRecord>(\n this.approvalKey(approvalRequest.approvalRequestId),\n );\n const normalized = preserveRotatedApprovalCapability(\n { ...approvalRequest, daemonId: profile.daemonId },\n existing,\n );\n nextApprovalIds.add(normalized.approvalRequestId);\n await this.writeJson(this.approvalKey(normalized.approvalRequestId), normalized);\n await this.client.zadd(\n approvalIndexKey,\n Date.parse(normalized.requestedAt),\n normalized.approvalRequestId,\n );\n }\n\n const staleApprovalIds = [...existingApprovalIds].filter(\n (approvalRequestId) => !nextApprovalIds.has(approvalRequestId),\n );\n if (staleApprovalIds.length > 0) {\n await this.client.zrem(approvalIndexKey, ...staleApprovalIds);\n for (const approvalRequestId of staleApprovalIds) {\n await this.client.del(this.approvalKey(approvalRequestId));\n await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));\n await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));\n }\n }\n }\n\n return {\n agentKeyCount: input.agentKeys?.length ?? 0,\n approvalRequestCount: input.approvalRequests?.length ?? 0,\n policyCount: input.policies?.length ?? 0,\n };\n } catch (error) {\n throw toCacheError(error, {\n key: this.daemonProfileKey(profile.daemonId),\n operation: 'syncDaemonRegistration',\n });\n }\n }\n\n async listDaemons(): Promise<RelayDaemonProfile[]> {\n const daemonIds = await this.client.smembers(this.daemonIndexKey());\n const profiles = await Promise.all(\n daemonIds.map((daemonId) =>\n this.readJson<RelayDaemonProfile>(this.daemonProfileKey(daemonId)),\n ),\n );\n\n return profiles.filter((profile): profile is RelayDaemonProfile => Boolean(profile));\n }\n\n async getDaemonProfile(daemonId: string): Promise<RelayDaemonProfile | null> {\n return await this.readJson<RelayDaemonProfile>(this.daemonProfileKey(daemonId));\n }\n\n async getDaemonPolicies(daemonId: string): Promise<RelayPolicyRecord[]> {\n return (await this.readJson<RelayPolicyRecord[]>(this.daemonPoliciesKey(daemonId))) ?? [];\n }\n\n async getDaemonAgentKeys(daemonId: string): Promise<RelayAgentKeyRecord[]> {\n return (await this.readJson<RelayAgentKeyRecord[]>(this.daemonAgentKeysKey(daemonId))) ?? [];\n }\n\n async getApprovalRequest(approvalRequestId: string): Promise<RelayApprovalRequestRecord | null> {\n return await this.readJson<RelayApprovalRequestRecord>(this.approvalKey(approvalRequestId));\n }\n\n async listApprovalRequests(\n filters: ApprovalRequestFilters = {},\n ): Promise<RelayApprovalRequestRecord[]> {\n const limit = clampLimit(filters.limit, 100, 500);\n const daemonIds = filters.daemonId\n ? [filters.daemonId]\n : await this.client.smembers(this.daemonIndexKey());\n const requestIdsByDaemon = await Promise.all(\n daemonIds.map((daemonId) =>\n this.client.zrange(this.daemonApprovalsKey(daemonId), 0, limit * 2, 'REV'),\n ),\n );\n const requestIds = dedupe(requestIdsByDaemon.flat()).slice(0, limit * 3);\n const requests = await Promise.all(\n requestIds.map((requestId) =>\n this.readJson<RelayApprovalRequestRecord>(this.approvalKey(requestId)),\n ),\n );\n\n return requests\n .filter((request): request is RelayApprovalRequestRecord => Boolean(request))\n .filter((request) => (filters.daemonId ? request.daemonId === filters.daemonId : true))\n .filter((request) => (filters.status ? request.status === filters.status : true))\n .filter((request) => matchesOptionalFilter(request.destination, filters.destination))\n .filter((request) => matchesOptionalFilter(request.tokenAddress, filters.tokenAddress))\n .sort((left, right) => Date.parse(right.requestedAt) - Date.parse(left.requestedAt))\n .slice(0, limit);\n }\n\n async createEncryptedUpdate(\n input: CreateEncryptedUpdateInput,\n ): Promise<RelayEncryptedUpdateRecord> {\n if (input.type === 'manual_approval_decision') {\n if (!input.targetApprovalRequestId) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n message: 'Manual approval updates require a target approval request id',\n operation: 'createEncryptedUpdate',\n });\n }\n\n const approvalKey = this.approvalKey(input.targetApprovalRequestId);\n const approval = await this.readJson<RelayApprovalRequestRecord>(approvalKey);\n if (!approval) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key: approvalKey,\n message: `Unknown approval '${input.targetApprovalRequestId}'`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n if (approval.daemonId !== input.daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: approvalKey,\n message: `Approval '${input.targetApprovalRequestId}' belongs to daemon '${approval.daemonId}', not '${input.daemonId}'`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n if (approval.status !== 'pending') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: approvalKey,\n message: `Approval '${input.targetApprovalRequestId}' is '${approval.status}' and cannot accept new updates`,\n operation: 'createEncryptedUpdate',\n });\n }\n }\n\n const updateId = input.updateId ?? randomUUID();\n const now = toIsoTimestamp();\n const record: RelayEncryptedUpdateRecord = {\n createdAt: now,\n daemonId: input.daemonId,\n metadata: input.metadata,\n payload: input.payload,\n status: 'pending',\n targetApprovalRequestId: input.targetApprovalRequestId,\n type: input.type,\n updateId,\n updatedAt: now,\n };\n\n const activeApprovalKey =\n input.type === 'manual_approval_decision' && input.targetApprovalRequestId\n ? this.activeApprovalUpdateKey(input.targetApprovalRequestId)\n : null;\n const updateKey = this.updateKey(updateId);\n let ownsActiveApprovalSlot = false;\n\n await this.writeJson(updateKey, record);\n\n try {\n if (activeApprovalKey) {\n const reserved = await this.client.set(activeApprovalKey, updateId, 'NX');\n if (reserved !== 'OK') {\n const existingUpdateId = await this.client.get(activeApprovalKey);\n const existingRecord = existingUpdateId\n ? await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(existingUpdateId))\n : null;\n\n if (isActiveApprovalUpdateRecord(existingRecord, input.targetApprovalRequestId!)) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: activeApprovalKey,\n message: `Approval '${input.targetApprovalRequestId}' already has a queued operator update`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n await this.client.del(activeApprovalKey);\n const retriedReservation = await this.client.set(activeApprovalKey, updateId, 'NX');\n if (retriedReservation !== 'OK') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: activeApprovalKey,\n message: `Approval '${input.targetApprovalRequestId}' already has a queued operator update`,\n operation: 'createEncryptedUpdate',\n });\n }\n }\n\n ownsActiveApprovalSlot = true;\n }\n\n await this.client.zadd(this.daemonUpdatesKey(input.daemonId), Date.now(), updateId);\n } catch (error) {\n await this.client.del(updateKey);\n if (activeApprovalKey && ownsActiveApprovalSlot) {\n await this.client.del(activeApprovalKey);\n }\n throw error;\n }\n\n return record;\n }\n\n async hasActiveApprovalUpdate(daemonId: string, approvalRequestId: string): Promise<boolean> {\n const indexedUpdateId = await this.client.get(this.activeApprovalUpdateKey(approvalRequestId));\n if (indexedUpdateId) {\n const indexedRecord = await this.readJson<RelayEncryptedUpdateRecord>(\n this.updateKey(indexedUpdateId),\n );\n if (isActiveApprovalUpdateRecord(indexedRecord, approvalRequestId)) {\n return true;\n }\n\n await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));\n }\n\n const updateIds = await this.client.zrange(this.daemonUpdatesKey(daemonId), 0, -1, 'REV');\n\n for (const updateId of updateIds) {\n const record = await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n if (isActiveApprovalUpdateRecord(record, approvalRequestId)) {\n await this.client.set(this.activeApprovalUpdateKey(approvalRequestId), updateId, 'NX');\n return true;\n }\n }\n\n return false;\n }\n\n async consumeApprovalCapability(\n approvalRequestId: string,\n capabilityHash: string,\n ): Promise<boolean> {\n try {\n const result = await this.client.set(\n this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n toIsoTimestamp(),\n 'NX',\n );\n return result === 'OK';\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n operation: 'consumeApprovalCapability',\n });\n }\n }\n\n async releaseApprovalCapabilityConsumption(\n approvalRequestId: string,\n capabilityHash: string,\n ): Promise<void> {\n try {\n await this.client.del(this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash));\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n operation: 'releaseApprovalCapabilityConsumption',\n });\n }\n }\n\n async clearApprovalCapabilityFailures(approvalRequestId: string): Promise<void> {\n try {\n await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityFailuresKey(approvalRequestId),\n operation: 'clearApprovalCapabilityFailures',\n });\n }\n }\n\n async recordApprovalCapabilityFailure(\n approvalRequestId: string,\n ): Promise<RecordApprovalCapabilityFailureResult> {\n const key = this.approvalCapabilityFailuresKey(approvalRequestId);\n const now = new Date();\n const nowMs = now.getTime();\n const existing = await this.readJson<ApprovalCapabilityFailureRecord>(key);\n\n if (existing?.blockedUntil && Date.parse(existing.blockedUntil) > nowMs) {\n return {\n attempts: existing.attempts,\n blocked: true,\n blockedUntil: existing.blockedUntil,\n };\n }\n\n const firstFailedAtMs = existing?.firstFailedAt\n ? Date.parse(existing.firstFailedAt)\n : Number.NaN;\n const withinWindow =\n Number.isFinite(firstFailedAtMs) &&\n nowMs - firstFailedAtMs <= approvalCapabilityFailureWindowMs;\n const attempts = withinWindow && existing ? existing.attempts + 1 : 1;\n const firstFailedAt = withinWindow && existing ? existing.firstFailedAt : now.toISOString();\n const blockedUntil =\n attempts >= approvalCapabilityMaxFailures\n ? new Date(nowMs + approvalCapabilityBlockWindowMs).toISOString()\n : undefined;\n\n await this.writeJson(key, {\n attempts,\n blockedUntil,\n firstFailedAt,\n lastFailedAt: now.toISOString(),\n } satisfies ApprovalCapabilityFailureRecord);\n\n return {\n attempts,\n blocked: blockedUntil !== undefined,\n blockedUntil: blockedUntil ?? null,\n };\n }\n\n async rotateApprovalCapability(approvalRequestId: string): Promise<RelayApprovalRequestRecord> {\n const key = this.approvalKey(approvalRequestId);\n const approval = await this.readJson<RelayApprovalRequestRecord>(key);\n\n if (!approval) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown approval '${approvalRequestId}'`,\n operation: 'rotateApprovalCapability',\n });\n }\n\n if (approval.status !== 'pending') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Approval '${approvalRequestId}' is '${approval.status}' and cannot accept a new secure approval link`,\n operation: 'rotateApprovalCapability',\n });\n }\n\n const capabilityToken = createApprovalCapabilityToken();\n const nextRecord: RelayApprovalRequestRecord = {\n ...approval,\n metadata: {\n ...(approval.metadata ?? {}),\n approvalCapabilityHash: approvalCapabilityHash(capabilityToken),\n approvalCapabilityToken: capabilityToken,\n },\n updatedAt: toIsoTimestamp(),\n };\n\n await this.writeJson(key, nextRecord);\n await this.clearApprovalCapabilityFailures(approvalRequestId);\n\n return nextRecord;\n }\n\n async claimEncryptedUpdates(\n input: ClaimEncryptedUpdatesInput,\n ): Promise<RelayEncryptedUpdateRecord[]> {\n const limit = clampLimit(input.limit, 25, 100);\n const leaseSeconds = clampLimit(input.leaseSeconds, 30, 300);\n const now = new Date();\n const nowMs = now.getTime();\n const claimUntil = new Date(nowMs + leaseSeconds * 1000).toISOString();\n const updateIds = await this.client.zrange(\n this.daemonUpdatesKey(input.daemonId),\n 0,\n limit * 4,\n 'REV',\n );\n const claimed: RelayEncryptedUpdateRecord[] = [];\n\n for (const updateId of updateIds) {\n if (claimed.length >= limit) {\n break;\n }\n\n const claimLockKey = this.updateClaimLockKey(updateId);\n let ownsClaimLock = false;\n\n try {\n const reserved = await this.client.set(claimLockKey, claimUntil, 'NX');\n if (reserved !== 'OK') {\n const existingClaimLockUntil = await this.client.get(claimLockKey);\n if (\n existingClaimLockUntil &&\n Number.isFinite(Date.parse(existingClaimLockUntil)) &&\n Date.parse(existingClaimLockUntil) > nowMs\n ) {\n continue;\n }\n\n await this.client.del(claimLockKey);\n const retriedReservation = await this.client.set(claimLockKey, claimUntil, 'NX');\n if (retriedReservation !== 'OK') {\n continue;\n }\n }\n\n ownsClaimLock = true;\n\n const record = await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n if (!record) {\n continue;\n }\n\n if (\n record.status === 'applied' ||\n record.status === 'failed' ||\n record.status === 'rejected'\n ) {\n continue;\n }\n\n if (\n record.status === 'inflight' &&\n record.claimUntil &&\n Date.parse(record.claimUntil) > nowMs\n ) {\n continue;\n }\n\n const nextRecord: RelayEncryptedUpdateRecord = {\n ...record,\n claimToken: randomUUID(),\n claimUntil,\n lastDeliveredAt: now.toISOString(),\n status: 'inflight',\n updatedAt: now.toISOString(),\n };\n await this.writeJson(this.updateKey(updateId), nextRecord);\n claimed.push(nextRecord);\n } finally {\n if (ownsClaimLock) {\n await this.client.del(claimLockKey);\n }\n }\n }\n\n return claimed;\n }\n\n async submitUpdateFeedback(\n input: SubmitUpdateFeedbackInput,\n ): Promise<RelayEncryptedUpdateRecord> {\n const key = this.updateKey(input.updateId);\n const record = await this.readJson<RelayEncryptedUpdateRecord>(key);\n const nowMs = Date.now();\n\n if (!record || record.daemonId !== input.daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown update '${input.updateId}' for daemon '${input.daemonId}'`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n if (record.status !== 'inflight') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Update '${input.updateId}' is '${record.status}' and is not currently claimed`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n const claimUntilMs = record.claimUntil ? Date.parse(record.claimUntil) : Number.NaN;\n if (!Number.isFinite(claimUntilMs) || claimUntilMs <= nowMs) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Claim for update '${input.updateId}' has expired`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n if (!record.claimToken || record.claimToken !== input.claimToken) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Claim token mismatch for update '${input.updateId}'`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n const feedback: RelayUpdateFeedbackRecord = {\n daemonId: input.daemonId,\n details: input.details,\n feedbackAt: toIsoTimestamp(),\n message: input.message,\n status: input.status,\n updateId: input.updateId,\n };\n const nextRecord: RelayEncryptedUpdateRecord = {\n ...record,\n claimToken: undefined,\n claimUntil: undefined,\n feedback,\n status: input.status,\n updatedAt: toIsoTimestamp(),\n };\n\n await this.writeJson(key, nextRecord);\n if (record.targetApprovalRequestId && record.type === 'manual_approval_decision') {\n const activeApprovalKey = this.activeApprovalUpdateKey(record.targetApprovalRequestId);\n const indexedUpdateId = await this.client.get(activeApprovalKey);\n if (indexedUpdateId === input.updateId) {\n await this.client.del(activeApprovalKey);\n }\n }\n return nextRecord;\n }\n\n async getEncryptedUpdate(updateId: string): Promise<RelayEncryptedUpdateRecord | null> {\n return await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n }\n\n async removeEncryptedUpdate(daemonId: string, updateId: string): Promise<void> {\n const key = this.updateKey(updateId);\n const record = await this.readJson<RelayEncryptedUpdateRecord>(key);\n if (!record || record.daemonId !== daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown update '${updateId}' for daemon '${daemonId}'`,\n operation: 'removeEncryptedUpdate',\n });\n }\n\n await this.client.zrem(this.daemonUpdatesKey(daemonId), updateId);\n await this.client.del(key);\n if (record.targetApprovalRequestId && record.type === 'manual_approval_decision') {\n const activeApprovalKey = this.activeApprovalUpdateKey(record.targetApprovalRequestId);\n const indexedUpdateId = await this.client.get(activeApprovalKey);\n if (indexedUpdateId === updateId) {\n await this.client.del(activeApprovalKey);\n }\n }\n }\n\n private readonly daemonIndexKey = (): string => `${this.namespace}:daemons`;\n private readonly daemonProfileKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:profile`;\n private readonly daemonPoliciesKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:policies`;\n private readonly daemonAgentKeysKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:agent-keys`;\n private readonly daemonApprovalsKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:approvals`;\n private readonly daemonUpdatesKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:updates`;\n private readonly approvalKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}`;\n private readonly approvalCapabilityConsumedKey = (\n approvalRequestId: string,\n capabilityHash: string,\n ): string =>\n `${this.namespace}:approval:${approvalRequestId}:capability:${capabilityHash}:consumed`;\n private readonly approvalCapabilityFailuresKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}:capability-failures`;\n private readonly activeApprovalUpdateKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}:active-update`;\n private readonly updateClaimLockKey = (updateId: string): string =>\n `${this.namespace}:update:${updateId}:claim-lock`;\n private readonly updateKey = (updateId: string): string => `${this.namespace}:update:${updateId}`;\n\n private async readJson<T>(key: string): Promise<T | null> {\n try {\n const payload = await this.client.get(key);\n if (payload === null) {\n return null;\n }\n\n return JSON.parse(payload) as T;\n } catch (error) {\n throw toCacheError(error, { key, operation: 'readJson' });\n }\n }\n\n private async writeJson(key: string, value: unknown): Promise<void> {\n try {\n await this.client.set(key, JSON.stringify(value));\n } catch (error) {\n throw toCacheError(error, { key, operation: 'writeJson' });\n }\n }\n}\n\nexport const createRelayCacheService = (options: { client?: Redis; namespace?: string } = {}) => {\n return new RelayCacheService(options);\n};\n"],"mappings":"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","names":[]}
|
|
@@ -101,6 +101,9 @@ var RelayCacheService = (_class = class {
|
|
|
101
101
|
await this.writeJson(this.daemonAgentKeysKey(profile.daemonId), agentKeys);
|
|
102
102
|
}
|
|
103
103
|
if (input.approvalRequests) {
|
|
104
|
+
const approvalIndexKey = this.daemonApprovalsKey(profile.daemonId);
|
|
105
|
+
const existingApprovalIds = new Set(await this.client.zrange(approvalIndexKey, 0, -1));
|
|
106
|
+
const nextApprovalIds = /* @__PURE__ */ new Set();
|
|
104
107
|
for (const approvalRequest of input.approvalRequests) {
|
|
105
108
|
const existing = await this.readJson(
|
|
106
109
|
this.approvalKey(approvalRequest.approvalRequestId)
|
|
@@ -109,13 +112,25 @@ var RelayCacheService = (_class = class {
|
|
|
109
112
|
{ ...approvalRequest, daemonId: profile.daemonId },
|
|
110
113
|
existing
|
|
111
114
|
);
|
|
115
|
+
nextApprovalIds.add(normalized.approvalRequestId);
|
|
112
116
|
await this.writeJson(this.approvalKey(normalized.approvalRequestId), normalized);
|
|
113
117
|
await this.client.zadd(
|
|
114
|
-
|
|
118
|
+
approvalIndexKey,
|
|
115
119
|
Date.parse(normalized.requestedAt),
|
|
116
120
|
normalized.approvalRequestId
|
|
117
121
|
);
|
|
118
122
|
}
|
|
123
|
+
const staleApprovalIds = [...existingApprovalIds].filter(
|
|
124
|
+
(approvalRequestId) => !nextApprovalIds.has(approvalRequestId)
|
|
125
|
+
);
|
|
126
|
+
if (staleApprovalIds.length > 0) {
|
|
127
|
+
await this.client.zrem(approvalIndexKey, ...staleApprovalIds);
|
|
128
|
+
for (const approvalRequestId of staleApprovalIds) {
|
|
129
|
+
await this.client.del(this.approvalKey(approvalRequestId));
|
|
130
|
+
await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));
|
|
131
|
+
await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
119
134
|
}
|
|
120
135
|
return {
|
|
121
136
|
agentKeyCount: _nullishCoalesce(_optionalChain([input, 'access', _10 => _10.agentKeys, 'optionalAccess', _11 => _11.length]), () => ( 0)),
|
|
@@ -438,6 +453,7 @@ var RelayCacheService = (_class = class {
|
|
|
438
453
|
async submitUpdateFeedback(input) {
|
|
439
454
|
const key = this.updateKey(input.updateId);
|
|
440
455
|
const record = await this.readJson(key);
|
|
456
|
+
const nowMs = Date.now();
|
|
441
457
|
if (!record || record.daemonId !== input.daemonId) {
|
|
442
458
|
throw new (0, _chunk2QFWMUXTcjs.CacheError)({
|
|
443
459
|
code: _chunk2QFWMUXTcjs.cacheErrorCodes.notFound,
|
|
@@ -446,6 +462,23 @@ var RelayCacheService = (_class = class {
|
|
|
446
462
|
operation: "submitUpdateFeedback"
|
|
447
463
|
});
|
|
448
464
|
}
|
|
465
|
+
if (record.status !== "inflight") {
|
|
466
|
+
throw new (0, _chunk2QFWMUXTcjs.CacheError)({
|
|
467
|
+
code: _chunk2QFWMUXTcjs.cacheErrorCodes.invalidPayload,
|
|
468
|
+
key,
|
|
469
|
+
message: `Update '${input.updateId}' is '${record.status}' and is not currently claimed`,
|
|
470
|
+
operation: "submitUpdateFeedback"
|
|
471
|
+
});
|
|
472
|
+
}
|
|
473
|
+
const claimUntilMs = record.claimUntil ? Date.parse(record.claimUntil) : Number.NaN;
|
|
474
|
+
if (!Number.isFinite(claimUntilMs) || claimUntilMs <= nowMs) {
|
|
475
|
+
throw new (0, _chunk2QFWMUXTcjs.CacheError)({
|
|
476
|
+
code: _chunk2QFWMUXTcjs.cacheErrorCodes.invalidPayload,
|
|
477
|
+
key,
|
|
478
|
+
message: `Claim for update '${input.updateId}' has expired`,
|
|
479
|
+
operation: "submitUpdateFeedback"
|
|
480
|
+
});
|
|
481
|
+
}
|
|
449
482
|
if (!record.claimToken || record.claimToken !== input.claimToken) {
|
|
450
483
|
throw new (0, _chunk2QFWMUXTcjs.CacheError)({
|
|
451
484
|
code: _chunk2QFWMUXTcjs.cacheErrorCodes.invalidPayload,
|
|
@@ -545,4 +578,4 @@ var createRelayCacheService = (options = {}) => {
|
|
|
545
578
|
|
|
546
579
|
|
|
547
580
|
exports.relayApprovalStatuses = relayApprovalStatuses; exports.relayUpdateStatuses = relayUpdateStatuses; exports.RelayCacheService = RelayCacheService; exports.createRelayCacheService = createRelayCacheService;
|
|
548
|
-
//# sourceMappingURL=chunk-
|
|
581
|
+
//# sourceMappingURL=chunk-UVU7VFE3.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/packages/cache/dist/chunk-UVU7VFE3.cjs","../src/service/index.ts"],"names":[],"mappings":"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","file":"/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/packages/cache/dist/chunk-UVU7VFE3.cjs","sourcesContent":[null,"import { createHash, randomBytes, randomUUID } from 'node:crypto';\nimport type Redis from 'ioredis';\nimport { getCacheClient } from '../client/index.js';\nimport { CacheError, cacheErrorCodes, toCacheError } from '../errors/index.js';\n\nexport const relayApprovalStatuses = [\n 'pending',\n 'approved',\n 'rejected',\n 'completed',\n 'expired',\n] as const;\nexport type RelayApprovalStatus = (typeof relayApprovalStatuses)[number];\n\nexport const relayUpdateStatuses = [\n 'pending',\n 'inflight',\n 'applied',\n 'rejected',\n 'failed',\n] as const;\nexport type RelayUpdateStatus = (typeof relayUpdateStatuses)[number];\n\nexport interface RelayDaemonProfile {\n daemonId: string;\n daemonPublicKey: string;\n ethereumAddress: string;\n label?: string;\n lastSeenAt: string;\n registeredAt: string;\n relayUrl?: string;\n signerBackend?: string;\n status: 'active' | 'paused';\n updatedAt: string;\n version?: string;\n}\n\nexport interface RelayPolicyRecord {\n action: string;\n amountMaxWei?: string;\n amountMinWei?: string;\n chainId?: number;\n daemonId: string;\n destination: string;\n metadata?: Record<string, string>;\n policyId: string;\n requiresManualApproval: boolean;\n scope: 'default' | 'override';\n tokenAddress?: string;\n updatedAt: string;\n}\n\nexport interface RelayAgentKeyRecord {\n agentKeyId: string;\n createdAt?: string;\n daemonId: string;\n label?: string;\n metadata?: Record<string, string>;\n status: 'active' | 'revoked';\n updatedAt: string;\n}\n\nexport interface RelayApprovalRequestRecord {\n agentKeyId?: string;\n amountWei?: string;\n approvalRequestId: string;\n chainId?: number;\n daemonId: string;\n destination: string;\n metadata?: Record<string, string>;\n network?: string;\n reason?: string;\n requestedAt: string;\n status: RelayApprovalStatus;\n tokenAddress?: string;\n transactionType: string;\n updatedAt: string;\n}\n\nexport interface RelayEncryptedPayload {\n aadBase64?: string;\n algorithm: string;\n ciphertextBase64: string;\n contentSha256Hex?: string;\n encapsulatedKeyBase64: string;\n nonceBase64: string;\n schemaVersion: number;\n}\n\nexport interface RelayUpdateFeedbackRecord {\n daemonId: string;\n details?: Record<string, string>;\n feedbackAt: string;\n message?: string;\n status: Extract<RelayUpdateStatus, 'applied' | 'failed' | 'rejected'>;\n updateId: string;\n}\n\nexport interface RelayEncryptedUpdateRecord {\n claimToken?: string;\n claimUntil?: string;\n createdAt: string;\n daemonId: string;\n feedback?: RelayUpdateFeedbackRecord;\n lastDeliveredAt?: string;\n metadata?: Record<string, string>;\n payload: RelayEncryptedPayload;\n status: RelayUpdateStatus;\n targetApprovalRequestId?: string;\n type: string;\n updateId: string;\n updatedAt: string;\n}\n\nexport interface SyncDaemonRegistrationInput {\n agentKeys?: RelayAgentKeyRecord[];\n approvalRequests?: RelayApprovalRequestRecord[];\n daemon: RelayDaemonProfile;\n policies?: RelayPolicyRecord[];\n}\n\nexport interface ApprovalRequestFilters {\n daemonId?: string;\n destination?: string;\n limit?: number;\n status?: RelayApprovalStatus;\n tokenAddress?: string;\n}\n\nexport interface CreateEncryptedUpdateInput {\n daemonId: string;\n metadata?: Record<string, string>;\n payload: RelayEncryptedPayload;\n targetApprovalRequestId?: string;\n type: string;\n updateId?: string;\n}\n\nexport interface ClaimEncryptedUpdatesInput {\n daemonId: string;\n leaseSeconds?: number;\n limit?: number;\n}\n\nexport interface SubmitUpdateFeedbackInput {\n claimToken: string;\n daemonId: string;\n details?: Record<string, string>;\n message?: string;\n status: Extract<RelayUpdateStatus, 'applied' | 'failed' | 'rejected'>;\n updateId: string;\n}\n\nexport interface ApprovalCapabilityFailureRecord {\n attempts: number;\n blockedUntil?: string;\n firstFailedAt: string;\n lastFailedAt: string;\n}\n\nexport interface RecordApprovalCapabilityFailureResult {\n attempts: number;\n blocked: boolean;\n blockedUntil: string | null;\n}\n\ninterface JsonCache {\n del(key: string): Promise<number>;\n get(key: string): Promise<string | null>;\n ping(): Promise<string>;\n quit(): Promise<string>;\n sadd(key: string, ...members: string[]): Promise<number>;\n set(key: string, value: string, mode?: 'NX' | 'XX'): Promise<'OK' | null>;\n smembers(key: string): Promise<string[]>;\n zadd(key: string, ...args: (string | number)[]): Promise<number>;\n zrange(key: string, start: number, stop: number, ...args: string[]): Promise<string[]>;\n zrem(key: string, ...members: string[]): Promise<number>;\n}\n\nconst defaultNamespace = 'wlfi:relay';\nconst approvalCapabilityFailureWindowMs = 5 * 60 * 1000;\nconst approvalCapabilityMaxFailures = 5;\nconst approvalCapabilityBlockWindowMs = 10 * 60 * 1000;\n\nconst toIsoTimestamp = (value = new Date()): string => value.toISOString();\n\nconst dedupe = <T>(values: T[]): T[] => [...new Set(values)];\n\nconst matchesOptionalFilter = (\n value: string | undefined,\n expected: string | undefined,\n): boolean => {\n if (!expected) {\n return true;\n }\n\n return value?.toLowerCase() === expected.toLowerCase();\n};\n\nconst clampLimit = (limit: number | undefined, fallback: number, max: number): number => {\n if (!limit || Number.isNaN(limit)) {\n return fallback;\n }\n\n return Math.max(1, Math.min(limit, max));\n};\n\nconst createApprovalCapabilityToken = (): string => randomBytes(32).toString('hex');\n\nconst approvalCapabilityHash = (token: string): string =>\n createHash('sha256').update(token, 'utf8').digest('hex');\n\nconst isActiveApprovalUpdateRecord = (\n record: RelayEncryptedUpdateRecord | null | undefined,\n approvalRequestId: string,\n): record is RelayEncryptedUpdateRecord =>\n Boolean(\n record &&\n record.type === 'manual_approval_decision' &&\n record.targetApprovalRequestId === approvalRequestId &&\n (record.status === 'pending' || record.status === 'inflight'),\n );\n\nconst preserveRotatedApprovalCapability = (\n incoming: RelayApprovalRequestRecord,\n existing: RelayApprovalRequestRecord | null,\n): RelayApprovalRequestRecord => {\n const existingMetadata = existing?.metadata;\n const incomingMetadata = incoming.metadata;\n const preservedCapabilityToken = existingMetadata?.approvalCapabilityToken?.trim();\n const preservedCapabilityHash = existingMetadata?.approvalCapabilityHash?.trim();\n\n if (!preservedCapabilityToken && !preservedCapabilityHash) {\n return incoming;\n }\n\n return {\n ...incoming,\n metadata: {\n ...(incomingMetadata ?? {}),\n ...(preservedCapabilityToken\n ? { approvalCapabilityToken: preservedCapabilityToken }\n : {}),\n ...(preservedCapabilityHash ? { approvalCapabilityHash: preservedCapabilityHash } : {}),\n },\n };\n};\n\nexport class RelayCacheService {\n private readonly client: JsonCache;\n private readonly namespace: string;\n\n constructor(options: { client?: Redis; namespace?: string } = {}) {\n this.client = (options.client ?? getCacheClient()) as unknown as JsonCache;\n this.namespace = options.namespace ?? defaultNamespace;\n }\n\n async ping(): Promise<string> {\n try {\n return await this.client.ping();\n } catch (error) {\n throw toCacheError(error, { operation: 'ping' });\n }\n }\n\n async syncDaemonRegistration(input: SyncDaemonRegistrationInput): Promise<{\n agentKeyCount: number;\n approvalRequestCount: number;\n policyCount: number;\n }> {\n const profile = {\n ...input.daemon,\n lastSeenAt: input.daemon.lastSeenAt || toIsoTimestamp(),\n updatedAt: input.daemon.updatedAt || toIsoTimestamp(),\n } satisfies RelayDaemonProfile;\n\n try {\n await this.writeJson(this.daemonProfileKey(profile.daemonId), profile);\n await this.client.sadd(this.daemonIndexKey(), profile.daemonId);\n\n if (input.policies) {\n const policies = input.policies.map((policy) => ({\n ...policy,\n daemonId: profile.daemonId,\n }));\n await this.writeJson(this.daemonPoliciesKey(profile.daemonId), policies);\n }\n\n if (input.agentKeys) {\n const agentKeys = input.agentKeys.map((agentKey) => ({\n ...agentKey,\n daemonId: profile.daemonId,\n }));\n await this.writeJson(this.daemonAgentKeysKey(profile.daemonId), agentKeys);\n }\n\n if (input.approvalRequests) {\n const approvalIndexKey = this.daemonApprovalsKey(profile.daemonId);\n const existingApprovalIds = new Set(await this.client.zrange(approvalIndexKey, 0, -1));\n const nextApprovalIds = new Set<string>();\n\n for (const approvalRequest of input.approvalRequests) {\n const existing = await this.readJson<RelayApprovalRequestRecord>(\n this.approvalKey(approvalRequest.approvalRequestId),\n );\n const normalized = preserveRotatedApprovalCapability(\n { ...approvalRequest, daemonId: profile.daemonId },\n existing,\n );\n nextApprovalIds.add(normalized.approvalRequestId);\n await this.writeJson(this.approvalKey(normalized.approvalRequestId), normalized);\n await this.client.zadd(\n approvalIndexKey,\n Date.parse(normalized.requestedAt),\n normalized.approvalRequestId,\n );\n }\n\n const staleApprovalIds = [...existingApprovalIds].filter(\n (approvalRequestId) => !nextApprovalIds.has(approvalRequestId),\n );\n if (staleApprovalIds.length > 0) {\n await this.client.zrem(approvalIndexKey, ...staleApprovalIds);\n for (const approvalRequestId of staleApprovalIds) {\n await this.client.del(this.approvalKey(approvalRequestId));\n await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));\n await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));\n }\n }\n }\n\n return {\n agentKeyCount: input.agentKeys?.length ?? 0,\n approvalRequestCount: input.approvalRequests?.length ?? 0,\n policyCount: input.policies?.length ?? 0,\n };\n } catch (error) {\n throw toCacheError(error, {\n key: this.daemonProfileKey(profile.daemonId),\n operation: 'syncDaemonRegistration',\n });\n }\n }\n\n async listDaemons(): Promise<RelayDaemonProfile[]> {\n const daemonIds = await this.client.smembers(this.daemonIndexKey());\n const profiles = await Promise.all(\n daemonIds.map((daemonId) =>\n this.readJson<RelayDaemonProfile>(this.daemonProfileKey(daemonId)),\n ),\n );\n\n return profiles.filter((profile): profile is RelayDaemonProfile => Boolean(profile));\n }\n\n async getDaemonProfile(daemonId: string): Promise<RelayDaemonProfile | null> {\n return await this.readJson<RelayDaemonProfile>(this.daemonProfileKey(daemonId));\n }\n\n async getDaemonPolicies(daemonId: string): Promise<RelayPolicyRecord[]> {\n return (await this.readJson<RelayPolicyRecord[]>(this.daemonPoliciesKey(daemonId))) ?? [];\n }\n\n async getDaemonAgentKeys(daemonId: string): Promise<RelayAgentKeyRecord[]> {\n return (await this.readJson<RelayAgentKeyRecord[]>(this.daemonAgentKeysKey(daemonId))) ?? [];\n }\n\n async getApprovalRequest(approvalRequestId: string): Promise<RelayApprovalRequestRecord | null> {\n return await this.readJson<RelayApprovalRequestRecord>(this.approvalKey(approvalRequestId));\n }\n\n async listApprovalRequests(\n filters: ApprovalRequestFilters = {},\n ): Promise<RelayApprovalRequestRecord[]> {\n const limit = clampLimit(filters.limit, 100, 500);\n const daemonIds = filters.daemonId\n ? [filters.daemonId]\n : await this.client.smembers(this.daemonIndexKey());\n const requestIdsByDaemon = await Promise.all(\n daemonIds.map((daemonId) =>\n this.client.zrange(this.daemonApprovalsKey(daemonId), 0, limit * 2, 'REV'),\n ),\n );\n const requestIds = dedupe(requestIdsByDaemon.flat()).slice(0, limit * 3);\n const requests = await Promise.all(\n requestIds.map((requestId) =>\n this.readJson<RelayApprovalRequestRecord>(this.approvalKey(requestId)),\n ),\n );\n\n return requests\n .filter((request): request is RelayApprovalRequestRecord => Boolean(request))\n .filter((request) => (filters.daemonId ? request.daemonId === filters.daemonId : true))\n .filter((request) => (filters.status ? request.status === filters.status : true))\n .filter((request) => matchesOptionalFilter(request.destination, filters.destination))\n .filter((request) => matchesOptionalFilter(request.tokenAddress, filters.tokenAddress))\n .sort((left, right) => Date.parse(right.requestedAt) - Date.parse(left.requestedAt))\n .slice(0, limit);\n }\n\n async createEncryptedUpdate(\n input: CreateEncryptedUpdateInput,\n ): Promise<RelayEncryptedUpdateRecord> {\n if (input.type === 'manual_approval_decision') {\n if (!input.targetApprovalRequestId) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n message: 'Manual approval updates require a target approval request id',\n operation: 'createEncryptedUpdate',\n });\n }\n\n const approvalKey = this.approvalKey(input.targetApprovalRequestId);\n const approval = await this.readJson<RelayApprovalRequestRecord>(approvalKey);\n if (!approval) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key: approvalKey,\n message: `Unknown approval '${input.targetApprovalRequestId}'`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n if (approval.daemonId !== input.daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: approvalKey,\n message: `Approval '${input.targetApprovalRequestId}' belongs to daemon '${approval.daemonId}', not '${input.daemonId}'`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n if (approval.status !== 'pending') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: approvalKey,\n message: `Approval '${input.targetApprovalRequestId}' is '${approval.status}' and cannot accept new updates`,\n operation: 'createEncryptedUpdate',\n });\n }\n }\n\n const updateId = input.updateId ?? randomUUID();\n const now = toIsoTimestamp();\n const record: RelayEncryptedUpdateRecord = {\n createdAt: now,\n daemonId: input.daemonId,\n metadata: input.metadata,\n payload: input.payload,\n status: 'pending',\n targetApprovalRequestId: input.targetApprovalRequestId,\n type: input.type,\n updateId,\n updatedAt: now,\n };\n\n const activeApprovalKey =\n input.type === 'manual_approval_decision' && input.targetApprovalRequestId\n ? this.activeApprovalUpdateKey(input.targetApprovalRequestId)\n : null;\n const updateKey = this.updateKey(updateId);\n let ownsActiveApprovalSlot = false;\n\n await this.writeJson(updateKey, record);\n\n try {\n if (activeApprovalKey) {\n const reserved = await this.client.set(activeApprovalKey, updateId, 'NX');\n if (reserved !== 'OK') {\n const existingUpdateId = await this.client.get(activeApprovalKey);\n const existingRecord = existingUpdateId\n ? await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(existingUpdateId))\n : null;\n\n if (isActiveApprovalUpdateRecord(existingRecord, input.targetApprovalRequestId!)) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: activeApprovalKey,\n message: `Approval '${input.targetApprovalRequestId}' already has a queued operator update`,\n operation: 'createEncryptedUpdate',\n });\n }\n\n await this.client.del(activeApprovalKey);\n const retriedReservation = await this.client.set(activeApprovalKey, updateId, 'NX');\n if (retriedReservation !== 'OK') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key: activeApprovalKey,\n message: `Approval '${input.targetApprovalRequestId}' already has a queued operator update`,\n operation: 'createEncryptedUpdate',\n });\n }\n }\n\n ownsActiveApprovalSlot = true;\n }\n\n await this.client.zadd(this.daemonUpdatesKey(input.daemonId), Date.now(), updateId);\n } catch (error) {\n await this.client.del(updateKey);\n if (activeApprovalKey && ownsActiveApprovalSlot) {\n await this.client.del(activeApprovalKey);\n }\n throw error;\n }\n\n return record;\n }\n\n async hasActiveApprovalUpdate(daemonId: string, approvalRequestId: string): Promise<boolean> {\n const indexedUpdateId = await this.client.get(this.activeApprovalUpdateKey(approvalRequestId));\n if (indexedUpdateId) {\n const indexedRecord = await this.readJson<RelayEncryptedUpdateRecord>(\n this.updateKey(indexedUpdateId),\n );\n if (isActiveApprovalUpdateRecord(indexedRecord, approvalRequestId)) {\n return true;\n }\n\n await this.client.del(this.activeApprovalUpdateKey(approvalRequestId));\n }\n\n const updateIds = await this.client.zrange(this.daemonUpdatesKey(daemonId), 0, -1, 'REV');\n\n for (const updateId of updateIds) {\n const record = await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n if (isActiveApprovalUpdateRecord(record, approvalRequestId)) {\n await this.client.set(this.activeApprovalUpdateKey(approvalRequestId), updateId, 'NX');\n return true;\n }\n }\n\n return false;\n }\n\n async consumeApprovalCapability(\n approvalRequestId: string,\n capabilityHash: string,\n ): Promise<boolean> {\n try {\n const result = await this.client.set(\n this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n toIsoTimestamp(),\n 'NX',\n );\n return result === 'OK';\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n operation: 'consumeApprovalCapability',\n });\n }\n }\n\n async releaseApprovalCapabilityConsumption(\n approvalRequestId: string,\n capabilityHash: string,\n ): Promise<void> {\n try {\n await this.client.del(this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash));\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityConsumedKey(approvalRequestId, capabilityHash),\n operation: 'releaseApprovalCapabilityConsumption',\n });\n }\n }\n\n async clearApprovalCapabilityFailures(approvalRequestId: string): Promise<void> {\n try {\n await this.client.del(this.approvalCapabilityFailuresKey(approvalRequestId));\n } catch (error) {\n throw toCacheError(error, {\n key: this.approvalCapabilityFailuresKey(approvalRequestId),\n operation: 'clearApprovalCapabilityFailures',\n });\n }\n }\n\n async recordApprovalCapabilityFailure(\n approvalRequestId: string,\n ): Promise<RecordApprovalCapabilityFailureResult> {\n const key = this.approvalCapabilityFailuresKey(approvalRequestId);\n const now = new Date();\n const nowMs = now.getTime();\n const existing = await this.readJson<ApprovalCapabilityFailureRecord>(key);\n\n if (existing?.blockedUntil && Date.parse(existing.blockedUntil) > nowMs) {\n return {\n attempts: existing.attempts,\n blocked: true,\n blockedUntil: existing.blockedUntil,\n };\n }\n\n const firstFailedAtMs = existing?.firstFailedAt\n ? Date.parse(existing.firstFailedAt)\n : Number.NaN;\n const withinWindow =\n Number.isFinite(firstFailedAtMs) &&\n nowMs - firstFailedAtMs <= approvalCapabilityFailureWindowMs;\n const attempts = withinWindow && existing ? existing.attempts + 1 : 1;\n const firstFailedAt = withinWindow && existing ? existing.firstFailedAt : now.toISOString();\n const blockedUntil =\n attempts >= approvalCapabilityMaxFailures\n ? new Date(nowMs + approvalCapabilityBlockWindowMs).toISOString()\n : undefined;\n\n await this.writeJson(key, {\n attempts,\n blockedUntil,\n firstFailedAt,\n lastFailedAt: now.toISOString(),\n } satisfies ApprovalCapabilityFailureRecord);\n\n return {\n attempts,\n blocked: blockedUntil !== undefined,\n blockedUntil: blockedUntil ?? null,\n };\n }\n\n async rotateApprovalCapability(approvalRequestId: string): Promise<RelayApprovalRequestRecord> {\n const key = this.approvalKey(approvalRequestId);\n const approval = await this.readJson<RelayApprovalRequestRecord>(key);\n\n if (!approval) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown approval '${approvalRequestId}'`,\n operation: 'rotateApprovalCapability',\n });\n }\n\n if (approval.status !== 'pending') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Approval '${approvalRequestId}' is '${approval.status}' and cannot accept a new secure approval link`,\n operation: 'rotateApprovalCapability',\n });\n }\n\n const capabilityToken = createApprovalCapabilityToken();\n const nextRecord: RelayApprovalRequestRecord = {\n ...approval,\n metadata: {\n ...(approval.metadata ?? {}),\n approvalCapabilityHash: approvalCapabilityHash(capabilityToken),\n approvalCapabilityToken: capabilityToken,\n },\n updatedAt: toIsoTimestamp(),\n };\n\n await this.writeJson(key, nextRecord);\n await this.clearApprovalCapabilityFailures(approvalRequestId);\n\n return nextRecord;\n }\n\n async claimEncryptedUpdates(\n input: ClaimEncryptedUpdatesInput,\n ): Promise<RelayEncryptedUpdateRecord[]> {\n const limit = clampLimit(input.limit, 25, 100);\n const leaseSeconds = clampLimit(input.leaseSeconds, 30, 300);\n const now = new Date();\n const nowMs = now.getTime();\n const claimUntil = new Date(nowMs + leaseSeconds * 1000).toISOString();\n const updateIds = await this.client.zrange(\n this.daemonUpdatesKey(input.daemonId),\n 0,\n limit * 4,\n 'REV',\n );\n const claimed: RelayEncryptedUpdateRecord[] = [];\n\n for (const updateId of updateIds) {\n if (claimed.length >= limit) {\n break;\n }\n\n const claimLockKey = this.updateClaimLockKey(updateId);\n let ownsClaimLock = false;\n\n try {\n const reserved = await this.client.set(claimLockKey, claimUntil, 'NX');\n if (reserved !== 'OK') {\n const existingClaimLockUntil = await this.client.get(claimLockKey);\n if (\n existingClaimLockUntil &&\n Number.isFinite(Date.parse(existingClaimLockUntil)) &&\n Date.parse(existingClaimLockUntil) > nowMs\n ) {\n continue;\n }\n\n await this.client.del(claimLockKey);\n const retriedReservation = await this.client.set(claimLockKey, claimUntil, 'NX');\n if (retriedReservation !== 'OK') {\n continue;\n }\n }\n\n ownsClaimLock = true;\n\n const record = await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n if (!record) {\n continue;\n }\n\n if (\n record.status === 'applied' ||\n record.status === 'failed' ||\n record.status === 'rejected'\n ) {\n continue;\n }\n\n if (\n record.status === 'inflight' &&\n record.claimUntil &&\n Date.parse(record.claimUntil) > nowMs\n ) {\n continue;\n }\n\n const nextRecord: RelayEncryptedUpdateRecord = {\n ...record,\n claimToken: randomUUID(),\n claimUntil,\n lastDeliveredAt: now.toISOString(),\n status: 'inflight',\n updatedAt: now.toISOString(),\n };\n await this.writeJson(this.updateKey(updateId), nextRecord);\n claimed.push(nextRecord);\n } finally {\n if (ownsClaimLock) {\n await this.client.del(claimLockKey);\n }\n }\n }\n\n return claimed;\n }\n\n async submitUpdateFeedback(\n input: SubmitUpdateFeedbackInput,\n ): Promise<RelayEncryptedUpdateRecord> {\n const key = this.updateKey(input.updateId);\n const record = await this.readJson<RelayEncryptedUpdateRecord>(key);\n const nowMs = Date.now();\n\n if (!record || record.daemonId !== input.daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown update '${input.updateId}' for daemon '${input.daemonId}'`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n if (record.status !== 'inflight') {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Update '${input.updateId}' is '${record.status}' and is not currently claimed`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n const claimUntilMs = record.claimUntil ? Date.parse(record.claimUntil) : Number.NaN;\n if (!Number.isFinite(claimUntilMs) || claimUntilMs <= nowMs) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Claim for update '${input.updateId}' has expired`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n if (!record.claimToken || record.claimToken !== input.claimToken) {\n throw new CacheError({\n code: cacheErrorCodes.invalidPayload,\n key,\n message: `Claim token mismatch for update '${input.updateId}'`,\n operation: 'submitUpdateFeedback',\n });\n }\n\n const feedback: RelayUpdateFeedbackRecord = {\n daemonId: input.daemonId,\n details: input.details,\n feedbackAt: toIsoTimestamp(),\n message: input.message,\n status: input.status,\n updateId: input.updateId,\n };\n const nextRecord: RelayEncryptedUpdateRecord = {\n ...record,\n claimToken: undefined,\n claimUntil: undefined,\n feedback,\n status: input.status,\n updatedAt: toIsoTimestamp(),\n };\n\n await this.writeJson(key, nextRecord);\n if (record.targetApprovalRequestId && record.type === 'manual_approval_decision') {\n const activeApprovalKey = this.activeApprovalUpdateKey(record.targetApprovalRequestId);\n const indexedUpdateId = await this.client.get(activeApprovalKey);\n if (indexedUpdateId === input.updateId) {\n await this.client.del(activeApprovalKey);\n }\n }\n return nextRecord;\n }\n\n async getEncryptedUpdate(updateId: string): Promise<RelayEncryptedUpdateRecord | null> {\n return await this.readJson<RelayEncryptedUpdateRecord>(this.updateKey(updateId));\n }\n\n async removeEncryptedUpdate(daemonId: string, updateId: string): Promise<void> {\n const key = this.updateKey(updateId);\n const record = await this.readJson<RelayEncryptedUpdateRecord>(key);\n if (!record || record.daemonId !== daemonId) {\n throw new CacheError({\n code: cacheErrorCodes.notFound,\n key,\n message: `Unknown update '${updateId}' for daemon '${daemonId}'`,\n operation: 'removeEncryptedUpdate',\n });\n }\n\n await this.client.zrem(this.daemonUpdatesKey(daemonId), updateId);\n await this.client.del(key);\n if (record.targetApprovalRequestId && record.type === 'manual_approval_decision') {\n const activeApprovalKey = this.activeApprovalUpdateKey(record.targetApprovalRequestId);\n const indexedUpdateId = await this.client.get(activeApprovalKey);\n if (indexedUpdateId === updateId) {\n await this.client.del(activeApprovalKey);\n }\n }\n }\n\n private readonly daemonIndexKey = (): string => `${this.namespace}:daemons`;\n private readonly daemonProfileKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:profile`;\n private readonly daemonPoliciesKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:policies`;\n private readonly daemonAgentKeysKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:agent-keys`;\n private readonly daemonApprovalsKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:approvals`;\n private readonly daemonUpdatesKey = (daemonId: string): string =>\n `${this.namespace}:daemon:${daemonId}:updates`;\n private readonly approvalKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}`;\n private readonly approvalCapabilityConsumedKey = (\n approvalRequestId: string,\n capabilityHash: string,\n ): string =>\n `${this.namespace}:approval:${approvalRequestId}:capability:${capabilityHash}:consumed`;\n private readonly approvalCapabilityFailuresKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}:capability-failures`;\n private readonly activeApprovalUpdateKey = (approvalRequestId: string): string =>\n `${this.namespace}:approval:${approvalRequestId}:active-update`;\n private readonly updateClaimLockKey = (updateId: string): string =>\n `${this.namespace}:update:${updateId}:claim-lock`;\n private readonly updateKey = (updateId: string): string => `${this.namespace}:update:${updateId}`;\n\n private async readJson<T>(key: string): Promise<T | null> {\n try {\n const payload = await this.client.get(key);\n if (payload === null) {\n return null;\n }\n\n return JSON.parse(payload) as T;\n } catch (error) {\n throw toCacheError(error, { key, operation: 'readJson' });\n }\n }\n\n private async writeJson(key: string, value: unknown): Promise<void> {\n try {\n await this.client.set(key, JSON.stringify(value));\n } catch (error) {\n throw toCacheError(error, { key, operation: 'writeJson' });\n }\n }\n}\n\nexport const createRelayCacheService = (options: { client?: Redis; namespace?: string } = {}) => {\n return new RelayCacheService(options);\n};\n"]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkUVU7VFE3cjs = require('./chunk-UVU7VFE3.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
|
|
@@ -25,5 +25,5 @@ var _chunk2QFWMUXTcjs = require('./chunk-2QFWMUXT.cjs');
|
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
exports.CacheError = _chunk2QFWMUXTcjs.CacheError; exports.RelayCacheService =
|
|
28
|
+
exports.CacheError = _chunk2QFWMUXTcjs.CacheError; exports.RelayCacheService = _chunkUVU7VFE3cjs.RelayCacheService; exports.cacheErrorCodes = _chunk2QFWMUXTcjs.cacheErrorCodes; exports.closeCacheClient = _chunkUYNEHZHBcjs.closeCacheClient; exports.createCacheClient = _chunkUYNEHZHBcjs.createCacheClient; exports.createRelayCacheService = _chunkUVU7VFE3cjs.createRelayCacheService; exports.getCacheClient = _chunkUYNEHZHBcjs.getCacheClient; exports.relayApprovalStatuses = _chunkUVU7VFE3cjs.relayApprovalStatuses; exports.relayUpdateStatuses = _chunkUVU7VFE3cjs.relayUpdateStatuses; exports.toCacheError = _chunk2QFWMUXTcjs.toCacheError;
|
|
29
29
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
var
|
|
6
|
+
var _chunkUVU7VFE3cjs = require('../chunk-UVU7VFE3.cjs');
|
|
7
7
|
require('../chunk-UYNEHZHB.cjs');
|
|
8
8
|
require('../chunk-2QFWMUXT.cjs');
|
|
9
9
|
|
|
@@ -11,5 +11,5 @@ require('../chunk-2QFWMUXT.cjs');
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
exports.RelayCacheService =
|
|
14
|
+
exports.RelayCacheService = _chunkUVU7VFE3cjs.RelayCacheService; exports.createRelayCacheService = _chunkUVU7VFE3cjs.createRelayCacheService; exports.relayApprovalStatuses = _chunkUVU7VFE3cjs.relayApprovalStatuses; exports.relayUpdateStatuses = _chunkUVU7VFE3cjs.relayUpdateStatuses;
|
|
15
15
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../tsup/dist/cli-default.js" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../tsup/dist/cli-default.js" "$@"
|
|
17
17
|
fi
|
|
@@ -11,7 +11,7 @@ else
|
|
|
11
11
|
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/dist/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules/tsup/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../tsup/dist/cli-node.js" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../tsup/dist/cli-node.js" "$@"
|
|
17
17
|
fi
|
|
@@ -6,12 +6,12 @@ case `uname` in
|
|
|
6
6
|
esac
|
|
7
7
|
|
|
8
8
|
if [ -z "$NODE_PATH" ]; then
|
|
9
|
-
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.
|
|
9
|
+
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.7_jsdom@28.1.0_@noble+hashes@1.8.0__tsx@4.21.0/node_modules/vitest/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.7_jsdom@28.1.0_@noble+hashes@1.8.0__tsx@4.21.0/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules"
|
|
10
10
|
else
|
|
11
|
-
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.
|
|
11
|
+
export NODE_PATH="/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.7_jsdom@28.1.0_@noble+hashes@1.8.0__tsx@4.21.0/node_modules/vitest/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/vitest@3.2.4_@types+node@24.12.0_jiti@1.21.7_jsdom@28.1.0_@noble+hashes@1.8.0__tsx@4.21.0/node_modules:/Users/hanzhi/Documents/WLFI/wlfi-agent-sdk/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
12
12
|
fi
|
|
13
13
|
if [ -x "$basedir/node" ]; then
|
|
14
|
-
exec "$basedir/node" "$basedir
|
|
14
|
+
exec "$basedir/node" "$basedir/../vitest/vitest.mjs" "$@"
|
|
15
15
|
else
|
|
16
|
-
exec node "$basedir
|
|
16
|
+
exec node "$basedir/../vitest/vitest.mjs" "$@"
|
|
17
17
|
fi
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"3.2.4","results":[[":src/service/index.test.ts",{"duration":
|
|
1
|
+
{"version":"3.2.4","results":[[":src/service/index.test.ts",{"duration":10.090374999999995,"failed":false}]]}
|