vios_app 0.1.1

Small JSON vaults: Argon2id + AES-GCM, with optional AAD binding.
Documentation
use anyhow::Result;
use clap::Parser;
use sha2::{Digest, Sha256};
use base64::{engine::general_purpose, Engine as _};
use vios_core::vault::types::VaultV2;

#[derive(Parser, Debug)]
struct Args {
    #[arg(long)] file: String,
    #[arg(long)] out_b64: Option<String>,
}

fn main() -> Result<()> {
    let a = Args::parse();
    let v: VaultV2 = serde_json::from_slice(&std::fs::read(&a.file)?)?;

    let memo_json = serde_json::json!({
        "v":"2.0",
        "h": v.cia.content_hash_hex,
        "d": v.cia.device_entropy_hex[..16].to_string(),
        "roy": v.license.as_ref().map(|l| l.royalty_bps).unwrap_or(0),
        "ttl": v.license.as_ref().map(|l| l.ttl_days).unwrap_or(0),
        "m": v.license.as_ref().map(|l| l.memo_hint.clone()).unwrap_or_default(),
    });
    let memo_str = memo_json.to_string();
    let memo_b64 = general_purpose::STANDARD.encode(memo_str.as_bytes());

    let mut h = Sha256::new();
    h.update(memo_str.as_bytes());
    let memo_hash = hex::encode(h.finalize());

    println!("XRPL Memo (b64): {memo_b64}");
    println!("Memo SHA256: {memo_hash}");

    if let Some(p) = a.out_b64 {
        std::fs::write(p, memo_b64)?;
    }
    println!("Attach memo_b64 to Payment/NFTokenMint on XRPL.");
    Ok(())
}