sui_sdk_types/
lib.rs

1//! Core type definitions for the [Sui] blockchain.
2//!
3//! [Sui] is a next-generation smart contract platform with high throughput, low latency, and an
4//! asset-oriented programming model powered by the Move programming language. This crate provides
5//! type definitions for working with the data that makes up the [Sui] blockchain.
6//!
7//! [Sui]: https://sui.io
8//!
9//! # Feature flags
10//!
11//! This library uses a set of [feature flags] to reduce the number of dependencies and amount of
12//! compiled code. By default, no features are enabled which allows one to enable a subset
13//! specifically for their use case. Below is a list of the available feature flags.
14//!
15//! - `serde`: Enables support for serializing and deserializing types to/from BCS utilizing [serde]
16//!   library.
17//! - `rand`: Enables support for generating random instances of a number of types via the [rand]
18//!   library.
19//! - `hash`: Enables support for hashing, which is required for deriving addresses and calculating
20//!   digests for various types.
21//! - `proptest`: Enables support for the [proptest] library by providing implementations of
22//!   [proptest::arbitrary::Arbitrary] for many types.
23//!
24//! [feature flags]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-features-section
25//! [serde]: https://docs.rs/serde
26//! [rand]: https://docs.rs/rand
27//! [proptest]: https://docs.rs/proptest
28//! [proptest::arbitrary::Arbitrary]: https://docs.rs/proptest/latest/proptest/arbitrary/trait.Arbitrary.html
29//!
30//! # BCS
31//!
32//! [BCS] is the serialization format used to represent the state of the blockchain and is used
33//! extensively throughout the Sui ecosystem. In particular the BCS format is leveraged because it
34//! _"guarantees canonical serialization, meaning that for any given data type, there is a
35//! one-to-one correspondence between in-memory values and valid byte representations."_ One
36//! benefit of this property of having a canonical serialized representation is to allow different
37//! entities in the ecosystem to all agree on how a particular type should be interpreted and more
38//! importantly define a deterministic representation for hashing and signing.
39//!
40//! This library strives to guarantee that the types defined are fully BCS-compatible with the data
41//! that the network produces. The one caveat to this would be that as the Sui protocol evolves,
42//! new type variants are added and older versions of this library may not support those newly
43//! added variants. The expectation is that the most recent release of this library will support
44//! new variants and types as they are released to Sui's `testnet` network.
45//!
46//! See the documentation for the various types defined by this crate for a specification of their
47//! BCS serialized representation which will be defined using ABNF notation as described by
48//! [RFC-5234]. In addition to the format itself, some types have an extra layer of verification
49//! and may impose additional restrictions on valid byte representations above and beyond those
50//! already provided by BCS. In these instances the documentation for those types will clearly
51//! specify these additional restrictions.
52//!
53//! Here are some common rules:
54//!
55//! ```text
56//! ; --- BCS Value ---
57//! bcs-value           = bcs-struct / bcs-enum / bcs-length-prefixed / bcs-fixed-length
58//! bcs-length-prefixed = bytes / string / vector / option
59//! bcs-fixed-length    = u8 / u16 / u32 / u64 / u128 /
60//!                       i8 / i16 / i32 / i64 / i128 /
61//!                       boolean
62//! bcs-struct          = *bcs-value                ; Sequence of serialized fields
63//! bcs-enum            = uleb128-index bcs-value   ; Enum index and associated value
64//!
65//! ; --- Length-prefixed types ---
66//! bytes           = uleb128 *OCTET          ; Raw bytes of the specified length
67//! string          = uleb128 *OCTET          ; valid utf8 string of the specified length
68//! vector          = uleb128 *bcs-value      ; Length-prefixed list of values
69//! option          = %x00 / (%x01 bcs-value) ; optional value
70//!
71//! ; --- Fixed-length types ---
72//! u8          = OCTET                     ; 1-byte unsigned integer
73//! u16         = 2OCTET                    ; 2-byte unsigned integer, little-endian
74//! u32         = 4OCTET                    ; 4-byte unsigned integer, little-endian
75//! u64         = 8OCTET                    ; 8-byte unsigned integer, little-endian
76//! u128        = 16OCTET                   ; 16-byte unsigned integer, little-endian
77//! i8          = OCTET                     ; 1-byte signed integer
78//! i16         = 2OCTET                    ; 2-byte signed integer, little-endian
79//! i32         = 4OCTET                    ; 4-byte signed integer, little-endian
80//! i64         = 8OCTET                    ; 8-byte signed integer, little-endian
81//! i128        = 16OCTET                   ; 16-byte signed integer, little-endian
82//! boolean     = %x00 / %x01               ; Boolean: 0 = false, 1 = true
83//! array       = *(bcs-value)              ; Fixed-length array
84//!
85//! ; --- ULEB128 definition ---
86//! uleb128         = 1*5uleb128-byte       ; Variable-length ULEB128 encoding
87//! uleb128-byte    = %x00-7F / %x80-FF     ; ULEB128 continuation rules
88//! uleb128-index   = uleb128               ; ULEB128-encoded variant index
89//! ```
90//!
91//! [BCS]: https://docs.rs/bcs
92//! [RFC-5234]: https://datatracker.ietf.org/doc/html/rfc5234
93
94#![cfg_attr(doc_cfg, feature(doc_cfg))]
95// TODO finish documenting all public items
96// #![warn(missing_docs)]
97
98mod address;
99mod checkpoint;
100mod crypto;
101mod digest;
102mod effects;
103mod events;
104mod execution_status;
105pub mod framework;
106mod gas;
107mod object;
108mod transaction;
109mod type_tag;
110mod u256;
111
112#[cfg(feature = "hash")]
113#[cfg_attr(doc_cfg, doc(cfg(feature = "hash")))]
114pub mod hash;
115
116pub use address::Address;
117pub use address::AddressParseError;
118pub use checkpoint::CheckpointCommitment;
119pub use checkpoint::CheckpointContents;
120pub use checkpoint::CheckpointData;
121pub use checkpoint::CheckpointSequenceNumber;
122pub use checkpoint::CheckpointSummary;
123pub use checkpoint::CheckpointTimestamp;
124pub use checkpoint::CheckpointTransaction;
125pub use checkpoint::CheckpointTransactionInfo;
126pub use checkpoint::EndOfEpochData;
127pub use checkpoint::EpochId;
128pub use checkpoint::ProtocolVersion;
129pub use checkpoint::SignedCheckpointSummary;
130pub use checkpoint::StakeUnit;
131pub use crypto::Bls12381PublicKey;
132pub use crypto::Bls12381Signature;
133pub use crypto::Bn254FieldElement;
134pub use crypto::CircomG1;
135pub use crypto::CircomG2;
136pub use crypto::Ed25519PublicKey;
137pub use crypto::Ed25519Signature;
138pub use crypto::Intent;
139pub use crypto::IntentAppId;
140pub use crypto::IntentScope;
141pub use crypto::IntentVersion;
142pub use crypto::InvalidZkLoginAuthenticatorError;
143pub use crypto::Jwk;
144pub use crypto::JwkId;
145pub use crypto::MultisigAggregatedSignature;
146pub use crypto::MultisigCommittee;
147pub use crypto::MultisigMember;
148pub use crypto::MultisigMemberPublicKey;
149pub use crypto::MultisigMemberSignature;
150pub use crypto::PasskeyAuthenticator;
151pub use crypto::PasskeyPublicKey;
152pub use crypto::Secp256k1PublicKey;
153pub use crypto::Secp256k1Signature;
154pub use crypto::Secp256r1PublicKey;
155pub use crypto::Secp256r1Signature;
156pub use crypto::SignatureScheme;
157pub use crypto::SimpleSignature;
158pub use crypto::UserSignature;
159pub use crypto::ValidatorAggregatedSignature;
160pub use crypto::ValidatorCommittee;
161pub use crypto::ValidatorCommitteeMember;
162pub use crypto::ValidatorSignature;
163pub use crypto::ZkLoginAuthenticator;
164pub use crypto::ZkLoginClaim;
165pub use crypto::ZkLoginInputs;
166pub use crypto::ZkLoginProof;
167pub use crypto::ZkLoginPublicIdentifier;
168pub use digest::Digest;
169pub use digest::DigestParseError;
170pub use digest::SigningDigest;
171pub use effects::ChangedObject;
172pub use effects::IdOperation;
173pub use effects::ModifiedAtVersion;
174pub use effects::ObjectIn;
175pub use effects::ObjectOut;
176pub use effects::ObjectReferenceWithOwner;
177pub use effects::TransactionEffects;
178pub use effects::TransactionEffectsV1;
179pub use effects::TransactionEffectsV2;
180pub use effects::UnchangedConsensusKind;
181pub use effects::UnchangedConsensusObject;
182pub use events::BalanceChange;
183pub use events::Event;
184pub use events::TransactionEvents;
185pub use execution_status::CommandArgumentError;
186pub use execution_status::ExecutionError;
187pub use execution_status::ExecutionStatus;
188pub use execution_status::MoveLocation;
189pub use execution_status::PackageUpgradeError;
190pub use execution_status::TypeArgumentError;
191pub use gas::GasCostSummary;
192pub use object::GenesisObject;
193pub use object::MovePackage;
194pub use object::MoveStruct;
195pub use object::Object;
196pub use object::ObjectData;
197pub use object::ObjectReference;
198pub use object::ObjectType;
199pub use object::Owner;
200pub use object::TypeOrigin;
201pub use object::UpgradeInfo;
202pub use object::Version;
203pub use transaction::ActiveJwk;
204pub use transaction::Argument;
205pub use transaction::AuthenticatorStateExpire;
206pub use transaction::AuthenticatorStateUpdate;
207pub use transaction::CanceledTransaction;
208pub use transaction::CanceledTransactionV2;
209pub use transaction::ChangeEpoch;
210pub use transaction::Command;
211pub use transaction::ConsensusCommitPrologue;
212pub use transaction::ConsensusCommitPrologueV2;
213pub use transaction::ConsensusCommitPrologueV3;
214pub use transaction::ConsensusCommitPrologueV4;
215pub use transaction::ConsensusDeterminedVersionAssignments;
216pub use transaction::EndOfEpochTransactionKind;
217pub use transaction::ExecutionTimeObservationKey;
218pub use transaction::ExecutionTimeObservations;
219pub use transaction::GasPayment;
220pub use transaction::GenesisTransaction;
221pub use transaction::Input;
222pub use transaction::MakeMoveVector;
223pub use transaction::MergeCoins;
224pub use transaction::MoveCall;
225pub use transaction::ProgrammableTransaction;
226pub use transaction::Publish;
227pub use transaction::RandomnessStateUpdate;
228pub use transaction::SignedTransaction;
229pub use transaction::SplitCoins;
230pub use transaction::SystemPackage;
231pub use transaction::Transaction;
232pub use transaction::TransactionExpiration;
233pub use transaction::TransactionKind;
234pub use transaction::TransferObjects;
235pub use transaction::Upgrade;
236pub use transaction::ValidatorExecutionTimeObservation;
237pub use transaction::VersionAssignment;
238pub use transaction::VersionAssignmentV2;
239pub use type_tag::Identifier;
240pub use type_tag::StructTag;
241pub use type_tag::TypeParseError;
242pub use type_tag::TypeTag;
243
244#[cfg(feature = "serde")]
245#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
246pub(crate) use transaction::SignedTransactionWithIntentMessage;
247
248#[cfg(test)]
249mod serialization_proptests;
250
251#[derive(Clone, Debug, PartialEq, Eq)]
252pub struct PersonalMessage<'a>(pub std::borrow::Cow<'a, [u8]>);
253
254#[cfg(feature = "serde")]
255mod _serde {
256    use base64ct::Base64;
257    use base64ct::Encoding;
258    use serde::Deserialize;
259    use serde::Deserializer;
260    use serde::Serialize;
261    use serde::Serializer;
262    use serde_with::Bytes;
263    use serde_with::DeserializeAs;
264    use serde_with::SerializeAs;
265    use std::borrow::Cow;
266
267    pub(crate) type ReadableBase64Encoded =
268        ::serde_with::As<::serde_with::IfIsHumanReadable<Base64Encoded, ::serde_with::Bytes>>;
269
270    pub(crate) struct Base64Encoded;
271
272    impl<T: AsRef<[u8]>> SerializeAs<T> for Base64Encoded {
273        fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
274        where
275            S: Serializer,
276        {
277            let bytes = source.as_ref();
278            let b64 = Base64::encode_string(bytes);
279            b64.serialize(serializer)
280        }
281    }
282
283    impl<'de, T: TryFrom<Vec<u8>>> DeserializeAs<'de, T> for Base64Encoded {
284        fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
285        where
286            D: Deserializer<'de>,
287        {
288            let b64: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
289            let bytes = Base64::decode_vec(&b64).map_err(serde::de::Error::custom)?;
290            let length = bytes.len();
291            T::try_from(bytes).map_err(|_| {
292                serde::de::Error::custom(format_args!(
293                    "Can't convert a Byte Vector of length {length} to the output type."
294                ))
295            })
296        }
297    }
298
299    /// Serializes a bitmap according to the roaring bitmap on-disk standard.
300    /// <https://github.com/RoaringBitmap/RoaringFormatSpec>
301    pub(crate) struct BinaryRoaringBitmap;
302
303    impl SerializeAs<roaring::RoaringBitmap> for BinaryRoaringBitmap {
304        fn serialize_as<S>(
305            source: &roaring::RoaringBitmap,
306            serializer: S,
307        ) -> Result<S::Ok, S::Error>
308        where
309            S: Serializer,
310        {
311            let mut bytes = vec![];
312
313            source
314                .serialize_into(&mut bytes)
315                .map_err(serde::ser::Error::custom)?;
316            Bytes::serialize_as(&bytes, serializer)
317        }
318    }
319
320    impl<'de> DeserializeAs<'de, roaring::RoaringBitmap> for BinaryRoaringBitmap {
321        fn deserialize_as<D>(deserializer: D) -> Result<roaring::RoaringBitmap, D::Error>
322        where
323            D: Deserializer<'de>,
324        {
325            let bytes: Cow<'de, [u8]> = Bytes::deserialize_as(deserializer)?;
326            roaring::RoaringBitmap::deserialize_from(&bytes[..]).map_err(serde::de::Error::custom)
327        }
328    }
329
330    pub(crate) struct Base64RoaringBitmap;
331
332    impl SerializeAs<roaring::RoaringBitmap> for Base64RoaringBitmap {
333        fn serialize_as<S>(
334            source: &roaring::RoaringBitmap,
335            serializer: S,
336        ) -> Result<S::Ok, S::Error>
337        where
338            S: Serializer,
339        {
340            let mut bytes = vec![];
341
342            source
343                .serialize_into(&mut bytes)
344                .map_err(serde::ser::Error::custom)?;
345            let b64 = Base64::encode_string(&bytes);
346            b64.serialize(serializer)
347        }
348    }
349
350    impl<'de> DeserializeAs<'de, roaring::RoaringBitmap> for Base64RoaringBitmap {
351        fn deserialize_as<D>(deserializer: D) -> Result<roaring::RoaringBitmap, D::Error>
352        where
353            D: Deserializer<'de>,
354        {
355            let b64: Cow<'de, str> = Deserialize::deserialize(deserializer)?;
356            let bytes = Base64::decode_vec(&b64).map_err(serde::de::Error::custom)?;
357            roaring::RoaringBitmap::deserialize_from(&bytes[..]).map_err(serde::de::Error::custom)
358        }
359    }
360
361    pub(crate) use super::SignedTransactionWithIntentMessage;
362}
363
364// declare `roaring` as a public dependency (for the moment) since its currently exposed in a few
365// types
366#[doc(hidden)]
367pub use roaring;