defituna_client/txbuilder/
open_tuna_spot_position.rs1use crate::instructions::{OpenTunaSpotPosition, OpenTunaSpotPositionInstructionArgs};
2use crate::types::PoolToken;
3use crate::{get_market_address, get_tuna_spot_position_address};
4use anyhow::{anyhow, Result};
5use fusionamm_client::{FusionPool, FUSIONAMM_ID};
6use orca_whirlpools_client::{Whirlpool, WHIRLPOOL_ID};
7use solana_client::rpc_client::RpcClient;
8use solana_instruction::Instruction;
9use solana_pubkey::Pubkey;
10use solana_sdk_ids::system_program;
11use spl_associated_token_account::get_associated_token_address_with_program_id;
12
13impl Default for OpenTunaSpotPositionInstructionArgs {
14 fn default() -> Self {
15 OpenTunaSpotPositionInstructionArgs {
16 position_token: PoolToken::A,
17 collateral_token: PoolToken::A,
18 }
19 }
20}
21
22pub fn open_tuna_spot_position_instructions(
23 rpc: &RpcClient,
24 authority: &Pubkey,
25 pool: &Pubkey,
26 args: OpenTunaSpotPositionInstructionArgs,
27) -> Result<Vec<Instruction>> {
28 let pool_account = rpc.get_account(pool)?;
29
30 let (mint_a_address, mint_b_address) = if pool_account.owner == FUSIONAMM_ID {
31 let pool = FusionPool::from_bytes(&pool_account.data)?;
32 (pool.token_mint_a, pool.token_mint_b)
33 } else if pool_account.owner == WHIRLPOOL_ID {
34 let pool = Whirlpool::from_bytes(&pool_account.data)?;
35 (pool.token_mint_a, pool.token_mint_b)
36 } else {
37 return Err(anyhow!("Incorrect fusion or orca pool"));
38 };
39
40 let mint_accounts = rpc.get_multiple_accounts(&[mint_a_address.into(), mint_b_address.into()])?;
41 let mint_a_account = mint_accounts[0].as_ref().ok_or(anyhow!("Token A mint account not found"))?;
42 let mint_b_account = mint_accounts[1].as_ref().ok_or(anyhow!("Token B mint account not found"))?;
43
44 let mut instructions = vec![];
45
46 instructions.push(open_tuna_spot_position_instruction(
47 authority,
48 pool,
49 &mint_a_address,
50 &mint_b_address,
51 &mint_a_account.owner,
52 &mint_b_account.owner,
53 args,
54 ));
55
56 Ok(instructions)
57}
58
59pub fn open_tuna_spot_position_instruction(
60 authority: &Pubkey,
61 pool: &Pubkey,
62 mint_a: &Pubkey,
63 mint_b: &Pubkey,
64 token_program_a: &Pubkey,
65 token_program_b: &Pubkey,
66 args: OpenTunaSpotPositionInstructionArgs,
67) -> Instruction {
68 let tuna_position_address = get_tuna_spot_position_address(authority, pool).0;
69 let market = get_market_address(pool).0;
70
71 let ix_builder = OpenTunaSpotPosition {
72 authority: *authority,
73 mint_a: *mint_a,
74 mint_b: *mint_b,
75 token_program_a: *token_program_a,
76 token_program_b: *token_program_b,
77 market,
78 tuna_position: tuna_position_address,
79 tuna_position_ata_a: get_associated_token_address_with_program_id(&tuna_position_address, mint_a, token_program_a),
80 tuna_position_ata_b: get_associated_token_address_with_program_id(&tuna_position_address, mint_b, token_program_b),
81 pool: *pool,
82 system_program: system_program::ID,
83 associated_token_program: spl_associated_token_account::ID,
84 };
85
86 ix_builder.instruction(args)
87}