Skip to content

Connecting

Build a TridentClientBuilder, register providers and signers for the chains you need, and connect.

use alloy_provider::{DynProvider, ProviderBuilder};
use alloy_provider::network::{AnyNetwork, EthereumWallet};
use alloy_signer_local::PrivateKeySigner;
use tonic::transport::Endpoint;
use trident_sdk::TridentClientBuilder;
let signer = PrivateKeySigner::from_bytes(&your_private_key)?;
// Build a provider for each chain you want to interact with
let avalanche_provider: DynProvider<AnyNetwork> = ProviderBuilder::default()
.with_recommended_fillers()
.wallet(EthereumWallet::new(signer.clone()))
.connect_http("https://api.avax.network/ext/bc/C/rpc".parse()?)
.erased();
let mut client = TridentClientBuilder::new(
Endpoint::from_static("http://your-attester-endpoint:9000")
)
.with_evm_chain(1, avalanche_provider, signer.clone()) // domain 1 = Avalanche
.with_evm_chain(2, optimism_provider, signer.clone()) // domain 2 = Optimism
.connect()
.await?;

Use PrivateKeySigner from Alloy to load your private key. This signer is used for both transaction signing and provider authentication.

For each chain, create a DynProvider<AnyNetwork> with the chain’s RPC endpoint and your signer. The with_recommended_fillers() call adds gas estimation and nonce management.

Call .with_evm_chain(domain, provider, signer) for each chain you plan to use. The domain ID follows Circle CCTP conventions (e.g., 1 = Avalanche, 2 = Optimism).

On connect(), the builder fetches all deployment metadata (contract addresses per domain) from the querier automatically. You only need to register providers and signers for the chains you plan to use.