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}