Как перенести собственный токен с помощью '@solana/web3.js'

Я хочу отправить свой развернутый токен, отличный от sol, с помощью solana web3.js, но не знаю как. Давно искал официальную документацию, но не нашел. Не могли бы вы сообщить мне, если у вас есть какая-либо информация по этому поводу? Спасибо

4 ответа

Проблема с существующими ответами заключается в том, что они только показывают вам, как сначала создать новый пользовательский токен, а затем выполнить перенос из одного кошелька в другой. Здесь я покажу, как это сделать с помощью существующего пользовательского токена.

      import { Token, TOKEN_PROGRAM_ID } 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 mintToken = new Token(
    connection,
    mintPublicKey,
    TOKEN_PROGRAM_ID,
    wallet.payer // the wallet owner will pay to transfer and to create recipients associated token account if it does not yet exist.
  );
        
  const fromTokenAccount = await mintToken.getOrCreateAssociatedAccountInfo(
    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 Token.getAssociatedTokenAddress(
    mintToken.associatedProgramId,
    mintToken.programId,
    mintPublicKey,
    destPublicKey
  );

  const receiverAccount = await connection.getAccountInfo(associatedDestinationTokenAddr);
        
  const instructions: web3.TransactionInstruction[] = [];  

  if (receiverAccount === null) {

    instructions.push(
      Token.createAssociatedTokenAccountInstruction(
        mintToken.associatedProgramId,
        mintToken.programId,
        mintPublicKey,
        associatedDestinationTokenAddr,
        destPublicKey,
        wallet.publicKey
      )
    )

  }
  
  instructions.push(
    Token.createTransferInstruction(
      TOKEN_PROGRAM_ID,
      fromTokenAccount.address,
      associatedDestinationTokenAddr,
      wallet.publicKey,
      [],
      amount
    )
  );

  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);
}

обратите внимание, как мы добавляем инструкцию для создания пользовательской учетной записи токена получателя, если у него ее нет.

Убедитесь, что вы установили привязки npm для программы токенов, как вы можете видеть из импорта ниже.

Небольшое обновление ответа @Ozymandias, похоже, в нем мало изменений spl-tokenбиблиотека. Во-первых Tokenбольше не существует. И несколько функций, таких как Token.getAssociatedTokenAddressвроде тоже удалили. Вот обновленный код:

       

    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);
                }

Предположения:

  1. Вы используете кошелек Phantom. Подразумевается, что платеж инициируется из фантомного кошелька.
  2. Вы работаете в сети разработчиков.
  3. Доступен открытый ключ (адрес) кошелька назначения.
  4. Этот пользовательский токен - это токен, который вы сами создали ранее из кошелька для минтинга, который здесь называется fromWallet .
  5. fromWallet создается здесь с помощью secretKey

Другие вопросы по тегам