1package avatar23import (4 "chain"5 "chain/runtime"6 "strings"78 "gno.land/p/g17khqpukees4237dtn3astzapmp462vjhsz6st4/settlers/nft/v0"9 "gno.land/p/nt/grc721/v0"10 "gno.land/p/nt/mdalert/v0"11 "gno.land/p/nt/ownable/v0"12 settlers "gno.land/r/g17khqpukees4237dtn3astzapmp462vjhsz6st4/settlers/nft"13)1415const (16 // MinSize is the minimum size allowed for an avatar in pixels.17 MinSize = 321819 // MaxSize is the maximum size allowed for an avatar in pixels.20 MaxSize = 204821)2223var (24 // Notice is a realm-wide message the admin can post at any time, shown at the top of the page.25 // It never affects SVG, URI or Markdown, it is purely informational.26 Notice string2728 // NoticeType is the style Notice is shown as.29 NoticeType mdalert.Type3031 // Realm path is the path of this realm.32 RealmPath string3334 // Admin account for the realm, only valid to post or clear realm-wide notices.35 admin *ownable.Ownable3637 // Go snippet is the Go usage example.38 goSnippet string3940 // Gnokey snippet is the gnokey example.41 gnokeySnippet string42)4344func init(cur realm) {45 RealmPath = strings.TrimPrefix(cur.PkgPath(), runtime.ChainDomain())46 admin = ownable.NewWithAddress(cur.Previous().Address())47 pkgPath := runtime.ChainDomain() + RealmPath4849 goSnippet = "import \"" + pkgPath + "\"\n\n" +50 "func RenderUser(addr address) string {\n\treturn avatar.Markdown(addr, 32, true) " +51 "+ \" \" + addr.String()\n}\n"5253 gnokeySnippet = "gnokey query vm/qrender \\\n" +54 " -remote <remote> \\\n" +55 " -data \"" + pkgPath + ":svg/{address}?size=256\" \\\n" +56 " | tail -n +2 | sed '1s/^data: //' > settler.svg\n"57}5859// Admin returns the address of the admin account.60func Admin() address { return admin.Owner() }6162// TransferAdmin makes another account the admin. Only the admin can call it.63func TransferAdmin(cur realm, newAdmin address) {64 assertIsCurrent(cur)65 if err := admin.TransferOwnership(0, cur, newAdmin); err != nil {66 panic(err)67 }68}6970// SetNotice posts a realm-wide message, shown at the top of the page.71func SetNotice(cur realm, alertType mdalert.Type, msg string) {72 assertIsCurrent(cur)73 admin.AssertOwnedBy(cur.Previous().Address())74 assertIsValidAlertType(alertType)7576 NoticeType = alertType77 Notice = msg78 chain.Emit("NoticeSet", "type", string(alertType))79}8081// ClearNotice removes the current notice.82func ClearNotice(cur realm) {83 assertIsCurrent(cur)84 admin.AssertOwnedBy(cur.Previous().Address())8586 NoticeType = ""87 Notice = ""88 chain.Emit("NoticeCleared")89}9091// SVG returns the SVG document of the Settler of an address, or an empty text if it has none.92//93// The size is the width and height in pixels of the square image, from 32 to 2048 (multiples of 32 keep94// every art pixel as a whole number of screen pixels). A size of 0 or less leaves out the width and the95// height, so that the image scales to its container. If transparent is true, the image has no background.96func SVG(addr address, size int, transparent bool) string {97 if tid, traits := lookup(addr); tid != "" {98 return nft.RenderSVG(traits, options(size, transparent))99 }100 return ""101}102103// URI returns the image of the Settler of an address as a "data:image/svg+xml;charset=utf-8," URI, that can104// be used as the source of an image or as the address of a Markdown image, or an empty text if it has none.105// The size and transparent are the same as in SVG.106func URI(addr address, size int, transparent bool) string {107 if tid, traits := lookup(addr); tid != "" {108 return nft.RenderDataURI(traits, options(size, transparent))109 }110 return ""111}112113// Markdown returns the avatar of an address as a Markdown image, or an empty text if it has none:114//115// 116//117// The size and transparent are the same as in SVG.118func Markdown(addr address, size int, transparent bool) string {119 if tid, traits := lookup(addr); tid != "" {120 uri := nft.RenderDataURI(traits, options(size, transparent))121 return ""122 }123 return ""124}125126// lookup returns the ID and traits of the Settler of an address, or an empty ID and a zero-value Traits if it127// has none.128func lookup(addr address) (grc721.TokenID, nft.Traits) {129 tid := settlers.TokenOf(addr)130 if tid == "" {131 return "", nft.Traits{}132 }133134 traits, err := settlers.TraitsOf(tid)135 if err != nil {136 return "", nft.Traits{}137 }138 return tid, traits139}140141// options builds the nft.Options for an image; size is clamped between MinSize and MaxSize (0 or less is142// left as 0, so the image has no fixed size and scales to its container), and transparent controls whether143// the background is drawn.144func options(size int, transparent bool) nft.Options {145 switch {146 case size <= 0:147 size = 0148 case size < MinSize:149 size = MinSize150 case size > MaxSize:151 size = MaxSize152 }153154 return nft.Options{155 Size: size,156 NoBackground: transparent,157 }158}159160func assertIsCurrent(cur realm) {161 if !cur.IsCurrent() {162 panic("unauthorized")163 }164}165166func assertIsValidAlertType(t mdalert.Type) {167 switch t {168 case mdalert.TypeCaution, mdalert.TypeInfo, mdalert.TypeNote,169 mdalert.TypeSuccess, mdalert.TypeTip, mdalert.TypeWarning:170 return171 }172 panic("invalid notice type")173}174Admin() string
ClearNotice(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})
Markdown(addr string, size int, transparent bool) string
Render(path string) string
SetNotice(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}, alertType string, msg string)
SVG(addr string, size int, transparent bool) 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}, newAdmin string)
URI(addr string, size int, transparent bool) string
Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.
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.