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.

inventory package

Overview

Package inventory is a per-owner inventory sub-ledger whose cost of goods sold is DERIVED from the lots on hand rather than asserted by a caller.

What this realm is for

A general ledger takes a debit code, a credit code and an amount from whoever is posting. That is the right design for a ledger, and it means gno.land/r/.../books structurally CANNOT know that an entry was a shipment, or that the cost charged for that shipment is the cost the goods were actually bought at. Nothing stops a shipper from booking a flattering number, and nothing in the book can tell afterwards.

This realm closes that gap for one class of entry. It holds each item's cost lots as state, and when goods ship it computes the charge from those lots by the item's declared costing method. The amount is never a parameter: Ship takes a QUANTITY and returns the cost it derived.

The resulting claims are narrow and checkable by anyone, which is the point. Per item, from p/lots' own cross-foot:

Example
1receivedCost == chargedCost + costOnHand

and, across a whole register, against the ledger the realm posted to:

Example
1balance(1300) == sum of costOnHand over items
2balance(5000) == sum of chargedCost over items
3balance(3900) == sum of receivedCost over items

All four are exported — ItemCrossFoot, CrossFootInventory, CrossFootCOGS, CrossFootContributed — and all are FREE reads, deliberately; see "Why the invariants are free reads" below.

Note what the three ledger identities are NOT. Each compares a walk of the lots against an account balance, and the two are maintained by different code: the pool counts for itself inside p/lots, while this realm posts to the book. A disagreement is therefore a real signal and not a tautology. That is the same reason p/lots keeps counters beside its lots.

The chart is three accounts and is fixed

Example
11300  Inventory                (asset,   debit-normal)
25000  Cost of goods sold       (expense, debit-normal)
33900  Inventory contributed    (equity,  credit-normal)

A receipt is debit 1300 / credit 3900. A shipment is debit 5000 / credit 1300 for the DERIVED cost. There is no OpenAccount entrypoint and the underlying book is created with a hard cap of three accounts, so the chart cannot grow. The accounting equation offsets at 0 = 0 on an empty register and after every posting, because 1300 + 5000 == 3900 is the register-wide restatement of each pool's own cross-foot.

3900 IS A PLUG, AND THIS REALM IS FORCED TO PICK ONE

This is the design's one unavoidable assertion about the world, so it is stated here rather than buried.

gno.land/r/.../assets faced the same question about an asset's cost basis and answered by NOT BOOKING IT: the only honest credit legs were a liability ("2000 Acquisition payable") or an equity plug ("3000 Contributed capital"), both of which assert how the asset was funded, which that realm does not know. It kept the cost in register state as data instead.

That answer is not available here, and the difference is structural rather than a matter of taste. The product IS cost of goods sold. A shipment debits 5000 and credits 1300, so 1300 must carry a balance, so the receipt must reach the book — and a debit to 1300 needs a credit leg. The choice is therefore not "book it or not" but "which plug", and every candidate asserts something unobservable:

  • 2000 Accounts payable asserts the goods were bought on credit and that a liability is outstanding. This realm cannot see a payment, so the liability would never be relieved and would grow without bound.
  • 1000 Cash asserts the goods were paid for in cash from a balance this realm does not hold and cannot verify. It holds no coins at all.
  • 3900 Inventory contributed asserts the goods were contributed by the owner. It is wrong in exactly the same way the other two are, and it is the only one of the three that is SELF-CONSISTENT without an unobservable second event: a contribution is complete on arrival.

So 3900 was chosen because it needs no follow-up transaction to stay coherent, not because it is true. Read it as "goods arrived from somewhere this ledger does not model". A register whose goods were in fact purchased on credit is understating liabilities and overstating equity by exactly balance(3900), and no code path here can detect that. Pairing this sub-ledger with a real payables ledger is out of scope for v1 and is the honest fix.

Costing method is per item and is FIXED at creation

An item is added by AddFIFO, AddLIFO or AddWAVG — three entrypoints rather than one taking a method code, following r/assets' Place / PlaceDeclining precedent, so a caller never has to know an enum's numbering.

p/lots fixes the method at pool construction and documents why: changing it mid-life would recost nothing already charged but would change what the next shipment costs, which is a restatement a sub-ledger must not be able to make silently. This realm inherits that and adds nothing: there is no entrypoint that changes an item's method. An owner who must switch opens a new SKU and discloses it.

The three methods differ observably, which is the point of having them: FIFO and LIFO charge different amounts whenever unit costs differ, and WAVG re-anchors every receipt into a single merged lot so it holds exactly one lot and can never hit the per-item lot cap.

That exemption is not a free win, and the trade is the other way round from how it reads. WAVG escapes the LOT cap and in exchange acquires a refusal FIFO and LIFO do not have: a merged lot must satisfy p/lots' per-lot overflow precondition `Cost <= maxInt64/Qty`, and two lots that each satisfy it separately can merge into one that does not. So under WAVG a receipt can be refused for the pool's ACCUMULATED HISTORY rather than for anything about the receipt — the same receipt a FIFO item would have taken. It is a far corner of the arithmetic and not a practical bound, but it is the reason LotCapacity is the wrong thing to watch for a WAVG item: its figure is a bound WAVG will never approach, so a caller sizing headroom from it is reading the one limit that does not apply. See p/lots' Pool.Receive.

A ZERO-COST POSTING IS SKIPPED, AND THAT IS NOT A SHORTCUT

p/journal rejects a posting of zero (ErrInvalidAmount) — correctly; a zero entry is not an event. But both of this realm's postings can legitimately be zero:

  • Receive with cost 0 is free goods, which p/lots accepts (ErrBadCost is only for a NEGATIVE cost).
  • Ship out of lots that cost nothing derives a charge of 0.

In both cases the pool is updated and NOTHING is posted. The identities above are preserved exactly, because a zero contribution to the ledger side is matched by a zero contribution to the walk side. The same choice r/assets makes for a degenerate declining schedule, for the same reason.

What this realm does NOT do

  • No custody. It holds no coins, has no withdrawal path, and refuses a user call that arrives carrying any. A cost is a number an owner typed.
  • No write-off, shrinkage or revaluation. Shrinkage is a real inventory event and its absence is a real limitation: there is currently no way to remove goods without charging them to 5000, so a loss is indistinguish- able from a sale. The posting it needs is a debit to a 5-series loss account against a credit to 1300, which means a fourth account and a fourth entrypoint. Deliberately deferred to keep the chart fixed at three for v1, and named here rather than discovered later.
  • No revenue. A shipment books its COST, never a sale price. Revenue belongs to a receivables ledger (r/invoices) and tying the two together would require this realm to learn what was sold for how much.
  • No period close. p/journal can seal a book up to a HEIGHT; sealing a derived book could only make the next derivation unpostable. The capability exists in the engine and is deliberately not exposed.
  • No bulk receive or ship. One item per call — see the bound below.
  • No truth. A sub-ledger is a set of claims by its owner. With no custody there is nothing tying "received 100 units at cost 5000" to a real holding. The invariants here prove that the postings follow from the stored lots; they prove nothing about the world.

Why the invariants are free reads, and what the bound costs

r/books exposes Rederive as an owner-only crossing function, to contain the cost of a full re-walk. This realm diverges, deliberately and for the same reason r/assets does: the derivation IS the product, and a claim only its owner can check is not a claim worth making. Rederive, ItemCrossFoot, the three register cross-foots and Render are all free reads, so any third party can verify a register from vm/qeval with no key.

MaxLotsPerItem is 64 against p/lots' own MaxLotsLimit of 1024, and the gap is not timidity. p/lots' audit left the cost of its O(live lots) walks explicitly UNPRICED and recorded that a realm rendering many pools must measure its own gas. This realm is that realm, so the figures are measured rather than reasoned about, under the pinned onyx toolchain.

There are TWO cost axes, not one, and this paragraph used to name only the first: MaxItemsPerRegister*MaxLotsPerItem live lots, and separately MaxEntriesPerRegister postings. It called 64 items of 64 live lots "the worst case this realm can hold", which is false — a register can sit at the lot cap and the entry cap AT ONCE. It was also claimed in review that the two are mutually exclusive by construction; that is wrong too. A one-unit FIFO shipment draws from the oldest lot, which holds 100 units, so 64 of them never exhaust it: 64 items x 64 receipts then 64 items x 64 one-unit shipments leaves 4096 live lots and exactly 8192 entries. The figures below were taken on a register asserted in-fixture to sit at all three caps simultaneously, so the combined shape is measured and not argued about.

Free reads, net of a trivial-read baseline on the same register:

Example
1Rederive                 506,486,523
2Render, register page    186,179,474
3CrossFoot                 96,213,741
4Render, item page          6,467,621
5Render, index                192,716

The dearest is 16.9% of the 3,000,000,000 maxGasQuery. The two axes do not compose in any single read's price, because no single read walks both: Rederive walks postings and reads no lot, while CrossFoot and Render walk lots and read three accounts plus EntryCount. Measured rather than inferred — Rederive at the lot cap agrees with the same read on a lot-cheap register (506,495,345) to 0.002%, which is what proves the lot axis does not price it. So the ceiling is the MAX of the two axes and never their product.

A bound is not a price, and one item per call is what keeps the write side cheap: Receive and Ship each touch exactly one pool. Measured on the same toolchain, net of the same kind of baseline:

Example
1Receive creating the 64th lot        930,676
2Ship of all OnHand, dropping all 64 lots  11,837,593
3Receive refused at the lot cap       304,454

The dearest write is 2.3% of the dearest read, so the read side is what the caps exist for. See DEPLOY_READINESS.md for the transcript, the per-header GAS pairing rule, and the two limits of these figures: they came from throwaway test files that were deleted rather than committed, so they are reproducible but NOT guarded by the suite; and gno test's GAS line covers a whole test function, so a figure is only a call's own price when the fixture that enables it lives in a separate test. Both halves bit: the refused receipt first measured at 53,123,019 — 174x its real price — because its 64-lot fixture shared its GAS line.

Deploy order

This realm imports p/journal and p/lots, so on any chain the order is p/journal, p/lots, then this realm. The order is stated and the deployment STATE of either import deliberately is not: a sentence about what is deployed is true at signing time at best, and addpkg freezes it — r/assets carries exactly that fossil. The import relation is the durable fact.

Functions

AccountKind

func AccountKind(owner address, code string) (string, bool)
Ask AI Claude ChatGPT

AccountKind returns an account's kind as a word, and whether it exists.

Params

Command

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

Result

AddFIFO

func AddFIFO(cur realm, sku, name string)
Ask AI Claude ChatGPT

AddFIFO adds an item whose shipments are costed oldest-lot-first.

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/inventory" -func "AddFIFO" -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/inventory" -func "AddFIFO" -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
  

AddLIFO

func AddLIFO(cur realm, sku, name string)
Ask AI Claude ChatGPT

AddLIFO adds an item whose shipments are costed newest-lot-first.

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/inventory" -func "AddLIFO" -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/inventory" -func "AddLIFO" -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
  

AddWAVG

func AddWAVG(cur realm, sku, name string)
Ask AI Claude ChatGPT

AddWAVG adds an item whose receipts are merged into a single re-anchored lot and whose shipments are costed at the blended unit cost.

A WAVG item holds exactly one lot however many receipts it takes, so it can never reach MaxLotsPerItem. It can still refuse a receipt: the MERGE has an overflow precondition the other two methods never evaluate, and it is a property of the pool's accumulated history rather than of the receipt. See the package doc; the practical consequence is that LotCapacity is not the figure to watch for a WAVG item.

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/inventory" -func "AddWAVG" -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/inventory" -func "AddWAVG" -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
  

AddedAt

func AddedAt(owner address, sku string) int64
Ask AI Claude ChatGPT

AddedAt is the height an item was added at.

Params

Command

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

Result

Balance

func Balance(owner address, code string) (int64, bool)
Ask AI Claude ChatGPT

Balance returns an account's balance in its NORMAL direction and whether the code exists. All three of this realm's accounts are normal, so all three read non-negative.

Params

Command

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

Result

COGSDebit

func COGSDebit(owner address) int64
Ask AI Claude ChatGPT

COGSDebit is the 5000 balance: everything ever charged out as cost of goods sold.

Param

Command

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

Result

Capacity

func Capacity(owner address) (itemsLeft, entriesLeft int)
Ask AI Claude ChatGPT

Capacity reports how much room an owner's register has left.

Param

Command

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

Result

Charged

func Charged(owner address, sku string) (qty, cost int64)
Ask AI Claude ChatGPT

Charged is an item's cumulative shipped quantity and the cost charged out for it. The cost figure is derived: no caller has ever supplied it.

Params

Command

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

Result

ContributedCredit

func ContributedCredit(owner address) int64
Ask AI Claude ChatGPT

ContributedCredit is the 3900 balance. Read it as "goods arrived from somewhere this ledger does not model" — see the package doc on why 3900 is a plug this realm is forced to pick.

Param

Command

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

Result

CostOnHand

func CostOnHand(owner address, sku string) int64
Ask AI Claude ChatGPT

CostOnHand is the carrying value of an item's live lots: the figure this item contributes to the 1300 balance. Derived, for the same reason as OnHand.

Params

Command

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

Result

CrossFoot

func CrossFoot(owner address) (inventoryAgrees, cogsAgrees, contributedAgrees, equationOffsets bool)
Ask AI Claude ChatGPT

CrossFoot reports all four register-wide agreements as separate bools.

They are returned SEPARATELY and there is deliberately no single aggregate bool: a one-word verdict over four checks is the shape that gets quoted without its coverage, and a reader who wants the figures behind any one of these has CrossFootInventory, CrossFootCOGS, CrossFootContributed and Equation.

Param

Command

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

Result

CrossFootCOGS

func CrossFootCOGS(owner address) (sumCharged, balance int64, agrees bool)
Ask AI Claude ChatGPT

CrossFootCOGS is the register-wide check on 5000: the sum of every item's charged cost against the ledger balance.

Param

Command

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

Result

CrossFootContributed

func CrossFootContributed(owner address) (sumReceived, balance int64, agrees bool)
Ask AI Claude ChatGPT

CrossFootContributed is the register-wide check on 3900: the sum of every item's received cost against the ledger balance.

Param

Command

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

Result

CrossFootInventory

func CrossFootInventory(owner address) (sumOnHand, balance int64, agrees bool)
Ask AI Claude ChatGPT

CrossFootInventory is the register-wide check on 1300: the sum of every item's carrying value against the ledger balance.

The identity is EXACT, not approximate, and the reason is structural: this realm exposes no general posting entrypoint, so it is its book's only writer. Adding a general Post would destroy this check, which is the cost of adding one.

Param

Command

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

Result

EntryCount

func EntryCount(owner address) int
Ask AI Claude ChatGPT

EntryCount is how many entries an owner's book holds.

Param

Command

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

Result

Equation

func Equation(owner address) (debitNormal, creditNormal int64, offsets bool)
Ask AI Claude ChatGPT

Equation reports the accounting equation: debit-normal against credit-normal, and whether they offset. For this realm that is 1300 + 5000 against 3900, which offsets at 0 = 0 on an empty register and after every posting.

READ THE SIGN BEFORE PRESENTING EITHER FIGURE. journal partitions RAW DELTAS — debits minus credits — so creditNormal is NEGATIVE whenever 3900 carries a credit balance, and `offsets` means debitNormal + creditNormal == 0, not debitNormal == creditNormal. The textbook "assets = equity" has both sides positive; this does not. A caller rendering a balance sheet wants -creditNormal. The first test written against this function asserted the right magnitude with the wrong sign and was red for it, which is why this paragraph exists rather than a reader discovering it.

What `offsets` does NOT prove is journal's obligation 7, inherited here verbatim: the two subtotals are a partition of the same addends, so reclassifying every account in the chart changes both and leaves `offsets` true. A Kind set wrongly at Open time is invisible to it. What pins this realm's chart is the PAIR — debitNormal == InventoryDebit + COGSDebit and creditNormal == -ContributedCredit — and the suite asserts exactly that.

Sharper than that, because the partition is arithmetically inert: the two subtotals are added back together, so `offsets` reduces to Σ debits == Σ credits over the whole chart, which is the FIRST of the three conjuncts IsBalanced checks. A balanced book therefore always offsets, and `offsets` carries no fact IsBalanced has not already carried more strongly. The informative half of this function is the PAIR OF FIGURES, not the boolean — the figures move when a Kind changes and the boolean does not. (The two walks accumulate in different orders, so a mid-sum overflow could in principle separate them. At 8192 entries it would take amounts no register can reach, and it is not a second independent check.)

Param

Command

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

Result

HasItem

func HasItem(owner address, sku string) bool
Ask AI Claude ChatGPT

HasItem reports whether an owner's register holds a SKU.

Params

Command

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

Result

HasRegister

func HasRegister(owner address) bool
Ask AI Claude ChatGPT

HasRegister reports whether an address has opened a register.

Param

Command

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

Result

Height

func Height() int64
Ask AI Claude ChatGPT

Height is the current chain height, so a reader can date every other figure on this page without a second query.

Command

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

Result

Invariant

func Invariant(owner address, sku string) (posted, derived int64, agrees bool)
Ask AI Claude ChatGPT

Invariant is the per-item derivation check, and it is this realm's central claim:

Example
1postedCOGS == pool.ChargedCost()

The left figure is what this realm posted to 5000 for the item; the right is what the pool says it charged. They are maintained by different code in different packages, so a false here means the realm posted an amount its own lots do not imply — which no code path in this realm can produce, and which is exactly why it is worth exporting. A claim is worth more checkable by a stranger than asserted in a comment.

The receipt side is checked the same way by InvariantReceipts.

Params

Command

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

Result

InvariantReceipts

func InvariantReceipts(owner address, sku string) (posted, derived int64, agrees bool)
Ask AI Claude ChatGPT

InvariantReceipts is Invariant for the receipt side:

Example
1postedRecv == pool.ReceivedCost()

Params

Command

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

Result

InventoryDebit

func InventoryDebit(owner address) int64
Ask AI Claude ChatGPT

InventoryDebit is the 1300 balance: the value of goods on hand per the ledger.

Param

Command

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

Result

IsBalanced

func IsBalanced(owner address) bool
Ask AI Claude ChatGPT

IsBalanced reports whether total debits equal total credits.

Param

Command

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

Result

ItemCount

func ItemCount(owner address) int
Ask AI Claude ChatGPT

ItemCount is how many items an owner's register holds.

Param

Command

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

Result

ItemCrossFoot

func ItemCrossFoot(owner address, sku string) (received, charged, onHand int64, foots bool)
Ask AI Claude ChatGPT

ItemCrossFoot is p/lots' own cost identity for one item:

Example
1receivedCost == chargedCost + costOnHand

Received and charged are counters; on-hand is a walk of the live lots. The identity therefore compares two independently maintained things, which is why p/lots keeps them apart.

Params

Command

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

Result

ItemCrossFootQty

func ItemCrossFootQty(owner address, sku string) (received, consumed, onHand int64, foots bool)
Ask AI Claude ChatGPT

ItemCrossFootQty is the quantity identity for one item:

Example
1receivedQty == consumedQty + qtyOnHand

It is not implied by ItemCrossFoot: costs and quantities can disagree independently, and a bug that moved cost without moving quantity would be invisible to the cost identity alone.

Params

Command

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

Result

ItemName

func ItemName(owner address, sku string) string
Ask AI Claude ChatGPT

ItemName is an item's human name.

Params

Command

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

Result

LotAt

func LotAt(owner address, sku string, i int) (qty, cost, consumed, remaining, remainingCost int64, ok bool)
Ask AI Claude ChatGPT

LotAt reports the i'th live lot of an item in receipt order, and whether i was in range. It returns primitives rather than a p/lots.Lot so that the figures are readable from vm/qeval without the caller knowing that type.

Params

Command

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

Result

LotCapacity

func LotCapacity(owner address, sku string) int
Ask AI Claude ChatGPT

LotCapacity reports how many further live lots one item can hold. A WAVG item merges into one lot, so its figure is a bound it will never approach — and reading headroom off it for a WAVG item is therefore reading the wrong limit, because the refusal that CAN bind there is a merge overflow this figure knows nothing about. See AddWAVG.

Params

Command

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

Result

LotCount

func LotCount(owner address, sku string) int
Ask AI Claude ChatGPT

LotCount is how many LIVE lots an item holds. Exhausted lots are dropped.

Params

Command

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

Result

Method

func Method(owner address, sku string) string
Ask AI Claude ChatGPT

Method is an item's costing method, as "fifo", "lifo" or "weighted-average".

Params

Command

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

Result

OnHand

func OnHand(owner address, sku string) int64
Ask AI Claude ChatGPT

OnHand is the quantity of an item on hand, DERIVED by walking its live lots rather than read from a counter — which is what makes ItemCrossFootQty a comparison rather than a tautology.

Params

Command

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

Result

OpenRegister

func OpenRegister(cur realm)
Ask AI Claude ChatGPT

OpenRegister creates the caller's register and opens its three accounts. It panics if the caller already has one.

The chart is opened HERE rather than on demand, and the book is created with a cap of exactly three accounts. Both facts are load-bearing: they are why this realm is its book's only writer and why the cross-foot identities are exact rather than approximate.

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/inventory" -func "OpenRegister" -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/inventory" -func "OpenRegister" -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
  

OpenedAt

func OpenedAt(owner address) int64
Ask AI Claude ChatGPT

OpenedAt is the height an owner's register was opened at.

Param

Command

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

Result

RawBalance

func RawBalance(owner address, code string) (int64, bool)
Ask AI Claude ChatGPT

RawBalance returns debits minus credits regardless of kind. Summed over the three accounts it is exactly zero in a balanced book, which is what makes it the useful figure for a consistency check and the wrong one for a report.

Params

Command

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

Result

Receipts

func Receipts(owner address, sku string) int64
Ask AI Claude ChatGPT

Receipts is how many receipts an item has taken, including those whose lots are exhausted and dropped. It is NOT the live lot count — see LotCount.

Params

Command

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

Result

Receive

func Receive(cur realm, sku string, qty, cost int64) uint64
Ask AI Claude ChatGPT

Receive takes qty units costing cost in total into the item's pool and posts debit 1300 / credit 3900, returning the entry id.

A cost of ZERO is accepted — free goods — and posts nothing; the returned id is then 0, which is not a valid entry id and is the signal that no entry was made. See the package doc.

Panics if the item does not exist, if qty is not positive, if cost is negative, if the pool's lot cap is reached, if a WAVG merge would breach the per-lot overflow precondition — a refusal that depends on the item's history and not on this receipt, see AddWAVG — or if the book is full. Every one of those aborts the whole transaction, which is what makes the pool-then-post order safe: an error return would NOT revert the pool update, a panic does.

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/inventory" -func "Receive" -args $'' -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/inventory" -func "Receive" -args $'' -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
  

Received

func Received(owner address, sku string) (qty, cost int64)
Ask AI Claude ChatGPT

Received is an item's cumulative received quantity and cost.

Params

Command

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

Result

Rederive

func Rederive(owner address) (debits, credits int64, agrees bool)
Ask AI Claude ChatGPT

Rederive re-walks every posting in the book and reports whether the account totals agree with the journal.

It is a FREE read, unlike r/books' owner-only equivalent, for the reason given in the package doc. The cost is linear in the posting count, which is what MaxEntriesPerRegister bounds.

Param

Command

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

Result

Registers

func Registers() int
Ask AI Claude ChatGPT

Registers is how many registers exist across the realm.

Command

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

Result

Rename

func Rename(cur realm, sku, name string)
Ask AI Claude ChatGPT

Rename changes an item's human name. The SKU, the costing method and every lot are immutable; a name is presentation only and nothing derives from it.

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/inventory" -func "Rename" -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/inventory" -func "Rename" -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
  

Render

func Render(path string) string
Ask AI Claude ChatGPT

Render shows the realm index at "/", one owner's register at "/<address>", and one item at "/<address>/<sku>".

Param

Command

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

Result

SKUs

func SKUs(owner address, from string, limit int) []string
Ask AI Claude ChatGPT

SKUs lists an owner's SKUs in key order, starting at or after from and returning at most limit of them. An empty from starts at the beginning.

This enumerator exists because its absence is a known defect elsewhere in this portfolio: r/books exposes no account enumerator, so a third party cannot discover what to ask it about without already knowing. A sub-ledger whose invariants are per-item is useless to a verifier who cannot list the items, so the list is part of the product rather than an afterthought.

A non-positive limit returns nothing rather than everything. The cap is the item cap, so a caller may always page the whole register.

Params

Command

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

Result

Ship

func Ship(cur realm, sku string, qty int64) int64
Ask AI Claude ChatGPT

Ship consumes qty units from the item's pool and posts debit 5000 / credit 1300 for the cost it DERIVED, returning that cost.

The cost is never a parameter. It is whatever the item's costing method charges against the lots on hand, which is the whole product.

A derived cost of ZERO posts nothing — goods that cost nothing to acquire cost nothing to ship. The return value is then 0 and so is indistinguishable from "no entry made", deliberately: both facts are the same fact here.

Panics if the item does not exist, if qty is not positive, if qty exceeds the quantity on hand (p/lots fails closed with ErrInsufficient and consumes nothing), or if the book is full.

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/inventory" -func "Ship" -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/inventory" -func "Ship" -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
  

Totals

func Totals(owner address) (debits, credits int64)
Ask AI Claude ChatGPT

Totals are the book's total debits and credits.

Param

Command

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

Result