Skip to main content
@faremeter/rides is the simplest way to use faremeter. It bundles all payment handlers and wallet adapters into a single package with automatic wallet detection.
pnpm add @faremeter/rides

Basic usage

import { payer } from "@faremeter/rides"

await payer.addLocalWallet(process.env.PAYER_KEYPAIR_PATH)
const response = await payer.fetch("https://api.example.com/resource")

The payer singleton

payer is a pre-configured singleton with sensible defaults. It supports all chains and assets out of the box.

addLocalWallet

await payer.addLocalWallet(input: unknown): Promise<void>
Adds a wallet to the payer. Auto-detects the wallet type:
  • File path (e.g., ~/.config/solana/id.json) — Treated as a Solana keypair file.
  • JSON array (e.g., [123, 45, ...]) — Treated as Solana keypair bytes.
  • Base64 string — Treated as a Solana keypair.
  • Hex string starting with 0x — Treated as an EVM private key.
Multiple wallets can be added. The payer will use the first wallet that matches a payment requirement.

addWalletAdapter

payer.addWalletAdapter(adapter: WalletAdapter): void
Registers a wallet adapter directly. Use this for wallet types that addLocalWallet cannot auto-detect, such as OWS, Ledger, or Crossmint wallets. A WalletAdapter has three fields:
FieldTypeDescription
x402IdPaymentIdV2[]Payment schemes this wallet supports (scheme, network, asset).
paymentHandlerPaymentHandlerThe payment handler that uses this wallet for signing.
getBalance() => Promise<Balance>Returns the wallet’s current balance for pre-payment checks.
Example with an OWS Solana wallet:
import { createPayer, type WalletAdapter } from "@faremeter/rides"
import { createOWSSolanaWallet } from "@faremeter/wallet-ows"
import { createPaymentHandler } from "@faremeter/payment-solana/exact"
import { lookupKnownSPLToken, clusterToCAIP2 } from "@faremeter/info/solana"
import { getTokenBalance } from "@faremeter/payment-solana/splToken"
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js"
import { createSolanaRpc } from "@solana/kit"

const network = "devnet"
const usdcInfo = lookupKnownSPLToken(network, "USDC")
if (!usdcInfo) throw new Error("Unknown SPL token")

const wallet = createOWSSolanaWallet(network, {
  walletNameOrId: "my-solana-wallet",
  passphrase: "my-passphrase",
})

const mint = new PublicKey(usdcInfo.address)
const connection = new Connection(clusterApiUrl(network), "confirmed")
const rpcClient = createSolanaRpc(clusterApiUrl(network))

const adapter: WalletAdapter = {
  x402Id: [{
    scheme: "exact",
    network: clusterToCAIP2(network).caip2,
    asset: usdcInfo.address,
  }],
  paymentHandler: createPaymentHandler(wallet, mint, connection),
  getBalance: async () => {
    const balance = await getTokenBalance({
      account: wallet.publicKey.toBase58(),
      asset: usdcInfo.address,
      rpcClient,
    })
    return { name: "USDC", amount: balance?.amount ?? 0n, decimals: balance?.decimals ?? 6 }
  },
}

const payer = createPayer()
payer.addWalletAdapter(adapter)

const response = await payer.fetch("https://api.example.com/resource")

fetch

await payer.fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response>
Drop-in replacement for the global fetch. If the server responds with 402, rides handles payment negotiation and retries the request automatically.

createPayer

For more control, create a custom payer instance:
import { createPayer } from "@faremeter/rides"

const customPayer = createPayer({
  networks: ["solana-devnet", "base-sepolia"],
  assets: ["USDC"],
  options: {
    disableBalanceChecks: true,
  },
})

await customPayer.addLocalWallet(process.env.PAYER_KEYPAIR_PATH)
const response = await customPayer.fetch("https://api.example.com/resource")

Options

OptionTypeDefaultDescription
networksKnownNetwork[]All supportedRestrict to specific networks.
assetsKnownAsset[]All supportedRestrict to specific assets.
options.disableBalanceChecksbooleanfalseSkip balance checks before payment.
options.fetchWrapOptsPass-through options for the underlying fetch wrapper.

Multi-chain support

Add wallets for different chains. Rides selects the correct one based on the server’s payment requirements.
import { payer } from "@faremeter/rides"

await payer.addLocalWallet(process.env.PAYER_KEYPAIR_PATH)
await payer.addLocalWallet(process.env.EVM_PRIVATE_KEY)

const response = await payer.fetch("https://api.example.com/resource")

When to use rides vs fetch

Use rides when:
  • You want the fastest setup with minimal configuration.
  • You do not need custom payer selection logic.
  • You are building a simple agent or script.
Use @faremeter/fetch when:
  • You need custom payment handlers or payer choosers.
  • You want to control which handlers are registered.
  • You need separate fetch instances with different configurations.
See Fetch Wrapper for the lower-level approach.