Jetton Transfer
This recipe provides an example of sending Jettons using a mnemonic for signing. It covers deriving a wallet key, constructing a Jetton transfer transaction, signing it, and broadcasting it to the blockchain.
TypeScript
import { WalletContractV5R1, Address, beginCell, internal, toNano, SendMode } from '@ton/ton';
import { mnemonicToPrivateKey } from '@ton/crypto';
import { TonApiClient } from '@ton-api/client';
import { ContractAdapter } from '@ton-api/ton-adapter';
// Initialize TonApi client
const ta = new TonApiClient({
baseUrl: 'https://tonapi.io',
apiKey: 'YOUR_API_KEY', // Optional, improves request limits and access
});
// Create an adapter for interacting with contracts
const adapter = new ContractAdapter(ta);
// Base gas fee required for the jetton transfer
const BASE_JETTON_SEND_AMOUNT = toNano(0.05);
// Define recipient and jetton master contract addresses
const destination = Address.parse('EQApwowlR6X54bXoso6orKCzCNm9ily8pAFy5vTwmsQ2Wqin'); // Replace with the actual recipient address
const jettonMaster = Address.parse('EQCxE6mUtQJKFnGfaROTKOt1lZbDiiX1kCixRv7Nw2Id_sDs'); // USDt jetton master contract
// Define jetton transfer amount in the smallest jetton units (1 USDt)
const jettonAmount = 1_000_000n;
// Convert mnemonic phrase to a private key
const mnemonics = 'word1 word2 ...'.split(' '); // Wallet seed phrase (24 words)
const keyPair = await mnemonicToPrivateKey(mnemonics); // Generate key pair
// Create a wallet contract (Wallet V5R1, other versions or contract types can be used)
const wallet = WalletContractV5R1.create({ workchain: 0, publicKey: keyPair.publicKey });
const contract = adapter.open(wallet); // Open the wallet contract using the adapter
// Get the sender's jetton wallet address from the jetton master contract
const jettonWalletAddressResult = await ta.blockchain.execGetMethodForBlockchainAccount(
jettonMaster,
'get_wallet_address',
{ args: [wallet.address.toRawString()] }
);
const jettonWallet = Address.parse(jettonWalletAddressResult.decoded.jetton_wallet_address); // Extract the jetton wallet address
// Create payload for the jetton transfer
const jettonTransferPayload = beginCell()
.storeUint(0xf8a7ea5, 32) // JETTON_TRANSFER_OP_CODE (operation identifier)
.storeUint(0, 64) // Query ID (0 for new transactions)
.storeCoins(jettonAmount) // Amount to transfer (1 USDt)
.storeAddress(destination) // Recipient address
.storeAddress(wallet.address) // Address to receive excess funds (usually address of sender)
.storeBit(false) // No custom payload
.storeCoins(1n) // Forward fee in nanoTON (for send notify to wallet)
.storeMaybeRef(undefined)
.endCell();
// Get the current seqno (sequence number) for the wallet transaction
const seqno = await contract.getSeqno();
// Send the transfer transaction
await contract.sendTransfer({
seqno, // Required to ensure transaction uniqueness
secretKey: keyPair.secretKey, // Sign the transaction with the private key
sendMode: SendMode.PAY_GAS_SEPARATELY + SendMode.IGNORE_ERRORS, // Specify send mode
messages: [
internal({
to: jettonWallet, // Sending to the sender's jetton wallet
value: BASE_JETTON_SEND_AMOUNT, // Gas fee
body: jettonTransferPayload // Jetton transfer payload
})
]
});