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