1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use std::str::FromStr;


use borsh::BorshDeserialize;

use colored::Colorize;
use solana_account_decoder::{UiAccountData, UiAccountEncoding};

use solana_client::rpc_client::RpcClient;
use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_client::rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType};
use solana_client::rpc_request::TokenAccountsFilter;

use common::command::{ProcessResult};
use common::contract::state::position::{Position, PositionUiList};
use solana_sdk::pubkey::Pubkey;
use tabled::object::Segment;
use tabled::style::Color;
use tabled::{Alignment, Modify, Panel, Style, Table};

use common::program::SWAP_PROGRAM_ID;


#[allow(deprecated)]
pub fn process_position_list(
    rpc_client: &RpcClient,
    clmmpool: Option<Pubkey>,
    auth: Option<Pubkey>,
) -> ProcessResult {
    if auth.is_none() && clmmpool.is_none() {
        panic!("clmmpool and auth must be a non-null")
    }

    let mut list = Vec::new();

    if auth.is_some() {
        let position_keys = rpc_client
            .get_token_accounts_by_owner(
                &auth.unwrap(),
                TokenAccountsFilter::ProgramId(spl_token::id())
            )
            .unwrap()
            .into_iter()
            .map(|a| {
                let mint = match a.account.data {
                    UiAccountData::Json(a) => {
                        let obj = a.parsed.as_object().unwrap();
                        let info = obj.get("info");
                        let mint = info
                            .and_then(|info| info.get("mint"))
                            .and_then(|mint| mint.as_str())
                            .and_then(|mint| Pubkey::from_str(mint).ok())
                            .unwrap();
                        mint
                    }
                    _ => panic!("rip"),
                };
                let position_pubkey = Pubkey::try_find_program_address(
                    &[
                        b"position",
                        mint.as_ref(),
                    ],
                    &SWAP_PROGRAM_ID,
                );
                position_pubkey.unwrap().0
            })
            .collect::<Vec<Pubkey>>();

        let position_accounts = rpc_client.get_multiple_accounts(
            &position_keys,
        )?;

        let mut i = 0;
        for account in position_accounts {
            i += 1;
            if account.is_none() {
                continue;
            }
            let position_ui_info: PositionUiList =
                Position::try_from_slice(&account.clone().unwrap().data[8..])
                    .unwrap()
                    .get_ui_info(position_keys[i - 1]);

            if clmmpool.is_some() {
                if position_ui_info.clmmpool.to_string() != clmmpool.unwrap().to_string() {
                    continue;
                }
            }

            list.push(position_ui_info);
        }
    } else {
        let accounts = rpc_client.get_program_accounts_with_config(
            &SWAP_PROGRAM_ID,
            RpcProgramAccountsConfig {
                filters: Some(vec![
                    RpcFilterType::DataSize((Position::LEN + 8) as u64),
                    RpcFilterType::Memcmp(Memcmp {
                        offset: 8,
                        bytes: MemcmpEncodedBytes::Base58(clmmpool.unwrap().to_string()),
                        encoding: None,
                    }),
                ]),
                account_config: RpcAccountInfoConfig {
                    encoding: Some(UiAccountEncoding::Base64),
                    data_slice: None,
                    commitment: None,
                    min_context_slot: None,
                },
                with_context: None,
            },
        );
        for account in accounts.unwrap() {
            let data_slice = &account.1.data[8..];

            list.push(
                Position::try_from_slice(data_slice)
                    .unwrap()
                    .get_ui_info(account.0),
            );
        }
    }

    let color = Color::try_from(" ".cyan().to_string()).unwrap();

    Ok(Table::builder(list)
        .build()
        .with(Style::modern())
        .with(color)
        .with(Panel("Position List", 0))
        .with(Modify::new(Segment::all()).with(Alignment::center()))
        .to_string())
}