Skip to main content

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.

Private Transfers

This guide covers sending tokens privately between privacy addresses using the Privacy Boost React SDK.

Basic Transfer

import { useVault } from '@sunnyside-io/privacy-boost-react';

function TransferButton() {
  const { send } = useVault();

  const handleTransfer = async () => {
    const result = await send({
      to: '0x04...recipient-privacy-address',
      tokenAddress: '0x...token-address',
      amount: '1.0',
    });

    console.log('Transfer request:', result.requestId);
  };

  return <button onClick={handleTransfer}>Send</button>;
}

Transfer Parameters

ParameterTypeRequiredDescription
toHex | stringYesRecipient’s privacy address
tokenAddressHexYesToken contract address
amountstring | bigintYesAmount (human-readable string or wei)

Privacy Address Validation

import { isValidPrivacyAddress } from '@sunnyside-io/privacy-boost';

function TransferForm() {
  const { send } = useVault();
  const [recipient, setRecipient] = useState('');
  const [error, setError] = useState('');

  const handleTransfer = async () => {
    if (!isValidPrivacyAddress(recipient)) {
      setError('Invalid privacy address');
      return;
    }

    await send({ to: recipient, tokenAddress: '0x...', amount: '1.0' });
  };

  // ...
}

Complete Example

import { useState } from 'react';
import { useVault, useBalances } from '@sunnyside-io/privacy-boost-react';
import { isValidPrivacyAddress } from '@sunnyside-io/privacy-boost';

function TransferForm({ tokenAddress }: { tokenAddress: string }) {
  const { send } = useVault();
  const { refresh } = useBalances();
  const [recipient, setRecipient] = useState('');
  const [amount, setAmount] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const handleTransfer = async () => {
    if (!isValidPrivacyAddress(recipient)) {
      setError('Invalid privacy address');
      return;
    }

    setLoading(true);
    setError(null);

    try {
      await send({ to: recipient, tokenAddress, amount });
      setRecipient('');
      setAmount('');
      await refresh();
    } catch (err: any) {
      if (err.code !== 'TRANSACTION_REJECTED') {
        setError(err.message);
      }
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <input
        type="text"
        value={recipient}
        onChange={(e) => setRecipient(e.target.value)}
        placeholder="Recipient privacy address"
        disabled={loading}
      />
      <input
        type="text"
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount"
        disabled={loading}
      />
      {error && <p style={{ color: 'red' }}>{error}</p>}
      <button onClick={handleTransfer} disabled={loading || !recipient || !amount}>
        {loading ? 'Sending...' : 'Send'}
      </button>
    </div>
  );
}

Error Handling

try {
  await send({ to: recipient, tokenAddress, amount });
} catch (error: any) {
  switch (error.code) {
    case 'TRANSACTION_REJECTED':
      return;
    case 'INSUFFICIENT_BALANCE':
      setError('Not enough shielded balance');
      break;
    case 'INVALID_RECIPIENT':
      setError('Invalid privacy address');
      break;
    default:
      setError(error.message);
  }
}

Best Practices

1. Validate Inputs Before Sending

Always validate the privacy address before attempting a transfer.

2. Refresh After Transfer

await send({ to: recipient, tokenAddress, amount });
await refresh();

Next Steps