DISCLAIMER: SWITCHBOARD ON-DEMAND FOR SUI IS UNAUDITED. USE AT YOUR OWN RISK.
This guide covers the setup and use of Switchboard data feeds within your project, using the Aggregator
module for updating feeds and integrating Switchboard
in Move.
The Switchboard On-Demand service is currently deployed on the following networks:
- Mainnet: 0x0b884dbc39d915f32a82cc62dabad75ca3efd3c568c329eba270b03c6f58cbd8
- Testnet: 0x81fc6bbc64b7968e631b2a5b3a88652f91a617534e3755efab2f572858a30989
To use Switchboard On-Demand, add the following dependencies to your project:
npm install @switchboard-xyz/sui-sdk --save
bun add @switchboard-xyz/sui-sdk
pnpm add @switchboard-xyz/sui-sdk
Building a feed in Switchboard can be done using the Typescript SDK, or it can be done with the Switchboard Web App. Visit our docs for more on designing and creating feeds.
import {
CrossbarClient,
SwitchboardClient,
Aggregator,
ON_DEMAND_MAINNET_QUEUE,
ON_DEMAND_TESTNET_QUEUE,
} from "@switchboard-xyz/sui-sdk";
// for initial testing and development, you can use the public
// https://crossbar.switchboard.xyz instance of crossbar
const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz");
// ... define some jobs ...
const queue = isMainnetSui ? ON_DEMAND_MAINNET_QUEUE : ON_DEMAND_TESTNET_QUEUE;
// Store some job definition
const { feedHash } = await crossbarClient.store(queue.pubkey.toBase58(), jobs);
// Create a SwitchboardClient using the SuiClient configured with your favorite RPC on testnet or mainnet
const sb = new SwitchboardClient(suiClient);
// try creating a feed
const feedName = "BTC/USDT";
// Require only one oracle response needed
const minSampleSize = 1;
// Allow update data to be up to 60 seconds old
const maxStalenessSeconds = 60;
// If jobs diverge more than 1%, don't allow the feed to produce a valid update
const maxVariance = 1e9;
// Require only 1 job response
const minJobResponses = 1;
//==========================================================
// Feed Initialization On-Chain
//==========================================================
let transaction = new Transaction();
// add the tx to the PTB
await Aggregator.initTx(sb, transaction, {
feedHash,
name: feedName,
authority: userAddress,
minSampleSize,
maxStalenessSeconds,
maxVariance,
minResponses: minJobResponses,
});
// Send the transaction
const res = await client.signAndExecuteTransaction({
signer: keypair,
transaction,
options: {
showEffects: true,
},
});
// Capture the created aggregator ID
let aggregatorId;
res.effects?.created?.forEach((c) => {
if (c.reference.objectId) {
aggregatorId = c.reference.objectId;
}
});
// Wait for transaction confirmation
await client.waitForTransaction({
digest: res.digest,
});
// Log the transaction effects
console.log(res);
With Switchboard On-Demand, passing the PTB (proof-to-be) into the feed update method handles the update automatically.
const aggregator = new Aggregator(sb, aggregatorId);
// Create the PTB transaction
let feedTx = new Transaction();
// Fetch and log the oracle responses
const response = await aggregator.fetchUpdateTx(feedTx);
console.log("Fetch Update Oracle Response: ", response);
// Send the transaction
const res = await client.signAndExecuteTransaction({
signer: keypair,
transaction: feedTx,
options: {
showEffects: true,
},
});
// Wait for transaction confirmation
await client.waitForTransaction({
digest: res.digest,
});
// Log the transaction effects
console.log({ aggregatorId, res });
Note: Ensure the Switchboard Aggregator update is the first action in your PTB or occurs before referencing the feed update.
To integrate Switchboard with Move, add the following dependencies to Move.toml:
[dependencies.Switchboard]
git = "https://github.com/switchboard-xyz/sui.git"
subdir = "on_demand/"
rev = "mainnet" # testnet or mainnet
[dependencies.Sui]
git = "https://github.com/MystenLabs/sui.git"
subdir = "crates/sui-framework/packages/sui-framework"
rev = "framework/mainnet" # testnet or mainnet
# override = true # Uncomment if you need to override the Sui dependency
Once dependencies are configured, updated aggregators can be referenced easily.
In the example.move module, use the Aggregator and CurrentResult types to access the latest feed data.
module example::switchboard;
use switchboard::aggregator::{Aggregator, CurrentResult};
use switchboard::decimal::Decimal;
public entry fun use_switchboard_value(aggregator: &Aggregator) {
// Get the latest update info for the feed
let current_result = aggregator.current_result();
// Access various result properties
let result: Decimal = current_result.result(); // Median result
let result_u128: u128 = result.value(); // Result as u128
let min_timestamp_ms: u64 = current_result.min_timestamp_ms(); // Oldest data timestamp
let max_timestamp_ms: u64 = current_result.max_timestamp_ms(); // Latest data timestamp
let range: Decimal = current_result.range(); // Range of results
let mean: Decimal = current_result.mean(); // Average (mean)
let stdev: Decimal = current_result.stdev(); // Standard deviation
let max_result: Decimal = current_result.max_result();// Max result
let min_result: Decimal = current_result.min_result();// Min result
let neg: bool = result.neg(); // Check if negative (ignore for prices)
// Use the computed result as needed...
}
This implementation allows you to read and utilize Switchboard data feeds within Move. If you have any questions or need further assistance, please contact the Switchboard team.