diff --git a/Cargo.lock b/Cargo.lock index 622bafd18..c61450bd9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3685,6 +3685,16 @@ dependencies = [ "workflow-serializer", ] +[[package]] +name = "kaspa-wrpc-simple-client-example" +version = "0.14.5" +dependencies = [ + "futures", + "kaspa-rpc-core", + "kaspa-wrpc-client", + "tokio", +] + [[package]] name = "kaspa-wrpc-wasm" version = "0.14.7" diff --git a/Cargo.toml b/Cargo.toml index f3096a714..c4d46c6ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,7 @@ members = [ "rpc/wrpc/proxy", "rpc/wrpc/wasm", "rpc/wrpc/examples/subscriber", + "rpc/wrpc/examples/simple_client", "mining", "mining/errors", "protocol/p2p", diff --git a/rpc/wrpc/examples/simple_client/Cargo.toml b/rpc/wrpc/examples/simple_client/Cargo.toml new file mode 100644 index 000000000..c55774b68 --- /dev/null +++ b/rpc/wrpc/examples/simple_client/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "kaspa-wrpc-simple-client-example" +description = "Kaspa wRPC simple client example" +publish = false +rust-version.workspace = true +version.workspace = true +edition.workspace = true +authors.workspace = true +include.workspace = true +license.workspace = true +repository.workspace = true + +[dependencies] +futures.workspace = true +kaspa-rpc-core.workspace = true +kaspa-wrpc-client.workspace = true +tokio.workspace = true + diff --git a/rpc/wrpc/examples/simple_client/src/main.rs b/rpc/wrpc/examples/simple_client/src/main.rs new file mode 100644 index 000000000..0d63a24c2 --- /dev/null +++ b/rpc/wrpc/examples/simple_client/src/main.rs @@ -0,0 +1,104 @@ +// Example of simple client to connect with Kaspa node using wRPC connection and collect some node and network basic data + +use kaspa_rpc_core::{api::rpc::RpcApi, GetBlockDagInfoResponse, GetServerInfoResponse}; +use kaspa_wrpc_client::{ + client::{ConnectOptions, ConnectStrategy}, + prelude::NetworkId, + prelude::NetworkType, + result::Result, + KaspaRpcClient, Resolver, WrpcEncoding, +}; +use std::process::ExitCode; +use std::time::Duration; + +#[tokio::main] +async fn main() -> ExitCode { + match check_node_status().await { + Ok(_) => { + println!("Well done! You successfully completed your first client connection to Kaspa node!"); + ExitCode::SUCCESS + } + Err(error) => { + println!("An error occurred: {error}"); + ExitCode::FAILURE + } + } +} + +async fn check_node_status() -> Result<()> { + // Select encoding method to use, depending on node settings + let encoding = WrpcEncoding::Borsh; + + // If you want to connect to your own node, define your node address and wRPC port using let url = Some("ws://0.0.0.0:17110") + // Verify your Kaspa node is runnning with --rpclisten-borsh=0.0.0.0:17110 parameter + // In this example we don't use a specific node but we connect through the resolver, which use a pool of public nodes + let url = None; + let resolver = Some(Resolver::default()); + + // Define the network your Kaspa node is connected to + // You can select NetworkType::Mainnet, NetworkType::Testnet, NetworkType::Devnet, NetworkType::Simnet + let network_type = NetworkType::Mainnet; + let selected_network = Some(NetworkId::new(network_type)); + + // Advanced options + let subscription_context = None; + + // Create new wRPC client with parameters defined above + let client = KaspaRpcClient::new(encoding, url, resolver, selected_network, subscription_context)?; + + // Advanced connection options + let timeout = 5_000; + let options = ConnectOptions { + block_async_connect: true, + connect_timeout: Some(Duration::from_millis(timeout)), + strategy: ConnectStrategy::Fallback, + ..Default::default() + }; + + // Connect to selected Kaspa node + client.connect(Some(options)).await?; + + // Retrieve and show Kaspa node information + let GetServerInfoResponse { is_synced, server_version, network_id, has_utxo_index, .. } = client.get_server_info().await?; + + println!("Node version: {server_version}"); + println!("Network: {network_id}"); + println!("Node is synced: {is_synced}"); + println!("Node is indexing UTXOs: {has_utxo_index}"); + + // Retrieve and show Kaspa network information + let GetBlockDagInfoResponse { + block_count, + header_count, + tip_hashes, + difficulty, + past_median_time, + virtual_parent_hashes, + pruning_point_hash, + virtual_daa_score, + sink, + .. + } = client.get_block_dag_info().await?; + + println!("Block count: {block_count}"); + println!("Header count: {header_count}"); + println!("Tip hashes:"); + for tip_hash in tip_hashes { + println!("{tip_hash}"); + } + println!("Difficulty: {difficulty}"); + println!("Past median time: {past_median_time}"); + println!("Virtual parent hashes:"); + for virtual_parent_hash in virtual_parent_hashes { + println!("{virtual_parent_hash}"); + } + println!("Pruning point hash: {pruning_point_hash}"); + println!("Virtual DAA score: {virtual_daa_score}"); + println!("Sink: {sink}"); + + // Disconnect client from Kaspa node + client.disconnect().await?; + + // Return function result + Ok(()) +}