client: configurable jupiter urls (#800)
(cherry picked from commit 71f0e5cc13
)
This commit is contained in:
parent
571e8d483c
commit
e2bfa9a1e6
|
@ -1508,14 +1508,38 @@ dependencies = [
|
|||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"darling_macro 0.14.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
"darling_core 0.20.3",
|
||||
"darling_macro 0.20.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2 1.0.67",
|
||||
"quote 1.0.33",
|
||||
"strsim 0.10.0",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1532,13 +1556,24 @@ dependencies = [
|
|||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.14.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e"
|
||||
dependencies = [
|
||||
"darling_core 0.14.4",
|
||||
"quote 1.0.33",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_core 0.20.3",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
@ -1617,6 +1652,37 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
|
||||
dependencies = [
|
||||
"derive_builder_macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_core"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
|
||||
dependencies = [
|
||||
"darling 0.14.4",
|
||||
"proc-macro2 1.0.67",
|
||||
"quote 1.0.33",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_builder_macro"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
|
||||
dependencies = [
|
||||
"derive_builder_core",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
|
@ -3379,6 +3445,7 @@ dependencies = [
|
|||
"atty",
|
||||
"base64 0.13.1",
|
||||
"bincode",
|
||||
"derive_builder",
|
||||
"fixed 1.11.0 (git+https://github.com/blockworks-foundation/fixed.git?branch=v1.11.0-borsh0_10-mango)",
|
||||
"futures 0.3.28",
|
||||
"itertools",
|
||||
|
@ -5779,7 +5846,7 @@ version = "2.3.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"darling 0.20.3",
|
||||
"proc-macro2 1.0.67",
|
||||
"quote 1.0.33",
|
||||
"syn 2.0.37",
|
||||
|
|
|
@ -140,6 +140,14 @@ struct Cli {
|
|||
#[clap(long, env, value_enum, default_value = "v6")]
|
||||
jupiter_version: JupiterVersionArg,
|
||||
|
||||
/// override the url to jupiter v4
|
||||
#[clap(long, env, default_value = "https://quote-api.jup.ag/v4")]
|
||||
jupiter_v4_url: String,
|
||||
|
||||
/// override the url to jupiter v6
|
||||
#[clap(long, env, default_value = "https://quote-api.jup.ag/v6")]
|
||||
jupiter_v6_url: String,
|
||||
|
||||
/// report liquidator's existence and pubkey
|
||||
#[clap(long, env, value_enum, default_value = "true")]
|
||||
telemetry: BoolArg,
|
||||
|
@ -170,18 +178,21 @@ async fn main() -> anyhow::Result<()> {
|
|||
let rpc_timeout = Duration::from_secs(10);
|
||||
let cluster = Cluster::Custom(rpc_url.clone(), ws_url.clone());
|
||||
let commitment = CommitmentConfig::processed();
|
||||
let client = Client::new(
|
||||
cluster.clone(),
|
||||
commitment,
|
||||
liqor_owner.clone(),
|
||||
Some(rpc_timeout),
|
||||
TransactionBuilderConfig {
|
||||
let client = Client::builder()
|
||||
.cluster(cluster.clone())
|
||||
.commitment(commitment)
|
||||
.fee_payer(Some(liqor_owner.clone()))
|
||||
.timeout(Some(rpc_timeout))
|
||||
.jupiter_v4_url(cli.jupiter_v4_url)
|
||||
.jupiter_v6_url(cli.jupiter_v6_url)
|
||||
.transaction_builder_config(TransactionBuilderConfig {
|
||||
prioritization_micro_lamports: (cli.prioritization_micro_lamports > 0)
|
||||
.then_some(cli.prioritization_micro_lamports),
|
||||
// Liquidation and tcs triggers set their own budgets, this is a default for other tx
|
||||
compute_budget_per_instruction: Some(250_000),
|
||||
},
|
||||
);
|
||||
})
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
// The representation of current on-chain account data
|
||||
let chain_data = Arc::new(RwLock::new(chain_data::ChainData::new()));
|
||||
|
|
|
@ -1157,14 +1157,12 @@ impl Context {
|
|||
solana_sdk::compute_budget::ComputeBudgetInstruction::set_compute_unit_limit(
|
||||
self.config.compute_limit_for_trigger,
|
||||
);
|
||||
let fee_payer = self.mango_client.client.fee_payer();
|
||||
TransactionBuilder {
|
||||
instructions: vec![compute_ix],
|
||||
address_lookup_tables: vec![],
|
||||
payer: self.mango_client.client.fee_payer.pubkey(),
|
||||
signers: vec![
|
||||
self.mango_client.owner.clone(),
|
||||
self.mango_client.client.fee_payer.clone(),
|
||||
],
|
||||
payer: fee_payer.pubkey(),
|
||||
signers: vec![self.mango_client.owner.clone(), fee_payer],
|
||||
config: self.mango_client.client.transaction_builder_config,
|
||||
}
|
||||
};
|
||||
|
|
|
@ -267,7 +267,7 @@ struct SettleBatchProcessor<'a> {
|
|||
impl<'a> SettleBatchProcessor<'a> {
|
||||
fn transaction(&self) -> anyhow::Result<VersionedTransaction> {
|
||||
let client = &self.mango_client.client;
|
||||
let fee_payer = client.fee_payer.clone();
|
||||
let fee_payer = client.fee_payer();
|
||||
|
||||
TransactionBuilder {
|
||||
instructions: self.instructions.clone().to_instructions(),
|
||||
|
|
|
@ -15,6 +15,7 @@ async-channel = "1.6"
|
|||
async-once-cell = { version = "0.4.2", features = ["unpin"] }
|
||||
async-trait = "0.1.52"
|
||||
atty = "0.2"
|
||||
derive_builder = "0.12.0"
|
||||
fixed = { workspace = true, features = ["serde", "borsh"] }
|
||||
futures = "0.3.25"
|
||||
itertools = "0.10.3"
|
||||
|
|
|
@ -49,17 +49,55 @@ use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signer::Si
|
|||
pub const MAX_ACCOUNTS_PER_TRANSACTION: usize = 64;
|
||||
|
||||
// very close to anchor_client::Client, which unfortunately has no accessors or Clone
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Builder)]
|
||||
pub struct Client {
|
||||
/// RPC url
|
||||
///
|
||||
/// Defaults to Cluster::Mainnet, using the public crowded mainnet-beta rpc endpoint.
|
||||
/// Should usually be overridden with a custom rpc endpoint.
|
||||
#[builder(default = "Cluster::Mainnet")]
|
||||
pub cluster: Cluster,
|
||||
pub fee_payer: Arc<Keypair>,
|
||||
|
||||
/// Transaction fee payer. Needs to be set to send transactions.
|
||||
pub fee_payer: Option<Arc<Keypair>>,
|
||||
|
||||
/// Commitment for interacting with the chain. Defaults to processed.
|
||||
#[builder(default = "CommitmentConfig::processed()")]
|
||||
pub commitment: CommitmentConfig,
|
||||
|
||||
/// Timeout, defaults to 60s
|
||||
#[builder(default = "Some(Duration::from_secs(60))")]
|
||||
pub timeout: Option<Duration>,
|
||||
|
||||
#[builder(default)]
|
||||
pub transaction_builder_config: TransactionBuilderConfig,
|
||||
|
||||
/// Defaults to a preflight check at processed commitment
|
||||
#[builder(default = "ClientBuilder::default_rpc_send_transaction_config()")]
|
||||
pub rpc_send_transaction_config: RpcSendTransactionConfig,
|
||||
|
||||
#[builder(default = "\"https://quote-api.jup.ag/v4\".into()")]
|
||||
pub jupiter_v4_url: String,
|
||||
|
||||
#[builder(default = "\"https://quote-api.jup.ag/v6\".into()")]
|
||||
pub jupiter_v6_url: String,
|
||||
}
|
||||
|
||||
impl ClientBuilder {
|
||||
pub fn default_rpc_send_transaction_config() -> RpcSendTransactionConfig {
|
||||
RpcSendTransactionConfig {
|
||||
preflight_commitment: Some(CommitmentLevel::Processed),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn builder() -> ClientBuilder {
|
||||
ClientBuilder::default()
|
||||
}
|
||||
|
||||
/// Prefer using the builder()
|
||||
pub fn new(
|
||||
cluster: Cluster,
|
||||
commitment: CommitmentConfig,
|
||||
|
@ -67,17 +105,14 @@ impl Client {
|
|||
timeout: Option<Duration>,
|
||||
transaction_builder_config: TransactionBuilderConfig,
|
||||
) -> Self {
|
||||
Self {
|
||||
cluster,
|
||||
fee_payer,
|
||||
commitment,
|
||||
timeout,
|
||||
transaction_builder_config,
|
||||
rpc_send_transaction_config: RpcSendTransactionConfig {
|
||||
preflight_commitment: Some(CommitmentLevel::Processed),
|
||||
..Default::default()
|
||||
},
|
||||
}
|
||||
Self::builder()
|
||||
.cluster(cluster)
|
||||
.commitment(commitment)
|
||||
.fee_payer(Some(fee_payer))
|
||||
.timeout(timeout)
|
||||
.transaction_builder_config(transaction_builder_config)
|
||||
.build()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn rpc_async(&self) -> RpcClientAsync {
|
||||
|
@ -96,6 +131,13 @@ impl Client {
|
|||
) -> anyhow::Result<T> {
|
||||
fetch_anchor_account(&self.rpc_async(), address).await
|
||||
}
|
||||
|
||||
pub fn fee_payer(&self) -> Arc<Keypair> {
|
||||
self.fee_payer
|
||||
.as_ref()
|
||||
.expect("fee payer must be set")
|
||||
.clone()
|
||||
}
|
||||
}
|
||||
|
||||
// todo: might want to integrate geyser, websockets, or simple http polling for keeping data fresh
|
||||
|
@ -1617,11 +1659,12 @@ impl MangoClient {
|
|||
&self,
|
||||
instructions: Vec<Instruction>,
|
||||
) -> anyhow::Result<Signature> {
|
||||
let fee_payer = self.client.fee_payer();
|
||||
TransactionBuilder {
|
||||
instructions,
|
||||
address_lookup_tables: self.mango_address_lookup_tables().await?,
|
||||
payer: self.client.fee_payer.pubkey(),
|
||||
signers: vec![self.owner.clone(), self.client.fee_payer.clone()],
|
||||
payer: fee_payer.pubkey(),
|
||||
signers: vec![self.owner.clone(), fee_payer],
|
||||
config: self.client.transaction_builder_config,
|
||||
}
|
||||
.send_and_confirm(&self.client)
|
||||
|
@ -1632,11 +1675,12 @@ impl MangoClient {
|
|||
&self,
|
||||
instructions: Vec<Instruction>,
|
||||
) -> anyhow::Result<Signature> {
|
||||
let fee_payer = self.client.fee_payer();
|
||||
TransactionBuilder {
|
||||
instructions,
|
||||
address_lookup_tables: self.mango_address_lookup_tables().await?,
|
||||
payer: self.client.fee_payer.pubkey(),
|
||||
signers: vec![self.client.fee_payer.clone()],
|
||||
payer: fee_payer.pubkey(),
|
||||
signers: vec![fee_payer],
|
||||
config: self.client.transaction_builder_config,
|
||||
}
|
||||
.send_and_confirm(&self.client)
|
||||
|
@ -1647,11 +1691,12 @@ impl MangoClient {
|
|||
&self,
|
||||
instructions: Vec<Instruction>,
|
||||
) -> anyhow::Result<SimulateTransactionResponse> {
|
||||
let fee_payer = self.client.fee_payer();
|
||||
TransactionBuilder {
|
||||
instructions,
|
||||
address_lookup_tables: vec![],
|
||||
payer: self.client.fee_payer.pubkey(),
|
||||
signers: vec![self.client.fee_payer.clone()],
|
||||
payer: fee_payer.pubkey(),
|
||||
signers: vec![fee_payer],
|
||||
config: self.client.transaction_builder_config,
|
||||
}
|
||||
.simulate(&self.client)
|
||||
|
|
|
@ -107,7 +107,7 @@ impl<'a> JupiterV4<'a> {
|
|||
let response = self
|
||||
.mango_client
|
||||
.http_client
|
||||
.get("https://quote-api.jup.ag/v4/quote")
|
||||
.get(format!("{}/quote", self.mango_client.client.jupiter_v4_url))
|
||||
.query(&[
|
||||
("inputMint", input_mint.to_string()),
|
||||
("outputMint", output_mint.to_string()),
|
||||
|
@ -158,7 +158,7 @@ impl<'a> JupiterV4<'a> {
|
|||
let swap_response = self
|
||||
.mango_client
|
||||
.http_client
|
||||
.post("https://quote-api.jup.ag/v4/swap")
|
||||
.post(format!("{}/swap", self.mango_client.client.jupiter_v4_url))
|
||||
.json(&SwapRequest {
|
||||
route: route.clone(),
|
||||
user_public_key: self.mango_client.owner.pubkey().to_string(),
|
||||
|
|
|
@ -183,7 +183,7 @@ impl<'a> JupiterV6<'a> {
|
|||
let response = self
|
||||
.mango_client
|
||||
.http_client
|
||||
.get("https://quote-api.jup.ag/v6/quote")
|
||||
.get(format!("{}/quote", self.mango_client.client.jupiter_v6_url))
|
||||
.query(&[
|
||||
("inputMint", input_mint.to_string()),
|
||||
("outputMint", output_mint.to_string()),
|
||||
|
@ -263,7 +263,10 @@ impl<'a> JupiterV6<'a> {
|
|||
let swap_response = self
|
||||
.mango_client
|
||||
.http_client
|
||||
.post("https://quote-api.jup.ag/v6/swap-instructions")
|
||||
.post(format!(
|
||||
"{}/swap-instructions",
|
||||
self.mango_client.client.jupiter_v6_url
|
||||
))
|
||||
.json(&SwapRequest {
|
||||
user_public_key: owner.to_string(),
|
||||
wrap_and_unwrap_sol: false,
|
||||
|
|
|
@ -17,3 +17,6 @@ pub mod perp_pnl;
|
|||
pub mod snapshot_source;
|
||||
mod util;
|
||||
pub mod websocket_source;
|
||||
|
||||
#[macro_use]
|
||||
extern crate derive_builder;
|
||||
|
|
Loading…
Reference in New Issue