Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

render.gno

3.35 Kb · 100 lines
  1package nativereg
  2
  3import (
  4	"strings"
  5
  6	"gno.land/p/moul/kit/ui/v0"
  7	"gno.land/p/moul/md/v0"
  8	"gno.land/p/nt/ufmt/v0"
  9)
 10
 11// Render lists the registry. `?<denom>` shows one entry, `?<pkgpath>` shows
 12// everything one realm issues.
 13func Render(path string) string {
 14	if path == "" {
 15		return renderIndex()
 16	}
 17	if strings.HasPrefix(path, "/") {
 18		return renderDenom(path)
 19	}
 20	return renderIssuer(path)
 21}
 22
 23func renderIndex() string {
 24	var sb strings.Builder
 25	sb.WriteString(md.H1("nativereg: what a native denom means"))
 26	sb.WriteString("\nA realm-issued coin is a string and a balance. The chain stores no name, " +
 27		"no symbol and no decimals for it, so this realm does. An issuer registers its own " +
 28		"denoms and nobody else's: the package path is embedded in the denom, and that is " +
 29		"the whole authorization.\n\n")
 30
 31	t := ui.NewTable("denom", "symbol", "name", "decimals", "issuer")
 32	for _, e := range List() {
 33		t.Row(md.InlineCode(ui.ShortN(e.Denom, 22, 12)), ui.Cell(e.Symbol), ui.Cell(e.Name),
 34			ufmt.Sprintf("%d", e.Decimals), md.Link(ui.Short(e.Issuer), "/"+strings.TrimPrefix(e.Issuer, "gno.land/")))
 35	}
 36	sb.WriteString(md.H2("Registered"))
 37	sb.WriteString("\n" + t.OrEmpty("Nothing registered yet.") + "\n")
 38
 39	sb.WriteString(md.H2("Register your own"))
 40	sb.WriteString("\nFrom inside the realm that issues the coin, never from a wallet:\n\n")
 41	sb.WriteString(md.LanguageCodeBlock("go",
 42		"import \"gno.land/r/moul/x/nativereg/v0\"\n\n"+
 43			"func init(cur realm) {\n"+
 44			"\tnativereg.Register(cross(cur), Denom, \"My Coin\", \"MINE\", 6,\n"+
 45			"\t\t\"one line about what it is for\")\n"+
 46			"}"))
 47	sb.WriteString("\n" + md.Italic("Decimals is a display hint. The bank counts whole units and "+
 48		"knows nothing about divisibility.") + "\n")
 49	return sb.String()
 50}
 51
 52func renderDenom(denom string) string {
 53	e, ok := Get(denom)
 54	if !ok {
 55		return md.H1("Not registered") + "\n" + md.InlineCode(denom) +
 56			" has said nothing about itself.\n\nIts issuer is " +
 57			md.InlineCode(safeIssuer(denom)) + ", and only that realm can change it.\n"
 58	}
 59
 60	t := ui.NewTable("", "")
 61	t.Row("denom", md.InlineCode(e.Denom))
 62	t.Row("issuer", md.InlineCode(e.Issuer))
 63	t.Row("name", ui.Cell(e.Name))
 64	t.Row("symbol", ui.Cell(e.Symbol))
 65	t.Row("decimals", ufmt.Sprintf("%d (display hint)", e.Decimals))
 66	t.Row("registered at block", ufmt.Sprintf("%d", e.Height))
 67	t.Row("revisions", ufmt.Sprintf("%d", e.Revisions))
 68
 69	s := md.H1(ui.Inline(e.Symbol)) + "\n"
 70	if e.Doc != "" {
 71		s += ui.Inline(e.Doc) + "\n\n"
 72	}
 73	s += t.String() + "\n"
 74	s += md.Blockquote("The issuer can rewrite every row but the first two, and can remove "+
 75		"this coin from any balance at any time. That is what a realm-issued coin is.") + "\n"
 76	return s
 77}
 78
 79func renderIssuer(pkgPath string) string {
 80	entries := ByIssuer(pkgPath)
 81	s := md.H1("Issued by "+ui.Inline(pkgPath)) + "\n"
 82	t := ui.NewTable("denom", "symbol", "name")
 83	for _, e := range entries {
 84		t.Row(md.InlineCode(ui.ShortN(e.Denom, 22, 12)), ui.Cell(e.Symbol), ui.Cell(e.Name))
 85	}
 86	return s + t.OrEmpty("This realm has registered nothing here.") + "\n"
 87}
 88
 89// safeIssuer is IssuerOf for a Render, which must never abort on a path a reader
 90// typed into the URL bar.
 91func safeIssuer(denom string) string {
 92	if !strings.HasPrefix(denom, "/") {
 93		return "unknown (not a realm denom)"
 94	}
 95	i := strings.LastIndex(denom, ":")
 96	if i < 1 {
 97		return "unknown (not a realm denom)"
 98	}
 99	return denom[1:i]
100}