SuiKit - Swift / iOS Sui SDK
Question:
- We have developed a fully featured Swift SDK, and have encountered some bugs on our SDK when replicating the end-to-end test from the TypeScript. Particularly around TransactionBlock and TransactionBlockData and BCS encoding.
- Would like to review TransactionBlock and TransactionBlockData implementation.
Discussion
- https://github.com/opendive/suikit, https://docs.google.com/document/d/14y-uZa2BDM1adQ5SVAnNZ2TS-sN3ME7LSaWeLNL-IWU/edit
- want to use enclaves to sign transactions. for the txn builder and using the txn block data and serializing, the BCS implementation gives a different output than expected. May relate to the size of the actual output.
- overview on the BCS writer on how serialization and deserialization happen. are you able to serialize/deserialize locally? what is the error message? looked at Libra implementation and wrote their own based on this. implementation. Should not be difference between the canonical one and the Sui ones.
- when building the builder, everything for the transaction is attached. noticed a max size that was not in the canonical implementation. max size is not part of the BCS implementation as BCS allows arbitrary size. however the RPC itself has limits on how large it is. The SDK checks this on the client side to make sure that it fits in the RPC.
- there is a lot of typescript magic to optimize for a better javascript building experience. The Rust implementation may be preferable. Rust is much more strictly typed (eg struct, enum)and easier to follow. Ordering matters in Rust, but not in Typescript, so when using Typescript, the order in which data is serialized might not match what you see in the serialized data. The Swift implementation has a different order for the enum which would be an issue. A struct is a sequence of content. Enum has the first order byte then the content which allows switching. If enum orders are switched, the BCS will do the wrong things. Order of fields in the struct are also important. The Swift implementation also looks out of order.
- BCS wrapper in TS has a notion of registration. One cannot translate Javascript into strong Rust types. Registration provides the mapping for the final enum shape since JS is more dynamic. For StarCoin and Aptos these seem cleaner. Registration works for TS, but is not meant for statically defined languages.
- NB: Address and vec<u8> are different things. A vec<u8> is prefixed with length. See the SuiAddress type in Rust for some context here. When Pure argument is passed to BCS, the serialization does not know its type.
- All Pure args need to be BCS serialized. To do that in an untyped language would need to know the type. Say DevInspect a struct needs to be passed as Pure inputs. Would need to know the schema for the struct. The SDKs finds all the functions being called, what the types need to be, and serialized as input. All transactionKind transactions are parsed.
- CSharp implementation for StarCoin and Aptos, allows each Move type to pass a serializer object. u8.serialize, it automatically dumps out the output bytes. In Sui an external writer is needed as the types does not know how to serialize itself. Inputs for txns are not types for Typescript but types for Move that exist on chain, hence are not known statically. https://github.com/aptos-labs/Aptos-Unity-SDK/tree/main/Assets/Aptos-Unity-SDK/Code/Aptos.BCS
- In Solana one generates an IDL which creates a mini-library to work with the object or contract. Use the IDL to generate a set of C Sharp classes. There is a project by KKlas called sui client gen but without the IDL, and primarily works off the Move package. Also working on packaging the canonical BCS implementation into a C library. Just supply the name of the types and JSON representation, and will get out the raw bytes. It is a local C library one would link into the SDK. How would this work for Unity? Would be happy to give feedback as Swift and Unity have some complexities for linking C libraries, so would need bindings. Can look in Rust for “derive Serialize”.
- Rust SDK documentation just landed recently. SDK should provide an interface that custom types can adhere to.
Noted Areas of Improvement
- Ordering constraints should be documented in the RPC endpoint documentation, possibly also in the TS/Rust SDKs.
SuiAddress vs vec<u8> / Pure arg serialization issues maybe also should be documented, since this is something that has come up in a few office hours. This will be documented when the new docsite goes live.
- Should there be a native Python implementation of BCS?