Dubhe Client SDK for Sui
Before getting started with Dubhe Client SDK, please install the required dependencies:
pnpm install @0xobelisk/sui-client @0xobelisk/sui-common
Note: @0xobelisk/sui-common contains essential configuration type definitions like DubheConfig, which are necessary for contract development.
Dubhe is a client-agnostic SDK that supports various platforms including browsers, Node.js, and the COCOS game engine. It provides a simple interface to interact with your Sui Move contracts.
Getting Started
Prerequisites
Before using the SDK, make sure you have:
- Created and deployed your contract using the Dubhe CLI
- Obtained the
packageId
after deployment
Data Model Setup
First, define your contract’s configuration using DubheConfig
:
import { DubheConfig } from "@0xobelisk/sui-common";
export const dubheConfig = {
name: "counter",
description: "counter",
systems: ["counter"],
schemas: {
counter: {
structure: {
value: "StorageValue<u32>",
},
},
},
} as DubheConfig;
Generate the contract code using CLI:
pnpm dubhe schemagen
Initializing the Client
There are two ways to initialize the Dubhe client:
- Using dynamic metadata loading:
import { loadMetadata, Dubhe, NetworkType } from "@0xobelisk/sui-client";
const network = "devnet" as NetworkType;
const packageId = "YOUR_PACKAGE_ID";
const metadata = await loadMetadata(network, packageId);
const dubhe = new Dubhe({
networkType: network,
packageId: packageId,
metadata: metadata,
secretKey: privkey,
});
- Using pre-saved metadata (recommended for better performance):
import metadata from "./metadata.json";
const dubhe = new Dubhe({
networkType: network,
packageId: packageId,
metadata: metadata,
secretKey: privkey,
});
Executing Transactions
To call contract methods:
import { Transaction } from "@0xobelisk/sui-client";
// Create transaction
const tx = new Transaction();
// Execute transaction with struct parameters
const response = await dubhe.tx.counter_system.inc({
tx,
params: [
/* your parameters */
],
typeArguments: ["0x2::coin::Coin<0x2::sui::SUI>"], // optional
isRaw: false, // optional, defaults to false
});
// For wallet integration
const walletTx = await dubhe.tx.counter_system.inc({
tx,
params: [
/* your parameters */
],
typeArguments: [],
isRaw: true,
});
const response = await dubhe.signAndSendTxn(walletTx);
Querying Data
To query contract state:
// Create transaction
const tx = new Transaction();
// Query with struct parameters
const result = await dubhe.query.counter_system.get({
tx,
params: [
/* your parameters */
],
typeArguments: [], // optional
isRaw: false, // optional
});
// For BCS encoded results
const decodedData = dubhe.view(result);
Parameter Structure
Both query and transaction methods accept a parameter structure with the following fields:
{
tx: Transaction; // Required: Transaction instance
params?: TransactionArg[]; // Optional: Array of transaction arguments
typeArguments?: string[]; // Optional: Generic type arguments
isRaw?: boolean; // Optional: Return raw transaction instead of executing
}
Example Usage
Here are some practical examples:
// Simple query without parameters
const tx1 = new Transaction();
const query1 = await dubhe.query.funt.get_u8({
tx: tx1,
});
const data1 = dubhe.view(query1);
// Query with parameters
const tx2 = new Transaction();
const query2 = await dubhe.query.funt.get_struct({
tx: tx2,
params: [
/* parameters */
],
typeArguments: ["0x2::coin::Coin<0x2::sui::SUI>"],
});
const data2 = dubhe.view(query2);
// Transaction with raw output
const tx3 = new Transaction();
const rawTx = await dubhe.tx.example_system.increase({
tx: tx3,
params: [tx3.pure("0x123...")],
isRaw: true,
});
const response = await dubhe.signAndSendTxn(rawTx);
BCS Data Decoding
The SDK provides a view()
method to decode BCS-encoded return values from contract queries.
For detailed examples and advanced usage of querying data, please refer to our Query With Client Guide.
Supported Types
- Basic types (u8, u16, u32, u64, u128, u256)
- Boolean
- String
- Vector
- Struct
- Option
- Custom objects
Example with Complex Types
// Example contract return type
struct GameState {
score: u64,
player_name: String,
is_active: bool,
items: vector<Item>
}
// Query and decode
const tx = new Transaction();
const result = await dubhe.query.game_system.get_state(tx, params);
const decodedState = dubhe.view(result);
Known Limitations
⚠️ Important Note:
- The current implementation cannot automatically decode enum types due to limitations in Sui metadata.
- Some complex nested structures might require additional handling.
Query Owned Objects
To query objects owned by a specific address:
const owner =
"0xfa99b5b0463fcfb7d0203c701a76da5eda21a96190eb1368ab36a437cc89195e";
const ownedObjects = await dubhe.getOwnedObjects(owner);
Querying Schema State
To query the state of schema fields defined in your Dubhe config:
const result = await dubhe.state({
schema: "counter", // Schema name from your Dubhe config
field: "value", // Field name within the schema
objectId: "0x123...", // Object ID of the schema instance
storageType: "StorageValue<u64>", // Storage type of the field
params: [], // Parameters for StorageMap/StorageDoubleMap keys
});
The state()
method supports three storage types:
StorageValue<V>
- For single value storage
// Query a simple storage value
const value = await dubhe.state({
schema: "player",
field: "score",
objectId: "0x123...",
storageType: "StorageValue<u64>",
params: [], // No params needed for StorageValue
});
StorageMap<K,V>
- For key-value map storage
// Query a value from storage map
const mapValue = await dubhe.state({
schema: "inventory",
field: "items",
objectId: "0x123...",
storageType: "StorageMap<address,u64>",
params: ["0x456..."], // Key to look up in the map
});
StorageDoubleMap<K1,K2,V>
- For double key-value map storage
// Query a value from double map
const doubleMapValue = await dubhe.state({
schema: "game",
field: "scores",
objectId: "0x123...",
storageType: "StorageDoubleMap<address,u64,u64>",
params: ["0x456...", 42], // Two keys needed for double map
});
Supported Key Types
The following key types are supported for StorageMap and StorageDoubleMap:
- Basic types:
u8
,u16
,u32
,u64
,u128
,u256
,bool
address
- Custom object types (format:
package::module::type
)
Error Handling
The method will throw an error if:
- Invalid storage type format is provided
- Wrong number of parameters for the storage type
- Unsupported key type is used
- Schema or field doesn’t exist
- Object ID is invalid
Best Practices
- Use pre-saved metadata for better performance in production
- Implement proper error handling for BCS decoding
- Consider the limitations of enum type handling when designing your contract return types
Support
For more information or support, please visit our GitHub repository or join our community channels.