> ## 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

> Setting up Solana and EVM payment handlers for the fetch wrapper.

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.

<Warning>
  `PaymentExecerV1` and `PaymentHandlerV1` are deprecated. Use `PaymentExecer` and `PaymentHandler` instead. See the [Client Types API reference](/api/types.src.Namespace.client) for migration details.
</Warning>

## Solana handler

```bash theme={null}
pnpm add @faremeter/payment-solana @faremeter/wallet-solana @solana/web3.js
```

```typescript theme={null}
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

```bash theme={null}
pnpm add @faremeter/payment-evm @faremeter/wallet-evm
```

```typescript theme={null}
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:

```typescript theme={null}
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)
```

```typescript theme={null}
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](/client/wallet-configuration#ows-open-wallet-standard) for full OWS setup details.

## Using both handlers

Register multiple handlers with the fetch wrapper to support both chains simultaneously:

```typescript theme={null}
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](/client/fetch-wrapper).

## Further reading

* [Fetch Wrapper](/client/fetch-wrapper) -- Registering handlers with `wrap()`.
* [Wallet Configuration](/client/wallet-configuration) -- Detailed setup for each wallet type.
* [Payment Schemes](/concepts/payment-schemes) -- How schemes work under the hood.
