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.
Wallet Integration
This guide covers connecting wallets and authenticating users with the Privacy Boost React Native SDK.
WalletDelegate Interface
The SDK interacts with wallets through the WalletDelegate interface:
import type { WalletDelegate } from '@sunnyside-io/privacy-boost-react-native';
interface WalletDelegate {
getAddress(): Promise<string>;
getChainId(): Promise<bigint>;
signMessage(message: string): Promise<string>;
signTypedData(typedDataJson: string): Promise<string>;
sendTransaction(toAddress: string, value: string, data: string): Promise<string>;
waitForTransactionReceipt(txHash: string): Promise<TransactionReceipt>;
}
interface TransactionReceipt {
txHash: string;
status: boolean; // true on success, false on revert
logs: Array<{
address: string;
topics: string[];
data: string;
}>;
}
The SDK calls waitForTransactionReceipt after sendTransaction to confirm
on-chain inclusion and read emitted events (e.g. the Shield event). It
should poll eth_getTransactionReceipt until the receipt is available.
Basic Authentication
import { PrivacyBoost } from '@sunnyside-io/privacy-boost-react-native';
const walletDelegate: WalletDelegate = {
getAddress: async () => '0x...wallet-address',
getChainId: async () => BigInt(1),
signMessage: async (message) => {
// Use your wallet library to sign
return '0x...signature';
},
signTypedData: async (typedDataJson) => {
return '0x...signature';
},
sendTransaction: async (to, value, data) => {
return '0x...txHash';
},
waitForTransactionReceipt: async (txHash) => {
// Poll eth_getTransactionReceipt until available.
return { txHash, status: true, logs: [] };
},
};
const result = await sdk.authenticate(walletDelegate);
switch (result.tag) {
case 'Authenticated':
console.log('Privacy Address:', result.loginResult.privacyAddress);
break;
case 'MnemonicGenerated':
console.log('Recovery phrase:', result.mnemonic);
await sdk.proceedAfterMnemonic(undefined);
break;
case 'CredentialRequired':
const loginResult = await sdk.submitCredential(credential, undefined);
console.log('Privacy Address:', loginResult.privacyAddress);
break;
case 'RecoveryRequired':
console.log('Recovery required:', result.challenge.reason);
break;
}
See Getting Started → Connecting a Wallet
for full handling of each AuthResult variant, including the mnemonic flow
for first-time users.
WalletConnect Integration
import { useWalletConnectModal } from '@walletconnect/modal-react-native';
function createWalletConnectDelegate(provider: any): WalletDelegate {
return {
getAddress: async () => {
const accounts = await provider.request({ method: 'eth_accounts' });
return accounts[0];
},
getChainId: async () => {
const chainId = await provider.request({ method: 'eth_chainId' });
return BigInt(parseInt(chainId, 16));
},
signMessage: async (message) => {
const address = await provider.request({ method: 'eth_accounts' }).then((a: string[]) => a[0]);
return provider.request({
method: 'personal_sign',
params: [message, address],
});
},
signTypedData: async (typedDataJson) => {
const address = await provider.request({ method: 'eth_accounts' }).then((a: string[]) => a[0]);
return provider.request({
method: 'eth_signTypedData_v4',
params: [address, typedDataJson],
});
},
sendTransaction: async (to, value, data) => {
const address = await provider.request({ method: 'eth_accounts' }).then((a: string[]) => a[0]);
return provider.request({
method: 'eth_sendTransaction',
params: [{ from: address, to, value: '0x' + BigInt(value).toString(16), data }],
});
},
};
}
Logout
| Method | What it does | Next login |
|---|
logout() | Clears everything (keys, token, connection) | Full re-auth with wallet |
clearSession() | Clears JWT only, keeps keys | Fast — no wallet signing |
// Full logout
sdk.logout();
// Quick session clear (keeps keys)
sdk.clearSession();
State Accessors
sdk.isConnected(); // boolean
sdk.isAuthenticated(); // boolean
sdk.getPrivacyAddress(); // string | undefined
sdk.getMpk(); // string | undefined
sdk.getWalletAddress(); // string | undefined
Complete Example
import React, { useState } from 'react';
import { View, Text, Button, ActivityIndicator } from 'react-native';
function ConnectScreen({ sdk }: { sdk: PrivacyBoost }) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [privacyAddress, setPrivacyAddress] = useState<string | null>(null);
const handleConnect = async () => {
setLoading(true);
setError(null);
try {
const result = await sdk.authenticate(walletDelegate);
if (result.tag === 'Authenticated') {
setPrivacyAddress(result.loginResult.privacyAddress);
}
} catch (err: any) {
if (err.tag !== 'SignatureRejected') {
setError(err.message ?? 'Authentication failed');
}
} finally {
setLoading(false);
}
};
if (privacyAddress) {
return (
<View style={{ padding: 16 }}>
<Text>Connected: {privacyAddress.slice(0, 10)}...</Text>
<Button title="Logout" onPress={() => { sdk.logout(); setPrivacyAddress(null); }} />
</View>
);
}
return (
<View style={{ padding: 16 }}>
{error && <Text style={{ color: 'red' }}>{error}</Text>}
{loading ? (
<ActivityIndicator />
) : (
<Button title="Connect Wallet" onPress={handleConnect} />
)}
</View>
);
}
Error Handling
try {
await sdk.authenticate(walletDelegate);
} catch (error: any) {
switch (error.tag) {
case 'SignatureRejected':
return; // User cancelled
case 'WalletError':
console.log('Wallet error:', error.message);
break;
case 'NetworkError':
console.log('Network error:', error.message);
break;
case 'InvalidConfig':
console.log('SDK configuration error');
break;
default:
console.log('Auth error:', error);
}
}
Best Practices
1. Handle Signature Rejection Silently
When users cancel the wallet signature, don’t show an error.
2. Save Session After Authentication
Use session persistence to avoid re-signing on app restart. See Session Storage.
3. Show Connection State
Display the privacy address so users can verify which account is active.
Next Steps