codespar_ledger
Double-entry ledger — record money movement, read balances, create accounts. Routes to the tenant's self-hosted Lerian Midaz. Typed wrapper session.ledger(args).
codespar_ledger
Meta-tool
Shared rail. Used by both buy-side and sell-side agents; not tied to a money direction.
codespar_ledger is your system of record / books — an immutable, auditable double-entry ledger. It is distinct from codespar_pay and codespar_charge, which move real money through PSPs; the ledger records what happened. Routes to the tenant's self-hosted Lerian Midaz (multi-currency, multi-asset). Covered by the session.ledger(args) typed wrapper.
Actions
The action argument picks the operation:
action | Purpose |
|---|---|
entry (default) | Post an n:n journal entry — source debits must equal destination credits |
balance | Read an account's balances |
account | Create an account |
receipt | Read ONE signed agentic receipt (the Control Record: mandate → payment → delivery) by receipt_id |
receipts | List a consumer's receipts (consumer_id defaults to the session user; limit defaults to 50) |
The ledger is asset-agnostic — no currency or country needed. Amounts are in minor units (centavos, satoshis, …) with a per-asset scale.
receipt / receipts are reads of the signed receipt store, not journal operations: they answer "what did this agent actually settle, and under which mandate" without touching the books. Every receipt read is itself audited.
Typed wrapper
// Post a journal entry: move 150.00 BRL from a wallet to revenue
const entry = await session.ledger({
action: "entry",
asset: "BRL",
scale: 2,
source: [{ account: "@wallet/user_123", amount: 15000 }],
destination: [{ account: "@revenue/store", amount: 15000 }],
description: "Order #1234 settled",
});
// Read a balance
const balance = await session.ledger({ action: "balance", account: "<account-uuid>" });
// Create an account
const account = await session.ledger({
action: "account",
alias: "@wallet/user_123",
name: "User 123 wallet",
type: "deposit",
});entry = session.ledger({
"action": "entry",
"asset": "BRL",
"scale": 2,
"source": [{"account": "@wallet/user_123", "amount": 15000}],
"destination": [{"account": "@revenue/store", "amount": 15000}],
"description": "Order #1234 settled",
})Direct execute
const balance = await session.execute("codespar_ledger", {
action: "balance",
account: "<account-uuid>",
});Args shape
| Field | Type | Required | Description |
|---|---|---|---|
action | "entry" | "balance" | "account" | No | Defaults to "entry" |
asset | string | entry, account | Asset / currency code (BRL, USD, USDC, …) |
scale | number | No | Decimal places for the asset (default 2; JPY=0, most crypto=6/8) |
source | array | entry | Debit side(s): [{ account (alias), amount (minor units) }] |
destination | array | entry | Credit side(s): same shape as source |
description | string | No | Transaction description (entry only) |
account | string | balance | Account UUID to read balances for |
alias | string | account | Account alias, e.g. @wallet/user_123 |
name | string | account | Account display name |
type | string | No | Midaz account type: deposit, savings, external (default deposit) |
metadata | object | No | Free-form metadata stored on the entry / account |
Operator setup
- Lerian Midaz — the ledger is the tenant's own Midaz instance. The operator connects it once in
/dashboard/auth-configs; credentials are stored in the vault. See Lerian Midaz for self-hosting.
See also
- codespar_pay / codespar_charge — move real money (the ledger records it)
- Agent with a Wallet cookbook — wallet balances backed by a ledger
- Tools & meta-tools — full meta-tool list
codespar_get_started
Read-only setup planner. Returns the ordered happy path for the authenticated workspace, covering which rails are already connected, what to connect next, and the first calls to try. Moves no money.
codespar_discover
Semantic + lexical tool search. pgvector text-embedding-3-small + pg_trgm fallback, with connection bias toward providers the session can already reach.