ipfrs_cli/commands/
network.rs1use anyhow::Result;
9
10use crate::output::{self, print_header, success};
11use crate::progress;
12
13pub async fn show_peers(format: &str) -> Result<()> {
19 use ipfrs::{Node, NodeConfig};
20
21 let mut node = Node::new(NodeConfig::default())?;
22 node.start().await?;
23
24 let peers = node.peers().await?;
25
26 match format {
27 "json" => {
28 println!("[");
29 for (i, peer) in peers.iter().enumerate() {
30 if i > 0 {
31 println!(",");
32 }
33 print!(" \"{}\"", peer);
34 }
35 println!();
36 println!("]");
37 }
38 _ => {
39 if peers.is_empty() {
40 println!("No connected peers");
41 } else {
42 println!("Connected peers ({}):", peers.len());
43 for peer in &peers {
44 println!(" {}", peer);
45 }
46 }
47 }
48 }
49
50 node.stop().await?;
51 Ok(())
52}
53
54pub async fn swarm_connect(addr: &str) -> Result<()> {
56 use ipfrs::{Node, NodeConfig};
57
58 let mut node = Node::new(NodeConfig::default())?;
59 node.start().await?;
60
61 println!("Connecting to {}...", addr);
62 node.connect(addr).await?;
63 println!("Connection initiated");
64
65 node.stop().await?;
66 Ok(())
67}
68
69pub async fn swarm_disconnect(peer_id: &str) -> Result<()> {
71 use ipfrs::{Node, NodeConfig};
72
73 let mut node = Node::new(NodeConfig::default())?;
74 node.start().await?;
75
76 println!("Disconnecting from {}...", peer_id);
77 node.disconnect(peer_id).await?;
78 println!("Disconnected");
79
80 node.stop().await?;
81 Ok(())
82}
83
84pub async fn swarm_addrs(format: &str) -> Result<()> {
86 use ipfrs::{Node, NodeConfig};
87
88 let mut node = Node::new(NodeConfig::default())?;
89 node.start().await?;
90
91 let stats = node.network_stats()?;
92
93 match format {
94 "json" => {
95 println!("[");
96 for (i, addr) in stats.listen_addrs.iter().enumerate() {
97 if i > 0 {
98 println!(",");
99 }
100 print!(" \"{}\"", addr);
101 }
102 println!();
103 println!("]");
104 }
105 _ => {
106 if stats.listen_addrs.is_empty() {
107 println!("No listening addresses");
108 } else {
109 println!("Listening addresses:");
110 for addr in &stats.listen_addrs {
111 println!(" {}", addr);
112 }
113 }
114 }
115 }
116
117 node.stop().await?;
118 Ok(())
119}
120
121pub async fn dht_findprovs(cid: &str, _format: &str) -> Result<()> {
127 use ipfrs::{Node, NodeConfig};
128
129 let cid_parsed: ipfrs_core::Cid = cid
130 .parse()
131 .map_err(|e| anyhow::anyhow!("Invalid CID: {}", e))?;
132
133 let mut node = Node::new(NodeConfig::default())?;
134 node.start().await?;
135
136 println!("Searching for providers of {}...", cid);
137 node.find_providers(&cid_parsed).await?;
138
139 println!("Provider query sent to DHT");
142 println!("(Provider discovery events would be received asynchronously)");
143
144 node.stop().await?;
145 Ok(())
146}
147
148pub async fn dht_provide(cid: &str) -> Result<()> {
150 use ipfrs::{Node, NodeConfig};
151
152 let cid_parsed: ipfrs_core::Cid = cid
153 .parse()
154 .map_err(|e| anyhow::anyhow!("Invalid CID: {}", e))?;
155
156 let mut node = Node::new(NodeConfig::default())?;
157 node.start().await?;
158
159 println!("Announcing {} to DHT...", cid);
160 node.provide(&cid_parsed).await?;
161 println!("Content announced to DHT");
162
163 node.stop().await?;
164 Ok(())
165}
166
167pub async fn dht_findpeer(peer_id: &str, format: &str) -> Result<()> {
169 use ipfrs::{Node, NodeConfig};
170
171 let pb = progress::spinner(&format!("Looking up peer {}", peer_id));
172 let mut node = Node::new(NodeConfig::default())?;
173 node.start().await?;
174
175 progress::finish_spinner_success(&pb, "Lookup complete");
178
179 match format {
180 "json" => {
181 println!("{{");
182 println!(" \"peer_id\": \"{}\",", peer_id);
183 println!(" \"addresses\": [],");
184 println!(" \"note\": \"DHT lookup placeholder - actual implementation pending\"");
185 println!("}}");
186 }
187 _ => {
188 print_header(&format!("Peer: {}", peer_id));
189 output::info("DHT peer lookup is a placeholder");
190 output::info("Full implementation requires peer routing protocol");
191 }
192 }
193
194 node.stop().await?;
195 Ok(())
196}
197
198pub async fn bootstrap_list(format: &str) -> Result<()> {
204 use ipfrs::{Node, NodeConfig};
205
206 let mut node = Node::new(NodeConfig::default())?;
207 node.start().await?;
208
209 let bootstrap_peers = node.bootstrap_peers()?;
210
211 match format {
212 "json" => {
213 println!("[");
214 for (i, addr) in bootstrap_peers.iter().enumerate() {
215 if i > 0 {
216 println!(",");
217 }
218 print!(" \"{}\"", addr);
219 }
220 println!();
221 println!("]");
222 }
223 _ => {
224 if bootstrap_peers.is_empty() {
225 println!("No bootstrap peers configured");
226 } else {
227 println!("Bootstrap peers ({}):", bootstrap_peers.len());
228 for addr in &bootstrap_peers {
229 println!(" {}", addr);
230 }
231 }
232 }
233 }
234
235 node.stop().await?;
236 Ok(())
237}
238
239pub async fn bootstrap_add(addr: &str) -> Result<()> {
241 use ipfrs::{Node, NodeConfig};
242
243 let pb = progress::spinner(&format!("Adding bootstrap peer {}", addr));
244 let mut node = Node::new(NodeConfig::default())?;
245 node.start().await?;
246
247 node.add_bootstrap_peer(addr).await?;
248 progress::finish_spinner_success(&pb, "Peer added");
249
250 success(&format!("Added bootstrap peer: {}", addr));
251
252 node.stop().await?;
253 Ok(())
254}
255
256pub async fn bootstrap_rm(addr: &str) -> Result<()> {
258 use ipfrs::{Node, NodeConfig};
259
260 let pb = progress::spinner(&format!("Removing bootstrap peer {}", addr));
261 let mut node = Node::new(NodeConfig::default())?;
262 node.start().await?;
263
264 node.remove_bootstrap_peer(addr).await?;
265 progress::finish_spinner_success(&pb, "Peer removed");
266
267 success(&format!("Removed bootstrap peer: {}", addr));
268
269 node.stop().await?;
270 Ok(())
271}