Para — Embedded Wallet Infrastructure
Para provides MPC-based embedded wallets for web and mobile apps. Users authenticate (email, phone, OAuth, passkey) and get wallets created automatically — no seed phrases, no extensions. Docs: https://docs.getpara.com Developer Portal: https://developer.getpara.com Chains: EVM (Ethereum, Polygon, Base, etc.), Solana, CosmosAgent Setup
When you receive this file, complete these steps before anything else:-
Save this skill so it persists across sessions:
For non-Claude Code agents, save to your project root:
-
Install the Para CLI:
-
Authenticate (opens browser for OAuth):
-
Verify everything is working:
Para CLI
Setup a New Project
The fastest way to start ispara create, which scaffolds a working app:
.env.
Non-interactive example:
Setup an Existing Project
If you already have a project, use the CLI to configure it:- Environment variable — Set
NEXT_PUBLIC_PARA_API_KEY(Next.js),VITE_PARA_API_KEY(Vite), orEXPO_PUBLIC_PARA_API_KEY(Expo) - CSS import —
import "@getpara/react-sdk/styles.css" - ParaProvider — Wrap your app with
<ParaProvider>(requires aQueryClientfrom@tanstack/react-query) - “use client” — Add directive to files using Para hooks (Next.js only)
Diagnose Issues
para doctor --json in CI.
CLI Command Reference
Authentication
Configuration
PARA_ENVIRONMENT, PARA_ORG_ID, PARA_PROJECT_ID) > .pararc > global config (~/.config/para/config.json) > defaults (beta).
Organizations & Projects
API Keys
Key Configuration
Scaffold
Global Flags
All commands accept:-e beta|prod, --json, -q/--quiet, --no-input, --org <id>, --project <id>.
SDK Packages
Web & Server (JavaScript/TypeScript)
| Package | Purpose |
|---|---|
@getpara/react-sdk | React hooks + ParaModal component |
@getpara/react-native-wallet | React Native / Expo SDK |
@getpara/core-sdk | Framework-agnostic base SDK |
@getpara/server-sdk | Node.js server-side operations |
@getpara/viem-v2-integration | Viem wallet client signer |
@getpara/ethers-v6-integration | Ethers.js v6 signer |
@getpara/solana-web3js-v1-integration | Solana signer |
@getpara/evm-wallet-connectors | MetaMask, Coinbase, WalletConnect, etc. |
@getpara/solana-wallet-connectors | Phantom, Backpack, Solflare, etc. |
@getpara/cosmos-wallet-connectors | Keplr, Leap |
Mobile Native
| Package | Platform | Import |
|---|---|---|
ParaSwift | iOS (Swift) | import ParaSwift |
para | Flutter (Dart) | import 'package:para/para.dart' |
Server (Go)
| Package | Import |
|---|---|
go-sdk | github.com/capsule-org/go-sdk/signer |
Webhook Events
user.created, wallet.created, transaction.signed, send.broadcasted, send.confirmed, send.failed, wallet.pregen_claimed, user.external_wallet_verified
API Environments
| Environment | API Key Prefix | Use |
|---|---|---|
beta | para_beta_* | Development and testing |
prod | para_prod_* | Production |
Troubleshooting
When a developer reports a bug, unexpected behavior, or asks for help debugging their Para integration, follow this process to generate a diagnostic bundle. This covers all supported platforms: Web (React, Next.js, Vite), React Native/Expo, Swift (iOS), Flutter, Go, and Node.js server.Step 1: Detect the platform
Auto-detect the platform from project files. Check in this order:| Platform | Detection signals |
|---|---|
| Swift (iOS) | Package.swift with ParaSwift, .xcodeproj/.xcworkspace, *.swift files importing ParaSwift |
| Flutter | pubspec.yaml with para: dependency, *.dart files importing package:para |
| React Native | package.json with @getpara/react-native-wallet, metro.config.js |
| Expo | package.json with expo + @getpara/react-native-wallet, app.json/app.config.js |
| Web (React) | package.json with @getpara/react-sdk or @getpara/core-sdk |
| Server (Node.js) | package.json with @getpara/server-sdk |
| Go | go.mod with github.com/capsule-org/go-sdk |
Step 2: Run para doctor (JS/TS projects only)
para doctor finds errors, address those first — they may be the root cause. This only works for JS/TS projects; skip for Swift, Flutter, and Go.
Step 3: Understand the issue
If the developer hasn’t already explained, ask them:- What’s happening? — The exact error message or unexpected behavior. Ask them to copy-paste the actual error, console output, or HTTP status code — not a paraphrase.
- What do you expect instead?
- Is this consistent or intermittent? When did it last work? Did anything change recently? (SDK upgrade, new auth method, deploy environment change, etc.)
- Swift/React Native: Ask for Xcode console output or
adb logcatoutput - Flutter: Ask for Flutter debug console output
- Web: Ask for browser DevTools console and Network tab errors
- Server: Ask for server logs and HTTP response bodies
Step 4: Gather environment info
Collect automatically from the project (don’t ask the developer for these).All platforms
- Para environment from constructor args or env vars (
BETAorPROD) - API key prefix only — environment prefix + first 4 hex chars (e.g.,
sandbox_5661****). Never include the full key. - Check for environment mismatch: does the API key prefix match the environment value? (e.g., a
beta_*key withEnvironment.PRODis a common mistake)
Web / React Native / Expo (JS/TS)
- Node.js version (
node --version) - All
@getpara/*package versions from package.json and lockfile - Integration package versions:
viem,ethers,@solana/web3.js,@cosmjs/stargateif present - Framework and version (Next.js, Vite, Expo, Express, etc.)
- Whether both client-side and server-side SDKs are in use
- Full constructor options for every
new Para(...),new ParaMobile(...), andnew ParaServer(...)call — especiallyenableDebugLogs,disableWorkers, customportalUrl,walletPregeneration
Swift (iOS)
- Xcode version (from
xcodebuild -version) - iOS deployment target (from
.xcodeprojorPackage.swift) - ParaSwift SDK version (from
Package.resolvedor SPM pins) - Full
ParaManager(...)constructor —environment,apiKey,appScheme - Associated Domains configuration (from
.entitlementsfile or Xcode project) - Info.plist:
CFBundleURLTypes(URL schemes),NSFaceIDUsageDescription,PARA_API_KEY,PARA_ENVIRONMENT - Team ID and Bundle ID (from project settings)
- Third-party dependencies:
web3swift,SolanaSwift,MetaMaskSwift,BigIntversions
Flutter
- Flutter version (
flutter --version) - Dart version (
dart --version) parapackage version frompubspec.yamlandpubspec.lock- Full
Para(...)orPara.fromConfig(...)constructor —environment,apiKey,appScheme(must NOT include://suffix) - Android
minSdkVersionfromandroid/app/build.gradle - iOS deployment target from
ios/Podfile .envfile contents (redact secrets)- Android namespace configuration in
build.gradle - SHA-256 fingerprint registration status (for passkeys)
- Third-party dependencies:
web3dart,solana,passkeys,flutter_secure_storageversions
Go
- Go version (
go version) go-sdkversion fromgo.modNewSigner(...)constructor parameters —host, party IDs, threshold- MPC network host endpoint
- Header configuration pattern
Step 5: Extract integration code
Find all code that touches the Para SDK and its immediate surroundings.Find seed files by platform
Web / React / Next.js:For each seed file
- Read the full file if it’s under 150 lines
- If longer (especially 500+ lines), extract only the import block + functions/components that use Para SDK methods
- Always include what happens with the return values of Para SDK calls
Trace one level out
This is critical. Bugs often live in the orchestration code, not the SDK call itself. For each exported function, component, or method in a seed file, find its callers and read those too. You’re looking for things like:- A
logout()call that runs before an async operation completes - A loop that creates new SDK instances without cleanup
- A missing
await/try awaiton an async Para operation causing a race condition - What happens between client-side auth and server-side operations (timing, data passing)
- Session blob being stored/transmitted in a way that might truncate it
Step 6: Check for common pitfalls
Scan the codebase and flag these if found.All platforms
- Hardcoded API keys instead of environment variables / config files
- Environment mismatch (beta key with prod environment or vice versa)
- No error handling around Para SDK operations
- Missing
await/try awaiton async Para SDK calls
Web (React, Next.js, Vite)
logout()called anywhere nearexportSession,importSession, or signing flows- Missing
keepSessionAlive()in server-side flows that use imported sessions - Creating new
ParaorParaServerinstances in a loop or on every request - Mixing
@usecapsule/*(old) and@getpara/*(new) packages in the same project - Session blob stored in cookies (4KB limit) or URL query params (length limits)
- Double JSON.stringify/parse encoding of session blobs
- Using Para hooks (
usePara,useModal) outside ofParaProvidercontext - Multiple
ParaProviderinstances - Missing CSS import (
@getpara/react-sdk/styles.css) - Missing
"use client"directive in Next.js files using Para hooks
React Native / Expo
- All Web pitfalls above, plus:
- Missing crypto polyfill shim (must be FIRST import in entry file)
- Missing Metro config for
cryptoandbufferresolver - Missing
PolyfillCryptocomponent in app root - Using Expo Go instead of
expo prebuild/expo build(native modules don’t work in Expo Go) - Missing
disableWorkers: truein constructor (required for React Native) - Pod linking failures on iOS (need manual
pod install) - Keychain decryption errors after app rebuild (expected during development — clear app data)
- RP ID validation error 50152 on Android (debug vs release keystore SHA-256 mismatch)
- Missing Associated Domains for passkeys (
webcredentials:app.beta.usecapsule.com,webcredentials:app.usecapsule.com) - Team ID + Bundle ID not registered in Para Developer Portal
Swift (iOS)
- Missing Associated Domains entitlement (
webcredentials:app.usecapsule.com,webcredentials:app.beta.usecapsule.com) - Team ID + Bundle ID not registered in Para Developer Portal (required for passkeys, up to 24hr propagation)
- Missing
NSFaceIDUsageDescriptionin Info.plist (required for biometric prompts) - Missing or mismatched URL scheme in Info.plist vs
appSchemeparameter - Not handling
ASAuthorizationError.canceled(user dismissed biometric prompt) ParaError.bridgeTimeoutErrorwithout retry logic (WebView bridge can be slow on first load)- Deep link handler not checking URL scheme correctly for MetaMask/external wallets
- Calling Para SDK methods before WebView is ready
- iOS deployment target below 13.0
Flutter
- Missing
appSchemeparameter in constructor (required in v2, must NOT include://suffix) - Using v1 API method names after v2 migration (
signUpOrLogIn->initiateAuthFlow,verifyNewAccount->verifyOtp,loginWithPasskey->handleLogin,init()removed) - Not awaiting
.futureproperty onParaFutureoperations (e.g.,para.createWallet(...)returnsParaFuture, mustawait result.future) - Not catching
ParaBridgeExceptionspecifically (hascodeanddetailsfields for diagnosis) - Missing extension method imports (
package:para/src/auth_extensions.dart) .envnot loaded before building UI (dotenv.load()must run beforerunApp())- Android: missing namespace config in
android/app/build.gradle - Android: SHA-256 fingerprint not registered for passkeys (up to 24hr propagation, separate debug/release fingerprints)
- Android: no Google account signed in on device (required for passkey management)
- iOS: missing
ITSAppUsesNonExemptEncryption: falsein Info.plist - UI thread blocking — heavy Para operations should use
compute()for isolation
Go
- Party configuration mismatch — all parties must agree on IDs, threshold, and protocol
- Must create protocol (
CreateProtocol) before callingSendTransaction - Inconsistent
useWebSocketparameter across calls (must be same for entire flow) SignHash(),Decrypt(),ComputeSharedSecret()are stubs — not implemented- Config state not persisted between operations (config bytes from
GetConfig()must be saved) - Network host not reachable (MPC network connectivity)
Server (Node.js / Bun / Deno)
- Missing
disableWebSockets: truefor Bun, Deno, or Cloudflare Workers - Missing
keepSessionAlive()after importing client session - Creating new
ParaServerinstances per request instead of reusing - Session imported but not refreshed — sessions expire after 90 minutes by default
Step 7: Produce the diagnostic bundle
Generate two outputs: 1. Short summary — for pasting into Slack or a support channel:para-diagnostic.md in the project root (remind the developer to add this to .gitignore or delete it after sharing — it contains source code):
- Para API keys -> show environment prefix + first 4 hex chars only (e.g.,
sandbox_5661****) - Session tokens or cookie values ->
[REDACTED] - Private keys or mnemonics ->
[REDACTED](and warn the developer if these appear in their code) - Third-party secrets — Stripe keys, database URIs (
postgres://,mongodb://), AWS keys (AKIA...), JWT tokens (eyJ...), Infura/Alchemy keys, or anything matching common secret patterns in.envfiles
After generating the bundle
Tell the developer:
I’ve generated a diagnostic report. The short summary above can be pasted into your support channel or shared with Para’s team. The detailed para-diagnostic.md file has the full context — share that too if possible. Review both before sending to make sure you’re comfortable with what’s included.
If the issue is hard to capture from static code alone (e.g., intermittent failures, timing-dependent bugs), suggest platform-appropriate debug logging:
- Web/RN/Expo: Add
enableDebugLogs: trueto the Para constructor - Swift: Use Xcode’s network debugger or Charles Proxy to inspect bridge traffic
- Flutter: Add
logLevel: ParaLogLevel.verbosetoParaConfig - Go: Inspect HTTP/WebSocket traffic to the MPC network host
- Server: Add
enableDebugLogs: trueto theParaServerconstructor