Farcaster Frames Integration
The @daimo/pay
SDK supports integration with Farcaster Frames v2 via a custom connector. This allows users to make payments directly from a Frame using Farcaster wallets. Follow the steps below to integrate Farcaster.
This guide demonstrates how to integrate Farcaster Frames v2 into the SDK. For more details on how to build a Farcaster Frame, see the Farcaster Frames docs.

Step 1: Create a Custom Farcaster Connector
To add Farcaster wallet support, create a custom connector using the @farcaster/frame-sdk
package. Below is an example implementation taken largely from the Farcaster connector SDK.
import FrameSDK from '@farcaster/frame-sdk'
import {
ChainNotConfiguredError,
type Connector,
createConnector,
} from '@wagmi/core'
import { SwitchChainError, fromHex, getAddress, numberToHex } from 'viem'
farcasterConnector.type = 'farcasterFrame' as const
let accountsChanged: Connector['onAccountsChanged'] | undefined
let chainChanged: Connector['onChainChanged'] | undefined
let disconnect: Connector['onDisconnect'] | undefined
export function farcasterConnector() {
return createConnector<typeof FrameSDK.wallet.ethProvider>((config) => ({
id: 'farcaster',
name: 'Farcaster Wallet',
rdns: 'xyz.farcaster',
icon: 'https://pay.daimo.com/wallet-logos/farcaster-logo.svg',
type: farcasterConnector.type,
async connect({ chainId } = {}) {
const provider = await this.getProvider()
const accounts = await provider.request({
method: 'eth_requestAccounts',
})
if (!accountsChanged) {
accountsChanged = this.onAccountsChanged.bind(this)
// @ts-expect-error - provider type is stricter
provider.on('accountsChanged', accountsChanged)
}
if (!chainChanged) {
chainChanged = this.onChainChanged.bind(this)
provider.on('chainChanged', chainChanged)
}
if (!disconnect) {
disconnect = this.onDisconnect.bind(this)
provider.on('disconnect', disconnect)
}
let currentChainId = await this.getChainId()
if (chainId && currentChainId !== chainId) {
const chain = await this.switchChain!({ chainId })
currentChainId = chain.id
}
return {
accounts: accounts.map((x) => getAddress(x)),
chainId: currentChainId,
}
},
async disconnect() {
const provider = await this.getProvider()
if (accountsChanged) {
// @ts-expect-error - provider type is stricter
provider.removeListener('accountsChanged', accountsChanged)
accountsChanged = undefined
}
if (chainChanged) {
provider.removeListener('chainChanged', chainChanged)
chainChanged = undefined
}
if (disconnect) {
provider.removeListener('disconnect', disconnect)
disconnect = undefined
}
},
async getAccounts() {
const provider = await this.getProvider()
const accounts = await provider.request({
method: 'eth_accounts',
})
return accounts.map((x) => getAddress(x))
},
async getChainId() {
const provider = await this.getProvider()
const hexChainId = await provider.request({ method: 'eth_chainId' })
return fromHex(hexChainId, 'number')
},
async isAuthorized() {
try {
const accounts = await this.getAccounts()
return !!accounts.length
} catch {
return false
}
},
async switchChain({ chainId }) {
const provider = await this.getProvider()
const chain = config.chains.find((x) => x.id === chainId)
if (!chain) {
throw new SwitchChainError(new ChainNotConfiguredError())
}
await provider.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: numberToHex(chainId) }],
})
config.emitter.emit('change', { chainId })
return chain
},
onAccountsChanged(accounts) {
if (accounts.length === 0) {
this.onDisconnect()
} else {
config.emitter.emit('change', {
accounts: accounts.map((x) => getAddress(x)),
})
}
},
onChainChanged(chain) {
const chainId = Number(chain)
config.emitter.emit('change', { chainId })
},
async onDisconnect() {
config.emitter.emit('disconnect')
},
async getProvider() {
return FrameSDK.wallet.ethProvider
},
}))
}
Step 2: Add the Connector to Your SDK Configuration
Add the farcasterConnector
to the additionalConnectors
parameter in the wagmi config to register the Farcaster connector:
const config = createConfig(
getDefaultConfig({
appName: 'Farcaster Daimo Pay Demo',
additionalConnectors: [farcasterConnector()],
}),
)
Once the Farcaster connector is added, the wallet will automatically surface in the DaimoPayButton modal.
By following these steps, you can integrate Farcaster wallets into your payment flow using the @daimo/pay
SDK. For more details about building a Farcaster Frame, see the Farcaster Frames Documentation.