Jupiter: Ensure source account is initialized (#721)

This commit is contained in:
Christian Kamm 2023-09-18 09:21:46 +02:00 committed by GitHub
parent 40ad0b7b66
commit 9b224eae1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 26 deletions

View File

@ -192,8 +192,15 @@ async fn main() -> Result<(), anyhow::Error> {
let output_mint = pubkey_from_cli(&cmd.output_mint);
let client = MangoClient::new_for_existing_account(client, account, owner).await?;
let txsig = client
.jupiter_v6()
.swap(input_mint, output_mint, cmd.amount, cmd.slippage_bps, false)
.jupiter_v4()
.swap(
input_mint,
output_mint,
cmd.amount,
cmd.slippage_bps,
mango_v4_client::JupiterSwapMode::ExactIn,
false,
)
.await?;
println!("{}", txsig);
}

View File

@ -100,7 +100,7 @@ impl<'a> JupiterV4<'a> {
input_mint: Pubkey,
output_mint: Pubkey,
amount: u64,
slippage: u64,
slippage_bps: u64,
swap_mode: JupiterSwapMode,
only_direct_routes: bool,
) -> anyhow::Result<QueryRoute> {
@ -115,7 +115,7 @@ impl<'a> JupiterV4<'a> {
("onlyDirectRoutes", only_direct_routes.to_string()),
("enforceSingleTx", "true".into()),
("filterTopNResult", "10".into()),
("slippageBps", format!("{}", slippage)),
("slippageBps", format!("{}", slippage_bps)),
(
"swapMode",
match swap_mode {
@ -227,14 +227,13 @@ impl<'a> JupiterV4<'a> {
.map(util::to_writable_account_meta)
.collect::<Vec<_>>();
let owner = self.mango_client.owner();
let token_ams = [source_token.mint_info.mint, target_token.mint_info.mint]
.into_iter()
.map(|mint| {
util::to_writable_account_meta(
anchor_spl::associated_token::get_associated_token_address(
&self.mango_client.owner(),
&mint,
),
anchor_spl::associated_token::get_associated_token_address(&owner, &mint),
)
})
.collect::<Vec<_>>();
@ -265,13 +264,24 @@ impl<'a> JupiterV4<'a> {
for ix in &jup_ixs[..jup_action_ix_begin] {
instructions.push(ix.clone());
}
// Ensure the source token account is created (jupiter takes care of the output account)
instructions.push(
spl_associated_token_account::instruction::create_associated_token_account_idempotent(
&owner,
&owner,
&source_token.mint_info.mint,
&Token::id(),
),
);
instructions.push(Instruction {
program_id: mango_v4::id(),
accounts: {
let mut ams = anchor_lang::ToAccountMetas::to_account_metas(
&mango_v4::accounts::FlashLoanBegin {
account: self.mango_client.mango_account_address,
owner: self.mango_client.owner(),
owner,
token_program: Token::id(),
instructions: solana_sdk::sysvar::instructions::id(),
},
@ -296,7 +306,7 @@ impl<'a> JupiterV4<'a> {
let mut ams = anchor_lang::ToAccountMetas::to_account_metas(
&mango_v4::accounts::FlashLoanEnd {
account: self.mango_client.mango_account_address,
owner: self.mango_client.owner(),
owner,
token_program: Token::id(),
},
None,
@ -319,7 +329,7 @@ impl<'a> JupiterV4<'a> {
let mut address_lookup_tables = self.mango_client.mango_address_lookup_tables().await?;
address_lookup_tables.extend(jup_alts.into_iter());
let payer = self.mango_client.owner.pubkey(); // maybe use fee_payer? but usually it's the same
let payer = owner; // maybe use fee_payer? but usually it's the same
Ok(TransactionBuilder {
instructions,
@ -335,7 +345,7 @@ impl<'a> JupiterV4<'a> {
input_mint: Pubkey,
output_mint: Pubkey,
amount: u64,
slippage: u64,
slippage_bps: u64,
swap_mode: JupiterSwapMode,
only_direct_routes: bool,
) -> anyhow::Result<Signature> {
@ -344,7 +354,7 @@ impl<'a> JupiterV4<'a> {
input_mint,
output_mint,
amount,
slippage,
slippage_bps,
swap_mode,
only_direct_routes,
)

View File

@ -10,7 +10,6 @@ use crate::MangoClient;
use crate::{util, TransactionBuilder};
use anyhow::Context;
use solana_sdk::signer::Signer;
use solana_sdk::{instruction::Instruction, signature::Signature};
#[derive(Deserialize, Serialize, Debug, Clone)]
@ -148,7 +147,7 @@ impl<'a> JupiterV6<'a> {
input_mint: Pubkey,
output_mint: Pubkey,
amount: u64,
slippage: u64,
slippage_bps: u64,
only_direct_routes: bool,
) -> anyhow::Result<QuoteResponse> {
let mut account = self.mango_client.mango_account().await?;
@ -189,7 +188,7 @@ impl<'a> JupiterV6<'a> {
("inputMint", input_mint.to_string()),
("outputMint", output_mint.to_string()),
("amount", format!("{}", amount)),
("slippageBps", format!("{}", slippage)),
("slippageBps", format!("{}", slippage_bps)),
("onlyDirectRoutes", only_direct_routes.to_string()),
(
"maxAccounts",
@ -237,14 +236,13 @@ impl<'a> JupiterV6<'a> {
.map(util::to_writable_account_meta)
.collect::<Vec<_>>();
let owner = self.mango_client.owner();
let token_ams = [source_token.mint_info.mint, target_token.mint_info.mint]
.into_iter()
.map(|mint| {
util::to_writable_account_meta(
anchor_spl::associated_token::get_associated_token_address(
&self.mango_client.owner(),
&mint,
),
anchor_spl::associated_token::get_associated_token_address(&owner, &mint),
)
})
.collect::<Vec<_>>();
@ -273,7 +271,7 @@ impl<'a> JupiterV6<'a> {
.http_client
.post("https://quote-api.jup.ag/v6/swap-instructions")
.json(&SwapRequest {
user_public_key: self.mango_client.owner.pubkey().to_string(),
user_public_key: owner.to_string(),
wrap_and_unwrap_sol: false,
use_shared_accounts: true,
fee_account: None,
@ -299,13 +297,24 @@ impl<'a> JupiterV6<'a> {
for ix in &swap.setup_instructions.unwrap_or_default() {
instructions.push(ix.try_into()?);
}
// Ensure the source token account is created (jupiter takes care of the output account)
instructions.push(
spl_associated_token_account::instruction::create_associated_token_account_idempotent(
&owner,
&owner,
&source_token.mint_info.mint,
&Token::id(),
),
);
instructions.push(Instruction {
program_id: mango_v4::id(),
accounts: {
let mut ams = anchor_lang::ToAccountMetas::to_account_metas(
&mango_v4::accounts::FlashLoanBegin {
account: self.mango_client.mango_account_address,
owner: self.mango_client.owner(),
owner,
token_program: Token::id(),
instructions: solana_sdk::sysvar::instructions::id(),
},
@ -328,7 +337,7 @@ impl<'a> JupiterV6<'a> {
let mut ams = anchor_lang::ToAccountMetas::to_account_metas(
&mango_v4::accounts::FlashLoanEnd {
account: self.mango_client.mango_account_address,
owner: self.mango_client.owner(),
owner,
token_program: Token::id(),
},
None,
@ -363,7 +372,7 @@ impl<'a> JupiterV6<'a> {
.await?;
address_lookup_tables.extend(jup_alts.into_iter());
let payer = self.mango_client.owner.pubkey(); // maybe use fee_payer? but usually it's the same
let payer = owner; // maybe use fee_payer? but usually it's the same
Ok(TransactionBuilder {
instructions,
@ -379,7 +388,7 @@ impl<'a> JupiterV6<'a> {
input_mint: Pubkey,
output_mint: Pubkey,
amount: u64,
slippage: u64,
slippage_bps: u64,
only_direct_routes: bool,
) -> anyhow::Result<Signature> {
let route = self
@ -387,7 +396,7 @@ impl<'a> JupiterV6<'a> {
input_mint,
output_mint,
amount,
slippage,
slippage_bps,
only_direct_routes,
)
.await?;