Skip to content

feat(billing): add live FX rates and integer ledger history - #5

Open
1amKhush wants to merge 10 commits into
ContextVM:masterfrom
1amKhush:feat/billing-hardening
Open

feat(billing): add live FX rates and integer ledger history#5
1amKhush wants to merge 10 commits into
ContextVM:masterfrom
1amKhush:feat/billing-hardening

Conversation

@1amKhush

@1amKhush 1amKhush commented Aug 4, 2026

Copy link
Copy Markdown

Summary

Addresses the two billing follow-ups identified during the review of #1:

  • Replace the operator-managed static BTC/USD rate with a live FX source.
  • Store all ledger monetary values as integer nano-USD.

This PR is independent of the pi-ai dependency upgrade.

Changes

Live FX rates

  • Added an Fx component that queries Kraken, Coinbase, and Binance.
  • Uses the minimum valid USD/BTC rate to favor the operator.
  • Caches the rate for one hour.
  • Tolerates individual provider failures.
  • Fails the top-up when every provider is unavailable instead of using a stale rate.
  • Preserves MUXLL_TOPUP_BUFFER_PCT when calculating Lightning quotes.
  • Removed the operator-managed MUXLL_USD_PER_SAT configuration.

Integer ledger storage

  • Changed usage history to store:
    • cost_nusd
    • charge_nusd
  • Changed credit history to store:
    • amount_nusd
  • Added an automatic transactional migration for existing REAL history columns.
  • Preserved the existing public ledger API, which continues to expose USD values.

Documentation

  • Updated .env.example, README.md, AGENTS.md, and design/billing.md.
  • Documented the one-hour FX cache, fail-closed behavior, and integer storage model.

Verification

  • Typecheck passes.
  • Lint passes.
  • Non-proxy test suite: 74 passed, 2 skipped, 0 failed.
  • Added regression coverage for:
    • FX provider selection and caching.
    • Individual and total provider failures.
    • Integer nano-USD storage.
    • Legacy ledger migration.
  • The existing proxy test still encounters the unrelated sandbox Bun.serve({ port: 0 }) EADDRINUSE issue.

Refs #1

ContextVM-org and others added 10 commits July 4, 2026 12:20
- Introduce model visibility policies via MUXLL_MODELS_ALLOW / DENY and config file
- Add gated admin tools (admin.models.setPolicy, admin.balance.credit) controlled by MUXLL_ADMIN_PUBKEYS
- Implement prepaid billing infrastructure: ledger DB, markup, min charge, option to enable via MUXLL_BILLING
- Update ENV example and developer docs to reflect new capabilities and code organization
Copilot AI lite review requested due to automatic review settings August 4, 2026 17:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Phase 1 billing + model-policy controls to the muxll server, including CEP-8 gating/top-ups, live FX quoting, and integer nano-USD ledger storage, while extending the client/CLI to support balance + top-up flows.

Changes:

  • Introduces server-side billing primitives (Ledger, PriceBook, CEP-8 resolvePrice/top-up) and live FX rate fetching with caching.
  • Adds a model visibility policy layer (Catalog) plus admin tools to manage it at runtime, with persistence.
  • Extends client and CLI surfaces (and tests) to support balance.*, topup, and new models.list search/limit semantics.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
README.md Updates project positioning and documents model policy/admin tools + billing CLI usage.
packages/server/tests/pricing.test.ts Regression coverage for free-output computeOutputCap behavior.
packages/server/tests/policy.test.ts End-to-end tests for model policy list/resolve hiding and admin gating.
packages/server/tests/ledger.test.ts Verifies nano-USD integer storage and legacy REAL-column migration.
packages/server/tests/integration.test.ts Adds reasoning-effort forwarding tests and mapReasoning unit coverage.
packages/server/tests/fx.test.ts Tests FX provider min-selection, caching, partial failure tolerance, fail-closed.
packages/server/tests/catalog.test.ts Unit tests for Catalog policy matching/patching/merge semantics.
packages/server/tests/billing.test.ts End-to-end billing tests (balances, caps, debits, CEP-8 top-up flow).
packages/server/src/wire.ts Adds mapReasoning for per-provider reasoning/thinking option mapping.
packages/server/src/server.ts Integrates Catalog, admin tools, billing cap+settle, and CEP-8 transport wrapping.
packages/server/src/pricing.ts Adds PriceBook (markup mode) and computeOutputCap token ceiling logic.
packages/server/src/payments.ts Implements CEP-8 resolvePrice policy for waive/reject and top-up quoting.
packages/server/src/main.ts Wires env-driven billing/policy config, persistence, and NWC payment processor.
packages/server/src/ledger.ts Implements SQLite-backed nano-USD ledger and transactional migration logic.
packages/server/src/index.ts Exposes new server public API exports (catalog/billing/fx/ledger/pricing).
packages/server/src/fx.ts Adds live USD/sat rate from multiple providers with TTL cache.
packages/server/src/catalog.ts Adds model visibility policy layer (list/resolve) with patch semantics.
packages/core/src/index.ts Adds new tool methods, schemas, and types for policy + billing + models.list params.
packages/client/tests/client.test.ts Adds client-side CEP-8 rejection/top-up identity regression test.
packages/client/src/index.ts Exports balance response types.
packages/client/src/client.ts Adds payments transport, balance/topup APIs, and streaming pre-rejection handling.
packages/cli/tests/cli.test.ts Adds test for actionable insufficient-balance CLI error formatting.
packages/cli/src/index.ts Adds balance / topup commands and CEP-8 payment interaction UX.
packages/cli/package.json Moves @contextvm/sdk to dependencies for runtime payments usage.
design/idea.md Adds design note for overall router intent (reference material).
design/billing.md Adds detailed billing/payout design document for current direction and next phases.
AGENTS.md Updates contributor guide for new model resolution/visibility and billing behavior.
.env.example Documents new env vars for model policy, admin tools, and billing/top-up config.
Suppressed comments (1)

packages/core/src/index.ts:341

  • admin.balance.credit accepts amountUsd as z.number().positive(), which may still allow Infinity. Constrain this to a finite number to avoid corrupting ledger state.
export const adminBalanceCreditInput = {
  pubkey: z.string(),
  amountUsd: z.number().positive(),
  note: z.string().optional(),

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +103 to +109
// Free output (no priced output): cap by the caller/model limit only.
if (i.rates.outputPerToken <= 0) {
const cap = Math.min(
i.userMaxTokens ?? Infinity,
i.modelMaxTokens ?? Infinity,
i.contextWindow ?? Infinity,
);
Comment on lines +302 to +305
// balance.topup: payment is verified by CEP-8 before the handler runs.
export const balanceTopupInput = {
amountUsd: z.number().positive(),
};
Comment thread README.md
Comment on lines 9 to +12
This repository currently holds a **proof of concept**: chat completions (with
and without streaming) and model listing. Payments, quotas, and provider config
files are intentionally out of scope for now.
and without streaming) and model listing. Billing is in progress (Phase 1:
a prepaid USD balance ledger funded by admin grants, with a markup over
upstream cost); see [`docs/billing.md`](docs/billing.md) for the design.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants