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/g138mdf0gqzue3ra2r335upclngn8t8r0n72cn3h/access

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
access
Namespace
g138mdf0gqzue3ra2r335upclngn8t8r0n72cn3h
Files
2 (gnomod.toml)
Exported functions
23
Module
gno.land/r/g138mdf0gqzue3ra2r335upclngn8t8r0n72cn3h/access
gno
0.9

Files (2)

  • gnomod.tomltoml
  • access.gnogno
access.gnogno
1// GnoPulse access: on-chain subscriptions + prepaid credits that gate the GnoPulse API.2// Users pay from their own wallet; the realm holds only what they pay it.3package access45import (6	"chain"7	"chain/banker"8	"chain/runtime"9	"chain/runtime/unsafe"10	"strconv"11	"time"12)1314var (15	// The GnoPulse owner wallet. Cold by design: it signs the deploy and SetOperator,16	// and nothing on a schedule. Every recurring job runs as the operator instead.17	owner = address("g138mdf0gqzue3ra2r335upclngn8t8r0n72cn3h")1819	// What a period costs, stated in USD. This is the price; the GNOT figure is derived from it.20	// It is recorded on chain so anyone can check a posted quote against a published GNOT price21	// and see that we quoted honestly.22	priceUsdCents int64 = 250023	periodSec     int64 = 30 * 24 * 60 * 602425	// A credit IS one API cost-unit. There is no second conversion: the old model bought credits26	// per ugnot and burned 100 of them per unit, which made credits GNOT-denominated while the27	// subscription was USD-denominated, so the two drifted apart whenever GNOT moved.28	//29	// Now both are priced the same way. One cent buys creditsPerUsdCent units, converted from the30	// payment at the live quote, so topping up N GNOT buys whatever N GNOT is worth in dollars.31	// 1600 units per cent is $6.25 per million, three times the rate a subscription includes,32	// which is the overage premium this pricing was set to. It is exact in integer math: a33	// million units is 625 cents with no remainder.34	creditsPerUsdCent int64 = 16003536	// TopUp multiplies the payment by priceUsdCents and creditsPerUsdCent before dividing, so a37	// large enough payment would overflow int64 before the divide. A million GNOT is far beyond38	// any real top-up and leaves three orders of magnitude of headroom.39	maxTopUpUgnot int64 = 1_000_000_000_0004041	// --- the quote ---------------------------------------------------------------------------42	//43	// A fiat price in a volatile coin is quoted, not computed at settlement. We convert44	// priceUsdCents to ugnot off chain (where the price feed is) and post the result here; that45	// number IS the obligation until it expires. The payment page reads quoteUgnot from this46	// realm rather than from any feed of ours, so the figure on screen and the figure charged are47	// the same number by construction, never merely close.48	//49	// This is what payment processors do, and expiry is the rate lock: BitPay locks a quote for50	// 15 minutes, BTCPay for 15, NOWPayments for 10. Slippage is a trading idea and has no place51	// here; nobody shows one number and charges another.52	quoteUgnot int64 // ugnot for one period53	quotedAt   int64 // when it was posted5455	// The superseded quote stays payable for a grace window, so a payer who was quoted a moment56	// before we posted a new number still pays what they were shown rather than being repriced57	// mid-flight. currentPrice charges whichever of the two is lower while both are live.58	prevUgnot int6459	prevUntil int646061	// How long a posted quote is good for, and how long a superseded one stays payable. If the62	// job that posts quotes stops, Subscribe refuses rather than pricing off a stale number: a63	// broken cron becomes failed payments, never wrong charges.64	quoteTtlSec   int64 = 90065	quoteGraceSec int64 = 9006667	// The grace window exists so a small tick does not reprice a payment in flight. It must NOT68	// survive a correction: currentPrice charges the LOWER of the two live quotes, so carrying a69	// wildly wrong quote forward means posting the right one keeps the wrong one payable for a70	// FRESH grace window. Correcting the mistake would extend it past the point it would have71	// lapsed on its own. A move of this factor or more is treated as a correction, not a tick,72	// and the old quote is dropped instead of carried.73	quoteGraceBand int64 = 47475	// Ownership moves in two steps. A single-step transfer to a mistyped address is76	// unrecoverable here: address is an unvalidated string type, so any non-empty value is77	// accepted, and the realm is immutable, so a wrong owner locks Withdraw and every admin78	// function forever. The offer sits here until the named address claims it itself, which is79	// proof the key exists and can transact.80	pendingOwner address8182	// operator is the HOT role. Two of the owner's jobs are not administrative at all: SetQuote83	// runs every five minutes and Consume every six hours, both from an unattended cron on a84	// public-facing box. With one role, automating them means the key that can Withdraw must sit85	// in a keybase on that box. Splitting them means a stolen box costs quote posting, not the86	// revenue: an operator can price and settle, and can do nothing else.87	//88	// Empty disables it, and that is the kill switch. The owner revokes a suspect operator in one89	// transaction from their own wallet, without touching anything else.90	operator address9192	subs    = map[address]int64{} // addr -> expiry (unix)93	credits = map[address]int64{} // addr -> credit balance9495	// settled is the billing watermark: cumulative API cost-units already charged to an address.96	// It lives on chain so that losing or restoring our off-chain database cannot re-bill usage97	// that was already paid for -- Consume rejects any total at or below what it already settled.98	settled = map[address]int64{}99)100101// Subscribe buys pro time for the caller at the live quote. Each whole quote sent buys one102// period; anything left over becomes units at the same rate a top-up gets, rather than being103// kept, so the payer keeps the value of every ugnot they sent.104//105// Every call is priced at the quote in force when it executes, so a renewal costs what a period106// costs today. Pinning a renewal to the price paid at first purchase is a known trap: Unlock107// Protocol does it and a renewal simply reverts once the price has moved.108func Subscribe(cur realm) {109	runtime.AssertOriginCall()110	subscribe(cur.Previous().Address(), int64(unsafe.OriginSend().AmountOf("ugnot")))111}112113// subscribe holds the money math, separate from the origin/caller plumbing above so it can be114// exercised directly (AssertOriginCall cannot be satisfied from a test frame).115func subscribe(payer address, paid int64) {116	price := currentPrice()117	if paid < price {118		// Underpayment is refused outright, which is what every processor surveyed does: BitPay119		// voids the whole payment, BTCPay defaults its tolerance to zero.120		panic("payment below the quoted price")121	}122	base := subs[payer]123	if now := time.Now().Unix(); base < now {124		base = now125	}126	subs[payer] = base + (paid/price)*periodSec127	change := unitsFor(paid%price, price)128	if change > 0 {129		credits[payer] += change130	}131	chain.Emit("Subscribe",132		"addr", payer.String(),133		"paid", strconv.FormatInt(paid, 10),134		"expiresAt", strconv.FormatInt(subs[payer], 10),135		"changeUnits", strconv.FormatInt(change, 10))136}137138// Login does nothing. Sign-In-With-Gno signs (never broadcasts) a call to it so the wallet shows139// a "Login" to GnoPulse rather than a token transfer; the challenge nonce rides in the tx memo.140func Login(cur realm) {141	// Login credits nothing, so coins sent with it would be kept by the realm with no record and142	// no way to return them. Refuse instead.143	if int64(unsafe.OriginSend().AmountOf("ugnot")) > 0 {144		panic("Login takes no payment")145	}146}147148// TopUp buys prepaid credits for the caller.149func TopUp(cur realm) {150	runtime.AssertOriginCall()151	topUp(cur.Previous().Address(), int64(unsafe.OriginSend().AmountOf("ugnot")))152}153154// topUp converts the payment to units at the SAME quote the subscription uses, so a credit is155// worth the same in dollars whatever GNOT is doing. Paying in GNOT, priced in USD.156func topUp(payer address, paid int64) {157	if paid <= 0 {158		panic("no payment")159	}160	if paid > maxTopUpUgnot {161		panic("payment too large")162	}163	// currentPrice is the live quote (with the same grace window Subscribe gets), and it panics164	// when there is none: pegging credits to USD means credits need a rate too, so a dead quote165	// job closes top-ups as well as subscriptions rather than selling at a stale rate.166	got := unitsFor(paid, currentPrice())167	if got <= 0 {168		panic("payment too small to buy a unit")169	}170	credits[payer] += got171	chain.Emit("TopUp",172		"addr", payer.String(),173		"paid", strconv.FormatInt(paid, 10),174		"units", strconv.FormatInt(got, 10),175		"balance", strconv.FormatInt(credits[payer], 10))176}177178// unitsFor converts a ugnot payment into API units at a given quote. The payment is worth179// paid/price of a period, a period costs priceUsdCents, and one cent buys creditsPerUsdCent180// units. One helper so a top-up and the change from a subscription can never diverge.181func unitsFor(paid, price int64) int64 {182	return paid * priceUsdCents * creditsPerUsdCent / price183}184185func HasAccess(addr address) bool { return subs[addr] > time.Now().Unix() || credits[addr] > 0 }186187func TierOf(addr address) string {188	if subs[addr] > time.Now().Unix() {189		return "pro"190	}191	return "free"192}193194func CreditsOf(addr address) int64 { return credits[addr] }195func ExpiresAt(addr address) int64 { return subs[addr] }196func SettledOf(addr address) int64 { return settled[addr] }197func Owner() address               { return owner }198199func Config() (int64, int64, int64, int64, int64) {200	return priceUsdCents, periodSec, creditsPerUsdCent, quoteTtlSec, quoteGraceSec201}202203// Consume charges an address for metered API usage, up to a cumulative cost-unit total.204//205// The owner passes the caller's running lifetime usage, not a delta: the realm keeps the206// watermark itself and charges only the part it has not charged before. That makes the call207// idempotent (a replay is rejected, not re-billed) and means a restored or rolled-back208// off-chain database cannot double-charge anyone.209//210// A caller with too few credits is charged what they have and the watermark still advances; the211// event records both what was owed and what was actually taken, so a shortfall is visible rather212// than silently forgiven.213func Consume(cur realm, addr address, uptoUnits int64) {214	assertOperator(cur)215	consume(addr, uptoUnits)216}217218func consume(addr address, uptoUnits int64) {219	prev := settled[addr]220	if uptoUnits <= prev {221		panic("already settled to that total")222	}223	owed := uptoUnits - prev224	took := owed225	if have := credits[addr]; have <= owed {226		took = have227		delete(credits, addr)228	} else {229		credits[addr] = have - owed230	}231	settled[addr] = uptoUnits232	chain.Emit("Consume",233		"addr", addr.String(),234		"units", strconv.FormatInt(uptoUnits-prev, 10),235		"settledTo", strconv.FormatInt(uptoUnits, 10),236		"owed", strconv.FormatInt(owed, 10),237		"debited", strconv.FormatInt(took, 10),238		"remaining", strconv.FormatInt(credits[addr], 10))239}240241// Forgive advances the billing watermark without charging: usage already covered by an active242// time-based subscription. Separate from Consume so that "we decided not to bill this" is its own243// auditable on-chain act rather than an invisible gap in the watermark.244func Forgive(cur realm, addr address, uptoUnits int64) {245	assertOwner(cur)246	forgive(addr, uptoUnits)247}248249func forgive(addr address, uptoUnits int64) {250	prev := settled[addr]251	if uptoUnits <= prev {252		panic("already settled to that total")253	}254	settled[addr] = uptoUnits255	chain.Emit("Forgive",256		"addr", addr.String(),257		"units", strconv.FormatInt(uptoUnits-prev, 10),258		"settledTo", strconv.FormatInt(uptoUnits, 10))259}260261// SetQuote posts the price of one period in ugnot. Called on a short schedule by the job that262// already tracks the GNOT price, which converts priceUsdCents off chain and publishes only the263// result. The previous quote stays payable for quoteGraceSec so payments already in flight are264// not repriced.265func SetQuote(cur realm, ugnotPerPeriod int64) {266	assertOperator(cur)267	setQuote(ugnotPerPeriod)268}269270func setQuote(ugnotPerPeriod int64) {271	if ugnotPerPeriod <= 0 {272		panic("quote must be positive")273	}274	now := time.Now().Unix()275	if quoteUgnot > 0 && ugnotPerPeriod/quoteUgnot < quoteGraceBand && quoteUgnot/ugnotPerPeriod < quoteGraceBand {276		prevUgnot, prevUntil = quoteUgnot, now+quoteGraceSec277	} else {278		// A correction (or the first quote). Drop any standing grace rather than let the279		// superseded number stay payable.280		prevUgnot, prevUntil = 0, 0281	}282	quoteUgnot, quotedAt = ugnotPerPeriod, now283	chain.Emit("SetQuote",284		"ugnot", strconv.FormatInt(ugnotPerPeriod, 10),285		"usdCents", strconv.FormatInt(priceUsdCents, 10),286		"expiresAt", strconv.FormatInt(now+quoteTtlSec, 10))287}288289// Quote is what the payment page reads: the amount to send for one period, and the moment it290// stops being honoured. Reading it from here rather than from a price feed is what makes the291// figure on screen and the figure charged the same number.292func Quote() (int64, int64, int64) {293	return quoteUgnot, quotedAt, quotedAt + quoteTtlSec294}295296// currentPrice is what Subscribe charges. While a superseded quote is still inside its grace297// window both are live, and the payer is charged the lower of the two: we cannot tell which one298// they were shown, and charging the lower one guarantees it is never more than they saw.299func currentPrice() int64 {300	now := time.Now().Unix()301	if quoteUgnot <= 0 {302		panic("no quote has been posted")303	}304	if now > quotedAt+quoteTtlSec {305		panic("the quote has expired")306	}307	if prevUgnot > 0 && now <= prevUntil && prevUgnot < quoteUgnot {308		return prevUgnot309	}310	return quoteUgnot311}312313func SetConfig(cur realm, cents, period, perUsdCent, ttl, grace int64) {314	assertOwner(cur)315	setConfig(cents, period, perUsdCent, ttl, grace)316}317318func setConfig(cents, period, perUsdCent, ttl, grace int64) {319	if cents <= 0 || period <= 0 || perUsdCent <= 0 || ttl <= 0 || grace < 0 {320		panic("must be positive")321	}322	priceUsdCents, periodSec, creditsPerUsdCent = cents, period, perUsdCent323	quoteTtlSec, quoteGraceSec = ttl, grace324	chain.Emit("SetConfig",325		"usdCents", strconv.FormatInt(cents, 10),326		"period", strconv.FormatInt(period, 10),327		"creditsPerUsdCent", strconv.FormatInt(perUsdCent, 10),328		"quoteTtl", strconv.FormatInt(ttl, 10),329		"quoteGrace", strconv.FormatInt(grace, 10))330}331332func Withdraw(cur realm, amount int64) {333	assertOwner(cur)334	if amount <= 0 {335		panic("must be positive")336	}337	banker.NewBanker(banker.BankerTypeRealmSend, cur).SendCoins(338		cur.Address(), owner, chain.Coins{{"ugnot", amount}})339	chain.Emit("Withdraw", "amount", strconv.FormatInt(amount, 10))340}341342// TransferOwnership OFFERS the realm to newOwner. It does not hand it over: the offer stands343// until that address claims it with AcceptOwnership. A mistyped address therefore costs nothing,344// where a single-step transfer would have locked every admin function and the revenue behind an345// address nobody holds, permanently, because the realm cannot be redeployed.346func TransferOwnership(cur realm, newOwner address) {347	assertOwner(cur)348	transferOwnership(newOwner)349}350351// transferOwnership holds the offer itself, split from the owner gate above for the same reason352// subscribe is split from Subscribe: assertOwner cannot be satisfied from a test frame.353func transferOwnership(newOwner address) {354	if newOwner == "" {355		panic("empty address")356	}357	pendingOwner = newOwner358	chain.Emit("OwnershipOffered", "from", owner.String(), "to", newOwner.String())359}360361// CancelOwnershipTransfer withdraws a standing offer.362func CancelOwnershipTransfer(cur realm) {363	assertOwner(cur)364	pendingOwner = ""365	chain.Emit("OwnershipOfferCancelled")366}367368// AcceptOwnership completes the handover. Only the offered address can call it, which proves the369// key exists and can sign before anything irreversible happens.370func AcceptOwnership(cur realm) {371	acceptOwnership(cur.Previous().Address())372}373374func acceptOwnership(caller address) {375	if pendingOwner == "" || caller != pendingOwner {376		panic("not the pending owner")377	}378	prev := owner379	owner, pendingOwner = caller, ""380	chain.Emit("TransferOwnership", "from", prev.String(), "to", owner.String())381}382383func PendingOwner() address { return pendingOwner }384385// SetOperator appoints, rotates or (with an empty address) revokes the hot role.386//387// One step, unlike TransferOwnership, and the asymmetry is deliberate: a mistyped owner is388// permanent and locks the revenue, while a mistyped operator only means quotes stop until the389// owner sets it again. Making revocation a two-step handshake would be worse than useless, since390// the address being revoked is the one you no longer trust to act.391func SetOperator(cur realm, op address) {392	assertOwner(cur)393	setOperator(op)394}395396func setOperator(op address) {397	prev := operator398	operator = op399	chain.Emit("SetOperator", "from", prev.String(), "to", op.String())400}401402func Operator() address { return operator }403404// assertOwner requires a DIRECT call from the owner. cur.Previous() is the immediate caller, so a405// relaying realm (owner -> X -> here) would fail this, no separate origin assert needed.406func assertOwner(cur realm) {407	if cur.Previous().Address() != owner {408		panic("owner only")409	}410}411412// isOperator is the routine-work gate as a pure predicate, so it is unit-testable: assertOperator413// below cannot be satisfied from a test frame, exactly as assertOwner cannot.414//415// The owner always passes. A fresh deploy has no operator yet, so the owner must be able to post416// the first quote or the realm is unusable until one is appointed, and the owner must be able to417// take over the moment an operator is revoked.418func isOperator(caller address) bool {419	return caller == owner || (operator != "" && caller == operator)420}421422// assertOperator gates the two jobs that run on a schedule. Everything that moves money or changes423// the terms stays behind assertOwner, including Forgive, which is the repair for an operator that424// over-charges and therefore must never be reachable by one.425func assertOperator(cur realm) {426	if !isOperator(cur.Previous().Address()) {427		panic("owner or operator only")428	}429}430431func Render(path string) string {432	if len(path) > 5 && path[:5] == "addr/" {433		a := address(path[5:])434		return "# " + a.String() + "\n\n- tier: " + TierOf(a) +435			"\n- expires: " + strconv.FormatInt(subs[a], 10) +436			"\n- credits: " + strconv.FormatInt(credits[a], 10) +437			"\n- billed through: " + strconv.FormatInt(settled[a], 10) + " cost-units\n"438	}439	// Three states, not two. The old text had one branch for "quoteUgnot > 0" and called440	// everything else "subscriptions are closed", which is wrong twice over on an immutable page:441	// a LAPSED quote still rendered as "good until <a timestamp in the past>", and a merely absent442	// quote was announced as the shop being shut. A quote is posted on request and lives for443	// quoteTtlSec, so "none standing" is the ordinary resting state, not a fault, and this page444	// cannot tell a quiet moment from an outage. It says what it knows and no more.445	quoteLine := "- quote: none standing. One is posted on request and is good for " +446		strconv.FormatInt(quoteTtlSec, 10) + "s once posted.\n"447	if quoteUgnot > 0 {448		if time.Now().Unix() <= quotedAt+quoteTtlSec {449			quoteLine = "- quote: " + strconv.FormatInt(quoteUgnot, 10) + " ugnot / " +450				strconv.FormatInt(periodSec, 10) + "s, good until " +451				strconv.FormatInt(quotedAt+quoteTtlSec, 10) + "\n"452		} else {453			quoteLine = "- quote: the last one lapsed at " +454				strconv.FormatInt(quotedAt+quoteTtlSec, 10) +455				". A fresh quote is posted on request.\n"456		}457	}458	return "# GnoPulse Access\n\nSubscribe() or TopUp() from your wallet. Send exactly the quote " +459		"below; it is what you will be charged.\n\n" +460		"- price: $" + usd(priceUsdCents) + " per " + strconv.FormatInt(periodSec, 10) + "s\n" +461		quoteLine +462		"- credits: " + strconv.FormatInt(creditsPerUsdCent, 10) +463		" API units per US cent, bought at the quote above\n"464}465466// usd renders cents as dollars, keeping the two decimal places (2500 -> "25.00", 2505 -> "25.05").467func usd(cents int64) string {468	c := cents % 100469	pad := "."470	if c < 10 {471		pad = ".0"472	}473	return strconv.FormatInt(cents/100, 10) + pad + strconv.FormatInt(c, 10)474}475

Functions

  • AcceptOwnership(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})

  • CancelOwnershipTransfer(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})

  • Config() (int64, int64, int64, int64, int64)

  • Consume(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}, addr string, uptoUnits int64)

  • CreditsOf(addr string) int64

  • ExpiresAt(addr string) int64

  • Forgive(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}, addr string, uptoUnits int64)

  • HasAccess(addr string) bool

  • Login(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})

  • Operator() string

  • Owner() string

  • PendingOwner() string

  • Quote() (int64, int64, int64)

  • Render(path string) string

  • SetConfig(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}, cents int64, period int64, perUsdCent int64, ttl int64, grace int64)

  • SetOperator(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}, op string)

  • SetQuote(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}, ugnotPerPeriod int64)

  • SettledOf(addr string) int64

  • Subscribe(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})

  • TierOf(addr string) string

  • TopUp(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})

  • TransferOwnership(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}, newOwner string)

  • Withdraw(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}, amount 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.