1use std::{fs::File, path::PathBuf};
2
3use anyhow::Result;
4use borsh::{BorshDeserialize, BorshSerialize};
5use indexmap::IndexSet;
6use serde::{Deserialize, Serialize};
7use serde_with::DisplayFromStr;
8use solana_program::{pubkey, pubkey::Pubkey};
9
10use crate::setup;
11
12const FAIR_LAUNCH_PROGRAM_ID: Pubkey = pubkey!("8bvPnYE5Pvz2Z9dE6RAqWr1rzLknTndZ9hwvRE6kPDXP");
13
14#[serde_with::serde_as]
15#[derive(Debug, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
16pub struct OnChainHashlist {
17 #[serde_as(as = "DisplayFromStr")]
18 pub deployment: Pubkey,
19 pub issues: Vec<MintAndOrder>,
20}
21
22#[serde_with::serde_as]
23#[derive(Debug, Deserialize, Serialize, BorshSerialize, BorshDeserialize)]
24pub struct MintAndOrder {
25 #[serde_as(as = "DisplayFromStr")]
26 pub mint: Pubkey,
27 pub order: u64,
28}
29
30pub fn fetch_hashlist(
31 keypair_path: Option<PathBuf>,
32 rpc_url: Option<String>,
33 ticker: String,
34) -> Result<()> {
35 let config = setup::CliConfig::new(keypair_path, rpc_url)?;
36
37 let deployment_pubkey = Pubkey::find_program_address(
38 &["deployment".as_bytes(), ticker.as_bytes()],
39 &FAIR_LAUNCH_PROGRAM_ID,
40 )
41 .0;
42
43 let hashlist_pubkey = Pubkey::find_program_address(
44 &["hashlist".as_bytes(), deployment_pubkey.as_ref()],
45 &FAIR_LAUNCH_PROGRAM_ID,
46 )
47 .0;
48
49 let hashlist_data = config.client.get_account_data(&hashlist_pubkey)?;
50 let onchain_hashlist: OnChainHashlist = OnChainHashlist::try_from_slice(&hashlist_data[8..])?;
51
52 let mut hashlist: IndexSet<String> = onchain_hashlist
53 .issues
54 .iter()
55 .map(|mint_and_order| mint_and_order.mint.to_string())
56 .collect();
57
58 hashlist.sort();
59
60 let f = File::create(format!("{ticker}_deployment.json"))?;
61 let g = File::create(format!("{ticker}_hashlist.json"))?;
62
63 serde_json::to_writer_pretty(f, &onchain_hashlist)?;
64 serde_json::to_writer_pretty(g, &hashlist)?;
65
66 Ok(())
67}