0

I have this code that transfers a token using spl-token 0.2.x.

How do I have the same code work in 0.1.8? From my understanding of the docs, there were no breaking changes between the two, but the older version uses a Token class, but I'm not sure how to call it for the getOrCreateAssociatedTokenAccount and transfer functions.

async function transferToken(endpoint: string, fromWallet: Keypair, address_to: string, token_id: string)
{
    const connection = new Connection(endpoint);
    const toWalletPublicKey = new PublicKey(address_to);
    const mint_key = new PublicKey(token_id);

    // From
    const from = [connection, fromWallet, mint_key, fromWallet.publicKey];
    const fromTokenAccount = await getOrCreateAssociatedTokenAccount(...from);

    // To
    const to = [connection, fromWallet, mint_key, toWalletPublicKey];
    const toTokenAccount = await getOrCreateAssociatedTokenAccount(...to);

    // Transfer
    const transferParams = [connection, fromWallet, fromTokenAccount.address, toTokenAccount.address, fromWallet.publicKey, 1, []];
    return await transfer(...transferParams);  
}

This is how I pass the fromWallet KeyPair loaded from hex string.

const fromWallet = Keypair.fromSecretKey(Uint8Array.from(Buffer.from(private_key, 'hex')));
Berry Blue
  • 15,330
  • 18
  • 62
  • 113

1 Answers1

1

Actually version 2 does have break changes (hence the major bump of the version), in this case it was removing the Token class in favour of those functions that you see in the example.

The docs are quite... bad, but if you check the Github project one year ago then you can see how the function was migrated little by little.

getOrCreateAssociatedTokenAccount and transfer require to use the class Token in the next way:


const token = new Token(connection, toWalletPublicKey, mint_key, fromWallet.publicKey) // Not sure about the last argument as it is the Signer

/**
   * Retrieve the associated account or create one if not found.
   *
   * This account may then be used as a `transfer()` or `approve()` destination
   *
   * @param owner User account that will own the new account
   * @return The new associated account
   */
const fromTokenAccount = token.getOrCreateAssociatedAccountInfo(fromWallet.publicKey)

const toTokenAccount = token.getOrCreateAssociatedAccountInfo(toWalletPublicKey)

/**
* Transfer parameters
* @param source Source account
* @param destination Destination account
* @param owner Owner of the source account
* @param multiSigners Signing accounts if `owner` is a multiSig
* @param amount Number of tokens to transfer
*/
token.transfer(fromTokenAccount, toTokenAccount, fromWallet, [], 1)

Also this is partially answered in here

SirPeople
  • 4,248
  • 26
  • 46
  • Ok! I think I'm not creating the signer correctly. How do I do this with a private key? This is how I create the KeyPair (fromWallet) from a stored private key. – Berry Blue Sep 19 '22 at 15:11
  • Keypair.fromSecretKey(Uint8Array.from(Buffer.from(private_key, 'hex'))) – Berry Blue Sep 19 '22 at 15:11
  • since you only have one signer, you can leave the signer alone in the transfer, it should come from the `fromTokenAccount` as for the initialization of the token the Signer is just the KeyPar you are pointing at. Do you get any particular error? – SirPeople Sep 20 '22 at 13:12
  • `.../node_modules/@solana/web3.js/src/transaction.ts:611 const key = signer.publicKey.toString(); ^ TypeError: Cannot read properties of undefined (reading 'toString')` – Berry Blue Sep 21 '22 at 15:45
  • have you debug that the signer that you are passing contains both private and public key? – SirPeople Sep 22 '22 at 09:12
  • Yes, the signer contains both the private and public key when I log it out. If I pass `fromWallet` instead of `fromWallet.publicKey` I get this error. ` throw new Error('Non-base' + BASE + ' character') ^ Error: Non-base58 character` – Berry Blue Sep 22 '22 at 21:33
  • I also added how I create the KeyPair from a stored hex string of the private key. My 0.2.0 code example works with these values. – Berry Blue Sep 22 '22 at 21:36
  • Also, if I add `await` to `token.getOrCreateAssociatedAccountInfo(fromWallet.publicKey)` it gives me this error. `Error: Failed to find account` – Berry Blue Sep 22 '22 at 21:38