6

This is my situation:

  1. I have created a wallet

    solana-keygen new

  2. I have created my own custom SPL Token

    spl-token create-token

  3. Then I created an Account for this SPL Token

    spl-token create-account

  4. The SPL token is now in my wallet A

In the Solana Program, I would like to programmatically transfer the custom SPL token from Wallet A to Alice(user) wallet when certain conditions are met (for example, when Alice answered a quiz correctly, she will be awarded some custom SPL token).

How do I authorise the Solana Program to deduct from Wallet A (which I had created) and transfer the tokens to Alice wallet?

Please advise me how to go about doing this. Really appreciate this.

Vince
  • 63
  • 1
  • 6

1 Answers1

4

To transfer an SPL token within a program, your best option is to have wallet A owned by a program-derived address, and then your program can transfer the tokens from wallet A based on any logic it wants.

So first, transfer the ownership to your program-derived address:

spl-token authorize <WALLET_2_ADDRESS> owner <PROGRAM_DERIVED_ADDRESS>

Then in your program, you can transfer to Alice with something like:

let transfer_instruction = spl_token::instruction::transfer(
    &token_program.key,
    &wallet_a_token_account.key,
    &alice_token_account.key,
    &program_derived_account.key,
    &[],
    transfer_amount,
)?;

let required_accounts_for_transfer = [
    wallet_a_token_account.clone(),
    alice_token_account.clone(),
    program_derived_account.clone(),
];

invoke_signed(
    &transfer_instruction,
    &required_accounts_for_transfer,
    &[
        &[b"your", b"seeds", b"here",]
    ]
)?;

This was adapted from a full example for transferring SPL tokens within a program: https://solanacookbook.com/references/programs.html#how-to-do-cross-program-invocation

More information about program-derived addresses at https://solanacookbook.com/references/programs.html#how-to-create-a-pda, with an example of how to create an account.

Jon C
  • 7,019
  • 10
  • 17
  • Thanks for pointing me to the right direction! I notice that the seeds are placed in the code. Wouldn't that be a security risk? – Vince Mar 12 '22 at 08:55
  • The runtime only accepts "signatures" for program-derived addresses from the program itself, so typically it's safe. If your program-derived address patterns are simple, then someone could DOS opportunities by sending lamports to them. For example, if a person's wallet address is the seed, and I know yours, I can transfer to the generated address to make `create_account` fail. In which case, you need to do `allocate` + `assign`. Here's an example of mitigating it: https://github.com/solana-labs/solana-program-library/blob/master/associated-token-account/program/src/tools/account.rs#L18 – Jon C Mar 12 '22 at 10:45