Documentation Index
Fetch the complete documentation index at: https://docs.rhinestone.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
External wallets like MetaMask, Coinbase Wallet, and WalletConnect-compatible wallets can be easily integrated with Rhinestone smart accounts. This approach is perfect for dApps that want to support users who already have established wallets.
Prerequisites
- React application setup
- External wallet installed (MetaMask, Coinbase Wallet, etc.)
- Basic familiarity with wallet connections
Install Dependencies
Install the required dependencies:npm install @rhinestone/sdk viem @reown/appkit @reown/appkit-adapter-wagmi wagmi
Set Up AppKit
The easiest way to integrate multiple wallets including WalletConnect. AppKit provides a beautiful, pre-built UI:npm install @reown/appkit @reown/appkit-adapter-wagmi wagmi viem
import { createAppKit } from '@reown/appkit'
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
import { mainnet, arbitrum, base } from '@reown/appkit/networks'
import { RhinestoneSDK } from '@rhinestone/sdk'
import { walletClientToAccount } from '@rhinestone/sdk/utils'
import { useAccount, useWalletClient } from 'wagmi'
// 1. Get projectId from https://dashboard.reown.com
const projectId = 'your-project-id'
// 2. Set up the Wagmi adapter
const wagmiAdapter = new WagmiAdapter({
networks: [mainnet, arbitrum, base],
projectId,
})
// 3. Configure the modal
createAppKit({
adapters: [wagmiAdapter],
networks: [mainnet, arbitrum, base],
projectId,
metadata: {
name: 'Your dApp',
description: 'Your dApp description',
url: 'https://yourdapp.com',
icons: ['https://yourdapp.com/icon.png']
}
})
// 4. Use in your React component
export function WalletConnector() {
const { isConnected } = useAccount()
const { data: walletClient } = useWalletClient()
const [rhinestoneAccount, setRhinestoneAccount] = useState(null)
useEffect(() => {
async function setupAccount() {
if (!isConnected || !walletClient) return
// wrap the wagmi client for the sdk
const wrappedWalletClient = walletClientToAccount(walletClient)
// Use the connected wallet client
const rhinestone = new RhinestoneSDK({
apiKey: process.env.RHINESTONE_API_KEY,
})
const account = await rhinestone.createAccount({
owners: {
type: "ecdsa",
accounts: [wrappedWalletClient],
},
});
setRhinestoneAccount(account)
}
setupAccount()
}, [isConnected, walletClient])
return (
<div>
<w3m-button />
{rhinestoneAccount && (
<p>Smart Account: {rhinestoneAccount.getAddress()}</p>
)}
</div>
)
}
Cross-Chain Transaction Example
async function sendCrossChainTransaction(rhinestoneAccount) {
const prepared = await rhinestoneAccount.prepareTransaction({
sourceChains: [arbitrumSepolia],
targetChain: baseSepolia,
calls: [
{
to: "USDC",
data: encodeFunctionData({
abi: erc20Abi,
functionName: "transfer",
args: ["0xrecipient", parseUnits("10", 6)],
}),
},
],
tokenRequests: [
{
address: "USDC",
amount: parseUnits("10", 6),
},
],
})
const signed = await rhinestoneAccount.signTransaction(prepared)
const transaction = await rhinestoneAccount.submitTransaction(signed)
console.log('Transaction submitted:', transaction.id)
}
Wallet Detection
export function getAvailableWallets() {
const wallets = []
if (window.ethereum?.isMetaMask) wallets.push('metamask')
if (window.ethereum?.isCoinbaseWallet) wallets.push('coinbase')
if (window.ethereum?.isRabby) wallets.push('rabby')
return wallets
}
// Usage
const availableWallets = getAvailableWallets()
if (availableWallets.length === 0) {
console.log('No compatible wallets detected')
} else {
console.log('Available wallets:', availableWallets)
}
Good Practice: Graceful Degradation
Always check for wallet availability when using server-side rendering:
if (typeof window === 'undefined' || !window.ethereum) {
// Show wallet installation prompt
return <WalletInstallPrompt />
}
Complete Example
Try the full integration in our example repository. We have lots of examples, can checkout the appkit example:
git clone https://github.com/rhinestonewtf/e2e-examples.git
cd e2e-examples/reown
npm install && npm run dev
Next Steps