# Kurabase Kurabase is experimental developer infrastructure: a Supabase-style REST API over EVM-backed relational state. It provides an independent `@kurabase/js` client, versioned migrations, CRUD, common filters including JSONB containment, RLS, relation projections, catalog and administrative endpoints, SQL-language RPC, and a local Anvil workflow. Read the complete machine reference at `/llms-full.txt`. Human documentation is at `/docs/intro`. Remote deployment guide: `/docs/production-deployment`. Production mode uses `deploy/production/compose.yaml` or the Kubernetes manifests, a remote HTTPS RPC, operator-managed file secrets, and explicit per-instance app/admin gateway grants. It is separate from `kura start` and does not imply production readiness. Owner keys are bootstrap-only; public instance metadata contains no signer, RPC or server secrets. GCP deployment guide: `/docs/gcp-deployment`. The supported first GCP route builds the reviewed production image in Cloud Build/Artifact Registry and runs the existing one-app-signer/one-admin-signer Compose deployment on a dedicated Compute Engine VM. Bootstrap occurs on a trusted operator machine and exports only public `instance.json` to the VM. The VM receives only exact-version Secret Manager values for RPC, app signer, admin signer and server key via a least-privilege service account; it never receives the owner key. Expose the app gateway through HTTPS and leave admin loopback/private. Cloud Run is not a supported current target because the current shared-instance/single-signer topology must not autoscale or overlap; GKE is a later single-replica path. The hosted Privy provider runtime remains a private dedicated-host MVP, not a public multi-tenant service claim. Auth-catalog reference: `/docs/auth-catalog`. The only shipped catalog relations are `kura_auth_users` and `kura_auth_identities`; there is no `auth.*` namespace. They are public-chain pseudonymous records registered only after a valid session exchange, not authentication evidence or a private profile store. Browser SDK and REST clients call the public application gateway URL directly; a developer-managed proxy is optional, not required. Browser code may use only the publishable `apikey`, never `KURA_DEV_SERVER_KEY`, gateway/server credentials, a wallet private key, or a pasted bearer token. The gateway accepts the SDK/PostgREST CORS headers and opts into local Chromium Private Network Access, so `localhost` frontends can call the default `http://127.0.0.1:55421` gateway. Wallet sign-in uses EIP-1193 plus EIP-712: `WalletRequestRejected` means user rejection; `WalletSignInFailed` retains the provider error message/code; `WalletChainMismatch` tells the user to switch chains. AA reference: `/docs/aa-writes`. Production application writes are gateway-attested transaction plans, sent by the authenticated Privy external/embedded account; the gateway EOA cannot submit the user plan. A plan signs its exact authenticated session digest, expires no later than that session, and becomes invalid when that session is individually revoked. `@kurabase/js` remains provider-independent. Its optional `@kurabase/privy` bridge gives an external wallet Privy's direct sender, while a Privy embedded wallet signs a ZeroDev Kernel EIP-7702 UserOperation that preserves the session address. The first hosted profile pins Portal and control plane to OP Sepolia (`11155420`), rejects other chain lists, and makes the user select the owner wallet. A gateway automation credential must be a user-approved, contract/selector/account/value/expiry-scoped ZeroDev session key in KMS/HSM, never a browser or universal gateway key. `GatewayPlan` ABI/type-hash changes require matching gateway and contract deployment. For `kura start`, Dashboard > Authentication persists only public `privyAppId`/`zeroDevProjectId`, updates discovery immediately, and enables account plans; it has no credential fields and clearing the App ID restores direct Anvil writes. A fresh local stack commits directly; after setting a Privy App ID, application writes require the app's `transaction.send` callback because the Dashboard neither verifies Privy tokens nor supplies a Privy/ZeroDev sender. The shipped Anvil acceptance proves account-owned execution, not a live Privy/ZeroDev provider or public-chain bundling. Hosted service configuration is draft and intentionally hidden from the normal docs sidebar. Its first provider profile is OP Sepolia, and its global ZeroDev policy is `eip7702` with `kernel-4337` recorded as a future compatibility mode. An owner can choose a pre-activation per-instance public `{privyAppId, zeroDevProjectId, sponsorTransactions}` override. API keys, administrative credentials, authorization keys and session-key material are rejected from this interface and remain runner/KMS secrets. ENS reference: `/docs/ens`. A configured ENS Universal Resolver resolves an already-normalized lowercase ASCII `.eth` name for reads such as `FROM "kura.eth".profiles`; the foreign instance's anonymous RLS applies. A target-side privileged-delegated gateway may also issue one administrative `INSERT`, `UPDATE`, or `DELETE` written as `"kura.eth".profiles`; local EIP-712 sessions are never replayed to authorize it. External FK bindings persist a stable address, validate changed references under foreign anonymous RLS, and expose deleted/unavailable targets as logical SQL NULL. External DDL/migrations/views/functions, application-session cross writes, CCIP-Read and cross-chain queries remain unsupported. On-chain SQL functions: `/docs/onchain-functions`. `EXECUTION ON CHAIN` is a V2-only, directly callable KuraIR function profile, not gateway RPC. The shipped compiler accepts exactly `SELECT value FROM relation WHERE key = function_parameter`, or a `MODIFIES SQL DATA` caller debit / address-parameter credit using `kura.caller()`, over a relation that is exactly an `address` primary key plus one `uint256` column. `EXTERNAL NAME` supplies the immutable ABI selector. `kura migration up` atomically publishes catalog metadata and program, seeds and seals the relation, and gateway projections replay subsequent value-change logs. Gateway SQL may not mutate a relation once it is owned by a published function. `CREATE EXTENSION kura_erc20` additionally verifies and atomically advertises a complete six-selector ERC-20 package (`totalSupply`, `balanceOf`, `transfer`, `allowance`, `approve`, `transferFrom`) through ERC-165. It supports composite `(owner,spender)` allowance storage, standard `Transfer` / `Approval` logs, and atomic allowance-plus-balance `transferFrom`; incomplete or ABI-incompatible bindings never advertise the capability. Arbitrary selectors via SQL expressions, dynamic/unbounded SQL and cross-instance on-chain calls are explicitly not implemented. Fresh `kura start` deploys V2; reset a persisted V1 local instance before using this feature. Important constraints: Kurabase is not production-ready, private, fully PostgreSQL-compatible, PostgreSQL wire-compatible, or a solution for secret data. `overlaps` is limited to declared one-dimensional integer, text, boolean, or UUID arrays; range, multidimensional and JSONB overlap are unsupported. A gateway needs explicit instance delegation. A user session must originate from a self-signed wallet or configured identity authority. `kura start` creates a local instance operator for local Dashboard management and a separate server-only `KURA_DEV_SERVER_KEY`; neither is a browser/user session. Remote Dashboard management retains the distinct owner/developer wallet signature. The gateway cannot invent user authority. Canonical cell types include `date`, `time(p)`, `timestamp(p)`, `timestamptz(p)` (precision 0–6) and `bytea`. Their public representation is a validated string; `timestamptz` is normalized to UTC and `bytea` uses lowercase PostgreSQL `\\x` hexadecimal. Literal comparisons, `BETWEEN`, `IN`, and string-literal `::type` casts share this codec. `varchar(n)` enforces width; `CHAR(n)` stores trailing-space-padded canonical values and normalizes comparison literals identically. `CREATE TYPE name AS ENUM (...)` is chain-replayed catalog metadata; enum writes, function arguments/returns, equality/inequality, `IN`, and literal casts validate labels. `ALTER TYPE`, declaration-order predicates, and enum `ORDER BY` explicitly return `UnsupportedFeature`.