-- Lightning deposits and withdrawals. -- -- Invoices key on payment_hash, which is what makes crediting idempotent: a -- node that reports the same settlement twice cannot produce two credits. CREATE TABLE lightning_invoices ( payment_hash TEXT PRIMARY KEY, account_id BIGINT NOT NULL REFERENCES accounts(id), amount_msat BIGINT NOT NULL CHECK (amount_msat > 0), bolt11 TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), expires_at TIMESTAMPTZ, -- Set exactly once, when the payment is credited to the ledger. credited_at TIMESTAMPTZ ); CREATE INDEX lightning_invoices_account_idx ON lightning_invoices (account_id, created_at DESC); CREATE INDEX lightning_invoices_pending_idx ON lightning_invoices (created_at) WHERE credited_at IS NULL; CREATE TYPE withdrawal_status AS ENUM ('queued', 'needs_approval', 'sending', 'paid', 'failed', 'rejected'); CREATE TABLE lightning_withdrawals ( id BIGSERIAL PRIMARY KEY, account_id BIGINT NOT NULL REFERENCES accounts(id), bolt11 TEXT NOT NULL, amount_msat BIGINT NOT NULL CHECK (amount_msat > 0), status withdrawal_status NOT NULL, payment_hash TEXT, fee_msat BIGINT, failure TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), resolved_at TIMESTAMPTZ ); CREATE INDEX lightning_withdrawals_account_idx ON lightning_withdrawals (account_id, id DESC); CREATE INDEX lightning_withdrawals_pending_idx ON lightning_withdrawals (id) WHERE status IN ('queued', 'needs_approval', 'sending');