@pwngh/economy-lab
    Preparing search index...

    Interface Ledger

    The append-only double-entry ledger: records money movements, reads back balances and history.

    Accounts & double-entry for postings, legs, and the chart of accounts.

    interface Ledger {
        append(posting: Posting, options?: CallOptions): Promise<Transaction>;
        appendAll?(
            postings: readonly Posting[],
            options?: CallOptions,
        ): Promise<Transaction[]>;
        archivePage?(
            cursor: number | null,
            limit: number,
            options?: CallOptions,
        ): Promise<{ cursor: number | null; postings: readonly ArchivedPosting[] }>;
        balance(account: AccountRef, options?: CallOptions): Promise<Amount>;
        balanceAccounts(options?: CallOptions): AsyncIterable<AccountRef>;
        derivedBalances(
            account: AccountRef,
            options?: CallOptions,
        ): Promise<readonly Amount[]>;
        hasAccount(account: AccountRef, options?: CallOptions): Promise<boolean>;
        heads(): AsyncIterable<readonly [AccountRef, string]>;
        headSums(
            options?: CallOptions,
        ): AsyncIterable<readonly [AccountRef, string, bigint]>;
        historySize?(options?: CallOptions): Promise<number>;
        lineage(
            account: AccountRef,
            options?: LineageOptions,
        ): AsyncIterable<StoredLink>;
        links(
            txnId: string,
            options?: CallOptions,
        ): Promise<readonly PostingLink[]>;
        linksPage(
            cursor: number | null,
            limit: number,
            options?: CallOptions,
        ): Promise<LinkPage>;
        list(options?: CallOptions): AsyncIterable<Posting>;
        lock(account: AccountRef, options?: CallOptions): Promise<void>;
        lockMany?(
            accounts: readonly AccountRef[],
            options?: CallOptions,
        ): Promise<void>;
        posting(txnId: string, options?: CallOptions): Promise<Posting | null>;
        prune?(txnIds: readonly string[], options?: CallOptions): Promise<void>;
        statement(
            account: AccountRef,
            range: Range,
            options?: CallOptions,
        ): Promise<Statement>;
        timeline(
            account: AccountRef,
            options?: TimelineOptions,
        ): AsyncIterable<Lot>;
    }
    Index
    • Commits one posting under the caller's txnId: stamps postedAt, assigns the next commit sequence, extends each leg account's hash chain, and folds each leg into the account's running balance — all atomic with the enclosing Store.transaction. Callers take the account locks first (lock/lockMany), so chain heads never fork.

      Parameters

      Returns Promise<Transaction>

    • Appends several postings in one engine round trip, exactly as if append ran per posting in order — a later posting chains onto an earlier one's new head when they share an account. Optional: the hot operations that post entry pairs (topUp, settlePayout) fuse through it where the engine offers it; absent, callers loop append.

      Parameters

      Returns Promise<Transaction[]>

    • The archival mover's page read: postings in commit order after cursor, each with its full content, links, posted time, and seq — everything verify-copy-delete needs in one shot (see src/worker/archive.ts). Optional, with prune; both absent means the store cannot host the mover.

      Parameters

      • cursor: number | null
      • limit: number
      • Optionaloptions: CallOptions

      Returns Promise<{ cursor: number | null; postings: readonly ArchivedPosting[] }>

    • Streams every account that has a cached running-balance row — such a row can exist with no posting behind it, which heads never visits, so the prover surfaces the mismatch from here.

      Parameters

      Returns AsyncIterable<AccountRef>

    • The balance re-derived from the account's legs, one Amount per currency present (empty when none), folded server-side on SQL so the prover never ships every leg over the wire.

      Parameters

      Returns Promise<readonly Amount[]>

    • Whether the ledger accepts postings against account: a registered platform account or any well-formed user wallet. The posting guard turns a false into an UNKNOWN_ACCOUNT fault, so a typo can never mint a new account and strand a balance on it.

      Parameters

      Returns Promise<boolean>

    • Streams every account with its chain-head hash, the latest in its tamper-evident chain.

      Returns AsyncIterable<readonly [AccountRef, string]>

    • Like heads plus each account's raw signed leg sum in minor units (debit positive — the leg sign convention, not the account's natural side); head and sum must be read in one statement so a concurrent posting can never tear the pair.

      Parameters

      Returns AsyncIterable<readonly [AccountRef, string, bigint]>

    • How many postings the ledger holds (the newest commit sequence) — the history-size gauge the capacity report reads, O(1) on the SQL engines via the seq index. Optional; a store without it reports the gauge as unknown, never as zero.

      Parameters

      Returns Promise<number>

    • Streams every posting that touched account, in commit order, with each recorded hash; the prover replays these because head hashes alone cannot catch an edited line. options.sinceHash bounds the walk to links recorded after the one carrying that head hash — the incremental seal's tail read; an unknown hash streams nothing.

      Parameters

      Returns AsyncIterable<StoredLink>

    • The chain links the posting extended, one per touched account. verifiedPosting (src/chain.ts) recomputes each link's hash from the posting's stored content before any handler derives money from it — the read that makes an in-place edit of stored history fault instead of shaping a reversal. Empty on an unknown id.

      Parameters

      Returns Promise<readonly PostingLink[]>

    • One page of every stored chain link in commit order, with each link's posting content — the rolling re-proof's read (src/worker/reproof.ts). limit bounds the postings visited per page (a posting's links never split across pages). cursor is engine-internal ordering state: pass null to start from the oldest posting, then the returned cursor verbatim; a null returned cursor means the walk consumed the newest stored posting.

      Parameters

      • cursor: number | null
      • limit: number
      • Optionaloptions: CallOptions

      Returns Promise<LinkPage>

    • Streams every committed posting with its full legs, newest first by commit sequence — a total order, so ties never reorder a page.

      Parameters

      Returns AsyncIterable<Posting>

    • Locks several accounts in one round trip, in a single deadlock-free global order; when absent, callers fall back to per-account lock in that same order. Locks release at commit.

      Parameters

      Returns Promise<void>

    • The whole posting committed under txnId, with all its legs, or null on an unknown id.

      Parameters

      Returns Promise<Posting | null>

    • Deletes the named postings with their legs and chain links — the mover's final step, run inside the same store transaction that updates the signed archive heads, after the page has been re-proved and copied. Never called on unverified or uncopied history.

      Parameters

      • txnIds: readonly string[]
      • Optionaloptions: CallOptions

      Returns Promise<void>

    • The account's entries whose postedAt falls in the half-open range, in commit order. Each entry's amount is the leg's signed effect on the account's balance (balanceDelta), not the raw debit-positive leg.

      Parameters

      Returns Promise<Statement>