Hook
usePrivatePayment
Typed React hook for the MagicBlock Private Payments API with auth-aware requests, transaction builders, balance readers, and mint initialization checks.
Installation
terminal
$npx shadcn@latest add https://uxdotsol.xyz/r/use-private-payment.jsonUsage
use-private-payment.tsx
"use client"; import { useState } from "react";import { usePrivatePayment, type PrivatePaymentTxResponse,} from "@/hooks/use-private-payment"; const USDC_MINT = "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"; export function SendPrivateUsdc({ owner, recipient, amountAtomics, signAndSend,}: { owner: string; recipient: string; amountAtomics: number; signAndSend: (tx: PrivatePaymentTxResponse) => Promise<string>;}) { const payments = usePrivatePayment({ cluster: "devnet" }); const [signature, setSignature] = useState<string | null>(null); async function sendPrivateUsdc() { setSignature(null); const mintStatus = await payments.isMintInitialized({ mint: USDC_MINT }); if (!mintStatus.initialized) { const setupTx = await payments.initializeMint({ payer: owner, mint: USDC_MINT, }); await signAndSend(setupTx); } const transferTx = await payments.transfer({ from: owner, to: recipient, mint: USDC_MINT, amount: amountAtomics, visibility: "private", fromBalance: "base", toBalance: "base", initIfMissing: false, initAtasIfMissing: false, initVaultIfMissing: false, }); setSignature(await signAndSend(transferTx)); } return ( <div className="grid gap-2"> <button disabled={payments.isLoading} onClick={sendPrivateUsdc}> {payments.isLoading ? "Sending..." : "Send private USDC"} </button> {signature ? <p>Confirmed: {signature}</p> : null} {payments.error ? <p>{payments.error.message}</p> : null} </div> );}Options
| Name | Type | Default | Description |
|---|---|---|---|
| endpoint | string | 'https://payments.magicblock.app' | Private Payments API base URL. |
| cluster | 'mainnet' | 'devnet' | http(s) URL | undefined | Default cluster sent to payment API requests. |
| validator | string | undefined | Default MagicBlock validator sent to supported requests. |
| authToken | string | undefined | Default bearer token for private balance reads and authenticated transfers. |
| headers / fetcher | HeadersInit / typeof fetch | undefined / fetch | Optional default headers and custom fetch implementation. Per-request headers are merged on top. |
Functions
| Name | Type | Default | Description |
|---|---|---|---|
| request | <T>(path, init?) => Promise<T> | - | Low-level typed request helper. It trims endpoint slashes, merges auth/custom headers, records timing, and parses JSON/text errors. |
| health | () => Promise<{ status: 'ok' }> | - | Checks Private Payments API availability. |
| deposit / transfer / withdraw / initializeMint | (params) => Promise<PrivatePaymentTxResponse> | - | Builds unsigned SPL transactions for wallet signing. transfer can pass a per-request authToken. |
| balance / privateBalance | (params) => Promise<PrivatePaymentBalance> | - | Reads public base-chain or private ephemeral token balance. |
| challenge / login | (params) => Promise<{ challenge: string } | { token: string }> | - | Runs the wallet challenge flow used to authorize private data access. |
| isMintInitialized | (params) => Promise<PrivatePaymentMintInitialization> | - | Checks whether the private-payment transfer queue is initialized for a mint before calling initializeMint. |
| reset / clearError | () => void | - | Clears hook state completely or only clears the current error. |
Types
| Name | Type | Default | Description |
|---|---|---|---|
| PrivatePaymentState | { status; isLoading; error; lastResponse; lastRequest } | - | Request lifecycle state exposed by the hook. |
| PrivatePaymentError | Error & { status?; payload?; path? } | - | Readable API error with response status, parsed payload, and endpoint path. |
| PrivatePaymentTxResponse | { kind; version; transactionBase64; sendTo; recentBlockhash; lastValidBlockHeight; instructionCount; requiredSigners; validator; transferQueue?; rentPda? } | - | Unsigned transaction payload returned by write endpoints. |
| PrivatePaymentCluster / BalanceLocation / Visibility | 'mainnet' | 'devnet' | URL / 'base' | 'ephemeral' / 'public' | 'private' | - | Shared string unions used across request configuration and transfer payloads. |
| PrivatePaymentDepositParams / WithdrawParams | { owner; mint?; amount; cluster?; validator?; initIfMissing?; initAtasIfMissing?; idempotent?; ... } | - | Deposit and withdraw request payloads. Amount is always integer token base units. |
| PrivatePaymentTransferParams | { from; to; mint; amount; visibility; fromBalance; toBalance; authToken?; ... } | - | Transfer request payload. |
| PrivatePaymentInitializeMintParams / IsMintInitializedParams | { payer; mint; cluster?; validator? } / { mint; cluster?; validator? } | - | Mint setup and setup-check request payloads. |
| PrivatePaymentChallengeParams / LoginParams | { pubkey; cluster?; mock? } / { pubkey; challenge; signature; cluster?; mock? } | - | Wallet-auth request payloads for private balance reads and authenticated transfers. |
| PrivatePaymentBalance | { address; mint; ata; location; balance } | - | Balance response shape. |
Returns
| Name | Type | Default | Description |
|---|---|---|---|
| status / isLoading | PrivatePaymentStatus / boolean | 'idle' / false | Current request lifecycle state. |
| error | PrivatePaymentError | null | null | Last request error. |
| lastResponse / lastRequest | unknown | null / PrivatePaymentRequestMeta | null | null / null | Latest successful response and request timing metadata. |
| endpoint | string | 'https://payments.magicblock.app' | Normalized endpoint with trailing slashes removed. |