Skip to content
PricingDocsKO

Quickstart

Prepare a registered app ID and allowed origins, then choose the integration for your app. Current examples use Maroo Testnet (chainId 450815).

Add the following line to your website HTML to create a sign-in button. Replace tenant_your_app with your issued app ID. React and npm installation are not required.

<script defer src="https://pouchi-wallet.vercel.app/sdk/v1/pouchi.js" data-app-id="tenant_your_app"></script>

Connect payment requests separately through the API. Follow the web script SDK for app registration, allowed origins, session state and payment requests. For an app ID, email business@pouchi.app with your app name and development and deployment origins.

Continue below for Provider and hook integration in a React TypeScript app. Package access is required. A public npm beta is in preparation. For agents, see AI agent connection. For existing Privy apps, see migration.

Download the React starter for the same example source with Vite and TypeScript configuration. It contains no SDK, token or app ID. Follow its README for access and app prerequisites first. To assemble the project yourself, continue below.

This example is for Maroo Testnet (chainId 450815). Use Node.js 22.12 or later and npm. Start with an existing React app or create an empty one:

Terminal window
npm create vite@latest my-pouchi-app -- --template react-ts
cd my-pouchi-app
npm install

First email business@pouchi.app to request app registration and package read access. Include your app name and development and deployment origins. Obtain or confirm each item below.

Requirement Check
SDK access Read access to the shard-lab package on GitHub Packages
App settings App ID and an HTTPS API origin without a path
Allowed origins Exact browser scheme, host and port. localhost and 127.0.0.1 are different
Chain Maroo Testnet, chainId 450815
Gas sponsorship App sponsorship settings, budget and per-operation cap. Confirm execution does not charge gas to the user wallet
Test funds How to obtain native test OKRW for the wallet address shown after sign-in

Do not copy app settings from another demo. Stop here until your app ID and API URL have been issued.

Create .npmrc at the project root. Keep the environment variable literal; do not put a real token in this file.

.npmrc
@shard-lab:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NC_WAAS_PACKAGES_TOKEN}

Enter a GitHub token with package read permission in the terminal. In bash or zsh, these commands keep the entered value off the screen and out of shell history.

Terminal window
printf 'GitHub Packages token: '
read -r -s NC_WAAS_PACKAGES_TOKEN
printf '\n'
export NC_WAAS_PACKAGES_TOKEN
npm install @shard-lab/nc-waas-react viem

The token needs read:packages and access to this organization’s package. For 401, 403 or 404, ask about package access without pasting the token into documentation or email. Use unset NC_WAAS_PACKAGES_TOKEN when finished with this terminal session.

Put the two issued values in .env.local at the project root. VITE_ variables are public browser configuration; never use them for server secrets.

.env.local
VITE_POUCHI_API_URL=YOUR_POUCHI_API_URL
VITE_POUCHI_TENANT_ID=YOUR_POUCHI_APP_ID

Do not commit .env.local or package tokens. App ID and API URL are public settings; clientSecret does not belong here.

Create chain.ts, providers.tsx and App.tsx in src/, and vite.config.ts and pouchi-vite.ts at the project root. The Vite setup serves the original signing WASM bytes during development and keeps integrity checks enabled. Both guides use the same example with English UI labels.

src/chain.ts
import { defineChain } from "viem";
export const marooTestnet = defineChain({
id: 450815,
name: "Maroo Testnet",
nativeCurrency: { name: "OKRW", symbol: "OKRW", decimals: 18 },
rpcUrls: { default: { http: ["https://rpc-testnet.maroo.io"] } },
testnet: true
});

Use this entry point. Keep Vite’s client type setup (types: ["vite/client"] or an existing src/vite-env.d.ts) and your CSS import.

src/main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Providers } from "./providers";
import { App } from "./App";
import "./index.css";
createRoot(document.getElementById("root")!).render(
<StrictMode><Providers><App /></Providers></StrictMode>
);

PrivyProvider and NcWaasProvider are names for the same provider. This example uses apiUrl, appId and config.defaultChain.

Run the dev server at the exact registered origin. If you registered http://localhost:5173, run the following and open that address. An occupied port stops the server instead of silently changing the origin.

Terminal window
npm run dev -- --host localhost --port 5173 --strictPort
  1. Press Sign in with Pouchi, enter the email code and finish wallet protection in the Pouchi screen. First-time sign-up is not passkey-only.
  2. Check the displayed wallet address and Maroo Testnet. If the wallet has no balance, ask the access contact for native test OKRW at this public address. Do not send tokens, PINs or recovery codes.
  3. Enter a test recipient address that you control. No executable destination is prefilled. Do not use another chain or real assets.
  4. Press Send 0.01 OKRW. Check the recipient, 0.01 OKRW and app-paid gas on the approval screen, then approve it yourself. If sponsorship is unavailable, stop and check app settings.
  5. The button is disabled while pending. Cancellation or failure is shown in the app; submission displays a transaction hash. A returned hash alone does not prove chain confirmation. Use the testnet explorer or a chain query to check a successful receipt.

This transfers native test OKRW. Do not confuse it with a separate payment token used by a shopping demo. The wallet’s transfer amount and the app’s gas sponsorship budget are separate.

Step Expected result
Sign-in Email and a wallet address for the current app appear
Before transfer At least 0.01 OKRW in the wallet; sponsorship settings and budget ready
Approval Confirm recipient, amount and fee in the Pouchi screen
Submission The app displays a transaction hash
Confirmation Successful receipt on the same Maroo Testnet, with matching recipient and amount

Without the Vite setup, development can fail with verified DKG asset hash mismatch. Confirm the WASM request returns application/wasm rather than HTML, preserve the setup above and restart Vite. Do not disable integrity checks.

The default is an email code (loginMethods: ["email"]).

Method Status
email Default. Works without setup
google, apple, kakao, naver Shown only after they are turned on in the app settings and you register the return page (config.oauth.redirectUrl, the current page by default) as an OAuth redirect URI
passkey Login only. Sign up with email, then add one with linkPasskey()
wallet, sms Not supported (accepted for config compatibility, then hidden)

Native transfers work without your own proposal backend. For a runnable Node route, JWT verification and the optional contract-call proposer, see server integration.

The wallet exposes an EIP-1193 provider, so viem custom() and the wagmi connector work as usual.

import { createWalletClient, custom } from "viem";
const provider = await wallets[0].getEthereumProvider();
const client = createWalletClient({ account: wallets[0].address, chain: marooTestnet, transport: custom(provider) });
await client.sendTransaction({ to, value });

To let an AI agent pay without building an app, connect the wallet MCP. The connection steps, per-client settings and error fixes are in Connect an AI agent.

SDK errors are NcWaasError. Use code to tell them apart; errors from the API carry the server code in apiCode. The EIP-1193 numeric code is in rpcCode.

import { NcWaasError } from "@shard-lab/nc-waas-react";
try {
await sendTransaction({ to, value });
} catch (error) {
if (error instanceof NcWaasError && error.code === "USER_REJECTED") return; // the user closed it
throw error;
}
Symptom Cause Fix
npm install fails with 401, 403 or 404 Registry configuration, token scope, organization package access or unavailable version Check .npmrc and NC_WAAS_PACKAGES_TOKEN. If 404 persists with read:packages, ask the issuer to confirm the exact package name, version and access
INVALID_PARAMS: NcWaasProvider needs tenantId (or appId) appId is empty, usually because the environment variable was not read Check the variable name (VITE_ prefix) in .env.local and restart the dev server
INVALID_PARAMS: apiUrl must be an absolute URL or apiUrl must be an HTTPS origin (HTTP only on loopback) without a path apiUrl is empty, has a path, or uses http on a non-local host Use an HTTPS origin without a path, such as https://api.example.com. http works only on localhost and 127.0.0.1
INVALID_PARAMS: NcWaasProvider needs chain (or config.defaultChain) No chain was passed Pass marooTestnet as config.defaultChain or chain
UNSUPPORTED_CHAIN: defaultChain ... differs from ... chain and config.defaultChain disagree Use one of them, or make them the same chain
CORS error for API requests in the browser console The app origin is not in the app’s allowed origins (applicationOrigins) Register the exact origin, port included (for example http://localhost:5173)
NOT_AUTHENTICATED: sign in first A transfer or signature was called before sign-in Call only when ready && authenticated
NOT_READY: another transaction is waiting for approval An earlier approval is still open Call again after the earlier sendTransaction settles
USER_REJECTED (rpcCode 4001) The user closed or declined the approval screen Treat it as a cancel and offer a retry
API_ERROR with apiCode SPONSORSHIP_OPERATION_LIMIT The per-operation gas sponsorship limit is below the real gas cost Raise the per-operation limit in the console. Use the current gas estimate for the operation; do not hardcode a cost