import 'package:solana/solana.dart' as web3;
import 'package:solana/token_program.dart' as token_program;
Future<String> transferSplToken(
Wallet wallet,
String recipientAddress,
String tokenMintAddress,
double amount,
int decimals,
) async {
// Convert wallet address to Solana public key
final publicKey = web3.Ed25519HDPublicKey.fromBase58(wallet.address!);
// Convert recipient address to Solana public key
final recipient = web3.Ed25519HDPublicKey.fromBase58(recipientAddress);
// Convert token mint address to Solana public key
final tokenMint = web3.Ed25519HDPublicKey.fromBase58(tokenMintAddress);
// Get the latest blockhash
final blockhash = (await solanaClient.rpcClient.getLatestBlockhash()).value;
// Find the token account addresses for sender and recipient
final senderTokenAccount = await token_program.findAssociatedTokenAddress(
owner: publicKey,
mint: tokenMint,
);
final recipientTokenAccount = await token_program.findAssociatedTokenAddress(
owner: recipient,
mint: tokenMint,
);
// Check if recipient token account exists, if not create it
final instructions = <web3.Instruction>[];
final accounts = await solanaClient.rpcClient
.getTokenAccountsByOwner(
recipient.toBase58(),
const web3.TokenAccountsFilter.byMint(tokenMint),
);
final recipientTokenAccountExists = accounts.value.any(
(account) => account.pubkey == recipientTokenAccount,
);
if (!recipientTokenAccountExists) {
instructions.add(
token_program.createAssociatedTokenAccountInstruction(
associatedToken: recipientTokenAccount,
payer: publicKey,
owner: recipient,
mint: tokenMint,
),
);
}
// Convert token amount accounting for decimals
final tokenAmount = (amount * (10 * decimals)).toInt();
// Add token transfer instruction
instructions.add(
token_program.transferInstruction(
source: senderTokenAccount,
destination: recipientTokenAccount,
owner: publicKey,
amount: tokenAmount,
),
);
// Create and compile the message
final message = web3.Message(instructions: instructions);
final compiledMessage = message.compile(
recentBlockhash: blockhash.blockhash,
feePayer: publicKey,
);
// Sign the transaction using Para
final signedTransaction = await solanaSigner.signTransaction(compiledMessage);
// Send the signed transaction
final signature = await solanaSigner.sendTransaction(signedTransaction);
return signature;
}