---
sidebar_position: 30
title: Data Feeds
---

import { Box, Typography, Grid } from "@mui/material";
import Link from "@docusaurus/Link";
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<!--
<Typography variant="h4">
  <Link to="https://github.com/switchboard-xyz/switchboard-v2/tree/main/programs/anchor-feed-parser">
    # anchor-feed-parser
  </Link>
</Typography>
-->

## Reading a Data Feed

<Tabs>
    <TabItem value="Rust" label="Rust" default>

```rust
use switchboard_v2::AggregatorAccountData;
use std::convert::TryInto;

let feed_result = AggregatorAccountData::new(feed_account_info)?.get_result()?;

let decimal: f64 = feed_result.try_into()?;
```

  </TabItem>
  <TabItem value="Typescript" label="Typescript">

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  loadSwitchboardProgram,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
const program = await loadSwitchboardProgram("devnet", undefined, payer);

const aggregatorAccount = new AggregatorAccount({
  program,
  publicKey: aggregatorKey,
});

const latestResult = await aggregatorAccount.getLatestValue();
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 aggregator print AGGREGATORKEY
# OR
sbv2 aggregator watch AGGREGATORKEY
```

  </TabItem>
</Tabs>

## Creating a Data Feed

- `aggregatorInit`
- `leaseInit`
- `jobInit`
- `permissionInit`
- `aggregatorAddJob`

<Tabs>
  <TabItem value="Typescript" label="Typescript" default>

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  loadSwitchboardProgram,
  LeaseAccount,
  OracleQueueAccount,
  SwitchboardPermission,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
let authority: Keypair; // queue authority
const program = await loadSwitchboardProgram("devnet", undefined, payer);
const queueAccount = new OracleQueueAccount({
  program,
  publicKey: queuePubkey,
});

// aggregator
const aggregatorAccount = await AggregatorAccount.create(program, {
  name: Buffer.from("MY SOL/USD Feed"),
  batchSize: 1,
  minRequiredOracleResults: 1,
  minRequiredJobResults: 1,
  minUpdateDelaySeconds: 10,
  queueAccount,
  authority: authority.publicKey,
});

// permission
const permissionAccount = await PermissionAccount.create(program, {
  authority: authority.publicKey,
  granter: queueAccount.publicKey,
  grantee: aggregatorAccount.publicKey,
});
await aggregatorPermission.set({
  authority,
  permission: SwitchboardPermission.PERMIT_ORACLE_QUEUE_USAGE,
  enable: true,
});

// lease
const leaseContract = await LeaseAccount.create(program, {
  loadAmount: new anchor.BN(0),
  funder: tokenAccount,
  funderAuthority: authority,
  oracleQueueAccount: queueAccount,
  aggregatorAccount,
});

// job
const tasks: OracleJob.Task[] = [
  OracleJob.Task.create({
    httpTask: OracleJob.HttpTask.create({
      url: `https://ftx.us/api/markets/SOL_USD`,
    }),
  }),
  OracleJob.Task.create({
    jsonParseTask: OracleJob.JsonParseTask.create({ path: "$.result.price" }),
  }),
];
const jobData = Buffer.from(
  OracleJob.encodeDelimited(
    OracleJob.create({
      tasks,
    })
  ).finish()
);
const jobKeypair = anchor.web3.Keypair.generate();
const jobAccount = await JobAccount.create(program, {
  data: jobData,
  keypair: jobKeypair,
  authority: authority.publicKey,
});

// add job to aggregator
await aggregatorAccount.addJob(jobAccount, authority);
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 aggregator create AGGREGATORKEY \
    --name "My Buffer" \
    --keypair "path/to/payer/keypair.json" \
    --batchSize 1 \
    --minOracles 1 \
    --minJobs 1 \
    --updateInterval 45 \
    --job "path/to/job-definition-1.json" \
    --job "path/to/job-definition-2.json" \
    --verbose
```

  </TabItem>
</Tabs>

## Funding a Data Feed

- `leeaseExtend`

<Tabs>
  <TabItem value="Typescript" label="Typescript" default>

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  loadSwitchboardProgram,
  LeaseAccount,
  OracleQueueAccount,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
let amount = new anchor.BN(1_000_000_000);
let authority: Keypair; // queue authority
const program = await loadSwitchboardProgram("devnet", undefined, payer);
const queueAccount = new OracleQueueAccount({
  program,
  publicKey: queuePubkey,
});
const mint = await queueAccount.loadMint();

const funderTokenAccount = (
  await mint.getOrCreateAssociatedAccountInfo(payer.publicKey)
).address;

const signature = await leaseAccount.extend({
  loadAmount: amount,
  funder: funderTokenAccount,
  funderAuthority: payer,
});
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 lease extend AGGREGATORKEY \
    --keypair "path/to/payer/keypair.json" \
    --authority "path/to/authority/keypair.json" \
    --amount 0.1
```

  </TabItem>
</Tabs>

## Requesting a Feed Update

- `openRound`

<Tabs>
  <TabItem value="Typescript" label="Typescript" default>

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  loadSwitchboardProgram,
  LeaseAccount,
  OracleQueueAccount,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
let amount = new anchor.BN(1_000_000_000);
let authority: Keypair; // queue authority
const program = await loadSwitchboardProgram("devnet", undefined, payer);
const queueAccount = new OracleQueueAccount({
  program,
  publicKey: queuePubkey,
});
const mint = await queueAccount.loadMint();

const payoutWallet = (
  await mint.getOrCreateAssociatedAccountInfo(payer.publicKey)
).address;

const aggregatorAccount = new AggregatorAccount({
  program,
  publicKey: aggregatorKey,
});

const signature = await aggregatorAccount.openRound({
  queueAccount,
  payoutWallet,
});
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 aggregator update AGGREGATORKEY \
    --keypair "path/to/payer/keypair.json" \
```

  </TabItem>
</Tabs>

## Push to Crank

- `crankPush`

<Tabs>
  <TabItem value="Typescript" label="Typescript" default>

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  CrankAccount,
  loadSwitchboardProgram,
  LeaseAccount,
  OracleQueueAccount,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
const program = await loadSwitchboardProgram("devnet", undefined, payer);

const aggregatorAccount = new AggregatorAccount({
  program,
  publicKey: aggregatorKey,
});
const aggregator = await aggregatorAccount.loadData();

const queueAccount = new OracleQueueAccount({
  program,
  publicKey: aggregator.queuePubkey,
});
const mint = await queueAccount.loadMint();

const crankAccount = new CrankAccount({ program, publicKey: crankKey });
const crank = await crankAccount.loadData();

await crankAccount.push({ aggregatorAccount });
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 crank push CRANKKEY AGGREGATORKEY \
    --keypair "path/to/payer/keypair.json"
```

  </TabItem>
</Tabs>

## Add History Buffer

- `aggregatorSetHistoryBuffer`

<Tabs>
  <TabItem value="Typescript" label="Typescript" default>

```ts
import * as anchor from "@project-serum/anchor";
import { Keypair } from "@solana/web3.js";
import {
  AggregatorAccount,
  CrankAccount,
  loadSwitchboardProgram,
  LeaseAccount,
  OracleQueueAccount,
} from "@switchboard-xyz/switchboard-v2";

let payer: Keypair;
let authority: Keypair; // feed authority
const program = await loadSwitchboardProgram("devnet", undefined, payer);

const aggregatorAccount = new AggregatorAccount({
  program,
  publicKey: aggregatorKey,
});
const aggregator = await aggregatorAccount.loadData();

const signature = await aggregatorAccount.setHistoryBuffer({ authority, size });
```

  </TabItem>
  <TabItem value="CLI" label="CLI">

```bash
sbv2 aggregator set history AGGREGATORKEY SIZE \
    --keypair "path/to/payer/keypair.json"
```

  </TabItem>
</Tabs>
