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/bazaarv4

Realm
Open in gnoweb ↗

Overview

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

Files (2)

  • gnomod.tomltoml
  • bazaarv4.gnogno
bazaarv4.gnogno
1package bazaarv423import (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/bazaarv4"15	nativeDenom      = "ugnot"16	defaultLaunchFee = int64(1_000_000_000) // 1000 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}4041type reservation struct {42	who  address43	paid int6444}4546var (47	bySlug      avl.Tree48	byPkg       avl.Tree49	reserved    avl.Tree50	inited      bool51	admin         address52	self          address53	protocolSink  address54	launchFee        int6455	protocolBps      int6456	genesisPkg       string57	genesisSink      address58	genesisShareBps  int6459	discountPusher   string60	holderDisc       avl.Tree61)6263func Init(cur realm) {64	if inited {65		panic("factory: already initialized")66	}67	if !cur.Previous().IsUserCall() {68		panic("factory: EOA only")69	}70	admin = cur.Previous().Address()71	protocolSink = admin72	self = cur.Address()73	bySlug = avl.Tree{}74	byPkg = avl.Tree{}75	reserved = avl.Tree{}76	holderDisc = avl.Tree{}77	genesisPkg = ""78	genesisShareBps = 079	discountPusher = ""80	var z address81	genesisSink = z82	launchFee = defaultLaunchFee83	protocolBps = defaultProtocolBps84	inited = true85	chain.Emit("Init", "admin", admin.String())86}8788func Address() address {89	return chain.PackageAddress(pkgPath)90}9192func LaunchFee() int64 {93	requireInit()94	return launchFee95}9697func Admin() string {98	requireInit()99	return admin.String()100}101102func SetLaunchFee(cur realm, ugnot int64) {103	requireAdmin(cur)104	if ugnot < 0 {105		panic("factory: launch fee")106	}107	launchFee = ugnot108	chain.Emit("SetLaunchFee", "ugnot", strconv.FormatInt(ugnot, 10))109}110111func ProtocolBps() int64 {112	requireInit()113	if protocolBps <= 0 {114		return defaultProtocolBps115	}116	return protocolBps117}118119func SetProtocolBps(cur realm, bps int64) {120	requireAdmin(cur)121	if bps < 0 || bps > maxProtocolBps {122		panic("factory: protocol bps")123	}124	protocolBps = bps125	chain.Emit("SetProtocolBps", "bps", strconv.FormatInt(bps, 10))126}127128func ProtocolSink() address {129	requireInit()130	return protocolSink131}132133func SetProtocolSink(cur realm, next address) {134	requireAdmin(cur)135	if !next.IsValid() {136		panic("factory: invalid address")137	}138	if next == protocolSink {139		panic("factory: already sink")140	}141	protocolSink = next142	chain.Emit("SetProtocolSink", "addr", next.String())143}144145func GenesisPkg() string {146	requireInit()147	return genesisPkg148}149150func GenesisSink() address {151	requireInit()152	return genesisSink153}154155func GenesisShareBps() int64 {156	requireInit()157	if genesisPkg == "" {158		return 0159	}160	if genesisShareBps <= 0 {161		return 1100162	}163	return genesisShareBps164}165166func HolderDiscount(owner string) int64 {167	requireInit()168	if genesisPkg == "" {169		return 0170	}171	v := holderDisc.Get(strings.ToLower(strings.TrimSpace(owner)))172	if v == nil {173		return 0174	}175	return v.(int64)176}177178func AttachGenesis(cur realm) {179	requireInit()180	prev := cur.Previous()181	if !prev.IsCode() {182		panic("factory: genesis realm")183	}184	eoa := prev.Previous()185	if !eoa.IsUserCall() || eoa.Address() != admin {186		panic("factory: not admin")187	}188	pkg := prev.PkgPath()189	if pkg == "" {190		panic("factory: genesis pkg")191	}192	if genesisPkg != "" && genesisPkg != pkg {193		panic("factory: genesis set")194	}195	genesisPkg = pkg196	genesisSink = prev.Address()197	if genesisShareBps <= 0 {198		genesisShareBps = 1100199	}200	chain.Emit("AttachGenesis", "pkg", pkg)201}202203func SetGenesis(cur realm, pkg string) {204	requireAdmin(cur)205	pkg = strings.TrimSpace(pkg)206	if pkg == "" || !strings.HasPrefix(pkg, "gno.land/r/") {207		panic("factory: genesis pkg")208	}209	genesisPkg = pkg210	genesisSink = chain.PackageAddress(pkg)211	if genesisShareBps <= 0 {212		genesisShareBps = 1100213	}214	chain.Emit("SetGenesis", "pkg", pkg)215}216217func SetDiscountPusher(cur realm, pkg string) {218	requireAdmin(cur)219	pkg = strings.TrimSpace(pkg)220	if pkg == "" || !strings.HasPrefix(pkg, "gno.land/r/") {221		panic("factory: pusher pkg")222	}223	discountPusher = pkg224	chain.Emit("SetDiscountPusher", "pkg", pkg)225}226227func DiscountPusher() string {228	requireInit()229	return discountPusher230}231232func NoteHolderDiscount(cur realm, owner string, bps int64) {233	requireInit()234	prev := cur.Previous()235	if !prev.IsCode() {236		panic("factory: not genesis")237	}238	from := prev.PkgPath()239	ok := (genesisPkg != "" && from == genesisPkg) || (discountPusher != "" && from == discountPusher)240	if !ok {241		panic("factory: not genesis")242	}243	if bps < 0 {244		panic("factory: discount")245	}246	who := strings.ToLower(strings.TrimSpace(owner))247	if who == "" {248		panic("factory: owner")249	}250	if bps == 0 {251		holderDisc.Remove(who)252		return253	}254	holderDisc.Set(who, bps)255}256257func Register(cur realm, name, symbol, cover string, maxSupply int, mintPrice, royaltyBps int64) {258	requireInit()259	prev := cur.Previous()260	if !prev.IsCode() {261		panic("factory: collection realm")262	}263	creatorRlm := prev.Previous()264	if !creatorRlm.IsUserCall() {265		panic("factory: EOA creator")266	}267	pkg := prev.PkgPath()268	slug := lastElem(pkg)269	res := mustReserve(slug)270	if creatorRlm.Address() != res.who {271		panic("factory: reserved")272	}273	reserved.Remove(slug)274	register(pkg, creatorRlm.Address(), name, symbol, cover, maxSupply, mintPrice, royaltyBps)275}276277func Reserve(cur realm, slug string) {278	requireInit()279	if !cur.Previous().IsUserCall() {280		panic("factory: EOA only")281	}282	slug = strings.ToLower(strings.TrimSpace(slug))283	if !validSlug(slug) {284		panic("factory: slug")285	}286	if bySlug.Has(slug) || reserved.Has(slug) {287		panic("factory: slug taken")288	}289	paid := launchFee290	takeFactorySend(paid)291	reserved.Set(slug, &reservation{who: cur.Previous().Address(), paid: paid})292	chain.Emit("Reserve", "slug", slug, "paid", strconv.FormatInt(paid, 10))293}294295func CancelReserve(cur realm, slug string) {296	requireInit()297	if !cur.Previous().IsUserCall() {298		panic("factory: EOA only")299	}300	slug = strings.ToLower(strings.TrimSpace(slug))301	res := mustReserve(slug)302	if res.who != cur.Previous().Address() {303		panic("factory: not reserver")304	}305	if bySlug.Has(slug) {306		panic("factory: already registered")307	}308	reserved.Remove(slug)309	if res.paid > 0 {310		bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)311		bk.SendCoins(self, res.who, chain.Coins{{Denom: nativeDenom, Amount: res.paid}})312	}313	chain.Emit("CancelReserve", "slug", slug, "paid", strconv.FormatInt(res.paid, 10))314}315316func ReservedCreator(slug string) string {317	requireInit()318	slug = strings.ToLower(strings.TrimSpace(slug))319	if !reserved.Has(slug) {320		return ""321	}322	return reserved.Get(slug).(*reservation).who.String()323}324325func takeFactorySend(want int64) {326	sent := unsafe.OriginSend()327	if want == 0 {328		if len(sent) != 0 {329			panic("factory: extra denoms")330		}331		return332	}333	if len(sent) != 1 || sent[0].Denom != nativeDenom || sent[0].Amount != want {334		panic("factory: wrong payment")335	}336}337338func NoteMinted(cur realm, n int) {339	requireInit()340	if n < 0 {341		panic("factory: minted")342	}343	prev := cur.Previous()344	if !prev.IsCode() {345		panic("factory: collection realm")346	}347	c := mustByPkg(prev.PkgPath())348	c.minted = n349	byPkg.Set(c.pkg, c)350	bySlug.Set(c.slug, c)351}352353func NoteRoyalty(cur realm, bps int) {354	requireInit()355	if bps < 0 || bps > maxRoyaltyBps {356		panic("factory: royalty")357	}358	prev := cur.Previous()359	if !prev.IsCode() {360		panic("factory: collection realm")361	}362	c := mustByPkg(prev.PkgPath())363	c.royaltyBps = bps364	byPkg.Set(c.pkg, c)365	bySlug.Set(c.slug, c)366}367368func CollectionOf(slug string) string {369	requireInit()370	c := mustBySlug(slug)371	return c.pkg372}373374func CollectionAddr(slug string) string {375	requireInit()376	c := mustBySlug(slug)377	return chain.PackageAddress(c.pkg).String()378}379380func RoyaltyOf(slug string) int {381	requireInit()382	c := mustBySlug(slug)383	return c.royaltyBps384}385386func ListCollections() string {387	requireInit()388	out := ""389	bySlug.Iterate("", "", func(_ string, value any) bool {390		c := value.(*collection)391		if out != "" {392			out += "\n"393		}394		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)395		return false396	})397	return out398}399400func Withdraw(cur realm) {401	requireAdmin(cur)402	bk := banker.NewBanker(banker.BankerTypeRealmSend, cur)403	ugnot := bk.GetCoins(self).AmountOf(nativeDenom)404	locked := reservedPaid()405	avail := ugnot - locked406	if avail <= 0 {407		panic("factory: no funds")408	}409	bk.SendCoins(self, admin, chain.Coins{{Denom: nativeDenom, Amount: avail}})410	chain.Emit("Withdraw", "amount", strconv.FormatInt(avail, 10))411}412413func TransferAdmin(cur realm, next address) {414	requireAdmin(cur)415	if !next.IsValid() {416		panic("factory: invalid address")417	}418	if next == admin {419		panic("factory: already admin")420	}421	admin = next422	chain.Emit("TransferAdmin", "addr", next.String())423}424425func Render(_ string) string {426	if !inited {427		return "# Bazaar factory\n\nCall Init first.\n"428	}429	out := "# Bazaar factory\n\n"430	out += "- launch fee: " + strconv.FormatInt(launchFee, 10) + " ugnot\n"431	out += "- collections: " + strconv.Itoa(bySlug.Size()) + "\n\n"432	lines := ListCollections()433	if lines == "" {434		out += "_No collections._\n"435	} else {436		out += "```\n" + lines + "\n```\n"437	}438	return out439}440441func register(pkg string, creator address, name, symbol, cover string, maxSupply int, mintPrice, royaltyBps int64) {442	if !strings.HasPrefix(pkg, "gno.land/r/") {443		panic("factory: pkg")444	}445	slug := lastElem(pkg)446	if !validSlug(slug) {447		panic("factory: slug")448	}449	if !validName(name) {450		panic("factory: name")451	}452	if !validSymbol(symbol) {453		panic("factory: symbol")454	}455	if !validImage(cover) {456		panic("factory: cover")457	}458	if maxSupply < 0 || maxSupply > maxSupplyBound {459		panic("factory: maxSupply")460	}461	if mintPrice < 0 {462		panic("factory: mintPrice")463	}464	if royaltyBps < 0 || royaltyBps > maxRoyaltyBps {465		panic("factory: royalty")466	}467	if bySlug.Has(slug) {468		panic("factory: slug taken")469	}470	if byPkg.Has(pkg) {471		panic("factory: pkg already registered")472	}473	c := &collection{474		slug:       slug,475		name:       name,476		symbol:     symbol,477		cover:      cover,478		pkg:        pkg,479		creator:    creator,480		maxSupply:  maxSupply,481		mintPrice:  mintPrice,482		royaltyBps: int(royaltyBps),483	}484	bySlug.Set(slug, c)485	byPkg.Set(pkg, c)486	chain.Emit("Register", "slug", slug, "pkg", pkg, "creator", creator.String())487}488489func requireInit() {490	if !inited {491		panic("factory: call Init first")492	}493}494495func requireAdmin(cur realm) {496	requireInit()497	if !cur.Previous().IsUserCall() {498		panic("factory: EOA only")499	}500	if cur.Previous().Address() != admin {501		panic("factory: not admin")502	}503}504505func mustReserve(slug string) *reservation {506	v := reserved.Get(slug)507	if v == nil {508		panic("factory: not reserved")509	}510	return v.(*reservation)511}512513func reservedPaid() int64 {514	var n int64515	reserved.Iterate("", "", func(_ string, value any) bool {516		n += value.(*reservation).paid517		return false518	})519	return n520}521522func mustBySlug(slug string) *collection {523	v := bySlug.Get(slug)524	if v == nil {525		panic("factory: unknown collection")526	}527	return v.(*collection)528}529530func mustByPkg(pkg string) *collection {531	v := byPkg.Get(pkg)532	if v == nil {533		panic("factory: unknown collection")534	}535	return v.(*collection)536}537538func lastElem(pkg string) string {539	i := strings.LastIndex(pkg, "/")540	if i < 0 || i+1 >= len(pkg) {541		panic("factory: pkg")542	}543	return pkg[i+1:]544}545546func validSlug(s string) bool {547	if len(s) < minSlugLen || len(s) > maxSlugLen {548		return false549	}550	if s[0] < 'a' || s[0] > 'z' {551		return false552	}553	return asciiSet(s, "abcdefghijklmnopqrstuvwxyz0123456789")554}555556func validSymbol(s string) bool {557	if len(s) < 1 || len(s) > maxSymbolLen {558		return false559	}560	return asciiSet(s, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-")561}562563func validName(name string) bool {564	if len(name) < 1 || len(name) > maxNameLen {565		return false566	}567	return !strings.ContainsAny(name, "\n\r|")568}569570func validImage(u string) bool {571	if u == "" {572		return true573	}574	if len(u) > maxImageLen {575		return false576	}577	if strings.ContainsAny(u, " \t\n\r|<>\"'`") {578		return false579	}580	if strings.HasPrefix(u, "https://") || strings.HasPrefix(u, "http://") {581		return true582	}583	const prefix = "/samples/"584	if !strings.HasPrefix(u, prefix) {585		return false586	}587	rest := u[len(prefix):]588	if rest == "" {589		return false590	}591	return asciiSet(rest, "abcdefghijklmnopqrstuvwxyz0123456789._-")592}593594func asciiSet(s, allowed string) bool {595	for i := 0; i < len(s); i++ {596		if !strings.ContainsRune(allowed, rune(s[i])) {597			return false598		}599	}600	return true601}602

Functions

  • Address() string

  • Admin() string

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

  • 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

  • DiscountPusher() string

  • GenesisPkg() string

  • GenesisShareBps() int64

  • GenesisSink() string

  • HolderDiscount(owner string) int64

  • 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

  • NoteHolderDiscount(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}, owner string, bps int64)

  • 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

  • ProtocolSink() string

  • 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

  • SetDiscountPusher(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}, pkg string)

  • SetGenesis(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}, pkg string)

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

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

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