PathrockNetwork Gno Explorer
HomeBlocksTransactionsRealmsPackagesValidators

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/gnomi/profile

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
profile
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt / gnomi
Files
2 (gnomod.toml)
Exported functions
7
Module
gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/gnomi/profile
gno
0.9

Files (2)

  • gnomod.tomltoml
  • profile.gnogno
profile.gnogno
1// Package profile stores lightweight user profiles for gnomemepad.2// Independent of pad versions — upgrade this realm without redeploying markets.3//4//	SetProfile(displayName, bio, uri) — EOA only, per caller address5//	GetProfile(addr) → name|bio|uri|updatedHeight6package profile78import (9	"chain"10	"chain/runtime"11	"strconv"12	"strings"1314	"gno.land/p/nt/avl/v0"15)1617const (18	maxNameLen = 4819	maxBioLen  = 28020	maxURILen  = 20021)2223// Profile is one user's public card (all fields exported for LaunchInfo-style reads).24type Profile struct {25	Name    string26	Bio     string27	URI     string28	Updated int64 // block height29}3031var (32	// byAddr: address string -> *Profile33	byAddr avl.Tree34	inited bool35)3637// Init is optional (no-op state). Kept for deploy symmetry with hub/pad.38func Init(cur realm) {39	if inited {40		panic("profile: already initialized")41	}42	if !cur.Previous().IsUserCall() {43		panic("profile: EOA only")44	}45	inited = true46	byAddr = avl.Tree{}47	chain.Emit("Init", "by", cur.Previous().Address().String())48}4950func ensure() {51	// Lazy: allow SetProfile before Init for simpler UX; Init still recommended.52	if !inited {53		byAddr = avl.Tree{}54		inited = true55	}56}5758func sanitizeText(s string, max int) string {59	s = strings.TrimSpace(s)60	if len(s) > max {61		s = s[:max]62	}63	// Strip control chars64	out := ""65	for _, c := range s {66		if c >= 0x20 && c != 0x7f {67			out += string(c)68		}69	}70	return out71}7273// SetProfile upserts the caller's profile.74func SetProfile(cur realm, name, bio, uri string) {75	if !cur.Previous().IsUserCall() {76		panic("profile: EOA only")77	}78	ensure()79	name = sanitizeText(name, maxNameLen)80	bio = sanitizeText(bio, maxBioLen)81	uri = sanitizeText(uri, maxURILen)82	if name == "" {83		panic("profile: name required")84	}85	if uri != "" && !(strings.HasPrefix(uri, "https://") || strings.HasPrefix(uri, "http://") || strings.HasPrefix(uri, "ipfs://")) {86		panic("profile: uri must be http(s) or ipfs")87	}88	addr := cur.Previous().Address()89	p := &Profile{90		Name:    name,91		Bio:     bio,92		URI:     uri,93		Updated: runtime.ChainHeight(),94	}95	byAddr.Set(addr.String(), p)96	chain.Emit("SetProfile", "addr", addr.String(), "name", name)97}9899// ClearProfile removes the caller's profile.100func ClearProfile(cur realm) {101	if !cur.Previous().IsUserCall() {102		panic("profile: EOA only")103	}104	ensure()105	addr := cur.Previous().Address().String()106	if byAddr.Has(addr) {107		byAddr.Remove(addr)108		chain.Emit("ClearProfile", "addr", addr)109	}110}111112// GetProfile returns pipe-delimited: name|bio|uri|updatedHeight113// Empty string if none.114func GetProfile(addr string) string {115	ensure()116	addr = strings.TrimSpace(addr)117	if addr == "" {118		return ""119	}120	v := byAddr.Get(addr)121	if v == nil {122		return ""123	}124	p, ok := v.(*Profile)125	if !ok || p == nil {126		return ""127	}128	return p.Name + "|" + p.Bio + "|" + p.URI + "|" + strconv.FormatInt(p.Updated, 10)129}130131// HasProfile reports whether addr has a profile.132func HasProfile(addr string) bool {133	ensure()134	return byAddr.Has(strings.TrimSpace(addr))135}136137// ProfileCount returns number of profiles.138func ProfileCount() int {139	ensure()140	return byAddr.Size()141}142143func sanitizeMD(s string) string {144	s = strings.ReplaceAll(s, "`", "'")145	s = strings.ReplaceAll(s, "<", "")146	s = strings.ReplaceAll(s, ">", "")147	return s148}149150// Render home or user/{addr}151func Render(path string) string {152	path = strings.Trim(path, "/")153	ensure()154	if path == "" {155		out := "# gnomi profiles\n\n"156		out += "- Profiles: **" + strconv.Itoa(byAddr.Size()) + "**\n\n"157		out += "Call `SetProfile(name, bio, uri)` from your wallet.\n"158		return out159	}160	if strings.HasPrefix(path, "user/") {161		addr := strings.TrimPrefix(path, "user/")162		raw := GetProfile(addr)163		if raw == "" {164			return "> [!WARNING]\n> No profile for `" + sanitizeMD(addr) + "`\n"165		}166		parts := strings.SplitN(raw, "|", 4)167		name, bio, uri := parts[0], "", ""168		if len(parts) > 1 {169			bio = parts[1]170		}171		if len(parts) > 2 {172			uri = parts[2]173		}174		out := "# " + sanitizeMD(name) + "\n\n"175		out += "- Address: `" + sanitizeMD(addr) + "`\n"176		if bio != "" {177			out += "- Bio: " + sanitizeMD(bio) + "\n"178		}179		if uri != "" {180			out += "- URI: " + sanitizeMD(uri) + "\n"181		}182		return out183	}184	return "> [!WARNING]\n> Path not found\n"185}186187func resetForTest() {188	byAddr = avl.Tree{}189	inited = false190}191

Functions

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

  • GetProfile(addr string) string

  • HasProfile(addr string) bool

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

  • ProfileCount() int

  • Render(path string) string

  • SetProfile(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}, name string, bio string, uri 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.