PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39/coinio

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
coinio
Namespace
g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39
Files
2 (gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39/coinio
gno
0.9

Files (2)

  • gnomod.tomltoml
  • coinio.gnogno
coinio.gnogno
1// Package coinio is the chain-facing coin plumbing that every2// value-holding realm on gno.land repeats: verified payment receipt,3// disciplined payout, and reserve-protected surplus sweeping. It was4// extracted from two audited, pearl-1-validated realms (vault and5// bounties) whose implementations of these mechanics were6// line-identical.7//8// The package is PURE and STATELESS: it holds no balances, no roles,9// and no configuration; all state stays in the consuming realm (and10// its accounting package, e.g. feeledger). It emits no events —11// consumers emit their own. Every function either succeeds or panics,12// aborting the transaction: these are payment guards, and no failure13// here has a meaningful recovery path.14//15// CAPABILITY CONTRACT: pure packages cannot declare crossing16// functions (a first `realm` parameter), so every coin-moving function17// here uses the canonical secondary-parameter shape `(_ int, rlm18// realm, ...)` — the same pattern as chain treasury packages. Pass 019// and your crossing entrypoint's own live `cur` (forwarded through20// non-crossing calls keeps it current). Each function asserts21// rlm.IsCurrent() before acting, so a stale, stored, or Previous()22// realm value fails closed (the designation-forgery guard secondary23// realm parameters require). Coins can only move FROM rlm.Address() —24// the calling realm itself — so no consumer can spend another realm's25// funds through this package.26//27// AUTHORIZATION is the consumer's responsibility: coinio decides HOW28// coins move, never WHO may move them. Gate your entrypoints before29// calling in.30//31// ORDERING CONTRACT (the one invariant coinio cannot enforce): debit32// your own accounting BEFORE calling Payout or Sweep33// (checks-effects-interactions). A panic inside coinio aborts the34// whole transaction, reverting your debit with it — that is what makes35// the debit-first order safe.36package coinio3738import (39	"chain"40	"chain/banker"41	"chain/runtime/unsafe"42)4344// Receive verifies the canonical receipt-guaranteed payment shape and45// returns the payer and amount:46//47//   - the caller of the consuming realm's entrypoint is an EOA via48//     MsgCall (IsUserCall) — the only shape where the chain guarantees49//     the -send envelope landed at the realm address before the body50//     ran (realms and maketx-run are rejected);51//   - the envelope is exactly one coin of the given denom;52//   - the amount is positive.53//54// Receive is a READ of the transaction's send envelope, NOT a55// consumption: a stateless pure package cannot mark an envelope spent,56// so calling Receive N times in one transaction reports the same57// envelope N times. CALL IT AT MOST ONCE PER TRANSACTION and credit58// its result at most once — a consumer that credits per call mints59// unbacked liabilities from a single -send.60//61// Call it first (and once) in any payable crossing entrypoint:62//63//	func Deposit(cur realm) {64//		from, amount := coinio.Receive(0, cur, "ugnot")65//		// credit `from` with `amount` in your accounting66//	}67func Receive(_ int, rlm realm, denom string) (from address, amount int64) {68	if !rlm.IsCurrent() {69		panic("coinio: realm capability is not current")70	}71	if denom == "" {72		panic("coinio: empty denom")73	}74	if !rlm.Previous().IsUserCall() {75		panic("coinio: payment must be a direct EOA call with -send (realms and maketx-run are rejected)")76	}77	sent := unsafe.OriginSend()78	if len(sent) != 1 || sent[0].Denom != denom {79		panic("coinio: send exactly one coin type: " + denom)80	}81	if sent[0].Amount <= 0 {82		panic("coinio: amount must be positive")83	}84	return rlm.Previous().Address(), sent[0].Amount85}8687// Payout sends amount of denom from the calling realm's own address to88// `to`. DEBIT YOUR ACCOUNTING FIRST — a panic here (or anywhere later89// in the transaction) reverts the debit together with the send.90func Payout(_ int, rlm realm, to address, denom string, amount int64) {91	if !rlm.IsCurrent() {92		panic("coinio: realm capability is not current")93	}94	var zero address95	if to == zero {96		panic("coinio: empty payout address")97	}98	if denom == "" {99		panic("coinio: empty denom")100	}101	if amount <= 0 {102		panic("coinio: amount must be positive")103	}104	bk := banker.NewBanker(banker.BankerTypeRealmSend, rlm)105	bk.SendCoins(rlm.Address(), to, chain.Coins{chain.NewCoin(denom, amount)})106}107108// Sweep sends the surplus of a single denomination — everything the109// calling realm holds above `reserve` — to `to`, and returns the swept110// amount. Pass your total liabilities as the reserve for the denom111// your accounting tracks, and 0 for foreign denominations. Panics if112// there is no positive surplus, so reserved funds are untouchable by113// construction. One denomination per call keeps the operation gas-114// bounded regardless of how many junk denoms third parties force-send.115func Sweep(_ int, rlm realm, to address, denom string, reserve int64) int64 {116	if !rlm.IsCurrent() {117		panic("coinio: realm capability is not current")118	}119	var zero address120	if to == zero {121		panic("coinio: empty sweep address")122	}123	if denom == "" {124		panic("coinio: empty denom")125	}126	if reserve < 0 {127		panic("coinio: negative reserve")128	}129	bk := banker.NewBanker(banker.BankerTypeRealmSend, rlm)130	surplus := bk.GetCoin(rlm.Address(), denom) - reserve131	if surplus <= 0 {132		panic("coinio: no surplus to sweep for " + denom)133	}134	bk.SendCoins(rlm.Address(), to, chain.Coins{chain.NewCoin(denom, surplus)})135	return surplus136}137138// HeldAt returns the amount of denom held at addr. Read-only; usable139// from views and Render without a realm capability.140func HeldAt(addr address, denom string) int64 {141	return banker.NewReadonlyBanker().GetCoin(addr, denom)142}143

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.