From 8944d8d6770bca99871b2a89316bedb3ff91a6a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sylwester=20R=C4=85pa=C5=82a?= <sylwesterrapala@outlook.com>
Date: Wed, 25 Sep 2024 20:19:43 +0200
Subject: [PATCH] feat: allow create Helius from Config with actually using
 this config

---
 src/config.rs     | 35 +++++++++++++++++++++++++++++++++++
 src/rpc_client.rs | 10 ++++++----
 2 files changed, 41 insertions(+), 4 deletions(-)

diff --git a/src/config.rs b/src/config.rs
index c5df168c..7a525185 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,5 +1,13 @@
+use std::sync::Arc;
+
+use reqwest::Client;
+use solana_client::nonblocking::rpc_client::RpcClient as AsyncSolanaRpcClient;
+use url::Url;
+
 use crate::error::{HeliusError, Result};
+use crate::rpc_client::RpcClient;
 use crate::types::{Cluster, HeliusEndpoints};
+use crate::Helius;
 
 /// Configuration settings for the Helius client
 ///
@@ -40,4 +48,31 @@ impl Config {
             endpoints,
         })
     }
+
+    pub fn rpc_client_with_reqwest_client(&self, client: Client) -> crate::error::Result<RpcClient> {
+        RpcClient::new(Arc::new(client), Arc::new(self.clone()))
+    }
+
+    pub fn client_with_async_solana(self) -> crate::error::Result<Helius> {
+        let mut rpc_url_with_api_key: Url = self.endpoints.rpc.parse()?;
+        rpc_url_with_api_key
+            .query_pairs_mut()
+            .append_pair("api_key", &self.api_key)
+            .finish();
+
+        let reqwest_client = Client::new();
+
+        // DAS client
+        let rpc_client = self.rpc_client_with_reqwest_client(reqwest_client.clone())?;
+
+        let async_rpc_client = Arc::new(AsyncSolanaRpcClient::new(rpc_url_with_api_key.to_string()));
+
+        Ok(Helius {
+            config: Arc::new(self.clone()),
+            client: reqwest_client,
+            rpc_client: Arc::new(rpc_client),
+            async_rpc_client: Some(async_rpc_client),
+            ws_client: None,
+        })
+    }
 }
diff --git a/src/rpc_client.rs b/src/rpc_client.rs
index 57713e6b..8a63b290 100644
--- a/src/rpc_client.rs
+++ b/src/rpc_client.rs
@@ -55,8 +55,9 @@ impl RpcClient {
     /// 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);
-        let solana_client: Arc<SolanaRpcClient> = Arc::new(SolanaRpcClient::new(url));
+        let mut url: Url = config.endpoints.rpc.parse()?;
+        url.query_pairs_mut().append_pair("api-key", &config.api_key);
+        let solana_client = Arc::new(SolanaRpcClient::new(url.to_string()));
 
         Ok(RpcClient {
             handler,
@@ -81,8 +82,9 @@ impl RpcClient {
         R: Debug + Serialize + Send + Sync,
         T: Debug + DeserializeOwned + Default,
     {
-        let base_url: String = format!("{}/?api-key={}", self.config.endpoints.rpc, self.config.api_key);
-        let url: Url = Url::parse(&base_url).expect("Failed to parse URL");
+        // TODO: why construct URL on every request?
+        let mut url: Url = self.config.endpoints.rpc.parse()?;
+        url.query_pairs_mut().append_pair("api-key", &self.config.api_key);
 
         let rpc_request: RpcRequest<R> = RpcRequest::new(method.to_string(), request);
         let rpc_response: RpcResponse<T> = self.handler.send(Method::POST, url, Some(&rpc_request)).await?;