github.com/gnolang/gno@v0.0.0-20240520182011-228e9d0192ce/gnovm/stdlibs/std/banker.gno (about) 1 package std 2 3 import "strconv" 4 5 // Realm functions can call std.GetBanker(options) to get 6 // a banker instance. Banker objects cannot be persisted, 7 // but can be passed onto other functions to be transacted 8 // on. A banker instance can be passed onto other realm 9 // functions; this allows other realms to spend coins on 10 // behalf of the first realm. 11 // 12 // Banker panics on errors instead of returning errors. 13 // This also helps simplify the interface and prevent 14 // hidden bugs (e.g. ignoring errors) 15 // 16 // NOTE: this Gno interface is satisfied by a native go 17 // type, and those can't return non-primitive objects 18 // (without confusion). 19 type Banker interface { 20 GetCoins(addr Address) (dst Coins) 21 SendCoins(from, to Address, amt Coins) 22 TotalCoin(denom string) int64 23 IssueCoin(addr Address, denom string, amount int64) 24 RemoveCoin(addr Address, denom string, amount int64) 25 } 26 27 // BankerType represents the "permission level" requested for a banker, 28 // retrievable through [GetBanker]. 29 type BankerType uint8 30 31 // Available types of banker. 32 const ( 33 // Can only read state. 34 BankerTypeReadonly BankerType = iota 35 // Can only send from tx send. 36 BankerTypeOrigSend 37 // Can send from all realm coins. 38 BankerTypeRealmSend 39 // Can issue and remove realm coins. 40 BankerTypeRealmIssue 41 42 maxBanker 43 ) 44 45 func (b BankerType) String() string { 46 switch b { 47 case BankerTypeReadonly: 48 return "BankerTypeReadonly" 49 case BankerTypeOrigSend: 50 return "BankerTypeOrigSend" 51 case BankerTypeRealmSend: 52 return "BankerTypeRealmSend" 53 case BankerTypeRealmIssue: 54 return "BankerTypeRealmIssue" 55 default: 56 panic("invalid BankerType: " + strconv.Itoa(int(b))) 57 } 58 } 59 60 //---------------------------------------- 61 // adapter for native banker 62 63 // GetBanker returns a new Banker, with its capabilities matching the given 64 // [BankerType]. 65 func GetBanker(bt BankerType) Banker { 66 if bt >= maxBanker { 67 panic("invalid banker type") 68 } 69 return banker{bt} 70 } 71 72 // These are native bindings to the banker's functions. 73 func bankerGetCoins(bt uint8, addr string) (denoms []string, amounts []int64) 74 func bankerSendCoins(bt uint8, from, to string, denoms []string, amounts []int64) 75 func bankerTotalCoin(bt uint8, denom string) int64 76 func bankerIssueCoin(bt uint8, addr string, denom string, amount int64) 77 func bankerRemoveCoin(bt uint8, addr string, denom string, amount int64) 78 79 type banker struct { 80 bt BankerType 81 } 82 83 func (b banker) GetCoins(addr Address) (dst Coins) { 84 denoms, amounts := bankerGetCoins(uint8(b.bt), string(addr)) 85 dst = make(Coins, len(denoms)) 86 for i := range dst { 87 dst[i] = Coin{denoms[i], amounts[i]} 88 } 89 return dst 90 } 91 92 func (b banker) SendCoins(from, to Address, amt Coins) { 93 if b.bt == BankerTypeReadonly { 94 panic("BankerTypeReadonly cannot send coins") 95 } 96 denoms, amounts := amt.expandNative() 97 bankerSendCoins(uint8(b.bt), string(from), string(to), denoms, amounts) 98 } 99 100 func (b banker) TotalCoin(denom string) int64 { 101 return bankerTotalCoin(uint8(b.bt), denom) 102 } 103 104 func (b banker) IssueCoin(addr Address, denom string, amount int64) { 105 if b.bt != BankerTypeRealmIssue { 106 panic(b.bt.String() + " cannot issue coins") 107 } 108 bankerIssueCoin(uint8(b.bt), string(addr), denom, amount) 109 } 110 111 func (b banker) RemoveCoin(addr Address, denom string, amount int64) { 112 if b.bt != BankerTypeRealmIssue { 113 panic(b.bt.String() + " cannot remove coins") 114 } 115 bankerRemoveCoin(uint8(b.bt), string(addr), denom, amount) 116 }