use clap::Parser;
use fuels::{
accounts::{
provider::Provider,
signers::private_key::PrivateKeySigner,
wallet::Wallet,
},
crypto::SecretKey,
};
use o2_deploy::{
DeployParams,
MarketsConfigPartial,
load_config_from_file,
};
use std::str::FromStr;
#[derive(Parser)]
#[command(name = "o2-deploy", about = "Deploy O2 exchange contracts")]
struct Cli {
#[arg(long, env = "DEPLOY_KEY")]
deploy_key: String,
#[arg(
long = "fuel-rpc",
env = "FUEL_RPC",
default_value = "http://127.0.0.1:4000"
)]
fuel_rpc: url::Url,
#[arg(long, env = "DEPLOY_CONFIG", default_value = "./deploy_config.json")]
deploy_config: String,
#[arg(long, env = "OUTPUT_FILE")]
output: Option<String>,
#[arg(long, env = "DEPLOY_WHITELIST", default_value = "false")]
deploy_whitelist: bool,
#[arg(long, env = "DEPLOY_BLACKLIST", default_value = "true")]
deploy_blacklist: bool,
#[arg(long, env, default_value = "false")]
upgrade_bytecode: bool,
#[arg(long, env = "DEPLOY_NEW_PROXY_OWNER")]
new_proxy_owner: Option<String>,
#[arg(long, env = "DEPLOY_NEW_CONTRACT_OWNER")]
new_contract_owner: Option<String>,
}
fn parse_address(s: &str) -> anyhow::Result<fuels::types::Address> {
let trimmed = s.strip_prefix("0x").unwrap_or(s);
let bytes = hex::decode(trimmed)?;
Ok(fuels::types::Address::new(
bytes
.try_into()
.map_err(|_| anyhow::anyhow!("Invalid address length"))?,
))
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.init();
let cli = Cli::parse();
let secret_key = SecretKey::from_str(&cli.deploy_key)
.map_err(|e| anyhow::anyhow!("Failed to parse deploy key: {e}"))?;
let provider = Provider::connect(cli.fuel_rpc.as_str()).await?;
let wallet = Wallet::new(PrivateKeySigner::new(secret_key), provider);
let deploy_config: MarketsConfigPartial = load_config_from_file(&cli.deploy_config)?;
let new_proxy_owner = cli
.new_proxy_owner
.as_deref()
.map(parse_address)
.transpose()?;
let new_contract_owner = cli
.new_contract_owner
.as_deref()
.map(parse_address)
.transpose()?;
let params = DeployParams {
deploy_config,
output: cli.output,
deploy_whitelist: cli.deploy_whitelist,
deploy_blacklist: cli.deploy_blacklist,
upgrade_bytecode: cli.upgrade_bytecode,
new_proxy_owner,
new_contract_owner,
};
let result = o2_deploy::deploy(wallet, params).await?;
println!("{}", serde_json::to_string_pretty(&result)?);
Ok(())
}