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: `0x${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