Search Apps Documentation Source Content File Folder Download Copy Actions Download

utils.gno

2.69 Kb · 93 lines
 1package gnft
 2
 3import (
 4	"math/rand"
 5	"time"
 6
 7	"gno.land/p/gnoswap/deps/grc721"
 8	ufmt "gno.land/p/nt/ufmt/v0"
 9)
10
11// generateRandInstance generates a new random instance.
12func generateRandInstance() *rand.Rand {
13	now := time.Now()
14	seed1 := now.Unix() + TotalSupply()
15	seed2 := now.UnixNano() + TotalSupply()
16	pcg := rand.NewPCG(uint64(seed1), uint64(seed2))
17	return rand.New(pcg)
18}
19
20// checkErr panics if an error occurs.
21func checkErr(err error) {
22	if err != nil {
23		panic(err.Error())
24	}
25}
26
27// checkTransferErr wraps transfer errors with more specific context.
28func checkTransferErr(err error, caller, from, to address, tid grc721.TokenID) {
29	if err == nil {
30		return
31	}
32
33	// Check if token exists
34	owner, ownerErr := nft.OwnerOf(tid)
35	if ownerErr != nil {
36		panic(ownerErr)
37	}
38
39	switch err {
40	case grc721.ErrCallerIsNotOwnerOrApproved:
41		// Check if caller is the owner
42		if caller == owner {
43			panic(makeErrorWithDetails(grc721.ErrTransferFromIncorrectOwner, ufmt.Sprintf("owner mismatch - from: %s, actual owner: %s, token: %s", from, owner, string(tid))))
44		}
45
46		// Check if caller is approved for this specific token
47		approved, _ := nft.GetApproved(tid)
48		if approved != caller {
49			// Check if caller is approved for all tokens
50			if !nft.IsApprovedForAll(owner, caller) {
51				panic(makeErrorWithDetails(grc721.ErrCallerIsNotOwnerOrApproved, ufmt.Sprintf("caller %s is not owner %s or approved for token %s", caller, owner, string(tid))))
52			}
53		}
54
55	case grc721.ErrInvalidAddress:
56		panic(makeErrorWithDetails(grc721.ErrInvalidAddress, ufmt.Sprintf("to address (%s)", to)))
57
58	case grc721.ErrTransferFromIncorrectOwner:
59		panic(makeErrorWithDetails(grc721.ErrTransferFromIncorrectOwner, ufmt.Sprintf("from %s is not the owner %s of token %s", from, owner, string(tid))))
60
61	case grc721.ErrInvalidTokenId:
62		panic(makeErrorWithDetails(grc721.ErrInvalidTokenId, ufmt.Sprintf("token %s", string(tid))))
63
64	default:
65		panic(err.Error())
66	}
67}
68
69// checkApproveErr wraps approve errors with more specific context.
70func checkApproveErr(err error, caller, approved address, tid grc721.TokenID) {
71	if err == nil {
72		return
73	}
74
75	errMsg := err.Error()
76
77	// Check if token exists
78	owner, ownerErr := nft.OwnerOf(tid)
79	if ownerErr != nil {
80		panic(makeErrorWithDetails(errTokenNotExists, ufmt.Sprintf("token %s", string(tid))))
81	}
82
83	switch {
84	case errMsg == "caller is not token owner or approved":
85		panic(makeErrorWithDetails(errNotOwnerOrApproved, ufmt.Sprintf("caller %s cannot approve for token %s owned by %s", caller, string(tid), owner)))
86
87	case errMsg == "approval to current owner":
88		panic(makeErrorWithDetails(errTransferToSelf, ufmt.Sprintf("cannot approve to current owner %s for token %s", approved, string(tid))))
89
90	default:
91		panic(err.Error())
92	}
93}