Documentation Index
Fetch the complete documentation index at: https://docs.faremeter.xyz/llms.txt
Use this file to discover all available pages before exploring further.
Payment handlers connect wallets to payment schemes. Each handler knows how to sign payments for a specific blockchain. This page covers configuring the built-in handlers for Solana and EVM.
PaymentExecerV1 and PaymentHandlerV1 are deprecated. Use PaymentExecer and PaymentHandler instead. See the Client Types API reference for migration details.
Solana handler
pnpm add @faremeter/payment-solana @faremeter/wallet-solana @solana/web3.js
import { Keypair, PublicKey } from "@solana/web3.js"
import { createPaymentHandler } from "@faremeter/payment-solana/exact"
import { createLocalWallet } from "@faremeter/wallet-solana"
import { lookupKnownSPLToken } from "@faremeter/info/solana"
const keypair = Keypair.fromSecretKey(new Uint8Array(keypairBytes))
const wallet = await createLocalWallet("devnet", keypair)
const splTokenInfo = lookupKnownSPLToken("devnet", "USDC")
if (!splTokenInfo) throw new Error("Unknown SPL token")
const mint = new PublicKey(splTokenInfo.address)
const handler = createPaymentHandler(wallet, mint)
The Solana handler supports:
- SPL token transfers (USDC)
- Native SOL transfers
- Devnet, testnet, and mainnet-beta
SPL token payments
SPL token payments use the splToken scheme. The handler constructs a token transfer transaction and signs it with the wallet.
Native SOL payments
SOL payments use the exact scheme with native SOL as the asset. The handler constructs a system transfer and signs it.
EVM handler
pnpm add @faremeter/payment-evm @faremeter/wallet-evm
import { createPaymentHandler } from "@faremeter/payment-evm/exact"
import { createLocalWallet } from "@faremeter/wallet-evm"
const wallet = await createLocalWallet({ id: 84532, name: "Base Sepolia" }, privateKey)
const handler = createPaymentHandler(wallet)
The EVM handler supports:
- EIP-3009 gasless USDC transfers
- ERC-20 token transfers
- Base, Base Sepolia, SKALE Europa Testnet, Polygon PoS, Polygon Amoy, Monad, Monad Testnet
Gasless payments
EIP-3009 payments are gasless. The client signs an EIP-712 typed message authorizing a transfer. The facilitator submits the transaction on-chain and pays the gas. The client never needs native tokens.
Using OWS wallets with handlers
OWS wallets are drop-in replacements for local wallets. Pass them to the same payment handler factories:
import { createOWSSolanaWallet } from "@faremeter/wallet-ows"
import { createPaymentHandler } from "@faremeter/payment-solana/exact"
import { lookupKnownSPLToken } from "@faremeter/info/solana"
import { PublicKey } from "@solana/web3.js"
const wallet = createOWSSolanaWallet("devnet", {
walletNameOrId: "my-solana-wallet",
passphrase: "my-passphrase",
})
const splTokenInfo = lookupKnownSPLToken("devnet", "USDC")
if (!splTokenInfo) throw new Error("Unknown SPL token")
const mint = new PublicKey(splTokenInfo.address)
const handler = createPaymentHandler(wallet, mint)
import { createOWSEvmWallet } from "@faremeter/wallet-ows"
import { createPaymentHandler } from "@faremeter/payment-evm/exact"
const wallet = createOWSEvmWallet(
{ id: 84532, name: "Base Sepolia" },
{ walletNameOrId: "my-evm-wallet", passphrase: "my-passphrase" },
)
const handler = createPaymentHandler(wallet)
See Wallet Configuration for full OWS setup details.
Using both handlers
Register multiple handlers with the fetch wrapper to support both chains simultaneously:
import { Keypair, PublicKey } from "@solana/web3.js"
import { wrap } from "@faremeter/fetch"
import { createPaymentHandler as createSolanaHandler } from "@faremeter/payment-solana/exact"
import { createPaymentHandler as createEVMHandler } from "@faremeter/payment-evm/exact"
import { createLocalWallet as createSolanaWallet } from "@faremeter/wallet-solana"
import { createLocalWallet as createEVMWallet } from "@faremeter/wallet-evm"
import { lookupKnownSPLToken } from "@faremeter/info/solana"
const keypair = Keypair.fromSecretKey(new Uint8Array(keypairBytes))
const solanaWallet = await createSolanaWallet("devnet", keypair)
const evmWallet = await createEVMWallet({ id: 84532, name: "Base Sepolia" }, privateKey)
const splTokenInfo = lookupKnownSPLToken("devnet", "USDC")
if (!splTokenInfo) throw new Error("Unknown SPL token")
const solanaMint = new PublicKey(splTokenInfo.address)
const fetchWithPayment = wrap(fetch, {
handlers: [
createSolanaHandler(solanaWallet, solanaMint),
createEVMHandler(evmWallet),
],
})
The fetch wrapper passes 402 requirements to each handler. The first handler that can fulfill a requirement is used. To customize selection, provide a payerChooser — see Fetch Wrapper.
Further reading