⚠️ JSON-RPC is being decommissioned by Sui (public endpoints shut down July 2026, fully off 2026-07-31). Use the new gRPC-web client (SuiGrpcClient) for reads/writes and GraphQL (SuiGraphQLClient) for advanced queries — see gRPC-web API (recommended) below. The legacySuiClient(JSON-RPC) API is kept for compatibility but is@Deprecatedand will stop working.
Note: This branch is in active development and may introduce breaking changes. If you don’t need Transaction v2 feature, use the
v1branch.
dependencies:
sui: ^0.4.0
SuiAccount is transport-agnostic — it works with both the new and legacy clients.
/// Ed25519 account
final ed25519 = SuiAccount.ed25519Account();
final ed25519Import = SuiAccount.fromPrivateKey(ed25519.privateKey());
/// Secp256k1 account
final secp256k1 = SuiAccount.secp256k1Account();
final sepc256k1Import = SuiAccount.fromPrivateKey(secp256k1.privateKey());
/// Secp256r1 account
final secp256r1 = SuiAccount.secp256r1Account();
final sepc256r1Import = SuiAccount.fromPrivateKey(secp256r1.privateKey());/// create mnemonics
final mnemonics = SuiAccount.generateMnemonic();
/// Ed25519 account
final ed25519 = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
/// Secp256k1 account
final secp256k1 = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Secp256k1);
/// Secp256r1 account
final secp256r1 = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Secp256r1);The SuiGrpcClient talks to Sui full nodes over gRPC-web — it works uniformly on
Mobile, Web and Desktop (no proxy required) and replaces the deprecated JSON-RPC client.
import 'package:sui/sui.dart';
final client = SuiGrpcClient(network: SuiNetwork.testnet);
// networks: SuiNetwork.mainnet | testnet | devnet | localnetThe faucet only serves
/v2/gasnow (v0/v1 are removed) and is rate-limited.
import 'package:dio/dio.dart';
await Dio().post('https://faucet.testnet.sui.io/v2/gas',
data: {'FixedAmountRequest': {'recipient': account.getAddress()}});// Balance / coins (transport-neutral models)
final balance = await client.balanceOf(owner); // SuiBalance
final coins = await client.listCoins(owner); // SuiCoinPage
// Objects
final object = await client.objectInfo(objectId); // SuiObjectInfo
final objects = await client.getObjects([id1, id2]); // raw proto (batch)
// Transactions
final tx = await client.getTransaction(digest);
await client.waitForTransaction(digest); // poll until available
// Chain / system
final gasPrice = await client.getReferenceGasPrice();
final systemState = await client.getCurrentSystemState();
final epoch = await client.getEpoch();
// Dynamic fields (name derived on-chain)
final field = await client.getDynamicFieldObject(parentId, 'u64', nameBcs);signAndExecuteTransaction handles gas price, gas-coin selection and budget
estimation (via simulateTransaction) for you.
final account = SuiAccount.ed25519Account(); // fund it first (see Faucet above)
final tx = Transaction();
final coin = tx.splitCoins(tx.gas, [tx.pureInt(1000000)]);
tx.transferObjects([coin], tx.pureAddress(account.getAddress()));
final executed = await client.signAndExecuteTransaction(account, tx);
print('${executed.digest} success=${executed.effects.status.success}');Move call (with an object argument, and optional Move Registry @org/app names):
final tx = Transaction();
tx.moveCall('0x2::clock::timestamp_ms', arguments: [tx.object('0x6')]);
// MVR names like '@org/app::module::fn' are auto-resolved on build.
final executed = await client.signAndExecuteTransaction(account, tx);Replaces the deprecated JSON-RPC WebSocket subscriptions.
final sub = client.subscribeCheckpoints().listen((res) {
print('checkpoint ${res.checkpoint.sequenceNumber}');
});
// later: await sub.cancel();final signed = account.keyPair.signPersonalMessage(message);
final result = await client.verifySignature(
message,
Uint8List.fromList(base64Decode(signed.signature)),
intentScope: IntentScope.personalMessage,
address: account.getAddress(),
);
print(result.isValid);final pkg = await client.mvr?.resolvePackage('@mvr/core'); // -> 0x…GraphQL is served by an indexer (not full nodes) and covers query patterns gRPC can't —
filtered transaction/event queries, validators, stakes. Public endpoints:
graphql.<network>.sui.io/graphql.
final gql = SuiGraphQLClient.forNetwork(SuiNetwork.testnet);
final page = await gql.queryTransactionsBySender(address, first: 10);
final events = await gql.queryEventsByModule('0x2', 'coin', first: 10);
final vals = await gql.getActiveValidators(first: 5);
final stakes = await gql.getStakes(address);
final epoch = await gql.getEpochSummary();
⚠️ TheSuiClientAPI below uses JSON-RPC, which Sui removes on 2026-07-31. New code should useSuiGrpcClient/SuiGraphQLClientabove. Kept for reference and migration.
/// connect to devnet
final devnetClient = SuiClient(SuiUrls.devnet);
/// connect to testnet
final testnetClient = SuiClient(SuiUrls.testnet);
/// connect to mainnet
final mainnetClient = SuiClient(SuiUrls.mainnet);final faucet = FaucetClient(SuiUrls.faucetDev);
await faucet.requestSuiFromFaucetV0('0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2');final faucet = FaucetClient(SuiUrls.faucetDev);
await faucet.requestSuiFromFaucetV1('0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2');final account = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
final client = SuiClient(SuiUrls.devnet);
final tx = Transaction();
tx.transferObjects(
[tx.objectId('0x2619f581cb1864d07c89453a69611202669fdc4784fb59b9cb4278ec60756011')],
account.getAddress()
);
final result = await client.signAndExecuteTransactionBlock(account, tx);
print(result.digest);final account = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
final client = SuiClient(SuiUrls.devnet);
final tx = Transaction();
final coin = tx.splitCoins(tx.gas, [1000]);
tx.transferObjects(
[coin],
account.getAddress()
);
final result = await client.signAndExecuteTransactionBlock(account, tx);
print(result.digest);final account = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
final client = SuiClient(SuiUrls.devnet);
final tx = Transaction();
tx.mergeCoins(tx.objectId('0x922ec73939b3288f6da39ebefb0cb88c6c54817441254d448bd2491ac4dd0cbd'),
[tx.objectId('0x8dafc96dec7f8d635e052a6da9a4153e37bc4d59ed44c45006e4e9d17d07f80d')]
);
final result = await client.signAndExecuteTransactionBlock(account, tx);
print(result.digest);final account = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
final client = SuiClient(SuiUrls.devnet);
const packageObjectId = '0x...';
final tx = Transaction();
tx.moveCall('$packageObjectId::nft::mint', arguments: [tx.pureString('Example NFT')]);
final result = await client.signAndExecuteTransactionBlock(account, tx);
print(result.digest);final account = SuiAccount.fromMnemonics(mnemonics, SignatureScheme.Ed25519);
final client = SuiClient(SuiUrls.devnet);
const moduels = <String>[];
const dependencies = <String>[];
final tx = Transaction();
final upgradeCap = tx.publish(moduels, dependencies);
tx.transferObjects([upgradeCap], account.getAddress());
final result = await client.signAndExecuteTransactionBlock(account, tx);
print(result.digest);final client = SuiClient(SuiUrls.devnet);
final objects = await client.getOwnedObjects('0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2');final client = SuiClient(SuiUrls.devnet);
final obj = await client.getObject('0x0d49dbda185cd0941b71315edb594276731f21b2232d8713f319b02c462a2da7',
options: SuiObjectDataOptions(showContent: true)
);
final objs = await client.multiGetObjects([
'0x0d49dbda185cd0941b71315edb594276731f21b2232d8713f319b02c462a2da7',
'0x922ec73939b3288f6da39ebefb0cb88c6c54817441254d448bd2491ac4dd0cbd'
], options: SuiObjectDataOptions(showType: true));final client = SuiClient(SuiUrls.devnet);
final txn = await client.getTransactionBlock('6oH779AUs2WpwW77xCVGbYqK1FYVamRqHjV6A5wCV8Qj',
options: SuiTransactionBlockResponseOptions(showEffects: true)
);
final txns = await client.multiGetTransactionBlocks([
'9znMGToLRRa8yZvjCUfj1FJmq4gpb8QwpibFAUffuto1',
'4CEFMajEtM62MthwY1xR3Bcddoh2h5wc7jeKEy7WWsbv'
], options: SuiTransactionBlockResponseOptions(showInput: true, showEffects: true));final client = SuiClient(SuiUrls.devnet);
final checkpoint = await client.getCheckpoint('338000');
final checkpoints = await client.getCheckpoints(descendingOrder: true);final client = SuiClient(SuiUrls.devnet);
final coins = await client.getCoins(
'0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2',
coinType: '0x2::sui::SUI');
final allCoins = await client.getAllCoins('0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2');
final suiBalance = await client.getBalance('0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2');final client = SuiClient(SuiUrls.devnet);
final events = await client.queryEvents(
{"Sender": "0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2"},
limit: 2
);
/// Or with EventFilter
final events = await client.queryEventsByFilter(
EventFilter(sender: "0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2"),
limit: 2
);final client = WebsocketClient(SuiUrls.webSocketDevnet);
final subscription = client.subscribeEvent({"Sender": "0xa2d8bb82df40770ac5bc8628d8070b041a13386fef17db27b32f3b0f316ae5a2"})
.listen((event) {
debugPrint(event);
}, onError: (e) {
debugPrint(e.toString());
});