Created
April 28, 2025 15:03
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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