cli: Add provider section to Anchor.toml (#305)

This commit is contained in:
Armani Ferrante 2021-05-23 10:00:24 -07:00 committed by GitHub
parent 8fa867fbd6
commit a9179600cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 80 additions and 47 deletions

View File

@ -18,12 +18,13 @@ incremented for features.
* cli: Add yarn flag to test command ([#267](https://github.com/project-serum/anchor/pull/267)). * cli: Add yarn flag to test command ([#267](https://github.com/project-serum/anchor/pull/267)).
* cli: Add `--skip-build` flag to test command ([301](https://github.com/project-serum/anchor/pull/301)). * cli: Add `--skip-build` flag to test command ([301](https://github.com/project-serum/anchor/pull/301)).
* cli: Add `anchor shell` command to spawn a node shell populated with an Anchor.toml based environment ([#303](https://github.com/project-serum/anchor/pull/303)). * cli: Add `anchor shell` command to spawn a node shell populated with an Anchor.toml based environment ([#303](https://github.com/project-serum/anchor/pull/303)).
* ts: Replace deprecated `web3.Account` with `web3.Signer` in public APIs ([#296](https://github.com/project-serum/anchor/pull/296)).
## Breaking Changes ## Breaking Changes
* cli: The Anchor.toml's `wallet` and `cluster` settings must now be under the `[provider]` table ([#305](https://github.com/project-serum/anchor/pull/305)).
* ts: Event coder `decode` API changed to decode strings directly instead of buffers ([#292](https://github.com/project-serum/anchor/pull/292)). * ts: Event coder `decode` API changed to decode strings directly instead of buffers ([#292](https://github.com/project-serum/anchor/pull/292)).
* ts: Event coder `encode` API removed ([#292](https://github.com/project-serum/anchor/pull/292)). * ts: Event coder `encode` API removed ([#292](https://github.com/project-serum/anchor/pull/292)).
* ts: Replace deprecated `web3.Account` with `web3.Signer` in public APIs ([#296](https://github.com/project-serum/anchor/pull/296)).
## [0.5.0] - 2021-05-07 ## [0.5.0] - 2021-05-07

View File

@ -13,12 +13,19 @@ use std::str::FromStr;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct Config { pub struct Config {
pub cluster: Cluster, pub provider: ProviderConfig,
pub clusters: Clusters, pub clusters: ClustersConfig,
pub wallet: WalletPath,
pub test: Option<Test>, pub test: Option<Test>,
} }
#[derive(Debug, Default)]
pub struct ProviderConfig {
pub cluster: Cluster,
pub wallet: WalletPath,
}
pub type ClustersConfig = BTreeMap<Cluster, BTreeMap<String, ProgramDeployment>>;
impl Config { impl Config {
// Searches all parent directories for an Anchor.toml file. // Searches all parent directories for an Anchor.toml file.
pub fn discover() -> Result<Option<(Self, PathBuf, Option<PathBuf>)>> { pub fn discover() -> Result<Option<(Self, PathBuf, Option<PathBuf>)>> {
@ -64,7 +71,7 @@ impl Config {
} }
pub fn wallet_kp(&self) -> Result<Keypair> { pub fn wallet_kp(&self) -> Result<Keypair> {
solana_sdk::signature::read_keypair_file(&self.wallet.to_string()) solana_sdk::signature::read_keypair_file(&self.provider.wallet.to_string())
.map_err(|_| anyhow!("Unable to read keypair file")) .map_err(|_| anyhow!("Unable to read keypair file"))
} }
} }
@ -73,12 +80,17 @@ impl Config {
// into base 58 strings. // into base 58 strings.
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct _Config { struct _Config {
cluster: String, provider: Provider,
wallet: String,
test: Option<Test>, test: Option<Test>,
clusters: Option<BTreeMap<String, BTreeMap<String, String>>>, clusters: Option<BTreeMap<String, BTreeMap<String, String>>>,
} }
#[derive(Debug, Serialize, Deserialize)]
struct Provider {
cluster: String,
wallet: String,
}
impl ToString for Config { impl ToString for Config {
fn to_string(&self) -> String { fn to_string(&self) -> String {
let clusters = { let clusters = {
@ -90,8 +102,10 @@ impl ToString for Config {
} }
}; };
let cfg = _Config { let cfg = _Config {
cluster: format!("{}", self.cluster), provider: Provider {
wallet: self.wallet.to_string(), cluster: format!("{}", self.provider.cluster),
wallet: self.provider.wallet.to_string(),
},
test: self.test.clone(), test: self.test.clone(),
clusters, clusters,
}; };
@ -107,8 +121,10 @@ impl FromStr for Config {
let cfg: _Config = toml::from_str(s) let cfg: _Config = toml::from_str(s)
.map_err(|e| anyhow::format_err!("Unable to deserialize config: {}", e.to_string()))?; .map_err(|e| anyhow::format_err!("Unable to deserialize config: {}", e.to_string()))?;
Ok(Config { Ok(Config {
cluster: cfg.cluster.parse()?, provider: ProviderConfig {
wallet: shellexpand::tilde(&cfg.wallet).parse()?, cluster: cfg.provider.cluster.parse()?,
wallet: shellexpand::tilde(&cfg.provider.wallet).parse()?,
},
test: cfg.test, test: cfg.test,
clusters: cfg clusters: cfg
.clusters .clusters
@ -233,8 +249,6 @@ impl Program {
} }
} }
pub type Clusters = BTreeMap<Cluster, BTreeMap<String, ProgramDeployment>>;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct ProgramDeployment { pub struct ProgramDeployment {
pub name: String, pub name: String,

View File

@ -540,7 +540,7 @@ fn verify(program_id: Pubkey) -> Result<()> {
let bin_path = program_dir let bin_path = program_dir
.join("../../target/deploy/") .join("../../target/deploy/")
.join(format!("{}.so", local_idl.name)); .join(format!("{}.so", local_idl.name));
let is_buffer = verify_bin(program_id, &bin_path, cfg.cluster.url())?; let is_buffer = verify_bin(program_id, &bin_path, cfg.provider.cluster.url())?;
// Verify IDL (only if it's not a buffer account). // Verify IDL (only if it's not a buffer account).
if !is_buffer { if !is_buffer {
@ -610,7 +610,7 @@ fn verify_bin(program_id: Pubkey, bin_path: &Path, cluster: &str) -> Result<bool
// Fetches an IDL for the given program_id. // Fetches an IDL for the given program_id.
fn fetch_idl(idl_addr: Pubkey) -> Result<Idl> { fn fetch_idl(idl_addr: Pubkey) -> Result<Idl> {
let cfg = Config::discover()?.expect("Inside a workspace").0; let cfg = Config::discover()?.expect("Inside a workspace").0;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
let mut account = client let mut account = client
.get_account_with_commitment(&idl_addr, CommitmentConfig::processed())? .get_account_with_commitment(&idl_addr, CommitmentConfig::processed())?
@ -669,7 +669,7 @@ fn idl(subcmd: IdlCommand) -> Result<()> {
fn idl_init(program_id: Pubkey, idl_filepath: String) -> Result<()> { fn idl_init(program_id: Pubkey, idl_filepath: String) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let keypair = cfg.wallet.to_string(); let keypair = cfg.provider.wallet.to_string();
let bytes = std::fs::read(idl_filepath)?; let bytes = std::fs::read(idl_filepath)?;
let idl: Idl = serde_json::from_reader(&*bytes)?; let idl: Idl = serde_json::from_reader(&*bytes)?;
@ -683,7 +683,7 @@ fn idl_init(program_id: Pubkey, idl_filepath: String) -> Result<()> {
fn idl_write_buffer(program_id: Pubkey, idl_filepath: String) -> Result<Pubkey> { fn idl_write_buffer(program_id: Pubkey, idl_filepath: String) -> Result<Pubkey> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let keypair = cfg.wallet.to_string(); let keypair = cfg.provider.wallet.to_string();
let bytes = std::fs::read(idl_filepath)?; let bytes = std::fs::read(idl_filepath)?;
let idl: Idl = serde_json::from_reader(&*bytes)?; let idl: Idl = serde_json::from_reader(&*bytes)?;
@ -699,9 +699,9 @@ fn idl_write_buffer(program_id: Pubkey, idl_filepath: String) -> Result<Pubkey>
fn idl_set_buffer(program_id: Pubkey, buffer: Pubkey) -> Result<()> { fn idl_set_buffer(program_id: Pubkey, buffer: Pubkey) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let keypair = solana_sdk::signature::read_keypair_file(&cfg.wallet.to_string()) let keypair = solana_sdk::signature::read_keypair_file(&cfg.provider.wallet.to_string())
.map_err(|_| anyhow!("Unable to read keypair file"))?; .map_err(|_| anyhow!("Unable to read keypair file"))?;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
// Instruction to set the buffer onto the IdlAccount. // Instruction to set the buffer onto the IdlAccount.
let set_buffer_ix = { let set_buffer_ix = {
@ -749,7 +749,7 @@ fn idl_upgrade(program_id: Pubkey, idl_filepath: String) -> Result<()> {
fn idl_authority(program_id: Pubkey) -> Result<()> { fn idl_authority(program_id: Pubkey) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
let idl_address = { let idl_address = {
let account = client let account = client
.get_account_with_commitment(&program_id, CommitmentConfig::processed())? .get_account_with_commitment(&program_id, CommitmentConfig::processed())?
@ -783,9 +783,9 @@ fn idl_set_authority(
None => IdlAccount::address(&program_id), None => IdlAccount::address(&program_id),
Some(addr) => addr, Some(addr) => addr,
}; };
let keypair = solana_sdk::signature::read_keypair_file(&cfg.wallet.to_string()) let keypair = solana_sdk::signature::read_keypair_file(&cfg.provider.wallet.to_string())
.map_err(|_| anyhow!("Unable to read keypair file"))?; .map_err(|_| anyhow!("Unable to read keypair file"))?;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
// Instruction data. // Instruction data.
let data = let data =
@ -853,9 +853,9 @@ fn idl_write(cfg: &Config, program_id: &Pubkey, idl: &Idl, idl_address: Pubkey)
idl.metadata = None; idl.metadata = None;
// Misc. // Misc.
let keypair = solana_sdk::signature::read_keypair_file(&cfg.wallet.to_string()) let keypair = solana_sdk::signature::read_keypair_file(&cfg.provider.wallet.to_string())
.map_err(|_| anyhow!("Unable to read keypair file"))?; .map_err(|_| anyhow!("Unable to read keypair file"))?;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
// Serialize and compress the idl. // Serialize and compress the idl.
let idl_data = { let idl_data = {
@ -950,7 +950,7 @@ fn test(
) -> Result<()> { ) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
// Bootup validator, if needed. // Bootup validator, if needed.
let validator_handle = match cfg.cluster.url() { let validator_handle = match cfg.provider.cluster.url() {
"http://127.0.0.1:8899" => { "http://127.0.0.1:8899" => {
match skip_build { match skip_build {
true => None, true => None,
@ -975,7 +975,7 @@ fn test(
}; };
// Setup log reader. // Setup log reader.
let log_streams = stream_logs(&cfg.cluster.url()); let log_streams = stream_logs(&cfg.provider.cluster.url());
// Check to see if yarn is installed, panic if not. // Check to see if yarn is installed, panic if not.
if use_yarn { if use_yarn {
@ -999,7 +999,7 @@ fn test(
.arg("-p") .arg("-p")
.arg("./tsconfig.json") .arg("./tsconfig.json")
.args(args) .args(args)
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url()) .env("ANCHOR_PROVIDER_URL", cfg.provider.cluster.url())
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -1008,7 +1008,7 @@ fn test(
(false, true) => std::process::Command::new("yarn") (false, true) => std::process::Command::new("yarn")
.arg("mocha") .arg("mocha")
.args(args) .args(args)
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url()) .env("ANCHOR_PROVIDER_URL", cfg.provider.cluster.url())
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -1018,7 +1018,7 @@ fn test(
.arg("-p") .arg("-p")
.arg("./tsconfig.json") .arg("./tsconfig.json")
.args(args) .args(args)
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url()) .env("ANCHOR_PROVIDER_URL", cfg.provider.cluster.url())
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -1026,7 +1026,7 @@ fn test(
.with_context(|| "ts-mocha"), .with_context(|| "ts-mocha"),
(false, false) => std::process::Command::new("mocha") (false, false) => std::process::Command::new("mocha")
.args(args) .args(args)
.env("ANCHOR_PROVIDER_URL", cfg.cluster.url()) .env("ANCHOR_PROVIDER_URL", cfg.provider.cluster.url())
.stdout(Stdio::inherit()) .stdout(Stdio::inherit())
.stderr(Stdio::inherit()) .stderr(Stdio::inherit())
.output() .output()
@ -1198,8 +1198,8 @@ fn _deploy(
) -> Result<Vec<(Pubkey, Program)>> { ) -> Result<Vec<(Pubkey, Program)>> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
// Fallback to config vars if not provided via CLI. // Fallback to config vars if not provided via CLI.
let url = url.unwrap_or_else(|| cfg.cluster.url().to_string()); let url = url.unwrap_or_else(|| cfg.provider.cluster.url().to_string());
let keypair = keypair.unwrap_or_else(|| cfg.wallet.to_string()); let keypair = keypair.unwrap_or_else(|| cfg.provider.wallet.to_string());
// Deploy the programs. // Deploy the programs.
println!("Deploying workspace: {}", url); println!("Deploying workspace: {}", url);
@ -1277,9 +1277,9 @@ fn upgrade(program_id: Pubkey, program_filepath: String) -> Result<()> {
.arg("program") .arg("program")
.arg("deploy") .arg("deploy")
.arg("--url") .arg("--url")
.arg(cfg.cluster.url()) .arg(cfg.provider.cluster.url())
.arg("--keypair") .arg("--keypair")
.arg(&cfg.wallet.to_string()) .arg(&cfg.provider.wallet.to_string())
.arg("--program-id") .arg("--program-id")
.arg(program_id.to_string()) .arg(program_id.to_string())
.arg(&program_filepath) .arg(&program_filepath)
@ -1306,8 +1306,8 @@ fn launch(
let programs = _deploy(url.clone(), keypair.clone(), program_name.clone())?; let programs = _deploy(url.clone(), keypair.clone(), program_name.clone())?;
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let url = url.unwrap_or_else(|| cfg.cluster.url().to_string()); let url = url.unwrap_or_else(|| cfg.provider.cluster.url().to_string());
let keypair = keypair.unwrap_or_else(|| cfg.wallet.to_string()); let keypair = keypair.unwrap_or_else(|| cfg.provider.wallet.to_string());
// Add metadata to all IDLs. // Add metadata to all IDLs.
for (address, program) in programs { for (address, program) in programs {
@ -1370,7 +1370,7 @@ fn create_idl_account(
let idl_address = IdlAccount::address(program_id); let idl_address = IdlAccount::address(program_id);
let keypair = solana_sdk::signature::read_keypair_file(keypair_path) let keypair = solana_sdk::signature::read_keypair_file(keypair_path)
.map_err(|_| anyhow!("Unable to read keypair file"))?; .map_err(|_| anyhow!("Unable to read keypair file"))?;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
let idl_data = serialize_idl(idl)?; let idl_data = serialize_idl(idl)?;
// Run `Create instruction. // Run `Create instruction.
@ -1423,7 +1423,7 @@ fn create_idl_buffer(
) -> Result<Pubkey> { ) -> Result<Pubkey> {
let keypair = solana_sdk::signature::read_keypair_file(keypair_path) let keypair = solana_sdk::signature::read_keypair_file(keypair_path)
.map_err(|_| anyhow!("Unable to read keypair file"))?; .map_err(|_| anyhow!("Unable to read keypair file"))?;
let client = RpcClient::new(cfg.cluster.url().to_string()); let client = RpcClient::new(cfg.provider.cluster.url().to_string());
let buffer = Keypair::generate(&mut OsRng); let buffer = Keypair::generate(&mut OsRng);
@ -1496,7 +1496,7 @@ fn migrate(url: Option<String>) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
println!("Running migration deploy script"); println!("Running migration deploy script");
let url = url.unwrap_or_else(|| cfg.cluster.url().to_string()); let url = url.unwrap_or_else(|| cfg.provider.cluster.url().to_string());
let cur_dir = std::env::current_dir()?; let cur_dir = std::env::current_dir()?;
let module_path = cur_dir.join("migrations/deploy.js"); let module_path = cur_dir.join("migrations/deploy.js");
@ -1607,11 +1607,11 @@ fn cluster(_cmd: ClusterCommand) -> Result<()> {
fn shell(cluster: Option<String>, wallet: Option<String>) -> Result<()> { fn shell(cluster: Option<String>, wallet: Option<String>) -> Result<()> {
with_workspace(|cfg, _path, _cargo| { with_workspace(|cfg, _path, _cargo| {
let cluster = match cluster { let cluster = match cluster {
None => cfg.cluster.clone(), None => cfg.provider.cluster.clone(),
Some(c) => Cluster::from_str(&c)?, Some(c) => Cluster::from_str(&c)?,
}; };
let wallet = match wallet { let wallet = match wallet {
None => cfg.wallet.to_string(), None => cfg.provider.wallet.to_string(),
Some(c) => c, Some(c) => c,
}; };
let programs = { let programs = {

View File

@ -182,15 +182,11 @@ pub fn ts_config() -> &'static str {
} }
pub fn git_ignore() -> &'static str { pub fn git_ignore() -> &'static str {
r#"# ignore Mac OS noise r#"
.DS_Store .DS_Store
# ignore the build directory for Rust/Anchor
target target
# Ignore backup files creates by cargo fmt.
**/*.rs.bk **/*.rs.bk
"# "#
} }
pub fn node_shell( pub fn node_shell(

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,3 +1,4 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,3 +1,4 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"

View File

@ -1,2 +1,3 @@
[provider]
cluster = "localnet" cluster = "localnet"
wallet = "~/.config/solana/id.json" wallet = "~/.config/solana/id.json"