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.

latefees package

Overview

Realm latefees publishes a graduated late-fee penalty on an overdue invoice held in the live r/invoices. A creditor (an invoice issuer) declares a late-fee SCHEDULE once — a p/tiers schedule over how many blocks an invoice is overdue — and the realm prices the penalty as a function of that overdue duration, escalating by tier. The penalty can be read live (PenaltyNow) or frozen into a sequence-numbered ASSESSMENT the creditor can point a payer to.

It is the fourth consumer of p/tiers and the one that exercises its "progressive fee" reading over TIME rather than quantity: r/meters prices usage, r/payslips prices withholding, and this prices lateness. It is the second consumer of r/invoices after r/receivables, and reads the exact integration surface that realm's header advertises — invoices.InvoiceInfo, invoices.IsOverdue, invoices.HasInvoice — all non-crossing views, no struct slice crossing a realm boundary.

It is a PUBLISHER, not a collector

r/invoices is live and immutable, so this realm CANNOT add a charge to an invoice there, and it holds no coins of its own — no banker, no deposit, no payout, no withdrawal path. A published penalty is a verifiable CLAIM backed by the invoice's own facts and the creditor's declared schedule, exactly as r/receivables publishes a loss provision and r/cashflow a statement. It compels nothing; a debtor who ignores a late fee is in the same position as one who ignores the invoice. A custodial variant that collects the fee is a separate, larger product and is deliberately out of scope.

The pricing axis, and the one it is not

The base handed to p/tiers is the OVERDUE DURATION in blocks (`now - dueHeight`), and each tier's rate is a ugnot accrual per RateScale blocks. So the penalty ESCALATES WITH TIME: the longer an invoice is overdue, the higher the marginal accrual. p/tiers' rate cap makes `penalty <= overdueBlocks` an arithmetic fact — the fee can never exceed one ugnot per overdue block, a natural ceiling.

It is NOT a percentage of the outstanding amount. p/tiers prices one amount against breakpoints — a single dimension — and a fee that is both time-escalating AND balance-scaled is two dimensions it cannot express in one call. The creditor scales the ugnot accrual to their debt magnitudes through the schedule; the assessment records the outstanding beside the penalty so a reader can compute an effective rate. Composing a balance- scaled fee as a single Charge call would be a plausible, wrong number.

The trust boundary, inherited twice over

A penalty is a self-report of a self-report of a self-report: the issuer set the invoice amount in r/invoices, the due height there, AND the late-fee schedule here. This realm computes faithfully from those; it does not validate that any of them is fair. A creditor may only assess their OWN invoices — Assess derives the issuer from `cur.Previous().Address()` and reads invoices.InvoiceInfo under that key, which returns only invoices that address issued.

Functions

Assess

func Assess(cur realm, invoiceID int64) int64
Ask AI Claude ChatGPT

Assess freezes a late-fee penalty on one of the caller's own overdue invoices and returns its sequence number. The caller must be the invoice's issuer (the creditor), must have declared a schedule, and the invoice must be overdue right now. The invoice's facts and the current schedule are snapshotted, so the assessment is a stable claim even as the invoice keeps accruing or is later paid.

Param

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees" -func "Assess" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "onyx-1" -remote "https://rpc.onyx.testnets.gno.land" ADDRESSgnokey query -remote "https://rpc.onyx.testnets.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees" -func "Assess" -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "onyx-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.onyx.testnets.gno.land" call.tx
  

AssessmentSchedule

func AssessmentSchedule(seq int64) (edges, rates []int64)
Ask AI Claude ChatGPT

AssessmentSchedule returns the schedule snapshot an assessment was priced under — the edges and rates frozen with it, which may differ from the issuer's current schedule.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.AssessmentSchedule()"

Result

AssessmentsOf

func AssessmentsOf(issuer address) int64
Ask AI Claude ChatGPT

AssessmentsOf is the number of assessments an issuer has frozen.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.AssessmentsOf()"

Result

HasAssessment

func HasAssessment(seq int64) bool
Ask AI Claude ChatGPT

HasAssessment reports whether a sequence number names a frozen assessment.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.HasAssessment()"

Result

HasSchedule

func HasSchedule(issuer address) bool
Ask AI Claude ChatGPT

HasSchedule reports whether an issuer has declared a late-fee schedule.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.HasSchedule()"

Result

Height

func Height() int64
Ask AI Claude ChatGPT

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.Height()"

Result

Invoices

func Invoices() string
Ask AI Claude ChatGPT

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.Invoices()"

Result

NumAssessments

func NumAssessments() int64
Ask AI Claude ChatGPT

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.NumAssessments()"

Result

PenaltyNow

func PenaltyNow(issuer address, invoiceID int64) int64
Ask AI Claude ChatGPT

PenaltyNow is the penalty an issuer's invoice has accrued as of the current height, under the issuer's CURRENT schedule. It is 0 when the invoice is not overdue — including once it is paid or voided, because r/invoices does not expose when a payment landed, so accrual is only computable while the invoice is still open and late. A frozen Assess is how a claim survives the invoice being paid. Panics only if the issuer has no schedule or the invoice does not exist.

Params

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.PenaltyNow(,)"

Result

QuotePenalty

func QuotePenalty(issuer address, overdueBlocks int64) int64
Ask AI Claude ChatGPT

QuotePenalty prices a hypothetical overdue duration against an issuer's current schedule, without reading any invoice — the preview a creditor uses to tune a schedule. Panics if the issuer has no schedule or overdueBlocks is negative.

Params

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.QuotePenalty(,)"

Result

Render

func Render(path string) string
Ask AI Claude ChatGPT

Render shows the catalog at "", an assessment at "seq/<n>", and an issuer's schedule at "issuer/<addr>". Every user-supplied value rendered between table pipes is escaped with sanitize.TableCell; addresses carry no markdown metacharacter but are passed through InlineText for the same reason the sibling realms do.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.Render()"

Result

ScheduleOf

func ScheduleOf(issuer address) (edges, rates []int64)
Ask AI Claude ChatGPT

ScheduleOf returns an issuer's current schedule as its edge and rate slices, or two empty slices if none is declared.

Param

Command

gnokey query vm/qeval -remote "https://rpc.onyx.testnets.gno.land" -data "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees.ScheduleOf()"

Result

SetSchedule

func SetSchedule(cur realm, edges, rates string) int
Ask AI Claude ChatGPT

SetSchedule declares or replaces the caller's late-fee schedule: a graduated accrual over OVERDUE BLOCKS, built from comma-separated int64 lists where len(rates) == len(edges)+1 and each rate is a ugnot accrual per RateScale blocks (0..10000). Edges are block counts — e.g. "216000,648000" is roughly ten and thirty days at ~4s blocks. A single rate with no edges is a flat accrual. Replacing a schedule does not touch already-frozen assessments, which snapshot the schedule that priced them.

Params

Command

# WARNING: This command is running in an INSECURE mode.
# It is strongly recommended to use a hardware device for signing
# and avoid trusting any computer connected to the internet,
# as your private keys could be exposed.

gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees" -func "SetSchedule" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -chainid "onyx-1" -remote "https://rpc.onyx.testnets.gno.land" ADDRESSgnokey query -remote "https://rpc.onyx.testnets.gno.land" auth/accounts/ADDRESS
gnokey maketx call -pkgpath "gno.land/r/g1ut6uspuh73e02yauxpmyt8g3wwddaq8utagvm3/latefees" -func "SetSchedule" -args $'' -args $'' -gas-fee 1000000ugnot -gas-wanted 1_000_000_000 -send "" -broadcast=false ADDRESS > call.tx
gnokey sign -tx-path call.tx -chainid "onyx-1" -account-number ACCOUNTNUMBER -account-sequence SEQUENCENUMBER ADDRESS
gnokey broadcast -remote "https://rpc.onyx.testnets.gno.land" call.tx