Skip to content

Commit

Permalink
Better Documentation For rpc_client.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
0xIchigo committed Apr 30, 2024
1 parent 1d6cb82 commit ad0ca66
Showing 1 changed file with 111 additions and 2 deletions.
113 changes: 111 additions & 2 deletions src/rpc_client.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/// # RPC Client for Helius
///
/// This module provides access to the Helius API using an RPC client with an embedded Solana client
///
/// ## Errors
///
/// Most methods in this client will return a `Result<T, HeliusError>`, where `HeliusError` can be:
/// - `BadRequest`: Incorrect request format or parameters. Check the path and the text for details
/// - `Unauthorized`: Incorrect or missing API key. Ensure you've provided the correct API key
/// - `NotFound`: The requested resource was not found. This could mean an invalid ID or a non-existent endpoint
/// - `RateLimitExceeded`: Too many requests have been sent in a short period. Consider implementing retries with an exponential backoff
/// - `InternalError`: Server-side errors. These are rare and typically indicate issues on the server side. If these issues persist, please contact Helius support
/// - `Network`: Errors during HTTP communication, typically from underlying network issues
/// - `SerdeJson`: Errors during the serialization or deserialization process
/// - `Unknown`: Catch-all for unclassified errors, with a status code and message provided for further investigation
///
/// Ensure to handle these errors gracefully in your application to maintain robustness and stellar UX
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;
Expand All @@ -24,7 +41,17 @@ pub struct RpcClient {
}

impl RpcClient {
/// Initializes a new RpcClient instance
/// Initializes a new RpcClient instance with an embedded Solana client
///
/// # Arguments
/// * `client` - Shared HTTP client for making requests
/// * `config` - Configuration holding a given API key and endpoint URLs
///
/// # Returns
/// A result that, if successful, contains the initialized RpcClient
///
/// # Errors
/// Returns `HeliusError` if the URL isn't formatted correctly or the `RequestHandler` fails to initialize
pub fn new(client: Arc<Client>, config: Arc<Config>) -> Result<Self> {
let handler: RequestHandler = RequestHandler::new(client)?;
let url: String = format!("{}/?api-key={}", config.endpoints.rpc, config.api_key);
Expand All @@ -38,9 +65,19 @@ impl RpcClient {
}

/// Streamlines an RPC POST request
///
/// # Arguments
/// * `method` - RPC method name as a string reference (e.g., "getAsset")
/// * `request` - Request data for a given method that conforms to the Debug, Serialize, Send, and Sync traits
///
/// # Returns
/// A result that, if successful, contains the deserialized response data
///
/// # Errors
/// Returns `HeliusError` if the URL cannot be parsed or the HTTP request fails
pub async fn post_rpc_request<R, T>(&self, method: &str, request: R) -> Result<T>
where
R: Debug + Serialize + Debug + Send + Sync,
R: Debug + Serialize + Send + Sync,
T: Debug + DeserializeOwned + Default,
{
let base_url: String = format!("{}/?api-key={}", self.config.endpoints.rpc, self.config.api_key);
Expand All @@ -58,21 +95,45 @@ impl RpcClient {
}

/// Gets an asset by its ID
///
/// # Arguments
/// * `request` - A struct containing the ID of the asset to fetch, along with other optional sorting and display options
///
/// # Returns
/// A `Result` with an optional `Asset` object if found. It can also return `None` if no asset matches the ID provided
pub async fn get_asset(&self, request: GetAsset) -> Result<Option<Asset>> {
self.post_rpc_request("getAsset", request).await
}

/// Gets multiple assets by their ID
///
/// # Arguments
/// * `request` - A struct containing the IDs of the assets to fetch in a batch
///
/// # Returns
/// A `Result` containing a vector of optional `Asset` objects, each corresponding to the IDs provided. It can also return `None` if no assets match the IDs provided
pub async fn get_asset_batch(&self, request: GetAssetBatch) -> Result<Vec<Option<Asset>>> {
self.post_rpc_request("getAssetBatch", request).await
}

/// Gets a merkle proof for a compressed asset by its ID
///
/// # Arguments
/// * `request` - A struct containing the ID of the asset for which the proof is requested
///
/// # Returns
/// A `Result` with an optional `AssetProof` object if the asset exists and the proof is retrievable. It can also return `None` if the proof doesn't exist or isn't retrievable
pub async fn get_asset_proof(&self, request: GetAssetProof) -> Result<Option<AssetProof>> {
self.post_rpc_request("getAssetProof", request).await
}

/// Gets multiple asset proofs by their IDs
///
/// # Arguments
/// * `request` - A struct containing the IDs of the assets for which proofs are requested
///
/// # Returns
/// A `Result` with a hashmap where each key is an asset ID and each value is an optional `AssetProof`. It can also return `None` if no proofs correspond to the IDs provided
pub async fn get_asset_proof_batch(
&self,
request: GetAssetProofBatch,
Expand All @@ -81,41 +142,89 @@ impl RpcClient {
}

/// Gets a list of assets of a given authority
///
/// # Arguments
/// * `request` - A struct containing the authority's address, along with other optional sorting and display options
///
/// # Returns
/// A `Result` containing an `AssetList` detailing the assets managed by the specified authority. It can also return `None` if no assets are managed by the given authority
pub async fn get_assets_by_authority(&self, request: GetAssetsByAuthority) -> Result<AssetList> {
self.post_rpc_request("getAssetsByAuthority", request).await
}

/// Gets a list of assets of a given creator
///
/// # Arguments
/// * `request` - A struct containing the creator's address and optional filters for verification, sorting, and display options
///
/// # Returns
/// A `Result` containing an `AssetList` of assets created by the specified address. It can also return `None` if the specified address hasn't created any assets
pub async fn get_assets_by_creator(&self, request: GetAssetsByCreator) -> Result<AssetList> {
self.post_rpc_request("getAssetsByCreator", request).await
}

/// Gets a list of assets by a group key and value
///
/// # Arguments
/// * `request` - A struct that defines a group key and value to query, along with other optional sorting and display options
///
/// # Returns
/// A `Result` containing an `AssetList` that matches the group criteria. It can also return `None` if no assets match the group criteria
pub async fn get_assets_by_group(&self, request: GetAssetsByGroup) -> Result<AssetList> {
self.post_rpc_request("getAssetsByGroup", request).await
}

/// Gets a list of assets owned by a given address
///
/// # Arguments
/// * `request` - A struct containing the owner's address, along with optional sorting, pagination, and display options
///
/// # Returns
/// A `Result` containing an `AssetList` of assets owned by the specified address. It can also return `None` if the specified address doesn't own any assets
pub async fn get_assets_by_owner(&self, request: GetAssetsByOwner) -> Result<AssetList> {
self.post_rpc_request("getAssetsByOwner", request).await
}

/// Gets assets based on the custom search criteria passed in
///
/// # Arguments
/// * `request` - A struct that specifies the search conditions, filtering options, and sorting preferences
///
/// # Returns
/// A `Result` containing an `AssetList` of assets that meet the search criteria. It can also return `None` if no assets match the search criteria
pub async fn search_assets(&self, request: SearchAssets) -> Result<AssetList> {
self.post_rpc_request("searchAssets", request).await
}

/// Gets transaction signatures for a given asset
///
/// # Arguments
/// * `request` - A struct that includes the asset's ID and optional pagination settings
///
/// # Returns
/// A `Result` containing a `TransactionSignatureList` detailing the transactions involving the specified asset. It can also return `None` if any transactions involving the specified asset cannot be retrieved
pub async fn get_asset_signatures(&self, request: GetAssetSignatures) -> Result<TransactionSignatureList> {
self.post_rpc_request("getSignaturesForAsset", request).await
}

/// Gets transaction signatures for a given asset
///
/// # Arguments
/// * `request` - A struct that includes the owner or mint address, along with optional sorting, pagination, and display options
///
/// # Returns
/// A `Result` containing a `TokenAccountsList` detailing the token accounts matching the request parameters. It can also return `None` if the specified address has no token accounts
pub async fn get_token_accounts(&self, request: GetTokenAccounts) -> Result<TokenAccountsList> {
self.post_rpc_request("getTokenAccounts", request).await
}

/// Gets all the NFT editions associated with a specific master NFT
///
/// # Arguments
/// * `request` - A struct that includes the master NFT's ID and optional pagination settings
///
/// # Returns
/// A `Result` containing an `EditionsList` of all the editions linked to the master NFT. It can also return `None` if there aren't any editions linked to the specified master NFT
pub async fn get_nft_editions(&self, request: GetNftEditions) -> Result<EditionsList> {
self.post_rpc_request("getNftEditions", request).await
}
Expand Down

0 comments on commit ad0ca66

Please sign in to comment.