nucleus-sdk 0.1.0

Rust SDK for Nucleus vault management
Documentation
pub mod error;
pub mod config;
pub mod calldata_queue;
pub mod utils;
pub use error::{Result, InvalidInputsError, ProtocolError, SdkError};
pub use crate::config::{DEFAULT_BASE_URL};

mod client;
use std::sync::Arc;

pub struct SDK {
    pub client: Arc<client::Client>
}

impl SDK {
    /// Creates a new SDK instance
    pub async fn new(api_key: String, base_url: Option<String>) -> Result<Self> {
        let base_url = base_url.unwrap_or_else(|| 
            DEFAULT_BASE_URL.to_string()
        );
        
        let client = Arc::new(client::Client::new(api_key, Some(base_url)).await?);
        
        Ok(Self { client })
    }

    /// Creates a new SDK instance with custom configuration
    pub async fn with_config(config: SDKConfig) -> Result<Self> {
        let client = Arc::new(client::Client::new(
            config.api_key,
            Some(config.base_url),
        ).await?);
        
        Ok(Self { client })
    }
}

pub struct SDKConfig {
    pub api_key: String,
    pub base_url: String,
    // Add other configuration options as needed
}

impl Default for SDKConfig {
    fn default() -> Self {
        Self {
            api_key: String::new(),
            base_url: DEFAULT_BASE_URL.to_string(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde_json::json;
    use mockito::{self, Mock, ServerGuard};

    // Helper function to create a mock server with address book endpoint
    fn setup_mock_server() -> (ServerGuard, Mock) {
        let mut server = mockito::Server::new();
        let fake_address_book = json!({
            "testnet": {
                "id": 1,
                "nucleus": {
                    "TEST": {
                        "manager": "0x1234567890123456789012345678901234567890"
                    }
                }
            }
        });

        // Mock the complete address book URL
        // Note: This should match the actual endpoint your client is calling
        let mock = server.mock("GET", "/v1/addressbook")  // Adjust this path to match your ADDRESS_BOOK_ENDPOINT
            .with_status(200)
            .with_header("content-type", "application/json")
            .with_body(fake_address_book.to_string())
            .expect(1)  // Expect exactly one call
            .create();

        (server, mock)
    }

    async fn test_sdk_new() {
        let (server, mock) = setup_mock_server();
        
        let base_url = server.url();
        let sdk = SDK::new("dummy_api_key".to_string(), Some(base_url)).await;
        
        // Print any error for debugging
        if let Err(ref e) = sdk {
            println!("SDK creation failed: {:?}", e);
        }
        
        assert!(sdk.is_ok(), "SDK::new should succeed with valid address book response");
        mock.assert();  // Verify the mock was called
    }

    async fn test_sdk_with_config() {
        let (server, mock) = setup_mock_server();

        let config = SDKConfig {
            api_key: "dummy_api_key".to_string(),
            base_url: server.url(),
        };

        let sdk = SDK::with_config(config).await;
        println!("SDK: {:?}", sdk.is_ok());
        assert!(sdk.is_ok(), "SDK::with_config should succeed with valid configuration");
    }
}