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/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/hearth/v1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v1
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt / hearth
Files
2 (gnomod.toml)
Exported functions
36
Module
gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/hearth/v1
gno
0.9

Files (2)

  • gnomod.tomltoml
  • hearth.gnogno
hearth.gnogno
1// Package hearth escrows a single ecosystem raise in ugnot and later2// splits revenue deposits across contributors by paid share.3//4// Contribute accepts ugnot while the raise is open. Each call must be at5// least MinContribute. The running total cannot pass HardCap; excess ugnot6// is sent back to the caller. Hitting HardCap closes the raise.7//8// Raise principal (WithdrawRaise) and revenue (DepositRevenue) are separate9// ledgers. Withdrawing the raise does not change shares. After Close,10// DepositRevenue opens an epoch. Settle pays the next batch of unpaid11// wallets for that epoch. Claim pays one caller. Integer dust stays in the12// realm and is not withdrawable.13package hearth1415import (16	"chain"17	"chain/banker"18	"chain/runtime/unsafe"19	"math/bits"20	"strconv"21	"strings"22	"time"2324	"gno.land/p/nt/avl/v0"25)2627const (28	// MinContribute is the smallest ugnot a Contribute call may accept (500 GNOT).29	MinContribute int64 = 500_000_00030	// HardCap is the maximum ugnot the raise will accept (150_000 GNOT).31	HardCap int64 = 150_000_000_00032	// MaxSeats is HardCap / MinContribute. A new address past this panics.33	MaxSeats int = 30034	// MaxSettle is the most wallets one Settle call will pay.35	MaxSettle int = 2036)3738// Raise window in UTC. 00:00 24 Sep 2026 through 00:00 1 Oct 2026, Vietnam (UTC+7).39// Start 2026-09-23T17:00:00Z. End 2026-09-30T17:00:00Z, exclusive.40var (41	raiseStart int64 = 179018280042	raiseEnd   int64 = 179078760043)4445type seat struct {46	who   address47	ugnot int6448}4950var (51	admin       address52	ready       bool53	closed      bool54	raised      int6455	raisedBank  int6456	revenueBank int6457	rewardBank  int6458	rewardOwed  int6459	epochCount  int60	seats       *avl.Tree61	epochs      *avl.Tree62	claimed     *avl.Tree63	handles     *avl.Tree64	owed        *avl.Tree65)6667func init() {68	seats = avl.NewTree()69	epochs = avl.NewTree()70	claimed = avl.NewTree()71	handles = avl.NewTree()72	owed = avl.NewTree()73}7475// Init binds the operator to the calling EOA. Once.76func Init(cur realm) {77	mustUser(cur)78	mustNoCoins()79	if ready {80		panic("hearth: already init")81	}82	admin = cur.Previous().Address()83	ready = true84	chain.Emit("Init", "admin", admin.String())85}8687// SetHandle records a public X handle for the caller. Same handle is a no-op.88func SetHandle(cur realm, handle string) {89	mustUser(cur)90	mustNoCoins()91	mustReady()92	h := cleanHandle(handle)93	key := cur.Previous().Address().String()94	if prev, ok := handles.Get(key).(string); ok && prev == h {95		return96	}97	handles.Set(key, h)98	chain.Emit("Handle", "addr", key, "handle", h)99}100101// Contribute accepts ugnot toward the raise.102func Contribute(cur realm) {103	mustUser(cur)104	mustReady()105	if closed {106		panic("hearth: raise closed")107	}108	got := ugnotSent()109	accept, refund, reason := planAccept(got)110	if reason != "" {111		panic("hearth: " + reason)112	}113	caller := cur.Previous().Address()114	key := caller.String()115	if curSeat, ok := seats.Get(key).(*seat); ok {116		curSeat.ugnot += accept117	} else {118		if seats.Size() >= MaxSeats {119			panic("hearth: seats full")120		}121		seats.Set(key, &seat{who: caller, ugnot: accept})122	}123	raised += accept124	raisedBank += accept125	if raised == HardCap {126		closed = true127	}128	if refund > 0 {129		send(cur, caller, refund)130	}131	chain.Emit(132		"Contributed",133		"addr", key,134		"accept", strconv.FormatInt(accept, 10),135		"refund", strconv.FormatInt(refund, 10),136		"raised", strconv.FormatInt(raised, 10),137	)138}139140// Close ends the raise before the cap so revenue epochs can start.141func Close(cur realm) {142	mustUser(cur)143	mustNoCoins()144	mustAdmin(cur)145	if closed {146		panic("hearth: already closed")147	}148	if raised <= 0 {149		panic("hearth: empty raise")150	}151	closed = true152	chain.Emit("Closed", "raised", strconv.FormatInt(raised, 10))153}154155// WithdrawRaise sends the operator the raise principal still on the realm.156// It does not touch revenue and does not change shares.157func WithdrawRaise(cur realm) {158	mustUser(cur)159	mustNoCoins()160	mustAdmin(cur)161	if raisedBank <= 0 {162		panic("hearth: no principal")163	}164	amt := raisedBank165	raisedBank = 0166	send(cur, admin, amt)167	chain.Emit("RaiseWithdrawn", "amount", strconv.FormatInt(amt, 10))168}169170// DepositReward takes the operator's ugnot and credits each contributor171// got * seat / raised. Rounding dust stays withdrawable. Principal is unchanged.172// MinMonthlyUgnot is the monthly floor, not a cap. A larger deposit uses the same split.173func DepositReward(cur realm) {174	mustUser(cur)175	mustAdmin(cur)176	got := ugnotSent()177	if got <= 0 {178		panic("hearth: no ugnot")179	}180	if raised <= 0 {181		panic("hearth: no raise")182	}183	credited := int64(0)184	seats.Iterate("", "", func(key string, value any) bool {185		s := value.(*seat)186		share := mulDiv(got, s.ugnot, raised)187		if share <= 0 {188			return false189		}190		setOwed(key, owedOf(key)+share)191		credited += share192		return false193	})194	if credited > got {195		panic("hearth: credit")196	}197	rewardOwed += credited198	rewardBank += got - credited199	chain.Emit(200		"RewardIn",201		"amount", strconv.FormatInt(got, 10),202		"credited", strconv.FormatInt(credited, 10),203		"dust", strconv.FormatInt(got-credited, 10),204	)205}206207// ClaimReward pays the caller the ugnot already credited to them.208func ClaimReward(cur realm) {209	mustUser(cur)210	mustNoCoins()211	key := cur.Previous().Address().String()212	share := owedOf(key)213	if share <= 0 {214		panic("hearth: nothing owed")215	}216	if share > rewardOwed {217		panic("hearth: owed short")218	}219	setOwed(key, 0)220	rewardOwed -= share221	send(cur, cur.Previous().Address(), share)222	chain.Emit("RewardPaid", "addr", key, "share", strconv.FormatInt(share, 10))223}224225// WithdrawReward sends unallocated rounding dust back to the operator.226// amt 0 withdraws all dust. Credited shares cannot be withdrawn.227func WithdrawReward(cur realm, amt int64) {228	mustUser(cur)229	mustNoCoins()230	mustAdmin(cur)231	if amt < 0 {232		panic("hearth: bad amount")233	}234	if amt == 0 {235		amt = rewardBank236	}237	if amt <= 0 || amt > rewardBank {238		panic("hearth: pool short")239	}240	rewardBank -= amt241	send(cur, admin, amt)242	chain.Emit("RewardOut", "amount", strconv.FormatInt(amt, 10), "dust", strconv.FormatInt(rewardBank, 10))243}244245// DepositRevenue opens one epoch with the attached ugnot. Raise must be closed.246func DepositRevenue(cur realm) {247	mustUser(cur)248	mustReady()249	if !closed {250		panic("hearth: raise open")251	}252	got := ugnotSent()253	if got <= 0 {254		panic("hearth: no ugnot")255	}256	epochCount++257	id := strconv.Itoa(epochCount)258	epochs.Set(id, got)259	revenueBank += got260	chain.Emit("Revenue", "epoch", id, "amount", strconv.FormatInt(got, 10))261}262263// Claim pays the caller their unpaid share of one epoch.264func Claim(cur realm, epoch int) {265	mustUser(cur)266	mustNoCoins()267	key := cur.Previous().Address().String()268	pay(cur, epoch, key, true)269}270271// Settle pays up to maxN unpaid seats for one epoch, in address order.272// Returns how many seats it marked this call.273func Settle(cur realm, epoch int, maxN int) int {274	mustUser(cur)275	mustNoCoins()276	if maxN < 1 || maxN > MaxSettle {277		panic("hearth: bad batch")278	}279	_ = epochAmount(epoch)280	n := 0281	seats.Iterate("", "", func(key string, _ any) bool {282		if n >= maxN {283			return true284		}285		if isClaimed(epoch, key) {286			return false287		}288		pay(cur, epoch, key, false)289		n++290		return false291	})292	chain.Emit("Settled", "epoch", strconv.Itoa(epoch), "n", strconv.Itoa(n))293	return n294}295296// TransferAdmin moves the operator. The raise ledger is unchanged.297func TransferAdmin(cur realm, next address) {298	mustUser(cur)299	mustNoCoins()300	mustAdmin(cur)301	if next == admin || next == address("") {302		panic("hearth: bad admin")303	}304	admin = next305	chain.Emit("Admin", "admin", admin.String())306}307308func pay(cur realm, epoch int, key string, mustPositive bool) {309	if isClaimed(epoch, key) {310		panic("hearth: already claimed")311	}312	s, ok := seats.Get(key).(*seat)313	if !ok {314		panic("hearth: no seat")315	}316	amt := epochAmount(epoch)317	share := mulDiv(amt, s.ugnot, raised)318	if share < 0 || share > revenueBank {319		panic("hearth: revenue short")320	}321	if share == 0 && mustPositive {322		panic("hearth: dust share")323	}324	markClaimed(epoch, key)325	if share == 0 {326		return327	}328	revenueBank -= share329	send(cur, s.who, share)330	chain.Emit(331		"Paid",332		"epoch", strconv.Itoa(epoch),333		"addr", key,334		"share", strconv.FormatInt(share, 10),335	)336}337338// Raised is the ugnot accepted into shares.339func Raised() int64 { return raised }340341// RaisedBank is principal still held for WithdrawRaise.342func RaisedBank() int64 { return raisedBank }343344// RevenueBank is deposited revenue not yet paid out, including dust.345func RevenueBank() int64 { return revenueBank }346347// RewardBank is the operator reward pool still on the realm.348func RewardBank() int64 { return rewardBank }349350// MinMonthlyUgnot is 5% of contributed ugnot. Deposits may be larger.351// A larger deposit still splits by contribution share.352func MinMonthlyUgnot() int64 {353	if raised <= 0 {354		return 0355	}356	return mulDiv(raised, 5, 100)357}358359// RewardOwed is ugnot credited to contributors and not yet claimed.360func RewardOwed() int64 { return rewardOwed }361362// PoolShare is the ugnot still owed to addr from deposits already split.363func PoolShare(addr address) int64 { return owedOf(addr.String()) }364365// Closed reports whether new contributions are rejected.366func Closed() bool { return closed }367368// Ready reports whether Init has run.369func Ready() bool { return ready }370371// RaiseStartUnix is the first second contributions are accepted, UTC.372func RaiseStartUnix() int64 { return raiseStart }373374// RaiseEndUnix is the first second contributions are rejected, UTC.375func RaiseEndUnix() int64 { return raiseEnd }376377// Admin is the operator address.378func Admin() address { return admin }379380// SeatCount is the number of contributor addresses.381func SeatCount() int { return seats.Size() }382383// EpochCount is the number of revenue deposits.384func EpochCount() int { return epochCount }385386// SeatOf returns ugnot contributed by addr, or 0.387func SeatOf(addr address) int64 {388	s, ok := seats.Get(addr.String()).(*seat)389	if !ok {390		return 0391	}392	return s.ugnot393}394395// HandleOf returns the stored X handle, or empty.396func HandleOf(addr address) string {397	h, ok := handles.Get(addr.String()).(string)398	if !ok {399		return ""400	}401	return h402}403404// EpochAmount returns the ugnot deposited for a 1-based epoch.405func EpochAmount(epoch int) int64 { return epochAmount(epoch) }406407// UserCall reports whether this crossing was a direct EOA MsgCall.408func UserCall(cur realm) bool {409	return cur.Previous().IsUserCall()410}411412// AdminCall reports whether the direct caller is the operator.413func AdminCall(cur realm) bool {414	return ready && cur.Previous().IsUserCall() && cur.Previous().Address() == admin415}416417// PlanAccept is the contribute decision. A non-empty reason means the call must revert.418func PlanAccept(got int64) (accept int64, refund int64, reason string) {419	return planAccept(got)420}421422// ShareOf is the ugnot addr would receive for epoch. Zero if none.423func ShareOf(epoch int, addr address) int64 {424	if raised <= 0 || epoch < 1 || epoch > epochCount {425		return 0426	}427	s, ok := seats.Get(addr.String()).(*seat)428	if !ok {429		return 0430	}431	return mulDiv(epochAmount(epoch), s.ugnot, raised)432}433434// Claimed reports whether addr was already paid or skipped for epoch.435func Claimed(epoch int, addr address) bool {436	return isClaimed(epoch, addr.String())437}438439// Summary is a single line for clients:440// admin|raised|raisedBank|revenueBank|closed|seats|epochs|cap|min|rewardDust|rewardOwed441func Summary() string {442	flag := "0"443	if closed {444		flag = "1"445	}446	return strings.Join([]string{447		admin.String(),448		strconv.FormatInt(raised, 10),449		strconv.FormatInt(raisedBank, 10),450		strconv.FormatInt(revenueBank, 10),451		flag,452		strconv.Itoa(seats.Size()),453		strconv.Itoa(epochCount),454		strconv.FormatInt(HardCap, 10),455		strconv.FormatInt(MinContribute, 10),456		strconv.FormatInt(rewardBank, 10),457		strconv.FormatInt(rewardOwed, 10),458	}, "|")459}460461// Render shows the raise terms and totals. It does not list every seat.462func Render(_ string) string {463	state := "open"464	if !ready {465		state = "awaiting init"466	} else if closed {467		state = "closed"468	}469	return strings.Join([]string{470		"# Commons",471		"",472		"One ugnot raise for the operator's gno.land products.",473		"Revenue deposits after close are split by contributed share.",474		"Contributions are not refundable. Revenue is only what is deposited.",475		"",476		"- State: " + state,477		"- Raised ugnot: " + strconv.FormatInt(raised, 10),478		"- Principal still here: " + strconv.FormatInt(raisedBank, 10),479		"- Revenue still here: " + strconv.FormatInt(revenueBank, 10),480		"- Seats: " + strconv.Itoa(seats.Size()),481		"- Epochs: " + strconv.Itoa(epochCount),482		"- Min ugnot: " + strconv.FormatInt(MinContribute, 10),483		"- Cap ugnot: " + strconv.FormatInt(HardCap, 10),484	}, "\n")485}486487func planAccept(got int64) (accept int64, refund int64, reason string) {488	if !ready {489		return 0, 0, "not init"490	}491	now := time.Now().Unix()492	if now < raiseStart {493		return 0, 0, "not started"494	}495	if now >= raiseEnd {496		return 0, 0, "raise ended"497	}498	if closed {499		return 0, 0, "raise closed"500	}501	if got <= 0 {502		return 0, 0, "no ugnot"503	}504	room := HardCap - raised505	if room < MinContribute {506		return 0, 0, "cap"507	}508	accept = got509	if accept > room {510		accept = room511	}512	if accept < MinContribute {513		return 0, 0, "below min"514	}515	return accept, got - accept, ""516}517518func mustUser(cur realm) {519	if !cur.Previous().IsUserCall() {520		panic("hearth: direct user call only")521	}522}523524func mustReady() {525	if !ready {526		panic("hearth: not init")527	}528}529530func mustAdmin(cur realm) {531	mustReady()532	if cur.Previous().Address() != admin {533		panic("hearth: operator only")534	}535}536537func mustNoCoins() {538	if ugnotSent() != 0 || foreignDenom() {539		panic("hearth: unexpected coins")540	}541}542543func foreignDenom() bool {544	for _, c := range unsafe.OriginSend() {545		if c.Denom != "ugnot" {546			return true547		}548	}549	return false550}551552func ugnotSent() int64 {553	coins := unsafe.OriginSend()554	for _, c := range coins {555		if c.Denom != "ugnot" {556			panic("hearth: ugnot only")557		}558	}559	return coins.AmountOf("ugnot")560}561562func epochAmount(epoch int) int64 {563	if epoch < 1 || epoch > epochCount {564		panic("hearth: bad epoch")565	}566	v, ok := epochs.Get(strconv.Itoa(epoch)).(int64)567	if !ok {568		panic("hearth: bad epoch")569	}570	return v571}572573func claimKey(epoch int, addr string) string {574	return strconv.Itoa(epoch) + "|" + addr575}576577func isClaimed(epoch int, addr string) bool {578	v, ok := claimed.Get(claimKey(epoch, addr)).(bool)579	return ok && v580}581582func markClaimed(epoch int, addr string) {583	claimed.Set(claimKey(epoch, addr), true)584}585586func owedOf(key string) int64 {587	v, ok := owed.Get(key).(int64)588	if !ok {589		return 0590	}591	return v592}593594func setOwed(key string, n int64) {595	owed.Set(key, n)596}597598func send(cur realm, to address, amt int64) {599	if amt <= 0 {600		panic("hearth: nothing to send")601	}602	bnk := banker.NewBanker(banker.BankerTypeRealmSend, cur)603	bnk.SendCoins(cur.Address(), to, chain.Coins{{Denom: "ugnot", Amount: amt}})604}605606func cleanHandle(handle string) string {607	h := strings.TrimPrefix(strings.TrimSpace(handle), "@")608	if len(h) < 1 || len(h) > 15 {609		panic("hearth: bad handle")610	}611	for i := 0; i < len(h); i++ {612		c := h[i]613		ok := (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'614		if !ok {615			panic("hearth: bad handle")616		}617	}618	return h619}620621const maxInt64 = int64(^uint64(0) >> 1)622623func mulDiv(x, y, d int64) int64 {624	if x < 0 || y < 0 {625		panic("hearth: muldiv sign")626	}627	if d <= 0 {628		panic("hearth: muldiv divisor")629	}630	if x == 0 || y == 0 {631		return 0632	}633	hi, lo := bits.Mul64(uint64(x), uint64(y))634	if uint64(d) <= hi {635		panic("hearth: muldiv overflow")636	}637	quo, _ := bits.Div64(hi, lo, uint64(d))638	if quo > uint64(maxInt64) {639		panic("hearth: muldiv overflow")640	}641	return int64(quo)642}643

Functions

  • Admin() string

  • AdminCall(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) bool

  • Claim(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, epoch int)

  • Claimed(epoch int, addr string) bool

  • ClaimReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • Close(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • Closed() bool

  • Contribute(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • DepositRevenue(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • DepositReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • EpochAmount(epoch int) int64

  • EpochCount() int

  • HandleOf(addr string) string

  • Init(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • MinMonthlyUgnot() int64

  • PlanAccept(got int64) (accept int64, refund int64, reason string)

  • PoolShare(addr string) int64

  • Raised() int64

  • RaisedBank() int64

  • RaiseEndUnix() int64

  • RaiseStartUnix() int64

  • Ready() bool

  • Render(string) string

  • RevenueBank() int64

  • RewardBank() int64

  • RewardOwed() int64

  • SeatCount() int

  • SeatOf(addr string) int64

  • SetHandle(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, handle string)

  • Settle(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, epoch int, maxN int) int

  • ShareOf(epoch int, addr string) int64

  • Summary() string

  • TransferAdmin(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, next string)

  • UserCall(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}) bool

  • WithdrawRaise(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string})

  • WithdrawReward(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, amt int64)

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

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.