added anchor-history-parser example

This commit is contained in:
Conner Gallagher 2022-10-18 18:57:57 -06:00
parent 9a08343831
commit 06d4d98cfe
10 changed files with 2316 additions and 0 deletions

View File

@ -0,0 +1,7 @@
.anchor
.DS_Store
target
**/*.rs.bk
node_modules
test-ledger

View File

@ -0,0 +1,8 @@
.anchor
.DS_Store
target
node_modules
dist
build
test-ledger

View File

@ -0,0 +1,31 @@
[workspace]
members = [
"."
]
[features]
seeds = false
[programs.localnet]
anchor_history_parser = "C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS"
[registry]
url = "https://anchor.projectserum.com"
[provider]
cluster = "devnet"
# cluster = "localnet"
wallet = "../../../payer-keypair.json"
# wallet = "~/.config/solana/id.json"
[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.test.ts"
[test.validator]
url="https://api.devnet.solana.com"
[[testnet.validator.clone]]
address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
[[testnet.validator.clone]]
address="7LLvRhMs73FqcLkA8jvEE1AM2mYZXTmqfUv8GAEurymx" # sbv2 SOL/USD History Buffer

View File

@ -0,0 +1,25 @@
[package]
name = "anchor-history-parser"
version = "0.1.0"
description = "Created with Anchor"
edition = "2021"
[lib]
crate-type = ["cdylib", "lib"]
name = "anchor_history_parser"
[features]
no-entrypoint = []
no-idl = []
no-log-ix-name = []
cpi = ["no-entrypoint"]
default = []
[profile.release]
overflow-checks = true
[dependencies]
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
switchboard-v2 = { version = "^0.1.14", features = ["devnet"] }
anchor-lang = "0.25.0"
solana-program = "~1.10.29"

View File

@ -0,0 +1,2 @@
[target.bpfel-unknown-unknown.dependencies.std]
features = []

View File

@ -0,0 +1,20 @@
{
"scripts": {
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
},
"dependencies": {
"@project-serum/anchor": "^0.25.0",
"@switchboard-xyz/switchboard-v2": "^0.0.137"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"prettier": "^2.6.2",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
}

View File

@ -0,0 +1,73 @@
use anchor_lang::prelude::*;
pub use switchboard_v2::{
AggregatorAccountData, AggregatorHistoryBuffer, SwitchboardDecimal, SWITCHBOARD_PROGRAM_ID,
};
use std::convert::TryInto;
declare_id!("C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS");
#[derive(Accounts)]
#[instruction(params: ReadHistoryParams)]
pub struct ReadHistory<'info> {
#[account(
has_one = history_buffer @ ErrorCode::InvalidHistoryBuffer,
constraint =
*aggregator.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ ErrorCode::InvalidSwitchboardAccount
)]
pub aggregator: AccountLoader<'info, AggregatorAccountData>,
/// CHECK: Verified by aggregator.history_buffer
#[account(
constraint =
*aggregator.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ ErrorCode::InvalidSwitchboardAccount
)]
pub history_buffer: AccountInfo<'info>,
}
#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
pub struct ReadHistoryParams {
pub timestamp: Option<i64>,
}
#[program]
pub mod anchor_history_parser {
use super::*;
pub fn read_history(
ctx: Context<ReadHistory>,
params: ReadHistoryParams,
) -> anchor_lang::Result<()> {
let aggregator = &ctx.accounts.aggregator.load()?;
// we validate this in the context but adding here for demonstration purposes
if aggregator.history_buffer != ctx.accounts.history_buffer.key() {
return Err(error!(ErrorCode::InvalidHistoryBuffer));
}
// demonstration purposes
if *ctx.accounts.history_buffer.owner != SWITCHBOARD_PROGRAM_ID {
return Err(error!(ErrorCode::InvalidHistoryBuffer));
}
let history_buffer = AggregatorHistoryBuffer::new(&ctx.accounts.history_buffer)?;
let timestamp: i64;
if let Some(i) = params.timestamp {
timestamp = i;
} else {
// one hour ago
timestamp = Clock::get()?.unix_timestamp - 3600;
}
let value_at_timestamp: f64 = history_buffer.lower_bound(timestamp).unwrap().value.try_into()?;
msg!("Result {:?}!", value_at_timestamp);
Ok(())
}
}
#[error_code]
#[derive(Eq, PartialEq)]
pub enum ErrorCode {
#[msg("Not a valid Switchboard account")]
InvalidSwitchboardAccount,
#[msg("History buffer mismatch")]
InvalidHistoryBuffer,
}

View File

@ -0,0 +1,60 @@
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import {
AggregatorAccount,
loadSwitchboardProgram,
programWallet,
} from "@switchboard-xyz/switchboard-v2";
import { AnchorHistoryParser } from "../target/types/anchor_history_parser";
export const AGGREGATOR_PUBKEY: anchor.web3.PublicKey =
new anchor.web3.PublicKey("GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR");
export const HISTORY_BUFFER_PUBKEY: anchor.web3.PublicKey =
new anchor.web3.PublicKey("7LLvRhMs73FqcLkA8jvEE1AM2mYZXTmqfUv8GAEurymx");
export const sleep = (ms: number): Promise<any> =>
new Promise((s) => setTimeout(s, ms));
describe("anchor-history-parser", () => {
// Configure the client to use the local cluster.
anchor.setProvider(anchor.AnchorProvider.env());
const program = anchor.workspace
.AnchorHistoryParser as Program<AnchorHistoryParser>;
it("Reads an aggregator history buffer", async () => {
// const ONE_HOUR_AGO: number = Math.floor(Date.now()) - 60 * 60;
const switchboard = await loadSwitchboardProgram(
"devnet",
program.provider.connection
);
const aggregatorAccount = new AggregatorAccount({
program: switchboard,
publicKey: AGGREGATOR_PUBKEY,
});
const aggregator = await aggregatorAccount.loadData();
// TODO: Verify the value in the program logs matches the history samples
const history = await aggregatorAccount.loadHistory();
const tx = await program.methods
.readHistory({ timestamp: null })
.accounts({
aggregator: AGGREGATOR_PUBKEY,
historyBuffer: aggregator.historyBuffer,
})
.rpc();
console.log("Your transaction signature", tx);
await sleep(5000);
const confirmedTxn = await program.provider.connection.getParsedTransaction(
tx,
"confirmed"
);
console.log(JSON.stringify(confirmedTxn?.meta?.logMessages, undefined, 2));
});
});

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"],
"lib": ["es2019", "dom"],
"moduleResolution": "node",
"module": "commonjs",
"target": "es6",
"esModuleInterop": true,
"paths": {
"@switchboard-xyz/switchboard-v2": ["../../javascript/solana.js"],
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"]
}
},
"include": [
"tests/**/*",
"client/**/*",
"./target/types/anchor_history_parser"
],
"references": [
{ "path": "../../javascript/solana.js" },
{ "path": "../../javascript/sbv2-utils" }
]
}

File diff suppressed because it is too large Load Diff