> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://viem-j480k1sbk-wevm.vercel.app/api/mcp` to find what you need.

# `withRelay`

Connects to a remote Tempo relay or applies relay plugins directly to a transport.

* [View Guide](https://docs.tempo.xyz/guide/payments/sponsor-user-fees)
* [View Specification](https://docs.tempo.xyz/protocol/transactions/spec-tempo-transaction)

In remote mode, `withRelay` forwards every `eth_fillTransaction` request to the relay and preserves the request's
`feePayer` value so the relay can decide whether to sponsor the transaction. It also forwards
multisig approvals, config and operation reads, and operation-aware transaction lookups. The relay
can therefore own the shared multisig store instead of each client.

* `feePayer: true` asks the relay to sponsor the transaction.
* If `feePayer` is omitted, `undefined`, or `null`, that value is forwarded as-is.
* An explicit `feePayer` address is preserved.

Transaction and receipt lookups query the default transport first. If no result exists,
Viem asks the relay whether the hash identifies a multisig operation and routes a
matching operation lookup through the relay. Other lookups retain the default result.

Requests to `eth_call` and `eth_estimateGas` with `requireFunds` also go to the relay for funding resolution. Calls and estimates without funding requirements use the default transport.

## Usage

### Remote Mode

:::code-group
```ts twoslash [example.ts]
import { privateKeyToAccount } from 'viem/accounts'
import { createClient, http, withRelay } from 'viem/tempo'

// See https://viem.sh/tempo/guides/relay/run for instructions on running a relay.
const client = createClient({
  account: privateKeyToAccount('0x...'),
  testnet: true,
  transport: withRelay(
    http(),                             // ← Default Transport
    http('https://relay.example.com'),  // ← Relay Transport // [!code hl]
  ),
})

// Regular transaction
const receipt1 = await client.sendTransactionSync({
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
})

// Sponsored transaction // [!code hl]
const receipt2 = await client.sendTransactionSync({ // [!code hl]
  feePayer: true, // [!code hl]
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb', // [!code hl]
})
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
// [!include ~/snippets/tempo/viem.config.ts:setup]
```
:::

#### Example Relay Service

Connect to a relay configured with the
[fee-payer plugin](/tempo/relay/plugins/fee-payer) to sponsor requests.

:::code-group
```ts twoslash [client.ts]
import { privateKeyToAccount } from 'viem/accounts'
import { createClient, http, withRelay } from 'viem/tempo'

// See https://viem.sh/tempo/guides/relay/run for instructions on running a relay.
const client = createClient({
  account: privateKeyToAccount('0x...'),
  testnet: true,
  transport: withRelay(
    http(),
    http('http://localhost:3000'),
  ),
})

const hash = await client.sendTransactionSync({
  feePayer: true,
  to: '0x0000000000000000000000000000000000000000',
})
```
:::

### Local Mode

```ts twoslash
import { createClient, http } from 'viem'
import { tempo } from 'viem/chains'
import { Relay, Store, withRelay } from 'viem/tempo'

const client = createClient({
  chain: tempo,
  transport: withRelay(http(), { // [!code focus]
    plugins: [Relay.multisig({ store: Store.memory() })], // [!code focus]
  }), // [!code focus]
})
```

Local plugins wrap the default transport directly. See the [available plugins](/tempo/guides/relay/connect#connect-to-a-local-relay)
for sponsorship, fee-token resolution, simulation, and multisig coordination.
Memory storage is process-local; independent multisig clients must share persistent atomic storage.

## Return Type

Remote mode returns `Transport<'relay', { multisig: true }>`. Local mode preserves
the default transport's attributes and RPC schema. It advertises multisig support
when a multisig plugin or the underlying transport provides it.

## Parameters

### defaultTransport

* **Type:** `Transport`

The execution transport. Local mode wraps this transport directly. Remote mode
uses it for ordinary requests and broadcasting with the `sign-only` policy.

### relayTransport

* **Type:** `Transport | Transport.withRelay.LocalOptions`

Pass a transport to connect to a remote relay, or an options object to run plugins
locally. Plugins run in array order; an empty array forwards requests unchanged.
Local options also accept `resolveTokens`, shared by fee selection and sponsorship.

### parameters.policy

* **Type:** `'sign-only' | 'sign-and-broadcast'`
* **Default:** `'sign-only'`

Available only in remote mode. For sponsored non-multisig transactions,
`sign-only` requests a signature from the relay and broadcasts through the default
transport. `sign-and-broadcast` submits through the relay. Multisig submissions
always use the relay for coordination.
