Smart Contract

Serialize

A.1e4aa0b87d10b141.Serialize

Valid From

85,982,002

Deployed

1w ago
Feb 16, 2026, 08:14:21 PM UTC

Dependents

0 imports
1import ViewResolver from 0x1d7e57aa55817448
2import MetadataViews from 0x1d7e57aa55817448
3import NonFungibleToken from 0x1d7e57aa55817448
4
5/// This contract is a utility for serializing primitive types, arrays, and common metadata mapping formats to JSON
6/// compatible strings. Also included are interfaces enabling custom serialization for structs and resources.
7///
8/// Special thanks to @austinkline for the idea and initial implementation & @bjartek + @bluesign for optimizations.
9///
10access(all)
11contract Serialize {
12
13    /// Method that returns a serialized representation of the given value or nil if the value is not serializable
14    ///
15    access(all)
16    fun tryToJSONString(_ value: AnyStruct): String? {
17        // Recursively serialize array & return
18        if value.getType().isSubtype(of: Type<[AnyStruct]>()) {
19            return self.arrayToJSONString(value as! [AnyStruct])
20        }
21        // Recursively serialize map & return
22        if value.getType().isSubtype(of: Type<{String: AnyStruct}>()) {
23            return self.dictToJSONString(dict: value as! {String: AnyStruct}, excludedNames: nil)
24        }
25        // Handle primitive types & optionals
26        switch value.getType() {
27            case Type<Never?>():
28                return "\"nil\""
29            case Type<String>():
30                return String.join(["\"", value as! String, "\"" ], separator: "")
31            case Type<String?>():
32                return String.join(["\"", value as? String ?? "nil", "\"" ], separator: "")
33            case Type<Character>():
34                return String.join(["\"", (value as! Character).toString(), "\"" ], separator: "")
35            case Type<Bool>():
36                return String.join(["\"", value as! Bool ? "true" : "false", "\"" ], separator: "")
37            case Type<Address>():
38                return String.join(["\"", (value as! Address).toString(), "\"" ], separator: "")
39            case Type<Address?>():
40                return String.join(["\"", (value as? Address)?.toString() ?? "nil", "\"" ], separator: "")
41            case Type<Int8>():
42                return String.join(["\"", (value as! Int8).toString(), "\"" ], separator: "")
43            case Type<Int16>():
44                return String.join(["\"", (value as! Int16).toString(), "\"" ], separator: "")
45            case Type<Int32>():
46                return String.join(["\"", (value as! Int32).toString(), "\"" ], separator: "")
47            case Type<Int64>():
48                return String.join(["\"", (value as! Int64).toString(), "\"" ], separator: "")
49            case Type<Int128>():
50                return String.join(["\"", (value as! Int128).toString(), "\"" ], separator: "")
51            case Type<Int256>():
52                return String.join(["\"", (value as! Int256).toString(), "\"" ], separator: "")
53            case Type<Int>():
54                return String.join(["\"", (value as! Int).toString(), "\"" ], separator: "")
55            case Type<UInt8>():
56                return String.join(["\"", (value as! UInt8).toString(), "\"" ], separator: "")
57            case Type<UInt16>():
58                return String.join(["\"", (value as! UInt16).toString(), "\"" ], separator: "")
59            case Type<UInt32>():
60                return String.join(["\"", (value as! UInt32).toString(), "\"" ], separator: "")
61            case Type<UInt64>():
62                return String.join(["\"", (value as! UInt64).toString(), "\"" ], separator: "")
63            case Type<UInt128>():
64                return String.join(["\"", (value as! UInt128).toString(), "\"" ], separator: "")
65            case Type<UInt256>():
66                return String.join(["\"", (value as! UInt256).toString(), "\"" ], separator: "")
67            case Type<UInt>():
68                return String.join(["\"", (value as! UInt).toString(), "\"" ], separator: "")
69            case Type<Word8>():
70                return String.join(["\"", (value as! Word8).toString(), "\"" ], separator: "")
71            case Type<Word16>():
72                return String.join(["\"", (value as! Word16).toString(), "\"" ], separator: "")
73            case Type<Word32>():
74                return String.join(["\"", (value as! Word32).toString(), "\"" ], separator: "")
75            case Type<Word64>():
76                return String.join(["\"", (value as! Word64).toString(), "\"" ], separator: "")
77            case Type<Word128>():
78                return String.join(["\"", (value as! Word128).toString(), "\"" ], separator: "")
79            case Type<Word256>():
80                return String.join(["\"", (value as! Word256).toString(), "\"" ], separator: "")
81            case Type<UFix64>():
82                return String.join(["\"", (value as! UFix64).toString(), "\"" ], separator: "")
83            default:
84                return nil
85        }
86    }
87
88    /// Returns a serialized representation of the given array or nil if the value is not serializable
89    ///
90    access(all)
91    fun arrayToJSONString(_ arr: [AnyStruct]): String? {
92        let parts: [String]= []
93        for element in arr {
94            let serializedElement = self.tryToJSONString(element)
95            if serializedElement == nil {
96                continue
97            }
98            parts.append(serializedElement!)
99        }
100        return "[".concat(String.join(parts, separator: ", ")).concat("]")
101    }
102
103    /// Returns a serialized representation of the given String-indexed mapping or nil if the value is not serializable.
104    /// The interface here is largely the same as as the `MetadataViews.dictToTraits` method, though here
105    /// a JSON-compatible String is returned instead of a `Traits` array.
106    ///
107    access(all)
108    fun dictToJSONString(dict: {String: AnyStruct}, excludedNames: [String]?): String? {
109        if excludedNames != nil {
110            for k in excludedNames! {
111                dict.remove(key: k)
112            }
113        }
114        let parts: [String] = []
115        for key in dict.keys {
116            let serializedValue = self.tryToJSONString(dict[key]!)
117            if serializedValue == nil {
118                continue
119            }
120            let serialializedKeyValue = String.join([self.tryToJSONString(key)!, serializedValue!], separator: ": ")
121            parts.append(serialializedKeyValue)
122        }
123        return "{".concat(String.join(parts, separator: ", ")).concat("}")
124    }
125}
126