pyth2wormhole: Add client with working initialize

Change-Id: Ie8d99373c4b7d91d1445f9697714493c32d2bd5a
This commit is contained in:
Stan Drozd 2021-06-25 17:37:43 +02:00 committed by Stanislaw Drozd
parent 2f4517e45a
commit 4fcc4f5674
6 changed files with 3496 additions and 61 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,2 +1,2 @@
[workspace]
members = [".", "program"]
members = ["client", "program"]

View File

@ -0,0 +1,22 @@
[package]
name = "pyth2wormhole-client"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = ["pyth2wormhole/client"]
[dependencies]
borsh = "0.8.1"
clap = "3.0.0-beta.2" # This beta assimilates structopt into clap
env_logger = "0.8.4"
log = "0.4.14"
pyth2wormhole = {path = "../program"}
shellexpand = "2.1.0"
solana-client = "=1.7.0"
solana-program = "=1.7.0"
solana-sdk = "=1.7.0"
solitaire-client = {path = "../../solitaire/client"}
solitaire = {path = "../../solitaire/program"}

View File

@ -0,0 +1,50 @@
//! CLI options
use solana_program::pubkey::Pubkey;
use clap::Clap;
#[derive(Clap)]
#[clap(
about = "A client for the pyth2wormhole Solana program",
author = "The Wormhole Project"
)]
pub struct Cli {
#[clap(
short,
long,
default_value = "3",
about = "Logging level, where 0..=1 RUST_LOG=error and 5.. is RUST_LOG=trace"
)]
pub log_level: u32,
#[clap(
long,
about = "Identity JSON file for the entity meant to cover transaction costs",
default_value = "~/.config/solana/id.json"
)]
pub payer: String,
#[clap(long, default_value = "http://localhost:8899")]
pub rpc_url: String,
pub p2w_addr: Pubkey,
#[clap(subcommand)]
pub action: Action,
}
#[derive(Clap)]
pub enum Action {
#[clap(about = "Initialize a pyth2wormhole program freshly deployed under <p2w_addr>")]
Init {
#[clap(long = "owner")]
new_owner_addr: Pubkey,
#[clap(long = "wormhole")]
wormhole_addr: Pubkey,
#[clap(long = "pyth")]
pyth_owner_addr: Pubkey,
},
#[clap(
about = "Use an existing pyth2wormhole program to forward product price information to another chain"
)]
Forward {
#[clap(long = "product")]
product_addr: Pubkey,
},
}

View File

@ -0,0 +1,100 @@
pub mod cli;
use borsh::BorshSerialize;
use clap::Clap;
use log::LevelFilter;
use solana_client::rpc_client::RpcClient;
use solana_program::{hash::Hash, pubkey::Pubkey};
use solana_sdk::{
commitment_config::CommitmentConfig, signature::read_keypair_file, transaction::Transaction,
};
use solitaire::{AccountState, processors::seeded::Seeded};
use solitaire_client::{AccEntry, Keypair, SolSigner, ToInstruction};
use cli::{Action, Cli};
use pyth2wormhole::{config::P2WConfigAccount, initialize::InitializeAccounts, Pyth2WormholeConfig};
pub type ErrBox = Box<dyn std::error::Error>;
fn main() -> Result<(), ErrBox> {
let cli = Cli::parse();
init_logging(cli.log_level);
let payer = read_keypair_file(&*shellexpand::tilde(&cli.payer))?;
let rpc_client = RpcClient::new_with_commitment(cli.rpc_url, CommitmentConfig::processed());
let p2w_addr = cli.p2w_addr;
let (recent_blockhash, _) = rpc_client.get_recent_blockhash()?;
let tx = match cli.action {
Action::Init {
new_owner_addr,
wormhole_addr,
pyth_owner_addr,
} => handle_init(
payer,
p2w_addr,
new_owner_addr,
wormhole_addr,
pyth_owner_addr,
recent_blockhash,
)?,
Action::Forward { product_addr: _ } => {
todo!()
}
};
rpc_client.send_and_confirm_transaction_with_spinner(&tx)?;
Ok(())
}
fn handle_init(
payer: Keypair,
p2w_addr: Pubkey,
new_owner_addr: Pubkey,
wormhole_addr: Pubkey,
pyth_owner_addr: Pubkey,
recent_blockhash: Hash,
) -> Result<Transaction, ErrBox> {
use AccEntry::*;
let payer_pubkey = payer.pubkey();
let accs = InitializeAccounts {
payer: Signer(payer),
new_config: Unprivileged(<P2WConfigAccount<'_, {AccountState::Uninitialized}>>::key(None, &p2w_addr)),
};
let config = Pyth2WormholeConfig {
owner: new_owner_addr,
wormhole_program_addr: wormhole_addr,
pyth_owner: pyth_owner_addr,
};
let ix_data = pyth2wormhole::instruction::Instruction::Initialize(config);
let (ix, signers) = accs.gen_client_ix(p2w_addr, ix_data.try_to_vec()?.as_slice())?;
let tx_signed = Transaction::new_signed_with_payer::<Vec<&Keypair>>(
&[ix],
Some(&payer_pubkey),
signers.iter().collect::<Vec<_>>().as_ref(),
recent_blockhash,
);
Ok(tx_signed)
}
fn init_logging(verbosity: u32) {
use LevelFilter::*;
let filter = match verbosity {
0..=1 => Error,
2 => Warn,
3 => Info,
4 => Debug,
_other => Trace,
};
env_logger::builder().filter_level(filter).init();
}

View File

@ -8,10 +8,10 @@ use solitaire::{
solitaire
};
use config::Pyth2WormholeConfig;
use forward::{forward_price, Forward, ForwardData};
use initialize::{initialize, Initialize};
use set_config::{set_config, SetConfig};
pub use config::Pyth2WormholeConfig;
pub use forward::{forward_price, Forward, ForwardData};
pub use initialize::{initialize, Initialize};
pub use set_config::{set_config, SetConfig};
solitaire! {
Forward(ForwardData) => forward_price,