Skip to main content

x402_cli/x402/
mod.rs

1pub mod deploy;
2pub mod facilitator;
3pub mod project;
4pub mod test;
5pub mod wallet;
6
7use anyhow::Result;
8use clap::Parser;
9use colored::Colorize;
10
11pub use facilitator::Facilitator;
12pub use project::Project;
13pub use wallet::Wallet;
14
15#[derive(Parser)]
16pub enum WalletCommands {
17    #[command(name = "create")]
18    Create {
19        #[arg(short, long, default_value = "testnet")]
20        network: String,
21    },
22    #[command(name = "import")]
23    Import {
24        #[arg(short, long)]
25        private_key: String,
26        #[arg(short, long, default_value = "testnet")]
27        network: String,
28    },
29}
30
31#[derive(Parser)]
32pub enum FacilitatorCommands {
33    #[command(name = "start")]
34    Start {
35        #[arg(short, long, default_value = "3001")]
36        port: u16,
37    },
38    #[command(name = "stop")]
39    Stop,
40}
41
42#[derive(Parser)]
43pub enum TestCommands {
44    #[command(name = "payment")]
45    Payment {
46        #[arg(short, long)]
47        api: String,
48        #[arg(short, long, default_value = "1000")]
49        amount: u64,
50    },
51}
52
53pub async fn init(name: String, chain: String, framework: String) -> Result<()> {
54    println!(
55        "{}",
56        format!("Initializing x402 project: {}", name.cyan()).bold()
57    );
58
59    let project = Project::new(name.clone(), chain, framework);
60
61    println!("{}", "  Creating project structure...".dimmed());
62    project.create_directories()?;
63
64    println!("{}", "  Creating configuration files...".dimmed());
65    project.create_config_files()?;
66
67    println!("{}", "  Installing dependencies...".dimmed());
68    project.install_dependencies()?;
69
70    project.generate_readme()?;
71
72    println!(
73        "{}",
74        format!("✓ Project initialized: {}", name.green()).bold()
75    );
76
77    println!(
78        "{}",
79        format!("  Project location: {}/", name.cyan()).dimmed()
80    );
81
82    Ok(())
83}
84
85pub async fn handle_wallet(command: WalletCommands) -> Result<()> {
86    match command {
87        WalletCommands::Create { network } => {
88            println!("{}", "Creating wallet...".cyan());
89
90            let wallet = Wallet::create(&network).await?;
91
92            wallet.save_to_file()?;
93
94            wallet.fund_from_faucet().await?;
95
96            println!(
97                "{}",
98                format!("  Wallet Address: {}", wallet.address.cyan()).dimmed()
99            );
100
101            Ok(())
102        }
103        WalletCommands::Import { private_key, network } => {
104            println!("{}", "Importing wallet...".cyan());
105
106            let wallet = Wallet::import(&private_key, &network)?;
107
108            wallet.save_to_file()?;
109
110            println!(
111                "{}",
112                format!("  Wallet Address: {}", wallet.address.cyan()).dimmed()
113            );
114
115            Ok(())
116        }
117    }
118}
119
120pub async fn handle_facilitator(command: FacilitatorCommands) -> Result<()> {
121    match command {
122        FacilitatorCommands::Start { port } => {
123            let _facilitator = Facilitator::start(port)?;
124
125            println!("{}", "  Start facilitator in background...".dimmed());
126            println!(
127                "{}",
128                "  Run `x402 facilitator stop` to stop".yellow().dimmed()
129            );
130
131            Ok(())
132        }
133        FacilitatorCommands::Stop => {
134            Facilitator::stop()?;
135            println!("{}", "✓ Facilitator stopped".green().bold());
136            Ok(())
137        }
138    }
139}
140
141pub async fn handle_test(command: TestCommands) -> Result<()> {
142    match command {
143        TestCommands::Payment { api, amount } => {
144            println!("{}", "Testing payment flow...".cyan());
145            println!("{}", format!("  API URL: {}", api.cyan()).dimmed());
146            println!("{}", format!("  Amount: {}", amount));
147
148            test::test_payment_flow(&api, amount).await?;
149
150            Ok(())
151        }
152    }
153}
154
155pub async fn deploy(provider: String) -> Result<()> {
156    println!("{}", format!("Deploying to {}", provider.cyan()).bold());
157
158    deploy::deploy(&provider).await?;
159
160    Ok(())
161}