Skip to content

Commit 02e3333

Browse files
authored
Nuke the client module (#246)
* Remove the client module * Remove all uses of clockwork_client in cli * Readd localnet startup script * Migrate to ToAccountMetas
1 parent d37ce1b commit 02e3333

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+607
-1585
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
[workspace]
22
members = [
33
"cli",
4-
"client",
54
"cron",
65
"plugin",
76
"programs/*",

cli/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ build = "build.rs"
1313

1414
[dependencies]
1515
anchor-lang = "0.27.0"
16+
anchor-spl = { features = ["mint", "token"], version = "0.27.0" }
1617
anyhow = "1.0.61"
1718
bincode = "1.3.3"
1819
bzip2 = "0.4"
1920
clap = { version = "3.1.2", features = ["derive"] }
20-
clockwork-client = { path = "../client", version = "=2.0.15" }
2121
clockwork-cron = { path = "../cron", version = "=2.0.15" }
22+
clockwork-network-program = { path = "../programs/network", version = "=2.0.15" }
2223
clockwork-relayer-api = { path = "../relayer/api", version = "=2.0.15" }
2324
clockwork-plugin-utils= { path = "../plugin/utils", version = "=2.0.15" }
25+
clockwork-thread-program = { path = "../programs/thread", version = "=2.0.15" }
2426
clockwork-utils = { path = "../utils", version = "=2.0.15" }
2527
clockwork-webhook-program = { path = "../programs/webhook", version = "=2.0.15" }
2628
chrono = { version = "0.4.19", default-features = false, features = ["alloc"] }

cli/src/cli.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
1-
use {
2-
crate::parser::ProgramInfo,
3-
clap::{
4-
crate_version,
5-
Arg,
6-
ArgGroup,
7-
Command,
8-
},
9-
clockwork_client::{
10-
thread::state::{
11-
SerializableInstruction,
12-
Trigger,
13-
},
14-
webhook::state::HttpMethod,
15-
},
16-
solana_sdk::{
17-
pubkey::Pubkey,
18-
signature::Keypair,
19-
},
20-
};
1+
use clap::{crate_version, Arg, ArgGroup, Command};
2+
use clockwork_thread_program::state::{SerializableInstruction, Trigger};
3+
use clockwork_webhook_program::state::HttpMethod;
4+
use solana_sdk::{pubkey::Pubkey, signature::Keypair};
5+
6+
use crate::parser::ProgramInfo;
217

228
#[derive(Debug, PartialEq)]
239
pub enum CliCommand {

cli/src/client.rs

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
use anchor_lang::{prelude::Clock, AccountDeserialize};
2+
use clockwork_utils::ProgramLogsDeserializable;
3+
use solana_client::{
4+
client_error, rpc_client::RpcClient,
5+
rpc_response::RpcSimulateTransactionResult,
6+
};
7+
use solana_sdk::{
8+
commitment_config::CommitmentConfig,
9+
hash::Hash,
10+
instruction::Instruction,
11+
program_error::ProgramError,
12+
pubkey::Pubkey,
13+
signature::{Keypair, Signature, Signer},
14+
signers::Signers,
15+
transaction::Transaction,
16+
};
17+
use std::{
18+
fmt::Debug,
19+
ops::{Deref, DerefMut},
20+
str::FromStr,
21+
};
22+
use thiserror::Error;
23+
24+
25+
#[derive(Debug, Error)]
26+
pub enum ClientError {
27+
#[error(transparent)]
28+
Client(#[from] client_error::ClientError),
29+
30+
#[error(transparent)]
31+
Program(#[from] ProgramError),
32+
33+
#[error("Failed to deserialize account data")]
34+
DeserializationError,
35+
}
36+
37+
pub type ClientResult<T> = Result<T, ClientError>;
38+
39+
pub struct Client {
40+
pub client: RpcClient,
41+
pub payer: Keypair,
42+
}
43+
44+
impl Client {
45+
pub fn new(payer: Keypair, url: String) -> Self {
46+
let client = RpcClient::new_with_commitment::<String>(url, CommitmentConfig::processed());
47+
Self { client, payer }
48+
}
49+
50+
pub fn get<T: AccountDeserialize>(&self, pubkey: &Pubkey) -> ClientResult<T> {
51+
let data = self.client.get_account_data(pubkey)?;
52+
T::try_deserialize(&mut data.as_slice()).map_err(|_| ClientError::DeserializationError)
53+
}
54+
55+
pub fn get_clock(&self) -> ClientResult<Clock> {
56+
let clock_pubkey = Pubkey::from_str("SysvarC1ock11111111111111111111111111111111").unwrap();
57+
let clock_data = self.client.get_account_data(&clock_pubkey)?;
58+
bincode::deserialize::<Clock>(&clock_data).map_err(|_| ClientError::DeserializationError)
59+
}
60+
61+
pub fn get_return_data<T: ProgramLogsDeserializable>(
62+
&self,
63+
ix: Instruction,
64+
) -> ClientResult<T> {
65+
// let result = self.simulate_transaction(&[ix.clone()], &[self.payer()])?;
66+
67+
// After we can upgrade our Solana SDK version to 1.14.0 we can just use the below code:
68+
// let data = result.logs;
69+
// Ok(T::try_from_slice(logs, &data)
70+
// .map_err(|_| ClientError::DeserializationError)?)
71+
//
72+
// But for the time being since RpcSimulateTransactionResult.data does not exist yet,
73+
// We can only parse the logs ourselves to find the return_data
74+
let logs = self.get_instruction_logs(ix.clone())?;
75+
T::try_from_program_logs(logs, &ix.program_id)
76+
.map_err(|_| ClientError::DeserializationError)
77+
}
78+
79+
pub fn get_instruction_logs(&self, ix: Instruction) -> ClientResult<Vec<String>> {
80+
let result = self.simulate_transaction(&[ix], &[self.payer()])?;
81+
let logs = result.logs.ok_or(ClientError::DeserializationError)?;
82+
Ok(logs)
83+
}
84+
85+
pub fn payer(&self) -> &Keypair {
86+
&self.payer
87+
}
88+
89+
pub fn payer_pubkey(&self) -> Pubkey {
90+
self.payer.pubkey()
91+
}
92+
93+
pub fn latest_blockhash(&self) -> ClientResult<Hash> {
94+
Ok(self.client.get_latest_blockhash()?)
95+
}
96+
97+
pub fn airdrop(&self, to_pubkey: &Pubkey, lamports: u64) -> ClientResult<Signature> {
98+
let blockhash = self.client.get_latest_blockhash()?;
99+
let signature = self.request_airdrop_with_blockhash(to_pubkey, lamports, &blockhash)?;
100+
self.confirm_transaction_with_spinner(&signature, &blockhash, self.commitment())?;
101+
Ok(signature)
102+
}
103+
104+
pub fn send_and_confirm<T: Signers>(
105+
&self,
106+
ixs: &[Instruction],
107+
signers: &T,
108+
) -> ClientResult<Signature> {
109+
let tx = self.transaction(ixs, signers)?;
110+
Ok(self.send_and_confirm_transaction(&tx)?)
111+
}
112+
113+
pub fn simulate_transaction<T: Signers>(
114+
&self,
115+
ixs: &[Instruction],
116+
signers: &T,
117+
) -> ClientResult<RpcSimulateTransactionResult> {
118+
let tx = self.transaction(ixs, signers)?;
119+
let result = self.client.simulate_transaction(&tx)?;
120+
if result.value.err.is_some() {
121+
Err(ClientError::DeserializationError)
122+
} else {
123+
Ok(result.value)
124+
}
125+
}
126+
127+
fn transaction<T: Signers>(
128+
&self,
129+
ixs: &[Instruction],
130+
signers: &T,
131+
) -> ClientResult<Transaction> {
132+
let mut tx = Transaction::new_with_payer(ixs, Some(&self.payer_pubkey()));
133+
tx.sign(signers, self.latest_blockhash()?);
134+
Ok(tx)
135+
}
136+
}
137+
138+
139+
impl Debug for Client {
140+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
141+
write!(f, "RPC client payer {}", self.payer_pubkey())
142+
}
143+
}
144+
145+
impl Deref for Client {
146+
type Target = RpcClient;
147+
148+
fn deref(&self) -> &Self::Target {
149+
&self.client
150+
}
151+
}
152+
153+
impl DerefMut for Client {
154+
fn deref_mut(&mut self) -> &mut Self::Target {
155+
&mut self.client
156+
}
157+
}
158+

cli/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
mod cli;
2+
mod client;
23
mod config;
34
mod deps;
45
mod errors;

cli/src/parser.rs

Lines changed: 12 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,17 @@
1-
use {
2-
crate::{
3-
cli::CliCommand,
4-
errors::CliError,
5-
},
6-
clap::ArgMatches,
7-
clockwork_client::{
8-
thread::state::{
9-
SerializableAccount,
10-
SerializableInstruction,
11-
Trigger,
12-
},
13-
webhook::state::HttpMethod,
14-
},
15-
serde::{
16-
Deserialize as JsonDeserialize,
17-
Serialize as JsonSerialize,
18-
},
19-
solana_sdk::{
20-
pubkey::Pubkey,
21-
signature::{
22-
read_keypair_file,
23-
Keypair,
24-
},
25-
signer::Signer,
26-
},
27-
std::{
28-
convert::TryFrom,
29-
fs,
30-
path::PathBuf,
31-
str::FromStr,
32-
},
1+
use std::{convert::TryFrom, fs, path::PathBuf, str::FromStr};
2+
3+
use clap::ArgMatches;
4+
use clockwork_thread_program::state::{SerializableAccount, SerializableInstruction, Trigger};
5+
use clockwork_webhook_program::state::HttpMethod;
6+
use serde::{Deserialize as JsonDeserialize, Serialize as JsonSerialize};
7+
use solana_sdk::{
8+
pubkey::Pubkey,
9+
signature::{read_keypair_file, Keypair},
10+
signer::Signer,
3311
};
3412

13+
use crate::{cli::CliCommand, errors::CliError};
14+
3515
impl TryFrom<&ArgMatches> for CliCommand {
3616
type Error = CliError;
3717

cli/src/processor/config.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use {
2-
crate::errors::CliError,
3-
clockwork_client::{
4-
network::state::{Config, ConfigSettings},
5-
Client,
1+
use anchor_lang::{
2+
solana_program::{
3+
instruction::Instruction, pubkey::Pubkey,
64
},
7-
solana_sdk::pubkey::Pubkey,
5+
InstructionData, ToAccountMetas
86
};
7+
use clockwork_network_program::state::{Config, ConfigSettings};
8+
9+
use crate::{client::Client, errors::CliError};
910

1011
pub fn get(client: &Client) -> Result<(), CliError> {
1112
let config = client
@@ -35,7 +36,14 @@ pub fn set(
3536
};
3637

3738
// Submit tx
38-
let ix = clockwork_client::network::instruction::config_update(client.payer_pubkey(), settings);
39+
let ix = Instruction {
40+
program_id: clockwork_network_program::ID,
41+
accounts: clockwork_network_program::accounts::ConfigUpdate {
42+
admin: client.payer_pubkey(),
43+
config: Config::pubkey(),
44+
}.to_account_metas(Some(false)),
45+
data: clockwork_network_program::instruction::ConfigUpdate { settings }.data(),
46+
};
3947
client.send_and_confirm(&[ix], &[client.payer()]).unwrap();
4048
get(client)?;
4149
Ok(())

cli/src/processor/crontab.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use {
2-
crate::errors::CliError,
3-
chrono::{DateTime, NaiveDateTime, Utc},
4-
clockwork_client::Client,
5-
clockwork_cron::Schedule,
6-
std::str::FromStr,
7-
};
1+
use chrono::{DateTime, NaiveDateTime, Utc};
2+
use clockwork_cron::Schedule;
3+
use std::str::FromStr;
4+
5+
use crate::{client::Client, errors::CliError};
86

97
pub fn get(client: &Client, schedule: String) -> Result<(), CliError> {
108
let clock = client.get_clock().unwrap();

0 commit comments

Comments
 (0)