Wagmi Integration
Using RISE Wallet with Wagmi React hooks
This guide covers integrating RISE Wallet with Wagmi, the popular collection of React Hooks for Ethereum.
Overview
RISE Wallet implements a Wagmi connector and provides custom React hooks that map directly to the wallet's capabilities. The integration is designed to feel natural to developers already familiar with Wagmi.
Installation
npm i rise-wallet wagmi viem @tanstack/react-querypnpm add rise-wallet wagmi viem @tanstack/react-queryyarn add rise-wallet wagmi viem @tanstack/react-querybun add rise-wallet wagmi viem @tanstack/react-queryBasic Setup
1. Configure the Rise Wallet Connector
// config/wagmi.ts
import { Chains, RiseWallet } from "rise-wallet";
import { risewallet } from "rise-wallet/wagmi";
import { createConfig, http } from "wagmi";
// Export the connector for advanced usage
export const rwConnector = risewallet(RiseWallet.defaultConfig);
// Create wagmi config
export const config = createConfig({
chains: [Chains.riseTestnet],
connectors: [rwConnector],
transports: {
[Chains.riseTestnet.id]: http("https://testnet.riselabs.xyz"),
},
});2. Set Up Providers
// app/providers.tsx
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider } from "wagmi";
import { config } from "@/config/wagmi";
const queryClient = new QueryClient();
export function Providers({ children }: { children: React.ReactNode }) {
return (
<WagmiProvider config={config}>
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
</WagmiProvider>
);
}Standard Wagmi Hooks
All standard Wagmi hooks work seamlessly with RISE Wallet:
Connection Management
import { useConnect, useAccount, useDisconnect } from "wagmi";
export function WalletButton() {
const { address, isConnected } = useAccount();
const { connect } = useConnect();
const { disconnect } = useDisconnect();
if (isConnected) {
return (
<div>
<span>{address}</span>
<button onClick={() => disconnect()}>Disconnect</button>
</div>
);
}
const rwConnector = config.connectors.find(c => c.id === "com.risechain.wallet");
return (
<button onClick={() => connect({ connector: rwConnector })}>
Connect with Passkey
</button>
);
}Sending Transactions
import { useSendCalls } from "wagmi";
import { parseEther } from "viem";
export function SendTransaction() {
const { sendCallsAsync, isPending } = useSendCalls();
const handleSend = async () => {
const result = await sendCallsAsync({
calls: [{
to: "0x...",
value: parseEther("0.001"),
}],
});
console.log("Transaction sent:", result);
};
return (
<button onClick={handleSend} disabled={isPending}>
{isPending ? "Sending..." : "Send 0.001 ETH"}
</button>
);
}RISE Wallet Specific Hooks
Import custom hooks via the Hooks namespace:
import { Hooks } from "rise-wallet/wagmi";
// or individually
import { useGrantPermissions } from "rise-wallet/wagmi/Hooks";useGrantPermissions
Create session keys with specific permissions:
const grantPermissions = Hooks.useGrantPermissions();
const createSession = async () => {
await grantPermissions.mutateAsync({
key: { publicKey: "...", type: "p256" },
expiry: Math.floor(Date.now() / 1000) + 3600, // 1 hour
permissions: {
calls: [{
to: "0x...",
signature: "0x...",
}],
},
});
};usePermissions
View current permissions for the connected account:
const { data: permissions } = Hooks.usePermissions();
if (permissions) {
console.log("Active permissions:", permissions);
}useRevokePermissions
Revoke previously granted permissions:
const revokePermissions = Hooks.useRevokePermissions();
const revokeSession = async (keyId: string) => {
await revokePermissions.mutateAsync({
keyId,
});
};useAssets
Get user's token balances and assets:
const { data: assets } = Hooks.useAssets();
return (
<div>
{assets?.map(asset => (
<div key={asset.address}>
{asset.symbol}: {asset.balance}
</div>
))}
</div>
);Advanced Patterns
Batched Transactions
Execute multiple operations atomically:
const { sendCallsAsync } = useSendCalls();
// Approve and swap in one transaction
await sendCallsAsync({
calls: [
{
to: TOKEN_ADDRESS,
data: approveCalldata,
},
{
to: DEX_ADDRESS,
data: swapCalldata,
},
],
// Atomic execution - all succeed or all fail
atomicRequired: true,
});Reading Transaction Status
Monitor transaction progress:
import { useWaitForTransactionReceipt } from "wagmi";
const { data: receipt, isLoading } = useWaitForTransactionReceipt({
hash: transactionHash,
});
if (receipt) {
console.log("Transaction confirmed:", receipt);
}Error Handling
Properly handle wallet errors:
import { BaseError } from "wagmi";
try {
await sendCallsAsync({...});
} catch (error) {
if (error instanceof BaseError) {
// Handle specific error types
if (error.shortMessage.includes("rejected")) {
console.log("User rejected the request");
}
}
}TypeScript Support
RISE Wallet provides full TypeScript support:
import type { RiseWallet } from "rise-wallet";
import type { Config } from "wagmi";
// Config is fully typed
const config: Config = createConfig({
chains: [Chains.riseTestnet],
connectors: [rwConnector],
transports: {
[Chains.riseTestnet.id]: http(),
},
});Best Practices
1. Check Connection State
Always verify the connection state before attempting transactions:
const { isConnected } = useAccount();
if (!isConnected) {
return <ConnectButton />;
}2. Handle Loading States
Provide feedback during async operations:
const { sendCallsAsync, isPending, isSuccess, isError } = useSendCalls();3. Use Error Boundaries
Wrap your app with error boundaries to catch unexpected errors:
import { ErrorBoundary } from "react-error-boundary";
<ErrorBoundary fallback={<ErrorFallback />}>
<App />
</ErrorBoundary>Examples
For complete working examples, check out: