Using write operation to send a transaction
Audience: developers ready to perform their first state-changing operation.
Prerequisites: a funded Sui devnet wallet and a basic Node.js setup.
Goal: write a script to transfer Sui tokens to another address, understanding the role of gas and signatures.
Introductionโ
In previous tutorials, you performed read operations by querying the SuiClient for data without incurring network fees.
Now, you perform a write operation to transfer Sui tokens from your wallet to another address. Because this modifies on-chain state, two requirements apply:
- Signature: you must cryptographically sign the request to prove ownership of the funds.
- Gas (postage): you must pay a fee in Sui tokens to compensate the network for processing the transaction.
Prerequisitesโ
To run this tutorial, you need:
- A funded wallet: a 12-word recovery phrase for a wallet that holds Sui
devnettokens. You can request free test tokens via the Sui Discord faucet or directly within a compatible Sui wallet. - The Ed25519 keypair package:
@mysten/suito sign the transaction.
Install the required package (if you have not already):
npm install @mysten/sui
In production applications, never hardcode your private key or recovery phrase. Always use environment variables (for example, .env). This tutorial uses an in-memory variable for demonstration, but never commit private recovery phrases to GitHub.
1. Import dependencies and configure the clientโ
Create a file named transfer.js. Import SuiClient for network communication and Ed25519Keypair to sign the transaction.
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { Transaction } from '@mysten/sui/transactions';
// 1. Connect to Devnet
const client = new SuiClient({ url: getFullnodeUrl('devnet') });
// 2. Load your Wallet (The Sender)
// REPLACE THIS with your actual 12-word mnemonic phrase
const MNEMONIC = "word1 word2 word3 ... word12";
const keypair = Ed25519Keypair.deriveKeypair(MNEMONIC);
const senderAddress = keypair.getPublicKey().toSuiAddress();
console.log(`๐ฆ Sender Address: ${senderAddress}`);
Before sending a transaction, your sender address needs test tokens to pay for gas. Copy the printed Sender Address from your terminal and request tokens through the #devnet-faucet channel in the Sui Discord.
2. Construct the transactionโ
In Sui, you construct a Transaction rather than sending raw commands. Think of this as filling out a shipping label and packing items into a box before sealing it.
Use the tx.splitCoins command to split a specific amount from your primary gas coin:
// 3. Define the Recipient
const RECIPIENT = '0x9999...'; // Replace with a friend's address or a burn address
// 4. Create the Transaction Container
const tx = new Transaction();
// Split 1000 MIST (The smallest unit of SUI) from the gas coin
const [coinToSend] = tx.splitCoins(tx.gas, [1000]);
// Transfer the split coin to the recipient
tx.transferObjects([coinToSend], RECIPIENT);
3. Sign and submit the transactionโ
This step calculates and pays gas before executing the transaction on-chain.
โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Build Transaction โ โโโบ โ 2. Sign with Keypair โ โโโบ โ 3. Submit via SuiClient โ
โ (splitCoins, transfer) โ โ (Cryptographic Proof) โ โ (Broadcasts to Devnet) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
When you call signAndExecuteTransaction, the SuiClient:
- Estimates gas: calculates the computational complexity and sets the required gas budget.
- Signs: applies your
keypairsignature to approve the state change. - Submits: transmits the signed transaction through the RPC fullnode to the network.
async function sendTransaction() {
try {
console.log("๐ Signing and submitting transaction...");
const result = await client.signAndExecuteTransaction({
signer: keypair,
transaction: tx,
});
console.log("โ
Transaction Submitted!");
console.log(`Digest (Tracking ID): ${result.digest}`);
} catch (error) {
console.error("โ Transaction Failed:", error);
}
}
sendTransaction();
Understanding gas in this transactionโ
You do not need to calculate gas costs manually.
- Automatic budgeting: by default, the SDK estimates the gas cost for you. It sets a sufficient budget for execution without excessive overpayment.
- Payment source: the SDK automatically selects a SUI coin object from your wallet to pay this fee. Because of this, always reserve a small amount of SUI in your wallet to cover gas.
Expected outputโ
When successful, the script outputs a Transaction Digest (your transaction tracking ID):
๐ฆ Sender Address: 0x123...
๐ Signing and submitting transaction...
โ
Transaction Submitted!
Digest (Tracking ID): 5T7x...9B2a
Copy this digest and search for it on Suiscan. The explorer displays the permanent on-chain record, including gas consumption and execution status.
Next stepsโ
Now that you have executed your first on-chain write transaction:
- Read How to fetch object data to inspect the recipient's newly received object.
- Review The SuiClient architecture for the conceptual model of Sui nodes and clerks.
- Explore the
getObjectAPI reference to query detailed transaction effects and object schemas.