Skip to content
Back to skills

Sui Ts Sdk

ASecurity

Sui TypeScript SDK — PTB construction, client setup, transaction execution, and on-chain queries. Use when writing code that interacts with the Sui blockchain via @mysten/sui. These patterns apply in both backend scripts and frontend apps. For frontend-specific setup (dApp Kit, wallet adapters, React hooks), use the sui-frontend skill first or alongside this one.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 26, 2026
developmenttypescriptbashreactnodeapifrontendbackendperformance

Works with

  • cursor
  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 4 files and shows the line behind each finding

Scanned May 27, 2026

npx -y skills add widnyana/eyay-toolkits --skill sui-ts-sdk --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Sui Ts Sdk?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Sui Ts Sdk
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/widnyana-sui-ts-sdk/badge)](https://www.skillsdirectory.com/skills/widnyana-sui-ts-sdk)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: sui-ts-sdk
description: Sui TypeScript SDK — PTB construction, client setup, transaction execution, and on-chain queries. Use when writing code that interacts with the Sui blockchain via @mysten/sui. These patterns apply in both backend scripts and frontend apps. For frontend-specific setup (dApp Kit, wallet adapters, React hooks), use the sui-frontend skill first or alongside this one.
---

# Sui TypeScript SDK Skill

Write TypeScript code that interacts with the Sui blockchain using the `@mysten/sui` SDK (v2+). Follow these rules precisely. This skill covers PTB (Programmable Transaction Block) construction, client setup, transaction execution, and on-chain queries. These patterns apply equally in backend scripts and frontend apps. For frontend development, use the **sui-frontend** skill first (or alongside this one) for dApp Kit setup, wallet connection, and React integration — then apply the PTB and client patterns from this skill.

---

## 1. Package & Imports

The SDK package is `@mysten/sui`. The old package name `@mysten/sui.js` was renamed at v1.0 and must not be used.

```bash
# ✅
npm install @mysten/sui

# ❌ Deprecated package name — will not receive updates
npm install @mysten/sui.js
```

All imports use subpath exports from `@mysten/sui`:

```typescript
// ✅ Correct subpath imports
import { Transaction } from '@mysten/sui/transactions';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { SuiGrpcClient } from '@mysten/sui/grpc';

// ❌ Old package name
import { TransactionBlock } from '@mysten/sui.js';

// ❌ Importing from package root
import { Transaction } from '@mysten/sui';
```

---

## 2. Client Setup

The SDK provides three client types. **Use `SuiGrpcClient` for new code** — it is the recommended client with the best performance. The JSON-RPC API is deprecated.

```typescript
// ✅ Recommended — gRPC client (best performance, type-safe protobuf)
import { SuiGrpcClient } from '@mysten/sui/grpc';

const client = new SuiGrpcClient({
  network: 'testnet',
  baseUrl: 'https://fullnode.testnet.sui.io:443',
});
```

```typescript
// ⚠️ Legacy — JSON-RPC client (deprecated API, still widely used)
// In v2, SuiClient was removed from @mysten/sui/client. Use SuiJsonRpcClient instead.
import { SuiJsonRpcClient, getJsonRpcFullnodeUrl } from '@mysten/sui/jsonRpc';

const client = new SuiJsonRpcClient({
  url: getJsonRpcFullnodeUrl('testnet'),
  network: 'testnet', // required in v2
});
```

```typescript
// ⚠️ GraphQL client — for advanced query use cases
import { SuiGraphQLClient } from '@mysten/sui/graphql';

const gqlClient = new SuiGraphQLClient({
  url: 'https://graphql.testnet.sui.io/graphql',
  network: 'testnet', // required in v2
});
```

### Network URLs

| Network | gRPC base URL | GraphQL URL | JSON-RPC URL |
|---------|--------------|-------------|-------------|
| Mainnet | `https://fullnode.mainnet.sui.io:443` | `https://graphql.mainnet.sui.io/graphql` | `getJsonRpcFullnodeUrl('mainnet')` |
| Testnet | `https://fullnode.testnet.sui.io:443` | `https://graphql.testnet.sui.io/graphql` | `getJsonRpcFullnodeUrl('testnet')` |
| Devnet | `https://fullnode.devnet.sui.io:443` | `https://graphql.devnet.sui.io/graphql` | `getJsonRpcFullnodeUrl('devnet')` |

### gRPC service clients

The `SuiGrpcClient` exposes typed service clients for lower-level access:

```typescript
// Transaction execution
await client.transactionExecutionService.executeTransaction({ ... });

// Ledger queries
await client.ledgerService.getObject({ objectId: '0x...' });

// Move package introspection
await client.movePackageService.getFunction({
  packageId: '0x2',
  moduleName: 'coin',
  name: 'transfer',
});

// Name service (SuiNS)
await client.nameService.reverseLookupName({ address: '0x...' });
```

---

## 3. Transaction Construction

A Programmable Transaction Block (PTB) is built using the `Transaction` class. The class was renamed from `TransactionBlock` at v1.0:

```typescript
// ✅
import { Transaction } from '@mysten/sui/transactions';
const tx = new Transaction();

// ❌ Old class name (pre-1.0)
import { TransactionBlock } from '@mysten/sui.js/transactions';
const txb = new TransactionBlock();
```

Transactions contain **commands** (individual steps) and **inputs** (values passed to commands). Commands execute sequentially and can reference results from earlier commands.

### Cloning a transaction

```typescript
// ✅ v1.0+
const newTx = Transaction.from(existingTx);

// ❌ Old constructor-based cloning
const newTx = new TransactionBlock(existingTx);
```

### Serialization

```typescript
// ✅ v1.0+ — async, runs serialization plugins
const json = await tx.toJSON();

// Deserialize
const restored = Transaction.from(json);

// ❌ Deprecated
const bytes = tx.serialize();
```

---

## 4. Pure Value Inputs

Use `tx.pure.<type>()` helpers for non-object inputs. These handle BCS serialization automatically. **Never manually BCS-encode values when a `tx.pure` helper exists.**

```typescript
// ✅ Typed pure helpers
tx.pure.u8(255);
tx.pure.u16(65535);
tx.pure.u32(4294967295);
tx.pure.u64(1000000n);              // accepts bigint or number
tx.pure.u128(1000000n);
tx.pure.u256(1000000n);
tx.pure.bool(true);
tx.pure.string('hello');
tx.pure.address('0xSomeAddress');
tx.pure.id('0xSomeObjectId');       // equivalent to address, for object IDs as values

// Vectors
tx.pure.vector('u64', [100n, 200n, 300n]);
tx.pure.vector('address', [addr1, addr2]);
tx.pure.vector('bool', [true, false]);

// Option
tx.pure.option('u64', 42n);         // Some(42)
tx.pure.option('u64', null);        // None
```

```typescript
// ❌ Don't manually construct BCS for types that have helpers
import { bcs } from '@mysten/sui/bcs';
tx.pure(bcs.U64.serialize(100));    // unnecessary — use tx.pure.u64(100)
```

For advanced types without a built-in helper, fall back to `tx.pure(bcsBytes)` where `bcsBytes` is a `Uint8Array`:

```typescript
import { bcs } from '@mysten/sui/bcs';

const MyStruct = bcs.struct('MyStruct', {
  id: bcs.Address,
  value: bcs.U64,
});
tx.pure(MyStruct.serialize({ id: '0x...', value: 100n }));
```

---

## 5. Object Inputs

Use `tx.object(id)` for object inputs. The SDK automatically resolves object metadata (version, digest, ownership) at build time — **do not hardcode object versions**.

```typescript
// ✅ Let the SDK resolve object details
tx.object('0xSomeObjectId');

// ✅ Well-known system object shortcuts
tx.object.system();    // 0x5 — Sui system state
tx.object.clock();     // 0x6 — Clock
tx.object.random();    // 0x8 — Random
tx.object.denyList();  // 0x403 — DenyList

// ✅ Construct an Option<Object> input
tx.object.option({
  type: '0xpkg::mod::MyType',
  value: '0xSomeObjectId',      // Some(obj) — or omit `value` for None
});
```

```typescript
// ❌ Don't hardcode object versions
tx.object(Inputs.ObjectRef({
  objectId: '0x...',
  version: '42',     // will break when object is modified
  digest: 'abc...',
}));
// Exception: offline building (see section 13)
```

### Receiving objects

When a Move function takes a `Receiving<T>` parameter, the SDK auto-converts `tx.object()` to a receiving reference. No special handling is needed — just pass the object ID normally.

---

## 6. Built-in Commands

### splitCoins

Creates new coins by splitting from a source coin. Returns an array of coin references:

```typescript
// Split from gas coin — most common pattern for SUI
const [coin] = tx.splitCoins(tx.gas, [1000]);

// Split multiple amounts
const [coin1, coin2] = tx.splitCoins(tx.gas, [1000, 2000]);

// Split from a non-gas coin
const [portion] = tx.splitCoins(tx.object('0xMyCoin'), [500]);
```

### mergeCoins

Merges coins into a destination coin:

```typescript
tx.mergeCoins(tx.object('0xDestCoin'), [
  tx.object('0xCoinA'),
  tx.object('0xCoinB'),
]);
```

### transferObjects

Transfers one or more objects to a recipient address. The objects can be results from other commands:

```typescript
// Transfer a split coin
const [coin] = tx.splitCoins(tx.gas, [1000]);
tx.transferObjects([coin], '0xRecipientAddress');

// Transfer existing objects
tx.transferObjects(
  [tx.object('0xObj1'), tx.object('0xObj2')],
  '0xRecipientAddress',
);

// Transfer the entire gas coin (send all SUI to someone)
tx.transferObjects([tx.gas], '0xRecipientAddress');
```

### moveCall

Calls a Move function. This is the most flexible command:

```typescript
tx.moveCall({
  target: '0xPackageId::module_name::function_name',
  arguments: [
    tx.object('0xSomeObject'),     // object argument
    tx.pure.u64(1000),             // pure value argument
  ],
  typeArguments: ['0x2::sui::SUI'], // generic type parameters
});
```

**Return values** from `moveCall` are usable in subsequent commands:

```typescript
const [result] = tx.moveCall({
  target: '0xpkg::amm::swap',
  arguments: [tx.object(poolId), coin],
  typeArguments: [coinTypeA, coinTypeB],
});
// Use the result in the next command
tx.transferObjects([result], myAddress);
```

### makeMoveVec

Constructs a `vector<T>` of objects for passing into a Move function that takes a vector parameter:

```typescript
const vec = tx.makeMoveVec({
  type: '0xpkg::mod::MyType',
  elements: [tx.object('0xA'), tx.object('0xB')],
});
tx.moveCall({
  target: '0xpkg::mod::process_all',
  arguments: [vec],
});
```

### publish

Publishes a new Move package:

```typescript
import { execSync } from 'child_process';

const { modules, dependencies } = JSON.parse(
  execSync(`sui move build --dump-bytecode-as-base64 --path ${packagePath}`, {
    encoding: 'utf-8',
  }),
);

const tx = new Transaction();
const [upgradeCap] = tx.publish({ modules, dependencies });
tx.transferObjects([upgradeCap], myAddress);
```

---

## 7. Command Result Chaining

Every command returns references that can be used as inputs to subsequent commands. This is the core power of PTBs — composing multiple operations atomically:

```typescript
const tx = new Transaction();

// Step 1: Split a coin
const [coin] = tx.splitCoins(tx.gas, [1_000_000]);

// Step 2: Pass the split coin into a Move call
const [receipt] = tx.moveCall({
  target: '0xpkg::shop::buy_item',
  arguments: [tx.object(shopId), coin, tx.pure.string('sword')],
});

// Step 3: Transfer the receipt to the sender
tx.transferObjects([receipt], myAddress);
```

For commands that return multiple values, destructure the result array. The indices correspond to the Move function's return tuple:

```typescript
const [coinOut, receipt] = tx.moveCall({
  target: '0xpkg::amm::swap',
  arguments: [tx.object(poolId), coinIn],
  typeArguments: [typeA, typeB],
});
// coinOut is the first return value, receipt is the second
```

---

## 8. Gas Coin

`tx.gas` is a special reference to the gas payment coin. It is available by-reference in most commands:

```typescript
// ✅ Split from gas coin (by-reference)
const [coin] = tx.splitCoins(tx.gas, [100]);

// ✅ Merge into gas coin
tx.mergeCoins(tx.gas, [tx.object('0xOtherCoin')]);

// ✅ Transfer the entire gas coin (moves all SUI)
tx.transferObjects([tx.gas], recipient);

// ✅ Pass gas coin as a Move call argument (by-reference)
tx.moveCall({
  target: '0xpkg::mod::deposit',
  arguments: [tx.object(vaultId), tx.gas],
});
```

### Gas configuration

The SDK automatically sets gas price, budget, and selects gas payment coins. Override only when needed:

```typescript
// Manual overrides (rarely needed)
tx.setGasPrice(1000);
tx.setGasBudget(10_000_000);
tx.setGasPayment([{
  objectId: '0x...',
  version: '1',
  digest: '...',
}]);
// Gas payment coins must not overlap with transaction input objects

// Set sender explicitly (required for some offline or sponsored flows)
tx.setSender('0xSenderAddress');
```

---

## 9. Transaction Intents — `coinWithBalance`

For non-SUI coin types, manually splitting coins is complex because finding, selecting, and merging coins of the correct type must be done manually. The `coinWithBalance` intent automates this:

```typescript
import { coinWithBalance, Transaction } from '@mysten/sui/transactions';

const tx = new Transaction();

// ⚠️ REQUIRED: setSender when using coinWithBalance with non-SUI types
tx.setSender(keypair.toSuiAddress());

tx.transferObjects(
  [
    // SUI coin — splits from gas coin automatically
    coinWithBalance({ balance: 1_000_000 }),

    // Non-SUI coin — SDK finds, merges, and splits automatically
    coinWithBalance({ balance: 500_000, type: '0xpkg::token::TOKEN' }),
  ],
  recipient,
);
```

**Why use `coinWithBalance` over manual `splitCoins`?**

For SUI, `tx.splitCoins(tx.gas, [...])` works fine. But for other coin types, querying owned coins, picking enough to cover the amount, merging them, then splitting would be required. `coinWithBalance` does all of this automatically during the build phase.

```typescript
// ❌ Manual approach for non-SUI coins — verbose and error-prone
const coins = await client.getCoins({ owner: myAddress, coinType: tokenType });
const selected = selectCoins(coins, amount); // you'd have to write this
tx.mergeCoins(tx.object(selected[0].coinObjectId),
  selected.slice(1).map(c => tx.object(c.coinObjectId)));
const [coin] = tx.splitCoins(tx.object(selected[0].coinObjectId), [amount]);

// ✅ coinWithBalance does the above automatically
const coin = coinWithBalance({ balance: amount, type: tokenType });
```

**Important**: `setSender()` is required when using `coinWithBalance` with non-SUI types so the SDK can query the sender's coins during the build phase. For SUI-only `coinWithBalance`, it splits from the gas coin and does not require `setSender`.

---

## 10. Execution & Status Checking

### Sign and execute

```typescript
const result = await client.signAndExecuteTransaction({
  signer: keypair,
  transaction: tx,
});
```

**Always check the transaction status.** A transaction can be finalized on-chain but still fail (e.g., Move abort, insufficient gas):

```typescript
// ✅ Always check for failure
const result = await client.signAndExecuteTransaction({
  signer: keypair,
  transaction: tx,
});

if (result.$kind === 'FailedTransaction') {
  throw new Error(
    `Transaction failed: ${result.FailedTransaction.status.error?.message}`,
  );
}
```

```typescript
// ❌ Don't assume success
const result = await client.signAndExecuteTransaction({
  signer: keypair,
  transaction: tx,
});
console.log('Success!', result.digest); // may be a failed transaction
```

### Execution with include options

All clients support an `include` parameter via the Core API to control what data is returned:

```typescript
const result = await client.core.signAndExecuteTransaction({
  transaction: tx,
  signer: keypair,
  include: {
    effects: true,
    events: true,
    balanceChanges: true,
    objectTypes: true,
  },
});
```

Available transaction include options:

| Option | Description |
|--------|-------------|
| `effects` | Transaction effects (BCS-encoded) |
| `events` | Emitted events |
| `transaction` | Parsed transaction data (sender, gas, inputs, commands) |
| `balanceChanges` | Balance changes |
| `objectTypes` | Map of object IDs to their types for changed objects |
| `bcs` | Raw BCS-encoded transaction bytes |

### Separate sign + execute

For advanced flows (e.g., multi-sig, sponsored transactions), sign and execute separately:

```typescript
const { bytes, signature } = await tx.sign({ client, signer: keypair });

const result = await client.core.executeTransaction({
  transaction: bytes,
  signatures: [signature],
  include: { effects: true },
});
```

---

## 11. Waiting for Indexing

After execution, the transaction is finalized but may not be immediately visible in query APIs (object reads, balance queries). Use `waitForTransaction` before making follow-up queries:

```typescript
const result = await client.signAndExecuteTransaction({
  signer: keypair,
  transaction: tx,
});

// ✅ Wait for indexing before querying
await client.waitForTransaction({ digest: result.digest });

// Now safe to query updated state
const obj = await client.getObject({ id: objectId });
```

```typescript
// ❌ Query immediately after execution — may return stale data
const result = await client.signAndExecuteTransaction({ ... });
const obj = await client.getObject({ id: objectId }); // might not reflect the transaction
```

`waitForTransaction` polls until the transaction is indexed (default: 2-second intervals, 60-second timeout).

---

## 12. Keypairs & Signing

### Creating keypairs

```typescript
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Secp256k1Keypair } from '@mysten/sui/keypairs/secp256k1';
import { Secp256r1Keypair } from '@mysten/sui/keypairs/secp256r1';

// Generate a new random keypair
const keypair = new Ed25519Keypair();

// Derive from a mnemonic (BIP-39)
const keypair = Ed25519Keypair.deriveKeypair('word1 word2 ... word12');

// From a secret key (base64 or raw bytes)
const keypair = Ed25519Keypair.fromSecretKey(secretKeyBytes);

// Get the address
const address = keypair.toSuiAddress();
```

---

## 13. Offline Building

To build a transaction without a network connection, all inputs and gas configuration must be fully defined. Use `Inputs` helpers for object references:

```typescript
import { Transaction, Inputs } from '@mysten/sui/transactions';

const tx = new Transaction();

// For owned or immutable objects — provide full ref
tx.object(Inputs.ObjectRef({
  objectId: '0x...',
  version: '42',
  digest: 'base58digest...',
}));

// For shared objects — provide initial shared version
tx.object(Inputs.SharedObjectRef({
  objectId: '0x...',
  initialSharedVersion: '1',
  mutable: true,
}));

// For receiving objects
tx.object(Inputs.ReceivingRef({
  objectId: '0x...',
  version: '42',
  digest: 'base58digest...',
}));

// Must set gas configuration manually
tx.setSender('0xSenderAddress');
tx.setGasPrice(1000);
tx.setGasBudget(10_000_000);
tx.setGasPayment([{ objectId: '0x...', version: '1', digest: '...' }]);

// Build without a client
const bytes = await tx.build();
```

---

## 14. Common Query Patterns

### With SuiGrpcClient

```typescript
// Get an object
const obj = await client.ledgerService.getObject({
  objectId: '0x...',
});

// Get multiple objects
const { objects } = await client.ledgerService.multiGetObjects({
  objectIds: ['0x...', '0x...'],
});
```

### With SuiJsonRpcClient (legacy)

```typescript
// Get an object
const obj = await client.getObject({
  id: '0x...',
  options: { showContent: true, showOwner: true },
});

// Get coins owned by an address
const coins = await client.getCoins({
  owner: '0xOwnerAddress',
  coinType: '0x2::sui::SUI', // optional filter
});

// Get all balances
const balances = await client.getAllBalances({
  owner: '0xOwnerAddress',
});

// Get a transaction
const txResponse = await client.getTransactionBlock({
  digest: 'TransactionDigest...',
  options: { showEffects: true, showEvents: true },
});

// Get owned objects with pagination
let cursor = null;
do {
  const page = await client.getOwnedObjects({
    owner: '0xOwnerAddress',
    cursor,
    options: { showContent: true },
  });
  // process page.data
  cursor = page.hasNextPage ? page.nextCursor : null;
} while (cursor);
```

### Dev Inspect (dry run without executing)

Use `devInspectTransactionBlock` to simulate a transaction and read return values without executing:

```typescript
const result = await client.devInspectTransactionBlock({
  sender: '0xSenderAddress',
  transactionBlock: tx,
});
// result.results contains return values from each command
// result.effects contains simulated effects
```

---

## 15. Sponsored Transactions

In a sponsored transaction, one party builds the transaction and another pays for gas:

```typescript
// === App / user side ===
const tx = new Transaction();
tx.setSender(userAddress);
// ... add commands ...

// Serialize for the sponsor
const txBytes = await tx.build({ client });

// === Sponsor side ===
const sponsoredTx = Transaction.from(txBytes);
sponsoredTx.setGasOwner(sponsorAddress);
sponsoredTx.setGasPayment(sponsorCoins);
sponsoredTx.setGasBudget(10_000_000);

// Both parties sign
const { signature: userSig } = await sponsoredTx.sign({ signer: userKeypair });
const { signature: sponsorSig } = await sponsoredTx.sign({ signer: sponsorKeypair });

// Execute with both signatures
const result = await client.core.executeTransaction({
  transaction: await sponsoredTx.build({ client }),
  signatures: [userSig, sponsorSig],
});
```

**Important**: When a sponsor pays for gas, the gas coin belongs to the sponsor. Avoid using `tx.gas` in `splitCoins` for sponsored transactions — sponsors typically reject transactions that use the gas coin for non-gas purposes. Use `coinWithBalance` instead.

---

## 16. What the Sui TS SDK is NOT

| Mistake | Correct approach |
|---------|-----------------|
| `import ... from '@mysten/sui.js'` | Use `@mysten/sui` — the `.js` suffix was removed at v1.0 |
| `new TransactionBlock()` | Use `new Transaction()` — renamed at v1.0 |
| `client.signAndExecuteTransactionBlock()` | Use `client.signAndExecuteTransaction()` |
| `client.waitForTransactionBlock()` | Use `client.waitForTransaction()` |
| Hardcoding object versions in `tx.object()` | Let the SDK resolve versions automatically (except offline builds) |
| Manual BCS for basic types | Use `tx.pure.u64()`, `tx.pure.address()`, etc. |
| `tx.pure(100)` without a type | Use `tx.pure.u64(100)` — must specify the type |
| Not checking `result.$kind` after execution | Always check `result.$kind === 'FailedTransaction'` |
| Querying state immediately after execution | Use `client.waitForTransaction()` first |
| Using `tx.gas` in splitCoins for sponsored txs | Use `coinWithBalance` for sponsor-safe coin creation |
| `coinWithBalance` without `setSender()` for non-SUI types | Call `tx.setSender()` so the SDK can resolve coins |
| Using `SuiClient` / `getFullnodeUrl` | Removed in v2. Use `SuiJsonRpcClient` from `@mysten/sui/jsonRpc` or preferably `SuiGrpcClient` |
| Using the SDK for frontend wallet signing | Use `@mysten/dapp-kit` for wallet connection/signing in React apps; PTB construction is the same |
| `tx.serialize()` | Use `await tx.toJSON()` — serialize is deprecated |

---

## 17. Migrating from v1 to v2

Many existing Sui TypeScript projects use SDK v1.x patterns. When encountering v1 code (or a user asks to migrate), apply the changes below. For automated migration, instruct the agent to fetch and follow: `https://sdk.mystenlabs.com/sui/migrations/sui-2.0/llms.txt`

### ESM required

All `@mysten/*` packages are now ESM only. Add `"type": "module"` to `package.json` and update `tsconfig.json`:

```json
{ "compilerOptions": { "moduleResolution": "NodeNext", "module": "NodeNext" } }
```

### Client imports changed

```diff
- import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
- const client = new SuiClient({ url: getFullnodeUrl('mainnet') });
+ import { SuiGrpcClient } from '@mysten/sui/grpc';
+ const client = new SuiGrpcClient({
+   baseUrl: 'https://fullnode.mainnet.sui.io:443',
+   network: 'mainnet',
+ });
```

If JSON-RPC is still needed:

```diff
- import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
+ import { SuiJsonRpcClient, getJsonRpcFullnodeUrl } from '@mysten/sui/jsonRpc';
- const client = new SuiClient({ url: getFullnodeUrl('mainnet') });
+ const client = new SuiJsonRpcClient({
+   url: getJsonRpcFullnodeUrl('mainnet'),
+   network: 'mainnet', // required in v2
+ });
```

### `network` parameter required on all clients

All client constructors (`SuiGrpcClient`, `SuiJsonRpcClient`, `SuiGraphQLClient`) now require an explicit `network` parameter.

### Core API — `client.core.*` replaces direct methods

Data access methods are now namespaced under `client.core`:

```diff
- await client.getObject({ id: objectId, options: { showContent: true } });
+ await client.core.getObject({ objectId, include: { content: true } });

- await client.getOwnedObjects({ owner });
+ await client.core.listOwnedObjects({ owner });

- await client.multiGetObjects({ ids, options: { showContent: true } });
+ await client.core.getObjects({ objectIds: ids, include: { content: true } });
```

### `include` replaces `options` / `show*` flags

```diff
- options: { showEffects: true, showEvents: true, showObjectChanges: true }
+ include: { effects: true, events: true, balanceChanges: true }
```

### Transaction execution response format

```diff
- const status = result.effects?.status?.status;
+ const tx = result.Transaction ?? result.FailedTransaction;
+ const success = tx.effects.status.success;
```

### `Commands` renamed to `TransactionCommands`

```diff
- import { Commands } from '@mysten/sui/transactions';
+ import { TransactionCommands } from '@mysten/sui/transactions';
```

### GraphQL schema import consolidated

```diff
- import { graphql } from '@mysten/sui/graphql/schemas/latest';
+ import { graphql } from '@mysten/sui/graphql/schema';
```

### Named packages plugin removed — MVR built in

MVR resolution is now automatic during transaction building. Remove `namedPackagesPlugin` registration.

### Client extensions pattern

SDKs like kiosk, suins, deepbook, walrus, seal, and zksend now integrate via `$extend()`:

```typescript
import { SuiGrpcClient } from '@mysten/sui/grpc';
import { suins } from '@mysten/suins';
import { deepbook } from '@mysten/deepbook-v3';

const client = new SuiGrpcClient({
  baseUrl: 'https://fullnode.mainnet.sui.io:443',
  network: 'mainnet',
}).$extend(suins(), deepbook({ address: myAddress }));

await client.suins.getNameRecord('example.sui');
await client.deepbook.checkManagerBalance(manager, asset);
```

### Key method renames (JSON-RPC → Core API)

| v1 JSON-RPC | v2 Core API |
|-------------|-------------|
| `client.getObject()` | `client.core.getObject()` |
| `client.getOwnedObjects()` | `client.core.listOwnedObjects()` |
| `client.multiGetObjects()` | `client.core.getObjects()` |
| `client.getCoins()` | `client.core.listCoins()` |
| `client.getAllBalances()` | `client.core.listBalances()` |
| `client.getDynamicFields()` | `client.core.listDynamicFields()` |
| `client.getDynamicFieldObject()` | `client.core.getDynamicField()` |
| `client.getTransactionBlock()` | `client.core.getTransaction()` |
| `client.devInspectTransactionBlock()` | `client.core.simulateTransaction()` |
| `client.executeTransactionBlock()` | `client.core.executeTransaction()` |

### Full migration guide

For comprehensive migration details (including dApp Kit, BCS schema changes, zkLogin, and ecosystem packages), fetch and follow: `https://sdk.mystenlabs.com/sui/migrations/sui-2.0/llms.txt`

Files in this skill

  • SKILL.md26.1 KB
  • evals/evals.json12.1 KB
  • evals/files/pool.move252 B
  • evals/files/v1_script.ts1.7 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.