Files
grin-lws/migrations/0001_init.sql
T
jwinterm 1dabd1513c scaffold: grin-lws — Grin light-wallet-server (view-key scan + DB store)
A standalone, self-hostable Grin light-wallet-server mirroring the Monero LWS:
register a view/rewind credential, run a background chain scanner, rewind outputs
against registered keys, store per-account matches in a DB, and serve balance /
outputs / broadcast / height fast (vs the current on-demand stateless scan proxy).
This is the scaffold — README (architecture + HTTP surface + DB schema + how a
wallet backend proxies to it), Cargo skeleton, migrations sketch, and route/scanner
stubs. Public-clean: no operator-specific infra, hosts, or secrets.
2026-07-09 04:47:13 -04:00

59 lines
2.7 KiB
SQL

-- grin-lws initial schema.
--
-- This service is a REAL light-wallet-server: it holds a per-account output
-- store keyed by each account's `rewind_hash` (a view credential) and a
-- reorg-safe chain cursor. It NEVER stores a private/spend key — `rewind_hash`
-- is view-only (it can recognize a wallet's outputs and read amounts, but
-- cannot spend).
--
-- Dialect note: written for PostgreSQL. For a single-operator SQLite build,
-- replace BIGINT -> INTEGER, BOOLEAN -> INTEGER (0/1), TIMESTAMPTZ ->
-- TEXT/INTEGER, and drop `DEFAULT now()`. `commit` is a reserved word in SQL,
-- hence it is always quoted as "commit".
-- An account = one registered view credential.
CREATE TABLE IF NOT EXISTS accounts (
-- The wallet's rewind_hash (64 hex). View-only; safe to persist.
rewind_hash TEXT PRIMARY KEY,
-- The height the scanner should (re)start from when this account was added
-- (a wallet birthday). Never advances backwards on its own.
start_height BIGINT NOT NULL,
-- How far the scanner has processed this account. Advances toward the tip;
-- lowered only by an explicit backwards rescan.
scan_height BIGINT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Outputs the scanner recognized for a registered account (rewound rangeproof
-- matched). Crucially stores the recovered derivation path (`key_id` /
-- `n_child`) so a client can spend WITHOUT a client-side identify search.
CREATE TABLE IF NOT EXISTS outputs (
"commit" TEXT PRIMARY KEY,
rewind_hash TEXT NOT NULL REFERENCES accounts(rewind_hash) ON DELETE CASCADE,
value BIGINT NOT NULL,
height BIGINT NOT NULL,
mmr_index BIGINT NOT NULL,
is_coinbase BOOLEAN NOT NULL DEFAULT false,
lock_height BIGINT NOT NULL DEFAULT 0,
-- Recovered from the proof message during rewind (grin_recover_output
-- equivalent, server-side). Enables direct spend by the client.
key_id TEXT,
n_child INTEGER,
-- Spend tracking: set when this output's commitment appears as a tx input.
spent BOOLEAN NOT NULL DEFAULT false,
spent_height BIGINT
);
-- Balance / unspent-set queries filter by (account, spent).
CREATE INDEX IF NOT EXISTS idx_outputs_account_spent ON outputs (rewind_hash, spent);
-- Spend detection matches an on-chain input commitment against stored outputs.
CREATE INDEX IF NOT EXISTS idx_outputs_commit ON outputs ("commit");
-- Single-row chain cursor for reorg-safe resume. On a reorg, roll back rows
-- above the fork height and reset the cursor to the fork point.
CREATE TABLE IF NOT EXISTS chain_cursor (
id INTEGER PRIMARY KEY CHECK (id = 1),
height BIGINT NOT NULL,
block_hash TEXT NOT NULL
);