1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Platform interfaces for credential storage.
//!
//! These traits are the platform integration boundary. The host selects the storage
//! root and provides a [`DeviceKeystore`] and [`AtomicBlobStore`]; core storage code
//! is root-agnostic and consumes a provider-supplied [`StoragePaths`].
//!
//! # Expected platform components
//!
//! - **iOS (Swift):** [`DeviceKeystore`] backed by Keychain / Secure Enclave;
//! [`AtomicBlobStore`] over the app container filesystem (atomic replace).
//! - **Android (Kotlin):** [`DeviceKeystore`] backed by the Android Keystore;
//! [`AtomicBlobStore`] over app internal storage (atomic replace).
//! - **Node.js:** file-backed [`DeviceKeystore`] (development; production can use an
//! OS keystore); [`AtomicBlobStore`] over app internal storage.
//! - **Browser (WASM):** `WebCrypto`-backed [`DeviceKeystore`]; [`AtomicBlobStore`]
//! over an origin-private storage namespace.
use Arc;
use StorageResult;
use StoragePaths;
/// Device keystore interface used to seal and open account keys.
/// Atomic blob store for small binary files (e.g., `account_keys.bin`).
/// Provider responsible for platform-specific storage components and paths.
/// Listener notified when the credential vault contents change and a new
/// backup is needed.
///
/// Register via [`super::CredentialStore::set_vault_changed_listener`]. The
/// callback is delivered on a dedicated background thread to avoid re-entering
/// the `UniFFI` call stack (see `logger.rs` for rationale).
///
/// This is only called when individual credentials are added or removed.
///
/// # Expected usage
///
/// The host app should treat this as a trigger to schedule a backup of the
/// vault. It should contain synchronous actions only.
///
/// # Safety
///
/// **Warning:** implementors **must not** call back into
/// [`super::CredentialStore`] from
/// [`on_vault_changed`](VaultChangedListener::on_vault_changed) — doing so
/// will deadlock.