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

utils.gno

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