Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

invoices state

Back to all declarations

RealmPath

untyped string

RealmPath is this realm's own path, used to build Render links.

Value

"/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/invoices"

Denom

untyped string

Denom is the only asset this realm holds.

Value

"ugnot"

MaxFeeBps

int64

MaxFeeBps is the hard ceiling on any fee this realm could ever charge, enforced by the feeledger the realm is constructed with — a feeBps above it is refused by the primitive's own validation, not by a check in this file. 500 bps = 5%.

Value

500

SettlementFeeBps

int64

SettlementFeeBps is charged on each payment, on the gross, floor-rounded in the ISSUER's favour: 100 bps = 1%. It matches the most conservative live fee in this portfolio (fee\_split, crowdfund, budgets, payroll). The ISSUER bears it, not the payer: a payment of N reduces the outstanding balance by exactly N, and the issuer is credited N minus the fee. A payer's debt must be discharged by what the payer sent, or the arithmetic of "paid in full" would depend on this realm's fee schedule. It is a compile-time constant with no setter, so an invoice's economics cannot be changed after it is issued. The fee is floored PER PAYMENT, so splitting a payment can lower the total fee. Each payment boundary forfeits at most 1 ugnot, and MinPayment bounds how many boundaries an invoice admits. MEASURED on onyx-1, not reasoned: 10,990 paid at once charges 109, while ten payments of 1,099 charge 100. The beneficiary is the ISSUER, who is credited the difference and does not control the payment schedule; the payer gains nothing, because the outstanding balance falls by the gross either way. Gas for one extra payment costs more than the 1 ugnot it saves, so this is priced out rather than prevented, and a colluding issuer/payer pair would spend more to exploit it than they recovered. A final settlement below the fee denominator pays zero fee for that same reason and is NOT a separate case: floor(99/100) is 0 whether or not MinPayment's settle-exactly clause admitted it, so that clause forfeits nothing on its own.

Value

100

FeeCollector

.uverse.address

FeeCollector receives withdrawn fees and swept surplus. Compile-time constant: there is no setter and no transfer path. It is the deploying namespace's address — stated plainly: the operator of this realm. NOTE FOR ANY RE-NAMESPACED PORT: this is the address-as-data hazard that a namespace substitution rewrites silently while every byte-comparison still reports the tree faithful, because the rewrite IS the intended transformation. Re-state it deliberately per chain; never let it be derived.

Value

<gnolang.StringValue>

MinInvoiceAmount

int64

MinInvoiceAmount is the smallest invoice that may be issued. Below the fee denominator a 1% fee floors to zero, so a smaller invoice would be fee-free by accident rather than by design.

Value

1000

MinPayment

int64

MinPayment keeps dust settlements out. It is NOT a floor on the final payment: a payment is accepted when it is at least MinPayment OR when it settles the invoice exactly. Without that second clause an invoice with 300 ugnot outstanding could never be closed, and "unpayable remainder" is a worse failure than dust.

Value

1000

MaxRecordsPerIssuer

untyped bigint

MaxRecordsPerIssuer caps the invoice records one issuer may have STORED at once — open, settled and voided alike. It is what makes the issuer-scoped getters gas-bounded; see the package doc for why the cap counts stored records and not open ones. Issue is permissionless, so this is an AVAILABILITY BOUND and it is documented rather than hidden: an issuer can exhaust their OWN capacity and no one else's, because the bound is per-issuer. The cost of filling it is gas plus a storage deposit on every record. Hitting it is self-service to clear: Release is permissionless and the chain refunds the freed deposit to whoever calls it, so an issuer at the cap can always release their own finished records, and a stranger has a standing incentive to do it for them.

Value

(64 <untyped> bigint)

MaxMemoLen

untyped bigint

MaxMemoLen bounds the free-text memo, in bytes. The memo is rendered, so it is sanitized at the render boundary, never at the write boundary — storing what the issuer actually wrote keeps the record honest.

Value

(256 <untyped> bigint)

StatusOpen

untyped string

Invoice statuses.

Value

"open"

StatusSettled

untyped string

Invoice statuses.

Value

"settled"

StatusVoided

untyped string

Invoice statuses.

Value

"voided"

invoice

type

Value

invoices.invoice

issuerRec

type

Value

invoices.issuerRec

self

.uverse.address

Value

<gnolang.StringValue>

invoices

*v0.Tree

// "issuer|%019d" -> \*invoice

Open
OID
0a544c…2232:5
invoices details

Inspect pointer

issuers

*v0.Tree

// address string -> \*issuerRec

Open
OID
0a544c…2232:8
issuers details

Inspect pointer

nextID

int64

Value

3

rejectStraySend

func()

rejectStraySend aborts when coins are attached to a non-payable call. This realm holds funds, so a stray send would become sweepable surplus, silently converting a user's coins into operator funds.

Open
OID
0a544c…2232:18
rejectStraySend details

Inspect func

Issue

func(payer .uverse.address, amount int64, dueHeight int64, memo string) int64

Issue records an obligation of \`amount\` owed by \`payer\` to the caller, to be settled by \`dueHeight\`. It moves no coins and reserves nothing. Returns the invoice id. dueHeight must not be in the past. A backdated due height would create an invoice that is overdue in the transaction that issued it, which is a claim about a deadline that was never offered.

Open
OID
0a544c…2232:19
Issue details

Inspect func

Pay

func(issuer .uverse.address, id int64) int64

Pay settles part or all of an invoice with the attached coins. The named payer only. Direct EOA calls with -send only (the receipt-guaranteed shape); exactly one positive ugnot coin. The attached amount must not exceed the outstanding balance. Accepting an overpayment would turn a payment into a donation the payer did not choose to make and this realm has no path to return, so it is refused and the payer keeps their coins. Returns the outstanding balance remaining after this payment.

Open
OID
0a544c…2232:20
Pay details

Inspect func

Void

func(id int64)

Void cancels the unpaid remainder of an invoice. The issuer only — this is an issuer forgiving a debt, and nobody else may forgive it for them. It does NOT reverse payments already made. Coins the payer sent are already credited to the issuer's ledger balance and may already have been claimed; there is no mechanism on chain to take them back, and pretending otherwise in the status would be worse than saying so. A voided invoice therefore keeps its \`paid\` figure, which is what makes the record readable afterwards. Voiding does not remove the record. Release does that.

Open
OID
0a544c…2232:21
Void details

Inspect func

Release

func(issuer .uverse.address, id int64)

Release removes a finished invoice and frees its storage. Permissionless: the chain refunds the freed storage deposit to the caller, which is the standing incentive to tidy up a record that is not your own. It refuses an open invoice, which is what makes it safe to let a stranger call: a Release can never destroy an outstanding obligation. An issuer who wants a record gone must Void it first, and that leaves an event. Releasing frees the issuer's slot against MaxRecordsPerIssuer. That is the only way a slot is ever freed — settling and voiding do not free one, because the record is still stored and still walked by every issuer-scoped getter.

Open
OID
0a544c…2232:22
Release details

Inspect func

Claim

func() int64

Claim pays the caller their whole settled balance. The issuer only — there is no "claim on behalf of", because that would let a third party choose the moment someone else's coins move.

Open
OID
0a544c…2232:23
Claim details

Inspect func

WithdrawFees

func() int64

WithdrawFees moves the accrued fee pot to FeeCollector. Anyone may call it; the destination is a compile-time constant, so the caller cannot influence where the coins go.

Open
OID
0a544c…2232:24
WithdrawFees details

Inspect func

SweepSurplus

func() int64

SweepSurplus sends coins held beyond every obligation to FeeCollector. The reserve passed to coinio is the realm's full liability, so a sweep can never reach a coin an issuer is owed.

Open
OID
0a544c…2232:25
SweepSurplus details

Inspect func

isOverdue

func(inv *invoices.invoice, now int64) bool

isOverdue is a pure function of an invoice and the clock, which is what makes it unit-testable without a chain. Overdue means: still open, still owing, and the due height has PASSED. Strictly passed — at exactly dueHeight the invoice is due but not yet late, which is what lets dueHeight == issue height mean "due on receipt" without being born late.

Open
OID
0a544c…2232:26
isOverdue details

Inspect func

IsOverdue

func(issuer .uverse.address, id int64) bool

IsOverdue reports whether one invoice is overdue right now.

Open
OID
0a544c…2232:27
IsOverdue details

Inspect func

OutstandingFrom

func(issuer .uverse.address, payer .uverse.address) int64

OutstandingFrom is the total a payer still owes THIS issuer across the issuer's open invoices. The iteration is bounded by MaxRecordsPerIssuer, NOT by the number of open invoices: it walks the issuer's whole stored prefix and skips the records that are not open. That is why the cap counts stored records — see the package doc. This is the issuer-scoped shape the package doc argues for: a consumer realm gating its own service on its own unpaid bills is trusting only itself. There is deliberately no global per-payer total — see the package doc, "Anyone may issue an invoice naming anyone".

Open
OID
0a544c…2232:28
OutstandingFrom details

Inspect func

OverdueFrom

func(issuer .uverse.address, payer .uverse.address) int64

OverdueFrom is OutstandingFrom restricted to invoices whose due height has passed. A consumer realm that wants to withhold service from a late payer reads this.

Open
OID
0a544c…2232:29
OverdueFrom details

Inspect func

HasOverdueFrom

func(issuer .uverse.address, payer .uverse.address) bool

HasOverdueFrom is OverdueFrom as a predicate, for a consumer that only needs the boolean. It stops at the first hit rather than summing.

Open
OID
0a544c…2232:30
HasOverdueFrom details

Inspect func

InvoiceInfo

func(issuer .uverse.address, id int64) (payer .uverse.address, amount int64, paid int64, dueHeight int64, issuedAt int64, status string)
Open
OID
0a544c…2232:31
InvoiceInfo details

Inspect func

Outstanding

func(issuer .uverse.address, id int64) int64

Outstanding is what is still owed on one invoice. Zero for a settled or voided one — a voided invoice owes nothing by definition, which is the point of voiding it.

Open
OID
0a544c…2232:32
Outstanding details

Inspect func

Memo

func(issuer .uverse.address, id int64) string

Memo is an invoice's free-text memo, exactly as the issuer wrote it. It is UNSANITIZED and caller-supplied: a consumer that renders it owes it the same treatment Render gives it here.

Open
OID
0a544c…2232:33
Memo details

Inspect func

StatusOf

func(issuer .uverse.address, id int64) string

StatusOf is an invoice's status.

Open
OID
0a544c…2232:34
StatusOf details

Inspect func

HasInvoice

func(issuer .uverse.address, id int64) bool

HasInvoice reports whether a record exists, without panicking on absence — every other invoice accessor panics, which makes them unusable as an existence probe.

Open
OID
0a544c…2232:35
HasInvoice details

Inspect func

OpenOf

func(issuer .uverse.address) int

OpenOf is the number of open invoices an issuer holds.

Open
OID
0a544c…2232:36
OpenOf details

Inspect func

RecordsOf

func(issuer .uverse.address) int

RecordsOf is the number of invoice records an issuer currently has stored, of any status. This — not OpenOf — is the figure capped by MaxRecordsPerIssuer, so it is the one an issuer near the cap needs.

Open
OID
0a544c…2232:37
RecordsOf details

Inspect func

IssuedOf

func(issuer .uverse.address) (count int64, invoiced int64)

IssuedOf is how many invoices an address has ever issued, and their total face value. Note the tense: both are lifetime figures and neither falls when an invoice is settled, voided or released.

Open
OID
0a544c…2232:38
IssuedOf details

Inspect func

BalanceOf

func(issuer .uverse.address) int64

BalanceOf is an issuer's settled, unclaimed balance.

Open
OID
0a544c…2232:39
BalanceOf details

Inspect func

Records

func() int

Records is the number of invoice records currently stored, open or not. It falls on Release, so it is a storage figure rather than a count of invoices that have existed.

Open
OID
0a544c…2232:40
Records details

Inspect func

Issuers

func() int

Issuers is the number of addresses that have ever issued an invoice.

Open
OID
0a544c…2232:41
Issuers details

Inspect func

NextID

func() int64

NextID is the id the next Issue will allocate. Exposed so a caller can tell a never-issued id from a released one.

Open
OID
0a544c…2232:42
NextID details

Inspect func

SettledTotal

func() int64

SettledTotal is the sum of every issuer's unclaimed balance.

Open
OID
0a544c…2232:43
SettledTotal details

Inspect func

FeesAccrued

func() int64

FeesAccrued is the fee pot awaiting WithdrawFees.

Open
OID
0a544c…2232:44
FeesAccrued details

Inspect func

Liabilities

func() int64

Liabilities is every coin this realm owes to anyone: the ledger's own total, which is issuer balances plus the fee pot. There is no pool term, and its ABSENCE is the unfunded property this realm exists to model — see the package doc. Do not "fix" this to match payroll's shape.

Open
OID
0a544c…2232:45
Liabilities details

Inspect func

Held

func() int64

Held is the realm's actual ugnot balance, read from the chain.

Open
OID
0a544c…2232:46
Held details

Inspect func

Surplus

func() int64

Surplus is coins held beyond every obligation — what SweepSurplus would move. It is zero when every coin arrived through an entrypoint.

Open
OID
0a544c…2232:47
Surplus details

Inspect func

Height

func() int64

Height is the current chain height, exposed so a caller can compute due heights against the same clock this realm uses.

Open
OID
0a544c…2232:49
Height details

Inspect func

invKey

func(issuer .uverse.address, id int64) string

invKey is issuer|paddedID. The id is left-padded to 19 digits — the width of MaxInt64 — so that lexicographic order over an issuer's prefix is numeric order over their invoice ids. An unpadded decimal would sort "10" before "9" and make a prefix scan return them out of order.

Open
OID
0a544c…2232:50
invKey details

Inspect func

eachOf

func(issuer .uverse.address, fn func(...))

eachOf iterates one issuer's invoice records in id order. The callback returns true to stop, matching avl's own convention.

Open
OID
0a544c…2232:52
eachOf details

Inspect func

getIssuer

func(key string) *invoices.issuerRec
Open
OID
0a544c…2232:53
getIssuer details

Inspect func

mustInvoice

func(issuer .uverse.address, id int64) *invoices.invoice
Open
OID
0a544c…2232:54
mustInvoice details

Inspect func

mustDecOpen

func(issuer .uverse.address)

mustDecOpen decrements an issuer's open count by one and REFUSES rather than masking if it cannot. Both call sites — settlement in Pay and forgiveness in Void — have already proved the invoice exists and was StatusOpen, so neither branch below can fire. The decrement is reachable only through a status transition out of StatusOpen, each invoice makes that transition at most once (both guards require StatusOpen and both set a terminal status), and Issue increments \`open\` for every record it stores. So an open invoice contributed exactly one to this counter and has not yet taken it back. The earlier spelling was \`if r := getIssuer(...); r != nil && r.open > 0\`, which reads as prudence and is the opposite. Those clauses cannot prevent the inconsistency — the status has already been written by the time we get here — they can only decline to notice it, and then COMMIT it. A panic aborts the whole transaction and reverts the status write too, which leaves the realm consistent; masking leaves it inconsistent and silent, and the counter it corrupts is the one MaxRecordsPerIssuer reads. So the guard exists for a future edit, not for today: a path that retires an invoice without coming through here fails loudly on the next one instead of quietly leaking a slot. A check that can never fire and a check that always passes are the same artifact from a reader's seat; the difference is what each does when it is wrong.

Open
OID
0a544c…2232:55
mustDecOpen details

Inspect func

checkedAdd

func(a int64, b int64) (int64, bool)
Open
OID
0a544c…2232:56
checkedAdd details

Inspect func

cell

func(s string) string

cell prepares caller-supplied text for a GFM table cell, truncating it for display first. TableCell rather than InlineText, and the slot is the reason: these bytes land between two \`|\` delimiters, and an unescaped \`|\` in a memo would open a new column and shift every column to its right. InlineText does not escape the pipe. The payer cell above uses the same helper for the same slot even though a bech32 address cannot contain one — matching the helper to the slot is the rule that survives a later edit, whereas "this particular value happens to be safe" is a fact about today's charset. TRUNCATE BEFORE ESCAPING, and on a RUNE boundary. Escaping first and cutting afterwards can slice a \`\\|\` in half and leave the cell ending in a bare backslash; cutting on a byte boundary can split a multi-byte rune and emit invalid UTF-8. Neither is something the sanitizer is asked to repair, because by the time it sees the string the damage is upstream.

Open
OID
0a544c…2232:59
cell details

Inspect func
RealmPath : untyped string ="/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/invoices"
Denom : untyped string ="ugnot"
MaxFeeBps : int64 =500
SettlementFeeBps : int64 =100
FeeCollector : .uverse.address =<gnolang.StringValue>
MinInvoiceAmount : int64 =1000
MinPayment : int64 =1000
MaxRecordsPerIssuer : untyped bigint =(64 <untyped> bigint)
MaxMemoLen : untyped bigint =(256 <untyped> bigint)
StatusOpen : untyped string ="open"
StatusSettled : untyped string ="settled"
StatusVoided : untyped string ="voided"
invoice : type =invoices.invoice
issuerRec : type =invoices.issuerRec
self : .uverse.address =<gnolang.StringValue>
invoices : *v0.Tree Inspect
issuers : *v0.Tree Inspect
ledger : *feeledger.Ledger Inspect
nextID : int64 =3
init.19 : func() Inspect
rejectStraySend : func() Inspect
Issue : func(payer .uverse.address, amount int64, dueHeight int64, memo string) int64 Inspect
Pay : func(issuer .uverse.address, id int64) int64 Inspect
Void : func(id int64) Inspect
Release : func(issuer .uverse.address, id int64) Inspect
Claim : func() int64 Inspect
WithdrawFees : func() int64 Inspect
SweepSurplus : func() int64 Inspect
isOverdue : func(inv *invoices.invoice, now int64) bool Inspect
IsOverdue : func(issuer .uverse.address, id int64) bool Inspect
OutstandingFrom : func(issuer .uverse.address, payer .uverse.address) int64 Inspect
OverdueFrom : func(issuer .uverse.address, payer .uverse.address) int64 Inspect
HasOverdueFrom : func(issuer .uverse.address, payer .uverse.address) bool Inspect
InvoiceInfo : func(issuer .uverse.address, id int64) (payer .uverse.address, amount int64, paid int64, dueHeight int64, issuedAt int64, status string) Inspect
Outstanding : func(issuer .uverse.address, id int64) int64 Inspect
Memo : func(issuer .uverse.address, id int64) string Inspect
StatusOf : func(issuer .uverse.address, id int64) string Inspect
HasInvoice : func(issuer .uverse.address, id int64) bool Inspect
OpenOf : func(issuer .uverse.address) int Inspect
RecordsOf : func(issuer .uverse.address) int Inspect
IssuedOf : func(issuer .uverse.address) (count int64, invoiced int64) Inspect
BalanceOf : func(issuer .uverse.address) int64 Inspect
Records : func() int Inspect
Issuers : func() int Inspect
NextID : func() int64 Inspect
SettledTotal : func() int64 Inspect
FeesAccrued : func() int64 Inspect
Liabilities : func() int64 Inspect
Held : func() int64 Inspect
Surplus : func() int64 Inspect
Address : func() .uverse.address Inspect
Height : func() int64 Inspect
invKey : func(issuer .uverse.address, id int64) string Inspect
padID : func(id int64) string Inspect
eachOf : func(issuer .uverse.address, fn func(...)) Inspect
getIssuer : func(key string) *invoices.issuerRec Inspect
mustInvoice : func(issuer .uverse.address, id int64) *invoices.invoice Inspect
mustDecOpen : func(issuer .uverse.address) Inspect
checkedAdd : func(a int64, b int64) (int64, bool) Inspect
itoa : func(n int64) string Inspect
Render : func(path string) string Inspect
cell : func(s string) string Inspect