Integrating your Feed On-Chain
This guide provides a comprehensive walkthrough of integrating Switchboard feeds into your Solidity smart contracts on EVM-compatible chains.
1. Understanding Switchboard's Diamond Pattern
Switchboard contracts use the Diamond Pattern. To simplify modular contract design it presents a single unchanging contract address. Traditional explorers cannot easily locate the verified contract, so this solution has been developed to make this process easier.
To help with this issue, we recommend the using louper.dev. This can be used for for seamless contract analysis and function calls. This is a custom diamond explorer, specifically designed to interact with Switchboard diamond contracts.
2. Installation
Before you begin, install these items:
Switchboard On-Demand Solidity SDK:
Forge (Optional):
If you are working with Forge, include this in your remappings.txt file:
3. Minimal Integration
To minimise dependencies, you can integrate Switchboard feeds by defining only function signatures and structures.
4. Solidity Walkthrough
Let’s walk through how to use Switchboard feeds in your Solidity code:
Import Statements:
ISwitchboard
: Defining the core implementation of the Switchboard contract interface.Structs
: Contract containing the data formats used within the Switchboard structure.
Contract Definition:
Within the
Example
contract:switchboard
is the reference to the diamond contract, it can be found in Technical ResourcesaggregatorId
that we're interested in reading. If you don't have an aggregatorId yet, create a feed by following: Designing a Feed (EVM).
Function Boilerplate:
Here we're adding the function to get feed data. The idea is that we'll pass in an encoded Switchboard update (or set of updates) that will be used to update the
aggregatorId
of our choice. We can then read our recently-written update safely.
Adding a Fee:
Here we're doing a few things relating to update fees.
We're adding a new error,
that will be used if the submitted transaction value isn't enough to cover the update.
We're calling
to get the cost of submitting a Switchboard update programmatically from the Switchboard program.
We're enforcing that users pay for fees before submitting any updates.
Submitting Updates:
This line updates feed values in the Switchboard contract, and sends the required fee. Internally, each update is parsed and encoded signatures are verified and checked against the list of valid oracles on a given chain.
This
bytes[] calldata
parameter keeps things simple by making common Switchboard updates into one data-type. Everything is handled behind the scenes.The
{ value: fee }
in the call sendsfee
wei over to the Switchboard contract as payment for updates. The intent here is to pay for the updates.Checking Validated Data:
Here we're pulling the result out of the latest update. Switchboard updates are encoded as int128's. Another important fact is that values are decimals scaled up by 10^18.
For example, the value
would represent
Next, we check that the value is positive and revert with an
if it isn't. Finally, if the update was successful, we emit a FeedData event.
Putting It All Together: (Full Example.Sol)
Review
This contract:
Sets the Switchboard contract address and
feed ID
in the constructorDefines a function
getFeedData
Checks if the transaction fee is paid, using
switchboard.getFee(bytes[] calldata updates)
.Submits the updates to the Switchboard contract using
switchboard.updateFeeds(bytes[] calldata updates)
.Reads the latest value from the feed using
switchboard.getLatestValue(bytes32 aggregatorId)
.Emits the latest result from the feed.
Follow the next section to understand how to use data feeds with Typescript
Last updated