run402-mcp
Version:
MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.
126 lines • 6.79 kB
TypeScript
export type RedeemKind = "handoff" | "invite" | "room";
export interface HandoffKeyPrefixEntry {
prefix: string;
kind: RedeemKind;
verb: string;
/** Error-code prefix for this kind (`HANDOFF` | `INVITE` | `ROOM_INVITE`) — every client-side code this module throws is `${errorPrefix}_…`. */
errorPrefix: string;
/** The exact CLI invocation named in a cross-kind `*_KEY_WRONG_KIND` refusal (design D3/D9 rule 4). */
doorLabel: string;
/**
* The sealed-envelope `envelope_kind` tag this kind's mint seals TODAY —
* the v2 shape for both vault kinds (`v: 2`, `writer_admission_grant_sha256`,
* `epoch_keys`), since writer admission rides the envelope for every vault
* redeem kind (vault-multi-writer D4). Absent for `room` — a room invite
* has no envelope, no wrap key, no admission seed (add-room-invite D3).
*/
envelopeKind?: string;
/** This kind's note schema tag. Absent for `room` — a room invite carries a plaintext `note`, not a Handoff/Invite Note. */
noteSchema?: string;
/** This kind's envelope frame magic (4 ASCII bytes). Absent for `room`. */
frameMagic?: string;
}
/**
* `kgh1_` is the first row (handoff); `kgi1_` the second (invite,
* kygit-invite design D3); `kri1_` the third (room, add-room-invite design
* D3). A future kind is a SIBLING row here, never a branch on an existing
* one's parser.
*/
export declare const HANDOFF_KEY_PREFIXES: readonly HandoffKeyPrefixEntry[];
export interface RedeemKeyParts {
kind: RedeemKind;
id_bytes: Uint8Array;
/** Canonical lowercase-hyphenated UUID form of `id_bytes` — the wire id (`handoff_id`/`invite_id`). */
id: string;
master_secret: Uint8Array;
}
/** {@link parseHandoffKey}'s legacy field names, preserved byte-identical. */
export interface HandoffKeyParts {
kind: "handoff";
handoff_id_bytes: Uint8Array;
handoff_id: string;
master_secret: Uint8Array;
}
/** {@link parseInviteKey}'s field names — the invite-kind sibling of {@link HandoffKeyParts}. */
export interface InviteKeyParts {
kind: "invite";
invite_id_bytes: Uint8Array;
invite_id: string;
master_secret: Uint8Array;
}
/** {@link parseRoomInviteKey}'s field names — the room-kind sibling of {@link HandoffKeyParts}/{@link InviteKeyParts} (add-room-invite design D3). */
export interface RoomInviteKeyParts {
kind: "room";
invite_id_bytes: Uint8Array;
invite_id: string;
master_secret: Uint8Array;
}
export declare function uuidToBytes(uuid: string, field?: string): Uint8Array;
/** A fresh RFC 4122 v4 UUID — the client-generated key id every bearer-redeem kind mints with (design D3: `auth_secret` derives off it, so it cannot be gateway-assigned). */
export declare function randomRedeemId(): string;
/**
* Assemble the printed key from a fresh 32-byte master secret and the
* gateway-minted `handoff_id`. The gateway never sees `master_secret` — the
* caller derives `auth_hash` (via {@link deriveHandoffSecrets}) and sends
* ONLY that.
*/
export declare function assembleHandoffKey(handoffId: string, masterSecret?: Uint8Array): {
key: string;
handoff_id_bytes: Uint8Array;
master_secret: Uint8Array;
};
/** The invite-kind sibling of {@link assembleHandoffKey} (kygit-invite design D3). */
export declare function assembleInviteKey(inviteId: string, masterSecret?: Uint8Array): {
key: string;
invite_id_bytes: Uint8Array;
master_secret: Uint8Array;
};
/**
* The room-kind sibling of {@link assembleHandoffKey}/{@link assembleInviteKey}
* (add-room-invite design D3). `invite_id` is CLIENT-generated (unlike the
* vault kinds, whose id the gateway mints) — the client sends it verbatim in
* the mint request and the gateway uses it as the row id, refusing a
* collision with `409 ROOM_INVITE_ID_CONFLICT`.
*/
export declare function assembleRoomInviteKey(inviteId: string, masterSecret?: Uint8Array): {
key: string;
invite_id_bytes: Uint8Array;
master_secret: Uint8Array;
};
/**
* Parse ANY registered redeem-family key by its prefix registry against the
* `expectedKind` the calling verb accepts. A recognized prefix of a
* DIFFERENT kind (a `kgi1_` invite key handed to `resume`, a `kri1_` room
* key handed to `repos join`/`resume`, or a `kgi1_`/`kgh1_` vault key handed
* to `rooms join`) refuses BY NAME pointing at its own door — never misread
* as a malformed key of the expected kind, and never contacting the gateway
* (design D9 rule 4 / kygit-invite design D3 / add-room-invite design D3).
*/
export declare function parseRedeemKey(raw: string, expectedKind: RedeemKind): RedeemKeyParts;
/**
* Parse ANY registered redeem-family key by its prefix registry. A
* recognized prefix of a DIFFERENT kind (an invite or room key handed to
* `resume`) refuses BY NAME pointing at its own door — never misread as a
* malformed handoff key (design D9 rule 4). Kind-bound alias of
* {@link parseRedeemKey}.
*/
export declare function parseHandoffKey(raw: string): HandoffKeyParts;
/** The invite-kind sibling of {@link parseHandoffKey} (kygit-invite design D3). */
export declare function parseInviteKey(raw: string): InviteKeyParts;
/** The room-kind sibling of {@link parseHandoffKey}/{@link parseInviteKey} (add-room-invite design D3). */
export declare function parseRoomInviteKey(raw: string): RoomInviteKeyParts;
export interface HandoffSecrets {
auth_secret: Uint8Array;
wrap_key: Uint8Array;
/** `SHA-256(auth-hash-label ‖ auth_secret)`, lowercase hex — the ONLY thing the gateway ever stores. */
auth_hash_hex: string;
}
/** `HKDF-SHA256(ikm=master_secret, salt=handoff_id[16], info=kygit/handoff/…)` per D3, for both `auth_secret` and `wrap_key`. */
export declare function deriveHandoffSecrets(handoffIdBytes: Uint8Array, masterSecret: Uint8Array): HandoffSecrets;
/** The invite-kind sibling of {@link deriveHandoffSecrets}, domain-separated under `kygit/invite/…` info strings (kygit-invite design D3) — an invite secret never verifies as a handoff hash, or the reverse. */
export declare function deriveInviteSecrets(inviteIdBytes: Uint8Array, masterSecret: Uint8Array): HandoffSecrets;
/** `HKDF-SHA256(ikm=master_secret, salt=invite_id[16], info="run402/room-invite/auth/v1")` — the ONE secret a room invite derives (design D3). */
export declare function deriveRoomInviteAuthSecret(inviteIdBytes: Uint8Array, masterSecret: Uint8Array): Uint8Array;
/** `SHA-256("run402/room-invite/auth-hash/v1" ‖ auth_secret)`, lowercase hex — exactly what the gateway's `mintRoomInvite`/`claimRoomInvite` compute and store/compare (design D3). */
export declare function computeRoomInviteAuthHash(authSecret: Uint8Array): string;
//# sourceMappingURL=bearer-redeem-key.d.ts.map