@oaath/server 0.1.0 → 0.3.1
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/README.md +239 -5
- package/dist/apns.d.ts +2 -2
- package/dist/apns.js +2 -2
- package/dist/{challenge-AGTmUfj2.js → challenge-DmpGSogj.js} +2 -2
- package/dist/{challenge-AGTmUfj2.js.map → challenge-DmpGSogj.js.map} +1 -1
- package/dist/inbox-B80EUVht.js +249 -0
- package/dist/inbox-B80EUVht.js.map +1 -0
- package/dist/index.d.ts +9 -255
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +631 -48
- package/dist/index.js.map +1 -1
- package/dist/interface-DHpwP0wr.d.ts +245 -0
- package/dist/interface-DHpwP0wr.d.ts.map +1 -0
- package/dist/kernel.d.ts +42 -0
- package/dist/kernel.d.ts.map +1 -0
- package/dist/kernel.js +80 -0
- package/dist/kernel.js.map +1 -0
- package/dist/kms-BWkywdJM.d.ts +18 -0
- package/dist/kms-BWkywdJM.d.ts.map +1 -0
- package/dist/native.d.ts +3 -30
- package/dist/native.js +115 -2
- package/dist/native.js.map +1 -0
- package/dist/postgres.d.ts +38 -3
- package/dist/postgres.d.ts.map +1 -1
- package/dist/postgres.js +301 -14
- package/dist/postgres.js.map +1 -1
- package/dist/projection-B7IB9irs.d.ts +228 -0
- package/dist/projection-B7IB9irs.d.ts.map +1 -0
- package/dist/{records-Bgr-9PUh.js → records-BQNDxbPg.js} +32 -8
- package/dist/records-BQNDxbPg.js.map +1 -0
- package/dist/records-BUvqmp0D.js +70 -0
- package/dist/records-BUvqmp0D.js.map +1 -0
- package/dist/service-Cf4f-9KP.js +706 -0
- package/dist/service-Cf4f-9KP.js.map +1 -0
- package/dist/service-J51bOVe6.d.ts +483 -0
- package/dist/service-J51bOVe6.d.ts.map +1 -0
- package/package.json +39 -8
- package/LICENSE +0 -201
- package/dist/authentication-HUYWk5Y2.d.ts +0 -46
- package/dist/authentication-HUYWk5Y2.d.ts.map +0 -1
- package/dist/decision-dEe9n108.d.ts +0 -53
- package/dist/decision-dEe9n108.d.ts.map +0 -1
- package/dist/interface-WwvwWs8e.d.ts +0 -114
- package/dist/interface-WwvwWs8e.d.ts.map +0 -1
- package/dist/native.d.ts.map +0 -1
- package/dist/projection-dGIkE0rI.js +0 -516
- package/dist/projection-dGIkE0rI.js.map +0 -1
- package/dist/projection-g6k_CCUK.d.ts +0 -136
- package/dist/projection-g6k_CCUK.d.ts.map +0 -1
- package/dist/records-Bgr-9PUh.js.map +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["HASH"],"sources":["../src/artifact/claim.ts","../src/authorization/code.ts","../src/authorization/resume.ts","../src/authorization/pickup.ts","../src/security/authentication.ts","../src/security/rate-limit.ts","../src/relay/handler.ts","../src/security/redact.ts","../src/session-signer/kms-provider.ts","../src/store/memory.ts"],"sourcesContent":["/**\n * One-time encrypted artifact release.\n *\n * ```text\n * state and owner the artifact record's `claimedAt` owns \"released\"\n * transitions sealed -> claimed, exactly once\n * terminal claimed; a second claim fails closed\n * retry positively safe? no. The claim commits before the KMS is asked to\n * decrypt, so a decrypt or transport failure burns the\n * artifact instead of risking a second release\n * crash/reload a crash before commit leaves the artifact claimable\n * ```\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { withRelayTransaction } from \"../store/interface.js\";\nimport { openArtifact } from \"./encrypt.js\";\n\nexport interface ClaimEncryptedArtifactInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n readonly kms: RelayKms;\n /** Authenticated `client` caller; only the bound client may claim. */\n readonly caller: RelayCaller;\n /** Released only by a successful code consume. */\n readonly artifactId: string;\n}\n\nexport interface ClaimedEncryptedArtifact {\n readonly requestId: string;\n readonly artifact: string;\n}\n\nexport async function claimEncryptedArtifact(\n input: ClaimEncryptedArtifactInput,\n): Promise<ClaimedEncryptedArtifact> {\n const claimedAt = relayNow(input.clock);\n const claimed = await withRelayTransaction(input.store, async (transaction) => {\n const record = await transaction.lockEncryptedArtifact(input.artifactId);\n // An artifact bound to another client is indistinguishable from an unknown one.\n if (!record || record.clientId !== input.caller.clientId) {\n return relayFailure(\"relay_not_found\", \"encrypted artifact does not exist\");\n }\n if (record.claimedAt !== null) {\n relayFailure(\"relay_artifact_already_claimed\", \"encrypted artifact was already claimed\");\n }\n if (!(await transaction.claimEncryptedArtifact(input.artifactId, claimedAt))) {\n relayFailure(\"relay_state_ambiguous\", \"one-time claim did not apply under its row lock\");\n }\n return record;\n });\n return Object.freeze({\n requestId: claimed.requestId,\n artifact: await openArtifact(input.kms, claimed.ciphertextRef),\n });\n}\n","/**\n * One-time authorization code consume.\n *\n * ```text\n * state and owner the code record's `consumedAt` owns \"used\"\n * transitions issued -> consumed, exactly once\n * terminal consumed; a second consume fails closed\n * retry positively safe? no, in either direction: a released code is never\n * re-released, and an ambiguous commit is never retried\n * crash/reload the guarded update and the release decide together in one\n * transaction under the code's row lock\n * ```\n *\n * A failed PKCE or redirect binding still burns the code, so a stolen code\n * cannot be brute-forced against the stored challenge.\n *\n * The endpoint is not an oracle for whether a guessed code was correct: an\n * unknown code, a code bound to another client, a wrong redirect URI, and a\n * wrong verifier all leave as the single `relay_code_invalid` code and status.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { type RelayErrorCode, relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { sha256Base64Url, verifyPkceS256 } from \"./challenge.js\";\n\nexport interface ConsumeAuthorizationCodeInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n /** Authenticated `client` caller; only the bound client may consume. */\n readonly caller: RelayCaller;\n readonly code: string;\n readonly codeVerifier: string;\n readonly redirectUri: string;\n}\n\nexport interface ConsumedAuthorizationCode {\n readonly requestId: string;\n /** One-time claim handle for the encrypted artifact. */\n readonly artifactId: string;\n}\n\ntype ConsumeOutcome =\n | Readonly<{ kind: \"released\"; released: ConsumedAuthorizationCode }>\n | Readonly<{ kind: \"burned\"; code: RelayErrorCode }>;\n\nexport async function consumeAuthorizationCode(\n input: ConsumeAuthorizationCodeInput,\n): Promise<ConsumedAuthorizationCode> {\n const consumedAt = relayNow(input.clock);\n const codeHash = await sha256Base64Url(input.code);\n const transaction = await input.store.begin();\n let outcome: ConsumeOutcome;\n try {\n const record = await transaction.lockAuthorizationCode(codeHash);\n // An unknown code and a code bound to another client are indistinguishable\n // from a code whose binding failed below.\n if (!record || record.clientId !== input.caller.clientId) {\n relayFailure(\"relay_code_invalid\", \"authorization code redemption failed\");\n }\n if (record.consumedAt !== null) {\n relayFailure(\"relay_code_already_consumed\", \"authorization code was already consumed\");\n }\n if (consumedAt >= record.expiresAt) {\n // Already dead; nothing left to burn.\n relayFailure(\"relay_expired\", \"authorization code expired\");\n }\n const bound =\n record.redirectUri === input.redirectUri &&\n (await verifyPkceS256(input.codeVerifier, record.codeChallenge));\n if (!(await transaction.consumeAuthorizationCode(codeHash, consumedAt))) {\n relayFailure(\"relay_state_ambiguous\", \"one-time consume did not apply under its row lock\");\n }\n if (!bound) {\n // Void the artifact with the code that would have released it. A `false`\n // result means it was already terminal, which is the same outcome.\n await transaction.lockEncryptedArtifact(record.artifactId);\n await transaction.claimEncryptedArtifact(record.artifactId, consumedAt);\n }\n outcome = bound\n ? Object.freeze({\n kind: \"released\",\n released: Object.freeze({\n requestId: record.requestId,\n artifactId: record.artifactId,\n }),\n })\n : Object.freeze({ kind: \"burned\", code: \"relay_code_invalid\" });\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n // The burn is committed before the failure is reported.\n await transaction.commit();\n if (outcome.kind === \"burned\") {\n relayFailure(outcome.code, \"authorization code redemption failed and the code was burned\");\n }\n return outcome.released;\n}\n","/**\n * Resume: fresh authentication plus a grant recovery read.\n *\n * Resume never transitions anything and never re-releases a code or an artifact.\n * The caller re-authenticates on every call, and receives only enough state to\n * decide whether its own grant work is still valid.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { withRelayTransaction } from \"../store/interface.js\";\nimport { type AuthorizationState, readAuthorizationState } from \"./request.js\";\n\nexport interface ResumeAuthorizationInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n /** Freshly authenticated `client` caller; only the bound client may resume. */\n readonly caller: RelayCaller;\n readonly requestId: string;\n}\n\nexport function resumeAuthorization(input: ResumeAuthorizationInput): Promise<AuthorizationState> {\n const now = relayNow(input.clock);\n return withRelayTransaction(input.store, (transaction) =>\n readAuthorizationState(\n transaction,\n input.requestId,\n now,\n (request) => request.clientId === input.caller.clientId,\n ),\n );\n}\n","/**\n * Authenticated client pickup of a released authorization code.\n *\n * ```text\n * state and owner reads the request and decision records; writes nothing\n * transitions none — pickup is idempotent\n * terminal follows the decision record\n * retry positively safe? yes: the code stays one-shot at consumption, where the\n * PKCE verifier and the code hash lock decide\n * ```\n *\n * The relay mints the code, so releasing the sealed copy to the authenticated\n * creating client adds no authority: consumption still requires the verifier\n * only that client holds. The request's stored clientId owns who may pick up;\n * any other caller reads absence, never existence.\n *\n * @author taek <leekt216@gmail.com>\n */\nimport { openArtifact } from \"../artifact/encrypt.js\";\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport { type RelayStore, withRelayTransaction } from \"../store/interface.js\";\n\nexport interface FetchAuthorizationCodeInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n readonly kms: RelayKms;\n /** Authenticated `client` caller; only the creating client may pick up. */\n readonly caller: RelayCaller;\n readonly requestId: string;\n}\n\nexport type FetchedAuthorizationCode =\n | Readonly<{ outcome: \"pending\" }>\n | Readonly<{ outcome: \"rejected\"; decidedAt: number }>\n | Readonly<{ outcome: \"approved\"; decidedAt: number; code: string; codeExpiresAt: number }>;\n\nexport async function fetchAuthorizationCode(\n input: FetchAuthorizationCodeInput,\n): Promise<FetchedAuthorizationCode> {\n const now = relayNow(input.clock);\n const decided = await withRelayTransaction(input.store, async (transaction) => {\n const request = await transaction.lockAuthorizationRequest(input.requestId);\n if (!request || request.clientId !== input.caller.clientId) {\n return relayFailure(\"relay_not_found\", \"authorization request does not exist\");\n }\n const decision = await transaction.lockAuthorizationDecision(input.requestId);\n if (!decision) {\n if (now >= request.expiresAt) {\n return relayFailure(\"relay_expired\", \"authorization request expired\");\n }\n return null;\n }\n return decision;\n });\n if (decided === null) return Object.freeze({ outcome: \"pending\" });\n if (decided.outcome === \"rejected\" || decided.codeRef === null) {\n return Object.freeze({ outcome: \"rejected\", decidedAt: decided.decidedAt });\n }\n const codeExpiresAt = decided.codeExpiresAt ?? 0;\n if (now >= codeExpiresAt) {\n return relayFailure(\"relay_expired\", \"authorization code expired\");\n }\n // Opened only after every stored fact agreed; the plaintext never persists.\n return Object.freeze({\n outcome: \"approved\",\n decidedAt: decided.decidedAt,\n code: await openArtifact(input.kms, decided.codeRef),\n codeExpiresAt,\n });\n}\n","/**\n * Deployment-owned client/device authentication port.\n *\n * The relay never parses credentials. It hands the request to the deployment,\n * which returns the authenticated bindings or nothing. `clientId` and `subject`\n * come only from here: wire input may never declare either.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type CaptureContext, captureDenseArray, exactRecord } from \"@oaath/protocol\";\nimport { OaathRelayError, relayFailure } from \"../relay/errors.js\";\nimport { boundedText, canonicalIdentifier, RELAY_LIMITS } from \"../store/records.js\";\n\n/** `client` is the requesting application; `owner` is the approving account owner. */\nexport type RelayCallerRole = \"client\" | \"owner\";\n\nconst MAX_REDIRECT_URIS = 8;\n\nexport interface RelayCaller {\n readonly role: RelayCallerRole;\n readonly clientId: string;\n /** Pairwise user/device subject. */\n readonly subject: string;\n /**\n * Redirect URIs the deployment registered for this client. An authorization\n * code may only be requested for one of them. `owner` callers pass an empty\n * list; they never receive a code at a redirect URI.\n */\n readonly redirectUris: readonly string[];\n}\n\nexport interface RelayAuthentication {\n /**\n * Resolves to a `RelayCaller`-shaped value, or `null`/`undefined` when the\n * caller is not authenticated. May throw `OaathRelayError` to choose a code.\n */\n authenticate(request: Request): Promise<unknown>;\n}\n\nfunction captureCaller(value: unknown): RelayCaller {\n const context: CaptureContext = new WeakSet();\n // A port that breaks its own contract is an internal failure, not a 401.\n const fail = (message: string): never => relayFailure(\"relay_internal\", message);\n const record = exactRecord(\n value,\n [\"role\", \"clientId\", \"subject\", \"redirectUris\"],\n \"authenticated caller\",\n context,\n fail,\n );\n if (record.role !== \"client\" && record.role !== \"owner\") {\n return relayFailure(\"relay_internal\", \"authenticated caller role is unsupported\");\n }\n const redirectUris = captureDenseArray(record.redirectUris, \"caller redirectUris\", context, fail);\n if (redirectUris.length > MAX_REDIRECT_URIS) {\n return relayFailure(\"relay_internal\", \"caller redirectUris is unbounded\");\n }\n return Object.freeze({\n role: record.role,\n clientId: canonicalIdentifier(record.clientId, \"caller clientId\", \"relay_internal\"),\n subject: canonicalIdentifier(record.subject, \"caller subject\", \"relay_internal\"),\n redirectUris: Object.freeze(\n redirectUris.map((uri) =>\n boundedText(uri, RELAY_LIMITS.redirectUri, \"caller redirectUri\", \"relay_internal\"),\n ),\n ),\n });\n}\n\nexport async function authenticateCaller(\n authentication: RelayAuthentication,\n request: Request,\n required: RelayCallerRole | readonly RelayCallerRole[],\n): Promise<RelayCaller> {\n let authenticated: unknown;\n try {\n authenticated = await authentication.authenticate(request);\n } catch (error) {\n // Unreadable authentication is not authentication.\n if (error instanceof OaathRelayError) throw error;\n return relayFailure(\"relay_unauthenticated\", \"authentication port failed\");\n }\n if (authenticated === null || authenticated === undefined) {\n return relayFailure(\"relay_unauthenticated\", \"caller is not authenticated\");\n }\n const caller = captureCaller(authenticated);\n const roles = typeof required === \"string\" ? [required] : required;\n if (!roles.includes(caller.role)) {\n return relayFailure(\"relay_forbidden\", \"caller may not act in the required role\");\n }\n return caller;\n}\n","/**\n * Optional deployment-owned limiter port.\n *\n * There is no default limiter: an unset port means no limiting, and the relay\n * never invents a policy the deployment did not choose. A limiter that fails is\n * treated as `limited`, because an unreadable limiter is not permission.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { relayFailure } from \"../relay/errors.js\";\n\nexport interface RelayRateLimitInput {\n /** Stable route name, never a credential-bearing URL. */\n readonly route: string;\n readonly clientId: string | null;\n}\n\nexport interface RelayRateLimiter {\n /** Resolves to `\"allowed\"` or `\"limited\"`. Anything else is `limited`. */\n check(input: RelayRateLimitInput): Promise<unknown>;\n}\n\nexport async function assertWithinRateLimit(\n limiter: RelayRateLimiter | undefined,\n input: RelayRateLimitInput,\n): Promise<void> {\n if (!limiter) return;\n let verdict: unknown;\n try {\n verdict = await limiter.check(input);\n } catch {\n return relayFailure(\"relay_rate_limited\", \"rate limiter is unreadable\");\n }\n if (verdict !== \"allowed\") {\n return relayFailure(\"relay_rate_limited\", \"rate limiter rejected the call\");\n }\n}\n","/**\n * Fetch-standard relay handler.\n *\n * Every wire input is exact-captured once here and handed to a use case as typed\n * data. Every failure leaves as a structured code projected to a status; no\n * message text, driver output, or internal detail reaches a response body.\n *\n * Endpoints:\n *\n * ```text\n * POST /authorization/requests client create request\n * GET /authorization/requests/{requestId} owner fetch request\n * POST /authorization/requests/{requestId}/decision owner approve or reject\n * GET /authorization/requests/{requestId}/code client released-code pickup\n * POST /authorization/codes/consume client one-time code consume\n * POST /authorization/artifacts/{artifactId}/claim client one-time artifact claim\n * POST /authorization/resume client fresh auth + recovery read\n * GET /bootstrap client URL-only service context\n * POST /invalidations client capability invalidation\n * POST /chains/{chainId}/{port} client chain execution relay,\n * port in reads |\n * observation | bundler |\n * quote | submissions | usage\n * POST /chains/{chainId}/paymaster/{method} client registered paymaster proxy,\n * method in stub-data | data\n * ```\n *\n * EXPERIMENTAL PREVIEW routes for the owner-phone approval surface. Preview\n * means: no stability guarantee and no production qualification. Their wire\n * shapes are pinned field-for-field by the strict Swift decoders in\n * `native/ios/Sources/OwnerPhone/{Projection,Decision}.swift`.\n *\n * ```text\n * GET /native/projections/{operationId} owner consent projection\n * POST /native/decisions/{operationId} owner approve or reject saga\n * ```\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport {\n type CaptureContext,\n captureDenseArray,\n captureRecord,\n exactCapturedRecord,\n OAATH_SERVICE_BOOTSTRAP_VERSION,\n parseServiceBootstrap,\n type ServiceBootstrap,\n} from \"@oaath/protocol\";\nimport { claimEncryptedArtifact } from \"../artifact/claim.js\";\nimport { consumeAuthorizationCode } from \"../authorization/code.js\";\nimport type { AuthorizationDecisionCommand } from \"../authorization/decision.js\";\nimport { submitAuthorizationDecision } from \"../authorization/decision.js\";\nimport { fetchAuthorizationCode } from \"../authorization/pickup.js\";\nimport {\n type AuthorizationState,\n createAuthorizationRequest,\n fetchAuthorizationRequest,\n} from \"../authorization/request.js\";\nimport { resumeAuthorization } from \"../authorization/resume.js\";\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { submitOwnerPhoneDecision } from \"../native/decision.js\";\nimport { projectOwnerPhoneRequest } from \"../native/projection.js\";\nimport {\n authenticateCaller,\n type RelayAuthentication,\n type RelayCaller,\n type RelayCallerRole,\n} from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport { assertWithinRateLimit, type RelayRateLimiter } from \"../security/rate-limit.js\";\nimport type { RelaySessionSignerProvider } from \"../session-signer/kms-provider.js\";\nimport { type RelayStore, withRelayTransaction } from \"../store/interface.js\";\nimport {\n boundedText,\n canonicalIdentifier,\n OAATH_CAPABILITY_INVALIDATION_RECORD_VERSION,\n RELAY_LIMITS,\n timestamp,\n} from \"../store/records.js\";\nimport { jsonResponse, relayErrorCode, relayErrorResponse, relayFailure } from \"./errors.js\";\n\nconst DEFAULT_REQUEST_TTL_MS = 300_000;\nconst DEFAULT_CODE_TTL_MS = 60_000;\nconst DEFAULT_MAX_BODY_BYTES = 65_536;\nconst MAX_TTL_MS = 86_400_000;\n/** RFC 6749 ceiling, matching `MAX_AUTHORIZATION_CODE_LIFETIME` in @oaath/protocol. */\nconst MAX_CODE_TTL_MS = 600_000;\nconst MAX_PAYMASTER_REQUEST_TIMEOUT_MS = 30_000;\nconst HASH = /^0x[0-9a-f]{64}$/u;\n\nconst INVALID = \"relay_request_invalid\" as const;\n\n/**\n * One deployment-injected chain execution surface the relay serves to clients.\n * Each port takes exactly one captured request value and answers with the\n * evidence it owns; the relay never interprets the payload beyond exact wire\n * hygiene, so port meaning stays with its SDK owner.\n */\nexport interface RelayChainPort {\n readonly chainId: number;\n readonly reads: (request: unknown) => Promise<unknown>;\n readonly observation: (request: unknown) => Promise<unknown>;\n readonly bundler: (request: unknown) => Promise<unknown>;\n readonly quote: (request: unknown) => Promise<unknown>;\n /** Opens, sends, and settles one submission in one call; never retried here. */\n readonly submission: (request: unknown) => Promise<unknown>;\n /** Finalized per-grant usage evidence, or null when this chain serves none. */\n readonly usage: ((request: unknown) => Promise<unknown>) | null;\n readonly feePayer: Readonly<{ address: `0x${string}`; balance: string }> | null;\n /** Authenticated commitment to one exact ERC-7902 static paymaster, or null. */\n readonly staticPaymasterConfigurationHash: `0x${string}` | null;\n}\n\n/** The identity facts `GET /bootstrap` serves; chains derive from `chains`. */\nexport interface RelayBootstrapConfiguration {\n readonly application: unknown;\n readonly userHandle: string;\n readonly account: unknown;\n readonly ownerValidator: `0x${string}` | null;\n}\n\n/**\n * Remote session-key custody, declared once for the deployment: the mode and\n * provider identity are served through the bootstrap document, and the same\n * provider answers the `/session-signers` routes. For `oaath_hosted` the\n * provider is typically `createKmsSessionSignerProvider`; for\n * `application_backend` it is the deployment's own authenticated port to the\n * integrating application's signer — never a client-supplied endpoint.\n */\nexport interface RelaySessionSignerConfiguration {\n readonly mode: \"application_backend\" | \"oaath_hosted\";\n readonly providerId: string;\n readonly provider: Readonly<RelaySessionSignerProvider>;\n}\n\n/** Authenticated identity and one opaque ERC-7677 params tuple. */\nexport interface RelayPaymasterServiceRequest {\n readonly caller: Readonly<{ clientId: string; subject: string }>;\n readonly params: unknown;\n readonly signal: AbortSignal;\n}\n\n/**\n * One deployment-owned paymaster provider. The relay exposes only these two\n * closed ERC-7677 operations and invokes the selected method once.\n */\nexport interface RelayPaymasterServiceProvider {\n readonly getPaymasterStubData: (\n request: Readonly<RelayPaymasterServiceRequest>,\n ) => Promise<unknown>;\n readonly getPaymasterData: (request: Readonly<RelayPaymasterServiceRequest>) => Promise<unknown>;\n}\n\nexport interface RelayPaymasterServiceConfiguration {\n readonly chainId: number;\n readonly providerId: string;\n /** Hard response deadline; the provider also receives its abort signal. */\n readonly requestTimeoutMs: number;\n readonly provider: Readonly<RelayPaymasterServiceProvider>;\n}\n\nexport interface RelayHandlerOptions {\n readonly store: RelayStore;\n readonly authentication: RelayAuthentication;\n readonly kms: RelayKms;\n readonly clock: RelayClock;\n /** Optional. There is no default limiter. */\n readonly rateLimit?: RelayRateLimiter;\n readonly requestTtlMs?: number;\n readonly codeTtlMs?: number;\n readonly maxBodyBytes?: number;\n /** Optional URL-only bootstrap surface; requires `chains` as well. */\n readonly bootstrap?: Readonly<RelayBootstrapConfiguration>;\n /** Optional chain execution relays; required when `bootstrap` is served. */\n readonly chains?: readonly Readonly<RelayChainPort>[];\n /** Optional remote session-key custody; requires `bootstrap` as well. */\n readonly sessionSigner?: Readonly<RelaySessionSignerConfiguration>;\n /**\n * Optional deployment-owned paymaster services, at most one per chain.\n * Configuration requires both bootstrap and a deployment rate limiter.\n */\n readonly paymasterServices?: readonly Readonly<RelayPaymasterServiceConfiguration>[];\n}\n\nexport type RelayHandler = (request: Request) => Promise<Response>;\n\nconst OPTION_KEYS: readonly string[] = [\n \"store\",\n \"authentication\",\n \"kms\",\n \"clock\",\n \"rateLimit\",\n \"requestTtlMs\",\n \"codeTtlMs\",\n \"maxBodyBytes\",\n \"bootstrap\",\n \"chains\",\n \"sessionSigner\",\n \"paymasterServices\",\n];\n\nconst CHAIN_PORT_NAMES = [\"reads\", \"observation\", \"bundler\", \"quote\", \"submission\"] as const;\ntype ChainPortName = (typeof CHAIN_PORT_NAMES)[number] | \"usage\";\n\n/**\n * The Grant a chain port request acts for, where the port's contract names\n * one: a submission's prepared operation and a usage read both carry it.\n * Reading it here is bounded extraction for the invalidation gate, not\n * interpretation — the port's own owner still captures the payload exactly.\n */\nfunction chainRequestGrantId(name: ChainPortName, request: unknown): string | null {\n try {\n if (name === \"usage\") {\n const grantId = (request as { readonly grantId?: unknown } | null)?.grantId;\n return typeof grantId === \"string\" && grantId.length > 0 ? grantId : null;\n }\n if (name === \"submission\") {\n const prepared = (request as { readonly prepared?: unknown } | null)?.prepared;\n const grantId = (prepared as { readonly grantId?: unknown } | null)?.grantId;\n return typeof grantId === \"string\" && grantId.length > 0 ? grantId : null;\n }\n } catch {\n // A hostile getter reads as absent; the port's exact capture still owns\n // whether such a payload is usable at all.\n }\n return null;\n}\n\n/**\n * Ports may be class instances, so only their required capabilities are checked.\n * Narrowing follows the runtime check.\n */\nfunction requirePort<Port>(value: unknown, methods: readonly string[], label: string): Port {\n if (!value || typeof value !== \"object\") {\n return relayFailure(\"relay_internal\", `${label} must be an object`);\n }\n for (const method of methods) {\n if (typeof (value as Record<string, unknown>)[method] !== \"function\") {\n return relayFailure(\"relay_internal\", `${label} must implement ${method}()`);\n }\n }\n return value as Port;\n}\n\nfunction duration(value: unknown, fallback: number, label: string, maximum = MAX_TTL_MS): number {\n if (value === undefined) return fallback;\n const milliseconds = timestamp(value, label, \"relay_internal\");\n if (milliseconds < 1 || milliseconds > maximum) {\n return relayFailure(\"relay_internal\", `${label} must be a bounded positive duration`);\n }\n return milliseconds;\n}\n\ninterface CapturedOptions {\n readonly store: RelayStore;\n readonly authentication: RelayAuthentication;\n readonly kms: RelayKms;\n readonly clock: RelayClock;\n readonly rateLimit: RelayRateLimiter | undefined;\n readonly requestTtlMs: number;\n readonly codeTtlMs: number;\n readonly maxBodyBytes: number;\n /** The exact parsed document `GET /bootstrap` serves, or null when unserved. */\n readonly bootstrap: Readonly<ServiceBootstrap> | null;\n readonly sessionSigner: Readonly<RelaySessionSignerConfiguration> | null;\n readonly chains: ReadonlyMap<number, Readonly<RelayChainPort>>;\n readonly paymasterServices: ReadonlyMap<number, Readonly<RelayPaymasterServiceConfiguration>>;\n}\n\nfunction captureChainPorts(value: unknown): ReadonlyMap<number, Readonly<RelayChainPort>> {\n if (!Array.isArray(value)) {\n return relayFailure(\"relay_internal\", \"chains must be an array of chain ports\");\n }\n const chains = new Map<number, Readonly<RelayChainPort>>();\n for (const entry of value) {\n const port = requirePort<RelayChainPort>(entry, [...CHAIN_PORT_NAMES], \"chain port\");\n if (\n typeof port.chainId !== \"number\" ||\n !Number.isSafeInteger(port.chainId) ||\n port.chainId < 1\n ) {\n return relayFailure(\"relay_internal\", \"chain port chainId must be a positive integer\");\n }\n if (port.usage !== null && typeof port.usage !== \"function\") {\n return relayFailure(\"relay_internal\", \"chain port usage must be a function or null\");\n }\n if (\n port.staticPaymasterConfigurationHash !== null &&\n (typeof port.staticPaymasterConfigurationHash !== \"string\" ||\n !HASH.test(port.staticPaymasterConfigurationHash))\n ) {\n return relayFailure(\n \"relay_internal\",\n \"chain port static paymaster commitment must be a lowercase hash or null\",\n );\n }\n if (chains.has(port.chainId)) {\n return relayFailure(\"relay_internal\", \"chain ports repeat a chainId\");\n }\n chains.set(port.chainId, port);\n }\n return chains;\n}\n\nfunction capturePaymasterServices(\n value: unknown,\n context: CaptureContext,\n chains: ReadonlyMap<number, Readonly<RelayChainPort>>,\n): ReadonlyMap<number, Readonly<RelayPaymasterServiceConfiguration>> {\n if (value === undefined) return new Map();\n const entries = captureDenseArray(value, \"paymaster services\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n );\n const services = new Map<number, Readonly<RelayPaymasterServiceConfiguration>>();\n for (const entry of entries) {\n const service = exactCapturedRecord(\n captureRecord(entry, \"paymaster service\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n ),\n [\"chainId\", \"providerId\", \"requestTimeoutMs\", \"provider\"],\n \"paymaster service\",\n (message) => relayFailure(\"relay_internal\", message),\n );\n const chainId = service.chainId;\n if (typeof chainId !== \"number\" || !Number.isSafeInteger(chainId) || chainId < 1) {\n relayFailure(\"relay_internal\", \"paymaster service chainId must be a positive integer\");\n }\n if (!chains.has(chainId)) {\n relayFailure(\"relay_internal\", \"paymaster service chain is not configured\");\n }\n if (services.has(chainId)) {\n relayFailure(\"relay_internal\", \"paymaster services repeat a chainId\");\n }\n if (service.requestTimeoutMs === undefined) {\n relayFailure(\"relay_internal\", \"paymaster requestTimeoutMs is required\");\n }\n services.set(\n chainId,\n Object.freeze({\n chainId,\n providerId: canonicalIdentifier(\n service.providerId,\n \"paymaster providerId\",\n \"relay_internal\",\n ),\n requestTimeoutMs: duration(\n service.requestTimeoutMs,\n 0,\n \"paymaster requestTimeoutMs\",\n MAX_PAYMASTER_REQUEST_TIMEOUT_MS,\n ),\n provider: requirePort<RelayPaymasterServiceProvider>(\n service.provider,\n [\"getPaymasterStubData\", \"getPaymasterData\"],\n \"paymaster provider\",\n ),\n }),\n );\n }\n return services;\n}\n\nfunction captureOptions(value: unknown): CapturedOptions {\n const context: CaptureContext = new WeakSet();\n const record = captureRecord(value, \"relay handler options\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n );\n for (const key of Object.keys(record)) {\n if (!OPTION_KEYS.includes(key)) {\n relayFailure(\"relay_internal\", \"relay handler options contain an unknown field\");\n }\n }\n const chains =\n record.chains === undefined\n ? new Map<number, Readonly<RelayChainPort>>()\n : captureChainPorts(record.chains);\n const rateLimit =\n record.rateLimit === undefined\n ? undefined\n : requirePort<RelayRateLimiter>(record.rateLimit, [\"check\"], \"rateLimit\");\n const paymasterServices = capturePaymasterServices(record.paymasterServices, context, chains);\n if (paymasterServices.size > 0) {\n if (record.bootstrap === undefined) {\n relayFailure(\"relay_internal\", \"a paymaster service requires a bootstrap surface\");\n }\n if (rateLimit === undefined) {\n relayFailure(\"relay_internal\", \"a paymaster service requires a rate limiter\");\n }\n }\n let sessionSigner: Readonly<RelaySessionSignerConfiguration> | null = null;\n if (record.sessionSigner !== undefined) {\n if (record.bootstrap === undefined) {\n relayFailure(\"relay_internal\", \"a session signer requires a bootstrap surface\");\n }\n const custody = captureRecord(\n record.sessionSigner,\n \"relay session signer configuration\",\n context,\n (message) => relayFailure(\"relay_internal\", message),\n );\n if (custody.mode !== \"application_backend\" && custody.mode !== \"oaath_hosted\") {\n relayFailure(\"relay_internal\", \"session signer mode is unsupported\");\n }\n if (typeof custody.providerId !== \"string\" || custody.providerId.length < 1) {\n relayFailure(\"relay_internal\", \"session signer providerId is invalid\");\n }\n sessionSigner = Object.freeze({\n mode: custody.mode as \"application_backend\" | \"oaath_hosted\",\n providerId: custody.providerId,\n provider: requirePort<RelaySessionSignerProvider>(\n custody.provider,\n [\"credential\", \"sign\"],\n \"session signer provider\",\n ),\n });\n }\n let bootstrap: Readonly<ServiceBootstrap> | null = null;\n if (record.bootstrap !== undefined) {\n if (chains.size === 0) {\n relayFailure(\"relay_internal\", \"a bootstrap surface requires chain ports\");\n }\n const identity = captureRecord(\n record.bootstrap,\n \"relay bootstrap configuration\",\n context,\n (message) => relayFailure(\"relay_internal\", message),\n );\n // The exact protocol parser owns document meaning; a misconfigured\n // deployment fails at construction, never at a client's request.\n try {\n bootstrap = parseServiceBootstrap({\n version: OAATH_SERVICE_BOOTSTRAP_VERSION,\n application: identity.application,\n userHandle: identity.userHandle,\n account: identity.account,\n ownerValidator: identity.ownerValidator,\n chains: [...chains.values()].map((port) => {\n const paymasterService = paymasterServices.get(port.chainId);\n return {\n chainId: port.chainId,\n usage: port.usage !== null,\n feePayer: port.feePayer,\n paymasterService:\n paymasterService === undefined ? null : { providerId: paymasterService.providerId },\n staticPaymasterConfigurationHash: port.staticPaymasterConfigurationHash,\n };\n }),\n // The one custody declaration serves both the document and the\n // signing routes; they can never disagree.\n sessionSigner:\n sessionSigner === null\n ? { mode: \"frontend\", providerId: null }\n : { mode: sessionSigner.mode, providerId: sessionSigner.providerId },\n });\n } catch {\n relayFailure(\"relay_internal\", \"relay bootstrap configuration is invalid\");\n }\n }\n return Object.freeze({\n store: requirePort<RelayStore>(record.store, [\"begin\", \"close\"], \"store\"),\n authentication: requirePort<RelayAuthentication>(\n record.authentication,\n [\"authenticate\"],\n \"authentication\",\n ),\n kms: requirePort<RelayKms>(record.kms, [\"encrypt\", \"decrypt\"], \"kms\"),\n clock: requirePort<RelayClock>(record.clock, [\"now\"], \"clock\"),\n rateLimit,\n requestTtlMs: duration(record.requestTtlMs, DEFAULT_REQUEST_TTL_MS, \"requestTtlMs\"),\n codeTtlMs: duration(record.codeTtlMs, DEFAULT_CODE_TTL_MS, \"codeTtlMs\", MAX_CODE_TTL_MS),\n maxBodyBytes: duration(record.maxBodyBytes, DEFAULT_MAX_BODY_BYTES, \"maxBodyBytes\"),\n bootstrap,\n sessionSigner,\n chains,\n paymasterServices,\n });\n}\n\nfunction requireMethod(request: Request, expected: \"GET\" | \"POST\"): void {\n if (request.method !== expected) {\n relayFailure(\"relay_method_not_allowed\", \"route does not accept this method\");\n }\n}\n\nasync function bodyRecord(\n request: Request,\n maxBodyBytes: number,\n): Promise<Record<string, unknown>> {\n const contentType = request.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().startsWith(\"application/json\")) {\n relayFailure(INVALID, \"request body must be application/json\");\n }\n let text: string;\n try {\n text = await request.text();\n } catch {\n return relayFailure(INVALID, \"request body is unreadable\");\n }\n if (new TextEncoder().encode(text).byteLength > maxBodyBytes) {\n return relayFailure(INVALID, \"request body exceeds its bound\");\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n return relayFailure(INVALID, \"request body is not JSON\");\n }\n const context: CaptureContext = new WeakSet();\n return captureRecord(parsed, \"request body\", context, (message) =>\n relayFailure(INVALID, message),\n );\n}\n\nfunction exactBody(\n record: Record<string, unknown>,\n keys: readonly string[],\n): Record<string, unknown> {\n return exactCapturedRecord(record, keys, \"request body\", (message) =>\n relayFailure(INVALID, message),\n );\n}\n\nasync function invokePaymasterService(\n service: Readonly<RelayPaymasterServiceConfiguration>,\n method: \"stub-data\" | \"data\",\n caller: Readonly<RelayCaller>,\n params: unknown,\n): Promise<unknown> {\n const controller = new AbortController();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const deadline = new Promise<never>((_resolve, reject) => {\n timeout = setTimeout(() => {\n controller.abort();\n reject(new Error(\"paymaster request deadline elapsed\"));\n }, service.requestTimeoutMs);\n });\n const capability =\n method === \"stub-data\"\n ? service.provider.getPaymasterStubData\n : service.provider.getPaymasterData;\n const request: Readonly<RelayPaymasterServiceRequest> = Object.freeze({\n caller: Object.freeze({ clientId: caller.clientId, subject: caller.subject }),\n params,\n signal: controller.signal,\n });\n return await Promise.race([\n Promise.resolve(Reflect.apply(capability, undefined, [request])),\n deadline,\n ]);\n } catch {\n return relayFailure(\"relay_chain_unavailable\", \"paymaster provider did not answer\");\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n }\n}\n\nfunction decisionCommand(record: Record<string, unknown>): AuthorizationDecisionCommand {\n if (record.outcome === \"approved\") {\n const exact = exactBody(record, [\"outcome\", \"artifact\"]);\n return Object.freeze({\n outcome: \"approved\",\n artifact: boundedText(exact.artifact, RELAY_LIMITS.artifactPlaintext, \"artifact\", INVALID),\n });\n }\n if (record.outcome === \"rejected\") {\n exactBody(record, [\"outcome\"]);\n return Object.freeze({ outcome: \"rejected\" });\n }\n return relayFailure(INVALID, \"decision outcome is unsupported\");\n}\n\n/**\n * EXPERIMENTAL PREVIEW — the phone decision body: `{command, artifact?}`.\n * `approve` hands over the artifact the client will claim once; `reject`\n * carries nothing else. The saga answers the stored outcome on a replay.\n */\nfunction phoneDecisionCommand(record: Record<string, unknown>): AuthorizationDecisionCommand {\n if (record.command === \"approve\") {\n const exact = exactBody(record, [\"command\", \"artifact\"]);\n return Object.freeze({\n outcome: \"approved\",\n artifact: boundedText(exact.artifact, RELAY_LIMITS.artifactPlaintext, \"artifact\", INVALID),\n });\n }\n if (record.command === \"reject\") {\n exactBody(record, [\"command\"]);\n return Object.freeze({ outcome: \"rejected\" });\n }\n return relayFailure(INVALID, \"decision command is unsupported\");\n}\n\nfunction stateBody(state: AuthorizationState): unknown {\n return {\n requestId: state.requestId,\n clientId: state.clientId,\n redirectUri: state.redirectUri,\n requestedScope: state.requestedScope,\n expiresAt: state.expiresAt,\n expired: state.expired,\n decision: state.decision,\n };\n}\n\nexport function createRelayHandler(options: RelayHandlerOptions): RelayHandler {\n const captured = captureOptions(options);\n\n const authenticate = async (\n request: Request,\n role: RelayCallerRole | readonly RelayCallerRole[],\n route: string,\n ): Promise<RelayCaller> => {\n const caller = await authenticateCaller(captured.authentication, request, role);\n // Limiting happens after authentication so a deployment can key on clientId.\n // The authentication port owns unauthenticated abuse.\n await assertWithinRateLimit(captured.rateLimit, { route, clientId: caller.clientId });\n return caller;\n };\n\n const route = async (request: Request): Promise<Response> => {\n const segments = new URL(request.url).pathname.split(\"/\").filter((part) => part.length > 0);\n const [head, group, third, fourth] = segments;\n\n // EXPERIMENTAL PREVIEW — owner-phone approval routes. Same wire hygiene as\n // every relay route: exact capture, structured codes, no-store responses.\n if (head === \"native\") {\n if (segments.length === 3 && group === \"projections\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"native.project\");\n const projection = await projectOwnerPhoneRequest({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(third, \"operationId\", INVALID),\n });\n return jsonResponse(200, projection);\n }\n if (segments.length === 3 && group === \"decisions\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"owner\", \"native.decide\");\n const command = phoneDecisionCommand(await bodyRecord(request, captured.maxBodyBytes));\n const decided = await submitOwnerPhoneDecision({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n operationId: canonicalIdentifier(third, \"operationId\", INVALID),\n command,\n codeTtlMs: captured.codeTtlMs,\n });\n return jsonResponse(200, decided);\n }\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (head === \"bootstrap\" && segments.length === 1) {\n requireMethod(request, \"GET\");\n await authenticate(request, \"client\", \"bootstrap.fetch\");\n if (captured.bootstrap === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n return jsonResponse(200, captured.bootstrap);\n }\n\n if (head === \"session-signers\") {\n // Remote session-key custody routes, served exactly when the deployment\n // declared it. The caller's authenticated identity — never anything the\n // body claims — names the key: one (clientId, subject, deviceId)\n // identity holds one credential, so a different credential can never\n // sign under an approval that bound this one (the rotation invariant).\n const custody = captured.sessionSigner;\n if (custody === null) return relayFailure(\"relay_not_found\", \"route does not exist\");\n if (segments.length === 1) {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"session-signers.credential\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"deviceId\"]);\n const deviceId = boundedText(body.deviceId, 256, \"session signer deviceId\", INVALID);\n let credential: unknown;\n try {\n credential = await custody.provider.credential({\n clientId: caller.clientId,\n subject: caller.subject,\n deviceId,\n });\n } catch {\n return relayFailure(\"relay_internal\", \"session signer provider did not answer\");\n }\n return jsonResponse(200, { operatorCredential: credential });\n }\n if (segments.length === 2 && group === \"signatures\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"session-signers.sign\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"deviceId\",\n \"hash\",\n ]);\n const deviceId = boundedText(body.deviceId, 256, \"session signer deviceId\", INVALID);\n // One exact 32-byte hash; the provider signs an identity, never a\n // message it interprets.\n if (typeof body.hash !== \"string\" || !/^0x[0-9a-f]{64}$/u.test(body.hash)) {\n return relayFailure(INVALID, \"session signer hash must be one exact 32-byte hash\");\n }\n let signature: unknown;\n try {\n signature = await custody.provider.sign({\n clientId: caller.clientId,\n subject: caller.subject,\n deviceId,\n hash: body.hash as `0x${string}`,\n });\n } catch {\n return relayFailure(\"relay_internal\", \"session signer provider did not answer\");\n }\n return jsonResponse(200, { signature });\n }\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (head === \"invalidations\" && segments.length === 1) {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"invalidations.create\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"grantId\",\n \"capabilityHash\",\n ]);\n const grantId = canonicalIdentifier(body.grantId, \"grantId\", INVALID);\n const capabilityHash = boundedText(body.capabilityHash, 66, \"capabilityHash\", INVALID);\n if (!/^0x[0-9a-f]{64}$/u.test(capabilityHash)) {\n return relayFailure(INVALID, \"capabilityHash must be a lowercase 32-byte hash\");\n }\n // Durable and enforced: from the committed record on, every chain\n // execution route below refuses this Grant, so the evidence states an\n // enforced fact — this service will no longer act for the capability.\n // Consuming the on-chain install nonce stays the chain-local revocation\n // operation's separate evidence. Replays answer the stored record, so\n // one Grant has exactly one invalidation time.\n const record = await withRelayTransaction(captured.store, async (transaction) => {\n const existing = await transaction.lockCapabilityInvalidation(grantId);\n if (existing) {\n if (existing.clientId !== caller.clientId) {\n // Reported as absence: not an existence oracle for another\n // client's Grant.\n return relayFailure(\"relay_not_found\", \"grant does not exist\");\n }\n return existing;\n }\n const created = Object.freeze({\n version: OAATH_CAPABILITY_INVALIDATION_RECORD_VERSION,\n grantId,\n clientId: caller.clientId,\n capabilityHash,\n invalidatedAt: relayNow(captured.clock),\n });\n if (!(await transaction.insertCapabilityInvalidation(created))) {\n return relayFailure(\"relay_internal\", \"capability invalidation did not commit\");\n }\n return created;\n });\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(\n `oaath-relay-invalidation:v1:${record.clientId}:${record.grantId}:${record.capabilityHash}:${record.invalidatedAt}`,\n ),\n );\n const evidenceHash = `0x${[...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n // The evidence is protocol-facing, so it speaks the protocol's seconds\n // domain rather than the relay's millisecond records.\n return jsonResponse(200, {\n evidenceHash,\n invalidatedAt: Math.floor(record.invalidatedAt / 1_000),\n });\n }\n\n if (head === \"chains\" && segments.length === 4 && third === \"paymaster\") {\n requireMethod(request, \"POST\");\n const service = captured.paymasterServices.get(Number(group));\n const method = fourth === \"stub-data\" || fourth === \"data\" ? fourth : null;\n if (service === undefined || method === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n const caller = await authenticate(request, \"client\", `chains.paymaster.${method}`);\n // The route selects the deployment-owned provider. An application URL\n // is never accepted in this body and therefore can never become a fetch\n // target here.\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"params\"]);\n const result = await invokePaymasterService(service, method, caller, body.params);\n return jsonResponse(\n 200,\n result === undefined ? { present: false, result: null } : { present: true, result },\n );\n }\n\n if (head === \"chains\") {\n if (segments.length !== 3) return relayFailure(\"relay_not_found\", \"route does not exist\");\n requireMethod(request, \"POST\");\n const port = captured.chains.get(Number(group));\n const name: ChainPortName | null =\n third === \"submissions\"\n ? \"submission\"\n : third === \"reads\" ||\n third === \"observation\" ||\n third === \"bundler\" ||\n third === \"quote\" ||\n third === \"usage\"\n ? third\n : null;\n if (!port || name === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n // Submissions also accept the owner role: the owner-signed revocation\n // operation is what removes an installed chain permission, so the\n // owner's console must be able to submit it after the capability died.\n const caller = await authenticate(\n request,\n name === \"submission\" ? [\"client\", \"owner\"] : \"client\",\n `chains.${name}`,\n );\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"request\"]);\n const capability = name === \"usage\" ? port.usage : port[name];\n if (capability === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n // Recorded invalidations are enforced here: a submission or usage read\n // that names an invalidated Grant is refused before its port runs. The\n // ports whose requests carry no Grant identity are chain reads, which\n // grant nothing. This guards the honest capability; the on-chain install\n // nonce is what a hostile holder must still be cut off from, by the\n // chain-local revocation operation.\n //\n // The one pass through the gate is the caller's PROVEN owner role —\n // never a payload claim, which any gated client could spoof to keep\n // spending relay, RPC, and fee-payer budget after invalidation.\n const grantId = caller.role === \"owner\" ? null : chainRequestGrantId(name, body.request);\n if (grantId !== null) {\n const invalidated = await withRelayTransaction(captured.store, (transaction) =>\n transaction.lockCapabilityInvalidation(grantId),\n );\n if (invalidated !== undefined) {\n return relayFailure(\n \"relay_capability_invalidated\",\n \"the Grant's capability is invalidated\",\n );\n }\n }\n let result: unknown;\n try {\n result = await capability(body.request);\n } catch {\n // Port meaning stays with its SDK owner; the relay reports only that\n // this chain surface did not answer. Nothing here retries.\n return relayFailure(\"relay_chain_unavailable\", \"chain port did not answer\");\n }\n // JSON cannot carry `undefined`, and several ports mean it (\"no such\n // fact\"), so the envelope states presence explicitly.\n return jsonResponse(\n 200,\n result === undefined ? { present: false, result: null } : { present: true, result },\n );\n }\n\n if (head !== \"authorization\") {\n relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (segments.length === 2 && group === \"requests\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.create\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"redirectUri\",\n \"codeChallenge\",\n \"requestedScope\",\n ]);\n const created = await createAuthorizationRequest({\n store: captured.store,\n clock: captured.clock,\n caller,\n redirectUri: boundedText(\n body.redirectUri,\n RELAY_LIMITS.redirectUri,\n \"redirectUri\",\n INVALID,\n ),\n codeChallenge: boundedText(\n body.codeChallenge,\n RELAY_LIMITS.codeChallenge,\n \"codeChallenge\",\n INVALID,\n ),\n requestedScope: boundedText(\n body.requestedScope,\n RELAY_LIMITS.requestedScope,\n \"requestedScope\",\n INVALID,\n ),\n requestTtlMs: captured.requestTtlMs,\n });\n return jsonResponse(201, created);\n }\n\n if (segments.length === 3 && group === \"requests\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"authorization.fetch\");\n const state = await fetchAuthorizationRequest({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n });\n return jsonResponse(200, stateBody(state));\n }\n\n if (segments.length === 4 && group === \"requests\" && fourth === \"decision\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"owner\", \"authorization.decide\");\n const command = decisionCommand(await bodyRecord(request, captured.maxBodyBytes));\n const decided = await submitAuthorizationDecision({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n command,\n codeTtlMs: captured.codeTtlMs,\n });\n return jsonResponse(200, decided);\n }\n\n if (segments.length === 4 && group === \"requests\" && fourth === \"code\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"client\", \"authorization.code\");\n const fetched = await fetchAuthorizationCode({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n });\n return jsonResponse(200, fetched);\n }\n\n if (segments.length === 3 && group === \"codes\" && third === \"consume\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.consume\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"code\",\n \"codeVerifier\",\n \"redirectUri\",\n ]);\n const consumed = await consumeAuthorizationCode({\n store: captured.store,\n clock: captured.clock,\n caller,\n code: canonicalIdentifier(body.code, \"code\", INVALID),\n codeVerifier: boundedText(\n body.codeVerifier,\n RELAY_LIMITS.codeVerifier,\n \"codeVerifier\",\n INVALID,\n ),\n redirectUri: boundedText(\n body.redirectUri,\n RELAY_LIMITS.redirectUri,\n \"redirectUri\",\n INVALID,\n ),\n });\n return jsonResponse(200, consumed);\n }\n\n if (segments.length === 4 && group === \"artifacts\" && fourth === \"claim\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.claim\");\n const claimed = await claimEncryptedArtifact({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n artifactId: canonicalIdentifier(third, \"artifactId\", INVALID),\n });\n return jsonResponse(200, claimed);\n }\n\n if (segments.length === 2 && group === \"resume\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.resume\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"requestId\"]);\n const state = await resumeAuthorization({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(body.requestId, \"requestId\", INVALID),\n });\n return jsonResponse(200, stateBody(state));\n }\n\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n };\n\n return async (request: Request): Promise<Response> => {\n try {\n return await route(request);\n } catch (error) {\n return relayErrorResponse(relayErrorCode(error));\n }\n };\n}\n","/**\n * Bounded credential and URL redaction for diagnostics only.\n *\n * Nothing here shapes a response or a machine decision. Its only job is to make\n * an adopter's log line safe and finite: no authorization code, verifier, token,\n * artifact, ciphertext, credential-bearing URL, or unbounded provider blob.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nexport const REDACTED = \"[redacted]\";\nconst UNREADABLE_URL = \"[unreadable-url]\";\nconst TRUNCATED = \"[truncated]\";\n\nconst MAX_TEXT = 128;\nconst MAX_DEPTH = 3;\nconst MAX_ENTRIES = 16;\n\n/** Key names whose values are never safe to log, matched after normalization. */\nconst SENSITIVE_KEYS: ReadonlySet<string> = new Set([\n \"apikey\",\n \"artifact\",\n \"authorization\",\n \"bearer\",\n \"ciphertext\",\n \"ciphertextref\",\n \"clientsecret\",\n \"code\",\n \"codechallenge\",\n \"codeverifier\",\n \"cookie\",\n \"credential\",\n \"idtoken\",\n \"key\",\n \"password\",\n \"plaintext\",\n \"privatekey\",\n \"secret\",\n \"session\",\n \"sessionkey\",\n \"setcookie\",\n \"signature\",\n \"token\",\n \"verifier\",\n]);\n\nfunction normalizeKey(key: string): string {\n return key.toLowerCase().replaceAll(/[^a-z0-9]/gu, \"\");\n}\n\nfunction isUrlKey(normalized: string): boolean {\n return normalized.endsWith(\"url\") || normalized.endsWith(\"uri\");\n}\n\nfunction boundText(value: string): string {\n return value.length <= MAX_TEXT ? value : `${value.slice(0, MAX_TEXT)}${TRUNCATED}`;\n}\n\n/** Keeps scheme, host, and path. Drops userinfo, query, and fragment. */\nexport function redactUrl(value: unknown): string {\n if (typeof value !== \"string\") return UNREADABLE_URL;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return UNREADABLE_URL;\n }\n const port = url.port === \"\" ? \"\" : `:${url.port}`;\n return boundText(`${url.protocol}//${url.hostname}${port}${url.pathname}`);\n}\n\nfunction redactValue(value: unknown, depth: number): unknown {\n if (value === null) return null;\n switch (typeof value) {\n case \"string\":\n return boundText(value);\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"boolean\":\n return value;\n case \"bigint\":\n return boundText(value.toString());\n case \"object\":\n break;\n default:\n // Functions, symbols, and undefined carry no safe diagnostic value.\n return REDACTED;\n }\n if (depth >= MAX_DEPTH) return REDACTED;\n if (Array.isArray(value)) {\n const items = value.slice(0, MAX_ENTRIES).map((item) => redactValue(item, depth + 1));\n return value.length > MAX_ENTRIES ? [...items, TRUNCATED] : items;\n }\n if (value instanceof Error) {\n // Provider and driver messages routinely embed credentials and payloads.\n return { name: boundText(value.name), message: REDACTED };\n }\n return redactRecord(value as Record<string, unknown>, depth);\n}\n\nfunction redactRecord(value: Record<string, unknown>, depth: number): Record<string, unknown> {\n const redacted: Record<string, unknown> = {};\n let entries = 0;\n for (const key of Object.keys(value)) {\n if (entries >= MAX_ENTRIES) {\n redacted[TRUNCATED] = true;\n break;\n }\n entries += 1;\n const normalized = normalizeKey(key);\n if (SENSITIVE_KEYS.has(normalized)) {\n redacted[key] = REDACTED;\n } else if (isUrlKey(normalized)) {\n redacted[key] = redactUrl(value[key]);\n } else {\n redacted[key] = redactValue(value[key], depth + 1);\n }\n }\n return redacted;\n}\n\n/** Returns a bounded, credential-free projection safe to hand to a logger. */\nexport function redactForLog(value: unknown): unknown {\n return redactValue(value, 0);\n}\n","/**\n * Reference hosted session-signer provider: one KMS-sealed secp256k1 operator\n * key per authenticated `(clientId, subject, deviceId)` identity, signing one\n * exact 32-byte hash at a time.\n *\n * Custody boundary: the private scalar exists in plaintext only inside this\n * process during key generation and signing; at rest it is exactly one\n * KMS-sealed string. No route, log, or return value ever carries key material\n * — `credential` answers the public operator profile and `sign` answers one\n * 65-byte ECDSA signature.\n *\n * Rotation invariant: one identity maps to one credential for this provider's\n * lifetime. There is no rotation path here — a new key requires a new\n * identity, and therefore a newly approved Grant; nothing can silently swap\n * the public key under an existing approval.\n *\n * Like `createMemoryRelayStore`, the in-memory registry makes this a\n * reference implementation, not a production durability claim: a deployment\n * that must survive restarts persists the sealed entries in its own store.\n *\n * @author taek <leekt216@gmail.com>\n */\nimport { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\nimport { OAATH_OPERATOR_CREDENTIAL_PROFILE_VERSION } from \"@oaath/protocol\";\nimport type { RelayKms } from \"../security/kms.js\";\n\nconst HASH = /^0x[0-9a-f]{64}$/u;\nconst MAX_IDENTITY_PART = 256;\n\nexport interface SessionSignerIdentity {\n readonly clientId: string;\n readonly subject: string;\n readonly deviceId: string;\n}\n\nexport interface SessionSignerSignRequest extends SessionSignerIdentity {\n /** The exact 32-byte hash to sign; never a message to interpret. */\n readonly hash: `0x${string}`;\n}\n\nexport interface RelaySessionSignerProvider {\n /**\n * The operator credential for one authenticated identity, creating the key\n * on first use. Idempotent: the same identity always answers the same\n * credential.\n */\n readonly credential: (request: Readonly<SessionSignerIdentity>) => Promise<unknown>;\n /** One ECDSA signature over one exact hash, under that identity's key. */\n readonly sign: (request: Readonly<SessionSignerSignRequest>) => Promise<unknown>;\n}\n\nfunction identityKey(request: Readonly<SessionSignerIdentity>): string {\n for (const part of [request.clientId, request.subject, request.deviceId]) {\n if (typeof part !== \"string\" || part.length < 1 || part.length > MAX_IDENTITY_PART) {\n throw new Error(\"session signer identity is invalid\");\n }\n }\n // JSON array form: no separator inside a part can collide two identities.\n return JSON.stringify([request.clientId, request.subject, request.deviceId]);\n}\n\nfunction addressOf(privateKey: Uint8Array): `0x${string}` {\n const publicKey = secp256k1.getPublicKey(privateKey, false);\n return `0x${bytesToHex(keccak_256(publicKey.slice(1)).slice(12))}`;\n}\n\nexport function createKmsSessionSignerProvider(input: {\n readonly kms: RelayKms;\n}): RelaySessionSignerProvider {\n const kms = input.kms;\n /** identity -> KMS-sealed private scalar; the only at-rest key form. */\n const sealed = new Map<string, string>();\n /** Serializes first-use creation so one identity never mints two keys. */\n const creating = new Map<string, Promise<string>>();\n\n async function sealedKeyFor(identity: string): Promise<string> {\n const existing = sealed.get(identity);\n if (existing !== undefined) return existing;\n const pending =\n creating.get(identity) ??\n (async () => {\n const scalar = secp256k1.utils.randomPrivateKey();\n const reference = String(await kms.encrypt(bytesToHex(scalar)));\n scalar.fill(0);\n sealed.set(identity, reference);\n return reference;\n })();\n creating.set(identity, pending);\n pending.finally(() => creating.delete(identity));\n return pending;\n }\n\n return Object.freeze({\n async credential(request: Readonly<SessionSignerIdentity>): Promise<unknown> {\n const identity = identityKey(request);\n const privateKey = hexToBytes(String(await kms.decrypt(await sealedKeyFor(identity))));\n try {\n return Object.freeze({\n version: OAATH_OPERATOR_CREDENTIAL_PROFILE_VERSION,\n kind: \"ecdsa\" as const,\n address: addressOf(privateKey),\n });\n } finally {\n privateKey.fill(0);\n }\n },\n async sign(request: Readonly<SessionSignerSignRequest>): Promise<unknown> {\n const identity = identityKey(request);\n if (typeof request.hash !== \"string\" || !HASH.test(request.hash)) {\n throw new Error(\"session signer hash must be one exact 32-byte hash\");\n }\n // Signing never creates a key: an identity that never fetched its\n // credential holds no approval that could authorize a signature.\n const reference = sealed.get(identity);\n if (reference === undefined) {\n throw new Error(\"session signer identity holds no credential\");\n }\n const privateKey = hexToBytes(String(await kms.decrypt(reference)));\n try {\n const signature = secp256k1.sign(hexToBytes(request.hash.slice(2)), privateKey, {\n lowS: true,\n });\n if (signature.recovery !== 0 && signature.recovery !== 1) {\n throw new Error(\"session signer produced an unusable signature\");\n }\n // 65-byte r ‖ s ‖ v with v in {27, 28}: the exact shape a locally held\n // viem account produces, so the Kernel-side validation is identical.\n return `0x${bytesToHex(signature.toCompactRawBytes())}${(27 + signature.recovery).toString(16)}`;\n } finally {\n privateKey.fill(0);\n }\n },\n });\n}\n","/**\n * In-memory relay store implementing the same transaction contract as\n * PostgreSQL. It is durable only for the life of the process: use it for local\n * development and tests, never for a deployment that must survive a restart.\n *\n * ponytail: one process-wide writer lock stands in for row locks. It is strictly\n * stronger than `SELECT ... FOR UPDATE`, so one-shot semantics are identical;\n * swap in per-row locks only if a single-process relay ever needs throughput.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayStore, RelayTransaction } from \"./interface.js\";\nimport {\n type AuthorizationCodeRecord,\n type AuthorizationDecisionRecord,\n type AuthorizationRequestRecord,\n type CapabilityInvalidationRecord,\n type EncryptedArtifactRecord,\n parseAuthorizationCodeRecord,\n parseAuthorizationDecisionRecord,\n parseAuthorizationRequestRecord,\n parseCapabilityInvalidationRecord,\n parseEncryptedArtifactRecord,\n} from \"./records.js\";\n\ninterface Tables {\n readonly requests: Map<string, unknown>;\n readonly decisions: Map<string, unknown>;\n readonly codes: Map<string, unknown>;\n readonly artifacts: Map<string, unknown>;\n readonly invalidations: Map<string, unknown>;\n}\n\nfunction emptyTables(): Tables {\n return {\n requests: new Map(),\n decisions: new Map(),\n codes: new Map(),\n artifacts: new Map(),\n invalidations: new Map(),\n };\n}\n\nfunction copyTables(tables: Tables): Tables {\n return {\n requests: new Map(tables.requests),\n decisions: new Map(tables.decisions),\n codes: new Map(tables.codes),\n artifacts: new Map(tables.artifacts),\n invalidations: new Map(tables.invalidations),\n };\n}\n\nfunction insert(table: Map<string, unknown>, key: string, record: unknown): boolean {\n if (table.has(key)) return false;\n table.set(key, record);\n return true;\n}\n\nfunction read<Value>(\n table: Map<string, unknown>,\n key: string,\n parse: (value: unknown) => Value,\n): Value | undefined {\n const stored = table.get(key);\n // Durable reads are re-validated here exactly as the SQL store validates rows.\n return stored === undefined ? undefined : parse(stored);\n}\n\nexport function createMemoryRelayStore(): RelayStore {\n let committed = emptyTables();\n let closed = false;\n let tail: Promise<void> = Promise.resolve();\n\n async function acquire(): Promise<() => void> {\n const prior = tail;\n let release = (): void => {};\n tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await prior;\n return release;\n }\n\n return {\n async begin(): Promise<RelayTransaction> {\n if (closed) relayFailure(\"relay_store_unavailable\", \"memory relay store is closed\");\n const release = await acquire();\n const staged = copyTables(committed);\n let settled = false;\n\n const open = (): Tables => {\n if (settled) relayFailure(\"relay_internal\", \"relay transaction already settled\");\n return staged;\n };\n const settle = (apply: boolean): void => {\n if (settled) relayFailure(\"relay_internal\", \"relay transaction already settled\");\n settled = true;\n if (apply) committed = staged;\n release();\n };\n\n return {\n async lockAuthorizationRequest(requestId) {\n return read(open().requests, requestId, parseAuthorizationRequestRecord);\n },\n async insertAuthorizationRequest(record: AuthorizationRequestRecord) {\n return insert(open().requests, record.requestId, record);\n },\n async lockAuthorizationDecision(requestId) {\n return read(open().decisions, requestId, parseAuthorizationDecisionRecord);\n },\n async insertAuthorizationDecision(record: AuthorizationDecisionRecord) {\n return insert(open().decisions, record.requestId, record);\n },\n async lockAuthorizationCode(codeHash) {\n return read(open().codes, codeHash, parseAuthorizationCodeRecord);\n },\n async insertAuthorizationCode(record: AuthorizationCodeRecord) {\n return insert(open().codes, record.codeHash, record);\n },\n async consumeAuthorizationCode(codeHash, consumedAt) {\n const codes = open().codes;\n const record = read(codes, codeHash, parseAuthorizationCodeRecord);\n if (!record || record.consumedAt !== null) return false;\n codes.set(codeHash, Object.freeze({ ...record, consumedAt }));\n return true;\n },\n async lockCapabilityInvalidation(grantId) {\n return read(open().invalidations, grantId, parseCapabilityInvalidationRecord);\n },\n async insertCapabilityInvalidation(record: CapabilityInvalidationRecord) {\n return insert(open().invalidations, record.grantId, record);\n },\n async lockEncryptedArtifact(artifactId) {\n return read(open().artifacts, artifactId, parseEncryptedArtifactRecord);\n },\n async insertEncryptedArtifact(record: EncryptedArtifactRecord) {\n return insert(open().artifacts, record.artifactId, record);\n },\n async claimEncryptedArtifact(artifactId, claimedAt) {\n const artifacts = open().artifacts;\n const record = read(artifacts, artifactId, parseEncryptedArtifactRecord);\n if (!record || record.claimedAt !== null) return false;\n artifacts.set(artifactId, Object.freeze({ ...record, claimedAt }));\n return true;\n },\n async commit() {\n settle(true);\n },\n async rollback() {\n if (!settled) settle(false);\n },\n };\n },\n async close(): Promise<void> {\n closed = true;\n committed = emptyTables();\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAuCA,eAAsB,uBACpB,OACmC;CACnC,MAAM,YAAY,SAAS,MAAM,KAAK;CACtC,MAAM,UAAU,MAAM,qBAAqB,MAAM,OAAO,OAAO,gBAAgB;EAC7E,MAAM,SAAS,MAAM,YAAY,sBAAsB,MAAM,UAAU;EAEvE,IAAI,CAAC,UAAU,OAAO,aAAa,MAAM,OAAO,UAC9C,OAAO,aAAa,mBAAmB,mCAAmC;EAE5E,IAAI,OAAO,cAAc,MACvB,aAAa,kCAAkC,wCAAwC;EAEzF,IAAI,CAAE,MAAM,YAAY,uBAAuB,MAAM,YAAY,SAAS,GACxE,aAAa,yBAAyB,iDAAiD;EAEzF,OAAO;CACT,CAAC;CACD,OAAO,OAAO,OAAO;EACnB,WAAW,QAAQ;EACnB,UAAU,MAAM,aAAa,MAAM,KAAK,QAAQ,aAAa;CAC/D,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;ACZA,eAAsB,yBACpB,OACoC;CACpC,MAAM,aAAa,SAAS,MAAM,KAAK;CACvC,MAAM,WAAW,MAAM,gBAAgB,MAAM,IAAI;CACjD,MAAM,cAAc,MAAM,MAAM,MAAM,MAAM;CAC5C,IAAI;CACJ,IAAI;EACF,MAAM,SAAS,MAAM,YAAY,sBAAsB,QAAQ;EAG/D,IAAI,CAAC,UAAU,OAAO,aAAa,MAAM,OAAO,UAC9C,aAAa,sBAAsB,sCAAsC;EAE3E,IAAI,OAAO,eAAe,MACxB,aAAa,+BAA+B,yCAAyC;EAEvF,IAAI,cAAc,OAAO,WAEvB,aAAa,iBAAiB,4BAA4B;EAE5D,MAAM,QACJ,OAAO,gBAAgB,MAAM,eAC5B,MAAM,eAAe,MAAM,cAAc,OAAO,aAAa;EAChE,IAAI,CAAE,MAAM,YAAY,yBAAyB,UAAU,UAAU,GACnE,aAAa,yBAAyB,mDAAmD;EAE3F,IAAI,CAAC,OAAO;GAGV,MAAM,YAAY,sBAAsB,OAAO,UAAU;GACzD,MAAM,YAAY,uBAAuB,OAAO,YAAY,UAAU;EACxE;EACA,UAAU,QACN,OAAO,OAAO;GACZ,MAAM;GACN,UAAU,OAAO,OAAO;IACtB,WAAW,OAAO;IAClB,YAAY,OAAO;GACrB,CAAC;EACH,CAAC,IACD,OAAO,OAAO;GAAE,MAAM;GAAU,MAAM;EAAqB,CAAC;CAClE,SAAS,OAAO;EACd,MAAM,YAAY,SAAS;EAC3B,MAAM;CACR;CAEA,MAAM,YAAY,OAAO;CACzB,IAAI,QAAQ,SAAS,UACnB,aAAa,QAAQ,MAAM,8DAA8D;CAE3F,OAAO,QAAQ;AACjB;;;;;;;;;;;;AC7EA,SAAgB,oBAAoB,OAA8D;CAChG,MAAM,MAAM,SAAS,MAAM,KAAK;CAChC,OAAO,qBAAqB,MAAM,QAAQ,gBACxC,uBACE,aACA,MAAM,WACN,MACC,YAAY,QAAQ,aAAa,MAAM,OAAO,QACjD,CACF;AACF;;;;;;;;;;;;;;;;;;;;;ACKA,eAAsB,uBACpB,OACmC;CACnC,MAAM,MAAM,SAAS,MAAM,KAAK;CAChC,MAAM,UAAU,MAAM,qBAAqB,MAAM,OAAO,OAAO,gBAAgB;EAC7E,MAAM,UAAU,MAAM,YAAY,yBAAyB,MAAM,SAAS;EAC1E,IAAI,CAAC,WAAW,QAAQ,aAAa,MAAM,OAAO,UAChD,OAAO,aAAa,mBAAmB,sCAAsC;EAE/E,MAAM,WAAW,MAAM,YAAY,0BAA0B,MAAM,SAAS;EAC5E,IAAI,CAAC,UAAU;GACb,IAAI,OAAO,QAAQ,WACjB,OAAO,aAAa,iBAAiB,+BAA+B;GAEtE,OAAO;EACT;EACA,OAAO;CACT,CAAC;CACD,IAAI,YAAY,MAAM,OAAO,OAAO,OAAO,EAAE,SAAS,UAAU,CAAC;CACjE,IAAI,QAAQ,YAAY,cAAc,QAAQ,YAAY,MACxD,OAAO,OAAO,OAAO;EAAE,SAAS;EAAY,WAAW,QAAQ;CAAU,CAAC;CAE5E,MAAM,gBAAgB,QAAQ,iBAAiB;CAC/C,IAAI,OAAO,eACT,OAAO,aAAa,iBAAiB,4BAA4B;CAGnE,OAAO,OAAO,OAAO;EACnB,SAAS;EACT,WAAW,QAAQ;EACnB,MAAM,MAAM,aAAa,MAAM,KAAK,QAAQ,OAAO;EACnD;CACF,CAAC;AACH;;;;;;;;;;;;ACvDA,MAAM,oBAAoB;AAuB1B,SAAS,cAAc,OAA6B;CAClD,MAAM,0BAA0B,IAAI,QAAQ;CAE5C,MAAM,QAAQ,YAA2B,aAAa,kBAAkB,OAAO;CAC/E,MAAM,SAAS,YACb,OACA;EAAC;EAAQ;EAAY;EAAW;CAAc,GAC9C,wBACA,SACA,IACF;CACA,IAAI,OAAO,SAAS,YAAY,OAAO,SAAS,SAC9C,OAAO,aAAa,kBAAkB,0CAA0C;CAElF,MAAM,eAAe,kBAAkB,OAAO,cAAc,uBAAuB,SAAS,IAAI;CAChG,IAAI,aAAa,SAAS,mBACxB,OAAO,aAAa,kBAAkB,kCAAkC;CAE1E,OAAO,OAAO,OAAO;EACnB,MAAM,OAAO;EACb,UAAU,oBAAoB,OAAO,UAAU,mBAAmB,gBAAgB;EAClF,SAAS,oBAAoB,OAAO,SAAS,kBAAkB,gBAAgB;EAC/E,cAAc,OAAO,OACnB,aAAa,KAAK,QAChB,YAAY,KAAK,aAAa,aAAa,sBAAsB,gBAAgB,CACnF,CACF;CACF,CAAC;AACH;AAEA,eAAsB,mBACpB,gBACA,SACA,UACsB;CACtB,IAAI;CACJ,IAAI;EACF,gBAAgB,MAAM,eAAe,aAAa,OAAO;CAC3D,SAAS,OAAO;EAEd,IAAI,iBAAiB,iBAAiB,MAAM;EAC5C,OAAO,aAAa,yBAAyB,4BAA4B;CAC3E;CACA,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,GAC9C,OAAO,aAAa,yBAAyB,6BAA6B;CAE5E,MAAM,SAAS,cAAc,aAAa;CAE1C,IAAI,EADU,OAAO,aAAa,WAAW,CAAC,QAAQ,IAAI,SAAA,CAC/C,SAAS,OAAO,IAAI,GAC7B,OAAO,aAAa,mBAAmB,yCAAyC;CAElF,OAAO;AACT;;;;;;;;;;;;ACrEA,eAAsB,sBACpB,SACA,OACe;CACf,IAAI,CAAC,SAAS;CACd,IAAI;CACJ,IAAI;EACF,UAAU,MAAM,QAAQ,MAAM,KAAK;CACrC,QAAQ;EACN,OAAO,aAAa,sBAAsB,4BAA4B;CACxE;CACA,IAAI,YAAY,WACd,OAAO,aAAa,sBAAsB,gCAAgC;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC6CA,MAAM,yBAAyB;AAC/B,MAAM,sBAAsB;AAC5B,MAAM,yBAAyB;AAC/B,MAAM,aAAa;;AAEnB,MAAM,kBAAkB;AACxB,MAAM,mCAAmC;AACzC,MAAMA,SAAO;AAEb,MAAM,UAAU;AAgGhB,MAAM,cAAiC;CACrC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAEA,MAAM,mBAAmB;CAAC;CAAS;CAAe;CAAW;CAAS;AAAY;;;;;;;AASlF,SAAS,oBAAoB,MAAqB,SAAiC;CACjF,IAAI;EACF,IAAI,SAAS,SAAS;GACpB,MAAM,UAAW,SAAmD;GACpE,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS,IAAI,UAAU;EACvE;EACA,IAAI,SAAS,cAAc;GAEzB,MAAM,WADY,SAAoD,SAAA,EACD;GACrE,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS,IAAI,UAAU;EACvE;CACF,QAAQ,CAGR;CACA,OAAO;AACT;;;;;AAMA,SAAS,YAAkB,OAAgB,SAA4B,OAAqB;CAC1F,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B,OAAO,aAAa,kBAAkB,GAAG,MAAM,mBAAmB;CAEpE,KAAK,MAAM,UAAU,SACnB,IAAI,OAAQ,MAAkC,YAAY,YACxD,OAAO,aAAa,kBAAkB,GAAG,MAAM,kBAAkB,OAAO,GAAG;CAG/E,OAAO;AACT;AAEA,SAAS,SAAS,OAAgB,UAAkB,OAAe,UAAU,YAAoB;CAC/F,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,MAAM,eAAe,UAAU,OAAO,OAAO,gBAAgB;CAC7D,IAAI,eAAe,KAAK,eAAe,SACrC,OAAO,aAAa,kBAAkB,GAAG,MAAM,qCAAqC;CAEtF,OAAO;AACT;AAkBA,SAAS,kBAAkB,OAA+D;CACxF,IAAI,CAAC,MAAM,QAAQ,KAAK,GACtB,OAAO,aAAa,kBAAkB,wCAAwC;CAEhF,MAAM,yBAAS,IAAI,IAAsC;CACzD,KAAK,MAAM,SAAS,OAAO;EACzB,MAAM,OAAO,YAA4B,OAAO,CAAC,GAAG,gBAAgB,GAAG,YAAY;EACnF,IACE,OAAO,KAAK,YAAY,YACxB,CAAC,OAAO,cAAc,KAAK,OAAO,KAClC,KAAK,UAAU,GAEf,OAAO,aAAa,kBAAkB,+CAA+C;EAEvF,IAAI,KAAK,UAAU,QAAQ,OAAO,KAAK,UAAU,YAC/C,OAAO,aAAa,kBAAkB,6CAA6C;EAErF,IACE,KAAK,qCAAqC,SACzC,OAAO,KAAK,qCAAqC,YAChD,CAACA,OAAK,KAAK,KAAK,gCAAgC,IAElD,OAAO,aACL,kBACA,yEACF;EAEF,IAAI,OAAO,IAAI,KAAK,OAAO,GACzB,OAAO,aAAa,kBAAkB,8BAA8B;EAEtE,OAAO,IAAI,KAAK,SAAS,IAAI;CAC/B;CACA,OAAO;AACT;AAEA,SAAS,yBACP,OACA,SACA,QACmE;CACnE,IAAI,UAAU,KAAA,GAAW,uBAAO,IAAI,IAAI;CACxC,MAAM,UAAU,kBAAkB,OAAO,sBAAsB,UAAU,YACvE,aAAa,kBAAkB,OAAO,CACxC;CACA,MAAM,2BAAW,IAAI,IAA0D;CAC/E,KAAK,MAAM,SAAS,SAAS;EAC3B,MAAM,UAAU,oBACd,cAAc,OAAO,qBAAqB,UAAU,YAClD,aAAa,kBAAkB,OAAO,CACxC,GACA;GAAC;GAAW;GAAc;GAAoB;EAAU,GACxD,sBACC,YAAY,aAAa,kBAAkB,OAAO,CACrD;EACA,MAAM,UAAU,QAAQ;EACxB,IAAI,OAAO,YAAY,YAAY,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,GAC7E,aAAa,kBAAkB,sDAAsD;EAEvF,IAAI,CAAC,OAAO,IAAI,OAAO,GACrB,aAAa,kBAAkB,2CAA2C;EAE5E,IAAI,SAAS,IAAI,OAAO,GACtB,aAAa,kBAAkB,qCAAqC;EAEtE,IAAI,QAAQ,qBAAqB,KAAA,GAC/B,aAAa,kBAAkB,wCAAwC;EAEzE,SAAS,IACP,SACA,OAAO,OAAO;GACZ;GACA,YAAY,oBACV,QAAQ,YACR,wBACA,gBACF;GACA,kBAAkB,SAChB,QAAQ,kBACR,GACA,8BACA,gCACF;GACA,UAAU,YACR,QAAQ,UACR,CAAC,wBAAwB,kBAAkB,GAC3C,oBACF;EACF,CAAC,CACH;CACF;CACA,OAAO;AACT;AAEA,SAAS,eAAe,OAAiC;CACvD,MAAM,0BAA0B,IAAI,QAAQ;CAC5C,MAAM,SAAS,cAAc,OAAO,yBAAyB,UAAU,YACrE,aAAa,kBAAkB,OAAO,CACxC;CACA,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,GAClC,IAAI,CAAC,YAAY,SAAS,GAAG,GAC3B,aAAa,kBAAkB,gDAAgD;CAGnF,MAAM,SACJ,OAAO,WAAW,KAAA,oBACd,IAAI,IAAsC,IAC1C,kBAAkB,OAAO,MAAM;CACrC,MAAM,YACJ,OAAO,cAAc,KAAA,IACjB,KAAA,IACA,YAA8B,OAAO,WAAW,CAAC,OAAO,GAAG,WAAW;CAC5E,MAAM,oBAAoB,yBAAyB,OAAO,mBAAmB,SAAS,MAAM;CAC5F,IAAI,kBAAkB,OAAO,GAAG;EAC9B,IAAI,OAAO,cAAc,KAAA,GACvB,aAAa,kBAAkB,kDAAkD;EAEnF,IAAI,cAAc,KAAA,GAChB,aAAa,kBAAkB,6CAA6C;CAEhF;CACA,IAAI,gBAAkE;CACtE,IAAI,OAAO,kBAAkB,KAAA,GAAW;EACtC,IAAI,OAAO,cAAc,KAAA,GACvB,aAAa,kBAAkB,+CAA+C;EAEhF,MAAM,UAAU,cACd,OAAO,eACP,sCACA,UACC,YAAY,aAAa,kBAAkB,OAAO,CACrD;EACA,IAAI,QAAQ,SAAS,yBAAyB,QAAQ,SAAS,gBAC7D,aAAa,kBAAkB,oCAAoC;EAErE,IAAI,OAAO,QAAQ,eAAe,YAAY,QAAQ,WAAW,SAAS,GACxE,aAAa,kBAAkB,sCAAsC;EAEvE,gBAAgB,OAAO,OAAO;GAC5B,MAAM,QAAQ;GACd,YAAY,QAAQ;GACpB,UAAU,YACR,QAAQ,UACR,CAAC,cAAc,MAAM,GACrB,yBACF;EACF,CAAC;CACH;CACA,IAAI,YAA+C;CACnD,IAAI,OAAO,cAAc,KAAA,GAAW;EAClC,IAAI,OAAO,SAAS,GAClB,aAAa,kBAAkB,0CAA0C;EAE3E,MAAM,WAAW,cACf,OAAO,WACP,iCACA,UACC,YAAY,aAAa,kBAAkB,OAAO,CACrD;EAGA,IAAI;GACF,YAAY,sBAAsB;IAChC,SAAS;IACT,aAAa,SAAS;IACtB,YAAY,SAAS;IACrB,SAAS,SAAS;IAClB,gBAAgB,SAAS;IACzB,QAAQ,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,SAAS;KACzC,MAAM,mBAAmB,kBAAkB,IAAI,KAAK,OAAO;KAC3D,OAAO;MACL,SAAS,KAAK;MACd,OAAO,KAAK,UAAU;MACtB,UAAU,KAAK;MACf,kBACE,qBAAqB,KAAA,IAAY,OAAO,EAAE,YAAY,iBAAiB,WAAW;MACpF,kCAAkC,KAAK;KACzC;IACF,CAAC;IAGD,eACE,kBAAkB,OACd;KAAE,MAAM;KAAY,YAAY;IAAK,IACrC;KAAE,MAAM,cAAc;KAAM,YAAY,cAAc;IAAW;GACzE,CAAC;EACH,QAAQ;GACN,aAAa,kBAAkB,0CAA0C;EAC3E;CACF;CACA,OAAO,OAAO,OAAO;EACnB,OAAO,YAAwB,OAAO,OAAO,CAAC,SAAS,OAAO,GAAG,OAAO;EACxE,gBAAgB,YACd,OAAO,gBACP,CAAC,cAAc,GACf,gBACF;EACA,KAAK,YAAsB,OAAO,KAAK,CAAC,WAAW,SAAS,GAAG,KAAK;EACpE,OAAO,YAAwB,OAAO,OAAO,CAAC,KAAK,GAAG,OAAO;EAC7D;EACA,cAAc,SAAS,OAAO,cAAc,wBAAwB,cAAc;EAClF,WAAW,SAAS,OAAO,WAAW,qBAAqB,aAAa,eAAe;EACvF,cAAc,SAAS,OAAO,cAAc,wBAAwB,cAAc;EAClF;EACA;EACA;EACA;CACF,CAAC;AACH;AAEA,SAAS,cAAc,SAAkB,UAAgC;CACvE,IAAI,QAAQ,WAAW,UACrB,aAAa,4BAA4B,mCAAmC;AAEhF;AAEA,eAAe,WACb,SACA,cACkC;CAElC,IAAI,EADgB,QAAQ,QAAQ,IAAI,cAAc,KAAK,GAAA,CAC1C,YAAY,CAAC,CAAC,WAAW,kBAAkB,GAC1D,aAAa,SAAS,uCAAuC;CAE/D,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK;CAC5B,QAAQ;EACN,OAAO,aAAa,SAAS,4BAA4B;CAC3D;CACA,IAAI,IAAI,YAAY,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,aAAa,cAC9C,OAAO,aAAa,SAAS,gCAAgC;CAE/D,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MAAM,IAAI;CAC1B,QAAQ;EACN,OAAO,aAAa,SAAS,0BAA0B;CACzD;CAEA,OAAO,cAAc,QAAQ,gCAAgB,IADT,QACe,IAAI,YACrD,aAAa,SAAS,OAAO,CAC/B;AACF;AAEA,SAAS,UACP,QACA,MACyB;CACzB,OAAO,oBAAoB,QAAQ,MAAM,iBAAiB,YACxD,aAAa,SAAS,OAAO,CAC/B;AACF;AAEA,eAAe,uBACb,SACA,QACA,QACA,QACkB;CAClB,MAAM,aAAa,IAAI,gBAAgB;CACvC,IAAI;CACJ,IAAI;EACF,MAAM,WAAW,IAAI,SAAgB,UAAU,WAAW;GACxD,UAAU,iBAAiB;IACzB,WAAW,MAAM;IACjB,uBAAO,IAAI,MAAM,oCAAoC,CAAC;GACxD,GAAG,QAAQ,gBAAgB;EAC7B,CAAC;EACD,MAAM,aACJ,WAAW,cACP,QAAQ,SAAS,uBACjB,QAAQ,SAAS;EACvB,MAAM,UAAkD,OAAO,OAAO;GACpE,QAAQ,OAAO,OAAO;IAAE,UAAU,OAAO;IAAU,SAAS,OAAO;GAAQ,CAAC;GAC5E;GACA,QAAQ,WAAW;EACrB,CAAC;EACD,OAAO,MAAM,QAAQ,KAAK,CACxB,QAAQ,QAAQ,QAAQ,MAAM,YAAY,KAAA,GAAW,CAAC,OAAO,CAAC,CAAC,GAC/D,QACF,CAAC;CACH,QAAQ;EACN,OAAO,aAAa,2BAA2B,mCAAmC;CACpF,UAAU;EACR,IAAI,YAAY,KAAA,GAAW,aAAa,OAAO;CACjD;AACF;AAEA,SAAS,gBAAgB,QAA+D;CACtF,IAAI,OAAO,YAAY,YAAY;EACjC,MAAM,QAAQ,UAAU,QAAQ,CAAC,WAAW,UAAU,CAAC;EACvD,OAAO,OAAO,OAAO;GACnB,SAAS;GACT,UAAU,YAAY,MAAM,UAAU,aAAa,mBAAmB,YAAY,OAAO;EAC3F,CAAC;CACH;CACA,IAAI,OAAO,YAAY,YAAY;EACjC,UAAU,QAAQ,CAAC,SAAS,CAAC;EAC7B,OAAO,OAAO,OAAO,EAAE,SAAS,WAAW,CAAC;CAC9C;CACA,OAAO,aAAa,SAAS,iCAAiC;AAChE;;;;;;AAOA,SAAS,qBAAqB,QAA+D;CAC3F,IAAI,OAAO,YAAY,WAAW;EAChC,MAAM,QAAQ,UAAU,QAAQ,CAAC,WAAW,UAAU,CAAC;EACvD,OAAO,OAAO,OAAO;GACnB,SAAS;GACT,UAAU,YAAY,MAAM,UAAU,aAAa,mBAAmB,YAAY,OAAO;EAC3F,CAAC;CACH;CACA,IAAI,OAAO,YAAY,UAAU;EAC/B,UAAU,QAAQ,CAAC,SAAS,CAAC;EAC7B,OAAO,OAAO,OAAO,EAAE,SAAS,WAAW,CAAC;CAC9C;CACA,OAAO,aAAa,SAAS,iCAAiC;AAChE;AAEA,SAAS,UAAU,OAAoC;CACrD,OAAO;EACL,WAAW,MAAM;EACjB,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB,gBAAgB,MAAM;EACtB,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,UAAU,MAAM;CAClB;AACF;AAEA,SAAgB,mBAAmB,SAA4C;CAC7E,MAAM,WAAW,eAAe,OAAO;CAEvC,MAAM,eAAe,OACnB,SACA,MACA,UACyB;EACzB,MAAM,SAAS,MAAM,mBAAmB,SAAS,gBAAgB,SAAS,IAAI;EAG9E,MAAM,sBAAsB,SAAS,WAAW;GAAE;GAAO,UAAU,OAAO;EAAS,CAAC;EACpF,OAAO;CACT;CAEA,MAAM,QAAQ,OAAO,YAAwC;EAC3D,MAAM,WAAW,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,SAAS,MAAM,GAAG,CAAC,CAAC,QAAQ,SAAS,KAAK,SAAS,CAAC;EAC1F,MAAM,CAAC,MAAM,OAAO,OAAO,UAAU;EAIrC,IAAI,SAAS,UAAU;GACrB,IAAI,SAAS,WAAW,KAAK,UAAU,eAAe;IACpD,cAAc,SAAS,KAAK;IAC5B,MAAM,SAAS,MAAM,aAAa,SAAS,SAAS,gBAAgB;IACpE,MAAM,aAAa,MAAM,yBAAyB;KAChD,OAAO,SAAS;KAChB,OAAO,SAAS;KAChB;KACA,WAAW,oBAAoB,OAAO,eAAe,OAAO;IAC9D,CAAC;IACD,OAAO,aAAa,KAAK,UAAU;GACrC;GACA,IAAI,SAAS,WAAW,KAAK,UAAU,aAAa;IAClD,cAAc,SAAS,MAAM;IAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,SAAS,eAAe;IACnE,MAAM,UAAU,qBAAqB,MAAM,WAAW,SAAS,SAAS,YAAY,CAAC;IACrF,MAAM,UAAU,MAAM,yBAAyB;KAC7C,OAAO,SAAS;KAChB,OAAO,SAAS;KAChB,KAAK,SAAS;KACd;KACA,aAAa,oBAAoB,OAAO,eAAe,OAAO;KAC9D;KACA,WAAW,SAAS;IACtB,CAAC;IACD,OAAO,aAAa,KAAK,OAAO;GAClC;GACA,OAAO,aAAa,mBAAmB,sBAAsB;EAC/D;EAEA,IAAI,SAAS,eAAe,SAAS,WAAW,GAAG;GACjD,cAAc,SAAS,KAAK;GAC5B,MAAM,aAAa,SAAS,UAAU,iBAAiB;GACvD,IAAI,SAAS,cAAc,MACzB,OAAO,aAAa,mBAAmB,sBAAsB;GAE/D,OAAO,aAAa,KAAK,SAAS,SAAS;EAC7C;EAEA,IAAI,SAAS,mBAAmB;GAM9B,MAAM,UAAU,SAAS;GACzB,IAAI,YAAY,MAAM,OAAO,aAAa,mBAAmB,sBAAsB;GACnF,IAAI,SAAS,WAAW,GAAG;IACzB,cAAc,SAAS,MAAM;IAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,4BAA4B;IACjF,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CAAC,UAAU,CAAC;IACrF,MAAM,WAAW,YAAY,KAAK,UAAU,KAAK,2BAA2B,OAAO;IACnF,IAAI;IACJ,IAAI;KACF,aAAa,MAAM,QAAQ,SAAS,WAAW;MAC7C,UAAU,OAAO;MACjB,SAAS,OAAO;MAChB;KACF,CAAC;IACH,QAAQ;KACN,OAAO,aAAa,kBAAkB,wCAAwC;IAChF;IACA,OAAO,aAAa,KAAK,EAAE,oBAAoB,WAAW,CAAC;GAC7D;GACA,IAAI,SAAS,WAAW,KAAK,UAAU,cAAc;IACnD,cAAc,SAAS,MAAM;IAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,sBAAsB;IAC3E,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CACvE,YACA,MACF,CAAC;IACD,MAAM,WAAW,YAAY,KAAK,UAAU,KAAK,2BAA2B,OAAO;IAGnF,IAAI,OAAO,KAAK,SAAS,YAAY,CAAC,oBAAoB,KAAK,KAAK,IAAI,GACtE,OAAO,aAAa,SAAS,oDAAoD;IAEnF,IAAI;IACJ,IAAI;KACF,YAAY,MAAM,QAAQ,SAAS,KAAK;MACtC,UAAU,OAAO;MACjB,SAAS,OAAO;MAChB;MACA,MAAM,KAAK;KACb,CAAC;IACH,QAAQ;KACN,OAAO,aAAa,kBAAkB,wCAAwC;IAChF;IACA,OAAO,aAAa,KAAK,EAAE,UAAU,CAAC;GACxC;GACA,OAAO,aAAa,mBAAmB,sBAAsB;EAC/D;EAEA,IAAI,SAAS,mBAAmB,SAAS,WAAW,GAAG;GACrD,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,sBAAsB;GAC3E,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CACvE,WACA,gBACF,CAAC;GACD,MAAM,UAAU,oBAAoB,KAAK,SAAS,WAAW,OAAO;GACpE,MAAM,iBAAiB,YAAY,KAAK,gBAAgB,IAAI,kBAAkB,OAAO;GACrF,IAAI,CAAC,oBAAoB,KAAK,cAAc,GAC1C,OAAO,aAAa,SAAS,iDAAiD;GAQhF,MAAM,SAAS,MAAM,qBAAqB,SAAS,OAAO,OAAO,gBAAgB;IAC/E,MAAM,WAAW,MAAM,YAAY,2BAA2B,OAAO;IACrE,IAAI,UAAU;KACZ,IAAI,SAAS,aAAa,OAAO,UAG/B,OAAO,aAAa,mBAAmB,sBAAsB;KAE/D,OAAO;IACT;IACA,MAAM,UAAU,OAAO,OAAO;KAC5B,SAAS;KACT;KACA,UAAU,OAAO;KACjB;KACA,eAAe,SAAS,SAAS,KAAK;IACxC,CAAC;IACD,IAAI,CAAE,MAAM,YAAY,6BAA6B,OAAO,GAC1D,OAAO,aAAa,kBAAkB,wCAAwC;IAEhF,OAAO;GACT,CAAC;GACD,MAAM,SAAS,MAAM,OAAO,OAAO,OACjC,WACA,IAAI,YAAY,CAAC,CAAC,OAChB,+BAA+B,OAAO,SAAS,GAAG,OAAO,QAAQ,GAAG,OAAO,eAAe,GAAG,OAAO,eACtG,CACF;GACA,MAAM,eAAe,KAAK,CAAC,GAAG,IAAI,WAAW,MAAM,CAAC,CAAC,CAClD,KAAK,SAAS,KAAK,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CACjD,KAAK,EAAE;GAGV,OAAO,aAAa,KAAK;IACvB;IACA,eAAe,KAAK,MAAM,OAAO,gBAAgB,GAAK;GACxD,CAAC;EACH;EAEA,IAAI,SAAS,YAAY,SAAS,WAAW,KAAK,UAAU,aAAa;GACvE,cAAc,SAAS,MAAM;GAC7B,MAAM,UAAU,SAAS,kBAAkB,IAAI,OAAO,KAAK,CAAC;GAC5D,MAAM,SAAS,WAAW,eAAe,WAAW,SAAS,SAAS;GACtE,IAAI,YAAY,KAAA,KAAa,WAAW,MACtC,OAAO,aAAa,mBAAmB,sBAAsB;GAO/D,MAAM,SAAS,MAAM,uBAAuB,SAAS,QAAQ,MALxC,aAAa,SAAS,UAAU,oBAAoB,QAAQ,GAIpE,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CAAC,QAAQ,CACV,CAAC,CAAC,MAAM;GAChF,OAAO,aACL,KACA,WAAW,KAAA,IAAY;IAAE,SAAS;IAAO,QAAQ;GAAK,IAAI;IAAE,SAAS;IAAM;GAAO,CACpF;EACF;EAEA,IAAI,SAAS,UAAU;GACrB,IAAI,SAAS,WAAW,GAAG,OAAO,aAAa,mBAAmB,sBAAsB;GACxF,cAAc,SAAS,MAAM;GAC7B,MAAM,OAAO,SAAS,OAAO,IAAI,OAAO,KAAK,CAAC;GAC9C,MAAM,OACJ,UAAU,gBACN,eACA,UAAU,WACR,UAAU,iBACV,UAAU,aACV,UAAU,WACV,UAAU,UACV,QACA;GACR,IAAI,CAAC,QAAQ,SAAS,MACpB,OAAO,aAAa,mBAAmB,sBAAsB;GAK/D,MAAM,SAAS,MAAM,aACnB,SACA,SAAS,eAAe,CAAC,UAAU,OAAO,IAAI,UAC9C,UAAU,MACZ;GACA,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CAAC,SAAS,CAAC;GACpF,MAAM,aAAa,SAAS,UAAU,KAAK,QAAQ,KAAK;GACxD,IAAI,eAAe,MACjB,OAAO,aAAa,mBAAmB,sBAAsB;GAY/D,MAAM,UAAU,OAAO,SAAS,UAAU,OAAO,oBAAoB,MAAM,KAAK,OAAO;GACvF,IAAI,YAAY,MAIV;QAAA,MAHsB,qBAAqB,SAAS,QAAQ,gBAC9D,YAAY,2BAA2B,OAAO,CAChD,MACoB,KAAA,GAClB,OAAO,aACL,gCACA,uCACF;GAAA;GAGJ,IAAI;GACJ,IAAI;IACF,SAAS,MAAM,WAAW,KAAK,OAAO;GACxC,QAAQ;IAGN,OAAO,aAAa,2BAA2B,2BAA2B;GAC5E;GAGA,OAAO,aACL,KACA,WAAW,KAAA,IAAY;IAAE,SAAS;IAAO,QAAQ;GAAK,IAAI;IAAE,SAAS;IAAM;GAAO,CACpF;EACF;EAEA,IAAI,SAAS,iBACX,aAAa,mBAAmB,sBAAsB;EAGxD,IAAI,SAAS,WAAW,KAAK,UAAU,YAAY;GACjD,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,sBAAsB;GAC3E,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG;IACvE;IACA;IACA;GACF,CAAC;GACD,MAAM,UAAU,MAAM,2BAA2B;IAC/C,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB;IACA,aAAa,YACX,KAAK,aACL,aAAa,aACb,eACA,OACF;IACA,eAAe,YACb,KAAK,eACL,aAAa,eACb,iBACA,OACF;IACA,gBAAgB,YACd,KAAK,gBACL,aAAa,gBACb,kBACA,OACF;IACA,cAAc,SAAS;GACzB,CAAC;GACD,OAAO,aAAa,KAAK,OAAO;EAClC;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,YAAY;GACjD,cAAc,SAAS,KAAK;GAC5B,MAAM,SAAS,MAAM,aAAa,SAAS,SAAS,qBAAqB;GACzE,MAAM,QAAQ,MAAM,0BAA0B;IAC5C,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB;IACA,WAAW,oBAAoB,OAAO,aAAa,OAAO;GAC5D,CAAC;GACD,OAAO,aAAa,KAAK,UAAU,KAAK,CAAC;EAC3C;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,cAAc,WAAW,YAAY;GAC1E,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,SAAS,sBAAsB;GAC1E,MAAM,UAAU,gBAAgB,MAAM,WAAW,SAAS,SAAS,YAAY,CAAC;GAChF,MAAM,UAAU,MAAM,4BAA4B;IAChD,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB,KAAK,SAAS;IACd;IACA,WAAW,oBAAoB,OAAO,aAAa,OAAO;IAC1D;IACA,WAAW,SAAS;GACtB,CAAC;GACD,OAAO,aAAa,KAAK,OAAO;EAClC;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,cAAc,WAAW,QAAQ;GACtE,cAAc,SAAS,KAAK;GAC5B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,oBAAoB;GACzE,MAAM,UAAU,MAAM,uBAAuB;IAC3C,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB,KAAK,SAAS;IACd;IACA,WAAW,oBAAoB,OAAO,aAAa,OAAO;GAC5D,CAAC;GACD,OAAO,aAAa,KAAK,OAAO;EAClC;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,WAAW,UAAU,WAAW;GACrE,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,uBAAuB;GAC5E,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG;IACvE;IACA;IACA;GACF,CAAC;GACD,MAAM,WAAW,MAAM,yBAAyB;IAC9C,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB;IACA,MAAM,oBAAoB,KAAK,MAAM,QAAQ,OAAO;IACpD,cAAc,YACZ,KAAK,cACL,aAAa,cACb,gBACA,OACF;IACA,aAAa,YACX,KAAK,aACL,aAAa,aACb,eACA,OACF;GACF,CAAC;GACD,OAAO,aAAa,KAAK,QAAQ;EACnC;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,eAAe,WAAW,SAAS;GACxE,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,qBAAqB;GAC1E,MAAM,UAAU,MAAM,uBAAuB;IAC3C,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB,KAAK,SAAS;IACd;IACA,YAAY,oBAAoB,OAAO,cAAc,OAAO;GAC9D,CAAC;GACD,OAAO,aAAa,KAAK,OAAO;EAClC;EAEA,IAAI,SAAS,WAAW,KAAK,UAAU,UAAU;GAC/C,cAAc,SAAS,MAAM;GAC7B,MAAM,SAAS,MAAM,aAAa,SAAS,UAAU,sBAAsB;GAC3E,MAAM,OAAO,UAAU,MAAM,WAAW,SAAS,SAAS,YAAY,GAAG,CAAC,WAAW,CAAC;GACtF,MAAM,QAAQ,MAAM,oBAAoB;IACtC,OAAO,SAAS;IAChB,OAAO,SAAS;IAChB;IACA,WAAW,oBAAoB,KAAK,WAAW,aAAa,OAAO;GACrE,CAAC;GACD,OAAO,aAAa,KAAK,UAAU,KAAK,CAAC;EAC3C;EAEA,OAAO,aAAa,mBAAmB,sBAAsB;CAC/D;CAEA,OAAO,OAAO,YAAwC;EACpD,IAAI;GACF,OAAO,MAAM,MAAM,OAAO;EAC5B,SAAS,OAAO;GACd,OAAO,mBAAmB,eAAe,KAAK,CAAC;EACjD;CACF;AACF;;;;;;;;;;;;ACt+BA,MAAa,WAAW;AACxB,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAElB,MAAM,WAAW;AACjB,MAAM,YAAY;AAClB,MAAM,cAAc;;AAGpB,MAAM,iCAAsC,IAAI,IAAI;CAClD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,aAAa,KAAqB;CACzC,OAAO,IAAI,YAAY,CAAC,CAAC,WAAW,eAAe,EAAE;AACvD;AAEA,SAAS,SAAS,YAA6B;CAC7C,OAAO,WAAW,SAAS,KAAK,KAAK,WAAW,SAAS,KAAK;AAChE;AAEA,SAAS,UAAU,OAAuB;CACxC,OAAO,MAAM,UAAU,WAAW,QAAQ,GAAG,MAAM,MAAM,GAAG,QAAQ,IAAI;AAC1E;;AAGA,SAAgB,UAAU,OAAwB;CAChD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,KAAK;CACrB,QAAQ;EACN,OAAO;CACT;CACA,MAAM,OAAO,IAAI,SAAS,KAAK,KAAK,IAAI,IAAI;CAC5C,OAAO,UAAU,GAAG,IAAI,SAAS,IAAI,IAAI,WAAW,OAAO,IAAI,UAAU;AAC3E;AAEA,SAAS,YAAY,OAAgB,OAAwB;CAC3D,IAAI,UAAU,MAAM,OAAO;CAC3B,QAAQ,OAAO,OAAf;EACE,KAAK,UACH,OAAO,UAAU,KAAK;EACxB,KAAK,UACH,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK;EACtD,KAAK,WACH,OAAO;EACT,KAAK,UACH,OAAO,UAAU,MAAM,SAAS,CAAC;EACnC,KAAK,UACH;EACF,SAEE,OAAO;CACX;CACA,IAAI,SAAS,WAAW,OAAO;CAC/B,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,MAAM,QAAQ,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,KAAK,SAAS,YAAY,MAAM,QAAQ,CAAC,CAAC;EACpF,OAAO,MAAM,SAAS,cAAc,CAAC,GAAG,OAAO,SAAS,IAAI;CAC9D;CACA,IAAI,iBAAiB,OAEnB,OAAO;EAAE,MAAM,UAAU,MAAM,IAAI;EAAG,SAAS;CAAS;CAE1D,OAAO,aAAa,OAAkC,KAAK;AAC7D;AAEA,SAAS,aAAa,OAAgC,OAAwC;CAC5F,MAAM,WAAoC,CAAC;CAC3C,IAAI,UAAU;CACd,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,GAAG;EACpC,IAAI,WAAW,aAAa;GAC1B,SAAS,aAAa;GACtB;EACF;EACA,WAAW;EACX,MAAM,aAAa,aAAa,GAAG;EACnC,IAAI,eAAe,IAAI,UAAU,GAC/B,SAAS,OAAO;OACX,IAAI,SAAS,UAAU,GAC5B,SAAS,OAAO,UAAU,MAAM,IAAI;OAEpC,SAAS,OAAO,YAAY,MAAM,MAAM,QAAQ,CAAC;CAErD;CACA,OAAO;AACT;;AAGA,SAAgB,aAAa,OAAyB;CACpD,OAAO,YAAY,OAAO,CAAC;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;;AChGA,MAAM,OAAO;AACb,MAAM,oBAAoB;AAwB1B,SAAS,YAAY,SAAkD;CACrE,KAAK,MAAM,QAAQ;EAAC,QAAQ;EAAU,QAAQ;EAAS,QAAQ;CAAQ,GACrE,IAAI,OAAO,SAAS,YAAY,KAAK,SAAS,KAAK,KAAK,SAAS,mBAC/D,MAAM,IAAI,MAAM,oCAAoC;CAIxD,OAAO,KAAK,UAAU;EAAC,QAAQ;EAAU,QAAQ;EAAS,QAAQ;CAAQ,CAAC;AAC7E;AAEA,SAAS,UAAU,YAAuC;CACxD,MAAM,YAAY,UAAU,aAAa,YAAY,KAAK;CAC1D,OAAO,KAAK,WAAW,WAAW,UAAU,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AACjE;AAEA,SAAgB,+BAA+B,OAEhB;CAC7B,MAAM,MAAM,MAAM;;CAElB,MAAM,yBAAS,IAAI,IAAoB;;CAEvC,MAAM,2BAAW,IAAI,IAA6B;CAElD,eAAe,aAAa,UAAmC;EAC7D,MAAM,WAAW,OAAO,IAAI,QAAQ;EACpC,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,UACJ,SAAS,IAAI,QAAQ,MACpB,YAAY;GACX,MAAM,SAAS,UAAU,MAAM,iBAAiB;GAChD,MAAM,YAAY,OAAO,MAAM,IAAI,QAAQ,WAAW,MAAM,CAAC,CAAC;GAC9D,OAAO,KAAK,CAAC;GACb,OAAO,IAAI,UAAU,SAAS;GAC9B,OAAO;EACT,EAAA,CAAG;EACL,SAAS,IAAI,UAAU,OAAO;EAC9B,QAAQ,cAAc,SAAS,OAAO,QAAQ,CAAC;EAC/C,OAAO;CACT;CAEA,OAAO,OAAO,OAAO;EACnB,MAAM,WAAW,SAA4D;GAC3E,MAAM,WAAW,YAAY,OAAO;GACpC,MAAM,aAAa,WAAW,OAAO,MAAM,IAAI,QAAQ,MAAM,aAAa,QAAQ,CAAC,CAAC,CAAC;GACrF,IAAI;IACF,OAAO,OAAO,OAAO;KACnB,SAAS;KACT,MAAM;KACN,SAAS,UAAU,UAAU;IAC/B,CAAC;GACH,UAAU;IACR,WAAW,KAAK,CAAC;GACnB;EACF;EACA,MAAM,KAAK,SAA+D;GACxE,MAAM,WAAW,YAAY,OAAO;GACpC,IAAI,OAAO,QAAQ,SAAS,YAAY,CAAC,KAAK,KAAK,QAAQ,IAAI,GAC7D,MAAM,IAAI,MAAM,oDAAoD;GAItE,MAAM,YAAY,OAAO,IAAI,QAAQ;GACrC,IAAI,cAAc,KAAA,GAChB,MAAM,IAAI,MAAM,6CAA6C;GAE/D,MAAM,aAAa,WAAW,OAAO,MAAM,IAAI,QAAQ,SAAS,CAAC,CAAC;GAClE,IAAI;IACF,MAAM,YAAY,UAAU,KAAK,WAAW,QAAQ,KAAK,MAAM,CAAC,CAAC,GAAG,YAAY,EAC9E,MAAM,KACR,CAAC;IACD,IAAI,UAAU,aAAa,KAAK,UAAU,aAAa,GACrD,MAAM,IAAI,MAAM,+CAA+C;IAIjE,OAAO,KAAK,WAAW,UAAU,kBAAkB,CAAC,KAAK,KAAK,UAAU,SAAA,CAAU,SAAS,EAAE;GAC/F,UAAU;IACR,WAAW,KAAK,CAAC;GACnB;EACF;CACF,CAAC;AACH;;;;;;;;;;;;;;ACpGA,SAAS,cAAsB;CAC7B,OAAO;EACL,0BAAU,IAAI,IAAI;EAClB,2BAAW,IAAI,IAAI;EACnB,uBAAO,IAAI,IAAI;EACf,2BAAW,IAAI,IAAI;EACnB,+BAAe,IAAI,IAAI;CACzB;AACF;AAEA,SAAS,WAAW,QAAwB;CAC1C,OAAO;EACL,UAAU,IAAI,IAAI,OAAO,QAAQ;EACjC,WAAW,IAAI,IAAI,OAAO,SAAS;EACnC,OAAO,IAAI,IAAI,OAAO,KAAK;EAC3B,WAAW,IAAI,IAAI,OAAO,SAAS;EACnC,eAAe,IAAI,IAAI,OAAO,aAAa;CAC7C;AACF;AAEA,SAAS,OAAO,OAA6B,KAAa,QAA0B;CAClF,IAAI,MAAM,IAAI,GAAG,GAAG,OAAO;CAC3B,MAAM,IAAI,KAAK,MAAM;CACrB,OAAO;AACT;AAEA,SAAS,KACP,OACA,KACA,OACmB;CACnB,MAAM,SAAS,MAAM,IAAI,GAAG;CAE5B,OAAO,WAAW,KAAA,IAAY,KAAA,IAAY,MAAM,MAAM;AACxD;AAEA,SAAgB,yBAAqC;CACnD,IAAI,YAAY,YAAY;CAC5B,IAAI,SAAS;CACb,IAAI,OAAsB,QAAQ,QAAQ;CAE1C,eAAe,UAA+B;EAC5C,MAAM,QAAQ;EACd,IAAI,gBAAsB,CAAC;EAC3B,OAAO,IAAI,SAAe,YAAY;GACpC,UAAU;EACZ,CAAC;EACD,MAAM;EACN,OAAO;CACT;CAEA,OAAO;EACL,MAAM,QAAmC;GACvC,IAAI,QAAQ,aAAa,2BAA2B,8BAA8B;GAClF,MAAM,UAAU,MAAM,QAAQ;GAC9B,MAAM,SAAS,WAAW,SAAS;GACnC,IAAI,UAAU;GAEd,MAAM,aAAqB;IACzB,IAAI,SAAS,aAAa,kBAAkB,mCAAmC;IAC/E,OAAO;GACT;GACA,MAAM,UAAU,UAAyB;IACvC,IAAI,SAAS,aAAa,kBAAkB,mCAAmC;IAC/E,UAAU;IACV,IAAI,OAAO,YAAY;IACvB,QAAQ;GACV;GAEA,OAAO;IACL,MAAM,yBAAyB,WAAW;KACxC,OAAO,KAAK,KAAK,CAAC,CAAC,UAAU,WAAW,+BAA+B;IACzE;IACA,MAAM,2BAA2B,QAAoC;KACnE,OAAO,OAAO,KAAK,CAAC,CAAC,UAAU,OAAO,WAAW,MAAM;IACzD;IACA,MAAM,0BAA0B,WAAW;KACzC,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,WAAW,gCAAgC;IAC3E;IACA,MAAM,4BAA4B,QAAqC;KACrE,OAAO,OAAO,KAAK,CAAC,CAAC,WAAW,OAAO,WAAW,MAAM;IAC1D;IACA,MAAM,sBAAsB,UAAU;KACpC,OAAO,KAAK,KAAK,CAAC,CAAC,OAAO,UAAU,4BAA4B;IAClE;IACA,MAAM,wBAAwB,QAAiC;KAC7D,OAAO,OAAO,KAAK,CAAC,CAAC,OAAO,OAAO,UAAU,MAAM;IACrD;IACA,MAAM,yBAAyB,UAAU,YAAY;KACnD,MAAM,QAAQ,KAAK,CAAC,CAAC;KACrB,MAAM,SAAS,KAAK,OAAO,UAAU,4BAA4B;KACjE,IAAI,CAAC,UAAU,OAAO,eAAe,MAAM,OAAO;KAClD,MAAM,IAAI,UAAU,OAAO,OAAO;MAAE,GAAG;MAAQ;KAAW,CAAC,CAAC;KAC5D,OAAO;IACT;IACA,MAAM,2BAA2B,SAAS;KACxC,OAAO,KAAK,KAAK,CAAC,CAAC,eAAe,SAAS,iCAAiC;IAC9E;IACA,MAAM,6BAA6B,QAAsC;KACvE,OAAO,OAAO,KAAK,CAAC,CAAC,eAAe,OAAO,SAAS,MAAM;IAC5D;IACA,MAAM,sBAAsB,YAAY;KACtC,OAAO,KAAK,KAAK,CAAC,CAAC,WAAW,YAAY,4BAA4B;IACxE;IACA,MAAM,wBAAwB,QAAiC;KAC7D,OAAO,OAAO,KAAK,CAAC,CAAC,WAAW,OAAO,YAAY,MAAM;IAC3D;IACA,MAAM,uBAAuB,YAAY,WAAW;KAClD,MAAM,YAAY,KAAK,CAAC,CAAC;KACzB,MAAM,SAAS,KAAK,WAAW,YAAY,4BAA4B;KACvE,IAAI,CAAC,UAAU,OAAO,cAAc,MAAM,OAAO;KACjD,UAAU,IAAI,YAAY,OAAO,OAAO;MAAE,GAAG;MAAQ;KAAU,CAAC,CAAC;KACjE,OAAO;IACT;IACA,MAAM,SAAS;KACb,OAAO,IAAI;IACb;IACA,MAAM,WAAW;KACf,IAAI,CAAC,SAAS,OAAO,KAAK;IAC5B;GACF;EACF;EACA,MAAM,QAAuB;GAC3B,SAAS;GACT,YAAY,YAAY;EAC1B;CACF;AACF"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["HASH"],"sources":["../src/artifact/claim.ts","../src/authorization/code.ts","../src/authorization/resume.ts","../src/directory/records.ts","../src/directory/service.ts","../src/authorization/pickup.ts","../src/authorization/verify.ts","../src/security/authentication.ts","../src/security/rate-limit.ts","../src/relay/handler.ts","../src/security/redact.ts","../src/session-signer/kms-provider.ts","../src/store/memory.ts"],"sourcesContent":["/**\n * One-time encrypted artifact release.\n *\n * ```text\n * state and owner the artifact record's `claimedAt` owns \"released\"\n * transitions sealed -> claimed, exactly once\n * terminal claimed; a second claim fails closed\n * retry positively safe? no. The claim commits before the KMS is asked to\n * decrypt, so a decrypt or transport failure burns the\n * artifact instead of risking a second release\n * crash/reload a crash before commit leaves the artifact claimable\n * ```\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { withRelayTransaction } from \"../store/interface.js\";\nimport { openArtifact } from \"./encrypt.js\";\n\nexport interface ClaimEncryptedArtifactInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n readonly kms: RelayKms;\n /** Authenticated `client` caller; only the bound client may claim. */\n readonly caller: RelayCaller;\n /** Released only by a successful code consume. */\n readonly artifactId: string;\n}\n\nexport interface ClaimedEncryptedArtifact {\n readonly requestId: string;\n readonly artifact: string;\n}\n\nexport async function claimEncryptedArtifact(\n input: ClaimEncryptedArtifactInput,\n): Promise<ClaimedEncryptedArtifact> {\n const claimedAt = relayNow(input.clock);\n const claimed = await withRelayTransaction(input.store, async (transaction) => {\n const record = await transaction.lockEncryptedArtifact(input.artifactId);\n // An artifact bound to another client is indistinguishable from an unknown one.\n if (!record || record.clientId !== input.caller.clientId) {\n return relayFailure(\"relay_not_found\", \"encrypted artifact does not exist\");\n }\n if (record.claimedAt !== null) {\n relayFailure(\"relay_artifact_already_claimed\", \"encrypted artifact was already claimed\");\n }\n if (!(await transaction.claimEncryptedArtifact(input.artifactId, claimedAt))) {\n relayFailure(\"relay_state_ambiguous\", \"one-time claim did not apply under its row lock\");\n }\n return record;\n });\n return Object.freeze({\n requestId: claimed.requestId,\n artifact: await openArtifact(input.kms, claimed.ciphertextRef),\n });\n}\n","/**\n * One-time authorization code consume.\n *\n * ```text\n * state and owner the code record's `consumedAt` owns \"used\"\n * transitions issued -> consumed, exactly once\n * terminal consumed; a second consume fails closed\n * retry positively safe? no, in either direction: a released code is never\n * re-released, and an ambiguous commit is never retried\n * crash/reload the guarded update and the release decide together in one\n * transaction under the code's row lock\n * ```\n *\n * A failed PKCE or redirect binding still burns the code, so a stolen code\n * cannot be brute-forced against the stored challenge.\n *\n * The endpoint is not an oracle for whether a guessed code was correct: an\n * unknown code, a code bound to another client, a wrong redirect URI, and a\n * wrong verifier all leave as the single `relay_code_invalid` code and status.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { type RelayErrorCode, relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { sha256Base64Url, verifyPkceS256 } from \"./challenge.js\";\n\nexport interface ConsumeAuthorizationCodeInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n /** Authenticated `client` caller; only the bound client may consume. */\n readonly caller: RelayCaller;\n readonly code: string;\n readonly codeVerifier: string;\n readonly redirectUri: string;\n}\n\nexport interface ConsumedAuthorizationCode {\n readonly requestId: string;\n /** One-time claim handle for the encrypted artifact. */\n readonly artifactId: string;\n}\n\ntype ConsumeOutcome =\n | Readonly<{ kind: \"released\"; released: ConsumedAuthorizationCode }>\n | Readonly<{ kind: \"burned\"; code: RelayErrorCode }>;\n\nexport async function consumeAuthorizationCode(\n input: ConsumeAuthorizationCodeInput,\n): Promise<ConsumedAuthorizationCode> {\n const consumedAt = relayNow(input.clock);\n const codeHash = await sha256Base64Url(input.code);\n const transaction = await input.store.begin();\n let outcome: ConsumeOutcome;\n try {\n const record = await transaction.lockAuthorizationCode(codeHash);\n // An unknown code and a code bound to another client are indistinguishable\n // from a code whose binding failed below.\n if (!record || record.clientId !== input.caller.clientId) {\n relayFailure(\"relay_code_invalid\", \"authorization code redemption failed\");\n }\n if (record.consumedAt !== null) {\n relayFailure(\"relay_code_already_consumed\", \"authorization code was already consumed\");\n }\n if (consumedAt >= record.expiresAt) {\n // Already dead; nothing left to burn.\n relayFailure(\"relay_expired\", \"authorization code expired\");\n }\n const bound =\n record.redirectUri === input.redirectUri &&\n (await verifyPkceS256(input.codeVerifier, record.codeChallenge));\n if (!(await transaction.consumeAuthorizationCode(codeHash, consumedAt))) {\n relayFailure(\"relay_state_ambiguous\", \"one-time consume did not apply under its row lock\");\n }\n if (!bound) {\n // Void the artifact with the code that would have released it. A `false`\n // result means it was already terminal, which is the same outcome.\n await transaction.lockEncryptedArtifact(record.artifactId);\n await transaction.claimEncryptedArtifact(record.artifactId, consumedAt);\n }\n outcome = bound\n ? Object.freeze({\n kind: \"released\",\n released: Object.freeze({\n requestId: record.requestId,\n artifactId: record.artifactId,\n }),\n })\n : Object.freeze({ kind: \"burned\", code: \"relay_code_invalid\" });\n } catch (error) {\n await transaction.rollback();\n throw error;\n }\n // The burn is committed before the failure is reported.\n await transaction.commit();\n if (outcome.kind === \"burned\") {\n relayFailure(outcome.code, \"authorization code redemption failed and the code was burned\");\n }\n return outcome.released;\n}\n","/**\n * Resume: fresh authentication plus a grant recovery read.\n *\n * Resume never transitions anything and never re-releases a code or an artifact.\n * The caller re-authenticates on every call, and receives only enough state to\n * decide whether its own grant work is still valid.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { withRelayTransaction } from \"../store/interface.js\";\nimport { type AuthorizationState, readAuthorizationState } from \"./request.js\";\n\nexport interface ResumeAuthorizationInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n /** Freshly authenticated `client` caller; only the bound client may resume. */\n readonly caller: RelayCaller;\n readonly requestId: string;\n}\n\nexport function resumeAuthorization(input: ResumeAuthorizationInput): Promise<AuthorizationState> {\n const now = relayNow(input.clock);\n return withRelayTransaction(input.store, (transaction) =>\n readAuthorizationState(\n transaction,\n input.requestId,\n now,\n (request) => request.clientId === input.caller.clientId,\n ),\n );\n}\n","import {\n captureDenseArray,\n captureRecord,\n captureServiceAccount,\n exactCapturedRecord,\n parseAccountId,\n parseClientId,\n type ServiceAccount,\n} from \"@oaath/protocol\";\nimport { type RelayErrorCode, relayFailure } from \"../relay/errors.js\";\nimport { boundedText } from \"../store/records.js\";\n\nexport const OAATH_SERVICE_DIRECTORY_VERSION = \"oaath.service-directory/v1\" as const;\n\nexport interface DirectoryWorkspace {\n readonly workspaceId: string;\n readonly kind: \"personal\" | \"team\";\n}\nexport interface DirectoryApplication {\n readonly clientId: string;\n readonly applicationId: string;\n readonly applicationName: string;\n}\n/** Membership names the authenticated application/user pair, not owner authority. */\nexport interface DirectoryMembership {\n readonly workspaceId: string;\n readonly clientId: string;\n readonly subject: string;\n}\n/** Enrollment identity used to route owner work; private key material is never stored here. */\nexport interface DirectoryOwnerDevice {\n readonly workspaceId: string;\n readonly ownerDeviceId: string;\n readonly subject: string;\n}\nexport interface DirectoryAccount extends ServiceAccount {\n readonly workspaceId: string;\n readonly accountId: string;\n readonly ownerDeviceId: string;\n readonly chainIds: readonly number[];\n}\n/** A preference; current membership is checked again whenever it is resolved. */\nexport interface DirectorySelection extends DirectoryMembership {\n readonly accountId: string;\n}\n\nexport interface ServiceDirectoryDocument {\n readonly version: typeof OAATH_SERVICE_DIRECTORY_VERSION;\n readonly workspaces: readonly Readonly<DirectoryWorkspace>[];\n readonly applications: readonly Readonly<DirectoryApplication>[];\n readonly memberships: readonly Readonly<DirectoryMembership>[];\n readonly ownerDevices: readonly Readonly<DirectoryOwnerDevice>[];\n readonly accounts: readonly Readonly<DirectoryAccount>[];\n readonly selections: readonly Readonly<DirectorySelection>[];\n}\n\n/** Captures one configuration or durable-storage boundary, including reference meaning. */\nexport function parseServiceDirectory(\n value: unknown,\n code: RelayErrorCode,\n): Readonly<ServiceDirectoryDocument> {\n const context = new WeakSet<object>();\n const fail = (message: string): never => relayFailure(code, message);\n const record = (entry: unknown, keys: readonly string[]) =>\n exactCapturedRecord(\n captureRecord(entry, \"service directory record\", context, fail),\n keys,\n \"service directory record\",\n fail,\n );\n const id = (entry: unknown) => parseClientId(entry, fail);\n const subject = (entry: unknown) => boundedText(entry, 256, \"directory subject\", code);\n function rows<T>(\n entries: unknown,\n parse: (entry: unknown) => T,\n key: (entry: T) => readonly string[],\n ): readonly Readonly<T>[] {\n const seen = new Set<string>();\n return Object.freeze(\n captureDenseArray(entries, \"directory records\", context, fail).map((entry) => {\n const parsed = parse(entry);\n const identity = JSON.stringify(key(parsed));\n if (seen.has(identity)) return fail(\"directory records repeat an identity\");\n seen.add(identity);\n return Object.freeze(parsed);\n }),\n );\n }\n try {\n const root = record(value, [\n \"version\",\n \"workspaces\",\n \"applications\",\n \"memberships\",\n \"ownerDevices\",\n \"accounts\",\n \"selections\",\n ]);\n if (root.version !== OAATH_SERVICE_DIRECTORY_VERSION)\n return fail(\"service directory version is unsupported\");\n const workspaces = rows(\n root.workspaces,\n (value): DirectoryWorkspace => {\n const entry = record(value, [\"workspaceId\", \"kind\"]);\n if (entry.kind !== \"personal\" && entry.kind !== \"team\")\n return fail(\"workspace kind is unsupported\");\n return { workspaceId: id(entry.workspaceId), kind: entry.kind };\n },\n (entry) => [entry.workspaceId],\n );\n const applications = rows(\n root.applications,\n (value): DirectoryApplication => {\n const entry = record(value, [\"clientId\", \"applicationId\", \"applicationName\"]);\n return {\n clientId: id(entry.clientId),\n applicationId: id(entry.applicationId),\n applicationName: boundedText(entry.applicationName, 256, \"application name\", code),\n };\n },\n (entry) => [entry.clientId],\n );\n const memberships = rows(\n root.memberships,\n (value): DirectoryMembership => {\n const entry = record(value, [\"workspaceId\", \"clientId\", \"subject\"]);\n return {\n workspaceId: id(entry.workspaceId),\n clientId: id(entry.clientId),\n subject: subject(entry.subject),\n };\n },\n (entry) => [entry.workspaceId, entry.clientId, entry.subject],\n );\n const ownerDevices = rows(\n root.ownerDevices,\n (value): DirectoryOwnerDevice => {\n const entry = record(value, [\"workspaceId\", \"ownerDeviceId\", \"subject\"]);\n return {\n workspaceId: id(entry.workspaceId),\n ownerDeviceId: id(entry.ownerDeviceId),\n subject: subject(entry.subject),\n };\n },\n (entry) => [entry.workspaceId, entry.ownerDeviceId],\n );\n const accounts = rows(\n root.accounts,\n (value): DirectoryAccount => {\n const entry = record(value, [\n \"workspaceId\",\n \"accountId\",\n \"ownerDeviceId\",\n \"account\",\n \"ownerValidator\",\n \"chainIds\",\n ]);\n const chainIds = captureDenseArray(entry.chainIds, \"account chains\", context, fail).map(\n (chainId) => {\n if (typeof chainId !== \"number\" || !Number.isSafeInteger(chainId) || chainId < 1)\n return fail(\"account chain must be a positive integer\");\n return chainId;\n },\n );\n if (\n chainIds.length < 1 ||\n chainIds.length > 32 ||\n new Set(chainIds).size !== chainIds.length\n )\n return fail(\"account chains must contain 1 to 32 distinct chains\");\n return {\n workspaceId: id(entry.workspaceId),\n accountId: parseAccountId(entry.accountId, fail),\n ownerDeviceId: id(entry.ownerDeviceId),\n ...captureServiceAccount(entry.account, entry.ownerValidator, context, fail),\n chainIds: Object.freeze(chainIds),\n };\n },\n (entry) => [entry.workspaceId, entry.accountId],\n );\n const selections = rows(\n root.selections,\n (value): DirectorySelection => {\n const entry = record(value, [\"clientId\", \"subject\", \"workspaceId\", \"accountId\"]);\n return {\n clientId: id(entry.clientId),\n subject: subject(entry.subject),\n workspaceId: id(entry.workspaceId),\n accountId: parseAccountId(entry.accountId, fail),\n };\n },\n (entry) => [entry.clientId, entry.subject],\n );\n\n const workspaceIds = new Set(workspaces.map((entry) => entry.workspaceId));\n const clientIds = new Set(applications.map((entry) => entry.clientId));\n for (const entry of [...memberships, ...ownerDevices, ...accounts]) {\n if (!workspaceIds.has(entry.workspaceId))\n return fail(\"directory reference names an absent workspace\");\n }\n for (const entry of memberships) {\n if (!clientIds.has(entry.clientId)) return fail(\"membership names an absent application\");\n }\n for (const account of accounts) {\n if (\n !ownerDevices.some(\n (owner) =>\n owner.workspaceId === account.workspaceId &&\n owner.ownerDeviceId === account.ownerDeviceId,\n )\n )\n return fail(\"account names an absent owner device\");\n }\n // Selections can outlive membership/account removal. They never confer access.\n return Object.freeze({\n version: OAATH_SERVICE_DIRECTORY_VERSION,\n workspaces,\n applications,\n memberships,\n ownerDevices,\n accounts,\n selections,\n });\n } catch {\n return fail(\"service directory is invalid\");\n }\n}\n","import {\n captureRecord,\n exactCapturedRecord,\n isKernelExistingAccountProfile,\n OAATH_WORKSPACE_ACCOUNT_CONTEXT_VERSION,\n parseAccountId,\n parseClientId,\n} from \"@oaath/protocol\";\nimport type { RelayOwnerRouting } from \"../authorization/request.js\";\nimport { classifyStoredAuthorizationScope } from \"../authorization/scope.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayBootstrapConfiguration, RelayBootstrapSelection } from \"../relay/handler.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { AuthorizationOwnerRoute } from \"../store/records.js\";\nimport {\n type DirectoryAccount,\n type DirectoryOwnerDevice,\n parseServiceDirectory,\n type ServiceDirectoryDocument,\n} from \"./records.js\";\n\nexport interface ServiceDirectorySnapshot {\n readonly revision: number;\n readonly directory: Readonly<ServiceDirectoryDocument>;\n}\n\n/** One atomic row. A failed/ambiguous write is never automatically retried. */\nexport interface ServiceDirectoryStore {\n read(): Promise<unknown>;\n /** Null expects absence; otherwise replace exactly this revision and advance it by one. */\n compareAndSwap(\n expectedRevision: number | null,\n directory: Readonly<ServiceDirectoryDocument>,\n ): Promise<boolean>;\n}\n\n/** Deployment-authenticated pairing result; contains public identity only. */\nexport interface EnrollOwnerDeviceInput {\n readonly expectedRevision: number;\n readonly device: Readonly<DirectoryOwnerDevice>;\n readonly accounts: readonly Readonly<DirectoryAccount>[];\n}\n\nexport interface ServiceDirectory extends RelayBootstrapConfiguration, RelayOwnerRouting {\n read(): Promise<Readonly<ServiceDirectorySnapshot> | null>;\n /** Admission for the original permission context, restricted to its configured chains. */\n resolveRevocationOwner(\n caller: Readonly<RelayCaller>,\n input: Readonly<{ requestId: string; requestedScope: string; chainId: number }>,\n ): Promise<Readonly<AuthorizationOwnerRoute> | null>;\n /** Deployment administration capability, never an unauthenticated HTTP endpoint. */\n replace(input: {\n readonly expectedRevision: number | null;\n readonly directory: unknown;\n }): Promise<boolean>;\n /**\n * Atomically enroll a new P-256 phone and its Kernel accounts in one workspace.\n * The deployment authenticates pairing and assigns the owner subject first.\n * No membership, authentication credential, or onchain operation is created.\n * False means the expected revision lost; read before a fresh admin decision.\n */\n enrollOwnerDevice(input: Readonly<EnrollOwnerDeviceInput>): Promise<boolean>;\n /** False means a concurrent directory write won; read current state before choosing again. */\n selectAccount(\n caller: Readonly<RelayCaller>,\n selection: { readonly workspaceId: string; readonly accountId: string },\n ): Promise<boolean>;\n}\n\n/**\n * Owns membership/account selection and atomic phone enrollment over one\n * versioned directory document. Enrollment moves absent device/accounts to\n * jointly registered identities; it cannot overwrite them. Its single CAS is\n * the persisted evidence and cleanup owner: a lost response causes no retry,\n * and a recreated reader sees the whole enrollment or none of it.\n * Writes use compare-and-swap; bootstrap/admission reads never reserve resources.\n * A reload reads durable state afresh. Member removal blocks new admission but\n * does not revoke grants or delete operation evidence. The deployment owns store\n * resources and cleanup; this service owns no connections and retries no writes.\n */\nexport function createServiceDirectory(store: ServiceDirectoryStore): Readonly<ServiceDirectory> {\n async function read(): Promise<Readonly<ServiceDirectorySnapshot> | null> {\n const raw = await store.read();\n if (raw === null) return null;\n try {\n const fail = (message: string): never => relayFailure(\"relay_record_unreadable\", message);\n const snapshot = exactCapturedRecord(\n captureRecord(raw, \"directory snapshot\", new WeakSet(), fail),\n [\"revision\", \"directory\"],\n \"directory snapshot\",\n fail,\n );\n if (\n typeof snapshot.revision !== \"number\" ||\n !Number.isSafeInteger(snapshot.revision) ||\n snapshot.revision < 1\n )\n return fail(\"directory revision is invalid\");\n return Object.freeze({\n revision: snapshot.revision,\n directory: parseServiceDirectory(snapshot.directory, \"relay_record_unreadable\"),\n });\n } catch {\n return relayFailure(\"relay_record_unreadable\", \"directory snapshot is unreadable\");\n }\n }\n function assigned(\n directory: Readonly<ServiceDirectoryDocument>,\n caller: Readonly<RelayCaller>,\n workspaceId: string,\n ): boolean {\n return (\n caller.role === \"client\" &&\n directory.memberships.some(\n (member) =>\n member.workspaceId === workspaceId &&\n member.clientId === caller.clientId &&\n member.subject === caller.subject,\n )\n );\n }\n async function resolveOwner(\n caller: Readonly<RelayCaller>,\n input: Readonly<{ requestId: string; requestedScope: string }>,\n chainId?: number,\n ): Promise<Readonly<AuthorizationOwnerRoute> | null> {\n const scope = classifyStoredAuthorizationScope(input.requestedScope, input.requestId);\n if (scope.kind !== \"permission-request\") return null;\n const request = scope.request;\n const snapshot = await read();\n if (snapshot === null || !assigned(snapshot.directory, caller, request.context.workspaceId))\n return null;\n const directory = snapshot.directory;\n const workspace = directory.workspaces.find(\n (entry) => entry.workspaceId === request.context.workspaceId,\n );\n const application = directory.applications.find((entry) => entry.clientId === caller.clientId);\n const account = directory.accounts.find(\n (entry) =>\n entry.workspaceId === request.context.workspaceId &&\n entry.accountId === request.context.accountId,\n );\n if (\n !workspace ||\n !application ||\n !account ||\n (chainId !== undefined && !account.chainIds.includes(chainId)) ||\n workspace.kind !== request.context.workspaceKind ||\n application.applicationId !== request.application.applicationId ||\n caller.clientId !== request.application.clientId ||\n JSON.stringify(account.account) !== JSON.stringify(request.logicalAccount)\n )\n return null;\n const device = directory.ownerDevices.find(\n (entry) =>\n entry.workspaceId === workspace.workspaceId &&\n entry.ownerDeviceId === account.ownerDeviceId,\n );\n if (!device) return null;\n return Object.freeze({ ownerDeviceId: device.ownerDeviceId, ownerSubject: device.subject });\n }\n return Object.freeze<ServiceDirectory>({\n read,\n resolveOwner,\n resolveRevocationOwner(caller, input) {\n return resolveOwner(caller, input, input.chainId);\n },\n async replace(input): Promise<boolean> {\n if (\n input.expectedRevision !== null &&\n (!Number.isSafeInteger(input.expectedRevision) ||\n input.expectedRevision < 1 ||\n input.expectedRevision === Number.MAX_SAFE_INTEGER)\n ) {\n return relayFailure(\"relay_request_invalid\", \"expected directory revision is invalid\");\n }\n return store.compareAndSwap(\n input.expectedRevision,\n parseServiceDirectory(input.directory, \"relay_request_invalid\"),\n );\n },\n async enrollOwnerDevice(input): Promise<boolean> {\n // Configuration is copied before the first await. The directory codec\n // below captures the complete proposed durable document once.\n const enrollment = structuredClone(input);\n if (\n !Number.isSafeInteger(enrollment.expectedRevision) ||\n enrollment.expectedRevision < 1 ||\n enrollment.expectedRevision === Number.MAX_SAFE_INTEGER\n ) {\n return relayFailure(\"relay_request_invalid\", \"expected directory revision is invalid\");\n }\n const snapshot = await read();\n if (snapshot === null)\n return relayFailure(\"relay_not_found\", \"service directory is not initialized\");\n if (snapshot.revision !== enrollment.expectedRevision) return false;\n // Appending lets the directory codec reject existing identities instead\n // of silently replacing a phone, account, or another workspace's facts.\n const proposed = parseServiceDirectory(\n {\n ...snapshot.directory,\n ownerDevices: [...snapshot.directory.ownerDevices, enrollment.device],\n accounts: [...snapshot.directory.accounts, ...enrollment.accounts],\n },\n \"relay_request_invalid\",\n );\n const device = proposed.ownerDevices.at(-1);\n const accounts = proposed.accounts.slice(snapshot.directory.accounts.length);\n const owner = accounts[0]?.account.ownerCredential;\n if (\n !device ||\n owner?.kind !== \"p256\" ||\n accounts.some(\n (account) =>\n account.workspaceId !== device.workspaceId ||\n account.ownerDeviceId !== device.ownerDeviceId ||\n isKernelExistingAccountProfile(account.account) ||\n account.account.factoryRoute !== \"kernel_factory\" ||\n account.account.ownerCredential.kind !== \"p256\" ||\n account.account.ownerCredential.publicKey !== owner.publicKey,\n )\n ) {\n return relayFailure(\n \"relay_request_invalid\",\n \"phone accounts must bind one workspace, device, and P-256 owner\",\n );\n }\n return store.compareAndSwap(enrollment.expectedRevision, proposed);\n },\n async selectAccount(caller, selection): Promise<boolean> {\n const fail = (message: string): never => relayFailure(\"relay_request_invalid\", message);\n const workspaceId = parseClientId(selection.workspaceId, fail);\n const accountId = parseAccountId(selection.accountId, fail);\n const snapshot = await read();\n if (snapshot === null || !assigned(snapshot.directory, caller, workspaceId))\n return relayFailure(\"relay_forbidden\", \"caller is not a member of this workspace\");\n if (\n !snapshot.directory.accounts.some(\n (account) => account.workspaceId === workspaceId && account.accountId === accountId,\n )\n )\n return relayFailure(\"relay_not_found\", \"account is not registered in this workspace\");\n const selections = snapshot.directory.selections.filter(\n (entry) => entry.clientId !== caller.clientId || entry.subject !== caller.subject,\n );\n selections.push(\n Object.freeze({\n clientId: caller.clientId,\n subject: caller.subject,\n workspaceId,\n accountId,\n }),\n );\n return store.compareAndSwap(\n snapshot.revision,\n Object.freeze({ ...snapshot.directory, selections: Object.freeze(selections) }),\n );\n },\n async resolve(caller): Promise<Readonly<RelayBootstrapSelection> | null> {\n const snapshot = await read();\n if (snapshot === null) return null;\n const directory = snapshot.directory;\n const selection = directory.selections.find(\n (entry) => entry.clientId === caller.clientId && entry.subject === caller.subject,\n );\n if (!selection || !assigned(directory, caller, selection.workspaceId)) return null;\n const workspace = directory.workspaces.find(\n (entry) => entry.workspaceId === selection.workspaceId,\n );\n const application = directory.applications.find(\n (entry) => entry.clientId === caller.clientId,\n );\n const account = directory.accounts.find(\n (entry) =>\n entry.workspaceId === selection.workspaceId && entry.accountId === selection.accountId,\n );\n if (!workspace || !application || !account) return null;\n return Object.freeze({\n application: Object.freeze({\n applicationId: application.applicationId,\n applicationName: application.applicationName,\n }),\n context: Object.freeze({\n version: OAATH_WORKSPACE_ACCOUNT_CONTEXT_VERSION,\n workspaceId: workspace.workspaceId,\n workspaceKind: workspace.kind,\n accountId: account.accountId,\n }),\n account: account.account,\n ownerValidator: account.ownerValidator,\n chainIds: account.chainIds,\n });\n },\n });\n}\n\n/** Ephemeral deployment/test store; the service captures every read and write boundary. */\nexport function createMemoryServiceDirectoryStore(): ServiceDirectoryStore {\n let snapshot: ServiceDirectorySnapshot | null = null;\n return {\n async read() {\n return structuredClone(snapshot);\n },\n async compareAndSwap(expectedRevision, directory) {\n if ((snapshot?.revision ?? null) !== expectedRevision) return false;\n snapshot = { revision: (expectedRevision ?? 0) + 1, directory: structuredClone(directory) };\n return true;\n },\n };\n}\n","/**\n * Authenticated client pickup of a released authorization code.\n *\n * ```text\n * state and owner reads the request and decision records; writes nothing\n * transitions none — pickup is idempotent\n * terminal follows the decision record\n * retry positively safe? yes: the code stays one-shot at consumption, where the\n * PKCE verifier and the code hash lock decide\n * ```\n *\n * The relay mints the code, so releasing the sealed copy to the authenticated\n * creating client adds no authority: consumption still requires the verifier\n * only that client holds. The request's stored clientId owns who may pick up;\n * any other caller reads absence, never existence.\n *\n * @author taek <leekt216@gmail.com>\n */\nimport { openArtifact } from \"../artifact/encrypt.js\";\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport { type RelayStore, withRelayTransaction } from \"../store/interface.js\";\n\nexport interface FetchAuthorizationCodeInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n readonly kms: RelayKms;\n /** Authenticated `client` caller; only the creating client may pick up. */\n readonly caller: RelayCaller;\n readonly requestId: string;\n}\n\nexport type FetchedAuthorizationCode =\n | Readonly<{ outcome: \"pending\" }>\n | Readonly<{ outcome: \"rejected\"; decidedAt: number }>\n | Readonly<{ outcome: \"approved\"; decidedAt: number; code: string; codeExpiresAt: number }>;\n\nexport async function fetchAuthorizationCode(\n input: FetchAuthorizationCodeInput,\n): Promise<FetchedAuthorizationCode> {\n const now = relayNow(input.clock);\n const decided = await withRelayTransaction(input.store, async (transaction) => {\n const request = await transaction.lockAuthorizationRequest(input.requestId);\n if (!request || request.clientId !== input.caller.clientId) {\n return relayFailure(\"relay_not_found\", \"authorization request does not exist\");\n }\n const decision = await transaction.lockAuthorizationDecision(input.requestId);\n if (!decision) {\n if (now >= request.expiresAt) {\n return relayFailure(\"relay_expired\", \"authorization request expired\");\n }\n return null;\n }\n return decision;\n });\n if (decided === null) return Object.freeze({ outcome: \"pending\" });\n if (decided.outcome === \"rejected\" || decided.codeRef === null) {\n return Object.freeze({ outcome: \"rejected\", decidedAt: decided.decidedAt });\n }\n const codeExpiresAt = decided.codeExpiresAt ?? 0;\n if (now >= codeExpiresAt) {\n return relayFailure(\"relay_expired\", \"authorization code expired\");\n }\n // Opened only after every stored fact agreed; the plaintext never persists.\n return Object.freeze({\n outcome: \"approved\",\n decidedAt: decided.decidedAt,\n code: await openArtifact(input.kms, decided.codeRef),\n codeExpiresAt,\n });\n}\n","/**\n * Grant reference verification: one read-only projection of the relay's\n * durable authorization evidence into the `@oaath/protocol` grant-reference\n * contract.\n *\n * ```text\n * state and owner no new state; the request, decision, and capability\n * invalidation records already own every fact projected\n * persisted evidence the immutable request (subject, clientId, audience,\n * requestedScope), terminal decision, sealed approval\n * artifact and one-shot invalidation\n * resource occupied? nothing; verification is a pure read\n * retry positively safe? yes: no write exists, so a replay answers the same\n * stored facts and never mutates the Grant\n * transitions none; this owner performs no transition\n * crash/reload nothing to recover; the projected records recover\n * through their own owners\n * cleanup owner none\n * ```\n *\n * Decision semantics, fail closed and in deterministic order:\n *\n * 1. absent grant, another client's grant, or unreadable/contradictory stored\n * scope → `unknown` (absence is reported for another client's grant so the\n * endpoint is not an existence oracle);\n * 2. subject, client, or audience assertion mismatch → `denied` before any\n * lifecycle fact is revealed;\n * 3. pending, rejected, revoked, expired → `denied`;\n * 4. revision other than the single approved authority revision → `denied`;\n * 5. reviewed call set digest differing from the permitted call set →\n * `denied`;\n * 6. otherwise → `authorized` with the immutable reference evidence.\n *\n * The sealed permission decision owns the approved policy. The requested\n * policy is its upper bound, checked through applyPermissionDecision. A missing\n * or unreadable artifact never falls back to outcome=approved. This reads\n * service-approved authority; Kernel capability verification and onchain\n * installation remain the runtime's separate domain.\n * `expiresAt`/`validUntil` speak protocol seconds; the relay clock speaks\n * milliseconds and is floored into the protocol domain before comparison.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport {\n type GrantVerificationResult,\n hashGrantPolicy,\n hashGrantPolicyCalls,\n OAATH_GRANT_REFERENCE_APPROVED_REVISION,\n OAATH_GRANT_REFERENCE_VERSION,\n type OaathGrantRef,\n parseVerifyGrantRevisionInput,\n type VerifyGrantRevisionInput,\n} from \"@oaath/protocol\";\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { relayFailure } from \"../relay/errors.js\";\nimport type { RelayCaller } from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport type { RelayStore } from \"../store/interface.js\";\nimport { withRelayTransaction } from \"../store/interface.js\";\nimport { readApprovedPermission } from \"./approved-permission.js\";\nimport { classifyStoredAuthorizationScope } from \"./scope.js\";\n\nexport interface VerifyGrantReferenceInput {\n readonly store: RelayStore;\n readonly clock: RelayClock;\n readonly kms: RelayKms;\n /** Authenticated `client` caller; only its own Grants are visible. */\n readonly caller: RelayCaller;\n readonly assertion: unknown;\n}\n\nfunction unknown(code: \"grant_unknown\" | \"grant_unreadable\"): GrantVerificationResult {\n return Object.freeze({ state: \"unknown\" as const, code });\n}\n\nfunction denied(\n code:\n | \"grant_pending\"\n | \"grant_rejected\"\n | \"grant_revoked\"\n | \"grant_expired\"\n | \"grant_revision_mismatch\"\n | \"grant_subject_mismatch\"\n | \"grant_client_mismatch\"\n | \"grant_audience_mismatch\"\n | \"grant_calls_mismatch\",\n): GrantVerificationResult {\n return Object.freeze({ state: \"denied\" as const, code });\n}\n\nexport async function verifyGrantReference(\n input: VerifyGrantReferenceInput,\n): Promise<GrantVerificationResult> {\n let assertion: Readonly<VerifyGrantRevisionInput>;\n try {\n assertion = parseVerifyGrantRevisionInput(input.assertion);\n } catch {\n return relayFailure(\"relay_request_invalid\", \"grant verification assertion is malformed\");\n }\n const now = relayNow(input.clock);\n\n return withRelayTransaction(input.store, async (transaction) => {\n const request = await transaction.lockAuthorizationRequest(assertion.grantId);\n // Another client's Grant reads as unknown: not an existence oracle.\n if (!request || request.clientId !== input.caller.clientId) {\n return unknown(\"grant_unknown\");\n }\n\n // The stored scope must be the exact permission request this Grant was\n // created from; anything else is unreadable evidence and never authorizes.\n const scope = classifyStoredAuthorizationScope(request.requestedScope, request.requestId);\n if (scope.kind !== \"permission-request\") {\n return unknown(\"grant_unreadable\");\n }\n // Contradictory evidence fails closed: the authenticated creator and the\n // scope's own application binding must name the same client.\n if (scope.request.application.clientId !== request.clientId) {\n return unknown(\"grant_unreadable\");\n }\n\n // Binding assertions deny before any lifecycle fact is revealed.\n if (assertion.subject !== request.subject) return denied(\"grant_subject_mismatch\");\n if (assertion.clientId !== request.clientId) return denied(\"grant_client_mismatch\");\n if (\n request.organizationAudience === null ||\n assertion.organizationAudience !== request.organizationAudience\n ) {\n return denied(\"grant_audience_mismatch\");\n }\n\n const decision = await transaction.lockAuthorizationDecision(assertion.grantId);\n if (!decision) return denied(\"grant_pending\");\n if (decision.outcome === \"rejected\") return denied(\"grant_rejected\");\n if (await transaction.lockCapabilityInvalidation(assertion.grantId)) {\n return denied(\"grant_revoked\");\n }\n // The sealed artifact is the authoritative approval. Request policy is\n // only its upper bound; a terminal OAuth outcome alone names no call set.\n const retained = await readApprovedPermission(\n transaction,\n input.kms,\n request,\n decision,\n scope.request,\n );\n const approval = retained?.permission ?? null;\n if (approval === null) return unknown(\"grant_unreadable\");\n // The policy's inclusive expiry bounds the authority usable for covered\n // calls; it is always earlier than the Grant expiry, so it is the strict\n // fail-closed bound. Protocol time is whole seconds.\n const validUntil = approval.approvedPolicy.validUntil;\n if (validUntil === null || Math.floor(now / 1_000) > validUntil) {\n return denied(\"grant_expired\");\n }\n\n if (assertion.revision !== OAATH_GRANT_REFERENCE_APPROVED_REVISION) {\n return denied(\"grant_revision_mismatch\");\n }\n if (assertion.requiredCallsDigest !== hashGrantPolicyCalls(approval.approvedPolicy.calls)) {\n return denied(\"grant_calls_mismatch\");\n }\n\n const ref: Readonly<OaathGrantRef> = Object.freeze({\n version: OAATH_GRANT_REFERENCE_VERSION,\n grantId: request.requestId,\n revision: OAATH_GRANT_REFERENCE_APPROVED_REVISION,\n subject: request.subject,\n clientId: request.clientId,\n organizationAudience: request.organizationAudience,\n state: \"active\" as const,\n policyDigest: hashGrantPolicy(approval.approvedPolicy),\n });\n return Object.freeze({ state: \"authorized\" as const, ref });\n });\n}\n","/**\n * Deployment-owned client/device authentication port.\n *\n * The relay never parses credentials. It hands the request to the deployment,\n * which returns the authenticated bindings or nothing. `clientId` and `subject`\n * come only from here: wire input may never declare either.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport {\n type CaptureContext,\n captureDenseArray,\n captureRecord,\n exactCapturedRecord,\n} from \"@oaath/protocol\";\nimport { OaathRelayError, relayFailure } from \"../relay/errors.js\";\nimport { boundedText, canonicalIdentifier, RELAY_LIMITS } from \"../store/records.js\";\n\n/** `client` is the requesting application; `owner` is the approving account owner. */\nexport type RelayCallerRole = \"client\" | \"owner\";\n\nconst MAX_REDIRECT_URIS = 8;\n\nexport interface RelayCaller {\n readonly role: RelayCallerRole;\n readonly clientId: string;\n /** Pairwise user/device subject. */\n readonly subject: string;\n /**\n * Redirect URIs the deployment registered for this client. An authorization\n * code may only be requested for one of them. `owner` callers pass an empty\n * list; they never receive a code at a redirect URI.\n */\n readonly redirectUris: readonly string[];\n /**\n * The application organization/audience the deployment binds this caller to,\n * or null when the deployment declares none. Like `clientId` and `subject`\n * it comes only from the authentication port; wire input may never declare\n * it. It is captured onto each authorization request, and Grant reference\n * verification later denies any assertion that does not match the captured\n * value — a deployment without audiences therefore never verifies one.\n */\n readonly organizationAudience: string | null;\n}\n\nexport interface RelayAuthentication {\n /**\n * Resolves to a `RelayCaller`-shaped value, or `null`/`undefined` when the\n * caller is not authenticated. May throw `OaathRelayError` to choose a code.\n */\n authenticate(request: Request): Promise<unknown>;\n}\n\nfunction captureCaller(value: unknown): RelayCaller {\n const context: CaptureContext = new WeakSet();\n // A port that breaks its own contract is an internal failure, not a 401.\n const fail = (message: string): never => relayFailure(\"relay_internal\", message);\n const captured = captureRecord(value, \"authenticated caller\", context, fail);\n // An absent field and an explicit null both mean \"no audience declared\", so\n // ports written before audiences existed keep their exact shape.\n const declaresAudience = Object.hasOwn(captured, \"organizationAudience\");\n const record = exactCapturedRecord(\n captured,\n declaresAudience\n ? [\"role\", \"clientId\", \"subject\", \"redirectUris\", \"organizationAudience\"]\n : [\"role\", \"clientId\", \"subject\", \"redirectUris\"],\n \"authenticated caller\",\n fail,\n );\n if (record.role !== \"client\" && record.role !== \"owner\") {\n return relayFailure(\"relay_internal\", \"authenticated caller role is unsupported\");\n }\n const redirectUris = captureDenseArray(record.redirectUris, \"caller redirectUris\", context, fail);\n if (redirectUris.length > MAX_REDIRECT_URIS) {\n return relayFailure(\"relay_internal\", \"caller redirectUris is unbounded\");\n }\n return Object.freeze({\n role: record.role,\n clientId: canonicalIdentifier(record.clientId, \"caller clientId\", \"relay_internal\"),\n subject: canonicalIdentifier(record.subject, \"caller subject\", \"relay_internal\"),\n redirectUris: Object.freeze(\n redirectUris.map((uri) =>\n boundedText(uri, RELAY_LIMITS.redirectUri, \"caller redirectUri\", \"relay_internal\"),\n ),\n ),\n organizationAudience:\n declaresAudience && record.organizationAudience !== null\n ? canonicalIdentifier(\n record.organizationAudience,\n \"caller organizationAudience\",\n \"relay_internal\",\n )\n : null,\n });\n}\n\nexport async function authenticateCaller(\n authentication: RelayAuthentication,\n request: Request,\n required: RelayCallerRole | readonly RelayCallerRole[],\n): Promise<RelayCaller> {\n let authenticated: unknown;\n try {\n authenticated = await authentication.authenticate(request);\n } catch (error) {\n // Unreadable authentication is not authentication.\n if (error instanceof OaathRelayError) throw error;\n return relayFailure(\"relay_unauthenticated\", \"authentication port failed\");\n }\n if (authenticated === null || authenticated === undefined) {\n return relayFailure(\"relay_unauthenticated\", \"caller is not authenticated\");\n }\n const caller = captureCaller(authenticated);\n const roles = typeof required === \"string\" ? [required] : required;\n if (!roles.includes(caller.role)) {\n return relayFailure(\"relay_forbidden\", \"caller may not act in the required role\");\n }\n return caller;\n}\n","/**\n * Optional deployment-owned limiter port.\n *\n * There is no default limiter: an unset port means no limiting, and the relay\n * never invents a policy the deployment did not choose. A limiter that fails is\n * treated as `limited`, because an unreadable limiter is not permission.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { relayFailure } from \"../relay/errors.js\";\n\nexport interface RelayRateLimitInput {\n /** Stable route name, never a credential-bearing URL. */\n readonly route: string;\n readonly clientId: string | null;\n}\n\nexport interface RelayRateLimiter {\n /** Resolves to `\"allowed\"` or `\"limited\"`. Anything else is `limited`. */\n check(input: RelayRateLimitInput): Promise<unknown>;\n}\n\nexport async function assertWithinRateLimit(\n limiter: RelayRateLimiter | undefined,\n input: RelayRateLimitInput,\n): Promise<void> {\n if (!limiter) return;\n let verdict: unknown;\n try {\n verdict = await limiter.check(input);\n } catch {\n return relayFailure(\"relay_rate_limited\", \"rate limiter is unreadable\");\n }\n if (verdict !== \"allowed\") {\n return relayFailure(\"relay_rate_limited\", \"rate limiter rejected the call\");\n }\n}\n","/**\n * Fetch-standard relay handler.\n *\n * Every wire input is exact-captured once here and handed to a use case as typed\n * data. Every failure leaves as a structured code projected to a status; no\n * message text, driver output, or internal detail reaches a response body.\n *\n * Endpoints:\n *\n * ```text\n * POST /authorization/requests client create request\n * GET /authorization/requests/{requestId} owner fetch request\n * POST /authorization/requests/{requestId}/decision owner approve or reject\n * GET /authorization/requests/{requestId}/code client released-code pickup\n * POST /authorization/codes/consume client one-time code consume\n * POST /authorization/artifacts/{artifactId}/claim client one-time artifact claim\n * POST /authorization/resume client fresh auth + recovery read\n * GET /bootstrap client URL-only service context\n * POST /invalidations client capability invalidation\n * POST /grants/verify client grant reference verification\n * POST /grants/{grantId}/revocations/{chainId} client request/recover phone custody\n * GET /grants/{grantId}/revocations/{chainId} client current custody status\n * POST /chains/{chainId}/{port} client chain execution relay,\n * port in reads |\n * observation | bundler |\n * quote | submissions | usage\n * POST /chains/{chainId}/paymaster/{method} client registered paymaster proxy,\n * method in stub-data | data\n * ```\n *\n * EXPERIMENTAL PREVIEW routes for the owner-phone approval surface. Preview\n * means: no stability guarantee and no production qualification. Consent and\n * decision shapes are pinned field-for-field by the strict Swift decoders in\n * `native/ios/Sources/OwnerPhone/{Projection,Decision}.swift`.\n *\n * ```text\n * GET /native/projections/{operationId} owner consent projection\n * POST /native/decisions/{operationId} owner approve or reject saga\n * POST /native/revocation-decisions/{operationId} owner revocation custody decision\n * ```\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport {\n type CaptureContext,\n captureDenseArray,\n captureRecord,\n exactCapturedRecord,\n OAATH_SERVICE_BOOTSTRAP_VERSION,\n parseServiceBootstrap,\n readRpcBundlerRejection,\n readValidationGasDiagnostic,\n type ServiceBootstrap,\n} from \"@oaath/protocol\";\nimport { claimEncryptedArtifact } from \"../artifact/claim.js\";\nimport { consumeAuthorizationCode } from \"../authorization/code.js\";\nimport type { AuthorizationDecisionCommand } from \"../authorization/decision.js\";\nimport { submitAuthorizationDecision } from \"../authorization/decision.js\";\nimport { fetchAuthorizationCode } from \"../authorization/pickup.js\";\nimport {\n type AuthorizationState,\n createAuthorizationRequest,\n fetchAuthorizationRequest,\n type RelayOwnerRouting,\n} from \"../authorization/request.js\";\nimport { resumeAuthorization } from \"../authorization/resume.js\";\nimport { verifyGrantReference } from \"../authorization/verify.js\";\nimport { type RelayClock, relayNow } from \"../clock.js\";\nimport { submitOwnerPhoneDecision } from \"../native/decision.js\";\nimport { listOwnerPhoneRequests } from \"../native/inbox.js\";\nimport type { OwnerPhonePermissionApprovals } from \"../native/permission-approval.js\";\nimport {\n projectOwnerPhonePermissionSigning,\n projectOwnerPhoneRequest,\n} from \"../native/projection.js\";\nimport { REVOCATION_OPERATION_PREFIX } from \"../revocation/records.js\";\nimport {\n fetchClientPhoneRevocation,\n fetchOwnerPhoneRevocation,\n type RequestOwnerPhoneRevocationInput,\n requestOwnerPhoneRevocation,\n submitOwnerPhoneRevocationDecision,\n} from \"../revocation/service.js\";\nimport {\n authenticateCaller,\n type RelayAuthentication,\n type RelayCaller,\n type RelayCallerRole,\n} from \"../security/authentication.js\";\nimport type { RelayKms } from \"../security/kms.js\";\nimport { assertWithinRateLimit, type RelayRateLimiter } from \"../security/rate-limit.js\";\nimport type { RelaySessionSignerProvider } from \"../session-signer/kms-provider.js\";\nimport { type RelayStore, withRelayTransaction } from \"../store/interface.js\";\nimport {\n boundedText,\n canonicalIdentifier,\n OAATH_CAPABILITY_INVALIDATION_RECORD_VERSION,\n RELAY_LIMITS,\n timestamp,\n} from \"../store/records.js\";\nimport {\n jsonResponse,\n OaathRelayError,\n relayErrorCode,\n relayErrorResponse,\n relayFailure,\n} from \"./errors.js\";\n\nconst DEFAULT_REQUEST_TTL_MS = 300_000;\nconst DEFAULT_CODE_TTL_MS = 60_000;\nconst DEFAULT_MAX_BODY_BYTES = 65_536;\nconst MAX_TTL_MS = 86_400_000;\n/** The relay owns the authorization-code lifetime ceiling, in milliseconds. */\nconst MAX_CODE_TTL_MS = 600_000;\nconst MAX_PAYMASTER_REQUEST_TIMEOUT_MS = 30_000;\nconst HASH = /^0x[0-9a-f]{64}$/u;\n\nconst INVALID = \"relay_request_invalid\" as const;\n\n/**\n * One deployment-injected chain execution surface the relay serves to clients.\n * Each port takes exactly one captured request value and answers with the\n * evidence it owns; the relay never interprets the payload beyond exact wire\n * hygiene, so port meaning stays with its SDK owner.\n */\nexport interface RelayChainPort {\n readonly gas?: Readonly<{ enableVerificationGasFloor: bigint }>;\n readonly chainId: number;\n readonly reads: (request: unknown) => Promise<unknown>;\n readonly observation: (request: unknown) => Promise<unknown>;\n readonly bundler: (request: unknown) => Promise<unknown>;\n readonly quote: (request: unknown) => Promise<unknown>;\n /** Opens, sends, and settles one submission in one call; never retried here. */\n readonly submission: (request: unknown) => Promise<unknown>;\n /** Finalized per-grant usage evidence, or null when this chain serves none. */\n readonly usage: ((request: unknown) => Promise<unknown>) | null;\n readonly feePayer: Readonly<{ address: `0x${string}`; balance: string }> | null;\n /** Authenticated commitment to one exact ERC-7902 static paymaster, or null. */\n readonly staticPaymasterConfigurationHash: `0x${string}` | null;\n}\n\n/** Selection resolved from the deployment's membership and account records. */\nexport interface RelayBootstrapSelection {\n readonly application: Readonly<\n Pick<ServiceBootstrap[\"application\"], \"applicationId\" | \"applicationName\">\n >;\n readonly context: ServiceBootstrap[\"context\"];\n readonly account: ServiceBootstrap[\"account\"];\n readonly ownerValidator: `0x${string}` | null;\n readonly chainIds: readonly number[];\n}\n\n/** Called for each authenticated bootstrap request; null means no assigned account. */\nexport interface RelayBootstrapConfiguration {\n readonly resolve: (\n caller: Readonly<RelayCaller>,\n ) => Promise<Readonly<RelayBootstrapSelection> | null>;\n}\n\n/**\n * Remote session-key custody, declared once for the deployment: the mode and\n * provider identity are served through the bootstrap document, and the same\n * provider answers the `/session-signers` routes. For `oaath_hosted` the\n * provider is typically `createKmsSessionSignerProvider`; for\n * `application_backend` it is the deployment's own authenticated port to the\n * integrating application's signer — never a client-supplied endpoint.\n */\nexport interface RelaySessionSignerConfiguration {\n readonly mode: \"application_backend\" | \"oaath_hosted\";\n readonly providerId: string;\n readonly provider: Readonly<RelaySessionSignerProvider>;\n}\n\n/** Authenticated identity and one opaque ERC-7677 params tuple. */\nexport interface RelayPaymasterServiceRequest {\n readonly caller: Readonly<{ clientId: string; subject: string }>;\n readonly params: unknown;\n readonly signal: AbortSignal;\n}\n\n/**\n * One deployment-owned paymaster provider. The relay exposes only these two\n * closed ERC-7677 operations and invokes the selected method once.\n */\nexport interface RelayPaymasterServiceProvider {\n readonly getPaymasterStubData: (\n request: Readonly<RelayPaymasterServiceRequest>,\n ) => Promise<unknown>;\n readonly getPaymasterData: (request: Readonly<RelayPaymasterServiceRequest>) => Promise<unknown>;\n}\n\nexport interface RelayPaymasterServiceConfiguration {\n readonly chainId: number;\n readonly providerId: string;\n /** Hard response deadline; the provider also receives its abort signal. */\n readonly requestTimeoutMs: number;\n readonly provider: Readonly<RelayPaymasterServiceProvider>;\n}\n\nexport interface RelayHandlerOptions {\n /** Enables application-initiated phone revocation; preparation never signs or submits. */\n readonly revocations?: Readonly<Pick<RequestOwnerPhoneRevocationInput, \"directory\" | \"prepare\">>;\n /** Enables canonical permission approval through the owner phone. */\n readonly permissionApprovals?: OwnerPhonePermissionApprovals;\n readonly store: RelayStore;\n readonly authentication: RelayAuthentication;\n /** Required. Resolves an approving device independently of the requesting member. */\n readonly ownerRouting: RelayOwnerRouting;\n readonly kms: RelayKms;\n readonly clock: RelayClock;\n /** Optional. There is no default limiter. */\n readonly rateLimit?: RelayRateLimiter;\n readonly requestTtlMs?: number;\n readonly codeTtlMs?: number;\n readonly maxBodyBytes?: number;\n /** Optional URL-only bootstrap surface; requires `chains` as well. */\n readonly bootstrap?: Readonly<RelayBootstrapConfiguration>;\n /** Optional chain execution relays; required when `bootstrap` is served. */\n readonly chains?: readonly Readonly<RelayChainPort>[];\n /** Optional remote session-key custody; requires `bootstrap` as well. */\n readonly sessionSigner?: Readonly<RelaySessionSignerConfiguration>;\n /**\n * Optional deployment-owned paymaster services, at most one per chain.\n * Configuration requires both bootstrap and a deployment rate limiter.\n */\n readonly paymasterServices?: readonly Readonly<RelayPaymasterServiceConfiguration>[];\n}\n\nexport type RelayHandler = (request: Request) => Promise<Response>;\n\nconst OPTION_KEYS: readonly string[] = [\n \"revocations\",\n \"permissionApprovals\",\n \"store\",\n \"authentication\",\n \"ownerRouting\",\n \"kms\",\n \"clock\",\n \"rateLimit\",\n \"requestTtlMs\",\n \"codeTtlMs\",\n \"maxBodyBytes\",\n \"bootstrap\",\n \"chains\",\n \"sessionSigner\",\n \"paymasterServices\",\n];\n\nconst CHAIN_PORT_NAMES = [\"reads\", \"observation\", \"bundler\", \"quote\", \"submission\"] as const;\ntype ChainPortName = (typeof CHAIN_PORT_NAMES)[number] | \"usage\";\n\n/**\n * The Grant a chain port request acts for, where the port's contract names\n * one: a submission's prepared operation and a usage read both carry it.\n * Reading it here is bounded extraction for the invalidation gate, not\n * interpretation — the port's own owner still captures the payload exactly.\n */\nfunction chainRequestGrantId(name: ChainPortName, request: unknown): string | null {\n try {\n if (name === \"usage\") {\n const grantId = (request as { readonly grantId?: unknown } | null)?.grantId;\n return typeof grantId === \"string\" && grantId.length > 0 ? grantId : null;\n }\n if (name === \"submission\") {\n const prepared = (request as { readonly prepared?: unknown } | null)?.prepared;\n const grantId = (prepared as { readonly grantId?: unknown } | null)?.grantId;\n return typeof grantId === \"string\" && grantId.length > 0 ? grantId : null;\n }\n } catch {\n // A hostile getter reads as absent; the port's exact capture still owns\n // whether such a payload is usable at all.\n }\n return null;\n}\n\n/**\n * Ports may be class instances, so only their required capabilities are checked.\n * Narrowing follows the runtime check.\n */\nfunction requirePort<Port>(value: unknown, methods: readonly string[], label: string): Port {\n if (!value || typeof value !== \"object\") {\n return relayFailure(\"relay_internal\", `${label} must be an object`);\n }\n for (const method of methods) {\n if (typeof (value as Record<string, unknown>)[method] !== \"function\") {\n return relayFailure(\"relay_internal\", `${label} must implement ${method}()`);\n }\n }\n return value as Port;\n}\n\nfunction duration(value: unknown, fallback: number, label: string, maximum = MAX_TTL_MS): number {\n if (value === undefined) return fallback;\n const milliseconds = timestamp(value, label, \"relay_internal\");\n if (milliseconds < 1 || milliseconds > maximum) {\n return relayFailure(\"relay_internal\", `${label} must be a bounded positive duration`);\n }\n return milliseconds;\n}\n\ninterface CapturedOptions {\n readonly revocations: RelayHandlerOptions[\"revocations\"] | null;\n readonly permissionApprovals: OwnerPhonePermissionApprovals | undefined;\n readonly store: RelayStore;\n readonly authentication: RelayAuthentication;\n readonly ownerRouting: RelayOwnerRouting;\n readonly kms: RelayKms;\n readonly clock: RelayClock;\n readonly rateLimit: RelayRateLimiter | undefined;\n readonly requestTtlMs: number;\n readonly codeTtlMs: number;\n readonly maxBodyBytes: number;\n /** The exact parsed document `GET /bootstrap` serves, or null when unserved. */\n readonly bootstrap: Readonly<RelayBootstrapConfiguration> | null;\n readonly sessionSigner: Readonly<RelaySessionSignerConfiguration> | null;\n readonly chains: ReadonlyMap<number, Readonly<RelayChainPort>>;\n readonly paymasterServices: ReadonlyMap<number, Readonly<RelayPaymasterServiceConfiguration>>;\n}\n\nfunction captureChainPorts(value: unknown): ReadonlyMap<number, Readonly<RelayChainPort>> {\n if (!Array.isArray(value)) {\n return relayFailure(\"relay_internal\", \"chains must be an array of chain ports\");\n }\n const chains = new Map<number, Readonly<RelayChainPort>>();\n for (const entry of value) {\n const port = requirePort<RelayChainPort>(entry, [...CHAIN_PORT_NAMES], \"chain port\");\n if (\n typeof port.chainId !== \"number\" ||\n !Number.isSafeInteger(port.chainId) ||\n port.chainId < 1\n ) {\n return relayFailure(\"relay_internal\", \"chain port chainId must be a positive integer\");\n }\n if (port.usage !== null && typeof port.usage !== \"function\") {\n return relayFailure(\"relay_internal\", \"chain port usage must be a function or null\");\n }\n if (\n port.staticPaymasterConfigurationHash !== null &&\n (typeof port.staticPaymasterConfigurationHash !== \"string\" ||\n !HASH.test(port.staticPaymasterConfigurationHash))\n ) {\n return relayFailure(\n \"relay_internal\",\n \"chain port static paymaster commitment must be a lowercase hash or null\",\n );\n }\n if (chains.has(port.chainId)) {\n return relayFailure(\"relay_internal\", \"chain ports repeat a chainId\");\n }\n let gas: RelayChainPort[\"gas\"];\n const configuredGas = port.gas;\n if (configuredGas !== undefined) {\n const policy = exactCapturedRecord(\n captureRecord(configuredGas, \"chain gas policy\", new WeakSet(), () =>\n relayFailure(\"relay_internal\", \"chain gas policy is invalid\"),\n ),\n [\"enableVerificationGasFloor\"],\n \"chain gas policy\",\n () => relayFailure(\"relay_internal\", \"chain gas policy is invalid\"),\n );\n if (\n typeof policy.enableVerificationGasFloor !== \"bigint\" ||\n policy.enableVerificationGasFloor < 0n ||\n policy.enableVerificationGasFloor >= 1n << 120n\n )\n return relayFailure(\"relay_internal\", \"chain gas floor is invalid\");\n gas = Object.freeze({ enableVerificationGasFloor: policy.enableVerificationGasFloor });\n }\n chains.set(\n port.chainId,\n Object.freeze({\n chainId: port.chainId,\n reads: port.reads,\n observation: port.observation,\n bundler: port.bundler,\n quote: port.quote,\n submission: port.submission,\n usage: port.usage,\n feePayer: port.feePayer,\n staticPaymasterConfigurationHash: port.staticPaymasterConfigurationHash,\n ...(gas === undefined ? {} : { gas }),\n }),\n );\n }\n return chains;\n}\n\nfunction capturePaymasterServices(\n value: unknown,\n context: CaptureContext,\n chains: ReadonlyMap<number, Readonly<RelayChainPort>>,\n): ReadonlyMap<number, Readonly<RelayPaymasterServiceConfiguration>> {\n if (value === undefined) return new Map();\n const entries = captureDenseArray(value, \"paymaster services\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n );\n const services = new Map<number, Readonly<RelayPaymasterServiceConfiguration>>();\n for (const entry of entries) {\n const service = exactCapturedRecord(\n captureRecord(entry, \"paymaster service\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n ),\n [\"chainId\", \"providerId\", \"requestTimeoutMs\", \"provider\"],\n \"paymaster service\",\n (message) => relayFailure(\"relay_internal\", message),\n );\n const chainId = service.chainId;\n if (typeof chainId !== \"number\" || !Number.isSafeInteger(chainId) || chainId < 1) {\n relayFailure(\"relay_internal\", \"paymaster service chainId must be a positive integer\");\n }\n if (!chains.has(chainId)) {\n relayFailure(\"relay_internal\", \"paymaster service chain is not configured\");\n }\n if (services.has(chainId)) {\n relayFailure(\"relay_internal\", \"paymaster services repeat a chainId\");\n }\n // A chain advertises at most one sponsorship kind; clients reject both.\n if (chains.get(chainId)?.staticPaymasterConfigurationHash !== null) {\n relayFailure(\n \"relay_internal\",\n \"a chain cannot combine a paymaster service and a static paymaster\",\n );\n }\n if (service.requestTimeoutMs === undefined) {\n relayFailure(\"relay_internal\", \"paymaster requestTimeoutMs is required\");\n }\n services.set(\n chainId,\n Object.freeze({\n chainId,\n providerId: canonicalIdentifier(\n service.providerId,\n \"paymaster providerId\",\n \"relay_internal\",\n ),\n requestTimeoutMs: duration(\n service.requestTimeoutMs,\n 0,\n \"paymaster requestTimeoutMs\",\n MAX_PAYMASTER_REQUEST_TIMEOUT_MS,\n ),\n provider: requirePort<RelayPaymasterServiceProvider>(\n service.provider,\n [\"getPaymasterStubData\", \"getPaymasterData\"],\n \"paymaster provider\",\n ),\n }),\n );\n }\n return services;\n}\n\nfunction captureOptions(value: unknown): CapturedOptions {\n const context: CaptureContext = new WeakSet();\n const record = captureRecord(value, \"relay handler options\", context, (message) =>\n relayFailure(\"relay_internal\", message),\n );\n for (const key of Object.keys(record)) {\n if (!OPTION_KEYS.includes(key)) {\n relayFailure(\"relay_internal\", \"relay handler options contain an unknown field\");\n }\n }\n const chains =\n record.chains === undefined\n ? new Map<number, Readonly<RelayChainPort>>()\n : captureChainPorts(record.chains);\n const rateLimit =\n record.rateLimit === undefined\n ? undefined\n : requirePort<RelayRateLimiter>(record.rateLimit, [\"check\"], \"rateLimit\");\n const paymasterServices = capturePaymasterServices(record.paymasterServices, context, chains);\n if (paymasterServices.size > 0) {\n if (record.bootstrap === undefined) {\n relayFailure(\"relay_internal\", \"a paymaster service requires a bootstrap surface\");\n }\n if (rateLimit === undefined) {\n relayFailure(\"relay_internal\", \"a paymaster service requires a rate limiter\");\n }\n }\n let sessionSigner: Readonly<RelaySessionSignerConfiguration> | null = null;\n if (record.sessionSigner !== undefined) {\n if (record.bootstrap === undefined) {\n relayFailure(\"relay_internal\", \"a session signer requires a bootstrap surface\");\n }\n const custody = captureRecord(\n record.sessionSigner,\n \"relay session signer configuration\",\n context,\n (message) => relayFailure(\"relay_internal\", message),\n );\n if (custody.mode !== \"application_backend\" && custody.mode !== \"oaath_hosted\") {\n relayFailure(\"relay_internal\", \"session signer mode is unsupported\");\n }\n if (typeof custody.providerId !== \"string\" || custody.providerId.length < 1) {\n relayFailure(\"relay_internal\", \"session signer providerId is invalid\");\n }\n sessionSigner = Object.freeze({\n mode: custody.mode as \"application_backend\" | \"oaath_hosted\",\n providerId: custody.providerId,\n provider: requirePort<RelaySessionSignerProvider>(\n custody.provider,\n [\"credential\", \"sign\"],\n \"session signer provider\",\n ),\n });\n }\n let bootstrap: Readonly<RelayBootstrapConfiguration> | null = null;\n if (record.bootstrap !== undefined) {\n if (chains.size === 0) {\n relayFailure(\"relay_internal\", \"a bootstrap surface requires chain ports\");\n }\n bootstrap = requirePort<RelayBootstrapConfiguration>(\n record.bootstrap,\n [\"resolve\"],\n \"bootstrap\",\n );\n }\n return Object.freeze({\n store: requirePort<RelayStore>(record.store, [\"begin\", \"close\"], \"store\"),\n revocations:\n record.revocations === undefined\n ? null\n : (() => {\n const configuration = requirePort<NonNullable<RelayHandlerOptions[\"revocations\"]>>(\n record.revocations,\n [\"prepare\"],\n \"revocations\",\n );\n return Object.freeze({\n prepare: configuration.prepare.bind(configuration),\n directory: requirePort<RequestOwnerPhoneRevocationInput[\"directory\"]>(\n configuration.directory,\n [\"resolveRevocationOwner\"],\n \"revocation directory\",\n ),\n });\n })(),\n permissionApprovals:\n record.permissionApprovals === undefined\n ? undefined\n : requirePort<OwnerPhonePermissionApprovals>(\n record.permissionApprovals,\n [\"prepare\"],\n \"permissionApprovals\",\n ),\n authentication: requirePort<RelayAuthentication>(\n record.authentication,\n [\"authenticate\"],\n \"authentication\",\n ),\n ownerRouting: requirePort<RelayOwnerRouting>(\n record.ownerRouting,\n [\"resolveOwner\"],\n \"ownerRouting\",\n ),\n kms: requirePort<RelayKms>(record.kms, [\"encrypt\", \"decrypt\"], \"kms\"),\n clock: requirePort<RelayClock>(record.clock, [\"now\"], \"clock\"),\n rateLimit,\n requestTtlMs: duration(record.requestTtlMs, DEFAULT_REQUEST_TTL_MS, \"requestTtlMs\"),\n codeTtlMs: duration(record.codeTtlMs, DEFAULT_CODE_TTL_MS, \"codeTtlMs\", MAX_CODE_TTL_MS),\n maxBodyBytes: duration(record.maxBodyBytes, DEFAULT_MAX_BODY_BYTES, \"maxBodyBytes\"),\n bootstrap,\n sessionSigner,\n chains,\n paymasterServices,\n });\n}\n\nfunction requireMethod(request: Request, expected: \"GET\" | \"POST\"): void {\n if (request.method !== expected) {\n relayFailure(\"relay_method_not_allowed\", \"route does not accept this method\");\n }\n}\n\nasync function bodyRecord(\n request: Request,\n maxBodyBytes: number,\n): Promise<Record<string, unknown>> {\n const contentType = request.headers.get(\"content-type\") ?? \"\";\n if (!contentType.toLowerCase().startsWith(\"application/json\")) {\n relayFailure(INVALID, \"request body must be application/json\");\n }\n let text: string;\n try {\n text = await request.text();\n } catch {\n return relayFailure(INVALID, \"request body is unreadable\");\n }\n if (new TextEncoder().encode(text).byteLength > maxBodyBytes) {\n return relayFailure(INVALID, \"request body exceeds its bound\");\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n return relayFailure(INVALID, \"request body is not JSON\");\n }\n const context: CaptureContext = new WeakSet();\n return captureRecord(parsed, \"request body\", context, (message) =>\n relayFailure(INVALID, message),\n );\n}\n\nfunction exactBody(\n record: Record<string, unknown>,\n keys: readonly string[],\n): Record<string, unknown> {\n return exactCapturedRecord(record, keys, \"request body\", (message) =>\n relayFailure(INVALID, message),\n );\n}\n\nasync function invokePaymasterService(\n service: Readonly<RelayPaymasterServiceConfiguration>,\n method: \"stub-data\" | \"data\",\n caller: Readonly<RelayCaller>,\n params: unknown,\n): Promise<unknown> {\n const controller = new AbortController();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const deadline = new Promise<never>((_resolve, reject) => {\n timeout = setTimeout(() => {\n controller.abort();\n reject(new Error(\"paymaster request deadline elapsed\"));\n }, service.requestTimeoutMs);\n });\n const capability =\n method === \"stub-data\"\n ? service.provider.getPaymasterStubData\n : service.provider.getPaymasterData;\n const request: Readonly<RelayPaymasterServiceRequest> = Object.freeze({\n caller: Object.freeze({ clientId: caller.clientId, subject: caller.subject }),\n params,\n signal: controller.signal,\n });\n return await Promise.race([\n Promise.resolve(Reflect.apply(capability, undefined, [request])),\n deadline,\n ]);\n } catch {\n return relayFailure(\"relay_chain_unavailable\", \"paymaster provider did not answer\");\n } finally {\n if (timeout !== undefined) clearTimeout(timeout);\n }\n}\n\nfunction decisionCommand(record: Record<string, unknown>): AuthorizationDecisionCommand {\n if (record.outcome === \"approved\") {\n const exact = exactBody(record, [\"outcome\", \"artifact\"]);\n return Object.freeze({\n outcome: \"approved\",\n artifact: boundedText(exact.artifact, RELAY_LIMITS.artifactPlaintext, \"artifact\", INVALID),\n });\n }\n if (record.outcome === \"rejected\") {\n exactBody(record, [\"outcome\"]);\n return Object.freeze({ outcome: \"rejected\" });\n }\n return relayFailure(INVALID, \"decision outcome is unsupported\");\n}\n\n/**\n * EXPERIMENTAL PREVIEW — the phone decision body: `{command, artifact?}`.\n * `approve` hands over the artifact the client will claim once; `reject`\n * carries nothing else. The saga answers the stored outcome on a replay.\n */\nfunction phoneDecisionCommand(record: Record<string, unknown>): AuthorizationDecisionCommand {\n if (record.command === \"approve\") {\n const exact = exactBody(record, [\"command\", \"artifact\"]);\n return Object.freeze({\n outcome: \"approved\",\n artifact: boundedText(exact.artifact, RELAY_LIMITS.artifactPlaintext, \"artifact\", INVALID),\n });\n }\n if (record.command === \"reject\") {\n exactBody(record, [\"command\"]);\n return Object.freeze({ outcome: \"rejected\" });\n }\n return relayFailure(INVALID, \"decision command is unsupported\");\n}\n\nfunction stateBody(state: AuthorizationState): unknown {\n return {\n requestId: state.requestId,\n clientId: state.clientId,\n redirectUri: state.redirectUri,\n requestedScope: state.requestedScope,\n expiresAt: state.expiresAt,\n expired: state.expired,\n decision: state.decision,\n };\n}\n\nexport function createRelayHandler(options: RelayHandlerOptions): RelayHandler {\n const captured = captureOptions(options);\n\n const authenticate = async (\n request: Request,\n role: RelayCallerRole | readonly RelayCallerRole[],\n route: string,\n ): Promise<RelayCaller> => {\n const caller = await authenticateCaller(captured.authentication, request, role);\n // Limiting happens after authentication so a deployment can key on clientId.\n // The authentication port owns unauthenticated abuse.\n await assertWithinRateLimit(captured.rateLimit, { route, clientId: caller.clientId });\n return caller;\n };\n\n const route = async (request: Request): Promise<Response> => {\n const segments = new URL(request.url).pathname.split(\"/\").filter((part) => part.length > 0);\n const [head, group, third, fourth] = segments;\n\n if (head === \"grants\" && third === \"revocations\" && segments.length === 4) {\n if (request.method !== \"GET\" && request.method !== \"POST\")\n return relayFailure(\"relay_method_not_allowed\", \"route does not accept this method\");\n const caller = await authenticate(request, \"client\", \"grants.revocation\");\n const grantId = canonicalIdentifier(group, \"grantId\", INVALID);\n if (\n typeof fourth !== \"string\" ||\n !/^[1-9][0-9]*$/u.test(fourth) ||\n !Number.isSafeInteger(Number(fourth))\n )\n return relayFailure(INVALID, \"revocation chain is invalid\");\n const input = {\n store: captured.store,\n clock: captured.clock,\n caller,\n grantId,\n chainId: Number(fourth),\n };\n if (request.method === \"GET\")\n return jsonResponse(200, await fetchClientPhoneRevocation(input));\n exactBody(await bodyRecord(request, captured.maxBodyBytes), []);\n if (!captured.revocations)\n return relayFailure(\"relay_not_found\", \"revocation preparation is not configured\");\n const { created, ...status } = await requestOwnerPhoneRevocation({\n ...input,\n kms: captured.kms,\n requestTtlMs: captured.requestTtlMs,\n ...captured.revocations,\n });\n return jsonResponse(created ? 201 : 200, status);\n }\n\n // EXPERIMENTAL PREVIEW — owner-phone approval routes. Same wire hygiene as\n // every relay route: exact capture, structured codes, no-store responses.\n if (head === \"native\") {\n if (segments.length === 2 && group === \"inbox\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"native.inbox\");\n return jsonResponse(\n 200,\n await listOwnerPhoneRequests({ store: captured.store, clock: captured.clock, caller }),\n );\n }\n if (segments.length === 3 && group === \"permission-signing\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"native.permissionSigning\");\n return jsonResponse(\n 200,\n await projectOwnerPhonePermissionSigning({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(third, \"operationId\", INVALID),\n ...(captured.permissionApprovals\n ? { permissionApprovals: captured.permissionApprovals }\n : {}),\n }),\n );\n }\n if (segments.length === 3 && group === \"projections\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"native.project\");\n const operationId = canonicalIdentifier(third, \"operationId\", INVALID);\n const projection = operationId.startsWith(REVOCATION_OPERATION_PREFIX)\n ? await fetchOwnerPhoneRevocation({\n store: captured.store,\n clock: captured.clock,\n caller,\n operationId,\n })\n : await projectOwnerPhoneRequest({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(third, \"operationId\", INVALID),\n });\n return jsonResponse(200, projection);\n }\n if (segments.length === 3 && group === \"revocation-decisions\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"owner\", \"native.revoke\");\n const command = phoneDecisionCommand(await bodyRecord(request, captured.maxBodyBytes));\n return jsonResponse(\n 200,\n await submitOwnerPhoneRevocationDecision({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n operationId: canonicalIdentifier(third, \"operationId\", INVALID),\n command,\n }),\n );\n }\n if (segments.length === 3 && group === \"decisions\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"owner\", \"native.decide\");\n const command = phoneDecisionCommand(await bodyRecord(request, captured.maxBodyBytes));\n const decided = await submitOwnerPhoneDecision({\n ...(captured.permissionApprovals\n ? { permissionApprovals: captured.permissionApprovals }\n : {}),\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n operationId: canonicalIdentifier(third, \"operationId\", INVALID),\n command,\n codeTtlMs: captured.codeTtlMs,\n });\n return jsonResponse(200, decided);\n }\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (head === \"bootstrap\" && segments.length === 1) {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"client\", \"bootstrap.fetch\");\n if (captured.bootstrap === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n const selection = await captured.bootstrap.resolve(caller);\n if (selection === null) return relayFailure(\"relay_not_found\", \"no assigned account\");\n let document: Readonly<ServiceBootstrap>;\n try {\n const context: CaptureContext = new WeakSet();\n const fail = (message: string): never => relayFailure(\"relay_internal\", message);\n const selected = exactCapturedRecord(\n captureRecord(selection, \"bootstrap selection\", context, fail),\n [\"application\", \"context\", \"account\", \"ownerValidator\", \"chainIds\"],\n \"bootstrap selection\",\n fail,\n );\n const application = exactCapturedRecord(\n captureRecord(selected.application, \"bootstrap application\", context, fail),\n [\"applicationId\", \"applicationName\"],\n \"bootstrap application\",\n fail,\n );\n const chainIds = captureDenseArray(selected.chainIds, \"selected chains\", context, fail);\n document = parseServiceBootstrap({\n version: OAATH_SERVICE_BOOTSTRAP_VERSION,\n application: {\n ...application,\n clientId: caller.clientId,\n redirectUris: caller.redirectUris,\n },\n userHandle: caller.subject,\n context: selected.context,\n account: selected.account,\n ownerValidator: selected.ownerValidator,\n chains: chainIds.map((chainId) => {\n const port = captured.chains.get(chainId as number);\n if (port === undefined) return fail(\"selected chain is not configured\");\n const paymasterService = captured.paymasterServices.get(port.chainId);\n return {\n chainId: port.chainId,\n ...(port.gas === undefined\n ? {}\n : {\n gas: {\n enableVerificationGasFloor: port.gas.enableVerificationGasFloor.toString(),\n },\n }),\n usage: port.usage !== null,\n feePayer: port.feePayer,\n paymasterService:\n paymasterService === undefined ? null : { providerId: paymasterService.providerId },\n staticPaymasterConfigurationHash: port.staticPaymasterConfigurationHash,\n };\n }),\n sessionSigner:\n captured.sessionSigner === null\n ? { mode: \"frontend\", providerId: null }\n : {\n mode: captured.sessionSigner.mode,\n providerId: captured.sessionSigner.providerId,\n },\n });\n } catch {\n return relayFailure(\"relay_internal\", \"resolved bootstrap is invalid\");\n }\n return jsonResponse(200, document);\n }\n\n if (head === \"session-signers\") {\n // Remote session-key custody routes, served exactly when the deployment\n // declared it. The caller's authenticated identity — never anything the\n // body claims — names the key: one (clientId, subject, deviceId)\n // identity holds one credential, so a different credential can never\n // sign under an approval that bound this one (the rotation invariant).\n const custody = captured.sessionSigner;\n if (custody === null) return relayFailure(\"relay_not_found\", \"route does not exist\");\n if (segments.length === 1) {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"session-signers.credential\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"deviceId\"]);\n const deviceId = boundedText(body.deviceId, 256, \"session signer deviceId\", INVALID);\n let credential: unknown;\n try {\n credential = await custody.provider.credential({\n clientId: caller.clientId,\n subject: caller.subject,\n deviceId,\n });\n } catch {\n return relayFailure(\"relay_internal\", \"session signer provider did not answer\");\n }\n return jsonResponse(200, { operatorCredential: credential });\n }\n if (segments.length === 2 && group === \"signatures\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"session-signers.sign\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"deviceId\",\n \"hash\",\n ]);\n const deviceId = boundedText(body.deviceId, 256, \"session signer deviceId\", INVALID);\n // One exact 32-byte hash; the provider signs an identity, never a\n // message it interprets.\n if (typeof body.hash !== \"string\" || !/^0x[0-9a-f]{64}$/u.test(body.hash)) {\n return relayFailure(INVALID, \"session signer hash must be one exact 32-byte hash\");\n }\n let signature: unknown;\n try {\n signature = await custody.provider.sign({\n clientId: caller.clientId,\n subject: caller.subject,\n deviceId,\n hash: body.hash as `0x${string}`,\n });\n } catch {\n return relayFailure(\"relay_internal\", \"session signer provider did not answer\");\n }\n return jsonResponse(200, { signature });\n }\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (head === \"grants\" && segments.length === 2 && group === \"verify\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"grants.verify\");\n // The whole exact-captured body is the assertion; its owner is the\n // protocol grant-reference contract, which re-captures it exactly.\n // Every result state answers 200: the machine decision lives in the\n // typed envelope, and a denial or unknown is a successful verification.\n const result = await verifyGrantReference({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n assertion: await bodyRecord(request, captured.maxBodyBytes),\n });\n return jsonResponse(200, result);\n }\n\n if (head === \"invalidations\" && segments.length === 1) {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"invalidations.create\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"grantId\",\n \"capabilityHash\",\n ]);\n const grantId = canonicalIdentifier(body.grantId, \"grantId\", INVALID);\n const capabilityHash = boundedText(body.capabilityHash, 66, \"capabilityHash\", INVALID);\n if (!/^0x[0-9a-f]{64}$/u.test(capabilityHash)) {\n return relayFailure(INVALID, \"capabilityHash must be a lowercase 32-byte hash\");\n }\n // Durable and enforced: from the committed record on, every chain\n // execution route below refuses this Grant, so the evidence states an\n // enforced fact — this service will no longer act for the capability.\n // Consuming the on-chain install nonce stays the chain-local revocation\n // operation's separate evidence. Replays answer the stored record, so\n // one Grant has exactly one invalidation time.\n const record = await withRelayTransaction(captured.store, async (transaction) => {\n const existing = await transaction.lockCapabilityInvalidation(grantId);\n if (existing) {\n if (existing.clientId !== caller.clientId) {\n // Reported as absence: not an existence oracle for another\n // client's Grant.\n return relayFailure(\"relay_not_found\", \"grant does not exist\");\n }\n return existing;\n }\n const created = Object.freeze({\n version: OAATH_CAPABILITY_INVALIDATION_RECORD_VERSION,\n grantId,\n clientId: caller.clientId,\n capabilityHash,\n invalidatedAt: relayNow(captured.clock),\n });\n if (!(await transaction.insertCapabilityInvalidation(created))) {\n return relayFailure(\"relay_internal\", \"capability invalidation did not commit\");\n }\n return created;\n });\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(\n `oaath-relay-invalidation:v1:${record.clientId}:${record.grantId}:${record.capabilityHash}:${record.invalidatedAt}`,\n ),\n );\n const evidenceHash = `0x${[...new Uint8Array(digest)]\n .map((byte) => byte.toString(16).padStart(2, \"0\"))\n .join(\"\")}`;\n // The evidence is protocol-facing, so it speaks the protocol's seconds\n // domain rather than the relay's millisecond records.\n return jsonResponse(200, {\n evidenceHash,\n invalidatedAt: Math.floor(record.invalidatedAt / 1_000),\n });\n }\n\n if (head === \"chains\" && segments.length === 4 && third === \"paymaster\") {\n requireMethod(request, \"POST\");\n const service = captured.paymasterServices.get(Number(group));\n const method = fourth === \"stub-data\" || fourth === \"data\" ? fourth : null;\n if (service === undefined || method === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n const caller = await authenticate(request, \"client\", `chains.paymaster.${method}`);\n // The route selects the deployment-owned provider. An application URL\n // is never accepted in this body and therefore can never become a fetch\n // target here.\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"params\"]);\n const result = await invokePaymasterService(service, method, caller, body.params);\n return jsonResponse(\n 200,\n result === undefined ? { present: false, result: null } : { present: true, result },\n );\n }\n\n if (head === \"chains\") {\n if (segments.length !== 3) return relayFailure(\"relay_not_found\", \"route does not exist\");\n requireMethod(request, \"POST\");\n const port = captured.chains.get(Number(group));\n const name: ChainPortName | null =\n third === \"submissions\"\n ? \"submission\"\n : third === \"reads\" ||\n third === \"observation\" ||\n third === \"bundler\" ||\n third === \"quote\" ||\n third === \"usage\"\n ? third\n : null;\n if (!port || name === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n // Submissions also accept the owner role: the owner-signed revocation\n // operation is what removes an installed chain permission, so the\n // owner's console must be able to submit it after the capability died.\n const caller = await authenticate(\n request,\n name === \"submission\" ? [\"client\", \"owner\"] : \"client\",\n `chains.${name}`,\n );\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"request\"]);\n const capability = name === \"usage\" ? port.usage : port[name];\n if (capability === null) {\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n // Recorded invalidations are enforced here: a submission or usage read\n // that names an invalidated Grant is refused before its port runs. The\n // ports whose requests carry no Grant identity are chain reads, which\n // grant nothing. This guards the honest capability; the on-chain install\n // nonce is what a hostile holder must still be cut off from, by the\n // chain-local revocation operation.\n //\n // The one pass through the gate is the caller's PROVEN owner role —\n // never a payload claim, which any gated client could spoof to keep\n // spending relay, RPC, and fee-payer budget after invalidation.\n const grantId = caller.role === \"owner\" ? null : chainRequestGrantId(name, body.request);\n if (grantId !== null) {\n const invalidated = await withRelayTransaction(captured.store, (transaction) =>\n transaction.lockCapabilityInvalidation(grantId),\n );\n if (invalidated !== undefined) {\n return relayFailure(\n \"relay_capability_invalidated\",\n \"the Grant's capability is invalidated\",\n );\n }\n }\n let result: unknown;\n try {\n result = await capability(body.request);\n } catch (error) {\n // Port meaning stays with its SDK owner; the relay reports only that\n // this chain surface did not answer. Nothing here retries.\n return relayFailure(\n \"relay_chain_unavailable\",\n \"chain port did not answer\",\n readValidationGasDiagnostic(error),\n name === \"submission\" ? readRpcBundlerRejection(error) : null,\n );\n }\n // JSON cannot carry `undefined`, and several ports mean it (\"no such\n // fact\"), so the envelope states presence explicitly.\n return jsonResponse(\n 200,\n result === undefined ? { present: false, result: null } : { present: true, result },\n );\n }\n\n if (head !== \"authorization\") {\n relayFailure(\"relay_not_found\", \"route does not exist\");\n }\n\n if (segments.length === 2 && group === \"requests\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.create\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"redirectUri\",\n \"codeChallenge\",\n \"requestedScope\",\n ]);\n const created = await createAuthorizationRequest({\n store: captured.store,\n ownerRouting: captured.ownerRouting,\n clock: captured.clock,\n caller,\n redirectUri: boundedText(\n body.redirectUri,\n RELAY_LIMITS.redirectUri,\n \"redirectUri\",\n INVALID,\n ),\n codeChallenge: boundedText(\n body.codeChallenge,\n RELAY_LIMITS.codeChallenge,\n \"codeChallenge\",\n INVALID,\n ),\n requestedScope: boundedText(\n body.requestedScope,\n RELAY_LIMITS.requestedScope,\n \"requestedScope\",\n INVALID,\n ),\n requestTtlMs: captured.requestTtlMs,\n });\n return jsonResponse(201, created);\n }\n\n if (segments.length === 3 && group === \"requests\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"owner\", \"authorization.fetch\");\n const state = await fetchAuthorizationRequest({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n });\n return jsonResponse(200, stateBody(state));\n }\n\n if (segments.length === 4 && group === \"requests\" && fourth === \"decision\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"owner\", \"authorization.decide\");\n const command = decisionCommand(await bodyRecord(request, captured.maxBodyBytes));\n const decided = await submitAuthorizationDecision({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n command,\n codeTtlMs: captured.codeTtlMs,\n });\n return jsonResponse(200, decided);\n }\n\n if (segments.length === 4 && group === \"requests\" && fourth === \"code\") {\n requireMethod(request, \"GET\");\n const caller = await authenticate(request, \"client\", \"authorization.code\");\n const fetched = await fetchAuthorizationCode({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n requestId: canonicalIdentifier(third, \"requestId\", INVALID),\n });\n return jsonResponse(200, fetched);\n }\n\n if (segments.length === 3 && group === \"codes\" && third === \"consume\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.consume\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\n \"code\",\n \"codeVerifier\",\n \"redirectUri\",\n ]);\n const consumed = await consumeAuthorizationCode({\n store: captured.store,\n clock: captured.clock,\n caller,\n code: canonicalIdentifier(body.code, \"code\", INVALID),\n codeVerifier: boundedText(\n body.codeVerifier,\n RELAY_LIMITS.codeVerifier,\n \"codeVerifier\",\n INVALID,\n ),\n redirectUri: boundedText(\n body.redirectUri,\n RELAY_LIMITS.redirectUri,\n \"redirectUri\",\n INVALID,\n ),\n });\n return jsonResponse(200, consumed);\n }\n\n if (segments.length === 4 && group === \"artifacts\" && fourth === \"claim\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.claim\");\n const claimed = await claimEncryptedArtifact({\n store: captured.store,\n clock: captured.clock,\n kms: captured.kms,\n caller,\n artifactId: canonicalIdentifier(third, \"artifactId\", INVALID),\n });\n return jsonResponse(200, claimed);\n }\n\n if (segments.length === 2 && group === \"resume\") {\n requireMethod(request, \"POST\");\n const caller = await authenticate(request, \"client\", \"authorization.resume\");\n const body = exactBody(await bodyRecord(request, captured.maxBodyBytes), [\"requestId\"]);\n const state = await resumeAuthorization({\n store: captured.store,\n clock: captured.clock,\n caller,\n requestId: canonicalIdentifier(body.requestId, \"requestId\", INVALID),\n });\n return jsonResponse(200, stateBody(state));\n }\n\n return relayFailure(\"relay_not_found\", \"route does not exist\");\n };\n\n return async (request: Request): Promise<Response> => {\n try {\n return await route(request);\n } catch (error) {\n return relayErrorResponse(\n relayErrorCode(error),\n readValidationGasDiagnostic(error),\n error instanceof OaathRelayError ? error.bundlerRejection : null,\n );\n }\n };\n}\n","/**\n * Bounded credential and URL redaction for diagnostics only.\n *\n * Nothing here shapes a response or a machine decision. Its only job is to make\n * an adopter's log line safe and finite: no authorization code, verifier, token,\n * artifact, ciphertext, credential-bearing URL, or unbounded provider blob.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nexport const REDACTED = \"[redacted]\";\nconst UNREADABLE_URL = \"[unreadable-url]\";\nconst TRUNCATED = \"[truncated]\";\n\nconst MAX_TEXT = 128;\nconst MAX_DEPTH = 3;\nconst MAX_ENTRIES = 16;\n\n/** Key names whose values are never safe to log, matched after normalization. */\nconst SENSITIVE_KEYS: ReadonlySet<string> = new Set([\n \"apikey\",\n \"artifact\",\n \"authorization\",\n \"bearer\",\n \"ciphertext\",\n \"ciphertextref\",\n \"clientsecret\",\n \"code\",\n \"codechallenge\",\n \"codeverifier\",\n \"cookie\",\n \"credential\",\n \"idtoken\",\n \"key\",\n \"password\",\n \"plaintext\",\n \"privatekey\",\n \"secret\",\n \"session\",\n \"sessionkey\",\n \"setcookie\",\n \"signature\",\n \"token\",\n \"verifier\",\n]);\n\nfunction normalizeKey(key: string): string {\n return key.toLowerCase().replaceAll(/[^a-z0-9]/gu, \"\");\n}\n\nfunction isUrlKey(normalized: string): boolean {\n return normalized.endsWith(\"url\") || normalized.endsWith(\"uri\");\n}\n\nfunction boundText(value: string): string {\n return value.length <= MAX_TEXT ? value : `${value.slice(0, MAX_TEXT)}${TRUNCATED}`;\n}\n\n/** Keeps scheme, host, and path. Drops userinfo, query, and fragment. */\nexport function redactUrl(value: unknown): string {\n if (typeof value !== \"string\") return UNREADABLE_URL;\n let url: URL;\n try {\n url = new URL(value);\n } catch {\n return UNREADABLE_URL;\n }\n const port = url.port === \"\" ? \"\" : `:${url.port}`;\n return boundText(`${url.protocol}//${url.hostname}${port}${url.pathname}`);\n}\n\nfunction redactValue(value: unknown, depth: number): unknown {\n if (value === null) return null;\n switch (typeof value) {\n case \"string\":\n return boundText(value);\n case \"number\":\n return Number.isFinite(value) ? value : String(value);\n case \"boolean\":\n return value;\n case \"bigint\":\n return boundText(value.toString());\n case \"object\":\n break;\n default:\n // Functions, symbols, and undefined carry no safe diagnostic value.\n return REDACTED;\n }\n if (depth >= MAX_DEPTH) return REDACTED;\n if (Array.isArray(value)) {\n const items = value.slice(0, MAX_ENTRIES).map((item) => redactValue(item, depth + 1));\n return value.length > MAX_ENTRIES ? [...items, TRUNCATED] : items;\n }\n if (value instanceof Error) {\n // Provider and driver messages routinely embed credentials and payloads.\n return { name: boundText(value.name), message: REDACTED };\n }\n return redactRecord(value as Record<string, unknown>, depth);\n}\n\nfunction redactRecord(value: Record<string, unknown>, depth: number): Record<string, unknown> {\n const redacted: Record<string, unknown> = {};\n let entries = 0;\n for (const key of Object.keys(value)) {\n if (entries >= MAX_ENTRIES) {\n redacted[TRUNCATED] = true;\n break;\n }\n entries += 1;\n const normalized = normalizeKey(key);\n if (SENSITIVE_KEYS.has(normalized)) {\n redacted[key] = REDACTED;\n } else if (isUrlKey(normalized)) {\n redacted[key] = redactUrl(value[key]);\n } else {\n redacted[key] = redactValue(value[key], depth + 1);\n }\n }\n return redacted;\n}\n\n/** Returns a bounded, credential-free projection safe to hand to a logger. */\nexport function redactForLog(value: unknown): unknown {\n return redactValue(value, 0);\n}\n","/**\n * Reference hosted session-signer provider: one KMS-sealed secp256k1 operator\n * key per authenticated `(clientId, subject, deviceId)` identity, signing one\n * exact 32-byte hash at a time.\n *\n * Custody boundary: the private scalar exists in plaintext only inside this\n * process during key generation and signing; at rest it is exactly one\n * KMS-sealed string. No route, log, or return value ever carries key material\n * — `credential` answers the public operator profile and `sign` answers one\n * 65-byte ECDSA signature.\n *\n * Rotation invariant: one identity maps to one credential for this provider's\n * lifetime. There is no rotation path here — a new key requires a new\n * identity, and therefore a newly approved Grant; nothing can silently swap\n * the public key under an existing approval.\n *\n * Like `createMemoryRelayStore`, the in-memory registry makes this a\n * reference implementation, not a production durability claim: a deployment\n * that must survive restarts persists the sealed entries in its own store.\n *\n * @author taek <leekt216@gmail.com>\n */\nimport { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport { keccak_256 } from \"@noble/hashes/sha3.js\";\nimport { bytesToHex, hexToBytes } from \"@noble/hashes/utils.js\";\nimport { OAATH_OPERATOR_CREDENTIAL_PROFILE_VERSION } from \"@oaath/protocol\";\nimport type { RelayKms } from \"../security/kms.js\";\n\nconst HASH = /^0x[0-9a-f]{64}$/u;\nconst MAX_IDENTITY_PART = 256;\n\nexport interface SessionSignerIdentity {\n readonly clientId: string;\n readonly subject: string;\n readonly deviceId: string;\n}\n\nexport interface SessionSignerSignRequest extends SessionSignerIdentity {\n /** The exact 32-byte hash to sign; never a message to interpret. */\n readonly hash: `0x${string}`;\n}\n\nexport interface RelaySessionSignerProvider {\n /**\n * The operator credential for one authenticated identity, creating the key\n * on first use. Idempotent: the same identity always answers the same\n * credential.\n */\n readonly credential: (request: Readonly<SessionSignerIdentity>) => Promise<unknown>;\n /** One ECDSA signature over one exact hash, under that identity's key. */\n readonly sign: (request: Readonly<SessionSignerSignRequest>) => Promise<unknown>;\n}\n\nfunction identityKey(request: Readonly<SessionSignerIdentity>): string {\n for (const part of [request.clientId, request.subject, request.deviceId]) {\n if (typeof part !== \"string\" || part.length < 1 || part.length > MAX_IDENTITY_PART) {\n throw new Error(\"session signer identity is invalid\");\n }\n }\n // JSON array form: no separator inside a part can collide two identities.\n return JSON.stringify([request.clientId, request.subject, request.deviceId]);\n}\n\nfunction addressOf(privateKey: Uint8Array): `0x${string}` {\n const publicKey = secp256k1.getPublicKey(privateKey, false);\n return `0x${bytesToHex(keccak_256(publicKey.slice(1)).slice(12))}`;\n}\n\nexport function createKmsSessionSignerProvider(input: {\n readonly kms: RelayKms;\n}): RelaySessionSignerProvider {\n const kms = input.kms;\n /** identity -> KMS-sealed private scalar; the only at-rest key form. */\n const sealed = new Map<string, string>();\n /** Serializes first-use creation so one identity never mints two keys. */\n const creating = new Map<string, Promise<string>>();\n\n async function sealedKeyFor(identity: string): Promise<string> {\n const existing = sealed.get(identity);\n if (existing !== undefined) return existing;\n const pending =\n creating.get(identity) ??\n (async () => {\n const scalar = secp256k1.utils.randomPrivateKey();\n const reference = String(await kms.encrypt(bytesToHex(scalar)));\n scalar.fill(0);\n sealed.set(identity, reference);\n return reference;\n })();\n creating.set(identity, pending);\n pending.finally(() => creating.delete(identity));\n return pending;\n }\n\n return Object.freeze({\n async credential(request: Readonly<SessionSignerIdentity>): Promise<unknown> {\n const identity = identityKey(request);\n const privateKey = hexToBytes(String(await kms.decrypt(await sealedKeyFor(identity))));\n try {\n return Object.freeze({\n version: OAATH_OPERATOR_CREDENTIAL_PROFILE_VERSION,\n kind: \"ecdsa\" as const,\n address: addressOf(privateKey),\n });\n } finally {\n privateKey.fill(0);\n }\n },\n async sign(request: Readonly<SessionSignerSignRequest>): Promise<unknown> {\n const identity = identityKey(request);\n if (typeof request.hash !== \"string\" || !HASH.test(request.hash)) {\n throw new Error(\"session signer hash must be one exact 32-byte hash\");\n }\n // Signing never creates a key: an identity that never fetched its\n // credential holds no approval that could authorize a signature.\n const reference = sealed.get(identity);\n if (reference === undefined) {\n throw new Error(\"session signer identity holds no credential\");\n }\n const privateKey = hexToBytes(String(await kms.decrypt(reference)));\n try {\n const signature = secp256k1.sign(hexToBytes(request.hash.slice(2)), privateKey, {\n lowS: true,\n });\n if (signature.recovery !== 0 && signature.recovery !== 1) {\n throw new Error(\"session signer produced an unusable signature\");\n }\n // 65-byte r ‖ s ‖ v with v in {27, 28}: the exact shape a locally held\n // viem account produces, so the Kernel-side validation is identical.\n return `0x${bytesToHex(signature.toCompactRawBytes())}${(27 + signature.recovery).toString(16)}`;\n } finally {\n privateKey.fill(0);\n }\n },\n });\n}\n","/**\n * In-memory relay store implementing the same transaction contract as\n * PostgreSQL. It is durable only for the life of the process: use it for local\n * development and tests, never for a deployment that must survive a restart.\n *\n * ponytail: one process-wide writer lock stands in for row locks. It is strictly\n * stronger than `SELECT ... FOR UPDATE`, so one-shot semantics are identical;\n * swap in per-row locks only if a single-process relay ever needs throughput.\n *\n * @author taek <leekt216@gmail.com>\n */\n\nimport { relayFailure } from \"../relay/errors.js\";\nimport {\n parseRevocationDecisionRecord,\n parseRevocationRequestRecord,\n type RevocationRequestRecord,\n} from \"../revocation/records.js\";\nimport type { RelayStore, RelayTransaction } from \"./interface.js\";\nimport {\n type AuthorizationCodeRecord,\n type AuthorizationDecisionRecord,\n type AuthorizationRequestRecord,\n type CapabilityInvalidationRecord,\n type EncryptedArtifactRecord,\n parseAuthorizationCodeRecord,\n parseAuthorizationDecisionRecord,\n parseAuthorizationRequestRecord,\n parseCapabilityInvalidationRecord,\n parseEncryptedArtifactRecord,\n} from \"./records.js\";\n\ninterface Tables {\n readonly revocationRequests: Map<string, unknown>;\n readonly revocationDecisions: Map<string, unknown>;\n readonly requests: Map<string, unknown>;\n readonly decisions: Map<string, unknown>;\n readonly codes: Map<string, unknown>;\n readonly artifacts: Map<string, unknown>;\n readonly invalidations: Map<string, unknown>;\n}\n\nfunction emptyTables(): Tables {\n return {\n revocationRequests: new Map(),\n revocationDecisions: new Map(),\n requests: new Map(),\n decisions: new Map(),\n codes: new Map(),\n artifacts: new Map(),\n invalidations: new Map(),\n };\n}\n\nfunction copyTables(tables: Tables): Tables {\n return {\n revocationRequests: new Map(tables.revocationRequests),\n revocationDecisions: new Map(tables.revocationDecisions),\n requests: new Map(tables.requests),\n decisions: new Map(tables.decisions),\n codes: new Map(tables.codes),\n artifacts: new Map(tables.artifacts),\n invalidations: new Map(tables.invalidations),\n };\n}\n\nfunction insert(table: Map<string, unknown>, key: string, record: unknown): boolean {\n if (table.has(key)) return false;\n table.set(key, record);\n return true;\n}\n\nfunction read<Value>(\n table: Map<string, unknown>,\n key: string,\n parse: (value: unknown) => Value,\n): Value | undefined {\n const stored = table.get(key);\n // Durable reads are re-validated here exactly as the SQL store validates rows.\n return stored === undefined ? undefined : parse(stored);\n}\n\nfunction artifactByRequest(tables: Tables, requestId: string): EncryptedArtifactRecord | undefined {\n let match: EncryptedArtifactRecord | undefined;\n for (const value of tables.artifacts.values()) {\n const record = parseEncryptedArtifactRecord(value);\n if (record.requestId !== requestId) continue;\n if (match) return relayFailure(\"relay_record_unreadable\", \"request has multiple artifacts\");\n match = record;\n }\n return match;\n}\n\nexport function createMemoryRelayStore(): RelayStore {\n let committed = emptyTables();\n let closed = false;\n let tail: Promise<void> = Promise.resolve();\n\n async function acquire(): Promise<() => void> {\n const prior = tail;\n let release = (): void => {};\n tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n await prior;\n return release;\n }\n\n return {\n async begin(): Promise<RelayTransaction> {\n if (closed) relayFailure(\"relay_store_unavailable\", \"memory relay store is closed\");\n const release = await acquire();\n const staged = copyTables(committed);\n let settled = false;\n\n const open = (): Tables => {\n if (settled) relayFailure(\"relay_internal\", \"relay transaction already settled\");\n return staged;\n };\n const settle = (apply: boolean): void => {\n if (settled) relayFailure(\"relay_internal\", \"relay transaction already settled\");\n settled = true;\n if (apply) committed = staged;\n release();\n };\n\n return {\n async listPendingOwnerRequests(ownerSubject, now, limit) {\n const tables = open();\n const requests = [];\n for (const value of tables.requests.values()) {\n const record = parseAuthorizationRequestRecord(value);\n if (\n record.ownerSubject === ownerSubject &&\n record.expiresAt > now &&\n !tables.decisions.has(record.requestId)\n ) {\n requests.push({\n operationId: record.requestId,\n ownerSubject,\n expiresAt: record.expiresAt,\n });\n }\n }\n for (const value of tables.revocationRequests.values()) {\n const record = parseRevocationRequestRecord(value);\n if (\n record.ownerSubject === ownerSubject &&\n record.expiresAt > now &&\n !tables.revocationDecisions.has(record.operationId)\n ) {\n requests.push({\n operationId: record.operationId,\n ownerSubject,\n expiresAt: record.expiresAt,\n });\n }\n }\n return requests\n .sort(\n (a, b) =>\n a.expiresAt - b.expiresAt ||\n (a.operationId < b.operationId ? -1 : a.operationId > b.operationId ? 1 : 0),\n )\n .slice(0, limit);\n },\n async lockLatestRevocationRequest(grantId, chainId) {\n let latest: RevocationRequestRecord | undefined;\n for (const stored of open().revocationRequests.values()) {\n const record = parseRevocationRequestRecord(stored);\n if (\n record.signingRequest.permissionRequest.requestId !== grantId ||\n record.signingRequest.chainId !== chainId\n )\n continue;\n if (!latest || record.createdAt > latest.createdAt) latest = record;\n }\n return latest;\n },\n async lockRevocationRequest(operationId) {\n return read(open().revocationRequests, operationId, parseRevocationRequestRecord);\n },\n async insertRevocationRequest(record) {\n return insert(open().revocationRequests, record.operationId, record);\n },\n async lockRevocationDecision(operationId) {\n return read(open().revocationDecisions, operationId, parseRevocationDecisionRecord);\n },\n async insertRevocationDecision(record) {\n return insert(open().revocationDecisions, record.operationId, record);\n },\n async lockAuthorizationRequest(requestId) {\n return read(open().requests, requestId, parseAuthorizationRequestRecord);\n },\n async insertAuthorizationRequest(record: AuthorizationRequestRecord) {\n return insert(open().requests, record.requestId, record);\n },\n async lockAuthorizationDecision(requestId) {\n return read(open().decisions, requestId, parseAuthorizationDecisionRecord);\n },\n async insertAuthorizationDecision(record: AuthorizationDecisionRecord) {\n return insert(open().decisions, record.requestId, record);\n },\n async lockAuthorizationCode(codeHash) {\n return read(open().codes, codeHash, parseAuthorizationCodeRecord);\n },\n async insertAuthorizationCode(record: AuthorizationCodeRecord) {\n return insert(open().codes, record.codeHash, record);\n },\n async consumeAuthorizationCode(codeHash, consumedAt) {\n const codes = open().codes;\n const record = read(codes, codeHash, parseAuthorizationCodeRecord);\n if (!record || record.consumedAt !== null) return false;\n codes.set(codeHash, Object.freeze({ ...record, consumedAt }));\n return true;\n },\n async lockCapabilityInvalidation(grantId) {\n return read(open().invalidations, grantId, parseCapabilityInvalidationRecord);\n },\n async insertCapabilityInvalidation(record: CapabilityInvalidationRecord) {\n return insert(open().invalidations, record.grantId, record);\n },\n async lockEncryptedArtifact(artifactId) {\n return read(open().artifacts, artifactId, parseEncryptedArtifactRecord);\n },\n async lockEncryptedArtifactByRequestId(requestId) {\n return artifactByRequest(open(), requestId);\n },\n async insertEncryptedArtifact(record: EncryptedArtifactRecord) {\n const tables = open();\n if (artifactByRequest(tables, record.requestId)) return false;\n return insert(tables.artifacts, record.artifactId, record);\n },\n async claimEncryptedArtifact(artifactId, claimedAt) {\n const artifacts = open().artifacts;\n const record = read(artifacts, artifactId, parseEncryptedArtifactRecord);\n if (!record || record.claimedAt !== null) return false;\n artifacts.set(artifactId, Object.freeze({ ...record, claimedAt }));\n return true;\n },\n async commit() {\n settle(true);\n },\n async rollback() {\n if (!settled) settle(false);\n },\n };\n },\n async close(): Promise<void> {\n closed = true;\n committed = emptyTables();\n },\n };\n}\n"],"mappings":"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"}
|