Part 2: Deploying your Feed On-Chain
Deploying Your Feed On-Chain using Typescript
This section provides the steps necessary to take your simulated feed definition and deploy it live to Solana/SVM, building on the design steps completed previously.
Prerequisites:
Successful completion of Section 1 (Designing and Simulating Your Feed).
A funded Solana Keypair file. Use the Solana CLI tool: Alternatively, you should note that each solana keypair file is essentially the representation of a private key in the format of an array with numbers like this:
[66,46,178,32,49, ...]solana-keygen new --outfile path/to/solana-keypair.json
Steps
Import Dependencies: Add the necessary
@switchboard-xyz/on-demanddependencies to yourindex.tsfile, which allow for Solana commands. Make sure you replace theindex.tswhich you'll want to deploy:import { AnchorUtils, PullFeed, getDefaultQueue, getDefaultDevnetQueue, asV0Tx, } from "@switchboard-xyz/on-demand"; import { CrossbarClient, OracleJob } from "@switchboard-xyz/common";Get the Queue: Obtain an instance of the Switchboard queue. This is typically done after a successful simulation step. Remember, queues in the context of Switchboard are subnets of Oracles that respond to feed updates.
Call
getDefaultQueue(solanaRPCUrl: string)to pull the Switchboard Mainnet Queue. CallinggetDefaultDevnetQueue(solanaRPCUrl: string)will pull the Switchboard Devnet queue.// Get the queue for the network you're deploying on let queue = await getDefaultQueue(connection.rpcUrl);[Optional] Store with Crossbar: For ease of use, and displaying your Jobs on the Explorer, you should store your feeds with CrossBar. This is a service that will store valid Job definitions on IPFS.
// Get the default crossbar server client const crossbarClient = CrossbarClient.default(); // Upload jobs to Crossbar, which pins valid feeds on ipfs // Feeds are associated with a specific queue, which is why we need to pass it in const { feedHash } = await crossbarClient.store(queue.pubkey.toBase58(), jobs);Load the Payer Keypair: Retrieve your Solana payer's loaded account. Ensure that it’s funded for pull feed creation to work.
// Get the payer keypair const payer = await AnchorUtils.initKeypairFromFile( "path/to/solana-keypair.json" ); console.log("Using Payer:", payer.publicKey.toBase58(), "\n");Generate a new pull feed object: This is just generating a new keypair associated with the PullFeedAccountData, and creating a wrapper object
const [pullFeed, feedKeypair] = PullFeed.generate(queue.program);Initialise the feed: Now, create the feed with all the required specs. Be mindful of parameters such as maximum variance and other values which determine the data feed.
// Get the initialization for the pull feeds const ix = await pullFeed.initIx({ name: "BTC Price Feed", // the feed name (max 32 bytes) queue: queue.pubkey, // the queue of oracles to bind to maxVariance: 1.0, // the maximum variance allowed for the feed results minResponses: 1, // minimum number of responses of jobs to allow feedHash: Buffer.from(feedHash.slice(2), "hex"), // the feed hash minSampleSize: 1, // The minimum number of samples required for setting feed value maxStaleness: 60, // The maximum number of slots that can pass before a feed value is considered stale. payer: payer.publicKey, // the payer of the feed });Create the Transaction and Simulation Check: Create the transaction and configure it so it can be sent to a Solana Validator. This example uses the
asV0Tx, a convenience function that's not necessary (but can be useful) for building transactions with priority fees.// Generate VersionedTransaction const tx = await asV0Tx({ connection: queue.program.provider.connection, ixs: [ix], payer: payer.publicKey, signers: [payer, feedKeypair], computeUnitPrice: 75_000, computeUnitLimitMultiple: 1.3, }); // Simulate the transaction const simulateResult = await queue.program.provider.connection.simulateTransaction(tx, { commitment: "processed", }); console.log(simulateResult); // Send transaction to validator const sig = await queue.program.provider.connection.sendTransaction(tx, { preflightCommitment: "processed", skipPreflight: true, }); // Finished! console.log(`Feed ${feedKeypair.publicKey} initialized: ${sig}`);
Congratulations, you have now created and fully deployed a feed using typescript on chain.
NOTE: If you need some help make sure to look at our update examples repo here.
Final Result
The assembled contract should go through the steps we've built:
Configure the OracleJobs and Simulate
Pick the queue for the target network (Mainnet or Devnet)
Store with Crossbar so it's visible in the explorer
Build the PullFeed's
initIxinstructionBuild and send the transaction on Solana
index.ts
Example output:
If it's successful, you should see a successful simulation in the console. Just to verify that the account was initialised correctly, search for the printed key or signature on a Solana Explorer.
Once your feed has been successfully created, take note of your feed's public key and move on to part 3.
Last updated