Skip to main content

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, Cosmos

Agent Setup

When you receive this file, complete these steps before anything else:
  1. Save this skill so it persists across sessions:
    mkdir -p ~/.claude/skills/para && curl -sL https://docs.getpara.com/skill.md > ~/.claude/skills/para/SKILL.md
    
    For non-Claude Code agents, save to your project root:
    curl -sL https://docs.getpara.com/skill.md > .para-skill.md
    
  2. Install the Para CLI:
    npm install -g @getpara/cli
    
  3. Authenticate (opens browser for OAuth):
    para login
    
  4. Verify everything is working:
    para whoami
    
Once setup is complete, ask the user what they’d like to build.

Para CLI

Setup a New Project

The fastest way to start is para create, which scaffolds a working app:
para create my-app
This walks you through: template (Next.js or Expo), chains, auth methods, OAuth providers, and external wallets. It installs dependencies and writes your API key to .env. Non-interactive example:
para create my-app -t nextjs --networks evm,solana --email --oauth GOOGLE,APPLE -y

Setup an Existing Project

If you already have a project, use the CLI to configure it:
# Select your org and project
para orgs switch
para projects switch

# Pin config to this directory (creates .pararc)
para init

# Get your API key
para keys get --copy
Then install the SDK. For React:
npm install @getpara/react-sdk
The minimum integration requires:
  1. Environment variable — Set NEXT_PUBLIC_PARA_API_KEY (Next.js), VITE_PARA_API_KEY (Vite), or EXPO_PUBLIC_PARA_API_KEY (Expo)
  2. CSS importimport "@getpara/react-sdk/styles.css"
  3. ParaProvider — Wrap your app with <ParaProvider> (requires a QueryClient from @tanstack/react-query)
  4. “use client” — Add directive to files using Para hooks (Next.js only)

Diagnose Issues

para doctor
Checks: API key env var, env var prefix for framework, CSS import, ParaProvider setup, QueryClient, “use client” directives, @getpara/* version consistency, chain dependencies, deprecated packages. Exit code 1 on errors — use para doctor --json in CI.

CLI Command Reference

Authentication

para login                  # OAuth in browser
para login --no-browser     # Print URL (headless/CI)
para logout                 # Clear credentials
para auth status            # Validate session
para whoami                 # Show current context

Configuration

para config get [key]                   # Show all config values with sources
para config set <key> <value>           # Set global config
para config set <key> <value> --local   # Set project config (.pararc)
para init                               # Create .pararc in current directory
Config resolution: CLI flags > env vars (PARA_ENVIRONMENT, PARA_ORG_ID, PARA_PROJECT_ID) > .pararc > global config (~/.config/para/config.json) > defaults (beta).

Organizations & Projects

para orgs list                          # List orgs
para orgs switch [org-id]               # Switch org

para projects list                      # List projects
para projects switch [project-id]       # Switch project
para projects create -n "My App" --framework nextjs
para projects archive [project-id] -y   # Archive (disables keys immediately)
para projects restore <project-id>      # Restore archived project

API Keys

para keys list                          # List keys for active project
para keys get --copy                    # Copy API key to clipboard
para keys get --copy-secret             # Copy secret key to clipboard
para keys create -n "prod-key"          # Create new key
para keys rotate [key-id] -y            # Rotate key (immediate, irreversible)
para keys rotate --secret -y            # Rotate secret key
para keys archive [key-id] -y           # Revoke key immediately

Key Configuration

# Security — auth methods, origins, sessions, IP restrictions
para keys config security \
  --auth-methods "PASSKEY,PASSWORD" \
  --origins "https://myapp.com" \
  --session-length 1440

# Branding — colors, fonts, social links
para keys config branding \
  --fg-color "#FFFFFF" --bg-color "#000000" --accent-color "#FF5500" \
  --font "Helvetica"

# Wallet setup — chains, native passkeys
para keys config setup \
  --wallet-types "EVM,~SOLANA,~COSMOS"

# Webhooks — events and endpoints
para keys config webhooks \
  --url "https://api.myapp.com/webhooks" \
  --events "user.created,wallet.created,transaction.signed" \
  --enabled

# Ramps — buy/sell crypto
para keys config ramps \
  --buy-enabled --providers "RAMP,STRIPE,MOONPAY"

Scaffold

para create [app-name]
  -t, --template nextjs|expo
  --networks evm,solana,cosmos          # Expo: EVM only
  --email                               # Email auth
  --phone                               # Phone/SMS auth
  --oauth GOOGLE,APPLE,TWITTER,DISCORD,FACEBOOK,FARCASTER
  --wallets METAMASK,COINBASE,WALLETCONNECT,PHANTOM,KEPLR,...
  --bundle-id com.example.app           # Required for Expo
  --package-manager npm|yarn|pnpm|bun
  -y, --yes                             # Non-interactive

Global Flags

All commands accept: -e beta|prod, --json, -q/--quiet, --no-input, --org <id>, --project <id>.

SDK Packages

Web & Server (JavaScript/TypeScript)

PackagePurpose
@getpara/react-sdkReact hooks + ParaModal component
@getpara/react-native-walletReact Native / Expo SDK
@getpara/core-sdkFramework-agnostic base SDK
@getpara/server-sdkNode.js server-side operations
@getpara/viem-v2-integrationViem wallet client signer
@getpara/ethers-v6-integrationEthers.js v6 signer
@getpara/solana-web3js-v1-integrationSolana signer
@getpara/evm-wallet-connectorsMetaMask, Coinbase, WalletConnect, etc.
@getpara/solana-wallet-connectorsPhantom, Backpack, Solflare, etc.
@getpara/cosmos-wallet-connectorsKeplr, Leap

Mobile Native

PackagePlatformImport
ParaSwiftiOS (Swift)import ParaSwift
paraFlutter (Dart)import 'package:para/para.dart'

Server (Go)

PackageImport
go-sdkgithub.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

EnvironmentAPI Key PrefixUse
betapara_beta_*Development and testing
prodpara_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:
PlatformDetection signals
Swift (iOS)Package.swift with ParaSwift, .xcodeproj/.xcworkspace, *.swift files importing ParaSwift
Flutterpubspec.yaml with para: dependency, *.dart files importing package:para
React Nativepackage.json with @getpara/react-native-wallet, metro.config.js
Expopackage.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
Gogo.mod with github.com/capsule-org/go-sdk
If multiple platforms are detected (e.g., Expo client + Node.js server), note all of them and trace across the boundary.

Step 2: Run para doctor (JS/TS projects only)

para doctor --json
Capture the full JSON output. If 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:
  1. 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.
  2. What do you expect instead?
  3. Is this consistent or intermittent? When did it last work? Did anything change recently? (SDK upgrade, new auth method, deploy environment change, etc.)
Platform-specific clarifications to ask:
  • Swift/React Native: Ask for Xcode console output or adb logcat output
  • 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
If they’ve already described the issue in conversation, don’t re-ask — use what they told you.

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 (BETA or PROD)
  • 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 with Environment.PROD is 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/stargate if 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(...), and new ParaServer(...) call — especially enableDebugLogs, disableWorkers, custom portalUrl, walletPregeneration

Swift (iOS)

  • Xcode version (from xcodebuild -version)
  • iOS deployment target (from .xcodeproj or Package.swift)
  • ParaSwift SDK version (from Package.resolved or SPM pins)
  • Full ParaManager(...) constructor — environment, apiKey, appScheme
  • Associated Domains configuration (from .entitlements file 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, BigInt versions

Flutter

  • Flutter version (flutter --version)
  • Dart version (dart --version)
  • para package version from pubspec.yaml and pubspec.lock
  • Full Para(...) or Para.fromConfig(...) constructor — environment, apiKey, appScheme (must NOT include :// suffix)
  • Android minSdkVersion from android/app/build.gradle
  • iOS deployment target from ios/Podfile
  • .env file contents (redact secrets)
  • Android namespace configuration in build.gradle
  • SHA-256 fingerprint registration status (for passkeys)
  • Third-party dependencies: web3dart, solana, passkeys, flutter_secure_storage versions

Go

  • Go version (go version)
  • go-sdk version from go.mod
  • NewSigner(...) 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:
grep -r "from ['\"]@getpara/" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" -l .
grep -r "from ['\"]@usecapsule/" --include="*.ts" --include="*.tsx" --include="*.js" --include="*.jsx" -l .
React Native / Expo: Same as Web, plus check for:
grep -r "ParaMobile\|react-native-wallet" --include="*.ts" --include="*.tsx" -l .
Swift:
grep -r "import ParaSwift" --include="*.swift" -l .
grep -r "ParaManager\|ParaConfig\|ParaEnvironment" --include="*.swift" -l .
Flutter:
grep -r "package:para" --include="*.dart" -l .
grep -r "Para\.\|Para(" --include="*.dart" -l .
Go:
grep -r "capsule-org/go-sdk\|signer\.NewSigner\|signer\.Signer" --include="*.go" -l .

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 await on 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
Present code in execution order, not alphabetical by file. If the flow is: login -> export session -> (server) import session -> sign, present in that order. Annotate client/server or native/bridge transitions. Keep it focused. Total extracted code should not exceed ~500 lines. Prioritize files most likely related to the reported issue.

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 await on async Para SDK calls

Web (React, Next.js, Vite)

  • logout() called anywhere near exportSession, importSession, or signing flows
  • Missing keepSessionAlive() in server-side flows that use imported sessions
  • Creating new Para or ParaServer instances 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 of ParaProvider context
  • Multiple ParaProvider instances
  • 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 crypto and buffer resolver
  • Missing PolyfillCrypto component in app root
  • Using Expo Go instead of expo prebuild / expo build (native modules don’t work in Expo Go)
  • Missing disableWorkers: true in 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 NSFaceIDUsageDescription in Info.plist (required for biometric prompts)
  • Missing or mismatched URL scheme in Info.plist vs appScheme parameter
  • Not handling ASAuthorizationError.canceled (user dismissed biometric prompt)
  • ParaError.bridgeTimeoutError without 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 appScheme parameter 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 .future property on ParaFuture operations (e.g., para.createWallet(...) returns ParaFuture, must await result.future)
  • Not catching ParaBridgeException specifically (has code and details fields for diagnosis)
  • Missing extension method imports (package:para/src/auth_extensions.dart)
  • .env not loaded before building UI (dotenv.load() must run before runApp())
  • 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: false in 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 calling SendTransaction
  • Inconsistent useWebSocket parameter 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: true for Bun, Deno, or Cloudflare Workers
  • Missing keepSessionAlive() after importing client session
  • Creating new ParaServer instances 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 Report
Platform: [Swift/Flutter/React Native/Expo/Web/Server/Go]
SDK: [package@version]
Environment: BETA/PROD | Framework: [name + version] | [Runtime version]
para doctor: [N failures, M warnings — or "N/A (non-JS platform)"]

Issue: [one-line summary of what's broken]

[any flags from Step 6, one per line]

Full diagnostic: see para-diagnostic.md
2. Detailed file — write to 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 Diagnostic Bundle
Generated: [timestamp]
Platform: [detected platform]

## Issue
[Developer's description from Step 3]

## Environment
[para doctor output (if JS) + Step 4 info as a table]

## Error Output
[Exact error messages, console output, HTTP status codes if available]

## Code
[All extracted code from Step 5, in execution order, with file:line annotations]

## Flags
[Anything found in Step 6]
Before including code in the bundle, redact:
  • 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 .env files

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: true to the Para constructor
  • Swift: Use Xcode’s network debugger or Charles Proxy to inspect bridge traffic
  • Flutter: Add logLevel: ParaLogLevel.verbose to ParaConfig
  • Go: Inspect HTTP/WebSocket traffic to the MPC network host
  • Server: Add enableDebugLogs: true to the ParaServer constructor