Skip to content

Commit

Permalink
chore: refactor examples and types, and add new swap_router example (
Browse files Browse the repository at this point in the history
…#119)

Refactored various examples and structs for improved clarity and usability, including updates to `NFTPermitData` and related modules. Added a new `swap_router` example to demonstrate token swaps. Updated dependencies and unified dev dependencies, while incrementing package version to 3.0.0.
  • Loading branch information
shuhuiluo authored Dec 23, 2024
1 parent d334f67 commit 3ad643d
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 25 deletions.
9 changes: 6 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "uniswap-v3-sdk"
version = "2.9.1"
version = "3.0.0"
edition = "2021"
authors = ["Shuhui Luo <twitter.com/aureliano_law>"]
description = "Uniswap V3 SDK for Rust"
Expand Down Expand Up @@ -39,8 +39,7 @@ extensions = ["alloy", "anyhow", "base64", "regex", "serde_json", "uniswap-lens"
std = ["alloy?/std", "thiserror/std", "uniswap-sdk-core/std", "uniswap-lens?/std"]

[dev-dependencies]
alloy-signer = "0.8"
alloy-signer-local = "0.8"
alloy = { version = "0.8", features = ["provider-anvil-node", "signer-local"] }
criterion = "0.5.1"
dotenv = "0.15.0"
tokio = { version = "1.40", features = ["full"] }
Expand All @@ -65,3 +64,7 @@ harness = false
[[example]]
name = "from_pool_key_with_tick_data_provider"
required-features = ["extensions"]

[[example]]
name = "swap_router"
required-features = ["extensions"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ It is feature-complete with unit tests matching the TypeScript SDK.
Add the following to your `Cargo.toml` file:

```toml
uniswap-v3-sdk = { version = "2.9.0", features = ["extensions", "std"] }
uniswap-v3-sdk = { version = "3.0.0", features = ["extensions", "std"] }
```

### Usage
Expand Down
21 changes: 7 additions & 14 deletions examples/from_pool_key_with_tick_data_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use alloy::{
rpc::types::TransactionRequest,
transports::http::reqwest::Url,
};
use alloy_primitives::{address, ruint::aliases::U256, U160};
use alloy_primitives::{address, U256};
use alloy_sol_types::SolCall;
use uniswap_sdk_core::{prelude::*, token};
use uniswap_v3_sdk::prelude::*;
Expand Down Expand Up @@ -42,28 +42,21 @@ async fn main() {
// Get the output amount from the pool
let amount_in = CurrencyAmount::from_raw_amount(wbtc.clone(), 100000000).unwrap();
let (local_amount_out, _pool_after) = pool.get_output_amount(&amount_in, None).unwrap();
println!("Local amount out: {}", local_amount_out.quotient());
let local_amount_out = local_amount_out.quotient();
println!("Local amount out: {}", local_amount_out);

let route = Route::new(vec![pool.clone()], wbtc, weth);
let params = quote_call_parameters(
&route,
&amount_in,
TradeType::ExactInput,
Some(QuoteOptions {
sqrt_price_limit_x96: U160::ZERO,
use_quoter_v2: false,
}),
);
// Get the output amount from the quoter
let route = Route::new(vec![pool], wbtc, weth);
let params = quote_call_parameters(&route, &amount_in, TradeType::ExactInput, None);
let tx = TransactionRequest::default()
.to(*QUOTER_ADDRESSES.get(&1).unwrap())
.input(params.calldata.into());
// Get the output amount from the quoter
let res = provider.call(&tx).block(block_id).await.unwrap();
let amount_out = IQuoter::quoteExactInputSingleCall::abi_decode_returns(res.as_ref(), true)
.unwrap()
.amountOut;
println!("Quoter amount out: {}", amount_out);

// Compare local calculation with on-chain quoter to ensure accuracy
assert_eq!(U256::from_big_int(local_amount_out.quotient()), amount_out);
assert_eq!(U256::from_big_int(local_amount_out), amount_out);
}
108 changes: 108 additions & 0 deletions examples/swap_router.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//! Example demonstrating how to swap tokens with the swap router
//!
//! # Prerequisites
//! - Environment variable MAINNET_RPC_URL must be set
//! - Requires the "extensions" feature
//!
//! # Note
//! This example uses mainnet block 17000000 for consistent results
use alloy::{
eips::BlockId,
node_bindings::WEI_IN_ETHER,
providers::{Provider, ProviderBuilder},
rpc::types::TransactionRequest,
sol,
transports::http::reqwest::Url,
};
use alloy_primitives::address;
use alloy_sol_types::SolCall;
use uniswap_sdk_core::{prelude::*, token};
use uniswap_v3_sdk::prelude::*;

sol!(
#[sol(rpc)]
contract IERC20 {
function balanceOf(address target) returns (uint256);
}
);

#[tokio::main]
async fn main() {
dotenv::dotenv().ok();
let rpc_url: Url = std::env::var("MAINNET_RPC_URL").unwrap().parse().unwrap();
let provider = ProviderBuilder::new().on_http(rpc_url.clone());
let block_id = BlockId::from(17000000);
const WBTC: Address = address!("2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599");
let wbtc = token!(1, WBTC, 8, "WBTC");
let eth = Ether::on_chain(1);

// Create a pool with a tick map data provider
let pool = Pool::<EphemeralTickMapDataProvider>::from_pool_key_with_tick_data_provider(
1,
FACTORY_ADDRESS,
wbtc.address(),
eth.address(),
FeeAmount::LOW,
provider.clone(),
Some(block_id),
)
.await
.unwrap();
let amount_in =
CurrencyAmount::from_raw_amount(eth.clone(), WEI_IN_ETHER.to_big_int()).unwrap();

// Get the output amount from the quoter
let route = Route::new(vec![pool], eth, wbtc);
let params = quote_call_parameters(&route, &amount_in, TradeType::ExactInput, None);
let tx = TransactionRequest::default()
.to(*QUOTER_ADDRESSES.get(&1).unwrap())
.input(params.calldata.into());
let res = provider.call(&tx).block(block_id).await.unwrap();
let amount_out = IQuoter::quoteExactInputSingleCall::abi_decode_returns(res.as_ref(), true)
.unwrap()
.amountOut;
println!("Quoter amount out: {}", amount_out);

// Create an Anvil fork
let provider = ProviderBuilder::new()
.with_recommended_fillers()
.on_anvil_with_config(|anvil| {
anvil
.fork(rpc_url)
.fork_block_number(block_id.as_u64().unwrap())
});
let account = provider.get_accounts().await.unwrap()[0];

// Build the swap transaction
let trade = Trade::from_route(route, amount_in, TradeType::ExactInput).unwrap();
let params = swap_call_parameters(
&mut [trade],
SwapOptions {
recipient: account,
..Default::default()
},
)
.unwrap();
let tx = TransactionRequest::default()
.from(account)
.to(*SWAP_ROUTER_02_ADDRESSES.get(&1).unwrap())
.input(params.calldata.into())
.value(params.value);

// Execute the swap
provider
.send_transaction(tx)
.await
.unwrap()
.register()
.await
.unwrap()
.await
.unwrap();

let iwbtc = IERC20::new(WBTC, provider);
let balance = iwbtc.balanceOf(account).call().await.unwrap()._0;
println!("WBTC balance: {}", balance);
assert_eq!(balance, amount_out);
}
11 changes: 6 additions & 5 deletions src/nonfungible_position_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ pub struct CollectOptions<Currency0: BaseCurrency, Currency1: BaseCurrency> {
pub recipient: Address,
}

pub type NFTPermitValues = IERC721Permit::Permit;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct NFTPermitData {
pub domain: Eip712Domain,
pub values: IERC721Permit::Permit,
pub values: NFTPermitValues,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
Expand Down Expand Up @@ -435,13 +437,12 @@ pub fn safe_transfer_from_parameters(options: SafeTransferOptions) -> MethodPara
/// ## Examples
///
/// ```
/// use alloy::signers::{local::PrivateKeySigner, SignerSync};
/// use alloy_primitives::{address, b256, uint, PrimitiveSignature, B256};
/// use alloy_signer::SignerSync;
/// use alloy_signer_local::PrivateKeySigner;
/// use alloy_sol_types::SolStruct;
/// use uniswap_v3_sdk::prelude::*;
///
/// let permit = IERC721Permit::Permit {
/// let permit = NFTPermitValues {
/// spender: address!("0000000000000000000000000000000000000002"),
/// tokenId: uint!(1_U256),
/// nonce: uint!(1_U256),
Expand All @@ -467,7 +468,7 @@ pub fn safe_transfer_from_parameters(options: SafeTransferOptions) -> MethodPara
#[inline]
#[must_use]
pub const fn get_permit_data(
permit: IERC721Permit::Permit,
permit: NFTPermitValues,
position_manager: Address,
chain_id: u64,
) -> NFTPermitData {
Expand Down
3 changes: 1 addition & 2 deletions src/self_permit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@ pub struct ERC20PermitData<P: SolStruct> {
/// ## Examples
///
/// ```
/// use alloy::signers::{local::PrivateKeySigner, SignerSync};
/// use alloy_primitives::{address, b256, uint, PrimitiveSignature, B256};
/// use alloy_signer::SignerSync;
/// use alloy_signer_local::PrivateKeySigner;
/// use alloy_sol_types::SolStruct;
/// use uniswap_v3_sdk::prelude::*;
///
Expand Down

0 comments on commit 3ad643d

Please sign in to comment.