With Viem's built in Celo transaction serializer and Celo block/transaction formatters it is easy to build a wallet that supports Celo's ability to pay gas fees with various erc20 tokens. Simply, import a Celo chain from `viem/chain`` and pass it to Viem's `createWalletClient`. Once the client is created you can add the feeCurrency field to your transaction with the address of the token you want to use for gas.
import { celo } from 'viem/chains'
import { createWalletClient, privateKeyToAccount, type SendTransactionParameters, http } from 'viem'
const account = privateKeyToAccount(PRIVATE_KEY)
// ALFAJORES ADDRESS: Celo Mainnet can be fetched from the registry
const cUSDAddress = '0x874069Fa1Eb16D44d622F2e0Ca25eeA172369bC1'
const localAccountClient = createWalletClient({
account,
chain: celo,
})
const sendTransaction = (tx: SendTransactionParameters<typeof celo>) => {
return localAccountClient.sendTransaction(tx)
}
const hash = await sendTransaction({
feeCurrency: cUSDAddress,
value: BigInt(100000000),
to: '0x22579CA45eE22E2E16dDF72D955D6cf4c767B0eF',
})
If you have a wallet that supports serializing feeCurrency you can use viem to send the transaction to that wallet for signing.
import { useWalletClient, usePublicClient } from 'wagmi'
import { type SendTransactionParameters } from 'viem'
const client = useWalletClient({chainId:celoAlfajores.id})
const publicClient = usePublicClient()
const tx: SendTransactionParameters<typeof celoAlfajores> = {
account: client.data?.account!,
feeCurrency: cUSDAddress.data,
maxFeePerGas: BigInt(700000),
maxPriorityFeePerGas: BigInt(700000),
value: BigInt(100000000000000000),
to: '0x22579CA45eE22E2E16dDF72D955D6cf4c767B0eF',
}
const gas = await publicClient.estimateGas(tx)
const hash = await client.data?.sendTransaction({...tx, gas})
const receipt = await publicClient.waitForTransactionReceipt({hash})