circles-pathfinder 0.3.0

Pathfinding and flow matrix calculation for the Circles protocol
Documentation

Circles-Pathfinder

Pathfinding and flow matrix calculation for the Circles protocol.

Features

  • Path Discovery: Find optimal paths between addresses in the Circles network
  • Flow Matrix Calculation: Generate flow matrices for smart contract interactions
  • Contract Integration: Ready-to-use types for smart contract calls
  • High Performance: Efficient coordinate packing and vertex transformation
  • Type Safety: Compile-time guarantees with alloy primitives

Quick Start

Basic Usage

use circles_pathfinder::{FindPathParams, prepare_flow_for_contract};
use alloy_primitives::{Address, aliases::U192};

let params = FindPathParams {
    from: "0x123...".parse()?,
    to: "0x456...".parse()?,
    target_flow: U192::from(1_000_000_000_000_000_000u64), // 1 CRC
    use_wrapped_balances: Some(true),
    // ... other fields
};

// One function call does everything!
let path_data = prepare_flow_for_contract("https://rpc.circles.com", params).await?;

// Convert to contract types and call
let (vertices, edges, streams, coords) = path_data.to_contract_params();
contract.some_function(vertices, edges, streams, coords).send().await?;

// Or use individual conversion methods:
contract.redeemPayment(
    module_address,
    subscription_id,
    path_data.flow_vertices,           // Vec<Address> - ready to use
    path_data.to_flow_edges(),         // Vec<FlowEdge> - converted
    path_data.to_streams(),            // Vec<Stream> - converted  
    path_data.to_packed_coordinates(), // Bytes - converted
).send().await?;

Advanced Usage

// For composable workflows
let transfers = circles_pathfinder::find_path(rpc_url, from, to, amount, true).await?;
let path_data = circles_pathfinder::PathData::from_transfers(&transfers, from, to, amount)?;

// Or use the lower-level API
let matrix = circles_pathfinder::create_flow_matrix(from, to, amount, &transfers)?;
// matrix contains the raw FlowMatrix from circles_types

Circles Hub Contract Integration

This crate provides seamless integration with Circles Hub smart contracts. The generated types match the exact ABI expected by the contracts:

use circles_pathfinder::{FlowEdge, Stream, PathData};

// Types generated by sol! macro - match contract ABI exactly
let edges: Vec<FlowEdge> = path_data.to_flow_edges();
let streams: Vec<Stream> = path_data.to_streams();

// FlowEdge and Stream have camelCase fields matching Solidity:
// FlowEdge { streamSinkId: u16, amount: U192 }
// Stream { sourceCoordinate: u16, flowEdgeIds: Vec<u16>, data: Bytes }

Contract ABI Compatibility

struct FlowEdge {
    uint16 streamSinkId;
    uint192 amount;
}

struct Stream {
    uint16 sourceCoordinate;
    uint16[] flowEdgeIds;
    bytes data;
}

function redeemPayment(
    address[] memory flowVertices,
    FlowEdge[] memory flowEdges,
    Stream[] memory streams,
    bytes memory packedCoordinates
) external;

No Manual Conversions Required

The old approach required manual field-by-field conversion:

// OLD WAY
let flow_edges: Vec<FlowEdge> = contract_matrix.flow_edges
    .into_iter()
    .map(|edge| FlowEdge {
        streamSinkId: edge.stream_sink_id,  // manual snake_case -> camelCase
        amount: edge.amount,
    })
    .collect();

// NEW WAY
let flow_edges: Vec<FlowEdge> = path_data.to_flow_edges();