5 releases (breaking)
Uses new Rust 2024
| new 0.5.0 | Dec 5, 2025 |
|---|---|
| 0.4.0 | Jul 21, 2025 |
| 0.3.0 | Jun 10, 2025 |
| 0.2.1 | Jun 10, 2025 |
| 0.1.0 | Jun 9, 2025 |
#14 in #defi
Used in 2 crates
(via circles-transfers)
170KB
3K
SLoC
circles-pathfinder
Pathfinding and flow matrix calculation for the Circles protocol. Uses circles-rpc to call circlesV2_findPath and produces contract-ready types for Hub interactions.
Features
- Path discovery through the trust network with optional wrapped-balance usage and simulated balances.
- Flow matrix creation and packing for on-chain
operateFlowMatrix/redeemPayment. - Wrapped token handling helpers: normalize wrappers, unwrap inflationary balances, and rewrite paths to underlying avatars.
- Netted-flow checks: shrink path values, compute/validate netted flow, and cap
U256inputs toU192for contract compatibility. - Contract-ready conversions via
sol!types (FlowEdge/Stream) and coordinate packing helpers.
Quickstart
use circles_pathfinder::{prepare_flow_for_contract, FindPathParams};
use alloy_primitives::{Address, U256};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let params = FindPathParams {
from: "0x1234567890123456789012345678901234567890".parse()?,
to: "0x0987654321098765432109876543210987654321".parse()?,
target_flow: U256::from(1_000_000_000_000_000_000u64), // 1 CRC (U256 input)
use_wrapped_balances: Some(true),
from_tokens: None,
to_tokens: None,
exclude_from_tokens: None,
exclude_to_tokens: None,
simulated_balances: None,
max_transfers: None,
};
// One call does everything: RPC pathfind + flow matrix ready for contracts
let path_data = prepare_flow_for_contract("https://rpc.aboutcircles.com/", params).await?;
let (vertices, edges, streams, coords) = path_data.into_contract_params();
println!("matrix: {} vertices, {} edges", vertices.len(), edges.len());
}
Wrapped tokens & netted flow
- Replace wrapped token owners with the underlying avatar for contract-facing flows:
use circles_pathfinder::{
token_info_map_from_path, wrapped_totals_from_path, expected_unwrapped_totals,
replace_wrapped_tokens, compute_netted_flow, assert_no_netted_flow_mismatch,
};
let info_map = token_info_map_from_path(current_avatar, &rpc, &path).await?;
let wrapped = wrapped_totals_from_path(&path, &info_map);
let unwrapped = expected_unwrapped_totals(&wrapped, &info_map); // uses converter + timestamp hint
let rewritten = replace_wrapped_tokens(&path, &unwrapped);
compute_netted_flow(&rewritten);
assert_no_netted_flow_mismatch(&rewritten, None, None)?;
- Helpers normalize wrapper variants, unwrap inflationary balances with
circles-utils, and ensure flow matrix amounts fit inU192(u256_to_u192).
Examples
contract_integration: end-to-end pathfinding and flow matrix creation for contract calls.find_path: basic pathfind against a Circles RPC endpoint.path_and_events: pathfind plus optional WS event subscription (CIRCLES_RPC_URL,CIRCLES_RPC_WS_URL). WS parsing tolerates heartbeats/batches; unknown events becomeCrcUnknownEvent.
Notes / status
- Targets Circles v2 RPCs; wrapper conversion logic matches the TypeScript
@pathfinderreference. - Use
circles-utilsdemurrage/inflation converters when inspecting wrapped balances directly. - Subscription reconnect/backoff is not handled here; use the SDK crate if you need retries or catch-up helpers.
Dependencies
~42–59MB
~1M SLoC