wip
This commit is contained in:
parent
84bbdcf20a
commit
50e580cdd4
|
@ -42,7 +42,14 @@ npm i --save @switchboard-xyz/solana.js
|
|||
|
||||
## Usage
|
||||
|
||||
### Load the Switchboard Program
|
||||
**Table Of Contents**
|
||||
|
||||
- [Load Switchboard Program](#load-switchboard-program)
|
||||
- [Create a Queue](#create-a-queue)
|
||||
|
||||
### Load Switchboard Program
|
||||
|
||||
|
||||
|
||||
```ts
|
||||
import { Connection } from '@solana/web3.js';
|
||||
|
@ -58,7 +65,12 @@ const program = await SwitchboardProgram.load(
|
|||
);
|
||||
```
|
||||
|
||||
### Create a queue
|
||||
|
||||
|
||||
|
||||
### Create a Queue
|
||||
|
||||
|
||||
|
||||
```ts
|
||||
import { QueueAccount } from '@switchboard-xyz/solana.js';
|
||||
|
@ -78,120 +90,6 @@ 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';
|
||||
|
||||
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());
|
||||
```
|
||||
|
||||
### 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 a 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());
|
||||
}
|
||||
});
|
||||
```
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<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
|
||||
|
||||
```bash
|
||||
npm i --save @switchboard-xyz/solana.js
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
<!-- usage -->
|
||||
|
||||
<!-- usagestop -->
|
||||
|
|
@ -47,9 +47,13 @@ switchboard-v2 = "0.1.23"
|
|||
|
||||
## Usage
|
||||
|
||||
### Aggregator
|
||||
**Table Of Contents**
|
||||
|
||||
- [Read Latest Result](#read-latest-result)
|
||||
|
||||
### Read Latest Result
|
||||
|
||||
|
||||
#### Read Latest Result
|
||||
|
||||
```rust
|
||||
use anchor_lang::solana_program::clock;
|
||||
|
@ -77,137 +81,5 @@ feed.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
|
|||
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)
|
||||
',
|
||||
|
||||
#### Read Aggregator History
|
||||
|
||||
**_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()?;
|
||||
```
|
||||
|
||||
### VRF Account
|
||||
|
||||
#### Read Latest Result
|
||||
|
||||
```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)
|
||||
|
||||
#### RequestRandomness 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)
|
||||
|
||||
### Buffer Relayer Account
|
||||
|
||||
#### Read Latest Result
|
||||
|
||||
```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)
|
||||
|
||||
## Supported CPI Calls
|
||||
|
||||
| Instruction | is supported |
|
||||
| --------------------------- | ------------ |
|
||||
| permission_set | true |
|
||||
| vrf_request_randomness | true |
|
||||
| vrf_set_callback | true |
|
||||
| vrf_close | true |
|
||||
| vrf_lite_request_randomness | true |
|
||||
| vrf_lite_close | true |
|
||||
| vrf_pool_request_randomness | true |
|
||||
| vrf_pool_remove | true |
|
||||
| vrf_pool_add | TODO |
|
||||
| aggregator_open_round | TODO |
|
||||
| buffer_relayer_open_round | TODO |
|
||||
|
||||
See
|
||||
[https://docs.switchboard.xyz/solana/idl](https://docs.switchboard.xyz/solana/idl)
|
||||
for a list of all program instructions.
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
<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 V2 accounts on Solana.</p>
|
||||
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<h4>
|
||||
<strong>Typedocs: </strong><a href="https://docs.rs/switchboard-v2/latest/switchboard-v2/">docs.rs/switchboard-v2</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
|
||||
|
||||
Run the following Cargo command in your project directory:
|
||||
|
||||
```bash
|
||||
cargo add switchboard-v2
|
||||
```
|
||||
|
||||
Or add the following line to your Cargo.toml:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
switchboard-v2 = "0.1.23"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
<!-- usage -->
|
||||
|
||||
<!-- usagestop -->
|
Loading…
Reference in New Issue