@minkprivacy/react
v0.1.3
Published
Mink Privacy React SDK - React bindings for Mink Privacy SDK
Downloads
12
Maintainers
Readme
@minkprivacy/react
React bindings for the Mink Privacy SDK. Provides a context provider and hooks for building privacy-enabled Solana dApps.
Install
npm install @minkprivacy/react
# or
pnpm add @minkprivacy/reactPeer dependencies:
npm install react @minkprivacy/core @solana/wallet-adapter-react @solana/web3.jsQuick Start
import { MinkProvider, useMink, useMinkBalance, useMinkAuth } from '@minkprivacy/react';
function App() {
return (
<MinkProvider config={{ network: 'devnet', connection }}>
<Dashboard />
</MinkProvider>
);
}
function Dashboard() {
const { sdk, isInitialized } = useMink();
const { isAuthenticated, authenticate } = useMinkAuth();
const { balance, isLoading } = useMinkBalance();
if (!isInitialized) return <p>Connecting...</p>;
if (!isAuthenticated) {
return <button onClick={authenticate}>Authenticate</button>;
}
if (isLoading) return <p>Loading balance...</p>;
return (
<div>
<p>Stealth balance: {balance?.sol} SOL</p>
<button onClick={() => sdk?.cloak({ amount: 0.1 })}>
Deposit 0.1 SOL
</button>
</div>
);
}Architecture
@minkprivacy/react
├── MinkProvider ← Context provider (wraps wallet adapter)
├── hooks/
│ ├── useMink ← SDK instance + init state
│ ├── useMinkBalance ← Balance with caching + auto-refresh
│ ├── useMinkAuth ← Relayer authentication
│ ├── useMinkInbox ← Inbox CRUD + forwarding
│ ├── useAutoForward ← Automatic inbox polling + forward
│ ├── useMinkEvents ← Single event subscription
│ ├── useMinkEventHandlers ← Multi-event subscription
│ └── useMinkStatus ← Operation status + messages
├── types/ ← TypeScript interfaces
└── cache/ ← Request deduplication (internal)Provider
MinkProvider
Wraps your app to provide SDK context. Must be nested inside a Solana WalletProvider.
import { MinkProvider } from '@minkprivacy/react';
<WalletProvider wallets={wallets}>
<MinkProvider
config={{ network: 'devnet', connection }}
autoInitialize={true} // default: auto-init when wallet connects
>
<App />
</MinkProvider>
</WalletProvider>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| config | MinkConfig | required | SDK configuration |
| children | ReactNode | required | Child components |
| autoInitialize | boolean | true | Auto-initialize SDK when wallet connects |
Lifecycle:
- SDK instance created on mount via
createMinkSDK(config) - When wallet connects (and
autoInitializeis true), callssdk.initialize()with wallet adapter - On wallet disconnect, resets state and clears request cache
- On unmount, calls
sdk.dispose()
Hooks
useMink()
Primary hook for accessing the SDK instance and initialization state.
const { sdk, isInitialized, isInitializing, error, initialize, status } = useMink();| Field | Type | Description |
|-------|------|-------------|
| sdk | MinkSDK \| null | SDK instance |
| isInitialized | boolean | SDK ready to use |
| isInitializing | boolean | Initialization in progress |
| error | MinkError \| null | Initialization error |
| initialize | () => Promise<void> | Manual initialization |
| status | OperationStatus | Current operation status |
useMinkBalance(options?)
Fetches stealth balance with caching and optional auto-refresh.
const { balance, isLoading, isRefetching, error, refetch } = useMinkBalance();
// Token balance
const { balance } = useMinkBalance({ token: 'USDC' });
// Auto-refresh every 10s
const { balance } = useMinkBalance({ refetchInterval: 10_000 });| Option | Type | Default | Description |
|--------|------|---------|-------------|
| token | TokenName | — | Token to query ('USDC' or 'USDT'). Omit for SOL. |
| refetchInterval | number | 0 | Auto-refresh interval in ms. 0 = disabled. |
| enabled | boolean | true | Enable/disable the query |
| Return | Type | Description |
|--------|------|-------------|
| balance | BalanceResult \| TokenBalanceResult \| null | Balance data |
| isLoading | boolean | Initial loading |
| isRefetching | boolean | Refetching in background |
| error | MinkError \| null | Error state |
| refetch | () => Promise<void> | Manual refetch (invalidates cache) |
Caching: Uses a built-in RequestCache (5s TTL) with deduplication — concurrent calls for the same balance share a single request.
useMinkAuth()
Manages relayer authentication state.
const { isAuthenticated, isAuthenticating, error, authenticate, logout } = useMinkAuth();| Return | Type | Description |
|--------|------|-------------|
| isAuthenticated | boolean | Current auth state |
| isAuthenticating | boolean | Auth in progress |
| error | MinkError \| null | Auth error |
| authenticate | () => Promise<boolean> | Authenticate (requires wallet) |
| logout | () => void | Clear auth token |
Subscribes to auth:authenticated and auth:expired SDK events automatically.
useMinkInbox()
Full inbox lifecycle — create, list, forward, refresh.
const {
inboxes,
isLoading,
isGeneratingProof,
isSubmitting,
error,
create,
forward,
refresh,
fetchInboxes,
} = useMinkInbox();
// Create inbox
const { inbox, signature } = await create();
// Share address
const address = inbox.address.toBase58();
// Forward pending balance to pool
const sig = await forward(inbox);| Return | Type | Description |
|--------|------|-------------|
| inboxes | PrivateInbox[] | All discovered inboxes |
| isLoading | boolean | Loading/operating |
| isGeneratingProof | boolean | ZK proof generation in progress |
| isSubmitting | boolean | Submitting to relayer |
| error | MinkError \| null | Error state |
| create | (params?) => Promise<{inbox, signature}> | Create new inbox |
| forward | (inbox) => Promise<string> | Forward inbox to pool |
| refresh | (inbox) => Promise<PrivateInbox> | Refresh inbox state |
| fetchInboxes | () => Promise<void> | Re-fetch all inboxes |
Subscribes to 8 inbox SDK events for granular progress tracking.
useAutoForward(options?)
Automatically polls for pending inboxes and forwards them to the privacy pool.
const {
isForwarding,
isGeneratingProof,
lastForwardTime,
forwardResult,
clearForwardResult,
checkPending,
setEnabled,
isEnabled,
} = useAutoForward({
minAmount: BigInt(1_000_000), // 0.001 SOL
pollInterval: 30_000,
});
// Show toast on forward
if (forwardResult?.success) {
toast(`Forwarded ${forwardResult.amount} SOL`);
}| Option | Type | Default | Description |
|--------|------|---------|-------------|
| minAmount | bigint | 1_000_000n | Minimum lamports to trigger forward |
| pollInterval | number | 30_000 | Poll interval in ms |
| successClearDelay | number | 5_000 | Auto-clear success result (ms) |
| errorClearDelay | number | 8_000 | Auto-clear error result (ms) |
| startEnabled | boolean | true | Start polling on mount |
| Return | Type | Description |
|--------|------|-------------|
| isForwarding | boolean | Forward operation in progress |
| isGeneratingProof | boolean | ZK proof generation in progress |
| lastForwardTime | Date \| null | Timestamp of last forward |
| forwardResult | ForwardResult \| null | Latest result (auto-clears) |
| clearForwardResult | () => void | Manually dismiss result |
| checkPending | () => Promise<void> | Trigger immediate check |
| setEnabled | (enabled: boolean) => void | Pause/resume polling |
| isEnabled | boolean | Current polling state |
useMinkEvents(event, handler, deps?)
Subscribe to a single SDK event with automatic cleanup.
useMinkEvents('deposit:confirmed', ({ signature, amount }) => {
console.log(`Deposited ${amount} — tx: ${signature}`);
});useMinkEventHandlers(handlers, deps?)
Subscribe to multiple SDK events at once.
useMinkEventHandlers({
'deposit:confirmed': ({ signature }) => toast(`Deposit: ${signature}`),
'withdraw:confirmed': ({ signature }) => toast(`Withdraw: ${signature}`),
'error': ({ error }) => toast.error(error.message),
});useMinkStatus()
Human-readable operation status.
const { status, isOperating, message } = useMinkStatus();
if (isOperating) {
return <Spinner label={message} />;
}| Return | Type | Description |
|--------|------|-------------|
| status | OperationStatus | 'idle' 'initializing' 'depositing' 'withdrawing' 'scanning' 'error' |
| isOperating | boolean | true if not idle/error |
| message | string \| null | Human-readable status message |
| Status | Message |
|--------|---------|
| idle | null |
| initializing | "Initializing SDK..." |
| depositing | "Processing deposit..." |
| withdrawing | "Processing withdrawal..." |
| scanning | "Scanning for UTXOs..." |
| error | "An error occurred" |
Types
All types are exported from the package root:
import type {
// React types
MinkProviderProps,
MinkContextValue,
OperationStatus,
UseBalanceOptions,
UseBalanceResult,
UseStatusResult,
UseAuthResult,
UseInboxResult,
MinkEventHandler,
ForwardResult,
UseAutoForwardReturn,
UseAutoForwardOptions,
// Re-exported from @minkprivacy/core
MinkConfig,
BalanceResult,
TokenBalanceResult,
AllBalancesResult,
DepositParams,
DepositResult,
WithdrawParams,
WithdrawResult,
FeeEstimate,
TokenName,
PrivateInbox,
CreateInboxParams,
MinkEventType,
MinkEventPayloads,
} from '@minkprivacy/react';
// MinkError is also re-exported as a value
import { MinkError } from '@minkprivacy/react';Peer Dependencies
| Package | Version |
|---------|---------|
| react | >= 18.0.0 |
| @minkprivacy/core | >= 0.1.0 |
| @solana/wallet-adapter-react | >= 0.15.0 |
| @solana/web3.js | >= 1.98.0 |
