React SDK
@shard-lab/nc-waas-react(Pouchi Wallet React SDK)의 주요 Privy 호환 공개 API 선언 스냅샷입니다. 진입점은 .(React), ./server, ./wagmi, ./smart-wallets, ./solana, ./core(React 없음)입니다.
훅 한눈에 보기
섹션 제목: “훅 한눈에 보기”| 이름 | 하는 일 | 상태 |
|---|---|---|
PrivyProvider, NcWaasProvider |
앱을 감싸는 Provider. apiUrl, appId(또는 tenantId), config.defaultChain(또는 chain) |
지원 |
usePrivy |
ready, authenticated, user, login, logout, getAccessToken, signMessage, exportWallet(안내만), 계정 연결 |
지원 |
useLogin, useLogout |
로그인 모달 열기와 완료, 로그아웃 콜백 | 지원 |
useLoginWithEmail |
이메일 코드 로그인. 새 이용자는 Pouchi 화면에서 지갑 보호 설정 (sendCode, loginWithCode) |
지원 |
useLoginWithOAuth |
google, apple, kakao, naver 로그인. 앱 운영자가 켜고 redirect URI를 등록해야 함 | 앱 설정 필요 |
useLinkAccount |
이메일, 소셜, 패스키 연결. 다른 수단은 onError로 거절 |
지원 |
useLoginWithPasskey |
등록된 패스키로 로그인 | 지원 |
useSignupWithPasskey |
패스키만으로 가입 | 미지원 (거절) |
useWallets |
임베디드 스마트 지갑 1개와 EIP-1193 provider | 지원 |
useSendTransaction |
송금, ERC-20, 컨트랙트 호출. 승인 화면 뒤 { hash } |
지원 |
useSignMessage, useSignTypedData |
ERC-1271 서명 (EIP-712 포함) | 지원 |
useSendCalls, useSmartWallets |
묶음 실행(EIP-5792, 최대 8개)과 Privy smart wallet 클라이언트 | 지원 |
useSessionApproval |
앱 안 세션 키 위임. config.approvals.session.clientId 필요 |
지원 |
useWalletRecovery, useRecoverWallet |
새 기기로 지갑 옮기기, 진행 중인 복구 보기 | 지원 |
useRecoveryBackups |
백업 수단 목록과 삭제 | 지원 |
useSessions, useRevokeSession, LoggedInDevices |
로그인한 기기 목록과 로그아웃시키기 | 지원 |
AssetMigrationCard, useAssetMigration |
Privy 옛 지갑에서 새 지갑으로 자산 옮기기 | 지원 |
useCreateWallet |
첫 로그인 때 만든 지갑 돌려주기. 추가 지갑은 거절 | 부분 지원 |
useSessionSigners |
Privy 세션 서명자 | 미지원 (거절). useSessionApproval이나 서버 위임 |
useSignTransaction |
원시 트랜잭션 서명 | 미지원 (거절). useSendTransaction |
useFundWallet, useImportWallet, useCrossAppAccounts, useMfaEnrollment, useMfa, useSolanaWallets |
Privy 전용 기능 | 미지원 (거절 또는 빈 값) |
useNcWaas, useNcWaasState |
직접 화면을 만들 때 쓰는 컨트롤러와 상태 | 고급 |
Provider
섹션 제목: “Provider”PrivyProvider
섹션 제목: “PrivyProvider”function · react/provider.d.ts
Privy-compatible name. Migration also requires the Pouchi API URL, app ID and chain configuration.
const PrivyProvider: typeof NcWaasProvider;NcWaasProvider
섹션 제목: “NcWaasProvider”function · react/provider.d.ts
function NcWaasProvider({ apiUrl, tenantId, appId, chain, config, core: suppliedCore, children }: NcWaasProviderProps): import("react").JSX.Element;NcWaasProviderProps
섹션 제목: “NcWaasProviderProps”interface · react/provider.d.ts
interface NcWaasProviderProps { /** Pouchi API origin, for example `https://api.example.com`. */ apiUrl: string; /** Pouchi tenant id. */ tenantId?: string; /** Privy-compatible alias of `tenantId`, so `<PrivyProvider appId=...>` keeps working. */ appId?: string; /** Accepted for Privy compatibility; not used. */ clientId?: string; /** The tenant's chain. Falls back to `config.defaultChain`. */ chain?: Chain; config?: NcWaasConfig; /** Advanced: supply a preconfigured controller (custom storage, tests). */ core?: NcWaasCore; children?: ReactNode;}NcWaasConfig
섹션 제목: “NcWaasConfig”interface · types.d.ts
interface NcWaasConfig { loginMethods?: LoginMethod[]; appearance?: NcWaasAppearance; /** Privy-compatible; external (Solana) wallet connectors are accepted and ignored. */ externalWallets?: Record<string, unknown>; /** Privy-compatible Solana settings (`solana.rpcs`); Pouchi wallets are EVM only, so this is accepted and ignored. */ solana?: Record<string, unknown>; /** Privy-compatible. Pouchi always creates the wallet at first login; the value is accepted and ignored. */ embeddedWallets?: { ethereum?: { createOnLogin?: "users-without-wallets" | "all-users" | "off"; }; solana?: { createOnLogin?: "users-without-wallets" | "all-users" | "off"; }; createOnLogin?: "users-without-wallets" | "all-users" | "off"; showWalletUIs?: boolean; }; /** Privy-compatible chain config. The chain must equal the tenant's Pouchi chain. */ defaultChain?: Chain; supportedChains?: Chain[]; approvals?: { /** * Session approvals: approve once, then one-tap confirmations inside a capped, short-lived * policy. Requires a client registered by the tenant for this app. See useSessionApproval. */ session?: SessionApprovalConfig; }; /** Recovery backup methods offered at wallet setup and in recovery (spec §4.6). */ backups?: { /** Google Drive app-data backup. Needs a Google OAuth web client ID for this app's origin (drive.appdata scope). */ googleDrive?: { clientId: string; apiBase?: string; uploadBase?: string; }; }; mfa?: Record<string, unknown>; walletConnectCloudProjectId?: string; fundingMethodConfig?: Record<string, unknown>; intl?: Record<string, unknown>; legal?: { termsAndConditionsUrl?: string; privacyPolicyUrl?: string; }; customAuth?: Record<string, unknown>; passkeys?: Record<string, unknown>; oauth?: { /** * The app page social login returns to. Default: the current page (origin + path). It must be registered * with Pouchi: an exact HTTPS URI in the tenant's OAuth redirect URIs (loopback pages on a registered * application origin also work outside production). */ redirectUrl?: string; }; transactions?: { /** * Optional tenant backend hook for contract calls. Without it, the signed-in user proposes * calls directly, limited by the tenant's userCallPolicy (registered contracts by default). */ propose?: TransactionProposer; /** How long `sendTransaction` waits for an on-chain hash. Default 120 s. */ timeoutMs?: number; };}NcWaasAppearance
섹션 제목: “NcWaasAppearance”interface · types.d.ts
interface NcWaasAppearance { /** * "light", "dark", or "auto" (follows the OS, the default). Privy also accepts a hex background; it is treated as "auto". * Both palettes come from the same warm neutrals as the Pouchi web wallet. */ theme?: "light" | "dark" | "auto" | `#${string}`; /** * Primary button, focus ring and selection color. Defaults to the near-black ink of the Pouchi look (no saturated * accent). The button text switches to black or white for contrast automatically. */ accentColor?: `#${string}`; /** * Brand shown at the top left of every modal: an image URL or any React node (an inline SVG, a component). Without * it the header shows `appName` (default: the tenant name). Pass `appName` too so the image has an accessible name. */ logo?: string | ReactNode; /** Title of the first login screen. Default: "이메일로 로그인" / "Log in with email". */ landingHeader?: string; /** Subtitle of the first login screen. Default: "처음이면 지갑을 함께 만들어요. 비밀번호는 필요 없어요." */ loginMessage?: string; /** Application name used in copy, as the logo's accessible name, and in local passkey prompts. */ appName?: string; /** * Modal language: "ko" or "en", or the app's own language tag ("ko-KR" is Korean; any other language is English, * the sheets' only other language). Defaults to the browser language. Pass the app's current language here: when it * changes, the provider switches every sheet, including one that is open. */ locale?: "ko" | "en" | (string & {}); /** Hide the small platform attribution ("Powered by ...") under the login form. Default false. */ hideAttribution?: boolean; /** Privy-compatible; Pouchi wallets are Ethereum only, so this is accepted and ignored. */ walletChainType?: "ethereum-only" | "solana-only" | "ethereum-and-solana";}로그인과 사용자
섹션 제목: “로그인과 사용자”usePrivy
섹션 제목: “usePrivy”function · react/hooks.d.ts
function usePrivy(): UsePrivyResult;UsePrivyResult
섹션 제목: “UsePrivyResult”type · react/hooks.d.ts
type UsePrivyResult = UsePrivyCore & ReturnType<typeof useUnsupportedUnlinks> & ReturnType<typeof useUnsupportedLinks>;useLogin
섹션 제목: “useLogin”function · react/hooks.d.ts
function useLogin(callbacks?: { onComplete?: (params: LoginCompleteParams) => void; onError?: (error: NcWaasError) => void;}): { login: () => void;};LoginCompleteParams
섹션 제목: “LoginCompleteParams”interface · react/hooks.d.ts
interface LoginCompleteParams { user: User; isNewUser: boolean; wasAlreadyAuthenticated: boolean; loginMethod: LoginMethodName | null; loginAccount: LinkedAccount | null;}useLogout
섹션 제목: “useLogout”function · react/hooks.d.ts
function useLogout(callbacks?: { onSuccess?: () => void;}): { logout: () => Promise<void>;};useLoginWithEmail
섹션 제목: “useLoginWithEmail”function · react/hooks.d.ts
Headless email login (Privy useLoginWithEmail). Drives the same flow as the modal; new
users still complete wallet protection and backup in the modal.
function useLoginWithEmail(callbacks?: { onComplete?: (params: LoginCompleteParams) => void; onError?: (error: NcWaasError) => void;}): { sendCode: ({ email }: { email: string; }) => Promise<void>; loginWithCode: ({ code }: { code: string; }) => Promise<void>; state: { status: string; error: Error | null; };};User
섹션 제목: “User”interface · types.d.ts
Privy-shaped user. id is stable per tenant wallet.
interface User { id: string; createdAt: Date; email?: { address: string; }; /** Privy-compatible; Pouchi has no phone login. */ phone?: { number: string; }; wallet?: UserWallet; google?: UserOAuthAccount; apple?: UserOAuthAccount; kakao?: UserOAuthAccount; naver?: UserOAuthAccount; linkedAccounts: LinkedAccount[]; mfaMethods: []; hasAcceptedTerms: boolean; isGuest: false; /** Pouchi specific. */ ncWaas: { tenantId: string; walletId: string; status: AccountResponse["status"]; deploymentStatus: AccountResponse["contract"]["deploymentStatus"]; };}UserWallet
섹션 제목: “UserWallet”interface · types.d.ts
interface UserWallet { address: Hex; /** Always "ethereum"; "solana" is in the type only so Privy code that branches on it compiles. */ chainType: "ethereum" | "solana"; chainId: string; /** "privy" is kept for drop-in compatibility with code that looks for the embedded wallet. */ walletClientType: "privy" | (string & {}); connectorType: "embedded" | (string & {}); imported: boolean; delegated: boolean; walletIndex: number | null; recoveryMethod: "user-passcode" | (string & {}); /** Pouchi specific. */ walletId: string; /** Privy server-wallet id. Pouchi has no server wallets, so it is never set; use `walletId`. */ id?: string | null;}소셜 로그인, 패스키, 계정 연결
섹션 제목: “소셜 로그인, 패스키, 계정 연결”useLoginWithOAuth
섹션 제목: “useLoginWithOAuth”function · react/hooks.d.ts
Privy useLoginWithOAuth. initOAuth({ provider }) leaves for the provider’s sign-in and comes back to this
page (or config.oauth.redirectUrl); the provider finishes the login on load and calls onComplete.
Providers: those the tenant enabled among google, apple, kakao, naver.
function useLoginWithOAuth(callbacks?: { onComplete?: (params: LoginCompleteParams) => void; onError?: (error: NcWaasError) => void;}): { state: OAuthFlowState; initOAuth: (input: { provider: OAuthProvider | PrivyOnlyOAuthProvider; disableSignup?: boolean; }) => Promise<void>; loading: boolean;};useLinkAccount
섹션 제목: “useLinkAccount”function · react/hooks.d.ts
Privy useLinkAccount: link methods plus success and error callbacks (OAuth links finish after the redirect).
function useLinkAccount(callbacks?: { onSuccess?: (params: LinkAccountSuccess) => void; onError?: (error: NcWaasError, details: { linkMethod: LoginMethodName; }) => void;}): { linkEmail: () => void; linkGoogle: () => void; linkApple: () => void; linkKakao: () => void; linkNaver: () => void; linkPhone: (..._args: unknown[]) => void; linkWallet: (..._args: unknown[]) => void; linkTwitter: (..._args: unknown[]) => void; linkDiscord: (..._args: unknown[]) => void; linkGithub: (..._args: unknown[]) => void; linkLinkedIn: (..._args: unknown[]) => void; linkTiktok: (..._args: unknown[]) => void; linkLine: (..._args: unknown[]) => void; linkSpotify: (..._args: unknown[]) => void; linkInstagram: (..._args: unknown[]) => void; linkFarcaster: (..._args: unknown[]) => void; linkTelegram: (..._args: unknown[]) => void; linkPasskey: () => void;};LinkAccountSuccess
섹션 제목: “LinkAccountSuccess”interface · react/hooks.d.ts
interface LinkAccountSuccess { user: User; linkMethod: LoginMethodName; linkedAccount: LinkedAccount | null;}useLoginWithPasskey
섹션 제목: “useLoginWithPasskey”function · react/hooks.d.ts
Privy useLoginWithPasskey: sign in with a passkey registered for this app (server-verified WebAuthn, discoverable
credential, no username). Register one with useLinkAccount().linkPasskey() while signed in.
function useLoginWithPasskey(callbacks?: { onComplete?: (params: LoginCompleteParams) => void; onError?: (error: NcWaasError) => void;}): { loginWithPasskey: () => Promise<void>; state: { status: "initial" | "generating-challenge" | "done" | "error"; error?: NcWaasError; };};useSignupWithPasskey
섹션 제목: “useSignupWithPasskey”function · react/hooks.d.ts
Privy useSignupWithPasskey. A Pouchi wallet needs an account identity (email or a social login) for recovery
notices, so passkey-only signup is refused; sign up with email or a social account and
add a passkey with linkPasskey().
function useSignupWithPasskey(callbacks?: { onError?: (error: NcWaasError) => void;}): { signupWithPasskey: () => Promise<never>; state: { status: "initial"; };};지갑과 트랜잭션
섹션 제목: “지갑과 트랜잭션”useWallets
섹션 제목: “useWallets”function · react/hooks.d.ts
function useWallets(): { ready: boolean; wallets: ConnectedWallet[];};ConnectedWallet
섹션 제목: “ConnectedWallet”interface · react/hooks.d.ts
interface ConnectedWallet { address: Hex; /** Privy v3: the chain family. Pouchi wallets are always "ethereum" (EVM smart wallets); "solana" is in the type only so Privy code that branches on it compiles. */ type: "ethereum" | "solana"; walletIndex: 0; /** CAIP-2, for example `eip155:450815`. */ chainId: string; walletClientType: "privy"; connectorType: "embedded"; imported: false; linked: true; meta: { name: string; id: string; icon?: string; }; getEthereumProvider(): Promise<NcWaasEthereumProvider>; /** Privy alias of getEthereumProvider. Raw-hash signing (secp256k1_sign) is refused with 4200. */ getProvider(): Promise<NcWaasEthereumProvider>; switchChain(chainId: number | `0x${string}`): Promise<void>; isConnected(): Promise<boolean>; disconnect(): void; /** Privy `wallet.sign(message)`: an ERC-1271 owner signature (WaaSWallet 4.1.0+). */ sign(message: string): Promise<Hex>;}getEthereumProviderFor
섹션 제목: “getEthereumProviderFor”function · react/hooks.d.ts
One EIP-1193 provider per controller, shared by every wallet object.
function getEthereumProviderFor(core: NcWaasCore): NcWaasEthereumProvider;useSendTransaction
섹션 제목: “useSendTransaction”function · react/hooks.d.ts
function useSendTransaction(callbacks?: { onSuccess?: (result: { hash: Hex; }) => void; onError?: (error: NcWaasError) => void;}): { sendTransaction: (input: UnsignedTransactionRequest, options?: SendTransactionOptions) => Promise<{ hash: Hex; } & Omit<SendTransactionResult, "hash">>;};SendTransactionOptions
섹션 제목: “SendTransactionOptions”interface · react/hooks.d.ts
interface SendTransactionOptions { /** Privy-compatible. Sponsorship follows the tenant policy; `false` is not honored yet. */ sponsor?: boolean; uiOptions?: { header?: string; description?: string; buttonText?: string; showWalletUIs?: boolean; }; address?: string;}useSignMessage
섹션 제목: “useSignMessage”function · react/hooks.d.ts
Privy useSignMessage: an ERC-1271 signature the wallet contract verifies
(isValidSignature, WaaSWallet 4.1.0+). The approval modal shows Pouchi’s decoding of the
message (SIWE, plain text, or opaque data) and its risk flags before PIN or passkey.
function useSignMessage(callbacks?: { onSuccess?: (result: { signature: Hex; }) => void; onError?: (error: NcWaasError) => void;}): { signMessage: (input: { message: string; }, _options?: unknown) => Promise<{ signature: Hex; }>;};useSignTypedData
섹션 제목: “useSignTypedData”function · react/hooks.d.ts
Privy useSignTypedData (EIP-712): permits, Permit2, marketplace orders. High-risk requests need an explicit confirmation.
function useSignTypedData(callbacks?: { onSuccess?: (result: { signature: Hex; }) => void; onError?: (error: NcWaasError) => void;}): { signTypedData: (typedData: WaasTypedDataInput | string, _options?: unknown) => Promise<{ signature: Hex; }>;};useSendCalls
섹션 제목: “useSendCalls”function · react/hooks.d.ts
Atomic batches (EIP-5792 wallet_sendCalls): one approval, executed together by the wallet contract; if one call
fails, none happen. Up to 8 calls. Returns the bundle id (for getCallsStatus) and the transaction hash.
function useSendCalls(callbacks?: { onSuccess?: (result: { id: string; hash: Hex; }) => void; onError?: (error: NcWaasError) => void;}): { sendCalls: (input: { calls: UnsignedTransactionRequest[]; }) => Promise<SendTransactionResult & { id: string; }>; getCallsStatus: (id: string) => Promise<import("../types").CallsStatus>;};useSmartWallets
섹션 제목: “useSmartWallets”function · react/hooks.d.ts
Privy useSmartWallets() (@privy-io/react-auth/smart-wallets). The Pouchi wallet is itself an ERC-4337 smart
wallet, so client.sendTransaction({ calls }) is an atomic batch and a single { to, value, data } is a normal
transaction. Resolves to the transaction hash, as in Privy.
function useSmartWallets(): { client: { account: { address: `0x${string}`; }; chain: import("viem").Chain; sendTransaction: (input: (UnsignedTransactionRequest | { calls: UnsignedTransactionRequest[]; }) & { chain?: unknown; account?: unknown; }, _options?: unknown) => Promise<Hex>; signMessage: (input: { message: string; }) => Promise<`0x${string}`>; signTypedData: (typedData: WaasTypedDataInput | string) => Promise<`0x${string}`>; } | undefined; getClientForChain: ({ id }: { id: number; }) => Promise<{ account: { address: `0x${string}`; }; chain: import("viem").Chain; sendTransaction: (input: (UnsignedTransactionRequest | { calls: UnsignedTransactionRequest[]; }) & { chain?: unknown; account?: unknown; }, _options?: unknown) => Promise<Hex>; signMessage: (input: { message: string; }) => Promise<`0x${string}`>; signTypedData: (typedData: WaasTypedDataInput | string) => Promise<`0x${string}`>; } | undefined>;};TransactionProposer
섹션 제목: “TransactionProposer”type · types.d.ts
type TransactionProposer = (input: TransactionProposalInput) => Promise<{ signingRequestId: string;}>;TransactionProposalInput
섹션 제목: “TransactionProposalInput”interface · types.d.ts
Input passed to an optional tenant-backend transaction proposer. General contract calls use the configured proposer; without it, the signed-in user may propose calls within the app’s user-call policy. Native and recognized supported-token transfers bypass this hook. See the server integration guide for the bounded example.
interface TransactionProposalInput { tenantId: string; walletId: string; walletAddress: Hex; chainId: number; to: Hex; value: string; data: Hex; /** App access token (ES256 JWT) for the backend to verify with `verifyAuthToken`. Never the Pouchi session. */ accessToken: string;}UnsignedTransactionRequest
섹션 제목: “UnsignedTransactionRequest”interface · types.d.ts
interface UnsignedTransactionRequest { /** A 0x address. Privy types this as a plain string, so a string is accepted and checked at runtime. */ to?: Hex | (string & {}); from?: Hex; value?: bigint | number | string | Hex; data?: Hex; chainId?: number | Hex; gas?: bigint | number | string | Hex; gasLimit?: bigint | number | string | Hex; maxFeePerGas?: bigint | number | string | Hex; maxPriorityFeePerGas?: bigint | number | string | Hex; nonce?: number | Hex;}SendTransactionResult
섹션 제목: “SendTransactionResult”interface · types.d.ts
interface SendTransactionResult { hash: Hex; /** Pouchi specific: the ERC-4337 user operation hash and the API operation id. */ userOperationHash?: Hex; operationId?: string; sponsored: boolean;}세션 승인
섹션 제목: “세션 승인”useSessionApproval
섹션 제목: “useSessionApproval”function · react/hooks.d.ts
Approve once with PIN or passkey, then confirm transactions inside the session with one tap.
Requires config.approvals.session. The limits live in an owner-signed WaaSWallet policy,
so the contract enforces them whatever this UI does.
function useSessionApproval(): { session: import("../session-approvals").SessionApprovalState | null; active: boolean; startSession: (input: StartSessionInput) => Promise<import("../session-approvals").SessionApprovalState>; endSession: () => void;};StartSessionInput
섹션 제목: “StartSessionInput”interface · session-approvals.d.ts
interface StartSessionInput { durationSeconds?: number; /** Total native value the session may move, decimal wei. "0" for calls without value. */ maxTotalValueWei: string; /** Per-call native value cap, decimal wei. Defaults to the total. */ maxValuePerCallWei?: string; maxCalls: number; contracts?: SessionPermissionInput[]; /** Addresses that may receive plain native transfers. */ nativeRecipients?: Hex[];}SessionApprovalConfig
섹션 제목: “SessionApprovalConfig”interface · session-approvals.d.ts
interface SessionApprovalConfig { /** Client registered by the tenant (`/v1/tenant/client-authorization-clients`, web channel). */ clientId: string; clientName?: string; /** Must equal one of the client's registered webApprovalUris. Defaults to `${origin}/`. */ approvalUri?: string; defaultDurationSeconds?: number;}SessionApprovalState
섹션 제목: “SessionApprovalState”interface · session-approvals.d.ts
interface SessionApprovalState { policyId: string; expiresAt: number; maxValuePerCallWei: string; valueAllowanceWei: string; spentWei: string; callsRemaining: number; permissions: SessionPermission[];}복구와 기기
섹션 제목: “복구와 기기”useWalletRecovery
섹션 제목: “useWalletRecovery”function · react/hooks.d.ts
Moving the wallet to this device and watching recoveries.
open() shows the sheet: approve from the old device, or use the account recovery flow with a passkey or recovery code.
function useWalletRecovery(): { /** This device can sign; when false, `open()` moves the wallet here. */ canSign: boolean; /** A recovery of this wallet that is waiting or running, on any device. */ pending: import("../types").WalletRecoveryState | null; open: () => void; cancel: () => Promise<void>;};useRecoverWallet
섹션 제목: “useRecoverWallet”function · react/hooks.d.ts
Alias in Privy-style naming.
const useRecoverWallet: typeof useWalletRecovery;useRecoveryBackups
섹션 제목: “useRecoveryBackups”function · react/hooks.d.ts
Account recovery uses a passkey or recovery code, configured once in Pouchi Home. The API snapshot below retains legacy backup fields. Passkey entries carry only ciphertext. App code never accesses key material; key-share operations stay inside the Pouchi vault frame.
function useRecoveryBackups(): { list: () => Promise<import("../core").RecoveryBackupSummary[]>; remove: (backupId: string) => Promise<void>; passkeySupported: () => Promise<boolean>; googleDriveAvailable: boolean;};useSessions
섹션 제목: “useSessions”function · react/devices.d.ts
The wallet’s signed-in devices (spec §4.7). Each device keeps its own session; signing still needs that device’s key
share and PIN or passkey. revoke(deviceId) signs another device out (it must sign in again).
function useSessions(options?: { auto?: boolean;}): { devices: SignedInDevice[]; maxDevices: number | null; loading: boolean; error: string | undefined; refresh: () => Promise<SignedInDevice[]>; revoke: (deviceId: string | null) => Promise<void>;};useRevokeSession
섹션 제목: “useRevokeSession”function · react/devices.d.ts
Signs one other device out (Privy-style naming).
function useRevokeSession(): { revokeSession: (deviceId: string | null) => Promise<void>;};LoggedInDevices
섹션 제목: “LoggedInDevices”function · react/devices.d.ts
A small “signed-in devices” list for a settings screen, in the modal’s look.
function LoggedInDevices({ theme }: { theme?: "light" | "dark" | "auto";}): import("react").JSX.Element | null;Privy 자산 이전
섹션 제목: “Privy 자산 이전”AssetMigrationCard
섹션 제목: “AssetMigrationCard”function · react/migration-card.d.ts
Minimal, unstyled-by-default card using the modal tokens; apps can build their own with the hook.
function AssetMigrationCard({ oldProvider, tokens }: { oldProvider: Eip1193Like | undefined; tokens?: MigrationToken[];}): import("react").JSX.Element | null;useAssetMigration
섹션 제목: “useAssetMigration”function · react/migration-card.d.ts
Plans and runs the move from an old wallet (for example the Privy embedded wallet’s
getEthereumProvider()) to the signed-in Pouchi wallet. The old wallet signs each step.
function useAssetMigration(options?: { tokens?: MigrationToken[];}): { destination: `0x${string}` | undefined; plan: MigrationPlan | null; results: MigrationStepResult[]; status: "error" | "done" | "ready" | "idle" | "planning" | "migrating"; error: string | undefined; prepare: (oldProvider: Eip1193Like) => Promise<MigrationPlan>; migrate: (oldProvider: Eip1193Like) => Promise<MigrationStepResult[]>;};Privy 호환 이름 (일부 거절)
섹션 제목: “Privy 호환 이름 (일부 거절)”Privy 이전에 필요한 일부 호환 이름을 제공합니다. 지원 표와 다른 동작을 먼저 확인하세요. 모델이 다른 기능은 호출하면 NOT_SUPPORTED(EIP-1193 4200)로 거절합니다.
useCreateWallet
섹션 제목: “useCreateWallet”function · react/privy-compat.d.ts
Privy useCreateWallet: the wallet already exists after first login; one wallet for the user in the current app context.
function useCreateWallet(callbacks?: { onSuccess?: (result: { wallet: UserWallet; }) => void; onError?: (error: NcWaasError) => void;}): { createWallet: (options?: { createAdditional?: boolean; walletIndex?: number; }) => Promise<UserWallet>;};useSolanaWallets
섹션 제목: “useSolanaWallets”function · react/privy-compat.d.ts
Privy useSolanaWallets: Pouchi wallets are Ethereum (EVM) only.
function useSolanaWallets(): { ready: boolean; wallets: Array<{ address: string; walletClientType: string; connectorType?: string; imported?: boolean; }>; createWallet: (..._args: unknown[]) => Promise<never>; exportWallet: (..._args: unknown[]) => Promise<never>;};useSignTransaction
섹션 제목: “useSignTransaction”function · react/privy-compat.d.ts
Privy useSignTransaction: an ERC-4337 smart wallet has no raw signed transaction to return. Use
useSendTransaction (signs and submits a user operation) instead.
function useSignTransaction(callbacks?: { onError?: (error: NcWaasError) => void;}): { signTransaction: (_input: UnsignedTransactionRequest, _options?: unknown) => Promise<string>;};useFundWallet
섹션 제목: “useFundWallet”function · react/privy-compat.d.ts
Privy useFundWallet: on-ramp and bridging are not part of Pouchi; fund the wallet address directly.
function useFundWallet(callbacks?: { onUserExited?: (params: unknown) => void;}): { fundWallet: FundWallet;};useCrossAppAccounts
섹션 제목: “useCrossAppAccounts”function · react/privy-compat.d.ts
Privy useCrossAppAccounts.
function useCrossAppAccounts(): { linkCrossAppAccount: (_input: { appId: string; }) => Promise<never>; loginWithCrossAppAccount: (_input: { appId: string; }) => Promise<never>; sendTransaction: (..._args: unknown[]) => Promise<never>; signMessage: (..._args: unknown[]) => Promise<never>; signTypedData: (..._args: unknown[]) => Promise<never>;};useSessionSigners
섹션 제목: “useSessionSigners”function · react/privy-compat.d.ts
Privy useSessionSigners (server-side delegated signing). Pouchi delegates through owner-signed, contract-
enforced policies instead: useSessionApproval for one-tap sessions, or agent permissions from the tenant backend.
function useSessionSigners(): { addSessionSigners: (_input: { address: string; signers: Array<{ signerId: string; policyIds?: string[]; }>; }) => Promise<never>; removeSessionSigners: (_input: { address: string; }) => Promise<never>;};useImportWallet
섹션 제목: “useImportWallet”function · react/privy-compat.d.ts
Privy useImportWallet: Pouchi never takes a raw private key; its key is generated 2-of-3 and never assembled.
function useImportWallet(): { importWallet: (_input: { privateKey: string; }) => Promise<never>;};useMfaEnrollment
섹션 제목: “useMfaEnrollment”function · react/privy-compat.d.ts
Privy useMfaEnrollment: Pouchi approval uses user authentication (such as a passkey or PIN).
function useMfaEnrollment(): { initEnrollmentWithSms: (..._args: unknown[]) => Promise<never>; submitEnrollmentWithSms: (..._args: unknown[]) => Promise<never>; initEnrollmentWithTotp: (..._args: unknown[]) => Promise<never>; submitEnrollmentWithTotp: (..._args: unknown[]) => Promise<never>; initEnrollmentWithPasskey: (..._args: unknown[]) => Promise<never>; submitEnrollmentWithPasskey: (..._args: unknown[]) => Promise<never>; showMfaEnrollmentModal: () => never; closeMfaEnrollmentModal: () => undefined;};useMfa
섹션 제목: “useMfa”function · react/privy-compat.d.ts
Privy useMfa (no separate MFA step in Pouchi).
function useMfa(): { mfaMethods: string[]; init: (..._args: unknown[]) => Promise<never>; submit: (..._args: unknown[]) => Promise<never>; cancel: () => undefined;};고급: 컨트롤러
섹션 제목: “고급: 컨트롤러”useNcWaas
섹션 제목: “useNcWaas”function · react/provider.d.ts
The controller, for custom UIs (headless login and approval).
function useNcWaas(): NcWaasCore;useNcWaasState
섹션 제목: “useNcWaasState”function · react/provider.d.ts
The raw controller state. Prefer the Privy-compatible hooks for app code.
function useNcWaasState(): NcWaasState;NcWaasError
섹션 제목: “NcWaasError”class · errors.d.ts
class NcWaasError extends Error { readonly code: NcWaasErrorCode; /** EIP-1193 numeric code. Wallet libraries read this as `error.code` via `toRpcError`. */ readonly rpcCode: number; /** Underlying API error code when the error came from the Pouchi API. */ readonly apiCode?: string; readonly status?: number; readonly data?: unknown; constructor(code: NcWaasErrorCode, message: string, options?: { apiCode?: string; status?: number; data?: unknown; cause?: unknown; });}NcWaasErrorCode
섹션 제목: “NcWaasErrorCode”type · errors.d.ts
Errors surfaced by @shard-lab/nc-waas-react.
Every error carries a stable string code (for app logic) and, where it maps to
EIP-1193, a numeric rpcCode so wallet libraries such as viem and wagmi classify
it correctly (4001 user rejected, 4100 unauthorized, 4200 unsupported method,
4900 disconnected, 4901 chain disconnected).
type NcWaasErrorCode = "NOT_READY" | "NOT_AUTHENTICATED" | "USER_REJECTED" | "NOT_SUPPORTED" | "UNSUPPORTED_METHOD" | "UNSUPPORTED_CHAIN" | "INVALID_PARAMS" | "WALLET_NOT_READY" | "LOCAL_KEY_SHARE_MISSING" | "TRANSACTION_PROPOSER_REQUIRED" | "TRANSACTION_TIMEOUT" | "LOGIN_FLOW_INVALID" | "TOKEN_INVALID" | "UNSUPPORTED_CAPABILITY" | "API_ERROR";@shard-lab/nc-waas-react/server
섹션 제목: “@shard-lab/nc-waas-react/server”서버 전용입니다. 브라우저 번들에 넣지 않습니다.
createNcWaasServerClient
섹션 제목: “createNcWaasServerClient”function · server.d.ts
Privy new PrivyClient(...) counterpart.
function createNcWaasServerClient(options: NcWaasServerOptions): NcWaasServerClient;NcWaasServerClient
섹션 제목: “NcWaasServerClient”class · server.d.ts
class NcWaasServerClient { constructor(options: NcWaasServerOptions); /** * Verifies an access token from `getAccessToken()` and returns who it belongs to. * JWTs are verified offline (signature, issuer, audience = this tenant's app, expiry). * Legacy session tokens fall back to introspection, which needs a credential. * Anything else throws `TOKEN_INVALID`. */ verifyAuthToken(token: string): Promise<NcWaasAuthTokenClaims>; /** `@privy-io/node` shape: `privy.utils().auth().verifyAccessToken({ access_token })`. */ utils(): { auth: () => { verifyAccessToken: ({ access_token }: { access_token: string; }) => Promise<NcWaasAuthTokenClaims>; }; }; /** * Creates the owner signing request for a contract call that the user then approves in the * browser. Optional: frontends can propose calls themselves within the tenant's policy. */ proposeTransaction(input: ProposeTransactionInput): Promise<{ signingRequestId: string; }>; /** The tenant's wallet by id (`wallets:read`): address, chain, status. No email or other login data. */ getWallet(walletId: string): Promise<TenantWallet>; /** The tenant's user with this email login (`wallets:read`), or null. The match ignores case and surrounding spaces. */ findUserByEmail(email: string): Promise<TenantUser | null>; /** The tenant's user with this wallet address (`wallets:read`), or null. */ findUserByWalletAddress(address: string): Promise<TenantUser | null>;}NcWaasServerOptions
섹션 제목: “NcWaasServerOptions”interface · server.d.ts
interface NcWaasServerOptions { apiUrl: string; tenantId: string; /** Tenant Client Credential. Only for introspection, wallet reads and user lookups (`wallets:read`) and `proposeTransaction` (`owner-intents:create`). */ credentialId?: string; clientSecret?: string; scopes?: Array<"wallets:read" | "owner-intents:create" | "user-intents:create" | "sponsorship:request">; /** Client Credential token audience. Defaults to the API origin. */ audience?: string; /** Expected JWT issuer. Defaults to "urn:nc-waas". */ issuer?: string; /** Defaults to `${apiUrl}/.well-known/jwks.json`. */ jwksUrl?: string; /** Allowed clock skew. Default 30 s. */ clockToleranceSeconds?: number; fetch?: typeof fetch; now?: () => number;}NcWaasAuthTokenClaims
섹션 제목: “NcWaasAuthTokenClaims”interface · server.d.ts
Verified claims. userId equals the browser user.id.
interface NcWaasAuthTokenClaims { appId: string; tenantId: string; tenantInstanceId?: string; userId: string; walletId: string; walletAddress: Hex; chainId: number; sessionId: string; issuer: string; /** Unix seconds. */ issuedAt: number; /** Unix seconds. */ expiration: number; authenticationMethod: string;}ProposeTransactionInput
섹션 제목: “ProposeTransactionInput”interface · server.d.ts
interface ProposeTransactionInput { walletId: string; to: Hex; value: string; data: Hex; title: string; description?: string; requester: { appName: string; origin: string; }; risk?: "low" | "medium" | "high";}linkPrivyUser
섹션 제목: “linkPrivyUser”function · server.d.ts
Builds the user-id mapping record for a dual-login migration. Call it only after verifying
BOTH tokens in the same request: the Privy token with Privy’s own verifier, the Pouchi
token with verifyAuthToken. Linking by email alone would let anyone who controls an
email claim another account. Store the record in your user table.
function linkPrivyUser(input: { privyClaims: { userId: string; }; ncWaasClaims: NcWaasAuthTokenClaims; oldAddress?: string; now?: Date;}): PrivyUserLink;PrivyUserLink
섹션 제목: “PrivyUserLink”interface · server.d.ts
interface PrivyUserLink { privyUserId: string; ncWaasUserId: string; tenantId: string; walletId: string; oldAddress?: Hex; newAddress: Hex; linkedAt: string;}@shard-lab/nc-waas-react/wagmi
섹션 제목: “@shard-lab/nc-waas-react/wagmi”ncWaasConnector
섹션 제목: “ncWaasConnector”function · wagmi.d.ts
function ncWaasConnector(options?: NcWaasConnectorOptions): (config: { emitter: WagmiConnectorEmitter;}) => NcWaasWagmiConnector;NcWaasConnectorOptions
섹션 제목: “NcWaasConnectorOptions”interface · wagmi.d.ts
interface NcWaasConnectorOptions { /** Defaults to the controller of the mounted provider. */ core?: NcWaasCore; name?: string; icon?: string;}