money

package
v1.801.413 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 4, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package money is exact money: a USD balance carried to 18 decimals, so no amount is ever rounded away.

It is the ONE money value for the Hanzo cloud finance stack. The 18 decimals are EVM/ERC-20 precision, so an off-chain ledger amount and an on-chain uint256 credit balance are THE SAME INTEGER — no conversion or rounding at the boundary. Every per-token AI price is represented and billed EXACTLY; there is no cent-flooring and no fractional-cent skim, at any scale.

The exact-number machinery (big.Int fixed-point, no float, no precision ceiling) is NOT reimplemented here — it lives ONCE in github.com/hanzoai/money + github.com/hanzoai/decimal, the shared money value for the whole stack. This package is the thin policy layer that pins the cloud's credit unit to 18-decimal USD and nothing else; it is the single place that decision lives.

An Amount is IMMUTABLE — every operation returns a new value — and the zero value is a valid 0.

Index

Constants

View Source
const Decimals = 18

Decimals is the fixed-point scale of the credit unit: 18 (the EVM/ERC-20 unit). The smallest representable amount is 10^-18 USD.

Variables

This section is empty.

Functions

This section is empty.

Types

type Amount

type Amount struct {
	// contains filtered or unexported fields
}

Amount is an exact USD credit value (18-decimal, big.Int-backed, immutable). It wraps the shared money.Amount, fixed to the credit unit.

func FromAtto

func FromAtto(units *big.Int) Amount

FromAtto wraps a raw atto-USD magnitude — 18 decimals, the storage/on-chain form (the value an EVM uint256 credit balance holds). A nil magnitude is 0.

It is named for the UNIT it takes, not for its Go type. As FromInt it read as "make an Amount from an integer", and money.Amount.Minor() also returns an integer — so FromInt(x.Minor()) type-checked, read fine, and fed CENTS to an 18-decimal constructor, understating every zen debit by 10^16 until v1.801.44. FromAtto(x.Cents()) cannot read fine. A name that states the unit refuses the bug the type system cannot see.

func FromCents

func FromCents(cents int64) Amount

FromCents converts integer cents (a human/legacy unit) to an exact credit Amount.

func FromDecimal

func FromDecimal(d decimal.Decimal) Amount

FromDecimal wraps an exact decimal USD value in the credit unit — the typed counterpart of ParseUSD, with no string round-trip. The decimal IS the value; the credit unit's 18 decimals are its storage scale, so nothing is rescaled and nothing is rounded here.

This is the ONE way to carry a value priced as a shared money.Amount (whose Currency may declare a COARSER minor unit — money.USD declares 2) into the credit unit. Take the decimal, never Amount.Minor(): Minor() rescales the value to the CURRENCY's minor unit, so an 18-dp value tagged money.USD comes back as CENTS, and cents fed to an 18-dp constructor understate by 10^16.

func ParseInt

func ParseInt(s string) (Amount, error)

ParseInt parses a signed 18-decimal integer string (the storage/on-chain form). An empty string is 0.

func ParseUSD

func ParseUSD(s string) (Amount, error)

ParseUSD parses a decimal USD string ("6.60", "-0.00132", "100") to an EXACT Amount — no float. Up to 18 fractional digits are honored; more is an error rather than a silent truncation (we never quietly drop money).

func TokenCost

func TokenCost(tokens int, pricePerMillion Amount) Amount

TokenCost is the EXACT cost of n tokens at pricePerMillion USD/1M-tokens: n × price / 1e6, rounded half-away-from-zero at 10^-18 — so a bill is never floored to zero and never skims a fraction.

func Zero

func Zero() Amount

Zero is the additive identity.

func (Amount) Add

func (a Amount) Add(b Amount) Amount

Add returns a + b. (The credit unit is fixed, so the shared add can never mismatch.)

func (Amount) Atto

func (a Amount) Atto() *big.Int

Atto returns a fresh big.Int of the atto-USD magnitude — 18 decimals, the on-chain uint256 value. The unit is in the name: this is NOT interchangeable with money.Amount.Minor(), which renders the CURRENCY's minor unit (money.USD declares 2, so it returns cents). Both are "an integer"; they differ by 10^16.

func (Amount) AttoString

func (a Amount) AttoString() string

AttoString is the canonical STORAGE form: the signed atto-USD integer as a decimal string (exact, on-chain-identical, sortable at fixed width by the caller).

func (Amount) Cents

func (a Amount) Cents() int64

Cents rounds the value to whole cents (half-away-from-zero) — a human/legacy display unit ONLY; never use it inside money math (it is lossy by construction).

func (Amount) CentsUp

func (a Amount) CentsUp() int64

CentsUp rounds AWAY from zero to whole cents: the amount rendered in a cents-only surface without ever rendering as less than it is.

Cents rounds to nearest, so a sub-half-cent charge becomes zero — and a zero charge sent to a spend cap is a charge the cap does not weigh at all. Rounding up is the conservative direction for anything that GATES: the caller may be refused a fraction of a cent early, never admitted for free. Use Cents for display and this for limits.

func (Amount) Cmp

func (a Amount) Cmp(b Amount) int

Cmp reports −1, 0, +1 as a <, ==, > b.

func (Amount) IsNeg

func (a Amount) IsNeg() bool

IsNeg reports whether a < 0.

func (Amount) IsZero

func (a Amount) IsZero() bool

IsZero reports whether a == 0.

func (Amount) MarshalJSON

func (a Amount) MarshalJSON() ([]byte, error)

MarshalJSON emits the exact decimal USD string ("0.00132") — a STRING, never a JSON number, so no consumer can reintroduce a float rounding error.

func (Amount) Neg

func (a Amount) Neg() Amount

Neg returns −a.

func (Amount) Sign

func (a Amount) Sign() int

Sign reports −1, 0, +1 as a <, ==, > 0.

func (Amount) String

func (a Amount) String() string

String renders the value as a trimmed decimal USD string ("6.6", "0.00132", "-0.5", "0") — the human/JSON form. Exact: derived from the integer coefficient, never a float.

func (Amount) Sub

func (a Amount) Sub(b Amount) Amount

Sub returns a − b.

func (*Amount) UnmarshalJSON

func (a *Amount) UnmarshalJSON(b []byte) error

UnmarshalJSON accepts either a quoted decimal USD string or a bare decimal number (parsed exactly, without float).

func (Amount) Unwrap

func (a Amount) Unwrap() hz.Amount

Unwrap is the wrapped shared money.Amount — the same exact value, in the credit unit. It exists for the ONE boundary that speaks the shared type: the internal plane (plane.Amount takes a hanzoai/money Amount), which is a decimal-string wire built so a debit crosses a process boundary UNROUNDED. Reaching that wire through Cents() defeated the wire's whole reason to exist: every plane.Amount call site in the repo was plane.Amount(money.FromUSD(x.Cents())) — an exact value, flattened to cents, re-wrapped as "exact". A per-token debit priced below a cent crossed as $0.00.

When this wrapper collapses into hanzoai/money, call sites lose the call and nothing else.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL