use std::collections::HashMap;
use std::sync::Arc;
use agent_pay::{
did_key_from_public_key, fetch_with_l402, generate_key_pair, FetchFn, FetchOptions,
FetchResponse, InnerHandler, LightningNode, MemoryLedger, MemoryNode, Paywall, PaywallOptions,
PaywallResponse,
};
const SECRET: &[u8] = b"thirty-two-byte-test-secret-pad!";
#[tokio::main]
async fn main() {
let kp = generate_key_pair();
let did = did_key_from_public_key(&kp.public_key).unwrap();
let ledger = MemoryLedger::new();
let server: Arc<dyn LightningNode> = Arc::new(MemoryNode::new(ledger.clone(), "server"));
let client: Arc<dyn LightningNode> = Arc::new(MemoryNode::new(ledger.clone(), "client"));
let opts = PaywallOptions::new(
did.clone(),
kp.private_key,
1000,
"/report",
server,
SECRET.to_vec(),
);
let paywall = Arc::new(Paywall::new(opts));
let handler: InnerHandler = Arc::new(|_p, _h| {
Box::pin(async move {
Ok(PaywallResponse {
status: 200,
json: Some(serde_json::json!({ "insight": "agents charging agents works." })),
..Default::default()
})
})
});
let pay = paywall.clone();
let fetch: FetchFn = Arc::new(move |url: String, headers: HashMap<String, String>| {
let pay = pay.clone();
let handler = handler.clone();
Box::pin(async move {
let path = url
.split_once("://")
.and_then(|(_, rest)| rest.split_once('/'))
.map(|(_, p)| format!("/{p}"))
.unwrap_or_else(|| url.clone());
let resp = pay.process_request(&path, headers, Some(handler)).await?;
Ok(FetchResponse {
status: resp.status,
headers: resp.headers,
body: resp.body,
json: resp.json,
})
})
});
let mut fopts = FetchOptions::new(client, 5000, fetch);
fopts.expected_did = Some(did.clone());
println!("server DID: {did}");
let res = fetch_with_l402("http://x/report", fopts).await.unwrap();
let receipt = res.header("x-payment-receipt").unwrap_or("");
println!("status: {}", res.status);
println!(
"payload: {}",
res.json
.as_ref()
.map(|v| v.to_string())
.unwrap_or_default()
);
let head = &receipt[..receipt.len().min(64)];
let suffix = if receipt.len() > 64 { "..." } else { "" };
println!("receipt: {head}{suffix}");
}