1package grc72123// IGRC721Reader is the read-only view of an NFT. Safe to receive across4// realm boundaries — has no rlm-typed methods, so a malicious impl can5// only lie about read results (data-integrity issue), not capture cur.6//7// Writes are concrete methods on *basicNFT only — there is no IGRC7218// writer interface. The owning realm should9// hold the concrete *basicNFT in an unexported package var and expose10// public rlm-validating wrappers like:11//12// func TransferFrom(cur realm, from, to address, tid TokenID) error {13// caller := cur.Previous().Address()14// return nft.TransferFrom(caller, from, to, tid)15// }16//17// This is the Reader/Writer split — stronger than the Authority-pattern18// because the writer interface doesn't exist at all, so no realm author19// can accidentally expose it. See `r/demo/foo721` for the canonical20// wrapper pattern.21type IGRC721Reader interface {22 Name() string23 Symbol() string24 TokenCount() int6425 BalanceOf(owner address) (int64, error)26 OwnerOf(tid TokenID) (address, error)27 GetApproved(tid TokenID) (address, error)28 IsApprovedForAll(owner, operator address) bool29}3031type (32 TokenID string33 TokenURI string34)3536func (t TokenID) String() string { return string(t) }37func (t TokenURI) String() string { return string(t) }3839const (40 MintEvent = "Mint"41 BurnEvent = "Burn"42 TransferEvent = "Transfer"43 ApprovalEvent = "Approval"44 ApprovalForAllEvent = "ApprovalForAll"45)4647// NFTGetter returns a reader-only view of an NFT. Aggregators (such as48// tokenhub) register and dispatch NFTGetters; the reader-only return49// type means even a malicious aggregator can't be used to leak cur.50type NFTGetter func() IGRC721Reader51Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.