diff --git a/docs/api-documentation.md b/docs/api-documentation.md index ac032b04..0716b2cb 100644 --- a/docs/api-documentation.md +++ b/docs/api-documentation.md @@ -140,3 +140,19 @@ curl "https://forest-explorer.chainsafe.dev/api/claim_token?faucet_info=MainnetF ```bash ServerError|I'm a teapot - mainnet tokens are not available. ``` + +--- + +## Faucet Top-Up Requests + +If you encounter a server error indicating that faucet is exhausted. + +**Example:** + +```bash +ServerError|Faucet is empty, Request top-up +``` + +You can request for faucet top-up +[Here](https://github.com/ChainSafe/forest-explorer/discussions/134). This +discussion thread is monitored for top-up requests. diff --git a/src/faucet/server_api.rs b/src/faucet/server_api.rs index 7c82e0ff..8250b4d1 100644 --- a/src/faucet/server_api.rs +++ b/src/faucet/server_api.rs @@ -219,6 +219,7 @@ pub async fn claim_token( .map_err(ServerFnError::new)?; SendWrapper::new(async move { + ensure_faucet_has_funds(&rpc, &from, &faucet_info).await?; match faucet_info { FaucetInfo::MainnetFIL => { set_response_status(StatusCode::IM_A_TEAPOT); @@ -253,6 +254,25 @@ fn parse_and_validate_address( } } +#[cfg(feature = "ssr")] +async fn ensure_faucet_has_funds( + rpc: &crate::utils::rpc_context::Provider, + from: &Address, + faucet_info: &FaucetInfo, +) -> Result<(), ServerFnError> { + let faucet_balance = rpc + .wallet_balance(*from, &faucet_info.token_type()) + .await + .map_err(ServerFnError::new)?; + let max_gas_estimate = faucet_info.max_gas_limit() * faucet_info.max_gas_fee_cap(); + if faucet_balance < (faucet_info.drip_amount() + max_gas_estimate) { + return Err(ServerFnError::ServerError( + "Faucet is empty, Request top-up".to_string(), + )); + } + Ok(()) +} + #[cfg(feature = "ssr")] async fn handle_native_claim( faucet_info: FaucetInfo,