Skip to content

Instantly share code, notes, and snippets.

@h4rkl
Last active July 11, 2022 08:19
Show Gist options
  • Save h4rkl/700400f515ab0736fd6d9318d44b2dca to your computer and use it in GitHub Desktop.
Save h4rkl/700400f515ab0736fd6d9318d44b2dca to your computer and use it in GitHub Desktop.
Can't get the correct signing authority for solana serum anchor implementation
const anchor = require("@project-serum/anchor");
const serumCmn = require("@project-serum/common");
const { TOKEN_PROGRAM_ID } = require("@solana/spl-token");
describe("harkl-tests", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.Provider.env());
const program = anchor.workspace.Harkl;
const MINT_TOKENS = 4200000000000000; // 42M with 8dp
const MINT_DECIMALS = 8;
let mint = null;
let god = null;
let creatorAcc = anchor.web3.Keypair.generate();
let creatorTokenAcc = null;
it("Sets up initial test state", async () => {
const [_mint, _god] = await serumCmn.createMintAndVault(
program.provider,
new anchor.BN(MINT_TOKENS),
undefined,
MINT_DECIMALS
);
mint = _mint;
god = _god;
creatorTokenAcc =await serumCmn.createTokenAccount(
program.provider,
mint,
creatorAcc.publicKey
);
});
it("Actions an interaction", async () => {
const INTERACTION_FEE = 200000000000000;
// let [_authority, nonce] = await anchor.web3.PublicKey.findProgramAddress(
// [god.toBuffer()],
// program.programId
// );
// authority = _authority;
console.log('*************', {
from: god.toBase58(),
to: creatorTokenAcc.toBase58(),
tokenProgram: TOKEN_PROGRAM_ID.toBase58(),
programId: program.programId.toBase58(),
});
await program.rpc.interaction(new anchor.BN(INTERACTION_FEE), {
accounts: {
from: god,
to: creatorTokenAcc,
owner: program.provider.wallet.publicKey,
tokenProgram: TOKEN_PROGRAM_ID,
},
});
});
});
//! Harkl intereaction
use anchor_lang::prelude::*;
use anchor_spl::token::{self, TokenAccount, Transfer};
use std::convert::Into;
#[program]
pub mod harkl {
use super::*;
pub fn interaction(ctx: Context<Interaction>, interaction_fee: u64) -> ProgramResult {
let cpi_accounts = Transfer {
from: ctx.accounts.from.to_account_info().clone(),
to: ctx.accounts.to.to_account_info().clone(),
authority: ctx.accounts.owner.clone(),
};
let cpi_program = ctx.accounts.token_program.clone();
let cpi_ctx = CpiContext::new(cpi_program, cpi_accounts);
token::transfer(cpi_ctx, interaction_fee)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct Interaction<'info> {
#[account(mut, has_one = owner)]
from: CpiAccount<'info, TokenAccount>,
#[account("from.mint == to.mint")]
to: CpiAccount<'info, TokenAccount>,
#[account(signer)]
owner: AccountInfo<'info>,
token_program: AccountInfo<'info>,
}
#[error]
pub enum ErrorCode {
#[msg("The derived interaction signer does not match that which was given.")]
InvalidInteractionSigner,
}
@awcchungster
Copy link

Hey @h4rkl, where did you find this in the anchor_spl documentation to add this validation? I've been working on a contract that issues token from the mint rather than transferring from a reserve account like in your example.

https://gist.github.com/h4rkl/700400f515ab0736fd6d9318d44b2dca#file-lib-rs-L29

@h4rkl
Copy link
Author

h4rkl commented Nov 30, 2021

Have a look through the code repo - https://github.com/project-serum/anchor/blob/3958533750c83c3e90709448c4f30ed9cce0b9b8/tests/cashiers-check/programs/cashiers-check/src/lib.rs#L99

I cloned the entire program and searched around accounts and creation in my IDE.

@awcchungster
Copy link

Sweet thanks!

@h4rkl
Copy link
Author

h4rkl commented Nov 30, 2021

Hope you're on sosol.app my dude. See you in there! :)

@magnum6actual
Copy link

Thanks for posting this - has been super helpful. I'm learning Rust & Sol/anchor/serum concurrently. Quick question - why use of 'to_account_info().clone()" rather just setting to accounts? Assuming it's something with rust and ownership, which I'm still wrapping my head around.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment