I have tried to transfer spl token from user account to program(contract) I wrote this contract with help of GPT have fixed many things now I stuck here with this error
My ultimate goal is to transfer money to contract then later from contract I should transfer it to some other wallets any help or any example?
solpg ERROR
Running client...
client.ts:
User ATA account: 3XNcYXdfZ5k1C6bFw3JeZD6zeChbbiyfKXkbs75tKo3G
Vault PDA account: D3kGGFN28uqBrfyYPpAy2etZ9Jv1UjWuuEWKNJDWNZGB
$
Error in main execution: { [Error: failed to send transaction: Transaction simulation failed: Error processing Instruction 0: Provided seeds do not result in a valid address]
logs:
[ 'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [1]',
'Program log: Create',
'Program log: Error: Associated address does not match seed derivation',
'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL consumed 8057 of 200000 compute units',
'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL failed: Provided seeds do not result in a valid address' ] }
$
lib.rs
use anchor_lang::prelude::*;
use anchor_lang::solana_program::entrypoint::ProgramResult;
use anchor_spl::token::{
self, transfer_checked, Mint, Token, TokenAccount, TransferChecked as SPLTransferChecked,
};
declare_id!("7KNzQPbmGAN4G45ncYvmCbh3xpdaYzh2iyRbZRtUwkUV");
#[program]
pub mod deposit_and_release {
use super::*;
pub fn deposit(ctx: Context<Deposit>, amount: u64) -> ProgramResult {
msg!("Deposit function called with amount: {}", amount);
// Validate deposit amount
if amount < 1_000_000 || amount > 10_000_000 {
msg!("Invalid deposit amount: {}", amount);
return Err(ProgramError::Custom(ErrorCode::InvalidDepositAmount as u32));
}
// Set up the CPI (cross-program invocation) context for the token transfer
let cpi_program = ctx.accounts.token_program.to_account_info();
let cpi_accounts = SPLTransferChecked {
from: ctx.accounts.depositor.to_account_info(),
mint: ctx.accounts.usdc_mint.to_account_info(),
to: ctx.accounts.vault.to_account_info(),
authority: ctx.accounts.depositor.to_account_info(),
};
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
// Execute the token transfer
transfer_checked(cpi_ctx, amount, ctx.accounts.usdc_mint.decimals)?;
msg!(
"Successfully transferred {} tokens from user's ATA to program's PDA vault.",
amount
);
Ok(())
}
}
#[derive(Accounts)]
pub struct Deposit<'info> {
#[account(mut)]
pub depositor: Signer<'info>, // User wallet that authorizes the transfer
#[account(mut, constraint = user_deposit.owner == depositor.key())]
pub user_deposit: Account<'info, TokenAccount>, // User's associated token account (ATA)
#[account(mut, seeds = [b"vault", usdc_mint.key().as_ref()], bump)]
// Ensure PDA ownership by program
pub vault: Account<'info, TokenAccount>, // PDA vault for receiving tokens
pub usdc_mint: Account<'info, Mint>, // Token mint for USDC
pub token_program: Program<'info, Token>, // Token program for the transfer
pub system_program: Program<'info, System>, // System program
}
#[error_code]
pub enum ErrorCode {
#[msg("Invalid deposit amount.")]
InvalidDepositAmount,
}
client.ts
import anchor from "@project-serum/anchor";
import {
Connection,
PublicKey,
SystemProgram,
Transaction,
} from "@solana/web3.js";
import {
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID,
getAssociatedTokenAddress,
createAssociatedTokenAccountInstruction,
} from "@solana/spl-token";
const solpg = pg;
const connection = solpg.connection;
const program = solpg.program;
async function main() {
const usdcMintAddress = new PublicKey(
"88vRvJtjbESDcQw8yDwGgu1HAotP6LPikpfp1UjsPy2K"
);
const wallet = solpg.wallet;
const userPublicKey = wallet.publicKey;
// Create user token account associated with USDC mint
const userTokenAccount = await getAssociatedTokenAddress(
usdcMintAddress,
userPublicKey,
false,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
);
console.log("User ATA account:", userTokenAccount.toString());
// Derive the PDA for the program-owned vault account
const [vaultAccount, vaultBump] = await PublicKey.findProgramAddress(
[Buffer.from("vault"), usdcMintAddress.toBuffer()],
program.programId
);
console.log("Vault PDA account:", vaultAccount.toString());
// Check if the vault account exists, if not, create it
const vaultAccountInfo = await connection.getAccountInfo(vaultAccount);
if (!vaultAccountInfo) {
const transaction = new Transaction().add(
createAssociatedTokenAccountInstruction(
wallet.publicKey, // Payer
vaultAccount, // ATA address
program.programId, // Owner of the ATA (program PDA)
usdcMintAddress, // Mint address
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
// Send transaction to create the ATA
await connection.sendTransaction(transaction, [wallet.keypair]);
console.log("Vault ATA account created.");
}
// Define deposit amount (1 USDC with 6 decimals)
const depositAmount = 1_000_000;
// Call the deposit function from the program
try {
await program.rpc.deposit(new anchor.BN(depositAmount), {
accounts: {
depositor: userPublicKey,
userDeposit: userTokenAccount,
vault: vaultAccount,
usdcMint: usdcMintAddress,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: SystemProgram.programId,
},
signers: [],
});
console.log("Deposited 1 USDC into the vault!");
} catch (error) {
console.error("Transaction failed:", error);
}
}
main().catch((err) => {
console.error("Error in main execution:", err);
});
I believe I'm missing something, any help? thanks in advance!!