Integrating Para Embedded Wallet with Graz
Para is a wallet connector that enables seamless integration with Cosmos-based chains in your Graz-powered application. This guide shows how to enable Para support, including the modal for user authentication and wallet selection.
Note: Para type definitions are re-exported by graz for convenience. You need to install both @getpara/react-sdk-lite (for the SDK) and @getpara/graz-integration (for the connector implementation). The connectorClass property is required in your ParaGrazConfig.
Prerequisites
- A Graz project set up with React and
@tanstack/react-query. - Access to a Para API key (sign up at developer.getpara.com).
- Enabled Cosmos network in you Para project settings
- Familiarity with Graz hooks like
useAccountanduseConnect.
Step 1: Install Dependencies
Install the required packages:
npm install graz @getpara/react-sdk-lite @getpara/graz-integration @tanstack/react-query
Package breakdown:
graz- Core library with Para type definitions re-exported@getpara/react-sdk-lite- Para SDK with UI components and ParaWeb client@getpara/graz-integration- Para connector implementation (ParaGrazConnector)@tanstack/react-query- Required for state management
Add postinstall script to your package.json to stub out unused packages from react-sdk-lite:
{
"scripts": {
"postinstall": "npx setup-para",
"dev": "next dev",
"build": "next build"
}
}
Then run npm install (or pnpm install) to install dependencies and run the postinstall script.
Step 2: Import Para Styles
Import Para styles in your global CSS file (e.g., app/globals.css):
@import "@getpara/react-sdk-lite/styles.css";
/* Your other styles... */
Step 3: Configure GrazProvider
Set up your provider with Para integration. In your provider file (e.g., app/providers.tsx):
"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { GrazProvider, type ParaGrazConfig } from "graz";
import { ParaGrazConnector } from "@getpara/graz-integration";
import ParaWeb, { Environment } from "@getpara/react-sdk-lite";
import { useState, useMemo } from "react";
import { cosmoshub } from "graz/chains"; // Example chain
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(() => new QueryClient());
// Initialize Para if API key is provided
const para = useMemo(() => {
const apiKey = process.env.NEXT_PUBLIC_PARA_API_KEY;
if (!apiKey) {
console.info("Para: No API key provided. Get one at https://developer.getpara.com");
return null;
}
return new ParaWeb(Environment.BETA, apiKey);
}, []);
const paraConfig: ParaGrazConfig | undefined = useMemo(
() =>
para
? {
paraWeb: para,
connectorClass: ParaGrazConnector,
modalProps: { appName: "Your App Name" },
queryClient: queryClient,
}
: undefined,
[para, queryClient],
);
return (
<QueryClientProvider client={queryClient}>
<GrazProvider
grazOptions={{
chains: [cosmoshub],
paraConfig,
}}
>
{children}
</GrazProvider>
</QueryClientProvider>
);
}
Then wrap your app with the provider in your root layout (e.g., app/layout.tsx):
import { Providers } from "./providers";
import "./globals.css";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Step 4: Set Environment Variables
Create a .env.local file in your project root:
NEXT_PUBLIC_PARA_API_KEY=your_api_key_here
Get your API key from developer.getpara.com.
Step 5: Connect and Use Para Wallet
Use Graz hooks to connect. Para will appear as an option (WalletType.PARA internally). The modal handles login and wallet selection.
Example in a header component:
"use client";
import { useAccount, useConnect, WalletType } from "graz";
export default function Header() {
const { data: accounts, isConnected } = useAccount({
chainId: ["cosmoshub-4"], // Use your configured chain
});
const { connect } = useConnect();
// Extract account for the specific chain
const account = accounts?.["cosmoshub-4"];
const handleConnect = () => {
connect({
chainId: ["cosmoshub-4"],
walletType: WalletType.PARA,
}); // Triggers Para modal if needed
};
return (
<header>
{isConnected && account ? (
<button>
Connected: {account.bech32Address.slice(0, 12)}...{account.bech32Address.slice(-6)}
</button>
) : (
<button onClick={handleConnect}>Connect Para Wallet</button>
)}
</header>
);
}
Type Definitions
Para type definitions are re-exported from graz for convenience, while the connector implementation comes from @getpara/graz-integration.
Import types from graz:
import { type ParaGrazConfig, type ParaWeb, type ParaWallet, type ParaModalProps } from "graz";
Import connector from @getpara/graz-integration:
import { ParaGrazConnector } from "@getpara/graz-integration";
Important Notes:
ParaGrazConfigrequires aconnectorClassproperty - you must passParaGrazConnectorexplicitly- Types like
ParaWebare sourced from@getpara/web-sdkbut re-exported bygrazfor convenience - The connector implementation must be provided by you, enabling tree-shaking and reducing bundle size if Para is not used
- This approach eliminates dynamic import issues and provides better error messages
Runtime Dependencies
For Para wallet functionality, you need these packages installed:
@getpara/react-sdk-lite- Para's React SDK with UI components andParaWebclient@getpara/graz-integration- Para connector implementation (ParaGrazConnector)
The Para connector is explicitly provided via paraConfig.connectorClass, so if you don't use Para, these packages won't be included in your bundle.
Benefits of the New Approach
The current implementation requires you to explicitly provide the connectorClass, which offers several advantages:
- 🚀 Better Performance: No runtime dynamic imports, faster initialization
- 🔧 Clearer Errors: Specific error messages when
connectorClassis missing - 📦 Tree Shaking: Unused Para packages are automatically excluded from your bundle
- 🐛 Easier Debugging: Direct imports are easier to trace and debug
- ⚡ No Module Resolution Issues: Eliminates pnpm/Node.js import resolution problems
- 🎯 Type Safety: Required
connectorClassprevents runtime errors
Troubleshooting
"Para connector class not provided" Error
Ensure you pass connectorClass: ParaGrazConnector in your paraConfig. This is now required:
const paraConfig: ParaGrazConfig = {
paraWeb: para,
connectorClass: ParaGrazConnector, // ✅ Required
// ...
};
Chunk Loading Errors (Next.js)
If you see errors about loading chunks:
-
Ensure
grazis intranspilePackagesinnext.config.js:transpilePackages: ["graz"]; -
Restart your Next.js dev server after making config changes
-
Clear Next.js cache if issues persist:
rm -rf .next
npm run dev
Module Not Found Errors
Cannot find module '@getpara/react-sdk-lite'→ Install:npm install @getpara/react-sdk-liteCannot find module '@getpara/graz-integration'→ Install:npm install @getpara/graz-integration- Run
npx setup-paraafter installing packages
Note: With the new approach, you no longer need to worry about dynamic import resolution issues that were common with the previous implementation.
Type Errors
- Import types from
graz:import { type ParaGrazConfig } from "graz" - Import connector from
@getpara/graz-integration:import { ParaGrazConnector } from "@getpara/graz-integration"
Modal Styling Not Appearing
Import Para styles in your global CSS:
@import "@getpara/react-sdk-lite/styles.css";
Other Issues
- Chain Mismatch: Verify chains in
GrazProvidermatch your Para project settings - API Key Issues: Check that
NEXT_PUBLIC_PARA_API_KEYis set in.env.local - Authentication Issues: Check browser console for Para-specific messages
- Need Help? Visit developer.getpara.com for support
For advanced customization, refer to the Para Docs at docs.getpara.com.