Skip to main content

hashtree_cli/
cashu_helper.rs

1pub use cashu_service::{
2    base_helper_args, helper_binary_name, helper_binary_path, run_helper_status, CashuHelperClient,
3    CashuMintBalance, CashuPaymentClient, CashuReceivedPayment, CashuSentPayment, CARGO_HELPER_ENV,
4    CASHU_HELPER_ENV,
5};
6
7#[cfg(test)]
8mod tests {
9    use super::*;
10    use crate::test_support::test_env_lock;
11    use serde_json::json;
12    use std::env;
13    #[cfg(unix)]
14    use std::os::unix::fs::PermissionsExt;
15    use std::path::Path;
16
17    #[test]
18    fn test_helper_binary_path_prefers_env_override() {
19        let _guard = test_env_lock().blocking_lock();
20        let temp_dir = tempfile::tempdir().unwrap();
21        let override_path = temp_dir.path().join("custom-helper");
22        std::fs::write(&override_path, b"").unwrap();
23
24        env::set_var(CASHU_HELPER_ENV, &override_path);
25        env::remove_var(CARGO_HELPER_ENV);
26
27        let resolved = helper_binary_path(Path::new("/tmp/htree")).unwrap();
28        assert_eq!(resolved, override_path);
29
30        env::remove_var(CASHU_HELPER_ENV);
31    }
32
33    #[test]
34    fn test_helper_binary_path_falls_back_to_sibling_binary() {
35        let _guard = test_env_lock().blocking_lock();
36        env::remove_var(CASHU_HELPER_ENV);
37        env::remove_var(CARGO_HELPER_ENV);
38
39        let temp_dir = tempfile::tempdir().unwrap();
40        let current_exe = temp_dir.path().join("htree");
41        std::fs::write(&current_exe, b"").unwrap();
42        let sibling = temp_dir.path().join(helper_binary_name());
43        std::fs::write(&sibling, b"").unwrap();
44
45        let resolved = helper_binary_path(&current_exe).unwrap();
46        assert_eq!(resolved, sibling);
47    }
48
49    #[cfg(unix)]
50    #[tokio::test]
51    async fn test_cashu_helper_client_send_and_receive_json() {
52        let _guard = test_env_lock().lock().await;
53        env::remove_var(CARGO_HELPER_ENV);
54
55        let temp_dir = tempfile::tempdir().unwrap();
56        let helper_path = temp_dir.path().join("htree-cashu-stub");
57        let script = format!(
58            "#!/bin/sh\nif [ \"$3\" = \"internal\" ] && [ \"$4\" = \"send\" ]; then\n  printf '%s' '{}'\nelif [ \"$3\" = \"internal\" ] && [ \"$4\" = \"receive\" ]; then\n  cat >/dev/null\n  printf '%s' '{}'\nelse\n  printf '%s' '{}'\nfi\n",
59            json!({
60                "mint_url": "https://mint.example",
61                "unit": "sat",
62                "amount_sat": 3,
63                "send_fee_sat": 1,
64                "operation_id": "op-123",
65                "token": "cashuBtoken"
66            }),
67            json!({
68                "mint_url": "https://mint.example",
69                "unit": "sat",
70                "amount_sat": 3
71            }),
72            json!({"ok": true}),
73        );
74        std::fs::write(&helper_path, script).unwrap();
75        let mut perms = std::fs::metadata(&helper_path).unwrap().permissions();
76        perms.set_mode(0o755);
77        std::fs::set_permissions(&helper_path, perms).unwrap();
78
79        env::set_var(CASHU_HELPER_ENV, &helper_path);
80        let client = CashuHelperClient::discover(temp_dir.path()).unwrap();
81
82        let sent = client
83            .send_payment("https://mint.example", 3)
84            .await
85            .unwrap();
86        assert_eq!(sent.amount_sat, 3);
87        assert_eq!(sent.send_fee_sat, 1);
88        assert_eq!(sent.operation_id, "op-123");
89
90        let received = client.receive_payment("cashuBtoken").await.unwrap();
91        assert_eq!(received.amount_sat, 3);
92        assert_eq!(received.mint_url, "https://mint.example");
93
94        client
95            .revoke_payment("https://mint.example", "op-123")
96            .await
97            .unwrap();
98
99        env::remove_var(CASHU_HELPER_ENV);
100    }
101
102    #[cfg(unix)]
103    #[tokio::test]
104    async fn test_cashu_helper_client_queries_mint_balance_json() {
105        let _guard = test_env_lock().lock().await;
106        env::remove_var(CARGO_HELPER_ENV);
107
108        let temp_dir = tempfile::tempdir().unwrap();
109        let helper_path = temp_dir.path().join("htree-cashu-stub");
110        let script = format!(
111            "#!/bin/sh\nif [ \"$3\" = \"internal\" ] && [ \"$4\" = \"balance\" ]; then\n  printf '%s' '{}'\nelse\n  printf '%s' '{}'\nfi\n",
112            json!({
113                "mint_url": "https://mint.example",
114                "unit": "sat",
115                "balance_sat": 21
116            }),
117            json!({"ok": true}),
118        );
119        std::fs::write(&helper_path, script).unwrap();
120        let mut perms = std::fs::metadata(&helper_path).unwrap().permissions();
121        perms.set_mode(0o755);
122        std::fs::set_permissions(&helper_path, perms).unwrap();
123
124        env::set_var(CASHU_HELPER_ENV, &helper_path);
125        let client = CashuHelperClient::discover(temp_dir.path()).unwrap();
126        let balance = client.mint_balance("https://mint.example").await.unwrap();
127        assert_eq!(balance.mint_url, "https://mint.example");
128        assert_eq!(balance.unit, "sat");
129        assert_eq!(balance.balance_sat, 21);
130
131        env::remove_var(CASHU_HELPER_ENV);
132    }
133}