The OpenDive Sui Unity SDK is the first fully-featured Unity SDK with offline transaction building.
This means that games built with our SDK can directly craft custom Move calls without relying Sui's "unsafe" RPC calls under the Transaction Builder API -- which in turn reduces the number of RPC / Network requests.
Our SDK fully supports mobile, desktop and WebGL application built with the Unity game engine.
About the Project
Sui-Unity-SDK is a C# Unity SDK designed to provide Unity developers with a seamless and efficient way to interact with the Sui Blockchain. Our aim is to lower the barrier for Unity developers, enabling them to leverage and integrate Sui's vast and versatile ecosystem into their games without having to delve deep into the complexities of the ecosystem.
Features
Make Account Transfer Quickly and Easily!
With how easy the library is to use, Sui-Unity-SDK gives you the power to quickly setup a Sui account and be able to transfer coins in only a few lines of code:
// Initialize Accounts.Account alice =newAccount();Account bob =newAccount();// Initialize Client and Transaction BlockSuiClient client =newSuiClient(Constants.LocalnetConnection);TransactionBlock tx_block =newTransactionBlock();// Call Transfer Objectstx_block.AddTransferObjectsTx(newSuiTransactionArgument[] { tx_block.gas },bob.SuiAddress());// Call SignAndExecuteTransactionBlockAsyncRpcResult<TransactionBlockResponse> published_tx_block =awaitclient.SignAndExecuteTransactionBlockAsync( tx_block, alice);// Return the TransactionBlockResponsereturnpublished_tx_block.Result;
Download the latest sui-unity-sdk-xx.unitypackage file from Release
Inside Unity, Click on Assets → Import Packages → Custom Package. and select the downloaded file.
NOTE: As of Unity 2021.x.x, Newtonsoft Json is a common dependency. Prior versions of Unity require installing Newtonsoft.
Test Suite
The SDK's test suite can be found in the following directory: Assets/Sui-Unity-SDK/Tests.
The test suite covers:
Account - private / public keys, signatures and verification
Transactions - creation, signing, serialization, and deserialization
Coin Querying
Extended API
Governance API
Move Utilities
Read API
Write API
BCS serialization and deserialization
Using Sui-Unity-SDK
Sui-Unity-SDK is designed to be very easy to integrate into your own Unity projects. The main functionality comes from several key classes: SuiClient, FacetClient, TransactionBlock, and Account.
There are four core classes:
SuiClient - used to query the Sui blockchain
FaucetClient - used to request for airdrops
TransactionBlock - used to represent a transaction block object
Account - used for representing sui accounts
SuiClient
The RPC Client provides you with the fundamental transaction endpoints needed for interacting with the Sui Blockchain. The following showcases how to initialize the SuiClient.
// Initialize Client with a local network connectionSuiClient client =newSuiClient(Constants.LocalnetConnection);
As shown before, it only take a few lines of code to initialize a transfer for Sui coins. This is the main class developers will be leveraging to interact directly with the Sui Blockchain via RPC Client calls. Here's another example showing how to publish a package:
// Initialize AccountAccount alice =newAccount();// Initialize Client and Transaction BlockSuiClient client =newSuiClient(Constants.LocalnetConnection);TransactionBlock tx_block =newTransactionBlock();// Initialize Modules and Dependencies//// Note: Please utilize an outside tool for// importing compiled packages as JSON files.string[] modules =newstring[] { "MODULE-BASE-64" };string[] dependencies =newstring[] { "DEPENDENCIES-HEXADECIMAL" };// Call Publish and Transfer ObjectList<SuiTransactionArgument> cap =tx_block.AddPublishTx( modules, dependencies);tx_block.AddTransferObjectsTx(cap.ToArray(),alice.SuiAddress());// Call SignAndExecuteTransactionBlockAsyncRpcResult<TransactionBlockResponse> published_tx_block = await this.Client.SignAndExecuteTransactionBlockAsync(tx_block, alice);
// Return the TransactionBlockResponsereturnpublished_tx_block.Result;
Here's also how to do various other calls:
// Initialize AccountAccount alice =newAccount();// Initialize Client and coinsSuiClient client =newSuiClient(Constants.LocalnetConnection);SuiStructTag sui_coin =newSuiStructTag("0x2::sui::SUI");SuiStructTag coin =newSuiStructTag("0x2::coin::Coin");// Get coin metadata and print the nameRpcResult<CoinMetadata> coin_metadata =awaitclient.GetCoinMetadataAsync(sui_coin);Debug.Log($"Sui coin name: {coin_metadata.Name}");// Get account balanceRpcResult<Balance> alice_balance =awaitclient.GetBalanceAsync(alice, sui_coin);Debug.Log($"Alice's current Sui coin balance: {alice_balance.TotalBalance}'");// Get coinRpcResult<CoinPage> alice_sui_coins =awaitclient.GetCoinsAsync(alice, sui_coin);Debug.Log($"Alice's Sui coin object ID - {alice_sui_coins.Result.Data[0].CoinObjectID.ToString()}");// Get Move structsRpcResult<SuiMoveNormalizedStruct> coin_move_struct =awaitclient.GetNormalizedMoveStructAsync( coin_struct);Debug.Log($"Coin struct fields: {Utils.ToReadableString(coin_move_struct.Fields)}");// Get ObjectsCoinDetails gas_coin =alice_sui_coins.Result.Data[0];ObjectData details =gas_coin.ToSuiObjectData();RpcResult<ObjectDataResponse> coin_object =awaitclient.GetObjectAsync(details.ObjectID);Debug.Log($"Sui coin object type: {coin_object.Result.Data.Type.ToString()}");
FaucetClient
The Faucet Client allows the developer to leverage the ability to fund wallets on any of the non-main networks within the Sui Blockchain. This can easily speed up development times through automating the process of funding accounts. Here's an example on how to use the Faucet Client:
// Initialize AccountAccount alice =Account.Generate();// Initialize Funding RequestFaucetClient faucet =newFaucetClient(Constants.LocalnetConnection);bool result =awaitfaucet.AirdropGasAsync(alice.SuiAddress());
TransactionBlock
The Transaction Block is a local object that helps developers build out the serialized representation of transaction data. This is the core of utilizing offline transaction building, along with building out interactions with on-chain objects. Here is an example to build out a simple Move call:
// Initialize AccountAccount alice =Account.Generate();// Initialize a transaction blockTransactionBlock tx_block =newTransactionBlock();// Call to create a Move calltx_block.AddMoveCallTx(SuiMoveNormalizedStructType.FromStr("0x2::pay::split"),newSerializableTypeTag[] { newSerializableTypeTag("0x2::sui::SUI") },newSuiTransactionArgument[] {tx_block.AddObjectInput("COIN-OBJECT-ID"),// Insert coin object ID heretx_block.AddPure(newU64(100)) // Insert split amount here });// Sign and execute transaction blockTask<RpcResult<TransactionBlockResponse>> result_task =client.SignAndExecuteTransactionBlockAsync( tx_block, alice);
As well, developers can utilize any arbitrary move calls published to the network. Here is an example using a serializer to set a value:
// Initialize AccountAccount alice =Account.Generate();// Initialize a transaction blockTransactionBlock tx_block =newTransactionBlock();string package_id ="PACKAGE-ID"; // Insert Package ID here// Call to create a Move call, specifically setting a valuetx_block.AddMoveCallTx(SuiMoveNormalizedStructType.FromStr($"{package_id}::serializer_tests::value"),newSerializableTypeTag[] { },newSuiTransactionArgument[] {tx_block.AddObjectInput("SHARED-OBJECT-ID") // Insert shared object ID here });tx_block.AddMoveCallTx(SuiMoveNormalizedStructType.FromStr($"{package_id}::serializer_tests::set_value"),newSerializableTypeTag[] { },newSuiTransactionArgument[] {tx_block.AddObjectInput("SHARED-OBJECT-ID") // Insert shared object ID here });// Sign and execute transaction blockTask<RpcResult<TransactionBlockResponse>> result_task =client.SignAndExecuteTransactionBlockAsync( tx_block, alice);
Account
Accounts within the SDK represent a Sui user's account, that give ease of access to the needed information you'd need for communicating with the Sui Blockchain. Here are some example initializations of accounts:
// Generate Random Accountalice =Account.Generate();// Initialize Account Using Hexadecimal Private Keyconststring PrivateKeyHex ="0x64f57603b58af16907c18a866123286e1cbce89790613558dc1775abb3fc5c8c";bob =Account.LoadKey(PrivateKeyHex);// Initialize Account Using Private and Public Key Bytesprivatestaticreadonlybyte[] PrivateKeyBytes = {100,245,118,3,181,138,241,105,7,193,138,134,97,35,40,110,28,188,232,151,144,97,53,88,220,23,117,171,179,252,92,140};privatestaticreadonlybyte[] PublicKeyBytes = {88,110,60,141,68,125,118,121,34,46,19,144,51,227,130,2,53,227,61,165,9,30,155,11,184,241,161,18,207,12,143,245};// Initialize the accountAccount chad =newAccount(PrivateKeyBytes, PublicKeyBytes);
From there, you're able to retrieve the byte array of the private and public keys, along with signing and verifying messages and transactions, as the core function of an Account object, as shown here:
The developer can now use the Account to sign various messages and transactions for interacting with the Sui Blockchain, as shown here:
// Create a Signature Object Storing the Signature of the Signed Messageprivatestaticreadonlybyte[] MessageUt8Bytes = {87,69,76,67,79,77,69,32,84,79,32,65,80,84,79,83,33};SignatureBase signature =privateKey.Sign(MessageUt8Bytes);
Developers can also verify the integrity of the message using the public key, as shown here: