use {
alloy_primitives::{Address, U256, address},
alloy_signer_local::PrivateKeySigner,
cowprotocol::{
Chain, DomainSeparator, EMPTY_APP_DATA_HASH, EMPTY_APP_DATA_JSON, EcdsaSigningScheme,
GPV2_SETTLEMENT, OrderBookApi, OrderCreation, QuoteRequest,
},
std::str::FromStr,
};
const WETH_SEPOLIA: Address = address!("fFf9976782d46CC05630D1f6eBAb18b2324d6B14");
const COW_SEPOLIA: Address = address!("0625aFB445C3B6B7B929342a04A22599fd5dBB59");
const SELL_AMOUNT_WEI: u128 = 10_000_000_000_000_000;
#[tokio::main]
async fn main() -> cowprotocol::Result<()> {
let Ok(raw_key) = std::env::var("SEPOLIA_PRIVATE_KEY") else {
println!("set SEPOLIA_PRIVATE_KEY=... to run live (skipping)");
return Ok(());
};
let signer = PrivateKeySigner::from_str(raw_key.trim())
.expect("SEPOLIA_PRIVATE_KEY must be a 0x-prefixed 32-byte hex string");
let owner = signer.address();
println!("signer: {owner:?}");
let api = OrderBookApi::new(Chain::Sepolia);
let request = QuoteRequest::sell_amount_before_fee(
WETH_SEPOLIA,
COW_SEPOLIA,
owner,
U256::from(SELL_AMOUNT_WEI),
);
let quote = api.get_quote(&request).await?;
println!("quote id: {}", quote.id);
println!("buy amount: {}", quote.quote.buy_amount);
println!("fee amount: {}", quote.quote.fee_amount);
println!("valid to: {}", quote.quote.valid_to);
let order_data = quote.to_signed_order_data(EMPTY_APP_DATA_HASH)?;
let domain = DomainSeparator::new(Chain::Sepolia.id(), GPV2_SETTLEMENT);
let signature = order_data.sign(EcdsaSigningScheme::Eip712, &domain, &signer)?;
let creation = OrderCreation::from_signed_order_data(
order_data,
signature,
owner,
EMPTY_APP_DATA_JSON.to_owned(),
Some(quote.id),
)?;
let uid = api.post_order(&creation).await?;
println!("order uid: {uid}");
println!("explorer: https://explorer.cow.fi/sepolia/orders/{uid}");
Ok(())
}