Skip to content

Commit

Permalink
Optional automatic query from AddressBook with Client initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
RickyLB authored Dec 3, 2024
1 parent 8ee1c7c commit ab816ca
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 2 deletions.
74 changes: 74 additions & 0 deletions examples/initialize_client_with_mirror_network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* ‌
* Hedera Rust SDK
* ​
* Copyright (C) 2022 - 2024 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

use assert_matches::assert_matches;
use clap::Parser;
use hedera::{AccountCreateTransaction, AccountId, Client, Hbar, PrivateKey};

#[derive(Parser, Debug)]
struct Args {
#[clap(long, env)]
operator_account_id: AccountId,

#[clap(long, env)]
operator_key: PrivateKey,

#[clap(long, env, default_value = "testnet")]
hedera_network: String,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let _ = dotenvy::dotenv();
let args = Args::parse();

/*
* Step 0: Create and Configure the Client
*/
let client =
Client::for_mirror_network(vec!["testnet.mirrornode.hedera.com:443".to_owned()]).await?;

// Set the operator account ID and key that will pay and sign all generated transactions.
client.set_operator(args.operator_account_id, args.operator_key);

/*
* Step 1: Genereate ED25519 key pair
*/
println!("Generating ED25519 key pair...");
let private_key = PrivateKey::generate_ed25519();

/*
* Step 2: Create an account
*/
let alice_id = AccountCreateTransaction::new()
.key(private_key.public_key())
.initial_balance(Hbar::new(5))
.execute(&client)
.await?
.get_receipt(&client)
.await?
.account_id;

let alice_id = assert_matches!(alice_id, Some(id) => id);

println!("Alice's ID = {alice_id}");

Ok(())
}
17 changes: 17 additions & 0 deletions src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ use crate::{
Hbar,
LedgerId,
NodeAddressBook,
NodeAddressBookQuery,
PrivateKey,
PublicKey,
};
Expand Down Expand Up @@ -289,6 +290,22 @@ impl Client {
Ok(ClientBuilder::new(network).disable_network_updating().build())
}

/// Construct a client from a select mirror network
pub async fn for_mirror_network(mirror_networks: Vec<String>) -> crate::Result<Self> {
let network_addresses: HashMap<String, AccountId> = HashMap::new();
let network = ManagedNetwork::new(
Network::from_addresses(&network_addresses)?,
MirrorNetwork::from_addresses(mirror_networks.into_iter().map(Cow::Owned).collect()),
);

let client = ClientBuilder::new(network).build();
let address_book = NodeAddressBookQuery::default().execute(&client).await?;

client.set_network_from_address_book(address_book);

Ok(client)
}

/// Construct a Hedera client pre-configured for mainnet access.
#[must_use]
pub fn for_mainnet() -> Self {
Expand Down
2 changes: 1 addition & 1 deletion src/client/network/mirror.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl MirrorNetworkData {
self.channel
.get_or_init(|| {
let endpoints = self.addresses.iter().map(|address| {
let uri = format!("tcp://{address}");
let uri = format!("https://{address}");
Endpoint::from_shared(uri)
.unwrap()
.keep_alive_timeout(Duration::from_secs(10))
Expand Down
1 change: 1 addition & 0 deletions src/client/network/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ pub(crate) const PREVIEWNET: &[(u64, &[&str])] = &[
(9, &["6.previewnet.hedera.com", "34.125.23.49", "50.18.17.93", "20.150.136.89"]),
];

#[derive(Default)]
pub(crate) struct Network(pub(crate) ArcSwap<NetworkData>);

impl Network {
Expand Down
1 change: 0 additions & 1 deletion src/mirror_query/subscribe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,6 @@ pub(crate) fn subscribe<I: Send, R: MirrorRequest<GrpcItem = I> + Send + Sync>(
return;
}
}

_ => {
// encountered an un-recoverable failure when attempting
// to establish the stream
Expand Down
16 changes: 16 additions & 0 deletions tests/e2e/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use std::collections::HashMap;

use hedera::Client;

#[tokio::test]
async fn initialize_with_mirror_network() -> anyhow::Result<()> {
let mirror_network_str = "testnet.mirrornode.hedera.com:443";
let client = Client::for_mirror_network(vec![mirror_network_str.to_owned()]).await?;
let mirror_network = client.mirror_network();

assert_eq!(mirror_network.len(), 1);
assert_eq!(mirror_network[0], mirror_network_str);
assert_ne!(client.network(), HashMap::new());

Ok(())
}
1 change: 1 addition & 0 deletions tests/e2e/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod account;
mod client;
mod common;
mod contract;
mod ethereum_transaction;
Expand Down

0 comments on commit ab816ca

Please sign in to comment.