@@ -13,6 +13,17 @@ class InvalidCIP68ReferenceNFT(Exception):
13
13
14
14
15
15
class CIP68TokenName (CIP67TokenName ):
16
+ """Generates a CIP-68 reference token name from an input asset name.
17
+
18
+ The reference_token property generates a reference token name by slicing off the label
19
+ portion of the asset name and assigning the (100) label hex value.
20
+
21
+ For more information on CIP-68 labels:
22
+ https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068
23
+
24
+ Args:
25
+ data: The token name as bytes, str, or AssetName
26
+ """
16
27
@property
17
28
def reference_token (self ) -> "CIP68ReferenceNFTName" :
18
29
ref_token = self .payload .hex ()[0 ] + "00643b" + self .payload .hex ()[7 :]
@@ -21,6 +32,7 @@ def reference_token(self) -> "CIP68ReferenceNFTName":
21
32
22
33
23
34
class CIP68ReferenceNFTName (CIP68TokenName ):
35
+ """Validates that an asset name has the 100 label for reference NFTs."""
24
36
def __init__ (self , data : Union [bytes , str , AssetName ]):
25
37
super ().__init__ (data )
26
38
@@ -29,6 +41,7 @@ def __init__(self, data: Union[bytes, str, AssetName]):
29
41
30
42
31
43
class CIP68UserNFTName (CIP68TokenName ):
44
+ """Validates that an asset name has the 222 label for NFTs."""
32
45
def __init__ (self , data : Union [bytes , str , AssetName ]):
33
46
super ().__init__ (data )
34
47
@@ -37,6 +50,10 @@ def __init__(self, data: Union[bytes, str, AssetName]):
37
50
38
51
39
52
class CIP68UserNFTFiles (TypedDict , total = False ):
53
+ """Multiple files may be included in metadata by using a list of dictionaries.
54
+
55
+ Example: files: [file_dict_1, file_dict_2]
56
+ """
40
57
name : bytes
41
58
mediaType : Required [bytes ]
42
59
src : Required [bytes ]
@@ -50,6 +67,7 @@ class CIP68UserNFTMetadata(TypedDict, total=False):
50
67
51
68
52
69
class CIP68UserFTName (CIP68TokenName ):
70
+ """Validates that an asset name has the 333 label for FTs."""
53
71
def __init__ (self , data : Union [bytes , str , AssetName ]):
54
72
super ().__init__ (data )
55
73
@@ -67,6 +85,7 @@ class CIP68UserFTMetadata(TypedDict, total=False):
67
85
68
86
69
87
class CIP68UserRFTName (CIP68TokenName ):
88
+ """Validates that an asset name has the 444 label for RFTs."""
70
89
def __init__ (self , data : Union [bytes , str , AssetName ]):
71
90
super ().__init__ (data )
72
91
@@ -82,36 +101,54 @@ class CIP68UserRFTMetadata(TypedDict, total=False):
82
101
83
102
@dataclass
84
103
class CIP68Datum (PlutusData ):
85
- """Wrapper class for CIP-68 metadata to be used as inline datum"""
104
+ """Wrapper class for CIP-68 metadata to be used as inline datum.
105
+
106
+ For detailed information on CIP-68 metadata structure and token types:
107
+ https://github.com/cardano-foundation/CIPs/tree/master/CIP-0068
108
+
109
+ This class wraps metadata dictionaries in a PlutusData class for attaching to a
110
+ reference NFT transaction as an inline datum.
111
+
112
+ Args:
113
+ metadata: A metadata dictionary. TypedDict classes are provided to define required
114
+ fields for each token type.
115
+ version: Metadata version number as 'int'
116
+ extra: Required - must be a PlutusData, or Unit() for empty PlutusData.
117
+
118
+ Example:
119
+ metadata = {
120
+ b"name": b"My NFT",
121
+ b"image": b"ipfs://...",
122
+ b"files": [{"mediaType": b"image/png", "src": b"ipfs://..."}]
123
+ }
124
+ datum = CIP68Datum(metadata=metadata, version=1, extra=Unit())
125
+ """
86
126
CONSTR_ID = 0
87
127
88
128
metadata : Dict [bytes , Any ]
89
129
version : int
90
130
extra : Any # This should be PlutusData or Unit() for empty PlutusData
91
131
92
132
def __post_init__ (self ):
93
- # Convert string keys to bytes in metadata
94
133
converted_metadata : Dict [bytes , Any ] = {}
95
134
for k , v in self .metadata .items ():
96
135
key = k .encode () if isinstance (k , str ) else k
97
- # Handle nested dictionaries (like in files)
98
136
if isinstance (v , dict ):
99
137
v = dict ((k .encode () if isinstance (k , str ) else k , v ) for k , v in v .items ())
100
- # Handle lists of dictionaries (allows multiple files)
101
138
elif isinstance (v , list ):
102
139
v = IndefiniteList ([dict ((k .encode () if isinstance (k , str ) else k , v ) for k , v in item .items ())
103
140
if isinstance (item , dict ) else item for item in v ])
104
141
converted_metadata [key ] = v
105
142
self .metadata = converted_metadata
106
143
107
144
def to_shallow_primitive (self ) -> CBORTag :
145
+ """Wraps PlutusData in 'extra' field in an indefinite list when converted to a CBOR primitive."""
108
146
primitives : Primitive = super ().to_shallow_primitive ()
109
147
if isinstance (primitives , CBORTag ):
110
148
value = primitives .value
111
149
if value :
112
150
extra = value [2 ]
113
151
if isinstance (extra , Unit ):
114
- # Convert Unit to CBORTag with IndefiniteList([])
115
152
extra = CBORTag (121 , IndefiniteList ([]))
116
153
elif isinstance (extra , CBORTag ):
117
154
extra = CBORTag (extra .tag , IndefiniteList (extra .value ))
0 commit comments