Documentation Index
Fetch the complete documentation index at: https://docs.privacyboost.io/llms.txt
Use this file to discover all available pages before exploring further.
Deposits
This guide covers depositing tokens into the privacy pool using the Privacy Boost React SDK.
Basic Deposit
import { useVault } from '@sunnyside-io/privacy-boost-react';
function ShieldButton() {
const { shield } = useVault();
const handleShield = async () => {
const result = await shield({
tokenAddress: '0x...token-address',
amount: '1.0',
});
console.log('Deposit tx:', result.txHash);
};
return <button onClick={handleShield}>Deposit</button>;
}
Deposit Parameters
| Parameter | Type | Required | Description |
|---|
tokenAddress | Hex | Yes | Token contract address |
amount | string | bigint | Yes | Either a human-readable decimal string (e.g. "1.5", parsed using the token’s decimals) or a bigint in wei (e.g. 1500000000000000000n). |
onProgress | OnProgress | No | Progress callback (see Progress Tracking). |
This differs from the TypeScript SDK, which only accepts bigint (wei), and from the mobile SDKs, which accept a wei-as-string. The React useVault hook normalizes for you: a human-readable string is parsed with the token’s decimals before being passed to the underlying SDK.
Progress Tracking
Track shield steps with the onProgress callback:
function DepositWithProgress() {
const { shield } = useVault();
const [step, setStep] = useState<string | null>(null);
const handleShield = async () => {
await shield({
tokenAddress: '0x...token-address',
amount: '1.0',
onProgress: ({ step, message }) => {
setStep(message);
},
});
setStep(null);
};
return (
<div>
<button onClick={handleShield}>Deposit</button>
{step && <p>{step}</p>}
</div>
);
}
Deposit Steps
The step value comes from the ShieldStep enum and matches the same values across all SDK platforms.
| Step | Description |
|---|
wrapping | Wrapping native ETH to WETH (only when shielding ETH) |
approving | Approving the shield contract to spend the token |
shielding | Submitting the shield transaction on-chain |
registering | Registering the new note with the indexer |
compliance | Awaiting the compliance check on the deposit |
Depositing ETH
Native ETH is automatically wrapped to WETH during shield:
const ETH_ADDRESS = '0x0000000000000000000000000000000000000000';
const result = await shield({
tokenAddress: ETH_ADDRESS,
amount: '0.1',
});
Complete Example
import { useState } from 'react';
import { useVault } from '@sunnyside-io/privacy-boost-react';
function ShieldForm({ tokenAddress }: { tokenAddress: string }) {
const { shield, refreshBalances } = useVault();
const [amount, setAmount] = useState('');
const [loading, setLoading] = useState(false);
const [step, setStep] = useState<string | null>(null);
const [error, setError] = useState<string | null>(null);
const handleShield = async () => {
setLoading(true);
setError(null);
try {
await shield({
tokenAddress,
amount,
onProgress: ({ message }) => setStep(message),
});
setAmount('');
await refreshBalances();
} catch (err: any) {
if (err.code !== 'TRANSACTION_REJECTED') {
setError(err.message);
}
} finally {
setLoading(false);
setStep(null);
}
};
return (
<div>
<input
type="text"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Amount"
disabled={loading}
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
{step && <p>{step}</p>}
<button onClick={handleShield} disabled={loading || !amount}>
{loading ? 'Depositing...' : 'Deposit'}
</button>
</div>
);
}
Error Handling
try {
await shield({ tokenAddress, amount });
} catch (error: any) {
switch (error.code) {
case 'TRANSACTION_REJECTED':
return;
case 'INSUFFICIENT_BALANCE':
setError('Not enough balance in wallet');
break;
case 'INVALID_AMOUNT':
setError('Invalid amount');
break;
default:
setError(error.message);
}
}
Best Practices
1. Refresh Balances After Deposit
useBalances() is reactive and will pick up updates the SDK already knows about. Call refreshBalances() (from useVault) to force a server fetch — for example, immediately after a shield, when you want the UI to reflect the new shielded balance without waiting for the next polling tick.
const { shield, refreshBalances } = useVault();
await shield({ tokenAddress, amount });
await refreshBalances();
2. Handle Wallet Rejection Silently
When users cancel the wallet popup, don’t show an error:
try {
await shield({ tokenAddress, amount });
} catch (err: any) {
if (err.code === 'TRANSACTION_REJECTED') return;
setError(err.message);
}
3. Show Progress to Users
Deposits involve multiple on-chain steps. Always show progress so users know the operation is working.
Next Steps