cli: Accounts subcmd
This commit is contained in:
parent
1fcea7cf01
commit
e4ef35bb19
|
@ -104,6 +104,7 @@ dependencies = [
|
|||
"anchor-lang",
|
||||
"anchor-syn",
|
||||
"anyhow",
|
||||
"bs58",
|
||||
"clap 3.0.0-beta.2",
|
||||
"dirs",
|
||||
"flate2",
|
||||
|
@ -113,6 +114,7 @@ dependencies = [
|
|||
"serde_yaml",
|
||||
"serum-common",
|
||||
"shellexpand",
|
||||
"solana-account-decoder",
|
||||
"solana-client",
|
||||
"solana-program",
|
||||
"solana-sdk",
|
||||
|
|
|
@ -22,7 +22,9 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
solana-sdk = "1.5.0"
|
||||
solana-program = "1.5.0"
|
||||
solana-client = "1.4.4"
|
||||
solana-account-decoder = "1.4.13"
|
||||
serum-common = { git = "https://github.com/project-serum/serum-dex", features = ["client"] }
|
||||
dirs = "3.0"
|
||||
heck = "0.3.1"
|
||||
flate2 = "1.0.19"
|
||||
bs58 = "0.3.1"
|
|
@ -8,8 +8,12 @@ use flate2::read::ZlibDecoder;
|
|||
use flate2::write::ZlibEncoder;
|
||||
use flate2::Compression;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use solana_account_decoder::UiAccountEncoding;
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_client::rpc_config::RpcSendTransactionConfig;
|
||||
use solana_client::rpc_config::{
|
||||
RpcAccountInfoConfig, RpcProgramAccountsConfig, RpcSendTransactionConfig,
|
||||
};
|
||||
use solana_client::rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType};
|
||||
use solana_program::instruction::{AccountMeta, Instruction};
|
||||
use solana_sdk::commitment_config::CommitmentConfig;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
@ -34,17 +38,13 @@ pub struct Opts {
|
|||
pub enum Command {
|
||||
/// Initializes a workspace.
|
||||
Init { name: String },
|
||||
/// Builds a Solana program.
|
||||
Build {
|
||||
/// Output directory for the IDL.
|
||||
#[clap(short, long)]
|
||||
idl: Option<String>,
|
||||
},
|
||||
/// Runs integration tests against a localnetwork.
|
||||
/// Builds programs.
|
||||
Build,
|
||||
/// Runs integration tests.
|
||||
Test,
|
||||
/// Creates a new program.
|
||||
New { name: String },
|
||||
/// Commands for interact with interface definitions.
|
||||
/// Commands for interface definitions.
|
||||
Idl {
|
||||
#[clap(subcommand)]
|
||||
subcmd: IdlCommand,
|
||||
|
@ -65,6 +65,10 @@ pub enum Command {
|
|||
/// Not yet implemented. Please use `solana program deploy` command to
|
||||
/// upgrade your program.
|
||||
Upgrade {},
|
||||
Account {
|
||||
#[clap(subcommand)]
|
||||
subcmd: AccountCommand,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clap)]
|
||||
|
@ -93,12 +97,25 @@ pub enum IdlCommand {
|
|||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clap)]
|
||||
pub enum AccountCommand {
|
||||
/// Outputs program owned accounts.
|
||||
List {
|
||||
#[clap(short, long)]
|
||||
program: Pubkey,
|
||||
/// The account kind. Matches the type defined in the program source,
|
||||
/// lowercase.
|
||||
#[clap(short, long)]
|
||||
kind: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let opts = Opts::parse();
|
||||
|
||||
match opts.command {
|
||||
Command::Init { name } => init(name),
|
||||
Command::Build { idl } => build(idl),
|
||||
Command::Build => build(None),
|
||||
Command::Test => test(),
|
||||
Command::New { name } => new(name),
|
||||
Command::Idl { subcmd } => idl(subcmd),
|
||||
|
@ -108,14 +125,61 @@ fn main() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
Command::Migrate { url } => migrate(&url),
|
||||
Command::Account { subcmd } => account(subcmd),
|
||||
}
|
||||
}
|
||||
|
||||
fn account(cmd: AccountCommand) -> Result<()> {
|
||||
match cmd {
|
||||
AccountCommand::List { program, kind } => account_list(program, kind),
|
||||
}
|
||||
}
|
||||
|
||||
fn account_list(program: Pubkey, kind: Option<String>) -> Result<()> {
|
||||
let cfg = Config::discover()?.expect("Must be inside a workspace").0;
|
||||
let client = RpcClient::new(cfg.cluster.url().to_string());
|
||||
|
||||
// Filter on the 8 byte account discriminator.
|
||||
let filters = kind.map(|kind| {
|
||||
let filter_bytes = {
|
||||
let discriminator_preimage = format!("account:{}", kind);
|
||||
let mut disc = [0u8; 8];
|
||||
disc.copy_from_slice(
|
||||
&solana_program::hash::hash(discriminator_preimage.as_bytes()).to_bytes()[..8],
|
||||
);
|
||||
bs58::encode(disc).into_string()
|
||||
};
|
||||
let disc_filter = RpcFilterType::Memcmp(Memcmp {
|
||||
offset: 0,
|
||||
bytes: MemcmpEncodedBytes::Binary(filter_bytes),
|
||||
encoding: None,
|
||||
});
|
||||
|
||||
vec![disc_filter]
|
||||
});
|
||||
|
||||
let resp = client.get_program_accounts_with_config(
|
||||
&program,
|
||||
RpcProgramAccountsConfig {
|
||||
filters,
|
||||
account_config: RpcAccountInfoConfig {
|
||||
encoding: Some(UiAccountEncoding::Base64),
|
||||
..RpcAccountInfoConfig::default()
|
||||
},
|
||||
},
|
||||
)?;
|
||||
|
||||
println!("RESP {:?}", resp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init(name: String) -> Result<()> {
|
||||
let cfg = Config::discover()?;
|
||||
|
||||
if cfg.is_some() {
|
||||
println!("Anchor workspace already initialized");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fs::create_dir(name.clone())?;
|
||||
|
|
Loading…
Reference in New Issue