minter.gno
3.43 Kb · 116 lines
1// GnoMoji — Minter Realm
2// gno.land/r/gnomoji/minter
3//
4// Treasury gateway for GnoMoji on Gno.land (v1.5.0 / Onyx testnet API).
5// Called server-side by treasury.server.ts after a player earns coins via ClaimMine.
6//
7// Security: only the admin (treasury wallet, set at deploy time) can call Mint or MintTool.
8
9package minter2
10
11import (
12 "strconv"
13 "strings"
14
15 "gno.land/p/nt/avl/v0"
16 "gno.land/p/nt/ufmt/v0"
17)
18
19var (
20 admin address
21 mintLogs avl.Tree // addr+":"+coinId → total minted (audit)
22)
23
24func init(cur realm) {
25 admin = cur.Previous().Address()
26}
27
28func isAdmin(cur realm) bool {
29 return cur.Previous().Address() == admin
30}
31
32// UpdateAdmin transfers the admin role to a new address.
33func UpdateAdmin(cur realm, newAdmin string) {
34 if !isAdmin(cur) {
35 panic("minter: unauthorized")
36 }
37 admin = address(newAdmin)
38}
39
40// AdminAddr returns the current admin address.
41func AdminAddr() string {
42 return admin.String()
43}
44
45// ── Core minting ──────────────────────────────────────────────────────────────
46
47// Mint credits coinId tokens to a player address.
48// Records in internal audit log. Uncomment GRC20 cross-realm call once
49// coin realms are deployed at gno.land/r/gnomoji/coins/{coinId}.
50func Mint(cur realm, coinId string, toAddr string, amountStr string) {
51 if !isAdmin(cur) {
52 panic("minter: unauthorized — only treasury can mint")
53 }
54 if coinId == "" || toAddr == "" {
55 panic("minter: coinId and toAddr required")
56 }
57 if !strings.HasPrefix(toAddr, "g1") {
58 panic("minter: invalid Gno.land address")
59 }
60 amount, err := strconv.ParseUint(amountStr, 10, 64)
61 if err != nil || amount == 0 {
62 panic("minter: invalid amount")
63 }
64
65 key := toAddr + ":" + coinId
66 existing := uint64(0)
67 if mintLogs.Has(key) {
68 existing, _ = strconv.ParseUint(mintLogs.Get(key).(string), 10, 64)
69 }
70 mintLogs.Set(key, strconv.FormatUint(existing+amount, 10))
71
72 // Once GRC20 coin realms are deployed at gno.land/r/gnomoji/coins/{coinId},
73 // uncomment to issue real on-chain tokens:
74 //
75 // coinPath := "gno.land/r/gnomoji/coins/" + coinId
76 // std.Call(coinPath, "Mint", address(toAddr), amount)
77}
78
79// MintTool records tool ownership for a player on-chain.
80func MintTool(cur realm, toolId string, toAddr string, _ string) {
81 if !isAdmin(cur) {
82 panic("minter: unauthorized — only treasury can mint tools")
83 }
84 if toolId == "" || toAddr == "" {
85 panic("minter: toolId and toAddr required")
86 }
87 mintLogs.Set(toAddr+":tool:"+toolId, "1")
88}
89
90// ClearPendingMints notifies the game realm that coins have been minted.
91func ClearPendingMints(cur realm, playerAddr string, coinsJson string) {
92 if !isAdmin(cur) {
93 panic("minter: unauthorized")
94 }
95 // Once game realm is deployed, uncomment:
96 // std.Call("gno.land/r/gnomoji/game", "ClearPendingMints", playerAddr, coinsJson)
97 _ = playerAddr
98 _ = coinsJson
99}
100
101// ── Queries ───────────────────────────────────────────────────────────────────
102
103func TotalMinted(playerAddr string, coinId string) string {
104 key := playerAddr + ":" + coinId
105 if mintLogs.Has(key) {
106 return mintLogs.Get(key).(string)
107 }
108 return "0"
109}
110
111func Render(_ string) string {
112 return ufmt.Sprintf(
113 "# GnoMoji Minter\n\nAdmin: `%s`\n\nUse Mint(coinId, addr, amount) to credit coins after ClaimMine.\n",
114 admin.String(),
115 )
116}