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 Native SDK.

Basic Transfer

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

const result = await sdk.send(
  '0x...token-address',
  '250000000000000000', // 0.25 tokens
  '0x04...recipient-privacy-address' // 194-char privacy address
);
console.log('Transfer TX:', result.txHash);

Transfer Parameters

ParameterTypeRequiredDescription
tokenAddressstringYesToken contract address
amountstringYesAmount in wei (smallest unit)
recipientPrivacyAddressstringYesRecipient’s 194-character privacy address

Transfer Result

interface TransferResult {
  txHash: string;  // Transaction hash
  fee: string;     // Fee paid (in wei)
}

Privacy Address Validation

Always validate the recipient’s privacy address before sending:
const isValid = sdk.isValidPrivacyAddress(recipientAddress);
if (!isValid) {
  console.log('Invalid privacy address');
  return;
}

const result = await sdk.send(tokenAddress, amount, recipientAddress);

Complete Example

import React, { useState } from 'react';
import { View, Text, TextInput, Button, ActivityIndicator } from 'react-native';
import { SdkError } from '@sunnyside-io/privacy-boost-react-native';

function TransferScreen({ sdk, tokenAddress }: { sdk: PrivacyBoost; tokenAddress: string }) {
  const [recipient, setRecipient] = useState('');
  const [amount, setAmount] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

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

    setLoading(true);
    setError(null);

    try {
      const weiAmount = sdk.parseAmount(amount, 18);
      await sdk.send(tokenAddress, weiAmount, recipient);
      setRecipient('');
      setAmount('');
    } catch (err: any) {
      if (SdkError.SignatureRejected.instanceOf(err)) return;
      setError(err?.inner?.message ?? err?.message ?? 'Transfer failed');
    } finally {
      setLoading(false);
    }
  };

  return (
    <View style={{ padding: 16 }}>
      <TextInput
        value={recipient}
        onChangeText={setRecipient}
        placeholder="Recipient privacy address"
        editable={!loading}
      />
      <TextInput
        value={amount}
        onChangeText={setAmount}
        placeholder="Amount (e.g. 1.0)"
        keyboardType="decimal-pad"
        editable={!loading}
      />
      {error && <Text style={{ color: 'red' }}>{error}</Text>}
      {loading ? (
        <ActivityIndicator />
      ) : (
        <Button
          title="Send"
          onPress={handleTransfer}
          disabled={!recipient || !amount}
        />
      )}
    </View>
  );
}

Error Handling

try {
  await sdk.send(tokenAddress, amount, recipientPrivacyAddress);
} catch (error: any) {
  switch (error.tag) {
    case 'SignatureRejected':
      return;
    case 'InsufficientBalance':
      console.log('Not enough shielded balance');
      break;
    case 'InvalidAddress':
      console.log('Invalid privacy address');
      break;
    case 'NetworkError':
      console.log('Network error:', error.message);
      break;
    default:
      console.log('Transfer error:', error);
  }
}

Best Practices

1. Validate Inputs Before Sending

Always validate the privacy address before attempting a transfer.

2. Refresh After Transfer

await sdk.send(tokenAddress, amount, recipientPrivacyAddress);
const updatedBalance = await sdk.getBalance(tokenAddress);
console.log('Remaining shielded:', updatedBalance.shieldedBalance);

Next Steps