This commit is contained in:
2026-04-20 22:51:55 +02:00
parent 64012db35d
commit 864fda22cd
5 changed files with 1180 additions and 163 deletions

View File

@@ -2,3 +2,4 @@
0.0.1 - initial skel 0.0.1 - initial skel
0.0.2 - Socle conforme 0.0.2 - Socle conforme
0.1.0 - Transport WebSocket générique

View File

@@ -8,7 +8,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.0.2" version = "0.1.0"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot" repository = "https://git.sasedev.com/Sasedev/khadhroony-bobobot"
@@ -23,7 +23,7 @@ chacha20poly1305 = { version = "^0.10", features = ["std", "stream"] }
chrono = { version = "^0.4", features = ["serde"] } chrono = { version = "^0.4", features = ["serde"] }
fs2 = { version = "^0.4", features = [] } fs2 = { version = "^0.4", features = [] }
futures-util = { version = "^0.3", features = ["default", "std" ,"futures-sink"] } futures-util = { version = "^0.3", features = ["default", "std" ,"futures-sink"] }
jsonschema = { version = "^0.40", features = [] } jsonschema = { version = "^0.46", features = [] }
rand = { version = "^0.10", features = ["std", "serde", "sys_rng"] } rand = { version = "^0.10", features = ["std", "serde", "sys_rng"] }
reqwest = { version = "^0.13", default-features = false, features = ["charset", "cookies", "deflate", "form", "gzip", "http2", "json", "multipart", "query", "rustls", "socks", "stream", "zstd"] } reqwest = { version = "^0.13", default-features = false, features = ["charset", "cookies", "deflate", "form", "gzip", "http2", "json", "multipart", "query", "rustls", "socks", "stream", "zstd"] }
rustls = { version = "^0.23", features = ["aws-lc-rs"] } rustls = { version = "^0.23", features = ["aws-lc-rs"] }

View File

@@ -15,124 +15,6 @@ pub struct KbConfig {
pub solana: KbSolanaConfig, pub solana: KbSolanaConfig,
} }
/// Generic application settings.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbAppConfig {
/// Human-readable application name.
pub name: std::string::String,
/// Current environment name such as `development` or `production`.
pub environment: std::string::String,
/// Default reconnection preference used by future UI settings.
pub auto_reconnect_default: bool,
}
/// Logging and tracing configuration.
///
/// In version `0.0.2`, the project actively uses:
/// `level`, `console_enabled`, `console_ansi`, `file_enabled`,
/// `directory`, `file_prefix`, and `rotation`.
///
/// The fields `message_format` and `time_format` are already stored in the
/// configuration so that the format policy is stabilized early, even though
/// their handling will be refined in later versions.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbLoggingConfig {
/// Global default log level.
pub level: std::string::String,
/// Enables console logging.
pub console_enabled: bool,
/// Enables ANSI colors on console output.
pub console_ansi: bool,
/// Enables file logging.
pub file_enabled: bool,
/// Directory where log files are stored.
pub directory: std::string::String,
/// Prefix used for log file names.
pub file_prefix: std::string::String,
/// File rotation strategy such as `daily`, `hourly`, or `never`.
pub rotation: std::string::String,
/// Preferred message formatting preset.
pub message_format: std::string::String,
/// Preferred time formatting preset.
pub time_format: std::string::String,
/// Per-target log level overrides.
pub target_filters: std::collections::BTreeMap<std::string::String, std::string::String>,
}
/// Local data paths used by the application.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbDataConfig {
/// SQLite database path.
pub sqlite_path: std::string::String,
/// Directory storing Solana wallets and related material in future versions.
pub wallets_directory: std::string::String,
}
/// Solana transport configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbSolanaConfig {
/// Named HTTP endpoints.
pub http_endpoints: std::vec::Vec<KbHttpEndpointConfig>,
/// Named WebSocket endpoints.
pub ws_endpoints: std::vec::Vec<KbWsEndpointConfig>,
}
/// HTTP endpoint configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbHttpEndpointConfig {
/// Stable internal endpoint name used by the application.
pub name: std::string::String,
/// Enables or disables the endpoint.
pub enabled: bool,
/// Provider name such as `solana-public`, `helius`, or `custom`.
pub provider: std::string::String,
/// Base HTTP RPC URL.
pub url: std::string::String,
/// Optional environment variable name used to resolve an API key later.
pub api_key_env_var: std::option::Option<std::string::String>,
/// Logical roles assigned to this endpoint.
pub roles: std::vec::Vec<std::string::String>,
/// Allowed average request rate.
pub requests_per_second: u32,
/// Burst capacity for future rate-limiting.
pub burst: u32,
/// HTTP connect timeout in milliseconds.
pub connect_timeout_ms: u64,
/// HTTP request timeout in milliseconds.
pub request_timeout_ms: u64,
}
/// WebSocket endpoint configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbWsEndpointConfig {
/// Stable internal endpoint name used by the application.
pub name: std::string::String,
/// Enables or disables the endpoint.
pub enabled: bool,
/// Provider name such as `solana-public`, `helius`, or `custom`.
pub provider: std::string::String,
/// Base WebSocket RPC URL.
pub url: std::string::String,
/// Optional environment variable name used to resolve an API key later.
pub api_key_env_var: std::option::Option<std::string::String>,
/// Logical roles assigned to this endpoint.
pub roles: std::vec::Vec<std::string::String>,
/// Maximum number of subscriptions allowed on this endpoint.
pub max_subscriptions: u32,
/// WebSocket connect timeout in milliseconds.
pub connect_timeout_ms: u64,
/// Timeout for request/response round-trips in milliseconds.
pub request_timeout_ms: u64,
/// Timeout used during unsubscribe on disconnect in milliseconds.
pub unsubscribe_timeout_ms: u64,
/// Capacity of the future outgoing write channel.
pub write_channel_capacity: usize,
/// Capacity of the future event channel.
pub event_channel_capacity: usize,
/// Enables future automatic reconnection behavior.
pub auto_reconnect: bool,
}
impl KbConfig { impl KbConfig {
/// Returns the default path of the JSON configuration file. /// Returns the default path of the JSON configuration file.
pub fn default_path() -> std::path::PathBuf { pub fn default_path() -> std::path::PathBuf {
@@ -419,6 +301,157 @@ impl KbConfig {
} }
} }
/// Generic application settings.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbAppConfig {
/// Human-readable application name.
pub name: std::string::String,
/// Current environment name such as `development` or `production`.
pub environment: std::string::String,
/// Default reconnection preference used by future UI settings.
pub auto_reconnect_default: bool,
}
/// Logging and tracing configuration.
///
/// In version `0.0.2`, the project actively uses:
/// `level`, `console_enabled`, `console_ansi`, `file_enabled`,
/// `directory`, `file_prefix`, and `rotation`.
///
/// The fields `message_format` and `time_format` are already stored in the
/// configuration so that the format policy is stabilized early, even though
/// their handling will be refined in later versions.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbLoggingConfig {
/// Global default log level.
pub level: std::string::String,
/// Enables console logging.
pub console_enabled: bool,
/// Enables ANSI colors on console output.
pub console_ansi: bool,
/// Enables file logging.
pub file_enabled: bool,
/// Directory where log files are stored.
pub directory: std::string::String,
/// Prefix used for log file names.
pub file_prefix: std::string::String,
/// File rotation strategy such as `daily`, `hourly`, or `never`.
pub rotation: std::string::String,
/// Preferred message formatting preset.
pub message_format: std::string::String,
/// Preferred time formatting preset.
pub time_format: std::string::String,
/// Per-target log level overrides.
pub target_filters: std::collections::BTreeMap<std::string::String, std::string::String>,
}
impl KbLoggingConfig {
/// Returns the resolved logging directory path.
pub fn directory_path(&self) -> std::path::PathBuf {
kb_resolve_workspace_relative_path(&self.directory)
}
}
/// Local data paths used by the application.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbDataConfig {
/// SQLite database path.
pub sqlite_path: std::string::String,
/// Directory storing Solana wallets and related material in future versions.
pub wallets_directory: std::string::String,
}
impl KbDataConfig {
/// Returns the resolved SQLite database path.
pub fn sqlite_path_buf(&self) -> std::path::PathBuf {
kb_resolve_workspace_relative_path(&self.sqlite_path)
}
/// Returns the resolved wallets directory path.
pub fn wallets_directory_path(&self) -> std::path::PathBuf {
kb_resolve_workspace_relative_path(&self.wallets_directory)
}
}
/// Solana transport configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbSolanaConfig {
/// Named HTTP endpoints.
pub http_endpoints: std::vec::Vec<KbHttpEndpointConfig>,
/// Named WebSocket endpoints.
pub ws_endpoints: std::vec::Vec<KbWsEndpointConfig>,
}
/// HTTP endpoint configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbHttpEndpointConfig {
/// Stable internal endpoint name used by the application.
pub name: std::string::String,
/// Enables or disables the endpoint.
pub enabled: bool,
/// Provider name such as `solana-public`, `helius`, or `custom`.
pub provider: std::string::String,
/// Base HTTP RPC URL.
pub url: std::string::String,
/// Optional environment variable name used to resolve an API key later.
pub api_key_env_var: std::option::Option<std::string::String>,
/// Logical roles assigned to this endpoint.
pub roles: std::vec::Vec<std::string::String>,
/// Allowed average request rate.
pub requests_per_second: u32,
/// Burst capacity for future rate-limiting.
pub burst: u32,
/// HTTP connect timeout in milliseconds.
pub connect_timeout_ms: u64,
/// HTTP request timeout in milliseconds.
pub request_timeout_ms: u64,
}
impl KbHttpEndpointConfig {
/// Returns the resolved endpoint URL.
pub fn resolved_url(&self) -> Result<std::string::String, crate::KbError> {
kb_resolve_endpoint_url(&self.url, &self.api_key_env_var)
}
}
/// WebSocket endpoint configuration.
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub struct KbWsEndpointConfig {
/// Stable internal endpoint name used by the application.
pub name: std::string::String,
/// Enables or disables the endpoint.
pub enabled: bool,
/// Provider name such as `solana-public`, `helius`, or `custom`.
pub provider: std::string::String,
/// Base WebSocket RPC URL.
pub url: std::string::String,
/// Optional environment variable name used to resolve an API key later.
pub api_key_env_var: std::option::Option<std::string::String>,
/// Logical roles assigned to this endpoint.
pub roles: std::vec::Vec<std::string::String>,
/// Maximum number of subscriptions allowed on this endpoint.
pub max_subscriptions: u32,
/// WebSocket connect timeout in milliseconds.
pub connect_timeout_ms: u64,
/// Timeout for request/response round-trips in milliseconds.
pub request_timeout_ms: u64,
/// Timeout used during unsubscribe on disconnect in milliseconds.
pub unsubscribe_timeout_ms: u64,
/// Capacity of the future outgoing write channel.
pub write_channel_capacity: usize,
/// Capacity of the future event channel.
pub event_channel_capacity: usize,
/// Enables future automatic reconnection behavior.
pub auto_reconnect: bool,
}
impl KbWsEndpointConfig {
/// Returns the resolved endpoint URL.
pub fn resolved_url(&self) -> Result<std::string::String, crate::KbError> {
kb_resolve_endpoint_url(&self.url, &self.api_key_env_var)
}
}
fn kb_workspace_root_dir() -> std::path::PathBuf { fn kb_workspace_root_dir() -> std::path::PathBuf {
let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); let manifest_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
match manifest_dir.parent() { match manifest_dir.parent() {
@@ -435,21 +468,30 @@ fn kb_resolve_workspace_relative_path<P: AsRef<std::path::Path>>(path: P) -> std
kb_workspace_root_dir().join(input_path) kb_workspace_root_dir().join(input_path)
} }
impl KbLoggingConfig { fn kb_resolve_endpoint_url(
/// Returns the resolved logging directory path. url: &str,
pub fn directory_path(&self) -> std::path::PathBuf { api_key_env_var: &std::option::Option<std::string::String>,
kb_resolve_workspace_relative_path(&self.directory) ) -> Result<std::string::String, crate::KbError> {
let env_var_name_option = api_key_env_var.as_deref();
let env_var_name = match env_var_name_option {
Some(env_var_name) => env_var_name,
None => {
return Ok(url.to_string());
} }
};
let placeholder = format!("${{{env_var_name}}}");
if !url.contains(&placeholder) {
return Ok(url.to_string());
} }
let env_value_result = std::env::var(env_var_name);
impl KbDataConfig { let env_value = match env_value_result {
/// Returns the resolved SQLite database path. Ok(env_value) => env_value,
pub fn sqlite_path_buf(&self) -> std::path::PathBuf { Err(error) => {
kb_resolve_workspace_relative_path(&self.sqlite_path) return Err(crate::KbError::Config(format!(
} "environment variable '{}' is required to resolve endpoint url '{}': {error}",
env_var_name, url
/// Returns the resolved wallets directory path. )));
pub fn wallets_directory_path(&self) -> std::path::PathBuf {
kb_resolve_workspace_relative_path(&self.wallets_directory)
} }
};
Ok(url.replace(&placeholder, &env_value))
} }

View File

@@ -32,3 +32,5 @@ pub use crate::tracing::KbTracingGuard;
pub use crate::tracing::init_tracing; pub use crate::tracing::init_tracing;
pub use crate::types::KbConnectionState; pub use crate::types::KbConnectionState;
pub use crate::ws_client::WsClient; pub use crate::ws_client::WsClient;
pub use crate::ws_client::WsEvent;
pub use crate::ws_client::WsOutgoingMessage;

File diff suppressed because it is too large Load Diff