added usages
This commit is contained in:
parent
4903b255b3
commit
fdf620ccec
|
@ -1,26 +1,19 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>Switchboard V2</h1>
|
||||
<!-- commonheader -->
|
||||
|
||||
<p>A collection of libraries and examples for interacting with Switchboard V2 on Solana.</p>
|
||||
<!-- commonheaderstop -->
|
||||
|
||||
<p>
|
||||
<a href="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml">
|
||||
<img alt="Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml">
|
||||
<img alt="Anchor Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg" />
|
||||
</a>
|
||||
<a href="https://crates.io/crates/switchboard-v2">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/v/switchboard-v2?label=switchboard-v2&logo=rust" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">
|
||||
<img alt="NPM Badge" src="https://img.shields.io/github/package-json/v/switchboard-xyz/sbv2-solana?color=red&filename=javascript%2Fsolana.js%2Fpackage.json&label=%40switchboard-xyz%2Fsolana.js&logo=npm" />
|
||||
</a>
|
||||
</p>
|
||||
# Switchboard V2
|
||||
|
||||
A collection of libraries and examples for interacting with Switchboard V2 on
|
||||
Solana.
|
||||
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
|
||||
|
||||
[](https://crates.io/crates/switchboard-v2)
|
||||
[](https://www.npmjs.com/package/@switchboard-xyz/solana.js)
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,37 +1,19 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>@switchboard-xyz/solana.js</h1>
|
||||
<!-- commonheader -->
|
||||
|
||||
<p>A Typescript client to interact with Switchboard V2 on Solana.</p>
|
||||
<!-- commonheaderstop -->
|
||||
|
||||
<p>
|
||||
<img alt="Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg" />
|
||||
<a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">
|
||||
<img alt="NPM Badge" src="https://img.shields.io/github/package-json/v/switchboard-xyz/sbv2-solana?color=red&filename=javascript%2Fsolana.js%2Fpackage.json&label=%40switchboard-xyz%2Fsolana.js&logo=npm" />
|
||||
</a>
|
||||
</p>
|
||||
# @switchboard-xyz/solana.js
|
||||
|
||||
<p>
|
||||
<a href="https://discord.gg/switchboardxyz">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/841525135311634443?color=blueviolet&logo=discord&logoColor=white" />
|
||||
</a>
|
||||
<a href="https://twitter.com/switchboardxyz">
|
||||
<img alt="Twitter" src="https://img.shields.io/twitter/follow/switchboardxyz?label=Follow+Switchboard" />
|
||||
</a>
|
||||
</p>
|
||||
> A Typescript client to interact with Switchboard V2 on Solana.
|
||||
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
|
||||
|
||||
[](https://www.npmjs.com/package/@switchboard-xyz/solana.js)
|
||||
[](https://docs.switchboard.xyz/api/solana.js)
|
||||
|
||||
<h4>
|
||||
<strong>Npm: </strong><a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">npmjs.com/package/@switchboard-xyz/solana.js</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<strong>Typedocs: </strong><a href="https://docs.switchboard.xyz/api/@switchboard-xyz/solana.js">docs.switchboard.xyz/api/@switchboard-xyz/solana.js</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<strong>Sbv2 Solana SDK: </strong><a href="https://github.com/switchboard-xyz/sbv2-solana">github.com/switchboard-xyz/sbv2-solana</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
## Install
|
||||
|
@ -45,4 +27,3 @@ npm i --save @switchboard-xyz/solana.js
|
|||
<!-- usage -->
|
||||
|
||||
<!-- usagestop -->
|
||||
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
import { QueueAccount } from "@switchboard-xyz/solana.js";
|
||||
import { OracleJob } from "@switchboard-xyz/common";
|
||||
|
||||
const queueAccount = new QueueAccount(program, queuePubkey);
|
||||
|
||||
const [aggregatorAccount, aggregatorInitSignatures] =
|
||||
await queueAccount.createFeed({
|
||||
batchSize: 1,
|
||||
minRequiredOracleResults: 1,
|
||||
minRequiredJobResults: 1,
|
||||
minUpdateDelaySeconds: 60,
|
||||
fundAmount: 2.5, // deposit 2.5 wSOL into the leaseAccount escrow
|
||||
jobs: [
|
||||
{ pubkey: jobAccount.publicKey },
|
||||
{
|
||||
weight: 2,
|
||||
data: OracleJob.encodeDelimited(
|
||||
OracleJob.fromObject({
|
||||
tasks: [
|
||||
{
|
||||
valueTask: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
).finish(),
|
||||
},
|
||||
],
|
||||
});
|
||||
const aggregator = await aggregatorAccount.loadData();
|
|
@ -0,0 +1,12 @@
|
|||
import { QueueAccount } from "@switchboard-xyz/solana.js";
|
||||
|
||||
const queueAccount = new QueueAccount(program, queuePubkey);
|
||||
|
||||
const [oracleAccount, oracleInitSignature] = await queueAccount.createOracle({
|
||||
name: "My Oracle",
|
||||
metadata: "Oracle #1",
|
||||
stakeAmount: 10,
|
||||
});
|
||||
const oracle = await oracleAccount.loadData();
|
||||
|
||||
await oracleAccount.heartbeat();
|
|
@ -0,0 +1,14 @@
|
|||
import {
|
||||
AggregatorAccount,
|
||||
AggregatorHistoryBuffer,
|
||||
} from "@switchboard-xyz/solana.js";
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
const aggregator = await aggregatorAccount.loadData();
|
||||
|
||||
const [historyBuffer, addHistorySignature] =
|
||||
await AggregatorHistoryBuffer.create(program, {
|
||||
aggregatorAccount,
|
||||
maxSamples: 10000,
|
||||
});
|
||||
const history = await historyBuffer.loadData();
|
|
@ -5,3 +5,21 @@ snippets:
|
|||
- name: "Create a Queue"
|
||||
description: ""
|
||||
filename: "create-queue.ts"
|
||||
- name: "Add an Oracle"
|
||||
description: ""
|
||||
filename: "add-an-oracle.ts"
|
||||
- name: "Add a Data Feed"
|
||||
description: ""
|
||||
filename: "add-a-data-feed.ts"
|
||||
- name: "Request a New Value"
|
||||
description: ""
|
||||
filename: "request-a-new-value.ts"
|
||||
- name: "Read a Data Feed"
|
||||
description: "After the oracles respond, read the feed result"
|
||||
filename: "read-data-feed.ts"
|
||||
- name: "Add a History Buffer"
|
||||
description: "Optionally, add a history buffer to your feed to store the last N historical samples"
|
||||
filename: "add-history-buffer.ts"
|
||||
- name: "Watch Data Feed"
|
||||
description: "Setup a websocket listener to invoke a callback whenever an aggregator is updated"
|
||||
filename: "watch-data-feed.ts"
|
|
@ -0,0 +1,10 @@
|
|||
import Big from "big.js";
|
||||
import { AggregatorAccount } from "@switchboard-xyz/solana.js";
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
const result: Big | null = await aggregatorAccount.fetchLatestValue();
|
||||
if (result === null) {
|
||||
throw new Error("Aggregator holds no value");
|
||||
}
|
||||
console.log(result.toString());
|
|
@ -0,0 +1,5 @@
|
|||
import { AggregatorAccount } from "@switchboard-xyz/solana.js";
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
await aggregatorAccount.openRound();
|
|
@ -0,0 +1,11 @@
|
|||
import Big from 'big.js';
|
||||
import { AggregatorAccount } from '@switchboard-xyz/solana.js';
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
const ws = aggregatorAccount.onChange(aggregator => {
|
||||
const result = AggregatorAccount.decodeLatestValue(aggregator);
|
||||
if (result !== null) {
|
||||
console.log(result.toString());
|
||||
}
|
||||
});
|
|
@ -1,17 +1,15 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>switchboard-v2</h1>
|
||||
<!-- commonheader -->
|
||||
|
||||
<p>A Rust library to interact with Switchboard accounts on Solana.</p>
|
||||
<!-- commonheaderstop -->
|
||||
|
||||
# switchboard-v2
|
||||
|
||||
> A Rust library to interact with Switchboard accounts on Solana.
|
||||
|
||||
[](https://crates.io/crates/switchboard-v2)
|
||||
|
||||
<p>
|
||||
<a href="https://crates.io/crates/switchboard-v2">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/v/switchboard-v2?label=switchboard-v2&logo=rust" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## Install
|
||||
|
|
|
@ -1,12 +1,33 @@
|
|||
snippets:
|
||||
- name: "Read Latest Result"
|
||||
filename: "read-result.rs"
|
||||
description:
|
||||
pre: |
|
||||
Read an aggregator result on-chain
|
||||
|
||||
post: |
|
||||
**Example(s)**:
|
||||
[anchor-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-feed-parser/src/lib.rs),
|
||||
[native-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/native-feed-parser/src/lib.rs)
|
||||
|
||||
filename: "read-result.rs"
|
||||
- [anchor-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-feed-parser/src/lib.rs)
|
||||
- [native-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/native-feed-parser/src/lib.rs)
|
||||
- name: "Read History Buffer"
|
||||
filename: "read-history.rs"
|
||||
description:
|
||||
pre: |
|
||||
**_Note: The Aggregator must have a history buffer initialized before using_**
|
||||
- name: "Read VRF"
|
||||
filename: "read-vrf.rs"
|
||||
description:
|
||||
post: |
|
||||
**Example**:
|
||||
- [anchor-vrf-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-vrf-parser/src/actions/update_result.rs)
|
||||
- name: "Request Randomness CPI"
|
||||
filename: "request-randomness.rs"
|
||||
description:
|
||||
post: |
|
||||
**Example**:
|
||||
- [anchor-vrf-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-vrf-parser/src/actions/request_result.rs)
|
||||
- name: "Read Buffer Relayer"
|
||||
filename: "read-buffer.rs"
|
||||
description:
|
||||
post: |
|
||||
**Example**:
|
||||
- [anchor-buffer-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-buffer-parser/src/lib.rs)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
use anchor_lang::solana_program::clock;
|
||||
use std::convert::TryInto;
|
||||
use switchboard_v2::{BufferRelayerAccountData, SWITCHBOARD_PROGRAM_ID};
|
||||
|
||||
// check feed owner
|
||||
let owner = *aggregator.owner;
|
||||
if owner != SWITCHBOARD_PROGRAM_ID {
|
||||
return Err(error!(ErrorCode::InvalidSwitchboardAccount));
|
||||
}
|
||||
|
||||
// deserialize account info
|
||||
let buffer = BufferRelayerAccountData::new(feed_account_info)?;
|
||||
|
||||
// get result
|
||||
let buffer_result = buffer.get_result();
|
||||
|
||||
// check if feed has been updated in the last 5 minutes
|
||||
buffer.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
|
||||
|
||||
// convert buffer to a string
|
||||
let result_string = String::from_utf8(buffer.result)
|
||||
.map_err(|_| error!(ErrorCode::StringConversionFailed))?;
|
||||
msg!("Buffer string {:?}!", result_string);
|
|
@ -0,0 +1,6 @@
|
|||
use switchboard_v2::AggregatorHistoryBuffer;
|
||||
use std::convert::TryInto;
|
||||
|
||||
let history_buffer = AggregatorHistoryBuffer::new(history_account_info)?;
|
||||
let current_timestamp = Clock::get()?.unix_timestamp;
|
||||
let one_hour_ago: f64 = history_buffer.lower_bound(current_timestamp - 3600).unwrap().try_into()?;
|
|
@ -0,0 +1,11 @@
|
|||
use switchboard_v2::VrfAccountData;
|
||||
|
||||
// deserialize the account info
|
||||
let vrf = ctx.accounts.vrf.load()?;
|
||||
// OR
|
||||
let vrf = VrfAccountData::new(vrf_account_info)?;
|
||||
|
||||
// read the result
|
||||
let result_buffer = vrf.get_result()?;
|
||||
let value: &[u128] = bytemuck::cast_slice(&result_buffer[..]);
|
||||
let result = value[0] % 256000 as u128;
|
|
@ -0,0 +1,35 @@
|
|||
pub use switchboard_v2::{VrfAccountData, VrfRequestRandomness};
|
||||
|
||||
let switchboard_program = ctx.accounts.switchboard_program.to_account_info();
|
||||
|
||||
let vrf_request_randomness = VrfRequestRandomness {
|
||||
authority: ctx.accounts.state.to_account_info(),
|
||||
vrf: ctx.accounts.vrf.to_account_info(),
|
||||
oracle_queue: ctx.accounts.oracle_queue.to_account_info(),
|
||||
queue_authority: ctx.accounts.queue_authority.to_account_info(),
|
||||
data_buffer: ctx.accounts.data_buffer.to_account_info(),
|
||||
permission: ctx.accounts.permission.to_account_info(),
|
||||
escrow: ctx.accounts.escrow.clone(),
|
||||
payer_wallet: ctx.accounts.payer_wallet.clone(),
|
||||
payer_authority: ctx.accounts.payer_authority.to_account_info(),
|
||||
recent_blockhashes: ctx.accounts.recent_blockhashes.to_account_info(),
|
||||
program_state: ctx.accounts.program_state.to_account_info(),
|
||||
token_program: ctx.accounts.token_program.to_account_info(),
|
||||
};
|
||||
|
||||
let vrf_key = ctx.accounts.vrf.key.clone();
|
||||
let authority_key = ctx.accounts.authority.key.clone();
|
||||
|
||||
let state_seeds: &[&[&[u8]]] = &[&[
|
||||
&STATE_SEED,
|
||||
vrf_key.as_ref(),
|
||||
authority_key.as_ref(),
|
||||
&[bump],
|
||||
]];
|
||||
msg!("requesting randomness");
|
||||
vrf_request_randomness.invoke_signed(
|
||||
switchboard_program,
|
||||
params.switchboard_state_bump,
|
||||
params.permission_bump,
|
||||
state_seeds,
|
||||
)?;
|
29
README.md
29
README.md
|
@ -1,26 +1,17 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>Switchboard V2</h1>
|
||||

|
||||
|
||||
<p>A collection of libraries and examples for interacting with Switchboard V2 on Solana.</p>
|
||||
# Switchboard V2
|
||||
|
||||
<p>
|
||||
<a href="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml">
|
||||
<img alt="Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg" />
|
||||
</a>
|
||||
<a href="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml">
|
||||
<img alt="Anchor Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg" />
|
||||
</a>
|
||||
<a href="https://crates.io/crates/switchboard-v2">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/v/switchboard-v2?label=switchboard-v2&logo=rust" />
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">
|
||||
<img alt="NPM Badge" src="https://img.shields.io/github/package-json/v/switchboard-xyz/sbv2-solana?color=red&filename=javascript%2Fsolana.js%2Fpackage.json&label=%40switchboard-xyz%2Fsolana.js&logo=npm" />
|
||||
</a>
|
||||
</p>
|
||||
A collection of libraries and examples for interacting with Switchboard V2 on
|
||||
Solana.
|
||||
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
|
||||
|
||||
[](https://crates.io/crates/switchboard-v2)
|
||||
[](https://www.npmjs.com/package/@switchboard-xyz/solana.js)
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -1,37 +1,17 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>@switchboard-xyz/solana.js</h1>
|
||||

|
||||
|
||||
<p>A Typescript client to interact with Switchboard V2 on Solana.</p>
|
||||
# @switchboard-xyz/solana.js
|
||||
|
||||
<p>
|
||||
<img alt="Test Status" src="https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg" />
|
||||
<a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">
|
||||
<img alt="NPM Badge" src="https://img.shields.io/github/package-json/v/switchboard-xyz/sbv2-solana?color=red&filename=javascript%2Fsolana.js%2Fpackage.json&label=%40switchboard-xyz%2Fsolana.js&logo=npm" />
|
||||
</a>
|
||||
</p>
|
||||
> A Typescript client to interact with Switchboard V2 on Solana.
|
||||
|
||||
<p>
|
||||
<a href="https://discord.gg/switchboardxyz">
|
||||
<img alt="Discord" src="https://img.shields.io/discord/841525135311634443?color=blueviolet&logo=discord&logoColor=white" />
|
||||
</a>
|
||||
<a href="https://twitter.com/switchboardxyz">
|
||||
<img alt="Twitter" src="https://img.shields.io/twitter/follow/switchboardxyz?label=Follow+Switchboard" />
|
||||
</a>
|
||||
</p>
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
|
||||
[](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
|
||||
|
||||
[](https://www.npmjs.com/package/@switchboard-xyz/solana.js)
|
||||
[](https://docs.switchboard.xyz/api/solana.js)
|
||||
|
||||
<h4>
|
||||
<strong>Npm: </strong><a href="https://www.npmjs.com/package/@switchboard-xyz/solana.js">npmjs.com/package/@switchboard-xyz/solana.js</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<strong>Typedocs: </strong><a href="https://docs.switchboard.xyz/api/@switchboard-xyz/solana.js">docs.switchboard.xyz/api/@switchboard-xyz/solana.js</a>
|
||||
</h4>
|
||||
<h4>
|
||||
<strong>Sbv2 Solana SDK: </strong><a href="https://github.com/switchboard-xyz/sbv2-solana">github.com/switchboard-xyz/sbv2-solana</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
## Install
|
||||
|
@ -46,6 +26,12 @@ npm i --save @switchboard-xyz/solana.js
|
|||
|
||||
- [Load Switchboard Program](#load-switchboard-program)
|
||||
- [Create a Queue](#create-a-queue)
|
||||
- [Add an Oracle](#add-an-oracle)
|
||||
- [Add a Data Feed](#add-a-data-feed)
|
||||
- [Request a New Value](#request-a-new-value)
|
||||
- [Read a Data Feed](#read-a-data-feed)
|
||||
- [Add a History Buffer](#add-a-history-buffer)
|
||||
- [Watch Data Feed](#watch-data-feed)
|
||||
|
||||
### Load Switchboard Program
|
||||
|
||||
|
@ -82,3 +68,122 @@ const [queueAccount, txnSignature] = await QueueAccount.create(program, {
|
|||
});
|
||||
const queue = await queueAccount.loadData();
|
||||
```
|
||||
|
||||
### Add an Oracle
|
||||
|
||||
```ts
|
||||
import { QueueAccount } from '@switchboard-xyz/solana.js';
|
||||
|
||||
const queueAccount = new QueueAccount(program, queuePubkey);
|
||||
|
||||
const [oracleAccount, oracleInitSignature] = await queueAccount.createOracle({
|
||||
name: 'My Oracle',
|
||||
metadata: 'Oracle #1',
|
||||
stakeAmount: 10,
|
||||
});
|
||||
const oracle = await oracleAccount.loadData();
|
||||
|
||||
await oracleAccount.heartbeat();
|
||||
```
|
||||
|
||||
### Add a Data Feed
|
||||
|
||||
```ts
|
||||
import { QueueAccount } from '@switchboard-xyz/solana.js';
|
||||
import { OracleJob } from '@switchboard-xyz/common';
|
||||
|
||||
const queueAccount = new QueueAccount(program, queuePubkey);
|
||||
|
||||
const [aggregatorAccount, aggregatorInitSignatures] =
|
||||
await queueAccount.createFeed({
|
||||
batchSize: 1,
|
||||
minRequiredOracleResults: 1,
|
||||
minRequiredJobResults: 1,
|
||||
minUpdateDelaySeconds: 60,
|
||||
fundAmount: 2.5, // deposit 2.5 wSOL into the leaseAccount escrow
|
||||
jobs: [
|
||||
{ pubkey: jobAccount.publicKey },
|
||||
{
|
||||
weight: 2,
|
||||
data: OracleJob.encodeDelimited(
|
||||
OracleJob.fromObject({
|
||||
tasks: [
|
||||
{
|
||||
valueTask: {
|
||||
value: 1,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
).finish(),
|
||||
},
|
||||
],
|
||||
});
|
||||
const aggregator = await aggregatorAccount.loadData();
|
||||
```
|
||||
|
||||
### Request a New Value
|
||||
|
||||
```ts
|
||||
import { AggregatorAccount } from '@switchboard-xyz/solana.js';
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
await aggregatorAccount.openRound();
|
||||
```
|
||||
|
||||
### Read a Data Feed
|
||||
|
||||
After the oracles respond, read the feed result
|
||||
|
||||
```ts
|
||||
import Big from 'big.js';
|
||||
import { AggregatorAccount } from '@switchboard-xyz/solana.js';
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
const result: Big | null = await aggregatorAccount.fetchLatestValue();
|
||||
if (result === null) {
|
||||
throw new Error('Aggregator holds no value');
|
||||
}
|
||||
console.log(result.toString());
|
||||
```
|
||||
|
||||
### Add a History Buffer
|
||||
|
||||
Optionally, add a history buffer to your feed to store the last N historical samples
|
||||
|
||||
```ts
|
||||
import {
|
||||
AggregatorAccount,
|
||||
AggregatorHistoryBuffer,
|
||||
} from '@switchboard-xyz/solana.js';
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
const aggregator = await aggregatorAccount.loadData();
|
||||
|
||||
const [historyBuffer, addHistorySignature] =
|
||||
await AggregatorHistoryBuffer.create(program, {
|
||||
aggregatorAccount,
|
||||
maxSamples: 10000,
|
||||
});
|
||||
const history = await historyBuffer.loadData();
|
||||
```
|
||||
|
||||
### Watch Data Feed
|
||||
|
||||
Setup a websocket listener to invoke a callback whenever an aggregator is updated
|
||||
|
||||
```ts
|
||||
import Big from 'big.js';
|
||||
import { AggregatorAccount } from '@switchboard-xyz/solana.js';
|
||||
|
||||
const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
|
||||
|
||||
const ws = aggregatorAccount.onChange(aggregator => {
|
||||
const result = AggregatorAccount.decodeLatestValue(aggregator);
|
||||
if (result !== null) {
|
||||
console.log(result.toString());
|
||||
}
|
||||
});
|
||||
```
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
<div align="center">
|
||||
<a href="#">
|
||||
<img src="https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png" />
|
||||
</a>
|
||||
|
||||
<h1>switchboard-v2</h1>
|
||||

|
||||
|
||||
<p>A Rust library to interact with Switchboard accounts on Solana.</p>
|
||||
# switchboard-v2
|
||||
|
||||
> A Rust library to interact with Switchboard accounts on Solana.
|
||||
|
||||
[](https://crates.io/crates/switchboard-v2)
|
||||
|
||||
<p>
|
||||
<a href="https://crates.io/crates/switchboard-v2">
|
||||
<img alt="Crates.io" src="https://img.shields.io/crates/v/switchboard-v2?label=switchboard-v2&logo=rust" />
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
## Install
|
||||
|
@ -34,6 +30,10 @@ switchboard-v2 = "0.1.23"
|
|||
**Directory**
|
||||
|
||||
- [Read Latest Result](#read-latest-result)
|
||||
- [Read History Buffer](#read-history-buffer)
|
||||
- [Read VRF](#read-vrf)
|
||||
- [Request Randomness CPI](#request-randomness-cpi)
|
||||
- [Read Buffer Relayer](#read-buffer-relayer)
|
||||
|
||||
### Read Latest Result
|
||||
|
||||
|
@ -66,5 +66,115 @@ feed.check_confidence_interval(SwitchboardDecimal::from_f64(0.80))?;
|
|||
```
|
||||
|
||||
**Example(s)**:
|
||||
[anchor-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-feed-parser/src/lib.rs),
|
||||
[native-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/native-feed-parser/src/lib.rs)
|
||||
|
||||
- [anchor-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-feed-parser/src/lib.rs)
|
||||
- [native-feed-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/native-feed-parser/src/lib.rs)
|
||||
|
||||
### Read History Buffer
|
||||
|
||||
**_Note: The Aggregator must have a history buffer initialized before using_**
|
||||
|
||||
```rust
|
||||
use switchboard_v2::AggregatorHistoryBuffer;
|
||||
use std::convert::TryInto;
|
||||
|
||||
let history_buffer = AggregatorHistoryBuffer::new(history_account_info)?;
|
||||
let current_timestamp = Clock::get()?.unix_timestamp;
|
||||
let one_hour_ago: f64 = history_buffer.lower_bound(current_timestamp - 3600).unwrap().try_into()?;
|
||||
```
|
||||
|
||||
### Read VRF
|
||||
|
||||
```rust
|
||||
use switchboard_v2::VrfAccountData;
|
||||
|
||||
// deserialize the account info
|
||||
let vrf = ctx.accounts.vrf.load()?;
|
||||
// OR
|
||||
let vrf = VrfAccountData::new(vrf_account_info)?;
|
||||
|
||||
// read the result
|
||||
let result_buffer = vrf.get_result()?;
|
||||
let value: &[u128] = bytemuck::cast_slice(&result_buffer[..]);
|
||||
let result = value[0] % 256000 as u128;
|
||||
```
|
||||
|
||||
**Example**:
|
||||
|
||||
- [anchor-vrf-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-vrf-parser/src/actions/update_result.rs)
|
||||
|
||||
### Request Randomness CPI
|
||||
|
||||
```rust
|
||||
pub use switchboard_v2::{VrfAccountData, VrfRequestRandomness};
|
||||
|
||||
let switchboard_program = ctx.accounts.switchboard_program.to_account_info();
|
||||
|
||||
let vrf_request_randomness = VrfRequestRandomness {
|
||||
authority: ctx.accounts.state.to_account_info(),
|
||||
vrf: ctx.accounts.vrf.to_account_info(),
|
||||
oracle_queue: ctx.accounts.oracle_queue.to_account_info(),
|
||||
queue_authority: ctx.accounts.queue_authority.to_account_info(),
|
||||
data_buffer: ctx.accounts.data_buffer.to_account_info(),
|
||||
permission: ctx.accounts.permission.to_account_info(),
|
||||
escrow: ctx.accounts.escrow.clone(),
|
||||
payer_wallet: ctx.accounts.payer_wallet.clone(),
|
||||
payer_authority: ctx.accounts.payer_authority.to_account_info(),
|
||||
recent_blockhashes: ctx.accounts.recent_blockhashes.to_account_info(),
|
||||
program_state: ctx.accounts.program_state.to_account_info(),
|
||||
token_program: ctx.accounts.token_program.to_account_info(),
|
||||
};
|
||||
|
||||
let vrf_key = ctx.accounts.vrf.key.clone();
|
||||
let authority_key = ctx.accounts.authority.key.clone();
|
||||
|
||||
let state_seeds: &[&[&[u8]]] = &[&[
|
||||
&STATE_SEED,
|
||||
vrf_key.as_ref(),
|
||||
authority_key.as_ref(),
|
||||
&[bump],
|
||||
]];
|
||||
msg!("requesting randomness");
|
||||
vrf_request_randomness.invoke_signed(
|
||||
switchboard_program,
|
||||
params.switchboard_state_bump,
|
||||
params.permission_bump,
|
||||
state_seeds,
|
||||
)?;
|
||||
```
|
||||
|
||||
**Example**:
|
||||
|
||||
- [anchor-vrf-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-vrf-parser/src/actions/request_result.rs)
|
||||
|
||||
### Read Buffer Relayer
|
||||
|
||||
```rust
|
||||
use anchor_lang::solana_program::clock;
|
||||
use std::convert::TryInto;
|
||||
use switchboard_v2::{BufferRelayerAccountData, SWITCHBOARD_PROGRAM_ID};
|
||||
|
||||
// check feed owner
|
||||
let owner = *aggregator.owner;
|
||||
if owner != SWITCHBOARD_PROGRAM_ID {
|
||||
return Err(error!(ErrorCode::InvalidSwitchboardAccount));
|
||||
}
|
||||
|
||||
// deserialize account info
|
||||
let buffer = BufferRelayerAccountData::new(feed_account_info)?;
|
||||
|
||||
// get result
|
||||
let buffer_result = buffer.get_result();
|
||||
|
||||
// check if feed has been updated in the last 5 minutes
|
||||
buffer.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
|
||||
|
||||
// convert buffer to a string
|
||||
let result_string = String::from_utf8(buffer.result)
|
||||
.map_err(|_| error!(ErrorCode::StringConversionFailed))?;
|
||||
msg!("Buffer string {:?}!", result_string);
|
||||
```
|
||||
|
||||
**Example**:
|
||||
|
||||
- [anchor-buffer-parser](https://github.com/switchboard-xyz/sbv2-solana/blob/main/programs/anchor-buffer-parser/src/lib.rs)
|
||||
|
|
Loading…
Reference in New Issue