PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidatorsAnalytics

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/moul/x/daily/faucet/v0

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
v0
Namespace
moul / x / daily / faucet
Files
3 (README)(gnomod.toml)
Exported functions
3
Module
gno.land/r/moul/x/daily/faucet/v0
gno
0.9

Files (3)

  • README.mdmarkdown
  • gnomod.tomltoml
  • faucet.gnogno
faucet.gnogno
1// Package faucet is a toy points faucet realm for the gno.land sapphire testnet.2//3// Any caller may Claim() 100 points, but only once per cooldown window of 1004// blocks. Cooldown is enforced deterministically via runtime.ChainHeight() — no5// real clocks, no RNG. Per-caller balance and last-claim height live in an6// avl.Tree so Render iterates in deterministic (address-sorted) order.7package faucet89import (10	"chain"11	"chain/runtime"12	"chain/runtime/unsafe"13	"strconv"14	"strings"1516	"gno.land/p/nt/avl/v0"17)1819const (20	// ClaimAmount is granted on every successful claim.21	ClaimAmount = 10022	// CooldownBlocks is the minimum number of blocks between two claims by the23	// same caller.24	CooldownBlocks = 10025)2627// claimer holds the per-address state.28type claimer struct {29	Balance   int64 // total points accumulated30	LastClaim int64 // chain height of the last successful claim31	Claims    int64 // number of successful claims by this address32}3334var (35	// claimers maps address string -> *claimer.36	claimers = avl.NewTree()37	// totalDistributed is the running sum of all points ever granted.38	totalDistributed int6439	// totalClaims is the total number of successful claims across all callers.40	totalClaims int6441)4243// Claim grants ClaimAmount points to the caller, subject to the per-caller44// cooldown. It aborts (cross-realm) if the caller must still wait.45func Claim(cur realm) {46	caller := unsafe.PreviousRealm().Address()47	key := caller.String()48	height := runtime.ChainHeight()4950	var c *claimer51	if v := claimers.Get(key); v != nil {52		c = v.(*claimer)53		wait := c.LastClaim + CooldownBlocks - height54		if wait > 0 {55			panic("cooldown active: " + strconv.FormatInt(wait, 10) +56				" block(s) remaining before you can claim again")57		}58	} else {59		c = &claimer{}60	}6162	c.Balance += ClaimAmount63	c.LastClaim = height64	c.Claims++65	claimers.Set(key, c)6667	totalDistributed += ClaimAmount68	totalClaims++6970	chain.Emit(71		"Claim",72		"caller", key,73		"amount", strconv.FormatInt(ClaimAmount, 10),74		"balance", strconv.FormatInt(c.Balance, 10),75		"height", strconv.FormatInt(height, 10),76	)77}7879// BalanceOf returns the current point balance of addr (0 if never claimed).80func BalanceOf(addr string) int64 {81	if v := claimers.Get(addr); v != nil {82		return v.(*claimer).Balance83	}84	return 085}8687// Render produces a Markdown dashboard of faucet activity.88func Render(path string) string {89	var b strings.Builder9091	b.WriteString("# Token Faucet\n\n")92	b.WriteString("A toy points faucet. Call `Claim` to receive **")93	b.WriteString(strconv.FormatInt(ClaimAmount, 10))94	b.WriteString(" points** — but only once every **")95	b.WriteString(strconv.FormatInt(CooldownBlocks, 10))96	b.WriteString(" blocks** per address.\n\n")9798	b.WriteString("## Stats\n\n")99	b.WriteString("- Total distributed: **")100	b.WriteString(strconv.FormatInt(totalDistributed, 10))101	b.WriteString("** points\n")102	b.WriteString("- Total claims: **")103	b.WriteString(strconv.FormatInt(totalClaims, 10))104	b.WriteString("**\n")105	b.WriteString("- Unique claimers: **")106	b.WriteString(strconv.Itoa(claimers.Size()))107	b.WriteString("**\n")108	b.WriteString("- Current block height: **")109	b.WriteString(strconv.FormatInt(runtime.ChainHeight(), 10))110	b.WriteString("**\n\n")111112	b.WriteString("## Claimers\n\n")113	if claimers.Size() == 0 {114		b.WriteString("_No one has claimed yet. Be the first!_\n")115		return b.String()116	}117118	b.WriteString("| Address | Balance | Claims | Last claim (height) |\n")119	b.WriteString("| --- | ---: | ---: | ---: |\n")120	claimers.Iterate("", "", func(key string, value interface{}) bool {121		c := value.(*claimer)122		b.WriteString("| `")123		b.WriteString(key)124		b.WriteString("` | ")125		b.WriteString(strconv.FormatInt(c.Balance, 10))126		b.WriteString(" | ")127		b.WriteString(strconv.FormatInt(c.Claims, 10))128		b.WriteString(" | ")129		b.WriteString(strconv.FormatInt(c.LastClaim, 10))130		b.WriteString(" |\n")131		return false132	})133134	return b.String()135}136

Functions

  • BalanceOf(addr string) int64

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

  • Render(path string) string

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.