use std::env;
use std::process::ExitCode;
use bee::swarm::{BatchId, PrivateKey, Topic};
use bee::{Client, Error};
#[tokio::main]
async fn main() -> ExitCode {
match run().await {
Ok(()) => ExitCode::SUCCESS,
Err(e) => {
eprintln!("error: {e}");
ExitCode::FAILURE
}
}
}
async fn run() -> Result<(), Error> {
let url = env::var("BEE_URL").unwrap_or_else(|_| "http://localhost:1633".into());
let mut args = env::args().skip(1);
let topic_str = args
.next()
.ok_or_else(|| Error::argument("usage: feed-update <topic-string> <message>"))?;
let message = args
.next()
.ok_or_else(|| Error::argument("missing <message>"))?;
let batch_hex = env::var("BEE_BATCH_ID")
.map_err(|_| Error::argument("BEE_BATCH_ID is required (set to a usable batch hex id)"))?;
let batch_id = BatchId::from_hex(&batch_hex)?;
let signer_hex = env::var("BEE_SIGNER_HEX").map_err(|_| {
Error::argument(
"BEE_SIGNER_HEX is required (32-byte hex). Generate one with `openssl rand -hex 32`.",
)
})?;
let signer = PrivateKey::from_hex(&signer_hex)?;
let owner = signer.public_key()?.address();
let topic = Topic::from_string(&topic_str);
println!("Feed parameters:");
println!("- Owner: {}", owner.to_hex());
println!("- Topic: {} (from \"{topic_str}\")", topic.to_hex());
println!("- Batch: {}\n", batch_id.to_hex());
let client = Client::new(&url)?;
println!("Publishing feed update with payload {:?}...", message);
let result = client
.file()
.update_feed(&batch_id, &signer, &topic, message.as_bytes())
.await?;
println!(" chunk reference: {}", result.reference.to_hex());
println!("\nFetching latest feed update...");
let update = client
.file()
.fetch_latest_feed_update(&owner, &topic)
.await?;
let payload = &update.payload;
if payload.len() < 8 {
return Err(Error::argument(format!(
"unexpected feed payload length: {}",
payload.len()
)));
}
let mut ts_bytes = [0u8; 8];
ts_bytes.copy_from_slice(&payload[..8]);
let timestamp = u64::from_be_bytes(ts_bytes);
let data = &payload[8..];
println!(" index: {}", update.index);
println!(" index_next: {}", update.index_next);
println!(" timestamp: {timestamp} (unix seconds)");
match std::str::from_utf8(data) {
Ok(s) => println!(" payload: {s:?}"),
Err(_) => println!(" payload: {} bytes (non-utf8)", data.len()),
}
Ok(())
}