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/bazaar/bazaarv1

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
bazaarv1
Namespace
g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt / bazaar
Files
2 (gnomod.toml)
Exported functions
21
Module
gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/bazaarv1
gno
0.9

Files (2)

  • gnomod.tomltoml
  • bazaarv1.gnogno
bazaarv1.gnogno
1package bazaarv123import (4	"chain"5	"chain/banker"6	"chain/runtime/unsafe"7	"strconv"8	"strings"910	"gno.land/p/nt/avl/v0"11)1213const (14	pkgPath          = "gno.land/r/g1n4pl5uc4yt5r96m9w6fmdznx3x0jyg8l6arhmt/bazaar/bazaarv1"15	nativeDenom      = "ugnot"16	defaultLaunchFee = int64(10_000_000) // 10 GNOT17	maxNameLen       = 6418	maxImageLen      = 20019	maxSupplyBound   = 1_000_00020	maxRoyaltyBps    = 100021	maxSymbolLen     = 1122	maxSlugLen         = 1123	minSlugLen         = 224	defaultProtocolBps = int64(200) // 2% Magic Eden25	maxProtocolBps     = int64(500)26)2728type collection struct {29	slug       string30	name       string31	symbol     string32	cover      string33	pkg        string34	creator    address35	maxSupply  int36	mintPrice  int6437	minted     int38	royaltyBps int39}4041var (42	bySlug    avl.Tree43	byPkg     avl.Tree44	pending   avl.Tree45	reserved  avl.Tree46	inited    bool47	admin     address48	self      address49	launchFee   int6450	protocolBps int6451	seenBank    int6452)5354func Init(cur realm) {55	if inited {56		panic("factory: already initialized")57	}58	if !cur.Previous().IsUserCall() {59		panic("factory: EOA only")60	}61	admin = cur.Previous().Address()62	self = cur.Address()63	bySlug = avl.Tree{}64	byPkg = avl.Tree{}65	pending = avl.Tree{}66	reserved = avl.Tree{}67	launchFee = defaultLaunchFee68	protocolBps = defaultProtocolBps69	seenBank = bankUgnot()70	inited = true71	chain.Emit("Init", "admin", admin.String())72}7374func Address() address {75	return chain.PackageAddress(pkgPath)76}7778func LaunchFee() int64 {79	requireInit()80	return launchFee81}8283func Admin() string {84	requireInit()85	return admin.String()86}8788func SetLaunchFee(cur realm, ugnot int64) {89	requireAdmin(cur)90	if ugnot < 0 {91		panic("factory: launch fee")92	}93	launchFee = ugnot94	chain.Emit("SetLaunchFee", "ugnot", strconv.FormatInt(ugnot, 10))95}9697func ProtocolBps() int64 {98	requireInit()99	if protocolBps <= 0 {100		return defaultProtocolBps101	}102	return protocolBps103}104105func SetProtocolBps(cur realm, bps int64) {106	requireAdmin(cur)107	if bps < 0 || bps > maxProtocolBps {108		panic("factory: protocol bps")109	}110	protocolBps = bps111	chain.Emit("SetProtocolBps", "bps", strconv.FormatInt(bps, 10))112}113114func CreditLaunchFee(cur realm) {115	requireInit()116	prev := cur.Previous()117	if !prev.IsCode() {118		panic("factory: collection realm")119	}120	pkg := prev.PkgPath()121	if pending.Has(pkg) {122		panic("factory: already credited")123	}124	if byPkg.Has(pkg) {125		panic("factory: already registered")126	}127	now := bankUgnot()128	if now < seenBank {129		panic("factory: bank")130	}131	if now-seenBank != launchFee {132		panic("factory: launch fee")133	}134	seenBank = now135	pending.Set(pkg, true)136	chain.Emit("CreditLaunchFee", "pkg", pkg)137}138139func Register(cur realm, name, symbol, cover string, maxSupply int, mintPrice, royaltyBps int64) {140	requireInit()141	prev := cur.Previous()142	if !prev.IsCode() {143		panic("factory: collection realm")144	}145	creatorRlm := prev.Previous()146	if !creatorRlm.IsUserCall() {147		panic("factory: EOA creator")148	}149	pkg := prev.PkgPath()150	slug := lastElem(pkg)151	if reserved.Has(slug) {152		who := reserved.Get(slug).(address)153		if creatorRlm.Address() != who {154			panic("factory: reserved")155		}156		reserved.Remove(slug)157		if pending.Has(pkg) {158			pending.Remove(pkg)159		}160	} else {161		if !pending.Has(pkg) {162			panic("factory: launch fee")163		}164		pending.Remove(pkg)165	}166	register(pkg, creatorRlm.Address(), name, symbol, cover, maxSupply, mintPrice, royaltyBps)167}168169func Reserve(cur realm, slug string) {170	requireInit()171	if !cur.Previous().IsUserCall() {172		panic("factory: EOA only")173	}174	slug = strings.ToLower(strings.TrimSpace(slug))175	if !validSlug(slug) {176		panic("factory: slug")177	}178	if bySlug.Has(slug) || reserved.Has(slug) {179		panic("factory: slug taken")180	}181	takeFactorySend(launchFee)182	seenBank = bankUgnot()183	reserved.Set(slug, cur.Previous().Address())184	chain.Emit("Reserve", "slug", slug)185}186187func CancelReserve(cur realm, slug string) {188	requireInit()189	if !cur.Previous().IsUserCall() {190		panic("factory: EOA only")191	}192	slug = strings.ToLower(strings.TrimSpace(slug))193	if !reserved.Has(slug) {194		panic("factory: not reserved")195	}196	who := reserved.Get(slug).(address)197	if who != cur.Previous().Address() {198		panic("factory: not reserver")199	}200	if bySlug.Has(slug) {201		panic("factory: already registered")202	}203	reserved.Remove(slug)204	if launchFee > 0 {205		bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)206		bk.SendCoins(self, who, chain.Coins{{Denom: nativeDenom, Amount: launchFee}})207	}208	seenBank = bankUgnot()209	chain.Emit("CancelReserve", "slug", slug)210}211212func ReservedCreator(slug string) string {213	requireInit()214	slug = strings.ToLower(strings.TrimSpace(slug))215	if !reserved.Has(slug) {216		return ""217	}218	return reserved.Get(slug).(address).String()219}220221func takeFactorySend(want int64) {222	sent := unsafe.OriginSend()223	if want == 0 {224		if len(sent) != 0 {225			panic("factory: extra denoms")226		}227		return228	}229	if len(sent) != 1 || sent[0].Denom != nativeDenom || sent[0].Amount != want {230		panic("factory: wrong payment")231	}232}233234func NoteMinted(cur realm, n int) {235	requireInit()236	if n < 0 {237		panic("factory: minted")238	}239	prev := cur.Previous()240	if !prev.IsCode() {241		panic("factory: collection realm")242	}243	c := mustByPkg(prev.PkgPath())244	c.minted = n245	byPkg.Set(c.pkg, c)246	bySlug.Set(c.slug, c)247}248249func NoteRoyalty(cur realm, bps int) {250	requireInit()251	if bps < 0 || bps > maxRoyaltyBps {252		panic("factory: royalty")253	}254	prev := cur.Previous()255	if !prev.IsCode() {256		panic("factory: collection realm")257	}258	c := mustByPkg(prev.PkgPath())259	c.royaltyBps = bps260	byPkg.Set(c.pkg, c)261	bySlug.Set(c.slug, c)262}263264func CollectionOf(slug string) string {265	requireInit()266	c := mustBySlug(slug)267	return c.pkg268}269270func CollectionAddr(slug string) string {271	requireInit()272	c := mustBySlug(slug)273	return chain.PackageAddress(c.pkg).String()274}275276func RoyaltyOf(slug string) int {277	requireInit()278	c := mustBySlug(slug)279	return c.royaltyBps280}281282func ListCollections() string {283	requireInit()284	out := ""285	bySlug.Iterate("", "", func(_ string, value any) bool {286		c := value.(*collection)287		if out != "" {288			out += "\n"289		}290		out += c.slug + "|" + c.name + "|" + c.cover + "|" + c.pkg + "|" + strconv.FormatInt(c.mintPrice, 10) + "|" + strconv.Itoa(c.maxSupply) + "|" + strconv.Itoa(c.minted) + "|" + c.creator.String() + "|" + chain.PackageAddress(c.pkg).String() + "|" + strconv.Itoa(c.royaltyBps)291		return false292	})293	return out294}295296func Withdraw(cur realm) {297	requireAdmin(cur)298	bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)299	ugnot := bk.GetCoins(self).AmountOf(nativeDenom)300	if ugnot <= 0 {301		panic("factory: no funds")302	}303	seenBank = 0304	bk.SendCoins(self, admin, chain.Coins{{Denom: nativeDenom, Amount: ugnot}})305	chain.Emit("Withdraw", "amount", strconv.FormatInt(ugnot, 10))306}307308func TransferAdmin(cur realm, next address) {309	requireAdmin(cur)310	if !next.IsValid() {311		panic("factory: invalid address")312	}313	if next == admin {314		panic("factory: already admin")315	}316	admin = next317	chain.Emit("TransferAdmin", "addr", next.String())318}319320func Render(_ string) string {321	if !inited {322		return "# Bazaar factory\n\nCall Init first.\n"323	}324	out := "# Bazaar factory\n\n"325	out += "- launch fee: " + strconv.FormatInt(launchFee, 10) + " ugnot\n"326	out += "- collections: " + strconv.Itoa(bySlug.Size()) + "\n\n"327	lines := ListCollections()328	if lines == "" {329		out += "_No collections._\n"330	} else {331		out += "```\n" + lines + "\n```\n"332	}333	return out334}335336func register(pkg string, creator address, name, symbol, cover string, maxSupply int, mintPrice, royaltyBps int64) {337	if !strings.HasPrefix(pkg, "gno.land/r/") {338		panic("factory: pkg")339	}340	slug := lastElem(pkg)341	if !validSlug(slug) {342		panic("factory: slug")343	}344	if !validName(name) {345		panic("factory: name")346	}347	if !validSymbol(symbol) {348		panic("factory: symbol")349	}350	if !validImage(cover) {351		panic("factory: cover")352	}353	if maxSupply < 0 || maxSupply > maxSupplyBound {354		panic("factory: maxSupply")355	}356	if mintPrice < 0 {357		panic("factory: mintPrice")358	}359	if royaltyBps < 0 || royaltyBps > maxRoyaltyBps {360		panic("factory: royalty")361	}362	if bySlug.Has(slug) {363		panic("factory: slug taken")364	}365	if byPkg.Has(pkg) {366		panic("factory: pkg already registered")367	}368	c := &collection{369		slug:       slug,370		name:       name,371		symbol:     symbol,372		cover:      cover,373		pkg:        pkg,374		creator:    creator,375		maxSupply:  maxSupply,376		mintPrice:  mintPrice,377		royaltyBps: int(royaltyBps),378	}379	bySlug.Set(slug, c)380	byPkg.Set(pkg, c)381	chain.Emit("Register", "slug", slug, "pkg", pkg, "creator", creator.String())382}383384func requireInit() {385	if !inited {386		panic("factory: call Init first")387	}388}389390func requireAdmin(cur realm) {391	requireInit()392	if !cur.Previous().IsUserCall() {393		panic("factory: EOA only")394	}395	if cur.Previous().Address() != admin {396		panic("factory: not admin")397	}398}399400func bankUgnot() int64 {401	return banker.NewReadonlyBanker().GetCoins(Address()).AmountOf(nativeDenom)402}403404func mustBySlug(slug string) *collection {405	v := bySlug.Get(slug)406	if v == nil {407		panic("factory: unknown collection")408	}409	return v.(*collection)410}411412func mustByPkg(pkg string) *collection {413	v := byPkg.Get(pkg)414	if v == nil {415		panic("factory: unknown collection")416	}417	return v.(*collection)418}419420func lastElem(pkg string) string {421	i := strings.LastIndex(pkg, "/")422	if i < 0 || i+1 >= len(pkg) {423		panic("factory: pkg")424	}425	return pkg[i+1:]426}427428func validSlug(s string) bool {429	if len(s) < minSlugLen || len(s) > maxSlugLen {430		return false431	}432	if s[0] < 'a' || s[0] > 'z' {433		return false434	}435	return asciiSet(s, "abcdefghijklmnopqrstuvwxyz0123456789")436}437438func validSymbol(s string) bool {439	if len(s) < 1 || len(s) > maxSymbolLen {440		return false441	}442	return asciiSet(s, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-")443}444445func validName(name string) bool {446	if len(name) < 1 || len(name) > maxNameLen {447		return false448	}449	return !strings.ContainsAny(name, "\n\r|")450}451452func validImage(u string) bool {453	if u == "" {454		return true455	}456	if len(u) > maxImageLen {457		return false458	}459	if strings.ContainsAny(u, " \t\n\r|<>\"'`") {460		return false461	}462	if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") {463		return true464	}465	const prefix = "/samples/"466	if !strings.HasPrefix(u, prefix) {467		return false468	}469	rest := u[len(prefix):]470	if rest == "" {471		return false472	}473	return asciiSet(rest, "abcdefghijklmnopqrstuvwxyz0123456789._-")474}475476func asciiSet(s, allowed string) bool {477	for i := 0; i < len(s); i++ {478		if !strings.ContainsRune(allowed, rune(s[i])) {479			return false480		}481	}482	return true483}484

Functions

  • Address() string

  • Admin() string

  • CancelReserve(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}, slug string)

  • CollectionAddr(slug string) string

  • CollectionOf(slug string) string

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

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

  • LaunchFee() int64

  • ListCollections() string

  • NoteMinted(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}, n int)

  • NoteRoyalty(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}, bps int)

  • ProtocolBps() int64

  • Register(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, symbol string, cover string, maxSupply int, mintPrice int64, royaltyBps int64)

  • Render(string) string

  • Reserve(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}, slug string)

  • ReservedCreator(slug string) string

  • RoyaltyOf(slug string) int

  • SetLaunchFee(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}, ugnot int64)

  • SetProtocolBps(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}, bps int64)

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

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

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.