Documentation Index
Fetch the complete documentation index at: https://docs.privora.xyz/llms.txt
Use this file to discover all available pages before exploring further.
This guide covers integrating Privora into web and mobile applications using the @privora/react package.
React Integration
Setup
npm install @privora/react @privora/sdk @solana/web3.js @solana/wallet-adapter-react
Using PrivoraProvider
The recommended approach is to use the @privora/react package which provides ready-to-use hooks and components:
import { PrivoraProvider, usePrivoraContext, useEncrypt } from '@privora/react';
import { useWallet } from '@solana/wallet-adapter-react';
function App() {
const { signMessage, connected } = useWallet();
return (
<PrivoraProvider
rpcUrl={process.env.NEXT_PUBLIC_SEQUENCER_URL!}
autoInitialize={connected}
signMessage={signMessage}
>
<MyApp />
</PrivoraProvider>
);
}
Using with Wallet Adapter
import { usePrivoraContext, useEncrypt } from '@privora/react';
function SubmitOrderForm() {
const { privora, userCrypto, isInitialized } = usePrivoraContext();
const { encryptAndSubmit, isEncrypting, isSubmitting, error } = useEncrypt(privora, userCrypto);
const { publicKey, signTransaction } = useWallet();
const [price, setPrice] = useState('');
const [quantity, setQuantity] = useState('');
if (!isInitialized) {
return <div>Connecting to Privora...</div>;
}
const handleSubmit = async (e: FormEvent) => {
e.preventDefault();
if (!publicKey || !privora) return;
// Encrypt and submit values
const priceResult = await encryptAndSubmit(Number(price), 'u8');
const qtyResult = await encryptAndSubmit(Number(quantity), 'u8');
if (!priceResult || !qtyResult) return;
// Build and send transaction
const tx = await privora
.transaction()
.add(buildSubmitOrderInstruction(priceResult.hash, qtyResult.hash))
.withFheData([priceResult.hash, qtyResult.hash])
.build();
const signed = await signTransaction!(tx);
const signature = await privora.sendTransaction(signed);
console.log('Order submitted:', signature);
// Store recovery data for later display
saveOrderRecovery({
priceHash: priceResult.hash,
priceCiphertext: priceResult.userCiphertext,
priceNonce: priceResult.userNonce,
qtyHash: qtyResult.hash,
qtyCiphertext: qtyResult.userCiphertext,
qtyNonce: qtyResult.userNonce,
});
};
return (
<form onSubmit={handleSubmit}>
<input value={price} onChange={e => setPrice(e.target.value)} placeholder="Price" />
<input value={quantity} onChange={e => setQuantity(e.target.value)} placeholder="Quantity" />
<button type="submit" disabled={isEncrypting || isSubmitting}>
{isEncrypting ? 'Encrypting...' : isSubmitting ? 'Submitting...' : 'Submit Order'}
</button>
{error && <p className="error">{error}</p>}
</form>
);
}
Local Recovery Display
Show users their encrypted values using the useDecryptReveal hook:
import { useDecryptReveal } from '@privora/react';
function OrderDisplay({ order, userCrypto }) {
const priceField = {
ciphertext: order.priceCiphertext,
nonce: order.priceNonce,
dataType: 'u8' as const,
};
const qtyField = {
ciphertext: order.qtyCiphertext,
nonce: order.qtyNonce,
dataType: 'u8' as const,
};
const [priceState, priceActions] = useDecryptReveal(priceField, userCrypto);
const [qtyState, qtyActions] = useDecryptReveal(qtyField, userCrypto);
return (
<div>
<div>
<span>Price: {priceState.revealed ? priceState.value : '****'}</span>
<button onClick={priceActions.toggle}>
{priceState.revealed ? 'Hide' : 'Reveal'}
</button>
</div>
<div>
<span>Quantity: {qtyState.revealed ? qtyState.value : '****'}</span>
<button onClick={qtyActions.toggle}>
{qtyState.revealed ? 'Hide' : 'Reveal'}
</button>
</div>
</div>
);
}
Revealing Multiple Fields
For orders with multiple encrypted values, use useDecryptRevealMultiple:
import { useDecryptRevealMultiple } from '@privora/react';
function OrderCard({ order, userCrypto }) {
const fields = {
price: { ciphertext: order.priceCiphertext, nonce: order.priceNonce, dataType: 'u8' as const },
quantity: { ciphertext: order.qtyCiphertext, nonce: order.qtyNonce, dataType: 'u8' as const },
};
const { price, quantity, revealAll, hideAll } = useDecryptRevealMultiple(fields, userCrypto);
return (
<div className="order-card">
<p>Price: {price.revealed ? price.value : '****'}</p>
<p>Quantity: {quantity.revealed ? quantity.value : '****'}</p>
<button onClick={revealAll}>Reveal All</button>
<button onClick={hideAll}>Hide All</button>
</div>
);
}
Error Handling
import { useEncrypt, usePrivoraContext } from '@privora/react';
function SubmitForm() {
const { privora, userCrypto, error: initError } = usePrivoraContext();
const { encryptAndSubmit, error: encryptError, clearError } = useEncrypt(privora, userCrypto);
const handleSubmit = async (value: number) => {
clearError(); // Clear previous errors
const result = await encryptAndSubmit(value, 'u8');
if (!result) {
// Error is available in encryptError
return;
}
// Success - continue with transaction
};
if (initError) {
return <div className="error">Failed to initialize: {initError}</div>;
}
return (
<div>
{encryptError && <div className="error">{encryptError}</div>}
<button onClick={() => handleSubmit(100)}>Submit</button>
</div>
);
}
TypeScript Types
import type {
EncryptedField,
SubmitResult,
RevealState,
} from '@privora/react';
interface Order {
owner: string;
priceHash: string;
qtyHash: string;
// User recovery data (base64 encoded)
priceCiphertext: string;
priceNonce: string;
qtyCiphertext: string;
qtyNonce: string;
side: 'buy' | 'sell';
status: 'open' | 'matched' | 'cancelled';
}
Best Practices
- Use the React package: Prefer
@privora/react over manual provider implementations
- Auto-initialize with wallet: Use
autoInitialize prop with wallet adapter for seamless connection
- Store recovery data: Always save
userCiphertext and userNonce for later decryption
- Handle loading states: Show appropriate UI during encryption/decryption operations
- Validate inputs: Check value ranges before encryption (e.g., 0-255 for u8)
- Secure storage: Consider encrypting recovery data at rest in local storage
Next Steps
React Integration Reference
Complete React SDK documentation
React Hooks API
Detailed hooks API reference