Search Apps Documentation Source Content File Folder Download Copy Actions Download

utils.gno

2.72 Kb · 123 lines
  1package block
  2
  3import (
  4	"chain"
  5	"chain/banker"
  6	"net/url"
  7	"strconv"
  8
  9	"gno.land/p/akkadia/v0/grc1155"
 10)
 11
 12func copyStringMap(source map[string]string) map[string]string {
 13	result := map[string]string{}
 14	for k, v := range source {
 15		result[k] = v
 16	}
 17	return result
 18}
 19
 20func encodeStringMap(values map[string]string) string {
 21	query := url.Values{}
 22	for key, value := range values {
 23		query.Set(key, value)
 24	}
 25	return query.Encode()
 26}
 27
 28func decodeStringMap(encoded string) map[string]string {
 29	values, err := url.ParseQuery(encoded)
 30	if err != nil {
 31		panic("invalid stored query string")
 32	}
 33
 34	result := map[string]string{}
 35	for key, entries := range values {
 36		if len(entries) != 1 {
 37			panic("invalid stored query string")
 38		}
 39		result[key] = entries[0]
 40	}
 41	return result
 42}
 43
 44func blockIDToString(blockID uint32) string {
 45	return strconv.FormatUint(uint64(blockID), 10)
 46}
 47
 48func stringToBlockID(blockIDStr string) uint32 {
 49	value, err := strconv.ParseUint(blockIDStr, 10, 32)
 50	if err != nil {
 51		panic("invalid blockID: " + err.Error())
 52	}
 53	return uint32(value)
 54}
 55
 56func parseBlockID(blockIDStr string) (uint32, bool) {
 57	value, err := strconv.ParseUint(blockIDStr, 10, 32)
 58	if err != nil {
 59		return 0, false
 60	}
 61	return uint32(value), true
 62}
 63
 64func blockIDToTokenID(blockID uint32) grc1155.TokenID {
 65	return grc1155.TokenID(blockIDToString(blockID))
 66}
 67
 68func tokenIDToBlockID(tokenID grc1155.TokenID) uint32 {
 69	return stringToBlockID(string(tokenID))
 70}
 71
 72func tokenIDsToBlockIDs(tokenIDs []grc1155.TokenID) []uint32 {
 73	blockIDs := make([]uint32, len(tokenIDs))
 74	for i, tokenID := range tokenIDs {
 75		blockIDs[i] = tokenIDToBlockID(tokenID)
 76	}
 77	return blockIDs
 78}
 79
 80func calculateBPSShares(amount int64, bps int) (int64, int64) {
 81	if amount <= 0 {
 82		return 0, 0
 83	}
 84	if bps <= 0 {
 85		return 0, amount
 86	}
 87	if bps >= 10000 {
 88		return amount, 0
 89	}
 90
 91	bps64 := int64(bps)
 92	first := (amount/10000)*bps64 + (amount%10000)*bps64/10000
 93	return first, amount - first
 94}
 95
 96func distributeShares(cur realm, recipientStr string, feeCollector address, cost int64, bps int) (int64, int64) {
 97	if cost <= 0 {
 98		return 0, 0
 99	}
100
101	recipientShare, feeCollectorShare := calculateBPSShares(cost, bps)
102	if recipientShare > 0 {
103		recipient := mustParseAddress(recipientStr)
104		send(cur, recipient, recipientShare)
105	}
106	if feeCollectorShare > 0 {
107		if !feeCollector.IsValid() {
108			panic("fee collector is invalid: " + feeCollector.String())
109		}
110		send(cur, feeCollector, feeCollectorShare)
111	}
112	return recipientShare, feeCollectorShare
113}
114
115func send(cur realm, to address, amount int64) {
116	if amount <= 0 {
117		panic("amount must be greater than 0")
118	}
119	bnk := banker.NewBanker(banker.BankerTypeRealmSend, cur)
120	realmAddr := cur.Address()
121	coins := chain.Coins{chain.Coin{"ugnot", amount}}
122	bnk.SendCoins(realmAddr, to, coins)
123}