Skip to main content
A wallet adapter signs payment proofs on behalf of the client. It takes a payment request and produces a signed payload that proves the client authorized the payment. Wallets never submit transactions directly — they only sign. The facilitator handles on-chain submission.

The wallet adapter pattern

Every wallet adapter in faremeter follows the same pattern: a factory function that creates a wallet object.
import { Keypair } from "@solana/web3.js"
import { createLocalWallet } from "@faremeter/wallet-solana"

const keypair = Keypair.fromSecretKey(new Uint8Array(keypairBytes))
const wallet = await createLocalWallet("devnet", keypair)
The wallet object is then passed to a payment handler, which uses it to sign payments when a 402 response is received.

Available adapters

PackageWallet typeUse case
@faremeter/wallet-solanaSolana keypairLocal development, server-side agents
@faremeter/wallet-evmEVM private keyLocal development, server-side agents
@faremeter/wallet-crossmintCrossmint custodialManaged wallets, no private keys
@faremeter/wallet-solana-squadsSquads multisigDAOs, shared treasuries
@faremeter/wallet-ledgerLedger hardwareHigh-security signing

How wallets plug in

Wallets are passed to payment handlers, which are passed to the fetch wrapper:
import { Keypair } from "@solana/web3.js"
import { wrap } from "@faremeter/fetch"
import { createPaymentHandler } from "@faremeter/payment-solana/exact"
import { createLocalWallet } from "@faremeter/wallet-solana"

const keypair = Keypair.fromSecretKey(new Uint8Array(keypairBytes))
const wallet = await createLocalWallet("devnet", keypair)
const handler = createPaymentHandler(wallet, wallet.mint)

const fetchWithPayment = wrap(fetch, {
  handlers: [handler],
})
Or with @faremeter/rides, wallets are added directly and everything else is wired up automatically:
import { payer } from "@faremeter/rides"

await payer.addLocalWallet(process.env.PAYER_KEYPAIR_PATH)
await payer.addLocalWallet(process.env.EVM_PRIVATE_KEY)
Rides detects the wallet type from the input. A file path is treated as a Solana keypair. A hex string starting with 0x is treated as an EVM private key.

Signing flow

  1. Client receives a 402 response with payment requirements.
  2. The payment handler checks if the wallet matches the required scheme/network/asset.
  3. If compatible, the handler asks the wallet to sign the payment.
  4. The wallet produces a signed payload (chain-specific format).
  5. The handler wraps the payload into an X-PAYMENT header.
The wallet never sees the HTTP request or response. It only receives the payment data to sign.

Further reading