use canton_admin::{AdminClient, Config};
use canton_auth::{OidcConfig, TokenProvider};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut args = std::env::args().skip(1);
let out = args
.next()
.ok_or("usage: fetch_packages <out-dir> [name-filter…]")?;
let filters: Vec<String> = args.collect();
let endpoint = std::env::var("CANTON_TEST_ENDPOINT")
.ok()
.or_else(|| canton_core::localnet::grpc_endpoint(None))
.ok_or("set CANTON_TEST_ENDPOINT")?;
let config = Config::new(endpoint);
let config = match (
std::env::var("CANTON_TEST_TOKEN_URL"),
std::env::var("CANTON_TEST_CLIENT_ID"),
std::env::var("CANTON_TEST_CLIENT_SECRET"),
) {
(Ok(url), Ok(id), Ok(secret)) => {
config.with_oidc(TokenProvider::new(OidcConfig::new(url, id, secret)))
}
_ => match canton_core::localnet::token(None) {
Some(token) => config.with_token(token),
None => config,
},
};
let admin = AdminClient::connect_lazy(config)?;
std::fs::create_dir_all(&out)?;
let ids = admin.list_packages().await?;
println!("the participant knows {} packages", ids.len());
let mut written = 0usize;
let mut total = 0usize;
for id in ids {
let archive = admin.get_package(&id).await?;
let package = canton_lf::decode_payload(&archive)?;
let name = canton_lf::package_name(&package).unwrap_or("unnamed");
let version = canton_lf::package_version(&package).unwrap_or("0.0.0");
if !filters.is_empty() && !filters.iter().any(|f| name.contains(f.as_str())) {
continue;
}
let path = format!("{out}/{name}-{version}-{id}.lfpayload");
std::fs::write(&path, &archive)?;
println!(
"{name:<45} {version:<8} {:>7} bytes {}",
archive.len(),
&id[..16]
);
written += 1;
total += archive.len();
}
println!("wrote {written} package(s), {} KB in total", total / 1024);
Ok(())
}