1use std::net::SocketAddr;
2
3use hyper::Method;
4use jsonrpsee::{
5 server::{middleware::proxy_get_request::ProxyGetRequestLayer, ServerBuilder, ServerHandle},
6 RpcModule,
7};
8use log::debug;
9use tower_http::cors::{Any, CorsLayer};
10
11use super::api::PhotonApi;
12
13pub async fn run_server(api: PhotonApi, port: u16) -> Result<ServerHandle, anyhow::Error> {
14 let addr = SocketAddr::from(([0, 0, 0, 0], port));
15 let cors = CorsLayer::new()
16 .allow_methods([Method::POST, Method::GET])
17 .allow_origin(Any)
18 .allow_headers([hyper::header::CONTENT_TYPE]);
19 let middleware = tower::ServiceBuilder::new()
20 .layer(cors)
21 .layer(ProxyGetRequestLayer::new("/liveness", "liveness")?)
22 .layer(ProxyGetRequestLayer::new("/readiness", "readiness")?);
23 let server = ServerBuilder::default()
24 .set_middleware(middleware)
25 .build(addr)
26 .await?;
27 let rpc_module = build_rpc_module(api)?;
28 server.start(rpc_module).map_err(|e| anyhow::anyhow!(e))
29}
30
31fn build_rpc_module(api_and_indexer: PhotonApi) -> Result<RpcModule<PhotonApi>, anyhow::Error> {
32 let mut module = RpcModule::new(api_and_indexer);
33
34 module.register_async_method("liveness", |_rpc_params, rpc_context| async move {
35 debug!("Checking Liveness");
36 let api = rpc_context.as_ref();
37 api.liveness().await.map_err(Into::into)
38 })?;
39
40 module.register_async_method("readiness", |_rpc_params, rpc_context| async move {
41 debug!("Checking Readiness");
42 let api = rpc_context.as_ref();
43 api.readiness().await.map_err(Into::into)
44 })?;
45
46 module.register_async_method(
47 "getCompressedAccount",
48 |rpc_params, rpc_context| async move {
49 let api = rpc_context.as_ref();
50 let payload = rpc_params.parse()?;
51 api.get_compressed_account(payload)
52 .await
53 .map_err(Into::into)
54 },
55 )?;
56
57 module.register_async_method(
58 "getCompressedAccountProof",
59 |rpc_params, rpc_context| async move {
60 let api = rpc_context.as_ref();
61 let payload = rpc_params.parse()?;
62 api.get_compressed_account_proof(payload)
63 .await
64 .map_err(Into::into)
65 },
66 )?;
67
68 module.register_async_method(
69 "getMultipleCompressedAccountProofs",
70 |rpc_params, rpc_context| async move {
71 let api = rpc_context.as_ref();
72 let payload = rpc_params.parse()?;
73 api.get_multiple_compressed_account_proofs(payload)
74 .await
75 .map_err(Into::into)
76 },
77 )?;
78
79 module.register_async_method(
80 "getCompressedTokenAccountsByOwner",
81 |rpc_params, rpc_context| async move {
82 let api = rpc_context.as_ref();
83 let payload = rpc_params.parse()?;
84 api.get_compressed_token_accounts_by_owner(payload)
85 .await
86 .map_err(Into::into)
87 },
88 )?;
89
90 module.register_async_method(
91 "getCompressedTokenAccountsByDelegate",
92 |rpc_params, rpc_context| async move {
93 let api = rpc_context.as_ref();
94 let payload = rpc_params.parse()?;
95 api.get_compressed_token_accounts_by_delegate(payload)
96 .await
97 .map_err(Into::into)
98 },
99 )?;
100
101 module.register_async_method(
102 "getCompressedBalanceByOwner",
103 |rpc_params, rpc_context| async move {
104 let api = rpc_context.as_ref();
105 let payload = rpc_params.parse()?;
106 api.get_compressed_balance_by_owner(payload)
107 .await
108 .map_err(Into::into)
109 },
110 )?;
111
112 module.register_async_method(
113 "getCompressedTokenBalancesByOwner",
114 |rpc_params, rpc_context| async move {
115 let api = rpc_context.as_ref();
116 let payload = rpc_params.parse()?;
117 api.get_compressed_token_balances_by_owner(payload)
118 .await
119 .map_err(Into::into)
120 },
121 )?;
122
123 module.register_async_method(
124 "getCompressedTokenAccountBalance",
125 |rpc_params, rpc_context| async move {
126 let api = rpc_context.as_ref();
127 let payload = rpc_params.parse()?;
128 api.get_compressed_token_account_balance(payload)
129 .await
130 .map_err(Into::into)
131 },
132 )?;
133
134 module.register_async_method(
135 "getCompressedBalance",
136 |rpc_params, rpc_context| async move {
137 let api = rpc_context.as_ref();
138 let payload = rpc_params.parse()?;
139 api.get_compressed_account_balance(payload)
140 .await
141 .map_err(Into::into)
142 },
143 )?;
144
145 module.register_async_method(
146 "getCompressedAccountBalance",
147 |rpc_params, rpc_context| async move {
148 let api = rpc_context.as_ref();
149 let payload = rpc_params.parse()?;
150 api.get_compressed_account_balance(payload)
151 .await
152 .map_err(Into::into)
153 },
154 )?;
155
156 module.register_async_method("getIndexerHealth", |_rpc_params, rpc_context| async move {
157 rpc_context
158 .as_ref()
159 .get_indexer_health()
160 .await
161 .map_err(Into::into)
162 })?;
163
164 module.register_async_method("getIndexerSlot", |_rpc_params, rpc_context| async move {
165 let api = rpc_context.as_ref();
166 api.get_indexer_slot().await.map_err(Into::into)
167 })?;
168
169 module.register_async_method(
170 "getCompressedAccountsByOwner",
171 |rpc_params, rpc_context| async move {
172 let api = rpc_context.as_ref();
173 let payload = rpc_params.parse()?;
174 api.get_compressed_accounts_by_owner(payload)
175 .await
176 .map_err(Into::into)
177 },
178 )?;
179
180 module.register_async_method(
181 "getMultipleCompressedAccounts",
182 |rpc_params, rpc_context| async move {
183 let api = rpc_context.as_ref();
184 let payload = rpc_params.parse()?;
185 api.get_multiple_compressed_accounts(payload)
186 .await
187 .map_err(Into::into)
188 },
189 )?;
190
191 module.register_async_method(
192 "getCompressionSignaturesForAccount",
193 |rpc_params, rpc_context| async move {
194 let api = rpc_context.as_ref();
195 let payload = rpc_params.parse()?;
196 api.get_compression_signatures_for_account(payload)
197 .await
198 .map_err(Into::into)
199 },
200 )?;
201
202 module.register_async_method(
203 "getCompressionSignaturesForAddress",
204 |rpc_params, rpc_context| async move {
205 let api = rpc_context.as_ref();
206 let payload = rpc_params.parse()?;
207 api.get_compression_signatures_for_address(payload)
208 .await
209 .map_err(Into::into)
210 },
211 )?;
212
213 module.register_async_method(
214 "getCompressionSignaturesForOwner",
215 |rpc_params, rpc_context| async move {
216 let api = rpc_context.as_ref();
217 let payload = rpc_params.parse()?;
218 api.get_compression_signatures_for_owner(payload)
219 .await
220 .map_err(Into::into)
221 },
222 )?;
223
224 module.register_async_method(
225 "getCompressionSignaturesForTokenOwner",
226 |rpc_params, rpc_context| async move {
227 let api = rpc_context.as_ref();
228 let payload = rpc_params.parse()?;
229 api.get_compression_signatures_for_token_owner(payload)
230 .await
231 .map_err(Into::into)
232 },
233 )?;
234
235 module.register_async_method(
236 "getTransactionWithCompressionInfo",
237 |rpc_params, rpc_context| async move {
238 let api = rpc_context.as_ref();
239 let payload = rpc_params.parse()?;
240 api.get_transaction_with_compression_info(payload)
241 .await
242 .map_err(Into::into)
243 },
244 )?;
245 module.register_async_method("getValidityProof", |rpc_params, rpc_context| async move {
246 let api = rpc_context.as_ref();
247 let payload = rpc_params.parse()?;
248 api.get_validity_proof(payload).await.map_err(Into::into)
249 })?;
250
251 module.register_async_method(
252 "getLatestCompressionSignatures",
253 |rpc_params, rpc_context| async move {
254 let api = rpc_context.as_ref();
255 let payload = rpc_params.parse()?;
256 api.get_latest_compression_signatures(payload)
257 .await
258 .map_err(Into::into)
259 },
260 )?;
261
262 module.register_async_method(
263 "getLatestNonVotingSignatures",
264 |rpc_params, rpc_context| async move {
265 let api = rpc_context.as_ref();
266 let payload = rpc_params.parse()?;
267 api.get_latest_non_voting_signatures(payload)
268 .await
269 .map_err(Into::into)
270 },
271 )?;
272
273 module.register_async_method(
274 "getMultipleNewAddressProofs",
275 |rpc_params, rpc_context| async move {
276 let api = rpc_context.as_ref();
277 let payload = rpc_params.parse()?;
278 api.get_multiple_new_address_proofs(payload)
279 .await
280 .map_err(Into::into)
281 },
282 )?;
283
284 module.register_async_method(
285 "getMultipleNewAddressProofsV2",
286 |rpc_params, rpc_context| async move {
287 let api = rpc_context.as_ref();
288 let payload = rpc_params.parse()?;
289 api.get_multiple_new_address_proofs_v2(payload)
290 .await
291 .map_err(Into::into)
292 },
293 )?;
294 module.register_async_method(
295 "getCompressedMintTokenHolders",
296 |rpc_params, rpc_context| async move {
297 let api = rpc_context.as_ref();
298 let payload = rpc_params.parse()?;
299 api.get_compressed_mint_token_holders(payload)
300 .await
301 .map_err(Into::into)
302 },
303 )?;
304
305 module.register_async_method(
306 "getCompressedTokenBalancesByOwnerV2",
307 |rpc_params, rpc_context| async move {
308 let api = rpc_context.as_ref();
309 let payload = rpc_params.parse()?;
310 api.get_compressed_token_balances_by_owner_v2(payload)
311 .await
312 .map_err(Into::into)
313 },
314 )?;
315
316 Ok(module)
317}