Skip to main content

fynd_client/
lib.rs

1#![deny(missing_docs)]
2//! Rust client for the [Fynd](https://fynd.xyz) DEX router.
3//!
4//! `fynd-client` lets you request swap quotes, build signable transaction payloads, and
5//! broadcast signed orders through the Fynd RPC API — all from a single typed interface.
6//!
7//! For guides, API reference, and setup instructions see **<https://docs.fynd.xyz/>**.
8//!
9//! # Workflow
10//!
11//! A complete swap runs in three steps: **quote → approve → sign and execute**.
12//! See `examples/swap_erc20.rs` for a full walkthrough, or follow the
13//! [quickstart](https://docs.fynd.xyz/get-started/quickstart) to run a local Fynd instance.
14//!
15//! # Constructing a client
16//!
17//! Use [`FyndClientBuilder`] to configure and build a [`FyndClient`]:
18//!
19//! ```rust,no_run
20//! # use fynd_client::FyndClientBuilder;
21//! # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
22//! let client = FyndClientBuilder::new(
23//!     "http://localhost:3000",
24//!     "https://reth-ethereum.ithaca.xyz/rpc",
25//! )
26//! .build()
27//! .await?;
28//! # Ok(()) }
29//! ```
30//!
31//! For quote-only use (no on-chain transactions), skip the RPC connection with
32//! [`FyndClientBuilder::build_quote_only`]:
33//!
34//! ```rust,no_run
35//! # use fynd_client::FyndClientBuilder;
36//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
37//! let client = FyndClientBuilder::new("http://localhost:3000", "http://localhost:3000")
38//!     .build_quote_only()?;
39//! # Ok(()) }
40//! ```
41//!
42//! # Requesting a quote
43//!
44//! ```rust,no_run
45//! # use fynd_client::{FyndClientBuilder, Order, OrderSide, QuoteOptions, QuoteParams};
46//! # use alloy::primitives::address;
47//! # use bytes::Bytes;
48//! # use num_bigint::BigUint;
49//! # #[tokio::main] async fn main() -> Result<(), Box<dyn std::error::Error>> {
50//! # let client = FyndClientBuilder::new("http://localhost:3000", "http://localhost:3000")
51//! #     .build_quote_only()?;
52//! // WETH → USDC on mainnet (Vitalik's address as sender).
53//! let weth: Bytes = address!("C02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2").to_vec().into();
54//! let usdc: Bytes = address!("A0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48").to_vec().into();
55//! let sender: Bytes = address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").to_vec().into();
56//!
57//! let quote = client
58//!     .quote(QuoteParams::new(
59//!         Order::new(
60//!             weth,
61//!             usdc,
62//!             BigUint::from(1_000_000_000_000_000_000u64), // 1 WETH (18 decimals)
63//!             OrderSide::Sell,
64//!             sender,
65//!             None,
66//!         ),
67//!         QuoteOptions::default(),
68//!     ))
69//!     .await?;
70//!
71//! println!("amount out: {}", quote.amount_out());
72//! # Ok(()) }
73//! ```
74
75pub use client::{
76    ApprovalParams, ExecutionOptions, FyndClient, FyndClientBuilder, RetryConfig, SigningHints,
77    StorageOverrides,
78};
79pub use error::{ErrorCode, FyndError};
80pub use signing::{
81    ApprovalPayload, ExecutionReceipt, FyndPayload, MinedTx, SettledOrder, SignedApproval,
82    SignedSwap, SwapPayload, TxReceipt,
83};
84pub use types::{
85    BackendKind, BlockInfo, ClientFeeParams, EncodingOptions, FeeBreakdown, HealthStatus,
86    InstanceInfo, Order, OrderSide, PermitDetails, PermitSingle, Quote, QuoteOptions, QuoteParams,
87    QuoteStatus, Route, Swap, Transaction, UserTransferType,
88};
89
90mod client;
91mod error;
92mod mapping;
93mod signing;
94mod types;