chore: pull monorepo changes (#114)
* Project import generated by Copybara. GitOrigin-RevId: 5ab5c6081a78d71f06b5e1570c8151f03bc19786 * chore: Update pnpm lockfile * chore: manually cleaned up deps * chore: Update pnpm lockfile --------- Co-authored-by: Copybara <copybara@example.com> Co-authored-by: gallynaut <gallynaut@users.noreply.github.com>
This commit is contained in:
parent
00eca445c9
commit
987ff26820
|
@ -4227,9 +4227,9 @@ checksum = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
|
|||
|
||||
[[package]]
|
||||
name = "switchboard-common"
|
||||
version = "0.8.1"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba2cc1d6055e0989756adc4f54fa1e27d684ce08d6164da23900e93ac0b13b6"
|
||||
checksum = "eaa7b85e2005ce058c626ce0d4d618dc18ca8f45a24bd66f3e11a6bf43f20082"
|
||||
dependencies = [
|
||||
"getrandom 0.2.10",
|
||||
"hex",
|
||||
|
@ -4249,7 +4249,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "switchboard-solana"
|
||||
version = "0.8.4"
|
||||
version = "0.9.5"
|
||||
dependencies = [
|
||||
"anchor-client",
|
||||
"anchor-lang",
|
||||
|
@ -4258,6 +4258,7 @@ dependencies = [
|
|||
"bytemuck",
|
||||
"chrono",
|
||||
"cron",
|
||||
"hex",
|
||||
"rust_decimal",
|
||||
"sgx-quote",
|
||||
"solana-address-lookup-table-program",
|
||||
|
@ -4265,6 +4266,7 @@ dependencies = [
|
|||
"solana-program",
|
||||
"superslice",
|
||||
"switchboard-common",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -16,6 +16,6 @@ no-log-ix-name = []
|
|||
cpi = ["no-entrypoint"]
|
||||
|
||||
[dependencies]
|
||||
# switchboard-solana = "0.8.4"
|
||||
switchboard-solana = { version = "0.8.4", path = "../../../rust/switchboard-solana" }
|
||||
# switchboard-solana = "0.9.5"
|
||||
switchboard-solana = { version = "0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
bytemuck = "1.13.1"
|
||||
|
|
|
@ -11,5 +11,5 @@ name = "native_feed_parser"
|
|||
no-entrypoint = []
|
||||
|
||||
[dependencies]
|
||||
# switchboard-solana = "0.8.4"
|
||||
switchboard-solana = { version = "0.8.4", path = "../../../rust/switchboard-solana" }
|
||||
# switchboard-solana = "0.9.5"
|
||||
switchboard-solana = { version = "0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
|
|
|
@ -17,7 +17,7 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
switchboard-solana = { version = "=0.9.5" }
|
||||
# switchboard-solana = { version = "0.9.4", path = "../../../rust/switchboard-solana" }
|
||||
switchboard-solana = { version = "0.9.5" }
|
||||
# switchboard-solana = { version = "0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
bytemuck = "^1"
|
||||
anchor-lang = { version = "0.28.0" }
|
||||
|
|
|
@ -17,8 +17,8 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
switchboard-solana = { version = "=0.9.1" }
|
||||
# switchboard-solana = { version = "0.9.1", path = "../../../rust/switchboard-solana" }
|
||||
switchboard-solana = { version = "0.9.5" }
|
||||
# switchboard-solana = { version = "0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
bytemuck = "^1"
|
||||
anchor-lang = { version = "0.28.0", features = [
|
||||
"init-if-needed",
|
||||
|
|
|
@ -17,8 +17,8 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
switchboard-solana = { version = "=0.9.1" }
|
||||
# switchboard-solana = { version = "0.9.1", path = "../../../rust/switchboard-solana" }
|
||||
switchboard-solana = { version = "0.9.5" }
|
||||
# switchboard-solana = { version = "0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
bytemuck = "^1"
|
||||
anchor-lang = { version = "0.28.0", features = [
|
||||
"init-if-needed",
|
||||
|
|
|
@ -18,4 +18,4 @@ default = []
|
|||
[dependencies]
|
||||
bytemuck = "^1"
|
||||
anchor-spl = "0.28.0"
|
||||
switchboard-solana = { version = "0.9.4", path = "../../../../../../../rust/switchboard-solana" }
|
||||
switchboard-solana = { version = "0.9.5", path = "../../../../../../../rust/switchboard-solana" }
|
||||
|
|
|
@ -17,5 +17,5 @@ cpi = ["no-entrypoint"]
|
|||
|
||||
[dependencies]
|
||||
bytemuck = "1.13.1"
|
||||
switchboard-solana = { path = "../../../rust/switchboard-solana", version = "0.8.4" }
|
||||
# switchboard-solana = { version = "^0.8.4", path = "../../../rust/switchboard-solana" }
|
||||
switchboard-solana = { path = "../../../rust/switchboard-solana", version = "0.9.5" }
|
||||
# switchboard-solana = { version = "^0.9.5", path = "../../../rust/switchboard-solana" }
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"extends": "@switchboard-xyz"
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Switchboard
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,119 +0,0 @@
|
|||
<div align="center">
|
||||
|
||||
![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png)
|
||||
|
||||
# Javascript Feed Walkthrough
|
||||
|
||||
> Create a private Switchboard queue and oracle and fulfill your own oracle
|
||||
> updates
|
||||
|
||||
[![Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg)](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
|
||||
|
||||
[![Types Badge](https://img.shields.io/badge/types-docs.switchboard.xyz-blue)](https://docs.switchboard.xyz/api/solana.js)
|
||||
|
||||
</div>
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
npm i
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
**Directory**
|
||||
|
||||
- [Simulate an OracleJob](#simulate-an-oraclejob)
|
||||
- [Create a Devnet Feed](#create-a-devnet-feed)
|
||||
- [Create a Private Switchboard Network](#create-a-private-switchboard-network)
|
||||
- [Create a Feed with the CLI](#create-a-feed-with-the-cli)
|
||||
|
||||
### Simulate an OracleJob
|
||||
|
||||
Edit the OracleJob file `src/oracle-job.json`, then run
|
||||
|
||||
```bash
|
||||
ts-node src/simulate
|
||||
```
|
||||
|
||||
### Create a Devnet Feed
|
||||
|
||||
You can create your own feeds using the devnet permissionless network. This
|
||||
network does _NOT_ require the queue authority to grant you permissions so you
|
||||
are free to use it as a testing environment.
|
||||
|
||||
You do **_NOT_** need to run your own oracles for this network.
|
||||
|
||||
Edit the OracleJob file `src/oracle-job.json`, then run
|
||||
|
||||
```bash
|
||||
ts-node src/devnet
|
||||
```
|
||||
|
||||
Optionally, provide these env variables
|
||||
|
||||
```bash
|
||||
RPC_URL=https://my_custom_rpc_url.com \
|
||||
PAYER_KEYPAIR=~/my_keypair.json \
|
||||
ts-node src/devnet
|
||||
```
|
||||
|
||||
### Create a Private Switchboard Network
|
||||
|
||||
You can also create your own private Switchboard network and run your own
|
||||
oracles. This requires you to run your own oracles for this network.
|
||||
|
||||
The following script will
|
||||
|
||||
- Create a private queue and crank
|
||||
- Create a new data feed on this network
|
||||
- Start a local oracle
|
||||
- Call OpenRound and await the updated result from your local oracle
|
||||
|
||||
```bash
|
||||
ts-node src/private-queue
|
||||
```
|
||||
|
||||
Optionally, provide these env variables
|
||||
|
||||
```bash
|
||||
RPC_URL=https://my_custom_rpc_url.com \
|
||||
PAYER_KEYPAIR=~/my_keypair.json \
|
||||
ts-node src/private-queue
|
||||
```
|
||||
|
||||
### Create a Feed with the CLI
|
||||
|
||||
First install the sbv2 cli
|
||||
|
||||
```bash
|
||||
npm install -g @switchboard-xyz
|
||||
```
|
||||
|
||||
Then run the following command to create your own feed using the devnet
|
||||
permissionless queue and crank
|
||||
|
||||
```bash
|
||||
export QUEUE_KEY=uPeRMdfPmrPqgRWSrjAnAkH78RqAhe5kXoW6vBYRqFX
|
||||
export CRANK_KEY=GN9jjCy2THzZxhYqZETmPM3my8vg4R5JyNkgULddUMa5
|
||||
sbv2 solana aggregator create "$QUEUE_KEY" \
|
||||
--keypair ~/.config/solana/id.json \
|
||||
--crankKey "$CRANK_KEY" \
|
||||
--name "My_Test_Feed" \
|
||||
--updateInterval 10 \
|
||||
--minOracles 1 \
|
||||
--batchSize 1 \
|
||||
--leaseAmount 0.1 \
|
||||
--job ./src/oracle-job.json \
|
||||
--verbose
|
||||
```
|
||||
|
||||
Then request an update for your new feed
|
||||
|
||||
```bash
|
||||
sbv2 solana aggregator update $AGGREGATOR_KEY \
|
||||
--keypair ~/.config/solana/id.json
|
||||
```
|
||||
|
||||
**_NOTE:_** You can provide multiple `--job` flags to add additional oracle jobs
|
||||
to your data feed
|
|
@ -1,24 +0,0 @@
|
|||
version: "3.3"
|
||||
services:
|
||||
oracle:
|
||||
image: "switchboardlabs/node:dev-v2-RC_11_28_22_04_01a"
|
||||
network_mode: host
|
||||
# restart: always
|
||||
secrets:
|
||||
- PAYER_SECRETS
|
||||
environment:
|
||||
# Logging
|
||||
- VERBOSE=1
|
||||
- DEBUG=1
|
||||
# Oracle
|
||||
- CHAIN=solana
|
||||
# Solana
|
||||
- CLUSTER=${CLUSTER:-devnet}
|
||||
- RPC_URL=${RPC_URL:-https://api.devnet.solana.com}
|
||||
- ORACLE_KEY=${ORACLE_KEY}
|
||||
- HEARTBEAT_INTERVAL=60 # Seconds
|
||||
# Task Runner
|
||||
- TASK_RUNNER_SOLANA_RPC=${TASK_RUNNER_SOLANA_RPC:-https://api.mainnet-beta.solana.com}
|
||||
secrets:
|
||||
PAYER_SECRETS:
|
||||
file: ${SOLANA_PAYER_SECRETS:-~/.config/solana/id.json}
|
|
@ -1,43 +0,0 @@
|
|||
{
|
||||
"name": "@switchboard-xyz/v2-feed-walkthrough",
|
||||
"version": "1.0.0",
|
||||
"description": "switchboard v2 example demonstrating how to create a private queue, oracle, and data feed",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/switchboard-xyz/sbv2-solana",
|
||||
"directory": "javascript/feed-walkthrough"
|
||||
},
|
||||
"homepage": "https://docs.switchboard.xyz",
|
||||
"main": "dist/main.js",
|
||||
"scripts": {
|
||||
"start": "ts-node src/private-queue",
|
||||
"start:devnet": "ts-node src/devnet",
|
||||
"start:simulate": "ts-node src/simulate",
|
||||
"lint": "gts lint ./src",
|
||||
"fix": "gts fix ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@solana/web3.js": "^1.73.3",
|
||||
"@switchboard-xyz/common": "^2.2.0",
|
||||
"@switchboard-xyz/oracle": "^2.1.13",
|
||||
"@switchboard-xyz/solana.js": "file:../solana.js",
|
||||
"chalk": "^4.1.2",
|
||||
"dotenv": "^16.0.1",
|
||||
"readline-sync": "^1.4.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@switchboard-xyz/eslint-config": "latest",
|
||||
"@types/node": "^18.7.18",
|
||||
"@types/readline-sync": "^1.4.4",
|
||||
"gts": "^3.1.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"shx": "^0.3.4",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.8.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
/**
|
||||
* Create a new data feed on the devnet permissionless queue.
|
||||
*
|
||||
* The devnet queue does NOT require you to run your own oracle.
|
||||
*
|
||||
* This script will:
|
||||
* - load the existing devnet permissionless queue
|
||||
* - load the existing devnet permissionless crank
|
||||
* - create a new data feed for the queue and crank
|
||||
* - call open round on the feed and await the result
|
||||
*/
|
||||
|
||||
import OracleJobJson from "./oracle-job.json";
|
||||
import { getKeypair, toAccountString } from "./utils";
|
||||
|
||||
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
|
||||
import { OracleJob } from "@switchboard-xyz/common";
|
||||
import {
|
||||
AggregatorAccount,
|
||||
CrankAccount,
|
||||
QueueAccount,
|
||||
SwitchboardProgram,
|
||||
} from "@switchboard-xyz/solana.js";
|
||||
import chalk from "chalk";
|
||||
import dotenv from "dotenv";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const DEVNET_PERMISSIONLESS_QUEUE = new PublicKey(
|
||||
"uPeRMdfPmrPqgRWSrjAnAkH78RqAhe5kXoW6vBYRqFX"
|
||||
);
|
||||
|
||||
const DEVNET_PERMISSIONLESS_CRANK = new PublicKey(
|
||||
"GN9jjCy2THzZxhYqZETmPM3my8vg4R5JyNkgULddUMa5"
|
||||
);
|
||||
|
||||
async function main() {
|
||||
// get payer keypair
|
||||
let payerKeypairPath: string;
|
||||
if (process.argv.length > 2 && process.argv[2]) {
|
||||
payerKeypairPath = process.argv[2];
|
||||
} else if (process.env.PAYER_KEYPAIR) {
|
||||
payerKeypairPath = process.env.PAYER_KEYPAIR;
|
||||
} else {
|
||||
payerKeypairPath = path.join(os.homedir(), ".config/solana/id.json");
|
||||
}
|
||||
const authority = getKeypair(payerKeypairPath);
|
||||
|
||||
// get RPC_URL
|
||||
let rpcUrl: string;
|
||||
if (process.env.RPC_URL) {
|
||||
rpcUrl = process.env.RPC_URL;
|
||||
} else {
|
||||
rpcUrl = clusterApiUrl("devnet");
|
||||
}
|
||||
|
||||
const program = await SwitchboardProgram.load(
|
||||
"devnet",
|
||||
new Connection(rpcUrl, "confirmed"),
|
||||
authority
|
||||
);
|
||||
|
||||
console.log(chalk.yellow("######## Switchboard Setup ########"));
|
||||
|
||||
const [queueAccount, queueData] = await QueueAccount.load(
|
||||
program,
|
||||
DEVNET_PERMISSIONLESS_QUEUE
|
||||
);
|
||||
console.log(toAccountString("Oracle Queue", queueAccount.publicKey));
|
||||
|
||||
if (
|
||||
!queueData.unpermissionedFeedsEnabled &&
|
||||
!queueData.authority.equals(authority.publicKey)
|
||||
) {
|
||||
throw new Error(
|
||||
`This queue requires the queue authority (${queueData.authority}) to grant you permissions to join`
|
||||
);
|
||||
}
|
||||
|
||||
const [crankAccount, crankData] = await CrankAccount.load(
|
||||
program,
|
||||
DEVNET_PERMISSIONLESS_CRANK
|
||||
);
|
||||
console.log(toAccountString("Crank", crankAccount.publicKey));
|
||||
|
||||
const [aggregatorAccount] = await queueAccount.createFeed({
|
||||
name: "SOL_USD",
|
||||
batchSize: 1,
|
||||
minRequiredOracleResults: 1,
|
||||
minRequiredJobResults: 1,
|
||||
minUpdateDelaySeconds: 10,
|
||||
fundAmount: 0.1,
|
||||
enable: false, // permissionless queue does not require explicit permissions
|
||||
crankPubkey: crankAccount.publicKey,
|
||||
jobs: [
|
||||
{
|
||||
weight: 2,
|
||||
data: OracleJob.encodeDelimited(
|
||||
OracleJob.fromObject(OracleJobJson)
|
||||
).finish(),
|
||||
},
|
||||
],
|
||||
});
|
||||
console.log(toAccountString("Aggregator", aggregatorAccount.publicKey));
|
||||
|
||||
console.log(chalk.green("\u2714 Switchboard setup complete"));
|
||||
|
||||
console.log(chalk.yellow("######## Calling OpenRound ########"));
|
||||
const [newAggregatorState] =
|
||||
await aggregatorAccount.openRoundAndAwaitResult();
|
||||
console.log(
|
||||
`${chalk.blue("Result:")} ${chalk.green(
|
||||
AggregatorAccount.decodeLatestValue(newAggregatorState).toString()
|
||||
)}\r\n`
|
||||
);
|
||||
console.log(chalk.green("\u2714 Aggregator succesfully updated!"));
|
||||
}
|
||||
|
||||
main().then(
|
||||
() => {
|
||||
process.exit();
|
||||
},
|
||||
(error) => {
|
||||
console.error("Failed to create a feed on the devnet permissionless queue");
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
);
|
|
@ -1,9 +0,0 @@
|
|||
{
|
||||
"tasks": [
|
||||
{
|
||||
"valueTask": {
|
||||
"value": 10
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
/**
|
||||
* Create a private switchboard oracle queue and fulfill your own open round request.
|
||||
*
|
||||
* This script will:
|
||||
* - create a new private switchboard network with a single oracle and crank
|
||||
* - create a new data feed for the queue and crank
|
||||
* - start a new switchboard oracle and heartbeat on-chain to signal readiness
|
||||
* - call open round on the feed and await the result
|
||||
*/
|
||||
|
||||
import OracleJobJson from "./oracle-job.json";
|
||||
import { getKeypair, toAccountString } from "./utils";
|
||||
|
||||
import { clusterApiUrl, Connection } from "@solana/web3.js";
|
||||
import { OracleJob, sleep } from "@switchboard-xyz/common";
|
||||
import { NodeOracle } from "@switchboard-xyz/oracle";
|
||||
import {
|
||||
AggregatorAccount,
|
||||
SwitchboardNetwork,
|
||||
SwitchboardProgram,
|
||||
} from "@switchboard-xyz/solana.js";
|
||||
import chalk from "chalk";
|
||||
import dotenv from "dotenv";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
let oracle: NodeOracle | undefined = undefined;
|
||||
|
||||
async function main() {
|
||||
// get payer keypair
|
||||
let payerKeypairPath: string;
|
||||
if (process.argv.length > 2 && process.argv[2]) {
|
||||
payerKeypairPath = process.argv[2];
|
||||
} else if (process.env.PAYER_KEYPAIR) {
|
||||
payerKeypairPath = process.env.PAYER_KEYPAIR;
|
||||
} else {
|
||||
payerKeypairPath = path.join(os.homedir(), ".config/solana/id.json");
|
||||
}
|
||||
const authority = getKeypair(payerKeypairPath);
|
||||
|
||||
if ((process.env.CLUSTER ?? "").startsWith("mainnet")) {
|
||||
throw new Error("This script should not be used on mainnet");
|
||||
}
|
||||
|
||||
// get cluster
|
||||
let cluster: "devnet" | "localnet";
|
||||
if (
|
||||
process.env.CLUSTER &&
|
||||
(process.env.CLUSTER === "devnet" || process.env.CLUSTER === "localnet")
|
||||
) {
|
||||
cluster = process.env.CLUSTER;
|
||||
} else {
|
||||
cluster = "devnet";
|
||||
}
|
||||
|
||||
// get RPC_URL
|
||||
let rpcUrl: string;
|
||||
if (process.env.RPC_URL) {
|
||||
rpcUrl = process.env.RPC_URL;
|
||||
} else {
|
||||
rpcUrl =
|
||||
cluster === "localnet" ? "http://localhost:8899" : clusterApiUrl(cluster);
|
||||
}
|
||||
|
||||
const program = await SwitchboardProgram.load(
|
||||
cluster === "localnet" ? "devnet" : cluster,
|
||||
new Connection(rpcUrl, "confirmed"),
|
||||
authority
|
||||
);
|
||||
|
||||
console.log(chalk.yellow("######## Switchboard Setup ########"));
|
||||
|
||||
const [network, signatures] = await SwitchboardNetwork.create(program, {
|
||||
name: "Queue-1",
|
||||
slashingEnabled: false,
|
||||
reward: 0,
|
||||
minStake: 0,
|
||||
cranks: [{ name: "Crank", maxRows: 10 }],
|
||||
oracles: [
|
||||
{
|
||||
name: "Oracle",
|
||||
enable: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const queueAccount = network.queue.account;
|
||||
console.log(toAccountString("Oracle Queue", queueAccount.publicKey));
|
||||
|
||||
const crankAccount = network.cranks[0].account;
|
||||
console.log(toAccountString("Crank", crankAccount.publicKey));
|
||||
|
||||
const oracleAccount = network.oracles[0].account;
|
||||
console.log(toAccountString("Oracle", oracleAccount.publicKey));
|
||||
|
||||
const [aggregatorAccount] = await queueAccount.createFeed({
|
||||
name: "SOL_USD",
|
||||
batchSize: 1,
|
||||
minRequiredOracleResults: 1,
|
||||
minRequiredJobResults: 1,
|
||||
minUpdateDelaySeconds: 10,
|
||||
fundAmount: 0.5,
|
||||
queueAuthority: authority,
|
||||
enable: true,
|
||||
crankPubkey: crankAccount.publicKey,
|
||||
jobs: [
|
||||
{
|
||||
weight: 2,
|
||||
data: OracleJob.encodeDelimited(
|
||||
OracleJob.fromObject(OracleJobJson)
|
||||
).finish(),
|
||||
},
|
||||
],
|
||||
});
|
||||
console.log(toAccountString("Aggregator", aggregatorAccount.publicKey));
|
||||
|
||||
console.log(chalk.green("\u2714 Switchboard setup complete"));
|
||||
|
||||
console.log(chalk.yellow("######## Start the Oracle ########"));
|
||||
oracle = await NodeOracle.fromReleaseChannel({
|
||||
releaseChannel: "testnet",
|
||||
chain: "solana",
|
||||
network: program.cluster === "mainnet-beta" ? "mainnet" : program.cluster,
|
||||
rpcUrl: program.connection.rpcEndpoint,
|
||||
oracleKey: oracleAccount.publicKey.toBase58(),
|
||||
secretPath: payerKeypairPath,
|
||||
envVariables: {
|
||||
VERBOSE: "1",
|
||||
DEBUG: "1",
|
||||
DISABLE_NONE_QUEUE: "1",
|
||||
},
|
||||
});
|
||||
await oracle.startAndAwait();
|
||||
let retryCount = 5;
|
||||
while (retryCount) {
|
||||
const activeOracles = await queueAccount.loadActiveOracleAccounts();
|
||||
if (activeOracles.length > 0) {
|
||||
retryCount = 0;
|
||||
break;
|
||||
}
|
||||
await sleep(1000);
|
||||
--retryCount;
|
||||
}
|
||||
console.log(chalk.green("\u2714 Oracle ready"));
|
||||
|
||||
console.log(chalk.yellow("######## Calling OpenRound ########"));
|
||||
const [newAggregatorState] =
|
||||
await aggregatorAccount.openRoundAndAwaitResult();
|
||||
console.log(
|
||||
`${chalk.blue("Result:")} ${chalk.green(
|
||||
AggregatorAccount.decodeLatestValue(newAggregatorState).toString()
|
||||
)}\r\n`
|
||||
);
|
||||
console.log(chalk.green("\u2714 Aggregator succesfully updated!"));
|
||||
|
||||
if (oracle) {
|
||||
oracle.stop();
|
||||
oracle = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
main().then(
|
||||
() => {
|
||||
oracle?.stop();
|
||||
process.exit();
|
||||
},
|
||||
(error) => {
|
||||
oracle?.stop();
|
||||
console.error("Failed to create a private feed");
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
);
|
|
@ -1,30 +0,0 @@
|
|||
import OracleJobJson from "./oracle-job.json";
|
||||
|
||||
import { OracleJob, simulateOracleJobs } from "@switchboard-xyz/common";
|
||||
import chalk from "chalk";
|
||||
|
||||
async function main() {
|
||||
const response = await simulateOracleJobs(
|
||||
[OracleJob.fromObject(OracleJobJson)],
|
||||
"devnet"
|
||||
);
|
||||
|
||||
console.log(
|
||||
chalk.blue(`\u2139 TaskRunner Version: ${response.taskRunnerVersion}`)
|
||||
);
|
||||
console.log(
|
||||
chalk.green(`\u2714 Result: ${response.result.toString()}`),
|
||||
`[${response.results.map((r) => r.toString()).join(", ")}]`
|
||||
);
|
||||
}
|
||||
|
||||
main().then(
|
||||
() => {
|
||||
process.exit();
|
||||
},
|
||||
(error) => {
|
||||
console.error("Failed to simulate the oracle job response");
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
}
|
||||
);
|
|
@ -1,30 +0,0 @@
|
|||
import { Keypair, PublicKey } from "@solana/web3.js";
|
||||
import chalk from "chalk";
|
||||
import fs from "fs";
|
||||
|
||||
export const toAccountString = (
|
||||
label: string,
|
||||
publicKey: PublicKey | string | undefined
|
||||
): string => {
|
||||
if (typeof publicKey === "string") {
|
||||
return `${chalk.blue(label.padEnd(24, " "))} ${chalk.yellow(publicKey)}`;
|
||||
}
|
||||
if (!publicKey) {
|
||||
return "";
|
||||
}
|
||||
return `${chalk.blue(label.padEnd(24, " "))} ${chalk.yellow(
|
||||
publicKey.toString()
|
||||
)}`;
|
||||
};
|
||||
|
||||
export const getKeypair = (keypairPath: string): Keypair => {
|
||||
if (!fs.existsSync(keypairPath)) {
|
||||
throw new Error(
|
||||
`failed to load authority keypair from ${keypairPath}, try providing a path to your keypair with the script 'ts-node src/main KEYPAIR_PATH'`
|
||||
);
|
||||
}
|
||||
const keypairString = fs.readFileSync(keypairPath, "utf8");
|
||||
const keypairBuffer = new Uint8Array(JSON.parse(keypairString));
|
||||
const walletKeypair = Keypair.fromSecretKey(keypairBuffer);
|
||||
return walletKeypair;
|
||||
};
|
|
@ -1,36 +0,0 @@
|
|||
{
|
||||
"ts-node": {
|
||||
// It is faster to skip typechecking.
|
||||
// Remove if you want ts-node to do typechecking.
|
||||
// "transpileOnly": true,
|
||||
// "files": true,
|
||||
"compilerOptions": {
|
||||
// compilerOptions specified here will override those declared below,
|
||||
// but *only* in ts-node. Useful if you want ts-node and tsc to use
|
||||
// different options with a single tsconfig.json.
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true
|
||||
}
|
||||
},
|
||||
"compilerOptions": {
|
||||
"target": "ES2019",
|
||||
"lib": ["es2019", "dom"],
|
||||
"module": "es2022",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"paths": {
|
||||
"@switchboard-xyz/solana.js": ["../solana.js"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["esbuild.js", "dist"],
|
||||
"references": [{ "path": "../solana.js" }],
|
||||
"files": ["src/private-queue.ts"]
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@switchboard-xyz/sbv2-lite",
|
||||
"version": "0.2.1",
|
||||
"version": "0.2.2",
|
||||
"description": "",
|
||||
"private": false,
|
||||
"repository": {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export { IDL as SWITCHBOARD_V2_IDL, SwitchboardV2 } from "./switchboard_v2";
|
File diff suppressed because it is too large
Load Diff
|
@ -1,17 +1,17 @@
|
|||
import type { SwitchboardV2 } from "./switchboard_v2";
|
||||
import type { SwitchboardV2 } from "./idl";
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import Big from "big.js";
|
||||
|
||||
export * from "./switchboard_v2";
|
||||
export * from "./idl";
|
||||
|
||||
// import idl from "./idl.json";
|
||||
|
||||
// export const IDL: anchor.Idl = idl;
|
||||
|
||||
// export const IDL: anchor.Idl = await import("./idl.json", {
|
||||
// assert: { type: "json" },
|
||||
// });
|
||||
export type Accounts = anchor.IdlAccounts<SwitchboardV2>;
|
||||
export type AggregatorAccountData = Accounts["aggregatorAccountData"];
|
||||
export type JobAccountData = Accounts["jobAccountData"];
|
||||
export type PermissionAccountData = Accounts["permissionAccountData"];
|
||||
export type LeaseAccountData = Accounts["leaseAccountData"];
|
||||
export type OracleQueueAccountData = Accounts["oracleQueueAccountData"];
|
||||
export type OracleAccountData = Accounts["oracleAccountData"];
|
||||
|
||||
/**
|
||||
* Check if a transaction object is a VersionedTransaction or not
|
||||
|
@ -154,7 +154,7 @@ export default class SwitchboardProgram {
|
|||
* @returns latest confirmed result as a big.js or null if the latest confirmed round has insufficient oracle responses or data is too stale
|
||||
*/
|
||||
private getLatestAggregatorValue(
|
||||
aggregator: any,
|
||||
aggregator: AggregatorAccountData,
|
||||
maxStaleness = 0
|
||||
): Big | null {
|
||||
if ((aggregator.latestConfirmedRound?.numSuccess ?? 0) === 0) {
|
||||
|
@ -189,14 +189,11 @@ export default class SwitchboardProgram {
|
|||
public async fetchAggregator(
|
||||
aggregatorPubkey: anchor.web3.PublicKey,
|
||||
commitment?: anchor.web3.Commitment
|
||||
): Promise<any> {
|
||||
const aggregator: any =
|
||||
await this.program.account.aggregatorAccountData?.fetch(
|
||||
aggregatorPubkey,
|
||||
commitment
|
||||
);
|
||||
aggregator.ebuf = undefined;
|
||||
return aggregator;
|
||||
): Promise<AggregatorAccountData> {
|
||||
return await this.program.account.aggregatorAccountData?.fetch(
|
||||
aggregatorPubkey,
|
||||
commitment
|
||||
);
|
||||
}
|
||||
|
||||
/** Fetch and decode an aggregator's latest confirmed value if valid
|
||||
|
@ -210,7 +207,10 @@ export default class SwitchboardProgram {
|
|||
commitment?: anchor.web3.Commitment,
|
||||
maxStaleness = 0
|
||||
): Promise<Big | null> {
|
||||
const aggregator = await this.fetchAggregator(aggregatorPubkey, commitment);
|
||||
const aggregator: AggregatorAccountData = await this.fetchAggregator(
|
||||
aggregatorPubkey,
|
||||
commitment
|
||||
);
|
||||
return this.getLatestAggregatorValue(aggregator, maxStaleness);
|
||||
}
|
||||
|
||||
|
@ -218,13 +218,14 @@ export default class SwitchboardProgram {
|
|||
* @param accountInfo the aggregatror's account info
|
||||
* @returns deserialized aggregator account, as specified by the Switchboard IDL
|
||||
*/
|
||||
public decodeAggregator(accountInfo: anchor.web3.AccountInfo<Buffer>): any {
|
||||
public decodeAggregator(
|
||||
accountInfo: anchor.web3.AccountInfo<Buffer>
|
||||
): AggregatorAccountData {
|
||||
const coder = new anchor.BorshAccountsCoder(this.program.idl);
|
||||
const aggregator: any = coder.decode(
|
||||
const aggregator: AggregatorAccountData = coder.decode(
|
||||
"AggregatorAccountData",
|
||||
accountInfo?.data
|
||||
);
|
||||
aggregator.ebuf = undefined;
|
||||
return aggregator;
|
||||
}
|
||||
|
||||
|
@ -237,7 +238,8 @@ export default class SwitchboardProgram {
|
|||
accountInfo: anchor.web3.AccountInfo<Buffer>,
|
||||
maxStaleness = 0
|
||||
): Big | null {
|
||||
const aggregator = this.decodeAggregator(accountInfo);
|
||||
const aggregator: AggregatorAccountData =
|
||||
this.decodeAggregator(accountInfo);
|
||||
return this.getLatestAggregatorValue(aggregator, maxStaleness);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,16 +28,6 @@
|
|||
"strictNullChecks": false,
|
||||
"strictFunctionTypes": true,
|
||||
"noImplicitReturns": true,
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/common": [
|
||||
"../common"
|
||||
]
|
||||
}
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../common"
|
||||
}
|
||||
]
|
||||
"esModuleInterop": true
|
||||
}
|
||||
}
|
|
@ -28,24 +28,8 @@
|
|||
"strictPropertyInitialization": false,
|
||||
"strict": true,
|
||||
"strictNullChecks": true,
|
||||
"allowJs": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/common": [
|
||||
"../common"
|
||||
],
|
||||
"@switchboard-xyz/oracle": [
|
||||
"../oracle"
|
||||
]
|
||||
}
|
||||
"allowJs": true
|
||||
},
|
||||
"references": [
|
||||
{
|
||||
"path": "../common"
|
||||
},
|
||||
{
|
||||
"path": "../oracle"
|
||||
}
|
||||
],
|
||||
"typedocOptions": {
|
||||
"entryPoints": [
|
||||
"src/index.ts",
|
||||
|
|
855
pnpm-lock.yaml
855
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue