> For the complete documentation index, see [llms.txt](https://docs.switchboard.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.switchboard.xyz/ai-agents-llms/switchboard-agent-skill/switchboard-evm-feeds.md).

# Switchboard EVM Feeds Skill

## Purpose

Integrate Switchboard on-demand feeds into EVM contracts and bots:

* Fetch verifiable update payloads off-chain
* Submit updates on-chain via the Switchboard contract (pay required fee)
* Read verified feed results and enforce freshness/deviation constraints
* Support “cranking” patterns to emulate push/heartbeat feeds

## Dependencies

Use exact pins from the [SDK Version Matrix](/tooling/sdk-version-matrix.md).

* `@switchboard-xyz/common@5.8.2`
* `@switchboard-xyz/on-demand-solidity@1.1.0`
* `ethers@6.13.1`

## Preconditions

* `OperatorPolicy` exists (chainId, RPC allowlist, contract allowlist, spend limits).

## Inputs to Collect

Always collect:

* `chainId` + network name
* `rpcUrl`
* `crossbarUrl` (default: `https://crossbar.switchboard.xyz`)
* `switchboardContractAddress` (resolve from official deployments)
* `feedId` list (bytes32)

Collect safety policy only if relevant (risk-sensitive logic) or requested:

* `maxAgeSeconds`
* `maxDeviationBps`

## EVM Integration Invariants

* Always compute and pay fee (e.g., `getFee`) before `updateFeeds`.
* For safety-critical logic, accept `updates` as calldata and do update+read inside the same app function.

## Minimal Example

```solidity
function updateAndRead(bytes[] calldata updates, bytes32 feedId) external payable {
    uint256 fee = switchboard.getFee(updates);
    switchboard.updateFeeds{value: fee}(updates);
    switchboard.latestUpdate(feedId);
}
```

## Playbook

### 1) Resolve deployments and feeds

* Resolve `switchboardContractAddress` from official docs for the chain/network.
* Confirm it is allowlisted by `OperatorPolicy`.
* Obtain `feedId`(s) for the same network.

### 2) Fetch update payloads off-chain (Crossbar)

```ts
import { CrossbarClient } from "@switchboard-xyz/common";

const crossbarUrl = process.env.CROSSBAR_URL ?? "https://crossbar.switchboard.xyz";
const crossbar = new CrossbarClient(crossbarUrl);

// For Feed Builder/custom feeds, use the v2 feed-hash flow.
await crossbar.simulateFeed(feedId, false, undefined, network);

const response = await crossbar.fetchV2Update([feedId], {
  chain: "evm",
  network,
  use_timestamp: true,
});

if (!response.encoded) throw new Error("Crossbar returned no encoded update payload");

const updates = [response.encoded];
```

### 3) Contract-side recommended pattern (atomic update+use)

```solidity
function updateAndUse(bytes[] calldata updates, bytes32[] calldata feedIds) external payable {
    uint256 fee = switchboard.getFee(updates);
    require(msg.value >= fee, "InsufficientFee");

    switchboard.updateFeeds{value: fee}(updates);

    for (uint256 i = 0; i < feedIds.length; i++) {
        // Read latest verified update for feedIds[i]
        // Enforce maxAgeSeconds and maxDeviationBps in your app logic
    }

    // Optional refund of msg.value - fee
}
```

### 4) Client-side submit flow

```ts
import { ethers } from "ethers";

const switchboard = new ethers.Contract(switchboardContractAddress, SWITCHBOARD_ABI, signer);

const fee = await switchboard.getFee(updates);
const tx = await switchboard.updateFeeds(updates, { value: fee });
await tx.wait();

const latest = await switchboard.latestUpdate(feedId);
```

### 5) Cranking pattern (push-like / heartbeat imitation)

Use this when you want other callers to read `latestUpdate(feedId)` without providing `updates` each time.

Tradeoffs:

* Pros: cheaper reads for many consumers; simpler UI integrations.
* Cons: data can go stale between cranks; consumers must enforce staleness.

Crank loop:

```ts
async function crankOnce(feedIds: string[]) {
  const response = await crossbar.fetchV2Update(feedIds, {
    chain: "evm",
    network,
    use_timestamp: true,
  });

  if (!response.encoded) {
    throw new Error("Crossbar returned no encoded update payload");
  }

  const updates = [response.encoded];

  const fee = await switchboard.getFee(updates);
  const tx = await switchboard.updateFeeds(updates, { value: fee });
  await tx.wait();
}

// Example: crank every 15 seconds (tune to costs and requirements)
setInterval(() => crankOnce([feedId]).catch(console.error), 15_000);
```

Operational guidance:

* Use a dedicated keeper wallet with explicit spend limits.
* For liquidation/settlement flows, prefer atomic update+use even if a crank exists.

## Outputs

Produce an `EvmFeedIntegrationPlan` including:

* chainId/network + RPC/Crossbar URL
* resolved Switchboard contract address (and source)
* feedId(s)
* atomic update+use pattern (recommended) vs crank pattern (optional)
* fee strategy with spend caps
* optional safety policy (maxAge/maxDeviation) if requested

## Troubleshooting Checklist

* Fee too low → always call `getFee(updates)` and set `msg.value`
* Stale timestamp → fetch fresh updates; raise max age only for non-critical paths
* Wrong feed/network → verify feedId and deployment match chainId/network
* Feed Builder custom feed on EVM → use `simulateFeed(...)` and `fetchV2Update(...)`, not `fetchEVMResults(...)`
* `ORACLE_UNAVAILABLE` after successful simulation -> check managed oracle/gateway availability and oracle-side validation errors such as `RangeExceeded`; raw v2 `maxJobRangePct` must be scaled by `1e9`

## References

* <https://docs.switchboard.xyz/docs-by-chain/evm>
* <https://docs.switchboard.xyz/docs-by-chain/evm/price-feeds>
* <https://docs.switchboard.xyz/tooling/crossbar>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.switchboard.xyz/ai-agents-llms/switchboard-agent-skill/switchboard-evm-feeds.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
