Documentation
¶
Overview ¶
Package treasury is the reserve fund behind every payout: real capital, held and accounted for.
It is the platform's OWN fund — a backed pool that stands behind the growth-loop payouts (referrals, affiliates, OSS authors), so a payout is a debit against funded capital and never unbounded minting. Where finance tracks what each CUSTOMER holds and spends, treasury tracks what the PLATFORM holds.
It answers on TWO prefixes and owns neither whole: GET /v1/finance/{treasury,accounts} beside billing's six commerce-projected /v1/finance/* customer reads, and the SuperAdmin /v1/admin/treasury/* reserve mutations. The routes are disjoint; the full table is below.
It is the cloud-facing adapter around the ledger-of-record PORT (ledger.Backend): this file owns HTTP, tenant scoping, audit and the KMS-signed L1 anchor + the Hanzo policy/fund/payout logic; the backend owns the double-entry. Two backends satisfy the port — the native Base/SQLite engine (apps/treasury/ledger, offline/default, and the SAME engine apps/finance keeps each org's prepaid wallet in) and the Formance adapter (apps/treasury/formance, the Postgres-backed ledger of record when FORMANCE_LEDGER_URL is wired). Selecting one is a config flip.
Storage tiers (OLTP → OLAP): the authoritative double-entry is the ledger-of-record backend (single-writer, overdraw-guarded — reserve/revenue/house on the house tenant). Cross-tenant GLOBAL analytics is the datastore OLAP projection in the shared hanzoai/datastore, fed by the SAME event stream o11y already emits — treasury money-actions mirror there via cloud's audit datastore mirror, so there is NO second metering pipeline. datastore is NEVER the ledger of record; single-tenant drill-down reads the authoritative ledger, cross-tenant aggregates read the projection.
ONE scope-aware /v1/finance/* engine, three tenancy surfaces — the tenant is derived from the validated IAM identity, house/reserve is locked to SuperAdmin, and a per-org caller only ever sees its own tenant:
GET /v1/finance/treasury (org) reserve health + policy (the pool backing MY payouts) GET /v1/finance/accounts (org) MY ledger accounts (admin: ?scope=house | ?org=<t>) GET /v1/admin/treasury (SuperAdmin) full report + journal + anchor status POST /v1/admin/treasury/policy (SuperAdmin) set the revenue-share % POST /v1/admin/treasury/sweep (SuperAdmin) accrue the revenue-share into the fund for a period POST /v1/admin/treasury/seed (SuperAdmin) inject bootstrap capital into the fund POST /v1/admin/treasury/anchor (SuperAdmin) anchor the ledger root on Hanzo L1 PUT /v1/admin/treasury/anchor/signer (SuperAdmin) the reserve MPC wallet that signs anchors
The three surfaces (admin.hanzo.ai SuperAdmin, console.hanzo.ai per-org customer, finance.hanzo.ai per-org operator) are the SAME engine projected by IAM scope. A separate frontend agent builds the console + finance surfaces against this contract. The reserve-fund admin board is the `treasury` admin head (distinct from the existing /v1/admin/finance COGS/margin god-view in apps/admin — they compose, never collide).
serve.go auto-registers GET /v1/finance/health.
Index ¶
- Constants
- func BindAnchorSigner(addr common.Address, ...)
- func Credit(ctx context.Context, program, ref, memo string, amountCents int64) (credited bool, entryID string, err error)
- func Mount(app cloud.Router, deps cloud.Deps) error
- func Reserve(ctx context.Context, program, ref, memo string, amountCents int64) (backed bool, entryID string, err error)
- func ReserveCents(ctx context.Context) (int64, bool)
- func Shutdown() error
- func StorageDriver() string
Constants ¶
const ( // DriverSQLite is the Hanzo default and what production runs: the per-tenant // Hanzo Base (SQLite) files this package's Manager opens under CLOUD_DATA_DIR. DriverSQLite = "sqlite" // DriverPostgres is the supported OPT-IN: the Formance Postgres ledger of record, // selected by wiring FORMANCE_LEDGER_URL. It is never the live default. DriverPostgres = "postgres" )
Storage-driver selection for the treasury ledger-of-record. Decomplected into ONE pure function so "the default is SQLite" is a single, testable fact rather than an implicit else-branch buried in Mount.
const ( ProgramReferral = "referral" ProgramAffiliate = "affiliate" ProgramAuthor = "author" )
Program identifiers for backed payouts — the ONE place the growth loops name themselves to the treasury, so a payout sink account id is never re-spelled.
Variables ¶
This section is empty.
Functions ¶
func BindAnchorSigner ¶
func BindAnchorSigner(addr common.Address, sign func(ctx context.Context, hash []byte) ([]byte, error))
BindAnchorSigner binds a quorum-gated treasury signer (the reserve's 3-of-5 MPC wallet) as the anchor's signer: addr is the wallet's EVM address, and sign delegates the 32-byte signing hash to the threshold ring. A nil sign unbinds (revert to the local key). This is the finance seam — the treasury reserve wallet, not a single key, governs on-chain anchors.
func Credit ¶
func Credit(ctx context.Context, program, ref, memo string, amountCents int64) (credited bool, entryID string, err error)
Credit is the INBOUND mirror of Reserve: it credits amountCents into the platform reserve fund (revenue:platform → fund:reserve), idempotently keyed by ref. It is the "pay ourselves" seam — when a growth loop's royalty is owed to HANZO itself (a Hanzo-maintained OSS template deployed by another org), the creator share is realized into the treasury reserve instead of paid out to an external wallet.
It reuses the ledger-of-record's Seed primitive (a fixed-amount reserve credit, distinct KindSeed, idempotent by ref) — NOT a new ledger. Idempotency by ref makes a retry a no-op: the reserve is credited AT MOST ONCE per ref, the mirror of the loops' at-most-once accrual latch.
- credited=true → posted (or already posted for this ref). entryID is the journal entry id (empty on passthrough), for the caller to record.
- credited=false → only on an unexpected ledger error (err set); the caller leaves its own reservation intact and reconciles.
When treasury is NOT mounted (a partial deploy or a growth-loop unit test that does not wire treasury) Credit is a PASSTHROUGH returning credited=true — the same degrade-gracefully contract Reserve uses.
func Reserve ¶
func Reserve(ctx context.Context, program, ref, memo string, amountCents int64) (backed bool, entryID string, err error)
Reserve backs a payout of amountCents (minor units) for `program` against the platform reserve fund: it posts the double-entry fund→payout:<program> journal entry, idempotently keyed by ref, and reports whether the fund could cover it.
- backed=true → posted (or already posted for this ref); the caller MUST now credit the recipient wallet. Fund down, wallet up — reconciled.
- backed=false → INSUFFICIENT RESERVE; the caller MUST NOT credit. The payout is honestly pending/blocked until a sweep or seed replenishes the fund.
When the treasury subsystem is NOT mounted (a partial deploy, or a growth-loop unit test that does not wire treasury) Reserve is a PASSTHROUGH returning backed=true — behaviour identical to before treasury existed, the same degrade-gracefully contract the commerce seam uses. In production the subsystem is always mounted, so the reserve is enforced. entryID is the journal entry id (empty on passthrough), for the caller to record alongside its own payout row.
func ReserveCents ¶
ReserveCents reports the reserve fund's currently available balance (minor units) and whether the treasury subsystem is mounted. The growth loops use it only to render an honest "X cents available" message when a payout is blocked for lack of reserve — never as an authority (the atomic guard in DebitReserve is the authority). Unmounted → (0, false).
func StorageDriver ¶
func StorageDriver() string
StorageDriver reports the storage driver the treasury ledger-of-record will use, decided by the environment ALONE:
- "sqlite" (default) — per-tenant Hanzo Base files. This is the standing rule: every tenant's books run live on its own Base file.
- "postgres" — set FORMANCE_LEDGER_URL to opt into the Formance Postgres ledger of record for the house books.
This is the ONE place the driver is decided; Mount branches on it and logs it.
Types ¶
This section is empty.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
anchorctl
command
Command anchorctl bootstraps the Hanzo L1 (chain 36963) treasury anchor: it provisions the KMS-held signer key, funds it, and deploys contracts/TreasuryAnchor.sol — the on-chain witness that clients/treasury/anchor_evm.go later writes ledger roots to.
|
Command anchorctl bootstraps the Hanzo L1 (chain 36963) treasury anchor: it provisions the KMS-held signer key, funds it, and deploys contracts/TreasuryAnchor.sol — the on-chain witness that clients/treasury/anchor_evm.go later writes ledger roots to. |
|
Package formance is the Formance Ledger adapter for the treasury: it satisfies ledger.Backend by posting the reserve fund's double-entry through a live Formance Ledger service (Postgres-backed, the production ledger of record) over its v2 HTTP API.
|
Package formance is the Formance Ledger adapter for the treasury: it satisfies ledger.Backend by posting the reserve fund's double-entry through a live Formance Ledger service (Postgres-backed, the production ledger of record) over its v2 HTTP API. |
|
Package ledger is the native, double-entry accounting core of the Hanzo finance stack — the store-agnostic engine that owns EVERY accounting rule (balanced postings, a non-negative reserve fund, idempotent journal entries, revenue-share math) and NOTHING about how those facts are persisted or served.
|
Package ledger is the native, double-entry accounting core of the Hanzo finance stack — the store-agnostic engine that owns EVERY accounting rule (balanced postings, a non-negative reserve fund, idempotent journal entries, revenue-share math) and NOTHING about how those facts are persisted or served. |
|
sqlstore
manager.go is the PER-TENANT selector over the treasury Store: it resolves each request to its OWN Hanzo Base (SQLite) file instead of a process-wide singleton, so one tenant's finance/ledger writes can NEVER appear in another tenant's reads.
|
manager.go is the PER-TENANT selector over the treasury Store: it resolves each request to its OWN Hanzo Base (SQLite) file instead of a process-wide singleton, so one tenant's finance/ledger writes can NEVER appear in another tenant's reads. |