SDK Setup
Before you can build Programmable Transaction Blocks (PTBs) in TypeScript, you need the SUI SDK and a client connection. This chapter covers installation, client creation, and the import patterns used throughout the AncientStorage dApp.
Installing the SUI SDK
The primary package is @mysten/sui, which includes everything you need:
npm install @mysten/suiFor React-based dApps that need wallet integration, you also need the DAppKit packages:
npm install @mysten/dapp-kit-core @mysten/dapp-kit-reactCreating a SUI Client
The SuiGrpcClient connects to a SUI fullnode. Here is how the AncientStorage dApp sets it up:
import { SuiGrpcClient } from '@mysten/sui/grpc';
const client = new SuiGrpcClient({
network: 'testnet',
baseUrl: 'https://fullnode.testnet.sui.io:443',
});For different networks:
const FULLNODE_URLS = {
mainnet: 'https://fullnode.mainnet.sui.io:443',
testnet: 'https://fullnode.testnet.sui.io:443',
};The Transaction Import
Transactions are built using the Transaction class from @mysten/sui/transactions:
import { Transaction } from '@mysten/sui/transactions';
const tx = new Transaction();In some codebases, you may also need Inputs for advanced object references:
import { Transaction, Inputs } from '@mysten/sui/transactions';Package Structure
A typical EVE Frontier dApp has several important constants:
// Your published Move package ID
const TRIBE_STORAGE_PACKAGE_ID = '0x789...';
// The shared ExtensionConfig object ID
const TRIBE_STORAGE_CONFIG_ID = '0xdef456...';
// The EVE Frontier world package ID (same for all extensions)
const EVE_FRONTIER_PACKAGE_ID = '0x28b497559d65ab320d9da4613bf2498d5946b2c0ae3597ccfda3072ce127448c';These constants come from:
- Your package ID: Output of
sui client publish - Config ID: Created during
init()when your package was published - EVE Frontier package ID: Provided by the game developers, same for all extensions on the same environment
In practice, these are stored as environment variables:
const TRIBE_STORAGE_PACKAGE_ID = process.env.NEXT_PUBLIC_TRIBE_STORAGE_PKG ?? '';
const TRIBE_STORAGE_CONFIG_ID = process.env.NEXT_PUBLIC_TRIBE_STORAGE_CONFIG ?? '';
const EVE_FRONTIER_PACKAGE_ID = process.env.NEXT_PUBLIC_EVE_FRONTIER_PKG ?? '';Reading Object Data via JSON-RPC
Before building transactions, you often need to fetch object data. The SUI JSON-RPC API provides this:
async function fetchObjectRef(objectId: string): Promise<{
version: string;
digest: string;
typeName: string | null;
owner: string | null;
} | null> {
const res = await fetch('https://fullnode.testnet.sui.io:443', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'sui_getObject',
params: [objectId, { showType: true, showOwner: true, showContent: true }],
}),
});
const json = await res.json();
const data = json.result?.data;
if (!data?.digest) return null;
return {
version: data.version ?? '0',
digest: data.digest,
typeName: data.type ?? null,
owner: data.owner?.AddressOwner ?? null,
};
}This is especially important for the ReceivingRef pattern used when borrowing OwnerCap objects -- you need the exact version and digest of the object at the time of the transaction.
GraphQL Alternative
SUI also provides a GraphQL endpoint for more complex queries. The AncientStorage dApp uses it for character lookups:
const GRAPHQL_ENDPOINTS = {
testnet: 'https://sui-testnet.mystenlabs.com/graphql',
mainnet: 'https://sui-mainnet.mystenlabs.com/graphql',
};
async function suiGraphQL<T>(
query: string,
variables: Record<string, unknown>,
): Promise<T | null> {
const res = await fetch(GRAPHQL_ENDPOINTS.testnet, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
});
const result = await res.json();
return result.data ?? null;
}GraphQL is better for:
- Querying objects owned by an address
- Filtering by object type
- Navigating object relationships (e.g.,
PlayerProfiletoCharacter)
JSON-RPC is better for:
- Fetching a single object by ID
- Getting object version/digest for transactions
- Simple lookups
Key Takeaways
- Install
@mysten/suifor the core SDK and@mysten/dapp-kit-reactfor wallet integration. - Create a
SuiGrpcClientwith the target network and fullnode URL. - Import
Transactionfrom@mysten/sui/transactionsto build PTBs. - Store package IDs and object IDs as environment variables.
- Use JSON-RPC (
sui_getObject) for single object lookups and GraphQL for complex queries.
Sign in to track your progress.