Skip to content

Commit

Permalink
Merge pull request #102 from Ackee-Blockchain/feat/anchor-keypair
Browse files Browse the repository at this point in the history
✨ Added new function to read keypair file generated by Anchor
  • Loading branch information
lukacan committed Sep 26, 2023
2 parents 91f320d + d8a6a71 commit d771595
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 16 deletions.
15 changes: 3 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,11 @@ async fn init_fixture() -> Fixture {
// create a test fixture
let mut fixture = Fixture {
client: Client::new(system_keypair(0)),
// make sure your program is using a correct program ID
program: program_keypair(1),
// make sure to pass the correct name of your program
program: anchor_keypair("my_program_name").unwrap(),
state: keypair(42),
};
// deploy a tested program
// deploy the program to test
fixture.deploy().await?;
// call instruction init
my_instruction::initialize(
Expand Down Expand Up @@ -129,15 +129,6 @@ async fn test_happy_path(#[future] init_fixture: Result<Fixture>) {
}
```

Make sure your program is using a correct program ID in the `derive_id!(...)` macro and inside `Anchor.toml`.
If not, obtain the public key of a key pair you're using and replace it in these two places.
To get the program ID of a key pair (key pair's public key) the `trdelnik key-pair` command can be used.
For example
```
$ trdelnik key-pair program 7
```
will print information about the key pair received from `program_keypair(7)`.

#### Instructions with custom structures

- If you want to test an instruction which has custom structure as an argument
Expand Down
33 changes: 33 additions & 0 deletions crates/client/src/keys.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
use std::error::Error;

use anchor_client::solana_sdk::signer::keypair::Keypair;
use heck::ToSnakeCase;
use solana_sdk::signer::EncodableKey;

use crate::config::Config;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum KeyPairError {
#[error("Cannot find the Anchor.toml file to locate the root folder")]
BadWorkspace,
#[error("Cannot the program keypair JSON file generated by Anchor")]
AnchorKeypairNotFound,
}

/// Reads program keypair JSON file generated by Anchor based on `program_name`. Returns error if not found.
pub fn anchor_keypair(program_name: &str) -> Result<Keypair, Box<dyn Error>> {
let root = match Config::discover_root() {
Ok(root) => root,
Err(_) => return Err(KeyPairError::BadWorkspace.into()),
};
let keypair_path = root
.join("target")
.join("deploy")
.join(format!("{}-keypair.json", program_name.to_snake_case()));

if !keypair_path.exists() {
return Err(KeyPairError::AnchorKeypairNotFound.into());
}

Keypair::read_from_file(keypair_path)
}

/// Generate a random keypair.
pub fn random_keypair() -> Keypair {
Expand Down
3 changes: 1 addition & 2 deletions crates/client/src/templates/trdelnik-tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use fehler::throws;
use program_client::*;
use trdelnik_client::{anyhow::Result, *};

// @todo: create and deploy your fixture
Expand Down Expand Up @@ -30,7 +29,7 @@ impl Fixture {
fn new() -> Self {
Fixture {
client: Client::new(system_keypair(0)),
program: program_keypair(1),
program: anchor_keypair("###PROGRAM_NAME###").unwrap(),
state: keypair(42),
}
}
Expand Down
5 changes: 4 additions & 1 deletion crates/client/src/test_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ impl TestGenerator {
throw!(Error::NoProgramsFound)
};
let test_content = test_content.replace("###PROGRAM_NAME###", program_name);
self.create_file(&test_path, TESTS_FILE_NAME, &test_content)
let use_instructions = format!("use program_client::{}_instruction::*;\n", program_name);
let template = format!("{use_instructions}{test_content}");

self.create_file(&test_path, TESTS_FILE_NAME, &template)
.await?;

let cargo_toml_path = workspace_path.join(CARGO_TOML);
Expand Down
6 changes: 5 additions & 1 deletion examples/escrow/trdelnik-tests/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,8 +200,12 @@ impl Fixture {
fn new() -> Self {
Fixture {
client: Client::new(system_keypair(0)),
program: program_keypair(1),

// We use the hardcoded program_keypair(1) to ensure users can run these tests without the
// need to modify the program ID in the program's lib.rs source file and in Anchor.toml configuraiton file.
// However the default option in the test template is now to use the keypair generated by Anchor
// located in target/deploy folder using the function anchor_keypair("name_of_your_program").
program: program_keypair(1),
mint_a: keypair(1),
mint_b: keypair(2),
mint_authority: system_keypair(1),
Expand Down
5 changes: 5 additions & 0 deletions examples/turnstile/trdelnik-tests/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ async fn init_fixture() -> Fixture {
// create a test fixture
let fixture = Fixture {
client: Client::new(system_keypair(0)),

// We use the hardcoded program_keypair(1) to ensure users can run these tests without the
// need to modify the program ID in the program's lib.rs source file and in Anchor.toml configuraiton file.
// However the default option in the test template is now to use the keypair generated by Anchor
// located in target/deploy folder using the function anchor_keypair("name_of_your_program").
program: program_keypair(1),
state: keypair(42),
user_initializer: keypair(45),
Expand Down

0 comments on commit d771595

Please sign in to comment.