Progressive Privacy
Applications are rarely "all private" or "all public." Real applications evolve. A user might start with a public profile and standard transactions, then upgrade to a "Pro" tier that offers shielded payments.
Veil is designed for this Progressive Privacy model.
Changing Adapters at Runtime
Veil is not a static singleton. It is an instance that can be reconfigured or recreated as application state changes.
Scenario: The Privacy Toggle
Imagine a "Private Mode" toggle in your settings.
Incorrect Approach:
Writing if (isPrivate) statements inside every button click handler to call different functions.
Veil Approach: Re-initializing the context when the user changes their preference.
// When the user toggles "Incognito Mode"
function onTogglePrivacy(enabled: boolean) {
updateVeilConfig({
// If enabled, prioritize privacy adapters.
// If disabled, fall back to Noop/Standard adapters.
mode: enabled ? 'privacy-first' : 'performance-first'
});
}Now, your payment buttons just call veil.send(). They don't know or care which mode is active.
State Boundaries and Pitfalls
When moving between adapters, you must handle Asset Fragmentation.
If a user receives 100 USDC via a Private Adapter, that money is often in a shielded pool account, not their public token account.
If you switch Veil to the NoopPrivacyAdapter (Public Mode), the user might see a balance of 0 USDC, because the public adapter looks at the SPL token account, while the funds are sitting in the private pool.
How to handle this:
- Unified Balance Hooks: Your UI should sum balances across all known adapters, or clearly distinct "Public Balance" vs "Shielded Balance."
- Sweeping: When a user disables privacy, you might prompt them to "Unshield" funds—using Veil to send from the private adapter to their own public address.
The Lifecycle
- Public Default: App starts cheap and fast (Noop).
- User Upgrade: User needs privacy. Adapter is swapped.
- Interaction: User transacts. Funds move to shielded pools.
- Degradation: If the privacy service goes down, Veil can be configured to throw an error or warn the user, preventing them from accidentally sending a public transaction when they expected privacy.
This explicit control over the "failure mode" is critical for maintaining user trust.