deino-sdk: the Eye Key is the developer surface
The SDK wraps the developer API — and the contract is one key, shown once.

The developer surface of DEINO is one key, shown once, never on disk. deino-sdk wraps that contract: one facade for the Eye-Key API, typed responses, and a key that lives in the memory of the caller, not in our database.
The developer surface of DEINO is one key, shown once, never on disk. deino-sdk wraps that contract: one facade for the Eye-Key API, typed responses, and a key that lives in the memory of the caller, not in our database.
One key, one surface
The Eye Key is the developer credential — the thing a developer presents to the /api/v1 surface to run a simulation, read a cone, or query the ledger. The SDK wraps that surface: it holds the key, signs requests, parses responses, and exposes typed return values. The contract is one key per developer, shown once at mint time, stored only as an HMAC and a fingerprint in Postgres. The plaintext never touches disk — not ours, not the SDK. The SDK holds it in memory; the developer puts it in an env var; our database holds the hash.

Why one key, shown once
Showing the key once, at mint time, is the honest version of key management. A key that is retrievable is a key that is retrievable by an attacker who reaches the database. A key that is shown once and then only exists as an HMAC cannot be stolen from disk, because it is not on disk. The developer writes it down (in an env var, in a secrets manager) at mint time, and if they lose it, they mint a new one. That is a deliberate friction: the key is a credential, not a convenience, and the one-time display enforces that.
A key that is retrievable is a key that is retrievable by an attacker who reaches the database. The plaintext never touches disk, because the plaintext is not there.
The SDK is the typed boundary
Responses from the API are parsed at the SDK boundary into typed values — a cone is a cone, a simulation is a simulation, a ledger actor is a ledger actor. The wire format is JSON, defined once in Zod schemas (on the frontend side) and mirrored in the SDK types. A bad payload surfaces as a typed error, not a crash. The SDK is where untrusted wire data becomes trusted typed data, and the type discipline is the whole point — the developer gets compile-time guarantees about what the API returns, not runtime surprises.
- One key, shown once, stored as HMAC + fingerprint — plaintext in memory only (INV-2).
- The SDK parses wire JSON into typed values — a bad payload is a typed error, not a crash.
- The Eye-Key API is per-key rate-limited — the SDK is the surface, the key is the credential.
Why the SDK is inside the workspace
The Rust SDK lives inside the backend workspace (backend/crates/deino-sdk) because it is coupled to deino-core — the types it exposes are the types the core defines. That coupling is the point: the SDK types cannot drift from the core types, because they are the same types, compiled in the same workspace. Other-language SDKs live in libs/ and are coupled by contract (the OpenAPI spec and the Zod schemas), not by compilation. The Rust SDK is the one that gets compile-time type sharing; the others get contract sharing. Both are honest; they differ in how the drift is prevented.
The key is a credential, not a convenience. One-time display is deliberate friction — the kind that keeps a key out of the database and in the place it belongs.
— Eye Key design note
What it is not
The SDK is not a claim that the API is stable forever. It is a claim that the types are stable as of the version you compile against, and that the wire format is the contract. The API is under /api/v1 with Swagger at /api/docs, and the OpenAPI spec is regenerable. We are pre-revenue and building the POC; the SDK is built, the Eye-Key surface is built, and the accuracy of any forecast the SDK returns is gated (Gate 1b), not promised.