Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit b27a96a

Browse files
ATA: Extract associated-token-account-client crate from associated-token-account crate (#7005)
* extract associated-token-address crate * use spl_associated_token_address in spl crates * use spl-program-ids in associated-token-address crate * update imports in repo * use solana-inline-spl instead of spl-program-ids * remove remaining references to spl-program-ids * Rename associated-token-address -> associated-token-account-client * Use the new package everywhere * Remove solana-inline-spl dependency * Remove dependency on ata program from token-client * Add #[doc(hidden)] attribute to internal function * Remove ATA from token upgrade CLI * Add program module for program id --------- Co-authored-by: Jon C <[email protected]>
1 parent fda1120 commit b27a96a

File tree

38 files changed

+272
-232
lines changed

38 files changed

+272
-232
lines changed

Cargo.lock

Lines changed: 16 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ split-debuginfo = "unpacked"
33

44
[workspace]
55
members = [
6+
"associated-token-account/client",
67
"associated-token-account/program",
78
"associated-token-account/program-test",
89
"binary-option/program",
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
[package]
2+
name = "spl-associated-token-account-client"
3+
version = "1.0.0"
4+
description = "Solana Program Library Associated Token Account Client"
5+
authors = ["Solana Labs Maintainers <[email protected]>"]
6+
repository = "https://github.com/solana-labs/solana-program-library"
7+
license = "Apache-2.0"
8+
edition = "2021"
9+
10+
[dependencies]
11+
solana-program = "2.0.3"
12+
13+
[package.metadata.docs.rs]
14+
targets = ["x86_64-unknown-linux-gnu"]
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//! Address derivation functions
2+
3+
use solana_program::pubkey::Pubkey;
4+
5+
/// Derives the associated token account address and bump seed
6+
/// for the given wallet address, token mint and token program id
7+
pub fn get_associated_token_address_and_bump_seed(
8+
wallet_address: &Pubkey,
9+
token_mint_address: &Pubkey,
10+
program_id: &Pubkey,
11+
token_program_id: &Pubkey,
12+
) -> (Pubkey, u8) {
13+
get_associated_token_address_and_bump_seed_internal(
14+
wallet_address,
15+
token_mint_address,
16+
program_id,
17+
token_program_id,
18+
)
19+
}
20+
21+
mod inline_spl_token {
22+
solana_program::declare_id!("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA");
23+
}
24+
25+
/// Derives the associated token account address for the given wallet address
26+
/// and token mint
27+
pub fn get_associated_token_address(
28+
wallet_address: &Pubkey,
29+
token_mint_address: &Pubkey,
30+
) -> Pubkey {
31+
get_associated_token_address_with_program_id(
32+
wallet_address,
33+
token_mint_address,
34+
&inline_spl_token::ID,
35+
)
36+
}
37+
38+
/// Derives the associated token account address for the given wallet address,
39+
/// token mint and token program id
40+
pub fn get_associated_token_address_with_program_id(
41+
wallet_address: &Pubkey,
42+
token_mint_address: &Pubkey,
43+
token_program_id: &Pubkey,
44+
) -> Pubkey {
45+
get_associated_token_address_and_bump_seed(
46+
wallet_address,
47+
token_mint_address,
48+
&crate::program::id(),
49+
token_program_id,
50+
)
51+
.0
52+
}
53+
54+
/// For internal use only.
55+
#[doc(hidden)]
56+
pub fn get_associated_token_address_and_bump_seed_internal(
57+
wallet_address: &Pubkey,
58+
token_mint_address: &Pubkey,
59+
program_id: &Pubkey,
60+
token_program_id: &Pubkey,
61+
) -> (Pubkey, u8) {
62+
Pubkey::find_program_address(
63+
&[
64+
&wallet_address.to_bytes(),
65+
&token_program_id.to_bytes(),
66+
&token_mint_address.to_bytes(),
67+
],
68+
program_id,
69+
)
70+
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
//! Instruction creators for the program
2+
use {
3+
crate::{address::get_associated_token_address_with_program_id, program::id},
4+
solana_program::{
5+
instruction::{AccountMeta, Instruction},
6+
pubkey::Pubkey,
7+
system_program,
8+
},
9+
};
10+
11+
fn build_associated_token_account_instruction(
12+
funding_address: &Pubkey,
13+
wallet_address: &Pubkey,
14+
token_mint_address: &Pubkey,
15+
token_program_id: &Pubkey,
16+
instruction: u8,
17+
) -> Instruction {
18+
let associated_account_address = get_associated_token_address_with_program_id(
19+
wallet_address,
20+
token_mint_address,
21+
token_program_id,
22+
);
23+
// safety check, assert if not a creation instruction, which is only 0 or 1
24+
assert!(instruction <= 1);
25+
Instruction {
26+
program_id: id(),
27+
accounts: vec![
28+
AccountMeta::new(*funding_address, true),
29+
AccountMeta::new(associated_account_address, false),
30+
AccountMeta::new_readonly(*wallet_address, false),
31+
AccountMeta::new_readonly(*token_mint_address, false),
32+
AccountMeta::new_readonly(system_program::id(), false),
33+
AccountMeta::new_readonly(*token_program_id, false),
34+
],
35+
data: vec![instruction],
36+
}
37+
}
38+
39+
/// Creates Create instruction
40+
pub fn create_associated_token_account(
41+
funding_address: &Pubkey,
42+
wallet_address: &Pubkey,
43+
token_mint_address: &Pubkey,
44+
token_program_id: &Pubkey,
45+
) -> Instruction {
46+
build_associated_token_account_instruction(
47+
funding_address,
48+
wallet_address,
49+
token_mint_address,
50+
token_program_id,
51+
0, // AssociatedTokenAccountInstruction::Create
52+
)
53+
}
54+
55+
/// Creates CreateIdempotent instruction
56+
pub fn create_associated_token_account_idempotent(
57+
funding_address: &Pubkey,
58+
wallet_address: &Pubkey,
59+
token_mint_address: &Pubkey,
60+
token_program_id: &Pubkey,
61+
) -> Instruction {
62+
build_associated_token_account_instruction(
63+
funding_address,
64+
wallet_address,
65+
token_mint_address,
66+
token_program_id,
67+
1, // AssociatedTokenAccountInstruction::CreateIdempotent
68+
)
69+
}
70+
71+
/// Creates a `RecoverNested` instruction
72+
pub fn recover_nested(
73+
wallet_address: &Pubkey,
74+
owner_token_mint_address: &Pubkey,
75+
nested_token_mint_address: &Pubkey,
76+
token_program_id: &Pubkey,
77+
) -> Instruction {
78+
let owner_associated_account_address = get_associated_token_address_with_program_id(
79+
wallet_address,
80+
owner_token_mint_address,
81+
token_program_id,
82+
);
83+
let destination_associated_account_address = get_associated_token_address_with_program_id(
84+
wallet_address,
85+
nested_token_mint_address,
86+
token_program_id,
87+
);
88+
let nested_associated_account_address = get_associated_token_address_with_program_id(
89+
&owner_associated_account_address, // ATA is wrongly used as a wallet_address
90+
nested_token_mint_address,
91+
token_program_id,
92+
);
93+
94+
Instruction {
95+
program_id: id(),
96+
accounts: vec![
97+
AccountMeta::new(nested_associated_account_address, false),
98+
AccountMeta::new_readonly(*nested_token_mint_address, false),
99+
AccountMeta::new(destination_associated_account_address, false),
100+
AccountMeta::new_readonly(owner_associated_account_address, false),
101+
AccountMeta::new_readonly(*owner_token_mint_address, false),
102+
AccountMeta::new(*wallet_address, true),
103+
AccountMeta::new_readonly(*token_program_id, false),
104+
],
105+
data: vec![2], // AssociatedTokenAccountInstruction::RecoverNested
106+
}
107+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
//! Client crate for interacting with the spl-associated-token-account program
2+
#![deny(missing_docs)]
3+
#![forbid(unsafe_code)]
4+
5+
pub mod address;
6+
pub mod instruction;
7+
8+
/// Module defining the program id
9+
pub mod program {
10+
solana_program::declare_id!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
11+
}

associated-token-account/program-test/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ solana-program = "2.0.3"
1515
solana-program-test = "2.0.3"
1616
solana-sdk = "2.0.3"
1717
spl-associated-token-account = { version = "4.0.0", path = "../program", features = ["no-entrypoint"] }
18+
spl-associated-token-account-client = { version = "1.0.0", path = "../client" }
1819
spl-token = { version = "6.0", path = "../../token/program", features = ["no-entrypoint"] }
1920
spl-token-2022 = { version = "4.0.0", path = "../../token/program-2022", features = ["no-entrypoint"] }

associated-token-account/program-test/tests/create_idempotent.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ use {
1717
},
1818
spl_associated_token_account::{
1919
error::AssociatedTokenAccountError,
20-
get_associated_token_address_with_program_id,
2120
instruction::{
2221
create_associated_token_account, create_associated_token_account_idempotent,
2322
},
2423
},
24+
spl_associated_token_account_client::address::get_associated_token_address_with_program_id,
2525
spl_token_2022::{
2626
extension::ExtensionType,
2727
instruction::initialize_account,

associated-token-account/program-test/tests/extended_mint.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@ use {
1313
signer::keypair::Keypair,
1414
transaction::{Transaction, TransactionError},
1515
},
16-
spl_associated_token_account::{
17-
get_associated_token_address_with_program_id, instruction::create_associated_token_account,
18-
},
16+
spl_associated_token_account::instruction::create_associated_token_account,
17+
spl_associated_token_account_client::address::get_associated_token_address_with_program_id,
1918
spl_token_2022::{
2019
error::TokenError,
2120
extension::{

associated-token-account/program-test/tests/process_create_associated_token_account.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ use {
1212
signature::Signer,
1313
transaction::{Transaction, TransactionError},
1414
},
15-
spl_associated_token_account::{
16-
get_associated_token_address_with_program_id, instruction::create_associated_token_account,
17-
},
15+
spl_associated_token_account::instruction::create_associated_token_account,
16+
spl_associated_token_account_client::address::get_associated_token_address_with_program_id,
1817
spl_token_2022::{extension::ExtensionType, state::Account},
1918
};
2019

0 commit comments

Comments
 (0)