From 9a62d60e237fc86d163b70a94badc3820dd99568 Mon Sep 17 00:00:00 2001 From: Will <82029448+wjthieme@users.noreply.github.com> Date: Wed, 16 Aug 2023 18:45:41 +0200 Subject: [PATCH 1/8] Update constraints.rs --- lang/syn/src/codegen/accounts/constraints.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index c144078dc8..d88ab9a54e 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -646,7 +646,7 @@ fn generate_constraint_init_group( return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociatedTokenTokenProgram).with_account_name(#name_str).with_pubkeys((*owner_program, #token_program.key()))); } - if pa.key() != ::anchor_spl::associated_token::get_associated_token_address(&#owner.key(), &#mint.key()) { + if pa.key() != ::anchor_spl::associated_token::get_associated_token_address_with_program_id(&#owner.key(), &#mint.key(), &#token_program.key()) { return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::AccountNotAssociatedTokenAccount).with_account_name(#name_str)); } } From 6279ebf72f39e8ab52f46ec4828495ed04d0b0a2 Mon Sep 17 00:00:00 2001 From: Wilhelm Thieme Date: Mon, 21 Aug 2023 19:28:47 +0200 Subject: [PATCH 2/8] Fixed the associated token constraint tests that include token program --- tests/misc/tests/misc/misc.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/tests/misc/tests/misc/misc.ts b/tests/misc/tests/misc/misc.ts index fd450588bf..ac2a639ea1 100644 --- a/tests/misc/tests/misc/misc.ts +++ b/tests/misc/tests/misc/misc.ts @@ -22,6 +22,10 @@ const { assert, expect } = require("chai"); const nativeAssert = require("assert"); const miscIdl = require("../../target/idl/misc.json"); +const TOKEN_2022_PROGRAM_ID = new anchor.web3.PublicKey( + "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" +); + const miscTest = ( program: anchor.Program | anchor.Program ) => { @@ -1060,14 +1064,14 @@ const miscTest = ( mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [newMint], }); const associatedToken = await Token.getAssociatedTokenAddress( ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, newMint.publicKey, provider.wallet.publicKey ); @@ -1078,7 +1082,7 @@ const miscTest = ( mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - associatedTokenTokenProgram: TOKEN_PROGRAM_ID, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, }, }); @@ -1086,7 +1090,7 @@ const miscTest = ( const token = new Token( program.provider.connection, newMint.publicKey, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, wallet.payer ); const ataAccount = await token.getAccountInfo(associatedToken); @@ -1767,14 +1771,14 @@ const miscTest = ( mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [newMint], }); const associatedToken = await Token.getAssociatedTokenAddress( ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, newMint.publicKey, provider.wallet.publicKey ); @@ -1786,7 +1790,7 @@ const miscTest = ( payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, - associatedTokenTokenProgram: TOKEN_PROGRAM_ID, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, authority: provider.wallet.publicKey, }, }); @@ -1794,7 +1798,7 @@ const miscTest = ( const mintClient = new Token( provider.connection, newMint.publicKey, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, wallet.payer ); const ataAccount = await mintClient.getAccountInfo(associatedToken); @@ -2439,14 +2443,14 @@ const miscTest = ( mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [mint], }); const associatedToken = await Token.getAssociatedTokenAddress( ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, mint.publicKey, provider.wallet.publicKey ); @@ -2457,7 +2461,7 @@ const miscTest = ( mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, + tokenProgram: TOKEN_2022_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, }, }); @@ -2468,7 +2472,7 @@ const miscTest = ( mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - associatedTokenTokenProgram: TOKEN_PROGRAM_ID, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, authority: provider.wallet.publicKey, }, From a8a88618a7d8e0edb062acc067852445236a99c0 Mon Sep 17 00:00:00 2001 From: Wilhelm Thieme Date: Tue, 22 Aug 2023 12:51:07 +0200 Subject: [PATCH 3/8] Fixed failing/wrong tests and added missing test cast --- .../programs/misc-optional/src/context.rs | 11 +- tests/misc/programs/misc/src/context.rs | 12 +- tests/misc/tests/misc/misc.ts | 170 ++++++++++-------- 3 files changed, 105 insertions(+), 88 deletions(-) diff --git a/tests/misc/programs/misc-optional/src/context.rs b/tests/misc/programs/misc-optional/src/context.rs index 85c3d7f506..f5432cf366 100644 --- a/tests/misc/programs/misc-optional/src/context.rs +++ b/tests/misc/programs/misc-optional/src/context.rs @@ -2,6 +2,7 @@ use crate::account::*; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token::{Mint, Token, TokenAccount}; +use anchor_spl::token_interface::{Mint as MintInterface, TokenAccount as TokenAccountInterface}; #[derive(Accounts)] pub struct TestTokenSeedsInit<'info> { @@ -55,8 +56,8 @@ pub struct TestInitAssociatedTokenWithTokenProgram<'info> { associated_token::authority = payer, associated_token::token_program = associated_token_token_program, )] - pub token: Option>, - pub mint: Option>, + pub token: Option>, + pub mint: Option>, #[account(mut)] pub payer: Option>, pub system_program: Option>, @@ -268,7 +269,7 @@ pub struct TestInitMintWithTokenProgram<'info> { mint::freeze_authority = payer, mint::token_program = mint_token_program, )] - pub mint: Option>, + pub mint: Option>, #[account(mut)] pub payer: Option>, pub system_program: Option>, @@ -465,8 +466,8 @@ pub struct TestInitAssociatedTokenIfNeededWithTokenProgram<'info> { associated_token::authority = authority, associated_token::token_program = associated_token_token_program, )] - pub token: Option>, - pub mint: Option>, + pub token: Option>, + pub mint: Option>, #[account(mut)] pub payer: Option>, pub system_program: Option>, diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index 9e1ad323ea..e50023f500 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -2,6 +2,7 @@ use crate::account::*; use anchor_lang::prelude::*; use anchor_spl::associated_token::AssociatedToken; use anchor_spl::token::{Mint, Token, TokenAccount}; +use anchor_spl::token_interface::{Mint as MintInterface, TokenAccount as TokenAccountInterface}; #[derive(Accounts)] pub struct TestTokenSeedsInit<'info> { @@ -47,6 +48,7 @@ pub struct TestInitAssociatedToken<'info> { pub associated_token_program: Program<'info, AssociatedToken>, } + #[derive(Accounts)] pub struct TestInitAssociatedTokenWithTokenProgram<'info> { #[account( @@ -56,8 +58,8 @@ pub struct TestInitAssociatedTokenWithTokenProgram<'info> { associated_token::authority = payer, associated_token::token_program = associated_token_token_program, )] - pub token: Account<'info, TokenAccount>, - pub mint: Account<'info, Mint>, + pub token: InterfaceAccount<'info, TokenAccountInterface>, + pub mint: InterfaceAccount<'info, MintInterface>, #[account(mut)] pub payer: Signer<'info>, pub system_program: Program<'info, System>, @@ -267,7 +269,7 @@ pub struct TestInitMintWithTokenProgram<'info> { mint::freeze_authority = payer, mint::token_program = mint_token_program, )] - pub mint: Account<'info, Mint>, + pub mint: InterfaceAccount<'info, MintInterface>, #[account(mut)] pub payer: Signer<'info>, pub system_program: Program<'info, System>, @@ -472,8 +474,8 @@ pub struct TestInitAssociatedTokenIfNeededWithTokenProgram<'info> { associated_token::authority = authority, associated_token::token_program = associated_token_token_program, )] - pub token: Account<'info, TokenAccount>, - pub mint: Account<'info, Mint>, + pub token: InterfaceAccount<'info, TokenAccountInterface>, + pub mint: InterfaceAccount<'info, MintInterface>, #[account(mut)] pub payer: Signer<'info>, pub system_program: Program<'info, System>, diff --git a/tests/misc/tests/misc/misc.ts b/tests/misc/tests/misc/misc.ts index ac2a639ea1..314f71b9e8 100644 --- a/tests/misc/tests/misc/misc.ts +++ b/tests/misc/tests/misc/misc.ts @@ -13,6 +13,8 @@ import { TOKEN_PROGRAM_ID, Token, ASSOCIATED_TOKEN_PROGRAM_ID, + AccountLayout, + MintLayout, } from "@solana/spl-token"; import { Misc } from "../../target/types/misc"; import { MiscOptional } from "../../target/types/misc_optional"; @@ -23,7 +25,7 @@ const nativeAssert = require("assert"); const miscIdl = require("../../target/idl/misc.json"); const TOKEN_2022_PROGRAM_ID = new anchor.web3.PublicKey( - "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" + "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb" ); const miscTest = ( @@ -961,28 +963,22 @@ const miscTest = ( mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - mintTokenProgram: TOKEN_PROGRAM_ID, + mintTokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [newMint], }); - const client = new Token( - program.provider.connection, - newMint.publicKey, - TOKEN_PROGRAM_ID, - wallet.payer - ); - const mintAccount = await client.getMintInfo(); + const rawAccount = await provider.connection.getAccountInfo(newMint.publicKey) + const mintAccount = MintLayout.decode(rawAccount.data); assert.strictEqual(mintAccount.decimals, 6); - assert.isTrue( - mintAccount.mintAuthority.equals(provider.wallet.publicKey) - ); - assert.isTrue( - mintAccount.freezeAuthority.equals(provider.wallet.publicKey) + assert.strictEqual( + new PublicKey(mintAccount.mintAuthority).toString(), + provider.wallet.publicKey.toString() ); - const accInfo = await program.provider.connection.getAccountInfo( - newMint.publicKey + assert.strictEqual( + new PublicKey(mintAccount.freezeAuthority).toString(), + provider.wallet.publicKey.toString() ); - assert.strictEqual(accInfo.owner.toString(), TOKEN_PROGRAM_ID.toString()); + assert.strictEqual(rawAccount.owner.toString(), TOKEN_2022_PROGRAM_ID.toString()); }); it("Can create a random token account with token program", async () => { @@ -998,22 +994,15 @@ const miscTest = ( signers: [token], }); - const client = new Token( - program.provider.connection, - mint.publicKey, - TOKEN_PROGRAM_ID, - wallet.payer - ); - const account = await client.getAccountInfo(token.publicKey); - // @ts-expect-error - assert.strictEqual(account.state, 1); - assert.strictEqual(account.amount.toNumber(), 0); - assert.isTrue(account.isInitialized); + const rawAccount = await provider.connection.getAccountInfo(token.publicKey) + const ataAccount = AccountLayout.decode(rawAccount.data); + assert.strictEqual(ataAccount.state, 1); + assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( - account.owner.toString(), + new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() ); - assert.strictEqual(account.mint.toString(), mint.publicKey.toString()); + assert.strictEqual(new PublicKey(ataAccount.mint).toString(), mint.publicKey.toString()); }); describe("associated_token constraints", () => { @@ -1059,12 +1048,12 @@ const miscTest = ( it("Can create an associated token account with token program", async () => { const newMint = anchor.web3.Keypair.generate(); - await program.rpc.testInitMint({ + await program.rpc.testInitMintWithTokenProgram({ accounts: { mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_2022_PROGRAM_ID, + mintTokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [newMint], }); @@ -1087,31 +1076,23 @@ const miscTest = ( }, }); - const token = new Token( - program.provider.connection, - newMint.publicKey, - TOKEN_2022_PROGRAM_ID, - wallet.payer + const rawAta = await provider.connection.getAccountInfo( + associatedToken ); - const ataAccount = await token.getAccountInfo(associatedToken); - // @ts-expect-error + const ataAccount = AccountLayout.decode(rawAta.data); assert.strictEqual(ataAccount.state, 1); - assert.strictEqual(ataAccount.amount.toNumber(), 0); - assert.isTrue(ataAccount.isInitialized); + assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( - ataAccount.owner.toString(), + new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() ); assert.strictEqual( - ataAccount.mint.toString(), + new PublicKey(ataAccount.mint).toString(), newMint.publicKey.toString() ); - const rawAta = await provider.connection.getAccountInfo( - associatedToken - ); assert.strictEqual( rawAta.owner.toBase58(), - TOKEN_PROGRAM_ID.toBase58() + TOKEN_2022_PROGRAM_ID.toBase58() ); }); @@ -1683,25 +1664,21 @@ const miscTest = ( }, signers: [newToken], }); - const mintClient = new Token( - provider.connection, - newMint.publicKey, - TOKEN_PROGRAM_ID, - wallet.payer + + const rawAccount = await provider.connection.getAccountInfo( + newToken.publicKey ); - const tokenAccount = await mintClient.getAccountInfo(newToken.publicKey); - assert.strictEqual(tokenAccount.amount.toNumber(), 0); + const ataAccount = AccountLayout.decode(rawAccount.data); + assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( - tokenAccount.mint.toString(), + new PublicKey(ataAccount.mint).toString(), newMint.publicKey.toString() ); assert.strictEqual( - tokenAccount.owner.toString(), + new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() ); - const rawAccount = await provider.connection.getAccountInfo( - newToken.publicKey - ); + assert.strictEqual( rawAccount.owner.toString(), TOKEN_PROGRAM_ID.toString() @@ -1766,12 +1743,12 @@ const miscTest = ( it("init_if_needed creates associated token account if not exists with token program", async () => { const newMint = anchor.web3.Keypair.generate(); - await program.rpc.testInitMint({ + await program.rpc.testInitMintWithTokenProgram({ accounts: { mint: newMint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_2022_PROGRAM_ID, + mintTokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [newMint], }); @@ -1795,28 +1772,22 @@ const miscTest = ( }, }); - const mintClient = new Token( - provider.connection, - newMint.publicKey, - TOKEN_2022_PROGRAM_ID, - wallet.payer + const rawAccount = await provider.connection.getAccountInfo( + associatedToken ); - const ataAccount = await mintClient.getAccountInfo(associatedToken); - assert.strictEqual(ataAccount.amount.toNumber(), 0); + const ataAccount = AccountLayout.decode(rawAccount.data); + assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( - ataAccount.mint.toString(), + new PublicKey(ataAccount.mint).toString(), newMint.publicKey.toString() ); assert.strictEqual( - ataAccount.owner.toString(), + new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() ); - const rawAccount = await provider.connection.getAccountInfo( - associatedToken - ); assert.strictEqual( rawAccount.owner.toString(), - TOKEN_PROGRAM_ID.toString() + TOKEN_2022_PROGRAM_ID.toString() ); }); @@ -2436,21 +2407,21 @@ const miscTest = ( } }); - it("init_if_needed pass if associated token exists with token program", async () => { + it("init_if_needed pass if associated token exists", async () => { const mint = anchor.web3.Keypair.generate(); await program.rpc.testInitMint({ accounts: { mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_2022_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, }, signers: [mint], }); const associatedToken = await Token.getAssociatedTokenAddress( ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_2022_PROGRAM_ID, + TOKEN_PROGRAM_ID, mint.publicKey, provider.wallet.publicKey ); @@ -2461,7 +2432,50 @@ const miscTest = ( mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_2022_PROGRAM_ID, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + }, + }); + + await program.rpc.testInitAssociatedTokenIfNeeded({ + accounts: { + token: associatedToken, + mint: mint.publicKey, + payer: provider.wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + tokenProgram: TOKEN_PROGRAM_ID, + associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + authority: provider.wallet.publicKey, + }, + }); + }); + + it("init_if_needed pass if associated token exists with token program", async () => { + const mint = anchor.web3.Keypair.generate(); + await program.rpc.testInitMintWithTokenProgram({ + accounts: { + mint: mint.publicKey, + payer: provider.wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + mintTokenProgram: TOKEN_2022_PROGRAM_ID, + }, + signers: [mint], + }); + + const associatedToken = await Token.getAssociatedTokenAddress( + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, + mint.publicKey, + provider.wallet.publicKey + ); + + await program.rpc.testInitAssociatedTokenWithTokenProgram({ + accounts: { + token: associatedToken, + mint: mint.publicKey, + payer: provider.wallet.publicKey, + systemProgram: anchor.web3.SystemProgram.programId, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, }, }); From df789de6c239518e1cd8646fd8ad619016564352 Mon Sep 17 00:00:00 2001 From: Wilhelm Thieme Date: Tue, 22 Aug 2023 15:07:48 +0200 Subject: [PATCH 4/8] Run prettier --- tests/misc/tests/misc/misc.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/tests/misc/tests/misc/misc.ts b/tests/misc/tests/misc/misc.ts index 314f71b9e8..710d800b1c 100644 --- a/tests/misc/tests/misc/misc.ts +++ b/tests/misc/tests/misc/misc.ts @@ -967,7 +967,9 @@ const miscTest = ( }, signers: [newMint], }); - const rawAccount = await provider.connection.getAccountInfo(newMint.publicKey) + const rawAccount = await provider.connection.getAccountInfo( + newMint.publicKey + ); const mintAccount = MintLayout.decode(rawAccount.data); assert.strictEqual(mintAccount.decimals, 6); assert.strictEqual( @@ -978,7 +980,10 @@ const miscTest = ( new PublicKey(mintAccount.freezeAuthority).toString(), provider.wallet.publicKey.toString() ); - assert.strictEqual(rawAccount.owner.toString(), TOKEN_2022_PROGRAM_ID.toString()); + assert.strictEqual( + rawAccount.owner.toString(), + TOKEN_2022_PROGRAM_ID.toString() + ); }); it("Can create a random token account with token program", async () => { @@ -994,7 +999,9 @@ const miscTest = ( signers: [token], }); - const rawAccount = await provider.connection.getAccountInfo(token.publicKey) + const rawAccount = await provider.connection.getAccountInfo( + token.publicKey + ); const ataAccount = AccountLayout.decode(rawAccount.data); assert.strictEqual(ataAccount.state, 1); assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); @@ -1002,7 +1009,10 @@ const miscTest = ( new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() ); - assert.strictEqual(new PublicKey(ataAccount.mint).toString(), mint.publicKey.toString()); + assert.strictEqual( + new PublicKey(ataAccount.mint).toString(), + mint.publicKey.toString() + ); }); describe("associated_token constraints", () => { From 456e7528e0741bf7d3b4933e1dabb8b496f2ffa8 Mon Sep 17 00:00:00 2001 From: Wilhelm Thieme Date: Tue, 22 Aug 2023 16:29:34 +0200 Subject: [PATCH 5/8] Fixed a test where BN is not defined --- tests/misc/tests/misc/misc.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/misc/tests/misc/misc.ts b/tests/misc/tests/misc/misc.ts index 710d800b1c..01d4b5fd3c 100644 --- a/tests/misc/tests/misc/misc.ts +++ b/tests/misc/tests/misc/misc.ts @@ -1004,7 +1004,7 @@ const miscTest = ( ); const ataAccount = AccountLayout.decode(rawAccount.data); assert.strictEqual(ataAccount.state, 1); - assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); + assert.strictEqual(new anchor.BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() @@ -1091,7 +1091,7 @@ const miscTest = ( ); const ataAccount = AccountLayout.decode(rawAta.data); assert.strictEqual(ataAccount.state, 1); - assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); + assert.strictEqual(new anchor.BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( new PublicKey(ataAccount.owner).toString(), provider.wallet.publicKey.toString() @@ -1679,7 +1679,7 @@ const miscTest = ( newToken.publicKey ); const ataAccount = AccountLayout.decode(rawAccount.data); - assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); + assert.strictEqual(new anchor.BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( new PublicKey(ataAccount.mint).toString(), newMint.publicKey.toString() @@ -1786,7 +1786,7 @@ const miscTest = ( associatedToken ); const ataAccount = AccountLayout.decode(rawAccount.data); - assert.strictEqual(new BN(ataAccount.amount).toNumber(), 0); + assert.strictEqual(new anchor.BN(ataAccount.amount).toNumber(), 0); assert.strictEqual( new PublicKey(ataAccount.mint).toString(), newMint.publicKey.toString() From 3de9ab7266b494a4e6aa52092b2b5d578eabb5a5 Mon Sep 17 00:00:00 2001 From: acheron Date: Wed, 23 Aug 2023 18:23:29 +0200 Subject: [PATCH 6/8] Modify a test to use Token 2022 to show non-init error case --- tests/misc/programs/misc-optional/src/context.rs | 4 ++-- tests/misc/programs/misc/src/context.rs | 5 ++--- tests/misc/tests/misc/misc.ts | 14 +++++++------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/tests/misc/programs/misc-optional/src/context.rs b/tests/misc/programs/misc-optional/src/context.rs index f5432cf366..b47b53cc8b 100644 --- a/tests/misc/programs/misc-optional/src/context.rs +++ b/tests/misc/programs/misc-optional/src/context.rs @@ -712,8 +712,8 @@ pub struct TestAssociatedTokenWithTokenProgramConstraint<'info> { associated_token::authority = authority, associated_token::token_program = associated_token_token_program, )] - pub token: Option>, - pub mint: Account<'info, Mint>, + pub token: Option>, + pub mint: InterfaceAccount<'info, MintInterface>, /// CHECK: ignore pub authority: AccountInfo<'info>, /// CHECK: ignore diff --git a/tests/misc/programs/misc/src/context.rs b/tests/misc/programs/misc/src/context.rs index e50023f500..4cf65b92fd 100644 --- a/tests/misc/programs/misc/src/context.rs +++ b/tests/misc/programs/misc/src/context.rs @@ -48,7 +48,6 @@ pub struct TestInitAssociatedToken<'info> { pub associated_token_program: Program<'info, AssociatedToken>, } - #[derive(Accounts)] pub struct TestInitAssociatedTokenWithTokenProgram<'info> { #[account( @@ -729,8 +728,8 @@ pub struct TestAssociatedTokenWithTokenProgramConstraint<'info> { associated_token::authority = authority, associated_token::token_program = associated_token_token_program, )] - pub token: Account<'info, TokenAccount>, - pub mint: Account<'info, Mint>, + pub token: InterfaceAccount<'info, TokenAccountInterface>, + pub mint: InterfaceAccount<'info, MintInterface>, /// CHECK: ignore pub authority: AccountInfo<'info>, /// CHECK: ignore diff --git a/tests/misc/tests/misc/misc.ts b/tests/misc/tests/misc/misc.ts index 01d4b5fd3c..af71d07b8d 100644 --- a/tests/misc/tests/misc/misc.ts +++ b/tests/misc/tests/misc/misc.ts @@ -1195,31 +1195,31 @@ const miscTest = ( it("associated_token constraints (no init) - Can make with associated_token::token_program", async () => { const mint = anchor.web3.Keypair.generate(); - await program.rpc.testInitMint({ + await program.rpc.testInitMintWithTokenProgram({ accounts: { mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, + mintTokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [mint], }); const associatedToken = await Token.getAssociatedTokenAddress( ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, mint.publicKey, provider.wallet.publicKey ); - await program.rpc.testInitAssociatedToken({ + await program.rpc.testInitAssociatedTokenWithTokenProgram({ accounts: { token: associatedToken, mint: mint.publicKey, payer: provider.wallet.publicKey, systemProgram: anchor.web3.SystemProgram.programId, - tokenProgram: TOKEN_PROGRAM_ID, associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, }, signers: [], }); @@ -1228,7 +1228,7 @@ const miscTest = ( token: associatedToken, mint: mint.publicKey, authority: provider.wallet.publicKey, - associatedTokenTokenProgram: TOKEN_PROGRAM_ID, + associatedTokenTokenProgram: TOKEN_2022_PROGRAM_ID, }, }); @@ -1237,7 +1237,7 @@ const miscTest = ( ); assert.strictEqual( account.owner.toString(), - TOKEN_PROGRAM_ID.toString() + TOKEN_2022_PROGRAM_ID.toString() ); }); From a70c48bc70af7dd0aeb7f8a7d7d756a907d94a11 Mon Sep 17 00:00:00 2001 From: acheron Date: Wed, 23 Aug 2023 19:23:26 +0200 Subject: [PATCH 7/8] Fix non-init `associated_token::token_program` --- lang/syn/src/codegen/accounts/constraints.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lang/syn/src/codegen/accounts/constraints.rs b/lang/syn/src/codegen/accounts/constraints.rs index d88ab9a54e..63f22bd334 100644 --- a/lang/syn/src/codegen/accounts/constraints.rs +++ b/lang/syn/src/codegen/accounts/constraints.rs @@ -913,6 +913,7 @@ fn generate_constraint_associated_token( let name_str = name.to_string(); let wallet_address = &c.wallet; let spl_token_mint_address = &c.mint; + let mut optional_check_scope = OptionalCheckScope::new_with_field(accs, name); let wallet_address_optional_check = optional_check_scope.generate_check(wallet_address); let spl_token_mint_address_optional_check = @@ -921,6 +922,7 @@ fn generate_constraint_associated_token( #wallet_address_optional_check #spl_token_mint_address_optional_check }; + let token_program_check = match &c.token_program { Some(token_program) => { let token_program_optional_check = optional_check_scope.generate_check(token_program); @@ -931,6 +933,14 @@ fn generate_constraint_associated_token( } None => quote! {}, }; + let get_associated_token_address = match &c.token_program { + Some(token_program) => quote! { + ::anchor_spl::associated_token::get_associated_token_address_with_program_id(&wallet_address, &#spl_token_mint_address.key(), &#token_program.key()) + }, + None => quote! { + ::anchor_spl::associated_token::get_associated_token_address(&wallet_address, &#spl_token_mint_address.key()) + }, + }; quote! { { @@ -942,7 +952,7 @@ fn generate_constraint_associated_token( if my_owner != wallet_address { return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintTokenOwner).with_account_name(#name_str).with_pubkeys((my_owner, wallet_address))); } - let __associated_token_address = ::anchor_spl::associated_token::get_associated_token_address(&wallet_address, &#spl_token_mint_address.key()); + let __associated_token_address = #get_associated_token_address; let my_key = #name.key(); if my_key != __associated_token_address { return Err(anchor_lang::error::Error::from(anchor_lang::error::ErrorCode::ConstraintAssociated).with_account_name(#name_str).with_pubkeys((my_key, __associated_token_address))); From 6f7f200d538cd1c0cfd962493ba65c4a426e1ef9 Mon Sep 17 00:00:00 2001 From: acheron Date: Wed, 23 Aug 2023 20:00:49 +0200 Subject: [PATCH 8/8] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f71715fcc7..2f38848dd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ The minor version will be incremented upon a breaking change and the patch versi - client: Compile with Solana `1.14` ([#2572](https://github.com/coral-xyz/anchor/pull/2572)). - cli: Fix `anchor build --no-docs` adding docs to the IDL ([#2575](https://github.com/coral-xyz/anchor/pull/2575)). - ts: Load workspace programs on-demand rather than loading all of them at once ([#2579](https://github.com/coral-xyz/anchor/pull/2579)). +- lang: Fix `associated_token::token_program` constraint ([#2603](https://github.com/coral-xyz/anchor/pull/2603)). ### Breaking