Skip to content

Instantly share code, notes, and snippets.

@goodylili
Created April 28, 2025 15:03
Show Gist options
  • Save goodylili/66772118b0675e6af584f7c094eccefa to your computer and use it in GitHub Desktop.
Save goodylili/66772118b0675e6af584f7c094eccefa to your computer and use it in GitHub Desktop.
The different implementations between user paid transactions and sponsored transactions on Sui clients.
import { Transaction } from '@mysten/sui/transactions';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
async function sponsoredTransaction() {
const client = new SuiClient({ url: getFullnodeUrl('testnet') });
// User's main keypair (your provided key)
const userKeypair = Ed25519Keypair.fromSecretKey(
'suiprivkey1qq9r6rkysny207t5vr7m5025swh7w0wzra9p0553paprhn8zshqsx2rz64r'
);
// Sponsor keypair (your provided key)
const sponsorKeypair = Ed25519Keypair.fromSecretKey(
'suiprivkey1qr3dtpdvecp2usjah06uyw8d8jvx9syqykxlu5x45cymq8lxn7hz2cqpwte'
);
// Build the user's transaction
const tx = new Transaction();
tx.setSender(userKeypair.getPublicKey().toSuiAddress());
const [coin] = tx.splitCoins(tx.gas, [1_000_000]); // Split 0.001 SUI
tx.transferObjects([coin], '0x83ecd81fdd132d4fb4f9ae2608656b000df13c4c3c5b10490d48ee981bc8f433');
// Build KIND bytes (no gas owner yet)
const kindBytes = await tx.build({
client,
onlyTransactionKind: true,
});
// Sponsor modifies transaction
const sponsoredTx = Transaction.fromKind(kindBytes);
sponsoredTx.setSender(userKeypair.getPublicKey().toSuiAddress());
sponsoredTx.setGasOwner(sponsorKeypair.getPublicKey().toSuiAddress());
// Build final transaction bytes
const builtBytes = await sponsoredTx.build({ client });
// ✍️ User signs first
const { signature: userSignature } = await userKeypair.signTransaction(builtBytes);
// ✍️ Sponsor signs
const { signature: sponsorSignature } = await sponsorKeypair.signTransaction(builtBytes);
// 🚀 Execute with both signatures
const result = await client.executeTransactionBlock({
transactionBlock: builtBytes,
signature: [userSignature, sponsorSignature], // ✅ Two signatures required
options: {
showEffects: true,
showEvents: true,
},
});
console.log('✅ Sponsored Transaction Successful!');
console.log('Digest:', result.digest);
}
sponsoredTransaction().catch(console.error);
import { Transaction } from '@mysten/sui/transactions';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
async function sponsoredGasTransaction() {
const client = new SuiClient({ url: getFullnodeUrl('testnet') });
// Main user keypair
// dummy keypair
const userKeypair = Ed25519Keypair.fromSecretKey(
'suiprivkey1qq9r6rkysny207t5vr7m5025swh7w0wzra9p0553paprhn8zshqsx2rz64r'
);
// Sponsor keypair (can be generated randomly here)
const sponsorKeypair = new Ed25519Keypair(); // In production, the sponsor would already exist
// Step 1: User builds transaction
const tx = new Transaction();
tx.setSender(userKeypair.getPublicKey().toSuiAddress());
const [coin] = tx.splitCoins(tx.gas, [500_000]);
tx.transferObjects([coin], '0xRecipientAddressHere'); // Change to your real recipient
const kindBytes = await tx.build({ provider: client, onlyTransactionKind: true });
// Step 2: Sponsor fills gas fields
const sponsoredTx = Transaction.fromKind(kindBytes);
sponsoredTx.setSender(userKeypair.getPublicKey().toSuiAddress());
sponsoredTx.setGasOwner(sponsorKeypair.getPublicKey().toSuiAddress());
// Sponsor gas coin setup (you must own this gas coin)
const sponsorGasCoin = {
objectId: '0xGasCoinObjectId', // You must replace this
version: 1,
digest: 'DigestOfGasCoin', // Replace accordingly
};
sponsoredTx.setGasPayment([sponsorGasCoin]);
const builtBytes = await sponsoredTx.build({ client });
const { signature } = await sponsorKeypair.signTransaction(builtBytes);
const result = await client.executeTransactionBlock({
transactionBlock: builtBytes,
signature,
options: {
showEffects: true,
showEvents: true,
},
});
console.log('Sponsored transaction successful with digest:', result.digest);
}
sponsoredGasTransaction().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment