mesh-llm-payments 0.78.1

Durable inference settlement: ledger, pricing, budgets and payment gates over a pluggable wallet
Documentation
use super::*;
use crate::provisioning::WalletFactory;

struct Factory {
    opens: AtomicUsize,
    wallet: Arc<MockWallet>,
}

#[async_trait]
impl WalletFactory for Factory {
    fn is_provisioned(&self, directory: &std::path::Path) -> bool {
        directory.join("fake-provider-ready").exists()
    }

    async fn open(&self, directory: &std::path::Path) -> Result<Arc<dyn WalletProvider>> {
        self.opens.fetch_add(1, Ordering::SeqCst);
        std::fs::write(directory.join("fake-provider-ready"), b"ready")?;
        Ok(self.wallet.clone())
    }
}

#[tokio::test]
async fn factory_is_lazy_single_flight_and_survives_service_restart() -> Result<()> {
    let directory = tempfile::tempdir()?;
    let factory = Arc::new(Factory {
        opens: AtomicUsize::new(0),
        wallet: Arc::default(),
    });
    {
        let service = PaymentService::with_factory(directory.path(), factory.clone())?;
        assert!(!service.has_wallet());
        assert_eq!(factory.opens.load(Ordering::SeqCst), 0);
        let (first, second) = tokio::join!(service.wallet(), service.wallet());
        assert!(Arc::ptr_eq(first?, second?));
        assert!(service.has_wallet());
        assert_eq!(factory.opens.load(Ordering::SeqCst), 1);
    }
    let service = PaymentService::with_factory(directory.path(), factory.clone())?;
    assert!(service.has_wallet());
    assert_eq!(factory.opens.load(Ordering::SeqCst), 1);
    service.wallet().await?;
    assert_eq!(factory.opens.load(Ordering::SeqCst), 2);
    Ok(())
}