Buenas noches a todos, estoy creando un sitio web donde las personas inician sesión en su billetera fantasma y luego, al hacer clic en un botón, enviarán una cierta cantidad de nuestro token personalizado a una billetera.
El código que se muestra a continuación funciona con SOL y me gustaría que funcione con nuestro token SPL personalizado. Tengo la dirección de menta del token, pero no pude encontrar ninguna forma de hacerlo funcionar. ¿Alguien podría ayudarme? Gracias por adelantado.
async function transferSOL(toSend) { // Detecing and storing the phantom wallet of the user (creator in this case) var provider = await getProvider(); console.log("Public key of the emitter: ",provider.publicKey.toString()); // Establishing connection var connection = new web3.Connection( "https://api.mainnet-beta.solana.com/" ); // I have hardcoded my secondary wallet address here. You can take this address either from user input or your DB or wherever var recieverWallet = new web3.PublicKey("address of the wallet recieving the custom SPL Token"); var transaction = new web3.Transaction().add( web3.SystemProgram.transfer({ fromPubkey: provider.publicKey, toPubkey: recieverWallet, lamports: (web3.LAMPORTS_PER_SOL)*toSend //Investing 1 SOL. Remember 1 Lamport = 10^-9 SOL. }), ); // Setting the variables for the transaction transaction.feePayer = await provider.publicKey; let blockhashObj = await connection.getRecentBlockhash(); transaction.recentBlockhash = await blockhashObj.blockhash; // Request creator to sign the transaction (allow the transaction) let signed = await provider.signTransaction(transaction); // The signature is generated let signature = await connection.sendRawTransaction(signed.serialize()); // Confirm whether the transaction went through or not console.log(await connection.confirmTransaction(signature)); //Signature chhap diya idhar console.log("Signature: ", signature); }Me gustaría especificar que las personas usarán phantom y no puedo tener acceso a sus claves privadas (porque era necesario en todas las respuestas que encontré en Internet)
¡Estás muy cerca! Solo necesita reemplazar la instrucción web3.SystemProgram.transfer con una instrucción para transferir tokens SPL, haciendo referencia a las cuentas adecuadas. Hay un ejemplo en el libro de cocina de Solana que cubre exactamente esta situación:https://solanacookbook.com/references/token.html#transfer-token
Puede hacer esto con la ayuda de anchor y spl-token , que se usa para manejar tokens personalizados en solana. Esta es una función de transferencia personalizada. Necesitará la dirección de menta del token, la billetera de la que se tomarán los tokens (que obtiene en el front-end cuando el usuario conecta la billetera. Puede usar solana-web3 ), la dirección y la cantidad.
import * as splToken from "@solana/spl-token"; import { web3, Wallet } from "@project-serum/anchor"; async function transfer(tokenMintAddress: string, wallet: Wallet, to: string, connection: web3.Connection, amount: number) { const mintPublicKey = new web3.PublicKey(tokenMintAddress); const {TOKEN_PROGRAM_ID} = splToken const fromTokenAccount = await splToken.getOrCreateAssociatedTokenAccount( connection, wallet.payer, mintPublicKey, wallet.publicKey ); const destPublicKey = new web3.PublicKey(to); // Get the derived address of the destination wallet which will hold the custom token const associatedDestinationTokenAddr = await splToken.getOrCreateAssociatedTokenAccount( connection, wallet.payer, mintPublicKey, destPublicKey ); const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr.address); const instructions: web3.TransactionInstruction[] = []; instructions.push( splToken.createTransferInstruction( fromTokenAccount.address, associatedDestinationTokenAddr.address, wallet.publicKey, amount, [], TOKEN_PROGRAM_ID ) ); const transaction = new web3.Transaction().add(...instructions); transaction.feePayer = wallet.publicKey; transaction.recentBlockhash = (await connection.getRecentBlockhash()).blockhash; const transactionSignature = await connection.sendRawTransaction( transaction.serialize(), { skipPreflight: true } ); await connection.confirmTransaction(transactionSignature); }