<!-- tempo-docs-context -->
> Source: [/docs/sdk/foundry/mpp](https://tempo.xyz/developers/docs/sdk/foundry/mpp.md)
> Section: [Get Started](https://tempo.xyz/developers/get-started.md). Choose a starting point, send a test payment, get testnet funds, connect a coding agent, and find the SDKs and CLI.
> [Documentation index](https://tempo.xyz/developers/llms.txt) · [Docs skill](https://tempo.xyz/developers/SKILL.md)

> Tempo MCP: Use `search`, `find_pages`, `read_page`, and `code` at `https://mcp.tempo.xyz` for Tempo and related documentation.
> If an indexed page is missing or reflects an older site, read this site’s [documentation index](https://tempo.xyz/developers/llms.txt) and Markdown pages directly.

# Using MPP with Foundry

Foundry includes native MPP support on Tempo. Authorize a Tempo account, then use `cast`, `forge`, `anvil`, or `chisel` with a paid RPC URL. When the endpoint returns `402 Payment Required`, Foundry handles the payment challenge. These instructions target [Foundry v1.8.5](https://github.com/foundry-rs/foundry/releases/tag/v1.8.5).

:::warning[`tempo-foundry` is deprecated]
`tempo-foundry` and `foundryup -n tempo` are deprecated. Install the latest Foundry release with `foundryup`.
:::

Every Foundry tool works transparently with MPP-gated endpoints:

* **`cast`** — queries and transactions
* **`forge`** — scripts and forked tests
* **`anvil`** — local forks of paid endpoints
* **`chisel`** — interactive REPL sessions

## How MPP works with Foundry

When you point any Foundry tool at an MPP-gated RPC URL, the built-in transport intercepts `402` responses and resolves them using MPP's [session flow](https://tempo.xyz/developers/docs/guide/machine-payments/pay-as-you-go):

1. **First request** — Foundry sends a normal JSON-RPC request to the endpoint.
2. **402 challenge** — The server responds with `402 Payment Required` and a `WWW-Authenticate: Payment` header describing the price.
3. **Account discovery** — Foundry reads an authorized access key from the Tempo Accounts store at `$TEMPO_HOME/wallet/store.json` (default `~/.tempo/wallet/store.json`) for the challenge's chain.
4. **Channel open** — For a session challenge, Foundry opens a payment channel. When the server does not suggest a deposit, the fallback is `20,000` base units (`0.02` of a six-decimal token). Unused funds remain in the channel until it closes.
5. **Voucher payment** — Foundry signs an off-chain voucher and retries the request with an `Authorization: Payment` header.
6. **Channel reuse** — Later requests reuse the channel. Foundry persists channel state in a local SQLite store, separated by RPC origin, and tops up sessions within its automatic deposit limit.

Opening or topping up a channel requires an on-chain transaction. Requests paid with vouchers reuse the channel without a new on-chain payment each time.

## Foundry MPP setup

:::note
Some endpoints use a one-shot `charge` intent instead of session-based channels. Foundry handles both — charge payments sign a single TIP-20 transfer without opening a channel.
:::

:::steps
### Install the Tempo CLI

```bash
curl -fsSL https://tempo.xyz/install | bash
```

### Install Foundry

Tempo support now ships in the latest Foundry releases:

```bash
foundryup
```

All standard Foundry commands work as before — MPP activates only when an endpoint returns `402`.

<span id="configure-your-wallet" />

### Authorize your account

Authorize an access key for Tempo mainnet:

```bash
cast tempo login
```

Use `cast tempo login --no-browser` on a headless machine. The login stores the access-key private key in `~/.tempo/wallet/store.json`; it does not store your account's root key. Authorize the account and fund it for the network and currency requested by the endpoint before making paid requests.

### Use MPP endpoints

Point any Foundry tool at an MPP-gated RPC URL. No additional flags or config needed.

```bash
cast block-number --rpc-url https://rpc.mpp.tempo.xyz
```
:::

## Foundry MPP examples

### MPP requests with `cast`

Query chain state through a paid endpoint:

```bash
# Get latest block number
cast block-number --rpc-url https://rpc.mpp.tempo.xyz

# Read a contract
cast call 0x20c0000000000000000000006a37da5c996874be \
  "balanceOf(address)(uint256)" 0xYourAddress \
  --rpc-url https://rpc.mpp.tempo.xyz
```

### MPP requests in `forge script`

Run deployment or read scripts against a paid endpoint:

```solidity
// script/ReadBlock.s.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Script.sol";

contract ReadBlock is Script {
    function run() public view {
        console.log("block", block.number);
        console.log("chain", block.chainid);
    }
}
```

```bash
forge script script/ReadBlock.s.sol --rpc-url https://rpc.mpp.tempo.xyz
```

### MPP requests in forked `forge test`

Fork a paid endpoint in tests using `vm.createSelectFork`:

```solidity
// test/MppFork.t.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "forge-std/Test.sol";

contract MppForkTest is Test {
    function test_fork_via_mpp() public {
        vm.createSelectFork("https://rpc.mpp.tempo.xyz");
        assertGt(block.number, 0);
        assertEq(block.chainid, 4217);
    }
}
```

```bash
forge test --match-test test_fork_via_mpp -vvv
```

### MPP requests with Anvil

Fork a paid endpoint locally. Local RPC calls stay local, but any upstream fetches Anvil makes to the fork URL go through MPP:

```bash
anvil --fork-url https://rpc.mpp.tempo.xyz
```

### MPP requests with Chisel

Interactive REPL against a paid endpoint:

```bash
chisel --fork-url https://rpc.mpp.tempo.xyz
```

```
➜ block.number
Type: uint256
├ Hex: 0x...
└ Decimal: 1234567
```

## Foundry MPP configuration

### MPP deposit amount

Foundry v1.8.5 uses a fallback deposit and top-up amount of `20,000` base units, with an automatic session deposit limit of `1,000,000` base units. For a six-decimal token, these are `0.02` and `1` token. The server can suggest a deposit within the client limit. This limits the channel reserve, not cumulative spending across requests.

### MPP key discovery

Foundry reads the Tempo Accounts store at `$TEMPO_HOME/wallet/store.json` (default `~/.tempo/wallet/store.json`). Use `cast tempo login --chain-id <CHAIN_ID>` to authorize an access key on the network requested by the challenge.

### MPP channel persistence

Foundry reuses open channels across process invocations through a local SQLite channel store. Channel state is namespaced by RPC origin, so different services do not share the same local session state.

## Tempo MPP testnet workflow

Authorize an access key for Moderato, then use its testnet MPP endpoint:

```bash
cast tempo login --chain-id 42431
cast block-number --rpc-url https://rpc.mpp.moderato.tempo.xyz

# Mainnet
cast block-number --rpc-url https://rpc.mpp.tempo.xyz
```

Fund the authorized account on Moderato before making requests. Follow the [testnet faucet instructions](https://tempo.xyz/developers/docs/quickstart/faucet); mainnet and testnet balances are separate.

### MPP gas sponsorship

Some MPP endpoints sponsor the payment transaction's gas fees. When the challenge supports sponsorship, the server pays those fees. You still need funds for the service charge or channel deposit. Without sponsorship, Tempo transaction fees also require a supported fee token.

## Troubleshoot MPP with Foundry

| Error | Cause | Fix |
|---|---|---|
| `tempo: command not found` | Tempo CLI not installed | Run `curl -fsSL https://tempo.xyz/install \| bash` |
| Tempo Accounts store cannot provide a wallet | No usable access key for the payment challenge | Run `cast tempo login --chain-id <CHAIN_ID>`; use `--no-browser` on a headless machine |
| Insufficient balance | The authorized account cannot fund the payment | Follow the funding command printed by Foundry and check the network and currency |
| Access key authorization fails | The key is missing, expired, or lacks permission | Authorize a suitable key with `cast tempo login --chain-id <CHAIN_ID>` and retry |

## Next steps for MPP with Foundry

* [Client quickstart](https://tempo.xyz/developers/docs/guide/machine-payments/client) — Handle payment-gated resources with the TypeScript SDK
* [Agent quickstart](https://tempo.xyz/developers/docs/guide/machine-payments/agent) — Make paid requests from a terminal or AI agent
* [Pay-as-you-go](https://tempo.xyz/developers/docs/guide/machine-payments/pay-as-you-go) — Session-based billing with off-chain vouchers
