surfpool_sdk/cheatcodes/builders/
deploy_program.rs1use std::path::{Path, PathBuf};
2
3use solana_pubkey::Pubkey;
4
5use crate::{
6 cheatcodes::read_keypair_pubkey,
7 error::{SurfnetError, SurfnetResult},
8};
9
10pub struct DeployProgram {
34 program_id: Pubkey,
35 so_path: Option<PathBuf>,
36 so_bytes: Option<Vec<u8>>,
37 idl_path: Option<PathBuf>,
38}
39
40impl DeployProgram {
41 pub fn new(program_id: Pubkey) -> Self {
43 Self {
44 program_id,
45 so_path: None,
46 so_bytes: None,
47 idl_path: None,
48 }
49 }
50
51 pub fn from_keypair_path(path: impl AsRef<Path>) -> SurfnetResult<Self> {
55 let path = path.as_ref();
56 let program_id = read_keypair_pubkey(path)?;
57 Ok(Self::new(program_id))
58 }
59
60 pub fn so_path(mut self, path: impl Into<PathBuf>) -> Self {
62 self.so_path = Some(path.into());
63 self
64 }
65
66 pub fn so_bytes(mut self, bytes: Vec<u8>) -> Self {
68 self.so_bytes = Some(bytes);
69 self
70 }
71
72 pub fn idl_path(mut self, path: impl Into<PathBuf>) -> Self {
74 self.idl_path = Some(path.into());
75 self
76 }
77
78 pub(crate) fn idl_path_if_exists(mut self, path: impl Into<PathBuf>) -> Self {
80 let path = path.into();
81 if path.exists() {
82 self.idl_path = Some(path);
83 }
84 self
85 }
86
87 pub(crate) fn program_id(&self) -> Pubkey {
89 self.program_id
90 }
91
92 pub(crate) fn load_so_bytes(&self) -> SurfnetResult<Vec<u8>> {
94 match (&self.so_bytes, &self.so_path) {
95 (Some(bytes), _) => Ok(bytes.clone()),
96 (None, Some(path)) => std::fs::read(path).map_err(|e| {
97 SurfnetError::Cheatcode(format!(
98 "failed to read program bytes from {}: {e}",
99 path.display()
100 ))
101 }),
102 (None, None) => Err(SurfnetError::Cheatcode(
103 "deploy program requires either so_path or so_bytes".to_string(),
104 )),
105 }
106 }
107
108 pub(crate) fn load_idl(&self) -> SurfnetResult<Option<surfpool_types::Idl>> {
110 let Some(path) = &self.idl_path else {
111 return Ok(None);
112 };
113
114 let contents = std::fs::read_to_string(path).map_err(|e| {
115 SurfnetError::Cheatcode(format!("failed to read IDL from {}: {e}", path.display()))
116 })?;
117 let idl = serde_json::from_str(&contents).map_err(|e| {
118 SurfnetError::Cheatcode(format!("failed to parse IDL from {}: {e}", path.display()))
119 })?;
120 Ok(Some(idl))
121 }
122}