parent
c63b80dc5a
commit
6c3283db30
|
@ -1,31 +0,0 @@
|
|||
[workspace]
|
||||
members = [
|
||||
"examples/programs/anchor-feed-parser",
|
||||
"examples/programs/anchor-vrf-parser",
|
||||
"examples/programs/anchor-buffer-parser",
|
||||
"examples/programs/native-feed-parser"
|
||||
]
|
||||
|
||||
[provider]
|
||||
# cluster = "devnet"
|
||||
cluster = "localnet"
|
||||
wallet = "../payer-keypair.json"
|
||||
# wallet = "~/.config/solana/id.json"
|
||||
|
||||
[programs.localnet]
|
||||
anchor_feed_parser = "FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
|
||||
anchor_vrf_parser = "HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
|
||||
anchor_buffer_parser = "96punQGZDShZGkzsBa3SsfTxfUnwu4XGpzXbhF7NTgcP"
|
||||
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
|
||||
[scripts]
|
||||
test = "yarn run ts-mocha -p ./tsconfig.testing.json -t 1000000 ./examples/programs/*/tests/*.test.ts"
|
||||
|
||||
|
||||
[test.validator]
|
||||
url="https://api.devnet.solana.com"
|
||||
|
||||
[[testnet.validator.clone]]
|
||||
address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
|
|
@ -18,9 +18,9 @@
|
|||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/web3.js": "^1.33.0",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.136",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"big.js": "^6.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../solana.js"]
|
||||
"@switchboard-xyz/switchboard-v2": ["../switchboard-v2"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["esbuild.js", "dist"],
|
||||
"references": [{ "path": "../solana.js" }],
|
||||
"references": [{ "path": "../switchboard-v2" }],
|
||||
"files": ["src/main.ts"]
|
||||
}
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
"test": "echo \"No test script for @switchboard-xyz/v2-feed-walkthrough\" && exit 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/spl-token-v2": "npm:@solana/spl-token@^0.2.0",
|
||||
"@solana/web3.js": "^1.50.1",
|
||||
"@switchboard-xyz/common": "^2.0.0",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.136",
|
||||
"@switchboard-xyz/common": "^2.1.7",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"chalk": "^4.1.2",
|
||||
"dotenv": "^16.0.1",
|
||||
"readline-sync": "^1.4.10"
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../switchboard-v2"],
|
||||
"@solana/spl-token": ["./node_modules/@solana/spl-token"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["esbuild.js", "dist"],
|
||||
"references": [{ "path": "../solana.js" }],
|
||||
"references": [{ "path": "../switchboard-v2" }],
|
||||
"files": ["src/main.ts"]
|
||||
}
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
"test": "echo \"No test script for @switchboard-xyz/lease-observer\" && exit 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/web3.js": "1.33.0",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.49",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.136",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"dotenv": "^16.0.1",
|
||||
"node-pagerduty": "^1.3.6"
|
||||
},
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
"rootDir": "src",
|
||||
"strict": false,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../sbv2-utils"],
|
||||
"@solana/spl-token": ["./node_modules/@solana/spl-token"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"references": [{ "path": "../solana.js" }, { "path": "../sbv2-utils" }],
|
||||
"references": [{ "path": "../switchboard-v2" }, { "path": "../sbv2-utils" }],
|
||||
"files": ["src/main.ts"]
|
||||
}
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
"@saberhq/token-utils": "^1.13.32",
|
||||
"@solana/spl-token-v2": "npm:@solana/spl-token@^0.2.0",
|
||||
"@solana/web3.js": "^1.66.2",
|
||||
"@switchboard-xyz/common": "^2.1.3",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.159",
|
||||
"@switchboard-xyz/common": "^2.1.7",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"big.js": "^6.2.1",
|
||||
"bn.js": "^5.2.1",
|
||||
"chalk": "4",
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/switchboard-xyz/switchboard-v2",
|
||||
"directory": "javascript/solana.js"
|
||||
"directory": "javascript/switchboard-v2"
|
||||
},
|
||||
"homepage": "https://docs.switchboard.xyz",
|
||||
"files": [
|
|
@ -5,19 +5,18 @@ import * as spl from "@solana/spl-token-v2";
|
|||
import {
|
||||
AccountInfo,
|
||||
AccountMeta,
|
||||
ComputeBudgetProgram,
|
||||
clusterApiUrl,
|
||||
ConfirmOptions,
|
||||
Connection,
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||
SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
sendAndConfirmTransaction,
|
||||
Signer,
|
||||
SystemProgram,
|
||||
SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||
SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
Transaction,
|
||||
TransactionSignature,
|
||||
clusterApiUrl,
|
||||
sendAndConfirmTransaction,
|
||||
} from "@solana/web3.js";
|
||||
import { OracleJob, SwitchboardDecimal, toUtf8 } from "@switchboard-xyz/common";
|
||||
import assert from "assert";
|
||||
|
@ -825,10 +824,7 @@ export class AggregatorAccount {
|
|||
* @param aggregator The loaded aggegator schema
|
||||
* @returns boolean
|
||||
*/
|
||||
static async shouldReportValue(
|
||||
value: Big,
|
||||
aggregator: any
|
||||
): Promise<boolean> {
|
||||
static shouldReportValue(value: Big, aggregator: any): boolean {
|
||||
if ((aggregator.latestConfirmedRound?.numSuccess ?? 0) === 0) {
|
||||
return true;
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
### Sbv2 Program Examples
|
||||
|
||||
| Package | Description |
|
||||
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [anchor-feed-parser](./anchor-feed-parser) | Anchor example program demonstrating how to deserialize and read an onchain aggregator account. |
|
||||
| [native-feed-parser](./native-feed-parser) | Solana Program Library example demonstrating how to deserialize and read an onchain aggregator account. |
|
||||
| [anchor-vrf-parser](./anchor-vrf-parser) | Anchor example program demonstrating how to deserialize and read an onchain verifiable randomness function (VRF) account. |
|
||||
| [anchor-buffer-parser](./anchor-buffer-parser) | Anchor example program demonstrating how to deserialize and read an onchain buffer relayer account. |
|
||||
| Package | Description |
|
||||
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- |
|
||||
| [anchor-feed-parser](./anchor-feed-parser) | Anchor example program demonstrating how to deserialize and read an onchain aggregator account. |
|
||||
| [native-feed-parser](./native-feed-parser) | Solana Program Library example demonstrating how to deserialize and read an onchain aggregator account. |
|
||||
| [anchor-history-parser](./anchor-history-parser) | Anchor example program demonstrating how to deserialize and read an onchain aggregator history buffer account. |
|
||||
| [anchor-vrf-parser](./anchor-vrf-parser) | Anchor example program demonstrating how to deserialize and read an onchain verifiable randomness function (VRF) account. |
|
||||
| [anchor-buffer-parser](./anchor-buffer-parser) | Anchor example program demonstrating how to deserialize and read an onchain buffer relayer account. |
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
client/
|
|
@ -22,5 +22,50 @@ test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 ./tests/*.test.ts"
|
|||
[test.validator]
|
||||
url="https://api.devnet.solana.com"
|
||||
|
||||
[test]
|
||||
startup_wait = 10000
|
||||
|
||||
[[testnet.validator.clone]]
|
||||
address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
|
||||
address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
|
||||
|
||||
# [[test.validator.clone]] # programID
|
||||
# address = "2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG"
|
||||
|
||||
# [[test.validator.clone]] # idlAddress
|
||||
# address = "CKwZcshn4XDvhaWVH9EXnk3iu19t6t5xP2Sy2pD6TRDp"
|
||||
|
||||
# [[test.validator.clone]] # programState
|
||||
# address = "BYM81n8HvTJuqZU1PmTVcwZ9G8uoji7FKM6EaPkwphPt"
|
||||
|
||||
# [[test.validator.clone]] # switchboardVault
|
||||
# address = "FVLfR6C2ckZhbSwBzZY4CX7YBcddUSge5BNeGQv5eKhy"
|
||||
|
||||
# [[test.validator.clone]] # tokenWallet
|
||||
# address = "98noixB6NnabjgFKw9wgXtqVd9Xg6rmj5kEVMeCHUB5e"
|
||||
|
||||
# [[test.validator.clone]] # queue
|
||||
# address = "AGhkGTuVfSGKYoFcRCUbbPNxhnaWNRXzcAYndyHdNV3V"
|
||||
|
||||
# [[test.validator.clone]] # queueAuthority
|
||||
# address = "AXrbiv8bmcJfscyYWjR8BMFvTUjmx7FSENCjtEx4NxFh"
|
||||
|
||||
# [[test.validator.clone]] # queueBuffer
|
||||
# address = "9SYE1tzHxKvRCYAv1yLLA4iMjk3p3VWiqgZX8v4HNBrw"
|
||||
|
||||
# [[test.validator.clone]] # crank
|
||||
# address = "7xN6FXxJBtPVgrzcAZogvw7kWjz1NQdXmx7hoTVG3abF"
|
||||
|
||||
# [[test.validator.clone]] # crankBuffer
|
||||
# address = "6pANimo6hHXShDcWdNZjsW6cbc2azGhcLGdnCBC4TBi8"
|
||||
|
||||
# [[test.validator.clone]] # oracle
|
||||
# address = "JArZ6Van92SM6VyaARFmstgX2n9TJmLvVBN9ZkwpKH8B"
|
||||
|
||||
# [[test.validator.clone]] # oracleAuthority
|
||||
# address = "AXrbiv8bmcJfscyYWjR8BMFvTUjmx7FSENCjtEx4NxFh"
|
||||
|
||||
# [[test.validator.clone]] # oracleEscrow
|
||||
# address = "3Dm7ZuqNH89QLBuuJbqa4XZfpz8n1pCobP23NtVisQHE"
|
||||
|
||||
# [[test.validator.clone]] # oraclePermissions
|
||||
# address = "GgNZcKzHBtEiLuDeaRAT8SsMTyG5Yzpm4XvetiazkHHW"
|
||||
|
|
|
@ -16,7 +16,7 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.14", features = ["devnet"] }
|
||||
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"
|
|
@ -1,70 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { PROGRAM_ID } from "../programId";
|
||||
|
||||
export interface BufferClientFields {}
|
||||
|
||||
export interface BufferClientJSON {}
|
||||
|
||||
export class BufferClient {
|
||||
static readonly discriminator = Buffer.from([
|
||||
142, 182, 89, 69, 9, 66, 10, 86,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([]);
|
||||
|
||||
constructor(fields: BufferClientFields) {}
|
||||
|
||||
static async fetch(
|
||||
c: Connection,
|
||||
programId: PublicKey,
|
||||
address: PublicKey
|
||||
): Promise<BufferClient | null> {
|
||||
const info = await c.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
c: Connection,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<BufferClient | null>> {
|
||||
const infos = await c.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): BufferClient {
|
||||
if (!data.slice(0, 8).equals(BufferClient.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = BufferClient.layout.decode(data.slice(8));
|
||||
|
||||
return new BufferClient({});
|
||||
}
|
||||
|
||||
toJSON(): BufferClientJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(obj: BufferClientJSON): BufferClient {
|
||||
return new BufferClient({});
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export {
|
||||
BufferClient,
|
||||
BufferClientFields,
|
||||
BufferClientJSON,
|
||||
} from "./BufferClient"
|
|
@ -1,690 +0,0 @@
|
|||
export type AnchorError =
|
||||
| InstructionMissing
|
||||
| InstructionFallbackNotFound
|
||||
| InstructionDidNotDeserialize
|
||||
| InstructionDidNotSerialize
|
||||
| IdlInstructionStub
|
||||
| IdlInstructionInvalidProgram
|
||||
| ConstraintMut
|
||||
| ConstraintHasOne
|
||||
| ConstraintSigner
|
||||
| ConstraintRaw
|
||||
| ConstraintOwner
|
||||
| ConstraintRentExempt
|
||||
| ConstraintSeeds
|
||||
| ConstraintExecutable
|
||||
| ConstraintState
|
||||
| ConstraintAssociated
|
||||
| ConstraintAssociatedInit
|
||||
| ConstraintClose
|
||||
| ConstraintAddress
|
||||
| ConstraintZero
|
||||
| ConstraintTokenMint
|
||||
| ConstraintTokenOwner
|
||||
| ConstraintMintMintAuthority
|
||||
| ConstraintMintFreezeAuthority
|
||||
| ConstraintMintDecimals
|
||||
| ConstraintSpace
|
||||
| RequireViolated
|
||||
| RequireEqViolated
|
||||
| RequireKeysEqViolated
|
||||
| RequireNeqViolated
|
||||
| RequireKeysNeqViolated
|
||||
| RequireGtViolated
|
||||
| RequireGteViolated
|
||||
| AccountDiscriminatorAlreadySet
|
||||
| AccountDiscriminatorNotFound
|
||||
| AccountDiscriminatorMismatch
|
||||
| AccountDidNotDeserialize
|
||||
| AccountDidNotSerialize
|
||||
| AccountNotEnoughKeys
|
||||
| AccountNotMutable
|
||||
| AccountOwnedByWrongProgram
|
||||
| InvalidProgramId
|
||||
| InvalidProgramExecutable
|
||||
| AccountNotSigner
|
||||
| AccountNotSystemOwned
|
||||
| AccountNotInitialized
|
||||
| AccountNotProgramData
|
||||
| AccountNotAssociatedTokenAccount
|
||||
| AccountSysvarMismatch
|
||||
| StateInvalidAddress
|
||||
| DeclaredProgramIdMismatch
|
||||
| Deprecated
|
||||
|
||||
export class InstructionMissing extends Error {
|
||||
readonly code = 100
|
||||
readonly name = "InstructionMissing"
|
||||
readonly msg = "8 byte instruction identifier not provided"
|
||||
|
||||
constructor() {
|
||||
super("100: 8 byte instruction identifier not provided")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionFallbackNotFound extends Error {
|
||||
readonly code = 101
|
||||
readonly name = "InstructionFallbackNotFound"
|
||||
readonly msg = "Fallback functions are not supported"
|
||||
|
||||
constructor() {
|
||||
super("101: Fallback functions are not supported")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotDeserialize extends Error {
|
||||
readonly code = 102
|
||||
readonly name = "InstructionDidNotDeserialize"
|
||||
readonly msg = "The program could not deserialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("102: The program could not deserialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotSerialize extends Error {
|
||||
readonly code = 103
|
||||
readonly name = "InstructionDidNotSerialize"
|
||||
readonly msg = "The program could not serialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("103: The program could not serialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionStub extends Error {
|
||||
readonly code = 1000
|
||||
readonly name = "IdlInstructionStub"
|
||||
readonly msg = "The program was compiled without idl instructions"
|
||||
|
||||
constructor() {
|
||||
super("1000: The program was compiled without idl instructions")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionInvalidProgram extends Error {
|
||||
readonly code = 1001
|
||||
readonly name = "IdlInstructionInvalidProgram"
|
||||
readonly msg =
|
||||
"The transaction was given an invalid program for the IDL instruction"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"1001: The transaction was given an invalid program for the IDL instruction"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMut extends Error {
|
||||
readonly code = 2000
|
||||
readonly name = "ConstraintMut"
|
||||
readonly msg = "A mut constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2000: A mut constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintHasOne extends Error {
|
||||
readonly code = 2001
|
||||
readonly name = "ConstraintHasOne"
|
||||
readonly msg = "A has_one constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2001: A has_one constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSigner extends Error {
|
||||
readonly code = 2002
|
||||
readonly name = "ConstraintSigner"
|
||||
readonly msg = "A signer constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2002: A signer constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRaw extends Error {
|
||||
readonly code = 2003
|
||||
readonly name = "ConstraintRaw"
|
||||
readonly msg = "A raw constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2003: A raw constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintOwner extends Error {
|
||||
readonly code = 2004
|
||||
readonly name = "ConstraintOwner"
|
||||
readonly msg = "An owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2004: An owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRentExempt extends Error {
|
||||
readonly code = 2005
|
||||
readonly name = "ConstraintRentExempt"
|
||||
readonly msg = "A rent exemption constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2005: A rent exemption constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSeeds extends Error {
|
||||
readonly code = 2006
|
||||
readonly name = "ConstraintSeeds"
|
||||
readonly msg = "A seeds constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2006: A seeds constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintExecutable extends Error {
|
||||
readonly code = 2007
|
||||
readonly name = "ConstraintExecutable"
|
||||
readonly msg = "An executable constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2007: An executable constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintState extends Error {
|
||||
readonly code = 2008
|
||||
readonly name = "ConstraintState"
|
||||
readonly msg = "A state constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2008: A state constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociated extends Error {
|
||||
readonly code = 2009
|
||||
readonly name = "ConstraintAssociated"
|
||||
readonly msg = "An associated constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2009: An associated constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociatedInit extends Error {
|
||||
readonly code = 2010
|
||||
readonly name = "ConstraintAssociatedInit"
|
||||
readonly msg = "An associated init constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2010: An associated init constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintClose extends Error {
|
||||
readonly code = 2011
|
||||
readonly name = "ConstraintClose"
|
||||
readonly msg = "A close constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2011: A close constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAddress extends Error {
|
||||
readonly code = 2012
|
||||
readonly name = "ConstraintAddress"
|
||||
readonly msg = "An address constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2012: An address constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintZero extends Error {
|
||||
readonly code = 2013
|
||||
readonly name = "ConstraintZero"
|
||||
readonly msg = "Expected zero account discriminant"
|
||||
|
||||
constructor() {
|
||||
super("2013: Expected zero account discriminant")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenMint extends Error {
|
||||
readonly code = 2014
|
||||
readonly name = "ConstraintTokenMint"
|
||||
readonly msg = "A token mint constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2014: A token mint constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenOwner extends Error {
|
||||
readonly code = 2015
|
||||
readonly name = "ConstraintTokenOwner"
|
||||
readonly msg = "A token owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2015: A token owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintMintAuthority extends Error {
|
||||
readonly code = 2016
|
||||
readonly name = "ConstraintMintMintAuthority"
|
||||
readonly msg = "A mint mint authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2016: A mint mint authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintFreezeAuthority extends Error {
|
||||
readonly code = 2017
|
||||
readonly name = "ConstraintMintFreezeAuthority"
|
||||
readonly msg = "A mint freeze authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2017: A mint freeze authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintDecimals extends Error {
|
||||
readonly code = 2018
|
||||
readonly name = "ConstraintMintDecimals"
|
||||
readonly msg = "A mint decimals constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2018: A mint decimals constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSpace extends Error {
|
||||
readonly code = 2019
|
||||
readonly name = "ConstraintSpace"
|
||||
readonly msg = "A space constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2019: A space constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireViolated extends Error {
|
||||
readonly code = 2500
|
||||
readonly name = "RequireViolated"
|
||||
readonly msg = "A require expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2500: A require expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireEqViolated extends Error {
|
||||
readonly code = 2501
|
||||
readonly name = "RequireEqViolated"
|
||||
readonly msg = "A require_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2501: A require_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysEqViolated extends Error {
|
||||
readonly code = 2502
|
||||
readonly name = "RequireKeysEqViolated"
|
||||
readonly msg = "A require_keys_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2502: A require_keys_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireNeqViolated extends Error {
|
||||
readonly code = 2503
|
||||
readonly name = "RequireNeqViolated"
|
||||
readonly msg = "A require_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2503: A require_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysNeqViolated extends Error {
|
||||
readonly code = 2504
|
||||
readonly name = "RequireKeysNeqViolated"
|
||||
readonly msg = "A require_keys_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2504: A require_keys_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGtViolated extends Error {
|
||||
readonly code = 2505
|
||||
readonly name = "RequireGtViolated"
|
||||
readonly msg = "A require_gt expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2505: A require_gt expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGteViolated extends Error {
|
||||
readonly code = 2506
|
||||
readonly name = "RequireGteViolated"
|
||||
readonly msg = "A require_gte expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2506: A require_gte expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorAlreadySet extends Error {
|
||||
readonly code = 3000
|
||||
readonly name = "AccountDiscriminatorAlreadySet"
|
||||
readonly msg = "The account discriminator was already set on this account"
|
||||
|
||||
constructor() {
|
||||
super("3000: The account discriminator was already set on this account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorNotFound extends Error {
|
||||
readonly code = 3001
|
||||
readonly name = "AccountDiscriminatorNotFound"
|
||||
readonly msg = "No 8 byte discriminator was found on the account"
|
||||
|
||||
constructor() {
|
||||
super("3001: No 8 byte discriminator was found on the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorMismatch extends Error {
|
||||
readonly code = 3002
|
||||
readonly name = "AccountDiscriminatorMismatch"
|
||||
readonly msg = "8 byte discriminator did not match what was expected"
|
||||
|
||||
constructor() {
|
||||
super("3002: 8 byte discriminator did not match what was expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotDeserialize extends Error {
|
||||
readonly code = 3003
|
||||
readonly name = "AccountDidNotDeserialize"
|
||||
readonly msg = "Failed to deserialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3003: Failed to deserialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotSerialize extends Error {
|
||||
readonly code = 3004
|
||||
readonly name = "AccountDidNotSerialize"
|
||||
readonly msg = "Failed to serialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3004: Failed to serialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotEnoughKeys extends Error {
|
||||
readonly code = 3005
|
||||
readonly name = "AccountNotEnoughKeys"
|
||||
readonly msg = "Not enough account keys given to the instruction"
|
||||
|
||||
constructor() {
|
||||
super("3005: Not enough account keys given to the instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotMutable extends Error {
|
||||
readonly code = 3006
|
||||
readonly name = "AccountNotMutable"
|
||||
readonly msg = "The given account is not mutable"
|
||||
|
||||
constructor() {
|
||||
super("3006: The given account is not mutable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountOwnedByWrongProgram extends Error {
|
||||
readonly code = 3007
|
||||
readonly name = "AccountOwnedByWrongProgram"
|
||||
readonly msg =
|
||||
"The given account is owned by a different program than expected"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"3007: The given account is owned by a different program than expected"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramId extends Error {
|
||||
readonly code = 3008
|
||||
readonly name = "InvalidProgramId"
|
||||
readonly msg = "Program ID was not as expected"
|
||||
|
||||
constructor() {
|
||||
super("3008: Program ID was not as expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramExecutable extends Error {
|
||||
readonly code = 3009
|
||||
readonly name = "InvalidProgramExecutable"
|
||||
readonly msg = "Program account is not executable"
|
||||
|
||||
constructor() {
|
||||
super("3009: Program account is not executable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSigner extends Error {
|
||||
readonly code = 3010
|
||||
readonly name = "AccountNotSigner"
|
||||
readonly msg = "The given account did not sign"
|
||||
|
||||
constructor() {
|
||||
super("3010: The given account did not sign")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSystemOwned extends Error {
|
||||
readonly code = 3011
|
||||
readonly name = "AccountNotSystemOwned"
|
||||
readonly msg = "The given account is not owned by the system program"
|
||||
|
||||
constructor() {
|
||||
super("3011: The given account is not owned by the system program")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotInitialized extends Error {
|
||||
readonly code = 3012
|
||||
readonly name = "AccountNotInitialized"
|
||||
readonly msg = "The program expected this account to be already initialized"
|
||||
|
||||
constructor() {
|
||||
super("3012: The program expected this account to be already initialized")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotProgramData extends Error {
|
||||
readonly code = 3013
|
||||
readonly name = "AccountNotProgramData"
|
||||
readonly msg = "The given account is not a program data account"
|
||||
|
||||
constructor() {
|
||||
super("3013: The given account is not a program data account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotAssociatedTokenAccount extends Error {
|
||||
readonly code = 3014
|
||||
readonly name = "AccountNotAssociatedTokenAccount"
|
||||
readonly msg = "The given account is not the associated token account"
|
||||
|
||||
constructor() {
|
||||
super("3014: The given account is not the associated token account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountSysvarMismatch extends Error {
|
||||
readonly code = 3015
|
||||
readonly name = "AccountSysvarMismatch"
|
||||
readonly msg = "The given public key does not match the required sysvar"
|
||||
|
||||
constructor() {
|
||||
super("3015: The given public key does not match the required sysvar")
|
||||
}
|
||||
}
|
||||
|
||||
export class StateInvalidAddress extends Error {
|
||||
readonly code = 4000
|
||||
readonly name = "StateInvalidAddress"
|
||||
readonly msg = "The given state account does not have the correct address"
|
||||
|
||||
constructor() {
|
||||
super("4000: The given state account does not have the correct address")
|
||||
}
|
||||
}
|
||||
|
||||
export class DeclaredProgramIdMismatch extends Error {
|
||||
readonly code = 4100
|
||||
readonly name = "DeclaredProgramIdMismatch"
|
||||
readonly msg = "The declared program id does not match the actual program id"
|
||||
|
||||
constructor() {
|
||||
super("4100: The declared program id does not match the actual program id")
|
||||
}
|
||||
}
|
||||
|
||||
export class Deprecated extends Error {
|
||||
readonly code = 5000
|
||||
readonly name = "Deprecated"
|
||||
readonly msg = "The API being used is deprecated and should no longer be used"
|
||||
|
||||
constructor() {
|
||||
super("5000: The API being used is deprecated and should no longer be used")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): AnchorError | null {
|
||||
switch (code) {
|
||||
case 100:
|
||||
return new InstructionMissing()
|
||||
case 101:
|
||||
return new InstructionFallbackNotFound()
|
||||
case 102:
|
||||
return new InstructionDidNotDeserialize()
|
||||
case 103:
|
||||
return new InstructionDidNotSerialize()
|
||||
case 1000:
|
||||
return new IdlInstructionStub()
|
||||
case 1001:
|
||||
return new IdlInstructionInvalidProgram()
|
||||
case 2000:
|
||||
return new ConstraintMut()
|
||||
case 2001:
|
||||
return new ConstraintHasOne()
|
||||
case 2002:
|
||||
return new ConstraintSigner()
|
||||
case 2003:
|
||||
return new ConstraintRaw()
|
||||
case 2004:
|
||||
return new ConstraintOwner()
|
||||
case 2005:
|
||||
return new ConstraintRentExempt()
|
||||
case 2006:
|
||||
return new ConstraintSeeds()
|
||||
case 2007:
|
||||
return new ConstraintExecutable()
|
||||
case 2008:
|
||||
return new ConstraintState()
|
||||
case 2009:
|
||||
return new ConstraintAssociated()
|
||||
case 2010:
|
||||
return new ConstraintAssociatedInit()
|
||||
case 2011:
|
||||
return new ConstraintClose()
|
||||
case 2012:
|
||||
return new ConstraintAddress()
|
||||
case 2013:
|
||||
return new ConstraintZero()
|
||||
case 2014:
|
||||
return new ConstraintTokenMint()
|
||||
case 2015:
|
||||
return new ConstraintTokenOwner()
|
||||
case 2016:
|
||||
return new ConstraintMintMintAuthority()
|
||||
case 2017:
|
||||
return new ConstraintMintFreezeAuthority()
|
||||
case 2018:
|
||||
return new ConstraintMintDecimals()
|
||||
case 2019:
|
||||
return new ConstraintSpace()
|
||||
case 2500:
|
||||
return new RequireViolated()
|
||||
case 2501:
|
||||
return new RequireEqViolated()
|
||||
case 2502:
|
||||
return new RequireKeysEqViolated()
|
||||
case 2503:
|
||||
return new RequireNeqViolated()
|
||||
case 2504:
|
||||
return new RequireKeysNeqViolated()
|
||||
case 2505:
|
||||
return new RequireGtViolated()
|
||||
case 2506:
|
||||
return new RequireGteViolated()
|
||||
case 3000:
|
||||
return new AccountDiscriminatorAlreadySet()
|
||||
case 3001:
|
||||
return new AccountDiscriminatorNotFound()
|
||||
case 3002:
|
||||
return new AccountDiscriminatorMismatch()
|
||||
case 3003:
|
||||
return new AccountDidNotDeserialize()
|
||||
case 3004:
|
||||
return new AccountDidNotSerialize()
|
||||
case 3005:
|
||||
return new AccountNotEnoughKeys()
|
||||
case 3006:
|
||||
return new AccountNotMutable()
|
||||
case 3007:
|
||||
return new AccountOwnedByWrongProgram()
|
||||
case 3008:
|
||||
return new InvalidProgramId()
|
||||
case 3009:
|
||||
return new InvalidProgramExecutable()
|
||||
case 3010:
|
||||
return new AccountNotSigner()
|
||||
case 3011:
|
||||
return new AccountNotSystemOwned()
|
||||
case 3012:
|
||||
return new AccountNotInitialized()
|
||||
case 3013:
|
||||
return new AccountNotProgramData()
|
||||
case 3014:
|
||||
return new AccountNotAssociatedTokenAccount()
|
||||
case 3015:
|
||||
return new AccountSysvarMismatch()
|
||||
case 4000:
|
||||
return new StateInvalidAddress()
|
||||
case 4100:
|
||||
return new DeclaredProgramIdMismatch()
|
||||
case 5000:
|
||||
return new Deprecated()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,63 +0,0 @@
|
|||
export type CustomError =
|
||||
| InvalidSwitchboardAccount
|
||||
| ExpectedResultMismatch
|
||||
| StaleBuffer
|
||||
| StringConversionFailed
|
||||
|
||||
export class InvalidSwitchboardAccount extends Error {
|
||||
readonly code = 6000
|
||||
readonly name = "InvalidSwitchboardAccount"
|
||||
readonly msg = "Not a valid Switchboard account"
|
||||
|
||||
constructor() {
|
||||
super("6000: Not a valid Switchboard account")
|
||||
}
|
||||
}
|
||||
|
||||
export class ExpectedResultMismatch extends Error {
|
||||
readonly code = 6001
|
||||
readonly name = "ExpectedResultMismatch"
|
||||
readonly msg = "Switchboard buffer does not match provided expected_result!"
|
||||
|
||||
constructor() {
|
||||
super("6001: Switchboard buffer does not match provided expected_result!")
|
||||
}
|
||||
}
|
||||
|
||||
export class StaleBuffer extends Error {
|
||||
readonly code = 6002
|
||||
readonly name = "StaleBuffer"
|
||||
readonly msg =
|
||||
"Switchboard buffer has not been updated in the last 5 minutes!"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"6002: Switchboard buffer has not been updated in the last 5 minutes!"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class StringConversionFailed extends Error {
|
||||
readonly code = 6003
|
||||
readonly name = "StringConversionFailed"
|
||||
readonly msg = "Failed to convert the buffer to a string!"
|
||||
|
||||
constructor() {
|
||||
super("6003: Failed to convert the buffer to a string!")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): CustomError | null {
|
||||
switch (code) {
|
||||
case 6000:
|
||||
return new InvalidSwitchboardAccount()
|
||||
case 6001:
|
||||
return new ExpectedResultMismatch()
|
||||
case 6002:
|
||||
return new StaleBuffer()
|
||||
case 6003:
|
||||
return new StringConversionFailed()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { PROGRAM_ID } from "../programId"
|
||||
import * as anchor from "./anchor"
|
||||
import * as custom from "./custom"
|
||||
|
||||
export function fromCode(
|
||||
code: number
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
return code >= 6000 ? custom.fromCode(code) : anchor.fromCode(code)
|
||||
}
|
||||
|
||||
function hasOwnProperty<X extends object, Y extends PropertyKey>(
|
||||
obj: X,
|
||||
prop: Y
|
||||
): obj is X & Record<Y, unknown> {
|
||||
return Object.hasOwnProperty.call(obj, prop)
|
||||
}
|
||||
|
||||
const errorRe = /Program (\w+) failed: custom program error: (\w+)/
|
||||
|
||||
export function fromTxError(
|
||||
err: unknown
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
if (
|
||||
typeof err !== "object" ||
|
||||
err === null ||
|
||||
!hasOwnProperty(err, "logs") ||
|
||||
!Array.isArray(err.logs)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
let firstMatch: RegExpExecArray | null = null
|
||||
for (const logLine of err.logs) {
|
||||
firstMatch = errorRe.exec(logLine)
|
||||
if (firstMatch !== null) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMatch === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [programIdRaw, codeRaw] = firstMatch.slice(1)
|
||||
if (programIdRaw !== PROGRAM_ID.toString()) {
|
||||
return null
|
||||
}
|
||||
|
||||
let errorCode: number
|
||||
try {
|
||||
errorCode = parseInt(codeRaw, 16)
|
||||
} catch (parseErr) {
|
||||
return null
|
||||
}
|
||||
|
||||
return fromCode(errorCode)
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export { readResult, ReadResultAccounts, ReadResultArgs } from "./readResult"
|
|
@ -1,29 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId"
|
||||
import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface ReadResultArgs {
|
||||
params: types.ReadResultParamsFields
|
||||
}
|
||||
|
||||
export interface ReadResultAccounts {
|
||||
buffer: PublicKey
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.ReadResultParams.layout("params")])
|
||||
|
||||
export function readResult(args: ReadResultArgs, accounts: ReadResultAccounts) {
|
||||
const keys = [{ pubkey: accounts.buffer, isSigner: false, isWritable: false }]
|
||||
const identifier = Buffer.from([130, 229, 115, 203, 180, 191, 240, 90])
|
||||
const buffer = Buffer.alloc(1000)
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.ReadResultParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
)
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
|
||||
const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data })
|
||||
return ix
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import { PublicKey } from "@solana/web3.js"
|
||||
|
||||
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
|
||||
export const PROGRAM_ID_CLI = new PublicKey(
|
||||
"96punQGZDShZGkzsBa3SsfTxfUnwu4XGpzXbhF7NTgcP"
|
||||
)
|
||||
|
||||
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
|
||||
export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI
|
|
@ -1,55 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"
|
||||
|
||||
export interface ReadResultParamsFields {
|
||||
expectedResult: Array<number> | null
|
||||
}
|
||||
|
||||
export interface ReadResultParamsJSON {
|
||||
expectedResult: Array<number> | null
|
||||
}
|
||||
|
||||
export class ReadResultParams {
|
||||
readonly expectedResult: Array<number> | null
|
||||
|
||||
constructor(fields: ReadResultParamsFields) {
|
||||
this.expectedResult = fields.expectedResult
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[borsh.option(borsh.vecU8(), "expectedResult")],
|
||||
property
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new ReadResultParams({
|
||||
expectedResult:
|
||||
(obj.expectedResult && Array.from(obj.expectedResult)) || null,
|
||||
})
|
||||
}
|
||||
|
||||
static toEncodable(fields: ReadResultParamsFields) {
|
||||
return {
|
||||
expectedResult:
|
||||
(fields.expectedResult && Buffer.from(fields.expectedResult)) || null,
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): ReadResultParamsJSON {
|
||||
return {
|
||||
expectedResult: this.expectedResult,
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(obj: ReadResultParamsJSON): ReadResultParams {
|
||||
return new ReadResultParams({
|
||||
expectedResult: obj.expectedResult,
|
||||
})
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return ReadResultParams.toEncodable(this)
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export {
|
||||
ReadResultParams,
|
||||
ReadResultParamsFields,
|
||||
ReadResultParamsJSON,
|
||||
} from "./ReadResultParams"
|
File diff suppressed because it is too large
Load Diff
|
@ -12,11 +12,11 @@
|
|||
"lint": "eslint --ext .js,.json,.ts 'src/**' --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@solana/web3.js": "^1.42.0",
|
||||
"@switchboard-xyz/common": "^2.0.0",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.43",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.135",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/web3.js": "^1.66.2",
|
||||
"@switchboard-xyz/common": "^2.1.7",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"node-fetch": "^2.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -28,10 +28,8 @@ pub mod anchor_buffer_parser {
|
|||
ctx: Context<ReadResult>,
|
||||
params: ReadResultParams,
|
||||
) -> anchor_lang::Result<()> {
|
||||
let buffer_account = &ctx.accounts.buffer;
|
||||
|
||||
// load and deserialize buffer
|
||||
let buffer = BufferRelayerAccountData::new(buffer_account)?;
|
||||
let buffer = BufferRelayerAccountData::new(&ctx.accounts.buffer)?;
|
||||
|
||||
msg!("Buffer account loaded!");
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ import {
|
|||
PermissionAccount,
|
||||
} from "@switchboard-xyz/switchboard-v2";
|
||||
import fetch from "node-fetch";
|
||||
import { AnchorBufferParser, IDL } from "../target/types/anchor_buffer_parser";
|
||||
import { PROGRAM_ID } from "../client/programId";
|
||||
import { AnchorBufferParser, IDL } from "../target/types/anchor_buffer_parser";
|
||||
|
||||
describe("anchor-buffer-parser test", () => {
|
||||
const provider = anchor.AnchorProvider.env();
|
||||
|
@ -41,6 +41,7 @@ describe("anchor-buffer-parser test", () => {
|
|||
return;
|
||||
} catch (error: any) {
|
||||
console.log(`Error: SBV2 Localnet - ${error.message}`);
|
||||
console.error(error);
|
||||
}
|
||||
// If fails, throw error
|
||||
throw new Error(
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"]
|
||||
}
|
||||
},
|
||||
"include": ["tests/**/*", "client/**/*", "./target/types/anchor_feed_parser"],
|
||||
"references": [
|
||||
{ "path": "../../javascript/solana.js" },
|
||||
{ "path": "../../javascript/switchboard-v2" },
|
||||
{ "path": "../../javascript/sbv2-utils" }
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
client/
|
|
@ -3,14 +3,12 @@ members = [
|
|||
"."
|
||||
]
|
||||
|
||||
[provider]
|
||||
# cluster = "devnet"
|
||||
cluster = "localnet"
|
||||
wallet = "../../../payer-keypair.json"
|
||||
# wallet = "~/.config/solana/id.json"
|
||||
|
||||
[programs.localnet]
|
||||
anchor_buffer_parser = "FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
|
||||
anchor_feed_parser = "5cjAZXFoY4KN1Sq35ZYE72fGdVy8sy5YGpNix1N4rtHY"
|
||||
|
||||
[provider]
|
||||
cluster = "devnet"
|
||||
wallet = "~/.config/solana/id.json"
|
||||
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
|
@ -18,9 +16,11 @@ url = "https://anchor.projectserum.com"
|
|||
[scripts]
|
||||
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 ./tests/*.test.ts"
|
||||
|
||||
# [test.validator]
|
||||
# url="https://api.devnet.solana.com"
|
||||
|
||||
[test.validator]
|
||||
url="https://api.devnet.solana.com"
|
||||
# [test]
|
||||
# startup_wait = 10000
|
||||
|
||||
[[testnet.validator.clone]]
|
||||
address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
|
||||
# [[testnet.validator.clone]]
|
||||
# address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed
|
|
@ -16,8 +16,8 @@ cpi = ["no-entrypoint"]
|
|||
default = []
|
||||
|
||||
[dependencies]
|
||||
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.14", features = ["devnet"] }
|
||||
switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
# switchboard-v2 = { version = "0.1.15", features = ["devnet"] }
|
||||
anchor-lang = "^0.25.0"
|
||||
solana-program = "~1.10.29"
|
||||
bytemuck = "1.7.2"
|
|
@ -0,0 +1,8 @@
|
|||
# Anchor Feed Parser
|
||||
|
||||
## Generate the Client
|
||||
|
||||
```bash
|
||||
anchor build
|
||||
npx anchor-client-gen target/idl/anchor_feed_parser.json client --program-id "$(solana-keygen pubkey target/deploy/anchor_feed_parser-keypair.json)"
|
||||
```
|
|
@ -1,70 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { PROGRAM_ID } from "../programId";
|
||||
|
||||
export interface FeedClientFields {}
|
||||
|
||||
export interface FeedClientJSON {}
|
||||
|
||||
export class FeedClient {
|
||||
static readonly discriminator = Buffer.from([
|
||||
30, 15, 152, 236, 85, 180, 84, 151,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([]);
|
||||
|
||||
constructor(fields: FeedClientFields) {}
|
||||
|
||||
static async fetch(
|
||||
c: Connection,
|
||||
programId: PublicKey,
|
||||
address: PublicKey
|
||||
): Promise<FeedClient | null> {
|
||||
const info = await c.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
c: Connection,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<FeedClient | null>> {
|
||||
const infos = await c.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): FeedClient {
|
||||
if (!data.slice(0, 8).equals(FeedClient.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = FeedClient.layout.decode(data.slice(8));
|
||||
|
||||
return new FeedClient({});
|
||||
}
|
||||
|
||||
toJSON(): FeedClientJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FeedClientJSON): FeedClient {
|
||||
return new FeedClient({});
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export { FeedClient, FeedClientFields, FeedClientJSON } from "./FeedClient"
|
|
@ -1,690 +0,0 @@
|
|||
export type AnchorError =
|
||||
| InstructionMissing
|
||||
| InstructionFallbackNotFound
|
||||
| InstructionDidNotDeserialize
|
||||
| InstructionDidNotSerialize
|
||||
| IdlInstructionStub
|
||||
| IdlInstructionInvalidProgram
|
||||
| ConstraintMut
|
||||
| ConstraintHasOne
|
||||
| ConstraintSigner
|
||||
| ConstraintRaw
|
||||
| ConstraintOwner
|
||||
| ConstraintRentExempt
|
||||
| ConstraintSeeds
|
||||
| ConstraintExecutable
|
||||
| ConstraintState
|
||||
| ConstraintAssociated
|
||||
| ConstraintAssociatedInit
|
||||
| ConstraintClose
|
||||
| ConstraintAddress
|
||||
| ConstraintZero
|
||||
| ConstraintTokenMint
|
||||
| ConstraintTokenOwner
|
||||
| ConstraintMintMintAuthority
|
||||
| ConstraintMintFreezeAuthority
|
||||
| ConstraintMintDecimals
|
||||
| ConstraintSpace
|
||||
| RequireViolated
|
||||
| RequireEqViolated
|
||||
| RequireKeysEqViolated
|
||||
| RequireNeqViolated
|
||||
| RequireKeysNeqViolated
|
||||
| RequireGtViolated
|
||||
| RequireGteViolated
|
||||
| AccountDiscriminatorAlreadySet
|
||||
| AccountDiscriminatorNotFound
|
||||
| AccountDiscriminatorMismatch
|
||||
| AccountDidNotDeserialize
|
||||
| AccountDidNotSerialize
|
||||
| AccountNotEnoughKeys
|
||||
| AccountNotMutable
|
||||
| AccountOwnedByWrongProgram
|
||||
| InvalidProgramId
|
||||
| InvalidProgramExecutable
|
||||
| AccountNotSigner
|
||||
| AccountNotSystemOwned
|
||||
| AccountNotInitialized
|
||||
| AccountNotProgramData
|
||||
| AccountNotAssociatedTokenAccount
|
||||
| AccountSysvarMismatch
|
||||
| StateInvalidAddress
|
||||
| DeclaredProgramIdMismatch
|
||||
| Deprecated
|
||||
|
||||
export class InstructionMissing extends Error {
|
||||
readonly code = 100
|
||||
readonly name = "InstructionMissing"
|
||||
readonly msg = "8 byte instruction identifier not provided"
|
||||
|
||||
constructor() {
|
||||
super("100: 8 byte instruction identifier not provided")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionFallbackNotFound extends Error {
|
||||
readonly code = 101
|
||||
readonly name = "InstructionFallbackNotFound"
|
||||
readonly msg = "Fallback functions are not supported"
|
||||
|
||||
constructor() {
|
||||
super("101: Fallback functions are not supported")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotDeserialize extends Error {
|
||||
readonly code = 102
|
||||
readonly name = "InstructionDidNotDeserialize"
|
||||
readonly msg = "The program could not deserialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("102: The program could not deserialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotSerialize extends Error {
|
||||
readonly code = 103
|
||||
readonly name = "InstructionDidNotSerialize"
|
||||
readonly msg = "The program could not serialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("103: The program could not serialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionStub extends Error {
|
||||
readonly code = 1000
|
||||
readonly name = "IdlInstructionStub"
|
||||
readonly msg = "The program was compiled without idl instructions"
|
||||
|
||||
constructor() {
|
||||
super("1000: The program was compiled without idl instructions")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionInvalidProgram extends Error {
|
||||
readonly code = 1001
|
||||
readonly name = "IdlInstructionInvalidProgram"
|
||||
readonly msg =
|
||||
"The transaction was given an invalid program for the IDL instruction"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"1001: The transaction was given an invalid program for the IDL instruction"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMut extends Error {
|
||||
readonly code = 2000
|
||||
readonly name = "ConstraintMut"
|
||||
readonly msg = "A mut constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2000: A mut constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintHasOne extends Error {
|
||||
readonly code = 2001
|
||||
readonly name = "ConstraintHasOne"
|
||||
readonly msg = "A has_one constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2001: A has_one constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSigner extends Error {
|
||||
readonly code = 2002
|
||||
readonly name = "ConstraintSigner"
|
||||
readonly msg = "A signer constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2002: A signer constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRaw extends Error {
|
||||
readonly code = 2003
|
||||
readonly name = "ConstraintRaw"
|
||||
readonly msg = "A raw constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2003: A raw constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintOwner extends Error {
|
||||
readonly code = 2004
|
||||
readonly name = "ConstraintOwner"
|
||||
readonly msg = "An owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2004: An owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRentExempt extends Error {
|
||||
readonly code = 2005
|
||||
readonly name = "ConstraintRentExempt"
|
||||
readonly msg = "A rent exemption constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2005: A rent exemption constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSeeds extends Error {
|
||||
readonly code = 2006
|
||||
readonly name = "ConstraintSeeds"
|
||||
readonly msg = "A seeds constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2006: A seeds constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintExecutable extends Error {
|
||||
readonly code = 2007
|
||||
readonly name = "ConstraintExecutable"
|
||||
readonly msg = "An executable constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2007: An executable constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintState extends Error {
|
||||
readonly code = 2008
|
||||
readonly name = "ConstraintState"
|
||||
readonly msg = "A state constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2008: A state constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociated extends Error {
|
||||
readonly code = 2009
|
||||
readonly name = "ConstraintAssociated"
|
||||
readonly msg = "An associated constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2009: An associated constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociatedInit extends Error {
|
||||
readonly code = 2010
|
||||
readonly name = "ConstraintAssociatedInit"
|
||||
readonly msg = "An associated init constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2010: An associated init constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintClose extends Error {
|
||||
readonly code = 2011
|
||||
readonly name = "ConstraintClose"
|
||||
readonly msg = "A close constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2011: A close constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAddress extends Error {
|
||||
readonly code = 2012
|
||||
readonly name = "ConstraintAddress"
|
||||
readonly msg = "An address constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2012: An address constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintZero extends Error {
|
||||
readonly code = 2013
|
||||
readonly name = "ConstraintZero"
|
||||
readonly msg = "Expected zero account discriminant"
|
||||
|
||||
constructor() {
|
||||
super("2013: Expected zero account discriminant")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenMint extends Error {
|
||||
readonly code = 2014
|
||||
readonly name = "ConstraintTokenMint"
|
||||
readonly msg = "A token mint constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2014: A token mint constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenOwner extends Error {
|
||||
readonly code = 2015
|
||||
readonly name = "ConstraintTokenOwner"
|
||||
readonly msg = "A token owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2015: A token owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintMintAuthority extends Error {
|
||||
readonly code = 2016
|
||||
readonly name = "ConstraintMintMintAuthority"
|
||||
readonly msg = "A mint mint authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2016: A mint mint authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintFreezeAuthority extends Error {
|
||||
readonly code = 2017
|
||||
readonly name = "ConstraintMintFreezeAuthority"
|
||||
readonly msg = "A mint freeze authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2017: A mint freeze authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintDecimals extends Error {
|
||||
readonly code = 2018
|
||||
readonly name = "ConstraintMintDecimals"
|
||||
readonly msg = "A mint decimals constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2018: A mint decimals constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSpace extends Error {
|
||||
readonly code = 2019
|
||||
readonly name = "ConstraintSpace"
|
||||
readonly msg = "A space constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2019: A space constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireViolated extends Error {
|
||||
readonly code = 2500
|
||||
readonly name = "RequireViolated"
|
||||
readonly msg = "A require expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2500: A require expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireEqViolated extends Error {
|
||||
readonly code = 2501
|
||||
readonly name = "RequireEqViolated"
|
||||
readonly msg = "A require_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2501: A require_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysEqViolated extends Error {
|
||||
readonly code = 2502
|
||||
readonly name = "RequireKeysEqViolated"
|
||||
readonly msg = "A require_keys_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2502: A require_keys_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireNeqViolated extends Error {
|
||||
readonly code = 2503
|
||||
readonly name = "RequireNeqViolated"
|
||||
readonly msg = "A require_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2503: A require_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysNeqViolated extends Error {
|
||||
readonly code = 2504
|
||||
readonly name = "RequireKeysNeqViolated"
|
||||
readonly msg = "A require_keys_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2504: A require_keys_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGtViolated extends Error {
|
||||
readonly code = 2505
|
||||
readonly name = "RequireGtViolated"
|
||||
readonly msg = "A require_gt expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2505: A require_gt expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGteViolated extends Error {
|
||||
readonly code = 2506
|
||||
readonly name = "RequireGteViolated"
|
||||
readonly msg = "A require_gte expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2506: A require_gte expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorAlreadySet extends Error {
|
||||
readonly code = 3000
|
||||
readonly name = "AccountDiscriminatorAlreadySet"
|
||||
readonly msg = "The account discriminator was already set on this account"
|
||||
|
||||
constructor() {
|
||||
super("3000: The account discriminator was already set on this account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorNotFound extends Error {
|
||||
readonly code = 3001
|
||||
readonly name = "AccountDiscriminatorNotFound"
|
||||
readonly msg = "No 8 byte discriminator was found on the account"
|
||||
|
||||
constructor() {
|
||||
super("3001: No 8 byte discriminator was found on the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorMismatch extends Error {
|
||||
readonly code = 3002
|
||||
readonly name = "AccountDiscriminatorMismatch"
|
||||
readonly msg = "8 byte discriminator did not match what was expected"
|
||||
|
||||
constructor() {
|
||||
super("3002: 8 byte discriminator did not match what was expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotDeserialize extends Error {
|
||||
readonly code = 3003
|
||||
readonly name = "AccountDidNotDeserialize"
|
||||
readonly msg = "Failed to deserialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3003: Failed to deserialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotSerialize extends Error {
|
||||
readonly code = 3004
|
||||
readonly name = "AccountDidNotSerialize"
|
||||
readonly msg = "Failed to serialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3004: Failed to serialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotEnoughKeys extends Error {
|
||||
readonly code = 3005
|
||||
readonly name = "AccountNotEnoughKeys"
|
||||
readonly msg = "Not enough account keys given to the instruction"
|
||||
|
||||
constructor() {
|
||||
super("3005: Not enough account keys given to the instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotMutable extends Error {
|
||||
readonly code = 3006
|
||||
readonly name = "AccountNotMutable"
|
||||
readonly msg = "The given account is not mutable"
|
||||
|
||||
constructor() {
|
||||
super("3006: The given account is not mutable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountOwnedByWrongProgram extends Error {
|
||||
readonly code = 3007
|
||||
readonly name = "AccountOwnedByWrongProgram"
|
||||
readonly msg =
|
||||
"The given account is owned by a different program than expected"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"3007: The given account is owned by a different program than expected"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramId extends Error {
|
||||
readonly code = 3008
|
||||
readonly name = "InvalidProgramId"
|
||||
readonly msg = "Program ID was not as expected"
|
||||
|
||||
constructor() {
|
||||
super("3008: Program ID was not as expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramExecutable extends Error {
|
||||
readonly code = 3009
|
||||
readonly name = "InvalidProgramExecutable"
|
||||
readonly msg = "Program account is not executable"
|
||||
|
||||
constructor() {
|
||||
super("3009: Program account is not executable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSigner extends Error {
|
||||
readonly code = 3010
|
||||
readonly name = "AccountNotSigner"
|
||||
readonly msg = "The given account did not sign"
|
||||
|
||||
constructor() {
|
||||
super("3010: The given account did not sign")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSystemOwned extends Error {
|
||||
readonly code = 3011
|
||||
readonly name = "AccountNotSystemOwned"
|
||||
readonly msg = "The given account is not owned by the system program"
|
||||
|
||||
constructor() {
|
||||
super("3011: The given account is not owned by the system program")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotInitialized extends Error {
|
||||
readonly code = 3012
|
||||
readonly name = "AccountNotInitialized"
|
||||
readonly msg = "The program expected this account to be already initialized"
|
||||
|
||||
constructor() {
|
||||
super("3012: The program expected this account to be already initialized")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotProgramData extends Error {
|
||||
readonly code = 3013
|
||||
readonly name = "AccountNotProgramData"
|
||||
readonly msg = "The given account is not a program data account"
|
||||
|
||||
constructor() {
|
||||
super("3013: The given account is not a program data account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotAssociatedTokenAccount extends Error {
|
||||
readonly code = 3014
|
||||
readonly name = "AccountNotAssociatedTokenAccount"
|
||||
readonly msg = "The given account is not the associated token account"
|
||||
|
||||
constructor() {
|
||||
super("3014: The given account is not the associated token account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountSysvarMismatch extends Error {
|
||||
readonly code = 3015
|
||||
readonly name = "AccountSysvarMismatch"
|
||||
readonly msg = "The given public key does not match the required sysvar"
|
||||
|
||||
constructor() {
|
||||
super("3015: The given public key does not match the required sysvar")
|
||||
}
|
||||
}
|
||||
|
||||
export class StateInvalidAddress extends Error {
|
||||
readonly code = 4000
|
||||
readonly name = "StateInvalidAddress"
|
||||
readonly msg = "The given state account does not have the correct address"
|
||||
|
||||
constructor() {
|
||||
super("4000: The given state account does not have the correct address")
|
||||
}
|
||||
}
|
||||
|
||||
export class DeclaredProgramIdMismatch extends Error {
|
||||
readonly code = 4100
|
||||
readonly name = "DeclaredProgramIdMismatch"
|
||||
readonly msg = "The declared program id does not match the actual program id"
|
||||
|
||||
constructor() {
|
||||
super("4100: The declared program id does not match the actual program id")
|
||||
}
|
||||
}
|
||||
|
||||
export class Deprecated extends Error {
|
||||
readonly code = 5000
|
||||
readonly name = "Deprecated"
|
||||
readonly msg = "The API being used is deprecated and should no longer be used"
|
||||
|
||||
constructor() {
|
||||
super("5000: The API being used is deprecated and should no longer be used")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): AnchorError | null {
|
||||
switch (code) {
|
||||
case 100:
|
||||
return new InstructionMissing()
|
||||
case 101:
|
||||
return new InstructionFallbackNotFound()
|
||||
case 102:
|
||||
return new InstructionDidNotDeserialize()
|
||||
case 103:
|
||||
return new InstructionDidNotSerialize()
|
||||
case 1000:
|
||||
return new IdlInstructionStub()
|
||||
case 1001:
|
||||
return new IdlInstructionInvalidProgram()
|
||||
case 2000:
|
||||
return new ConstraintMut()
|
||||
case 2001:
|
||||
return new ConstraintHasOne()
|
||||
case 2002:
|
||||
return new ConstraintSigner()
|
||||
case 2003:
|
||||
return new ConstraintRaw()
|
||||
case 2004:
|
||||
return new ConstraintOwner()
|
||||
case 2005:
|
||||
return new ConstraintRentExempt()
|
||||
case 2006:
|
||||
return new ConstraintSeeds()
|
||||
case 2007:
|
||||
return new ConstraintExecutable()
|
||||
case 2008:
|
||||
return new ConstraintState()
|
||||
case 2009:
|
||||
return new ConstraintAssociated()
|
||||
case 2010:
|
||||
return new ConstraintAssociatedInit()
|
||||
case 2011:
|
||||
return new ConstraintClose()
|
||||
case 2012:
|
||||
return new ConstraintAddress()
|
||||
case 2013:
|
||||
return new ConstraintZero()
|
||||
case 2014:
|
||||
return new ConstraintTokenMint()
|
||||
case 2015:
|
||||
return new ConstraintTokenOwner()
|
||||
case 2016:
|
||||
return new ConstraintMintMintAuthority()
|
||||
case 2017:
|
||||
return new ConstraintMintFreezeAuthority()
|
||||
case 2018:
|
||||
return new ConstraintMintDecimals()
|
||||
case 2019:
|
||||
return new ConstraintSpace()
|
||||
case 2500:
|
||||
return new RequireViolated()
|
||||
case 2501:
|
||||
return new RequireEqViolated()
|
||||
case 2502:
|
||||
return new RequireKeysEqViolated()
|
||||
case 2503:
|
||||
return new RequireNeqViolated()
|
||||
case 2504:
|
||||
return new RequireKeysNeqViolated()
|
||||
case 2505:
|
||||
return new RequireGtViolated()
|
||||
case 2506:
|
||||
return new RequireGteViolated()
|
||||
case 3000:
|
||||
return new AccountDiscriminatorAlreadySet()
|
||||
case 3001:
|
||||
return new AccountDiscriminatorNotFound()
|
||||
case 3002:
|
||||
return new AccountDiscriminatorMismatch()
|
||||
case 3003:
|
||||
return new AccountDidNotDeserialize()
|
||||
case 3004:
|
||||
return new AccountDidNotSerialize()
|
||||
case 3005:
|
||||
return new AccountNotEnoughKeys()
|
||||
case 3006:
|
||||
return new AccountNotMutable()
|
||||
case 3007:
|
||||
return new AccountOwnedByWrongProgram()
|
||||
case 3008:
|
||||
return new InvalidProgramId()
|
||||
case 3009:
|
||||
return new InvalidProgramExecutable()
|
||||
case 3010:
|
||||
return new AccountNotSigner()
|
||||
case 3011:
|
||||
return new AccountNotSystemOwned()
|
||||
case 3012:
|
||||
return new AccountNotInitialized()
|
||||
case 3013:
|
||||
return new AccountNotProgramData()
|
||||
case 3014:
|
||||
return new AccountNotAssociatedTokenAccount()
|
||||
case 3015:
|
||||
return new AccountSysvarMismatch()
|
||||
case 4000:
|
||||
return new StateInvalidAddress()
|
||||
case 4100:
|
||||
return new DeclaredProgramIdMismatch()
|
||||
case 5000:
|
||||
return new Deprecated()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
export type CustomError =
|
||||
| InvalidSwitchboardAccount
|
||||
| StaleFeed
|
||||
| ConfidenceIntervalExceeded
|
||||
|
||||
export class InvalidSwitchboardAccount extends Error {
|
||||
readonly code = 6000
|
||||
readonly name = "InvalidSwitchboardAccount"
|
||||
readonly msg = "Not a valid Switchboard account"
|
||||
|
||||
constructor() {
|
||||
super("6000: Not a valid Switchboard account")
|
||||
}
|
||||
}
|
||||
|
||||
export class StaleFeed extends Error {
|
||||
readonly code = 6001
|
||||
readonly name = "StaleFeed"
|
||||
readonly msg = "Switchboard feed has not been updated in 5 minutes"
|
||||
|
||||
constructor() {
|
||||
super("6001: Switchboard feed has not been updated in 5 minutes")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConfidenceIntervalExceeded extends Error {
|
||||
readonly code = 6002
|
||||
readonly name = "ConfidenceIntervalExceeded"
|
||||
readonly msg = "Switchboard feed exceeded provided confidence interval"
|
||||
|
||||
constructor() {
|
||||
super("6002: Switchboard feed exceeded provided confidence interval")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): CustomError | null {
|
||||
switch (code) {
|
||||
case 6000:
|
||||
return new InvalidSwitchboardAccount()
|
||||
case 6001:
|
||||
return new StaleFeed()
|
||||
case 6002:
|
||||
return new ConfidenceIntervalExceeded()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { PROGRAM_ID } from "../programId"
|
||||
import * as anchor from "./anchor"
|
||||
import * as custom from "./custom"
|
||||
|
||||
export function fromCode(
|
||||
code: number
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
return code >= 6000 ? custom.fromCode(code) : anchor.fromCode(code)
|
||||
}
|
||||
|
||||
function hasOwnProperty<X extends object, Y extends PropertyKey>(
|
||||
obj: X,
|
||||
prop: Y
|
||||
): obj is X & Record<Y, unknown> {
|
||||
return Object.hasOwnProperty.call(obj, prop)
|
||||
}
|
||||
|
||||
const errorRe = /Program (\w+) failed: custom program error: (\w+)/
|
||||
|
||||
export function fromTxError(
|
||||
err: unknown
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
if (
|
||||
typeof err !== "object" ||
|
||||
err === null ||
|
||||
!hasOwnProperty(err, "logs") ||
|
||||
!Array.isArray(err.logs)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
let firstMatch: RegExpExecArray | null = null
|
||||
for (const logLine of err.logs) {
|
||||
firstMatch = errorRe.exec(logLine)
|
||||
if (firstMatch !== null) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMatch === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [programIdRaw, codeRaw] = firstMatch.slice(1)
|
||||
if (programIdRaw !== PROGRAM_ID.toString()) {
|
||||
return null
|
||||
}
|
||||
|
||||
let errorCode: number
|
||||
try {
|
||||
errorCode = parseInt(codeRaw, 16)
|
||||
} catch (parseErr) {
|
||||
return null
|
||||
}
|
||||
|
||||
return fromCode(errorCode)
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
import { Connection, Keypair, PublicKey, Transaction } from "@solana/web3.js";
|
||||
import fs from "fs";
|
||||
import { readResult } from "./instructions/readResult";
|
||||
|
||||
async function main() {
|
||||
const payer = Keypair.fromSecretKey(
|
||||
new Uint8Array(JSON.parse(fs.readFileSync(process.argv[2], "utf8")))
|
||||
);
|
||||
const connection = new Connection(
|
||||
"https://devnet.genesysgo.net",
|
||||
"confirmed"
|
||||
);
|
||||
const ix = readResult(
|
||||
{ params: { maxConfidenceInterval: null } },
|
||||
{
|
||||
aggregator: new PublicKey("8SXvChNYFhRq4EZuZvnhjrB3jJRQCv4k3P4W6hesH3Ee"),
|
||||
}
|
||||
);
|
||||
const tx = new Transaction();
|
||||
tx.add(ix);
|
||||
tx.feePayer = payer.publicKey;
|
||||
const sig = await connection.sendTransaction(tx, [payer]);
|
||||
console.log(`https://explorer.solana.com/tx/${sig}?cluster=devnet`);
|
||||
}
|
||||
|
||||
(async () => main())();
|
|
@ -1 +0,0 @@
|
|||
export { readResult, ReadResultAccounts, ReadResultArgs } from "./readResult"
|
|
@ -1,31 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId"
|
||||
import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface ReadResultArgs {
|
||||
params: types.ReadResultParamsFields
|
||||
}
|
||||
|
||||
export interface ReadResultAccounts {
|
||||
aggregator: PublicKey
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.ReadResultParams.layout("params")])
|
||||
|
||||
export function readResult(args: ReadResultArgs, accounts: ReadResultAccounts) {
|
||||
const keys = [
|
||||
{ pubkey: accounts.aggregator, isSigner: false, isWritable: false },
|
||||
]
|
||||
const identifier = Buffer.from([130, 229, 115, 203, 180, 191, 240, 90])
|
||||
const buffer = Buffer.alloc(1000)
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.ReadResultParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
)
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
|
||||
const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data })
|
||||
return ix
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
import { PublicKey } from "@solana/web3.js"
|
||||
|
||||
// Program ID defined in the provided IDL. Do not edit, it will get overwritten.
|
||||
export const PROGRAM_ID_IDL = new PublicKey(
|
||||
"FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
|
||||
)
|
||||
|
||||
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
|
||||
export const PROGRAM_ID_CLI = new PublicKey(
|
||||
"FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
|
||||
)
|
||||
|
||||
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
|
||||
export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI
|
|
@ -1,53 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"
|
||||
|
||||
export interface ReadResultParamsFields {
|
||||
maxConfidenceInterval: number | null
|
||||
}
|
||||
|
||||
export interface ReadResultParamsJSON {
|
||||
maxConfidenceInterval: number | null
|
||||
}
|
||||
|
||||
export class ReadResultParams {
|
||||
readonly maxConfidenceInterval: number | null
|
||||
|
||||
constructor(fields: ReadResultParamsFields) {
|
||||
this.maxConfidenceInterval = fields.maxConfidenceInterval
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[borsh.option(borsh.f64(), "maxConfidenceInterval")],
|
||||
property
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new ReadResultParams({
|
||||
maxConfidenceInterval: obj.maxConfidenceInterval,
|
||||
})
|
||||
}
|
||||
|
||||
static toEncodable(fields: ReadResultParamsFields) {
|
||||
return {
|
||||
maxConfidenceInterval: fields.maxConfidenceInterval,
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): ReadResultParamsJSON {
|
||||
return {
|
||||
maxConfidenceInterval: this.maxConfidenceInterval,
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(obj: ReadResultParamsJSON): ReadResultParams {
|
||||
return new ReadResultParams({
|
||||
maxConfidenceInterval: obj.maxConfidenceInterval,
|
||||
})
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return ReadResultParams.toEncodable(this)
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
export {
|
||||
ReadResultParams,
|
||||
ReadResultParamsFields,
|
||||
ReadResultParamsJSON,
|
||||
} from "./ReadResultParams"
|
File diff suppressed because it is too large
Load Diff
|
@ -12,10 +12,10 @@
|
|||
"lint": "eslint --ext .js,.json,.ts 'src/**' --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@solana/web3.js": "^1.50.1",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.43",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.135",
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/web3.js": "^1.66.2",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"fs": "^0.0.1-security"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use anchor_lang::solana_program::clock;
|
||||
// use anchor_lang::{Discriminator, Owner, ZeroCopy};
|
||||
// use bytemuck::{Pod, Zeroable};
|
||||
use std::convert::TryInto;
|
||||
pub use switchboard_v2::{AggregatorAccountData, SwitchboardDecimal, SWITCHBOARD_PROGRAM_ID};
|
||||
|
||||
declare_id!("FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh");
|
||||
declare_id!("5cjAZXFoY4KN1Sq35ZYE72fGdVy8sy5YGpNix1N4rtHY");
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(params: ReadResultParams)]
|
||||
pub struct ReadResult<'info> {
|
||||
#[account(
|
||||
constraint =
|
||||
*aggregator.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ FeedErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub aggregator: AccountLoader<'info, AggregatorAccountData>,
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@ import { PublicKey } from "@solana/web3.js";
|
|||
import { sleep, SwitchboardTestContext } from "@switchboard-xyz/sbv2-utils";
|
||||
import type { AnchorWallet } from "@switchboard-xyz/switchboard-v2";
|
||||
import chai from "chai";
|
||||
import { AnchorFeedParser, IDL } from "../target/types/anchor_feed_parser";
|
||||
import { PROGRAM_ID } from "../client/programId";
|
||||
import { AnchorFeedParser, IDL } from "../target/types/anchor_feed_parser";
|
||||
const expect = chai.expect;
|
||||
|
||||
// Anchor.toml will copy this to localnet when we start our tests
|
||||
|
@ -31,6 +31,8 @@ describe("anchor-feed-parser test", () => {
|
|||
let switchboard: SwitchboardTestContext;
|
||||
let aggregatorKey: PublicKey;
|
||||
|
||||
console.log(`rpc: ${feedParserProgram.provider.connection.rpcEndpoint}`);
|
||||
|
||||
before(async () => {
|
||||
try {
|
||||
switchboard = await SwitchboardTestContext.loadDevnetQueue(
|
||||
|
@ -49,7 +51,7 @@ describe("anchor-feed-parser test", () => {
|
|||
|
||||
it("Read SOL/USD Feed", async () => {
|
||||
const signature = await feedParserProgram.methods
|
||||
.readResult({ maxConfidenceInterval: 0.25 })
|
||||
.readResult({ maxConfidenceInterval: null })
|
||||
.accounts({ aggregator: aggregatorKey })
|
||||
.rpc();
|
||||
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
import * as anchor from "@project-serum/anchor";
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { Connection } from "@solana/web3.js";
|
||||
import { sleep, SwitchboardTestContext } from "@switchboard-xyz/sbv2-utils";
|
||||
import type {
|
||||
AggregatorAccount,
|
||||
AnchorWallet,
|
||||
} from "@switchboard-xyz/switchboard-v2";
|
||||
import chai from "chai";
|
||||
import { AnchorFeedParser, IDL } from "../target/types/anchor_feed_parser";
|
||||
import { PROGRAM_ID } from "../client/programId";
|
||||
import { AnchorFeedParser, IDL } from "../target/types/anchor_feed_parser";
|
||||
const expect = chai.expect;
|
||||
|
||||
// Anchor.toml will copy this to localnet when we start our tests
|
||||
const DEFAULT_SOL_USD_FEED = new PublicKey(
|
||||
"GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR"
|
||||
);
|
||||
|
||||
describe("anchor-feed-parser test", () => {
|
||||
const tomlProvider = anchor.AnchorProvider.env();
|
||||
const provider = new anchor.AnchorProvider(
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"]
|
||||
}
|
||||
},
|
||||
"include": ["tests/**/*", "client/**/*", "./target/types/anchor_feed_parser"],
|
||||
"references": [
|
||||
{ "path": "../../javascript/solana.js" },
|
||||
{ "path": "../../javascript/switchboard-v2" },
|
||||
{ "path": "../../javascript/sbv2-utils" }
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -5,3 +5,4 @@ target
|
|||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
client/
|
|
@ -20,6 +20,6 @@ overflow-checks = true
|
|||
|
||||
[dependencies]
|
||||
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.14", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.16", features = ["devnet"] }
|
||||
anchor-lang = "0.25.0"
|
||||
solana-program = "~1.10.29"
|
File diff suppressed because it is too large
Load Diff
|
@ -1,22 +1,22 @@
|
|||
{
|
||||
"scripts": {
|
||||
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@switchboard-xyz/common": "^2.0.3",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.49",
|
||||
"@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"
|
||||
}
|
||||
"scripts": {
|
||||
"lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w",
|
||||
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@switchboard-xyz/common": "^2.1.7",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165"
|
||||
},
|
||||
"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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use anchor_lang::prelude::*;
|
||||
use std::convert::TryInto;
|
||||
pub use switchboard_v2::{
|
||||
AggregatorAccountData, AggregatorHistoryBuffer, SwitchboardDecimal, SWITCHBOARD_PROGRAM_ID,
|
||||
};
|
||||
use std::convert::TryInto;
|
||||
|
||||
declare_id!("C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS");
|
||||
|
||||
|
@ -10,16 +10,10 @@ declare_id!("C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS");
|
|||
#[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
|
||||
has_one = history_buffer @ ErrorCode::InvalidHistoryBuffer
|
||||
)]
|
||||
pub aggregator: AccountLoader<'info, AggregatorAccountData>,
|
||||
/// CHECK: Verified by aggregator.history_buffer
|
||||
#[account(
|
||||
constraint =
|
||||
*aggregator.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ ErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
/// CHECK: verified in the aggregator has_one check
|
||||
pub history_buffer: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
|
@ -36,17 +30,6 @@ pub mod anchor_history_parser {
|
|||
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;
|
||||
|
@ -57,8 +40,13 @@ pub mod anchor_history_parser {
|
|||
timestamp = Clock::get()?.unix_timestamp - 3600;
|
||||
}
|
||||
|
||||
let value_at_timestamp: f64 = history_buffer.lower_bound(timestamp).unwrap().value.try_into()?;
|
||||
let value_at_timestamp: f64 = history_buffer
|
||||
.lower_bound(timestamp)
|
||||
.unwrap()
|
||||
.value
|
||||
.try_into()?;
|
||||
msg!("Result {:?}!", value_at_timestamp);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
"target": "es6",
|
||||
"esModuleInterop": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"]
|
||||
}
|
||||
},
|
||||
|
@ -18,7 +18,7 @@
|
|||
"./target/types/anchor_history_parser"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../../javascript/solana.js" },
|
||||
{ "path": "../../javascript/switchboard-v2" },
|
||||
{ "path": "../../javascript/sbv2-utils" }
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,8 @@
|
|||
|
||||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
client/
|
|
@ -4,13 +4,12 @@ members = [
|
|||
]
|
||||
|
||||
[provider]
|
||||
# cluster = "devnet"
|
||||
cluster = "localnet"
|
||||
wallet = "../../../payer-keypair.json"
|
||||
# wallet = "~/.config/solana/id.json"
|
||||
cluster = "devnet"
|
||||
# cluster = "localnet"
|
||||
wallet = "~/.config/solana/id.json"
|
||||
|
||||
[programs.localnet]
|
||||
anchor_buffer_parser = "HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
|
||||
anchor_vrf_parser = "HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
|
||||
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
|
@ -18,7 +17,6 @@ url = "https://anchor.projectserum.com"
|
|||
[scripts]
|
||||
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 ./tests/*.test.ts"
|
||||
|
||||
|
||||
[test.validator]
|
||||
url="https://api.devnet.solana.com"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ default = []
|
|||
|
||||
[dependencies]
|
||||
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.14", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.16", features = ["devnet"] }
|
||||
anchor-lang = "^0.25.0"
|
||||
anchor-spl = "^0.25.0"
|
||||
solana-program = "~1.10.29"
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
import * as anchor from "@project-serum/anchor";
|
||||
import * as spl from "@solana/spl-token-v2";
|
||||
import type {
|
||||
import {
|
||||
clusterApiUrl,
|
||||
Connection,
|
||||
ParsedTransactionWithMeta,
|
||||
PublicKey,
|
||||
|
@ -19,12 +20,12 @@ const { hideBin } = require("yargs/helpers");
|
|||
// import { hideBin } from "yargs/helpers";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { AnchorVrfParser, IDL } from "../../../target/types/anchor_vrf_parser";
|
||||
import { AnchorVrfParser, IDL } from "./target/types/anchor_vrf_parser";
|
||||
import { VrfClient } from "./client/accounts";
|
||||
import { PROGRAM_ID } from "./client/programId";
|
||||
|
||||
const DEFAULT_MAINNET_RPC = "https://ssc-dao.genesysgo.net";
|
||||
const DEFAULT_DEVNET_RPC = "https://devnet.genesysgo.net";
|
||||
// const DEFAULT_MAINNET_RPC = "https://ssc-dao.genesysgo.net";
|
||||
// const DEFAULT_DEVNET_RPC = "https://devnet.genesysgo.net";
|
||||
const DEFAULT_LOCALNET_RPC = "http://localhost:8899";
|
||||
|
||||
const DEFAULT_COMMITMENT = "confirmed";
|
||||
|
@ -178,10 +179,11 @@ yargs(hideBin(process.argv))
|
|||
}
|
||||
|
||||
const { vrfClientProgram, switchboardProgram, payer, provider } =
|
||||
await loadCli(rpcUrl as string, cluster as string);
|
||||
await loadCli((rpcUrl as string) ?? "", (cluster as string) ?? "");
|
||||
|
||||
const vrfClient = await VrfClient.fetch(
|
||||
provider.connection,
|
||||
vrfClientProgram.programId,
|
||||
new anchor.web3.PublicKey(vrfClientKey)
|
||||
);
|
||||
if (!vrfClient) {
|
||||
|
@ -353,6 +355,7 @@ yargs(hideBin(process.argv))
|
|||
|
||||
const vrfClient = await VrfClient.fetch(
|
||||
provider.connection,
|
||||
vrfClientProgram.programId,
|
||||
vrfClientPubkey
|
||||
);
|
||||
if (!vrfClient) {
|
||||
|
@ -440,8 +443,7 @@ yargs(hideBin(process.argv))
|
|||
let successes = 0;
|
||||
let failures = 0;
|
||||
try {
|
||||
for await (const i of [...Array(numLoops).keys()]) {
|
||||
writeStatus(i, numLoops, successes, failures);
|
||||
for await (const i of Array.from(Array(numLoops).keys())) {
|
||||
let success = false;
|
||||
try {
|
||||
while (true) {
|
||||
|
@ -460,10 +462,13 @@ yargs(hideBin(process.argv))
|
|||
}
|
||||
}
|
||||
|
||||
await awaitCallback(provider.connection, vrfClientPubkey, 45_000)
|
||||
await awaitCallback(provider.connection, vrfClientPubkey, 90_000)
|
||||
.then(() => {
|
||||
success = true;
|
||||
successes++;
|
||||
|
||||
clearStatus();
|
||||
writeStatus(i, numLoops, successes, failures);
|
||||
})
|
||||
.catch(async (error) => {
|
||||
failures++;
|
||||
|
@ -506,11 +511,11 @@ yargs(hideBin(process.argv))
|
|||
15
|
||||
),
|
||||
};
|
||||
|
||||
results.push(result);
|
||||
|
||||
saveResults(startTime, vrfClientKey, results);
|
||||
|
||||
clearStatus();
|
||||
writeStatus(i, numLoops, successes, failures);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`GLOBAL: ${error}`);
|
||||
|
@ -543,9 +548,9 @@ yargs(hideBin(process.argv))
|
|||
function getRpcUrl(cluster: string): string {
|
||||
switch (cluster) {
|
||||
case "mainnet-beta":
|
||||
return DEFAULT_MAINNET_RPC;
|
||||
return clusterApiUrl("mainnet-beta");
|
||||
case "devnet":
|
||||
return DEFAULT_DEVNET_RPC;
|
||||
return clusterApiUrl("devnet");
|
||||
case "localnet":
|
||||
return DEFAULT_LOCALNET_RPC;
|
||||
default:
|
||||
|
|
|
@ -1,135 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import BN from "bn.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId";
|
||||
|
||||
export interface VrfClientFields {
|
||||
bump: number;
|
||||
maxResult: BN;
|
||||
resultBuffer: Array<number>;
|
||||
result: BN;
|
||||
lastTimestamp: BN;
|
||||
authority: PublicKey;
|
||||
vrf: PublicKey;
|
||||
}
|
||||
|
||||
export interface VrfClientJSON {
|
||||
bump: number;
|
||||
maxResult: string;
|
||||
resultBuffer: Array<number>;
|
||||
result: string;
|
||||
lastTimestamp: string;
|
||||
authority: string;
|
||||
vrf: string;
|
||||
}
|
||||
|
||||
export class VrfClient {
|
||||
readonly bump: number;
|
||||
readonly maxResult: BN;
|
||||
readonly resultBuffer: Array<number>;
|
||||
readonly result: BN;
|
||||
readonly lastTimestamp: BN;
|
||||
readonly authority: PublicKey;
|
||||
readonly vrf: PublicKey;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
230, 174, 157, 153, 51, 18, 230, 163,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.u8("bump"),
|
||||
borsh.u64("maxResult"),
|
||||
borsh.array(borsh.u8(), 32, "resultBuffer"),
|
||||
borsh.u128("result"),
|
||||
borsh.i64("lastTimestamp"),
|
||||
borsh.publicKey("authority"),
|
||||
borsh.publicKey("vrf"),
|
||||
]);
|
||||
|
||||
constructor(fields: VrfClientFields) {
|
||||
this.bump = fields.bump;
|
||||
this.maxResult = fields.maxResult;
|
||||
this.resultBuffer = fields.resultBuffer;
|
||||
this.result = fields.result;
|
||||
this.lastTimestamp = fields.lastTimestamp;
|
||||
this.authority = fields.authority;
|
||||
this.vrf = fields.vrf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
c: Connection,
|
||||
programId: PublicKey,
|
||||
address: PublicKey
|
||||
): Promise<VrfClient | null> {
|
||||
const info = await c.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
c: Connection,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<VrfClient | null>> {
|
||||
const infos = await c.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(PROGRAM_ID)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): VrfClient {
|
||||
if (!data.slice(0, 8).equals(VrfClient.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = VrfClient.layout.decode(data.slice(8));
|
||||
|
||||
return new VrfClient({
|
||||
bump: dec.bump,
|
||||
maxResult: dec.maxResult,
|
||||
resultBuffer: dec.resultBuffer,
|
||||
result: dec.result,
|
||||
lastTimestamp: dec.lastTimestamp,
|
||||
authority: dec.authority,
|
||||
vrf: dec.vrf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): VrfClientJSON {
|
||||
return {
|
||||
bump: this.bump,
|
||||
maxResult: this.maxResult.toString(),
|
||||
resultBuffer: this.resultBuffer,
|
||||
result: this.result.toString(),
|
||||
lastTimestamp: this.lastTimestamp.toString(),
|
||||
authority: this.authority.toString(),
|
||||
vrf: this.vrf.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: VrfClientJSON): VrfClient {
|
||||
return new VrfClient({
|
||||
bump: obj.bump,
|
||||
maxResult: new BN(obj.maxResult),
|
||||
resultBuffer: obj.resultBuffer,
|
||||
result: new BN(obj.result),
|
||||
lastTimestamp: new BN(obj.lastTimestamp),
|
||||
authority: new PublicKey(obj.authority),
|
||||
vrf: new PublicKey(obj.vrf),
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
export { VrfClient, VrfClientFields, VrfClientJSON } from "./VrfClient"
|
|
@ -1,690 +0,0 @@
|
|||
export type AnchorError =
|
||||
| InstructionMissing
|
||||
| InstructionFallbackNotFound
|
||||
| InstructionDidNotDeserialize
|
||||
| InstructionDidNotSerialize
|
||||
| IdlInstructionStub
|
||||
| IdlInstructionInvalidProgram
|
||||
| ConstraintMut
|
||||
| ConstraintHasOne
|
||||
| ConstraintSigner
|
||||
| ConstraintRaw
|
||||
| ConstraintOwner
|
||||
| ConstraintRentExempt
|
||||
| ConstraintSeeds
|
||||
| ConstraintExecutable
|
||||
| ConstraintState
|
||||
| ConstraintAssociated
|
||||
| ConstraintAssociatedInit
|
||||
| ConstraintClose
|
||||
| ConstraintAddress
|
||||
| ConstraintZero
|
||||
| ConstraintTokenMint
|
||||
| ConstraintTokenOwner
|
||||
| ConstraintMintMintAuthority
|
||||
| ConstraintMintFreezeAuthority
|
||||
| ConstraintMintDecimals
|
||||
| ConstraintSpace
|
||||
| RequireViolated
|
||||
| RequireEqViolated
|
||||
| RequireKeysEqViolated
|
||||
| RequireNeqViolated
|
||||
| RequireKeysNeqViolated
|
||||
| RequireGtViolated
|
||||
| RequireGteViolated
|
||||
| AccountDiscriminatorAlreadySet
|
||||
| AccountDiscriminatorNotFound
|
||||
| AccountDiscriminatorMismatch
|
||||
| AccountDidNotDeserialize
|
||||
| AccountDidNotSerialize
|
||||
| AccountNotEnoughKeys
|
||||
| AccountNotMutable
|
||||
| AccountOwnedByWrongProgram
|
||||
| InvalidProgramId
|
||||
| InvalidProgramExecutable
|
||||
| AccountNotSigner
|
||||
| AccountNotSystemOwned
|
||||
| AccountNotInitialized
|
||||
| AccountNotProgramData
|
||||
| AccountNotAssociatedTokenAccount
|
||||
| AccountSysvarMismatch
|
||||
| StateInvalidAddress
|
||||
| DeclaredProgramIdMismatch
|
||||
| Deprecated
|
||||
|
||||
export class InstructionMissing extends Error {
|
||||
readonly code = 100
|
||||
readonly name = "InstructionMissing"
|
||||
readonly msg = "8 byte instruction identifier not provided"
|
||||
|
||||
constructor() {
|
||||
super("100: 8 byte instruction identifier not provided")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionFallbackNotFound extends Error {
|
||||
readonly code = 101
|
||||
readonly name = "InstructionFallbackNotFound"
|
||||
readonly msg = "Fallback functions are not supported"
|
||||
|
||||
constructor() {
|
||||
super("101: Fallback functions are not supported")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotDeserialize extends Error {
|
||||
readonly code = 102
|
||||
readonly name = "InstructionDidNotDeserialize"
|
||||
readonly msg = "The program could not deserialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("102: The program could not deserialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotSerialize extends Error {
|
||||
readonly code = 103
|
||||
readonly name = "InstructionDidNotSerialize"
|
||||
readonly msg = "The program could not serialize the given instruction"
|
||||
|
||||
constructor() {
|
||||
super("103: The program could not serialize the given instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionStub extends Error {
|
||||
readonly code = 1000
|
||||
readonly name = "IdlInstructionStub"
|
||||
readonly msg = "The program was compiled without idl instructions"
|
||||
|
||||
constructor() {
|
||||
super("1000: The program was compiled without idl instructions")
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionInvalidProgram extends Error {
|
||||
readonly code = 1001
|
||||
readonly name = "IdlInstructionInvalidProgram"
|
||||
readonly msg =
|
||||
"The transaction was given an invalid program for the IDL instruction"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"1001: The transaction was given an invalid program for the IDL instruction"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMut extends Error {
|
||||
readonly code = 2000
|
||||
readonly name = "ConstraintMut"
|
||||
readonly msg = "A mut constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2000: A mut constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintHasOne extends Error {
|
||||
readonly code = 2001
|
||||
readonly name = "ConstraintHasOne"
|
||||
readonly msg = "A has_one constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2001: A has_one constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSigner extends Error {
|
||||
readonly code = 2002
|
||||
readonly name = "ConstraintSigner"
|
||||
readonly msg = "A signer constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2002: A signer constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRaw extends Error {
|
||||
readonly code = 2003
|
||||
readonly name = "ConstraintRaw"
|
||||
readonly msg = "A raw constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2003: A raw constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintOwner extends Error {
|
||||
readonly code = 2004
|
||||
readonly name = "ConstraintOwner"
|
||||
readonly msg = "An owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2004: An owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRentExempt extends Error {
|
||||
readonly code = 2005
|
||||
readonly name = "ConstraintRentExempt"
|
||||
readonly msg = "A rent exemption constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2005: A rent exemption constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSeeds extends Error {
|
||||
readonly code = 2006
|
||||
readonly name = "ConstraintSeeds"
|
||||
readonly msg = "A seeds constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2006: A seeds constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintExecutable extends Error {
|
||||
readonly code = 2007
|
||||
readonly name = "ConstraintExecutable"
|
||||
readonly msg = "An executable constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2007: An executable constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintState extends Error {
|
||||
readonly code = 2008
|
||||
readonly name = "ConstraintState"
|
||||
readonly msg = "A state constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2008: A state constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociated extends Error {
|
||||
readonly code = 2009
|
||||
readonly name = "ConstraintAssociated"
|
||||
readonly msg = "An associated constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2009: An associated constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociatedInit extends Error {
|
||||
readonly code = 2010
|
||||
readonly name = "ConstraintAssociatedInit"
|
||||
readonly msg = "An associated init constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2010: An associated init constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintClose extends Error {
|
||||
readonly code = 2011
|
||||
readonly name = "ConstraintClose"
|
||||
readonly msg = "A close constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2011: A close constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAddress extends Error {
|
||||
readonly code = 2012
|
||||
readonly name = "ConstraintAddress"
|
||||
readonly msg = "An address constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2012: An address constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintZero extends Error {
|
||||
readonly code = 2013
|
||||
readonly name = "ConstraintZero"
|
||||
readonly msg = "Expected zero account discriminant"
|
||||
|
||||
constructor() {
|
||||
super("2013: Expected zero account discriminant")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenMint extends Error {
|
||||
readonly code = 2014
|
||||
readonly name = "ConstraintTokenMint"
|
||||
readonly msg = "A token mint constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2014: A token mint constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenOwner extends Error {
|
||||
readonly code = 2015
|
||||
readonly name = "ConstraintTokenOwner"
|
||||
readonly msg = "A token owner constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2015: A token owner constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintMintAuthority extends Error {
|
||||
readonly code = 2016
|
||||
readonly name = "ConstraintMintMintAuthority"
|
||||
readonly msg = "A mint mint authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2016: A mint mint authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintFreezeAuthority extends Error {
|
||||
readonly code = 2017
|
||||
readonly name = "ConstraintMintFreezeAuthority"
|
||||
readonly msg = "A mint freeze authority constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2017: A mint freeze authority constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintDecimals extends Error {
|
||||
readonly code = 2018
|
||||
readonly name = "ConstraintMintDecimals"
|
||||
readonly msg = "A mint decimals constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2018: A mint decimals constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSpace extends Error {
|
||||
readonly code = 2019
|
||||
readonly name = "ConstraintSpace"
|
||||
readonly msg = "A space constraint was violated"
|
||||
|
||||
constructor() {
|
||||
super("2019: A space constraint was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireViolated extends Error {
|
||||
readonly code = 2500
|
||||
readonly name = "RequireViolated"
|
||||
readonly msg = "A require expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2500: A require expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireEqViolated extends Error {
|
||||
readonly code = 2501
|
||||
readonly name = "RequireEqViolated"
|
||||
readonly msg = "A require_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2501: A require_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysEqViolated extends Error {
|
||||
readonly code = 2502
|
||||
readonly name = "RequireKeysEqViolated"
|
||||
readonly msg = "A require_keys_eq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2502: A require_keys_eq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireNeqViolated extends Error {
|
||||
readonly code = 2503
|
||||
readonly name = "RequireNeqViolated"
|
||||
readonly msg = "A require_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2503: A require_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysNeqViolated extends Error {
|
||||
readonly code = 2504
|
||||
readonly name = "RequireKeysNeqViolated"
|
||||
readonly msg = "A require_keys_neq expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2504: A require_keys_neq expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGtViolated extends Error {
|
||||
readonly code = 2505
|
||||
readonly name = "RequireGtViolated"
|
||||
readonly msg = "A require_gt expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2505: A require_gt expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGteViolated extends Error {
|
||||
readonly code = 2506
|
||||
readonly name = "RequireGteViolated"
|
||||
readonly msg = "A require_gte expression was violated"
|
||||
|
||||
constructor() {
|
||||
super("2506: A require_gte expression was violated")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorAlreadySet extends Error {
|
||||
readonly code = 3000
|
||||
readonly name = "AccountDiscriminatorAlreadySet"
|
||||
readonly msg = "The account discriminator was already set on this account"
|
||||
|
||||
constructor() {
|
||||
super("3000: The account discriminator was already set on this account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorNotFound extends Error {
|
||||
readonly code = 3001
|
||||
readonly name = "AccountDiscriminatorNotFound"
|
||||
readonly msg = "No 8 byte discriminator was found on the account"
|
||||
|
||||
constructor() {
|
||||
super("3001: No 8 byte discriminator was found on the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorMismatch extends Error {
|
||||
readonly code = 3002
|
||||
readonly name = "AccountDiscriminatorMismatch"
|
||||
readonly msg = "8 byte discriminator did not match what was expected"
|
||||
|
||||
constructor() {
|
||||
super("3002: 8 byte discriminator did not match what was expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotDeserialize extends Error {
|
||||
readonly code = 3003
|
||||
readonly name = "AccountDidNotDeserialize"
|
||||
readonly msg = "Failed to deserialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3003: Failed to deserialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotSerialize extends Error {
|
||||
readonly code = 3004
|
||||
readonly name = "AccountDidNotSerialize"
|
||||
readonly msg = "Failed to serialize the account"
|
||||
|
||||
constructor() {
|
||||
super("3004: Failed to serialize the account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotEnoughKeys extends Error {
|
||||
readonly code = 3005
|
||||
readonly name = "AccountNotEnoughKeys"
|
||||
readonly msg = "Not enough account keys given to the instruction"
|
||||
|
||||
constructor() {
|
||||
super("3005: Not enough account keys given to the instruction")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotMutable extends Error {
|
||||
readonly code = 3006
|
||||
readonly name = "AccountNotMutable"
|
||||
readonly msg = "The given account is not mutable"
|
||||
|
||||
constructor() {
|
||||
super("3006: The given account is not mutable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountOwnedByWrongProgram extends Error {
|
||||
readonly code = 3007
|
||||
readonly name = "AccountOwnedByWrongProgram"
|
||||
readonly msg =
|
||||
"The given account is owned by a different program than expected"
|
||||
|
||||
constructor() {
|
||||
super(
|
||||
"3007: The given account is owned by a different program than expected"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramId extends Error {
|
||||
readonly code = 3008
|
||||
readonly name = "InvalidProgramId"
|
||||
readonly msg = "Program ID was not as expected"
|
||||
|
||||
constructor() {
|
||||
super("3008: Program ID was not as expected")
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramExecutable extends Error {
|
||||
readonly code = 3009
|
||||
readonly name = "InvalidProgramExecutable"
|
||||
readonly msg = "Program account is not executable"
|
||||
|
||||
constructor() {
|
||||
super("3009: Program account is not executable")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSigner extends Error {
|
||||
readonly code = 3010
|
||||
readonly name = "AccountNotSigner"
|
||||
readonly msg = "The given account did not sign"
|
||||
|
||||
constructor() {
|
||||
super("3010: The given account did not sign")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSystemOwned extends Error {
|
||||
readonly code = 3011
|
||||
readonly name = "AccountNotSystemOwned"
|
||||
readonly msg = "The given account is not owned by the system program"
|
||||
|
||||
constructor() {
|
||||
super("3011: The given account is not owned by the system program")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotInitialized extends Error {
|
||||
readonly code = 3012
|
||||
readonly name = "AccountNotInitialized"
|
||||
readonly msg = "The program expected this account to be already initialized"
|
||||
|
||||
constructor() {
|
||||
super("3012: The program expected this account to be already initialized")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotProgramData extends Error {
|
||||
readonly code = 3013
|
||||
readonly name = "AccountNotProgramData"
|
||||
readonly msg = "The given account is not a program data account"
|
||||
|
||||
constructor() {
|
||||
super("3013: The given account is not a program data account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotAssociatedTokenAccount extends Error {
|
||||
readonly code = 3014
|
||||
readonly name = "AccountNotAssociatedTokenAccount"
|
||||
readonly msg = "The given account is not the associated token account"
|
||||
|
||||
constructor() {
|
||||
super("3014: The given account is not the associated token account")
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountSysvarMismatch extends Error {
|
||||
readonly code = 3015
|
||||
readonly name = "AccountSysvarMismatch"
|
||||
readonly msg = "The given public key does not match the required sysvar"
|
||||
|
||||
constructor() {
|
||||
super("3015: The given public key does not match the required sysvar")
|
||||
}
|
||||
}
|
||||
|
||||
export class StateInvalidAddress extends Error {
|
||||
readonly code = 4000
|
||||
readonly name = "StateInvalidAddress"
|
||||
readonly msg = "The given state account does not have the correct address"
|
||||
|
||||
constructor() {
|
||||
super("4000: The given state account does not have the correct address")
|
||||
}
|
||||
}
|
||||
|
||||
export class DeclaredProgramIdMismatch extends Error {
|
||||
readonly code = 4100
|
||||
readonly name = "DeclaredProgramIdMismatch"
|
||||
readonly msg = "The declared program id does not match the actual program id"
|
||||
|
||||
constructor() {
|
||||
super("4100: The declared program id does not match the actual program id")
|
||||
}
|
||||
}
|
||||
|
||||
export class Deprecated extends Error {
|
||||
readonly code = 5000
|
||||
readonly name = "Deprecated"
|
||||
readonly msg = "The API being used is deprecated and should no longer be used"
|
||||
|
||||
constructor() {
|
||||
super("5000: The API being used is deprecated and should no longer be used")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): AnchorError | null {
|
||||
switch (code) {
|
||||
case 100:
|
||||
return new InstructionMissing()
|
||||
case 101:
|
||||
return new InstructionFallbackNotFound()
|
||||
case 102:
|
||||
return new InstructionDidNotDeserialize()
|
||||
case 103:
|
||||
return new InstructionDidNotSerialize()
|
||||
case 1000:
|
||||
return new IdlInstructionStub()
|
||||
case 1001:
|
||||
return new IdlInstructionInvalidProgram()
|
||||
case 2000:
|
||||
return new ConstraintMut()
|
||||
case 2001:
|
||||
return new ConstraintHasOne()
|
||||
case 2002:
|
||||
return new ConstraintSigner()
|
||||
case 2003:
|
||||
return new ConstraintRaw()
|
||||
case 2004:
|
||||
return new ConstraintOwner()
|
||||
case 2005:
|
||||
return new ConstraintRentExempt()
|
||||
case 2006:
|
||||
return new ConstraintSeeds()
|
||||
case 2007:
|
||||
return new ConstraintExecutable()
|
||||
case 2008:
|
||||
return new ConstraintState()
|
||||
case 2009:
|
||||
return new ConstraintAssociated()
|
||||
case 2010:
|
||||
return new ConstraintAssociatedInit()
|
||||
case 2011:
|
||||
return new ConstraintClose()
|
||||
case 2012:
|
||||
return new ConstraintAddress()
|
||||
case 2013:
|
||||
return new ConstraintZero()
|
||||
case 2014:
|
||||
return new ConstraintTokenMint()
|
||||
case 2015:
|
||||
return new ConstraintTokenOwner()
|
||||
case 2016:
|
||||
return new ConstraintMintMintAuthority()
|
||||
case 2017:
|
||||
return new ConstraintMintFreezeAuthority()
|
||||
case 2018:
|
||||
return new ConstraintMintDecimals()
|
||||
case 2019:
|
||||
return new ConstraintSpace()
|
||||
case 2500:
|
||||
return new RequireViolated()
|
||||
case 2501:
|
||||
return new RequireEqViolated()
|
||||
case 2502:
|
||||
return new RequireKeysEqViolated()
|
||||
case 2503:
|
||||
return new RequireNeqViolated()
|
||||
case 2504:
|
||||
return new RequireKeysNeqViolated()
|
||||
case 2505:
|
||||
return new RequireGtViolated()
|
||||
case 2506:
|
||||
return new RequireGteViolated()
|
||||
case 3000:
|
||||
return new AccountDiscriminatorAlreadySet()
|
||||
case 3001:
|
||||
return new AccountDiscriminatorNotFound()
|
||||
case 3002:
|
||||
return new AccountDiscriminatorMismatch()
|
||||
case 3003:
|
||||
return new AccountDidNotDeserialize()
|
||||
case 3004:
|
||||
return new AccountDidNotSerialize()
|
||||
case 3005:
|
||||
return new AccountNotEnoughKeys()
|
||||
case 3006:
|
||||
return new AccountNotMutable()
|
||||
case 3007:
|
||||
return new AccountOwnedByWrongProgram()
|
||||
case 3008:
|
||||
return new InvalidProgramId()
|
||||
case 3009:
|
||||
return new InvalidProgramExecutable()
|
||||
case 3010:
|
||||
return new AccountNotSigner()
|
||||
case 3011:
|
||||
return new AccountNotSystemOwned()
|
||||
case 3012:
|
||||
return new AccountNotInitialized()
|
||||
case 3013:
|
||||
return new AccountNotProgramData()
|
||||
case 3014:
|
||||
return new AccountNotAssociatedTokenAccount()
|
||||
case 3015:
|
||||
return new AccountSysvarMismatch()
|
||||
case 4000:
|
||||
return new StateInvalidAddress()
|
||||
case 4100:
|
||||
return new DeclaredProgramIdMismatch()
|
||||
case 5000:
|
||||
return new Deprecated()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
export type CustomError =
|
||||
| InvalidSwitchboardVrfAccount
|
||||
| MaxResultExceedsMaximum
|
||||
| EmptyCurrentRoundResult
|
||||
| InvalidAuthorityError
|
||||
|
||||
export class InvalidSwitchboardVrfAccount extends Error {
|
||||
readonly code = 6000
|
||||
readonly name = "InvalidSwitchboardVrfAccount"
|
||||
readonly msg = "Not a valid Switchboard VRF account"
|
||||
|
||||
constructor() {
|
||||
super("6000: Not a valid Switchboard VRF account")
|
||||
}
|
||||
}
|
||||
|
||||
export class MaxResultExceedsMaximum extends Error {
|
||||
readonly code = 6001
|
||||
readonly name = "MaxResultExceedsMaximum"
|
||||
readonly msg = "The max result must not exceed u64"
|
||||
|
||||
constructor() {
|
||||
super("6001: The max result must not exceed u64")
|
||||
}
|
||||
}
|
||||
|
||||
export class EmptyCurrentRoundResult extends Error {
|
||||
readonly code = 6002
|
||||
readonly name = "EmptyCurrentRoundResult"
|
||||
readonly msg = "Current round result is empty"
|
||||
|
||||
constructor() {
|
||||
super("6002: Current round result is empty")
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidAuthorityError extends Error {
|
||||
readonly code = 6003
|
||||
readonly name = "InvalidAuthorityError"
|
||||
readonly msg = "Invalid authority account provided."
|
||||
|
||||
constructor() {
|
||||
super("6003: Invalid authority account provided.")
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number): CustomError | null {
|
||||
switch (code) {
|
||||
case 6000:
|
||||
return new InvalidSwitchboardVrfAccount()
|
||||
case 6001:
|
||||
return new MaxResultExceedsMaximum()
|
||||
case 6002:
|
||||
return new EmptyCurrentRoundResult()
|
||||
case 6003:
|
||||
return new InvalidAuthorityError()
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
import { PROGRAM_ID } from "../programId"
|
||||
import * as anchor from "./anchor"
|
||||
import * as custom from "./custom"
|
||||
|
||||
export function fromCode(
|
||||
code: number
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
return code >= 6000 ? custom.fromCode(code) : anchor.fromCode(code)
|
||||
}
|
||||
|
||||
function hasOwnProperty<X extends object, Y extends PropertyKey>(
|
||||
obj: X,
|
||||
prop: Y
|
||||
): obj is X & Record<Y, unknown> {
|
||||
return Object.hasOwnProperty.call(obj, prop)
|
||||
}
|
||||
|
||||
const errorRe = /Program (\w+) failed: custom program error: (\w+)/
|
||||
|
||||
export function fromTxError(
|
||||
err: unknown
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
if (
|
||||
typeof err !== "object" ||
|
||||
err === null ||
|
||||
!hasOwnProperty(err, "logs") ||
|
||||
!Array.isArray(err.logs)
|
||||
) {
|
||||
return null
|
||||
}
|
||||
|
||||
let firstMatch: RegExpExecArray | null = null
|
||||
for (const logLine of err.logs) {
|
||||
firstMatch = errorRe.exec(logLine)
|
||||
if (firstMatch !== null) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMatch === null) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [programIdRaw, codeRaw] = firstMatch.slice(1)
|
||||
if (programIdRaw !== PROGRAM_ID.toString()) {
|
||||
return null
|
||||
}
|
||||
|
||||
let errorCode: number
|
||||
try {
|
||||
errorCode = parseInt(codeRaw, 16)
|
||||
} catch (parseErr) {
|
||||
return null
|
||||
}
|
||||
|
||||
return fromCode(errorCode)
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
export { initState, InitStateAccounts, InitStateArgs } from "./initState"
|
||||
export {
|
||||
requestResult,
|
||||
RequestResultAccounts,
|
||||
RequestResultArgs,
|
||||
} from "./requestResult"
|
||||
export { updateResult, UpdateResultAccounts } from "./updateResult"
|
|
@ -1,39 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId"
|
||||
import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface InitStateArgs {
|
||||
params: types.InitStateParamsFields
|
||||
}
|
||||
|
||||
export interface InitStateAccounts {
|
||||
state: PublicKey
|
||||
authority: PublicKey
|
||||
payer: PublicKey
|
||||
vrf: PublicKey
|
||||
systemProgram: PublicKey
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.InitStateParams.layout("params")])
|
||||
|
||||
export function initState(args: InitStateArgs, accounts: InitStateAccounts) {
|
||||
const keys = [
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.vrf, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
]
|
||||
const identifier = Buffer.from([124, 213, 73, 136, 80, 37, 141, 54])
|
||||
const buffer = Buffer.alloc(1000)
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.InitStateParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
)
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
|
||||
const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data })
|
||||
return ix
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId"
|
||||
import * as types from "../types" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface RequestResultArgs {
|
||||
params: types.RequestResultParamsFields
|
||||
}
|
||||
|
||||
export interface RequestResultAccounts {
|
||||
state: PublicKey
|
||||
authority: PublicKey
|
||||
switchboardProgram: PublicKey
|
||||
vrf: PublicKey
|
||||
oracleQueue: PublicKey
|
||||
queueAuthority: PublicKey
|
||||
dataBuffer: PublicKey
|
||||
permission: PublicKey
|
||||
escrow: PublicKey
|
||||
payerWallet: PublicKey
|
||||
payerAuthority: PublicKey
|
||||
recentBlockhashes: PublicKey
|
||||
programState: PublicKey
|
||||
tokenProgram: PublicKey
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.RequestResultParams.layout("params")])
|
||||
|
||||
export function requestResult(
|
||||
args: RequestResultArgs,
|
||||
accounts: RequestResultAccounts
|
||||
) {
|
||||
const keys = [
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.switchboardProgram, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.vrf, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oracleQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.dataBuffer, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.payerWallet, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.payerAuthority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.recentBlockhashes, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.programState, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
]
|
||||
const identifier = Buffer.from([52, 47, 170, 99, 27, 80, 113, 141])
|
||||
const buffer = Buffer.alloc(1000)
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.RequestResultParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
)
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len)
|
||||
const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data })
|
||||
return ix
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { PROGRAM_ID } from "../programId"
|
||||
|
||||
export interface UpdateResultAccounts {
|
||||
state: PublicKey
|
||||
vrf: PublicKey
|
||||
}
|
||||
|
||||
export function updateResult(accounts: UpdateResultAccounts) {
|
||||
const keys = [
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.vrf, isSigner: false, isWritable: false },
|
||||
]
|
||||
const identifier = Buffer.from([145, 72, 9, 94, 61, 97, 126, 106])
|
||||
const data = identifier
|
||||
const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data })
|
||||
return ix
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import { PublicKey } from "@solana/web3.js"
|
||||
|
||||
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
|
||||
export const PROGRAM_ID_CLI = new PublicKey(
|
||||
"HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
|
||||
)
|
||||
|
||||
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
|
||||
export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI
|
|
@ -1,51 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"
|
||||
import BN from "bn.js" // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface InitStateParamsFields {
|
||||
maxResult: BN
|
||||
}
|
||||
|
||||
export interface InitStateParamsJSON {
|
||||
maxResult: string
|
||||
}
|
||||
|
||||
export class InitStateParams {
|
||||
readonly maxResult: BN
|
||||
|
||||
constructor(fields: InitStateParamsFields) {
|
||||
this.maxResult = fields.maxResult
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.u64("maxResult")], property)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new InitStateParams({
|
||||
maxResult: obj.maxResult,
|
||||
})
|
||||
}
|
||||
|
||||
static toEncodable(fields: InitStateParamsFields) {
|
||||
return {
|
||||
maxResult: fields.maxResult,
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): InitStateParamsJSON {
|
||||
return {
|
||||
maxResult: this.maxResult.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(obj: InitStateParamsJSON): InitStateParams {
|
||||
return new InitStateParams({
|
||||
maxResult: new BN(obj.maxResult),
|
||||
})
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return InitStateParams.toEncodable(this)
|
||||
}
|
||||
}
|
|
@ -1,61 +0,0 @@
|
|||
import * as borsh from "@project-serum/borsh"
|
||||
|
||||
export interface RequestResultParamsFields {
|
||||
permissionBump: number
|
||||
switchboardStateBump: number
|
||||
}
|
||||
|
||||
export interface RequestResultParamsJSON {
|
||||
permissionBump: number
|
||||
switchboardStateBump: number
|
||||
}
|
||||
|
||||
export class RequestResultParams {
|
||||
readonly permissionBump: number
|
||||
readonly switchboardStateBump: number
|
||||
|
||||
constructor(fields: RequestResultParamsFields) {
|
||||
this.permissionBump = fields.permissionBump
|
||||
this.switchboardStateBump = fields.switchboardStateBump
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[borsh.u8("permissionBump"), borsh.u8("switchboardStateBump")],
|
||||
property
|
||||
)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new RequestResultParams({
|
||||
permissionBump: obj.permissionBump,
|
||||
switchboardStateBump: obj.switchboardStateBump,
|
||||
})
|
||||
}
|
||||
|
||||
static toEncodable(fields: RequestResultParamsFields) {
|
||||
return {
|
||||
permissionBump: fields.permissionBump,
|
||||
switchboardStateBump: fields.switchboardStateBump,
|
||||
}
|
||||
}
|
||||
|
||||
toJSON(): RequestResultParamsJSON {
|
||||
return {
|
||||
permissionBump: this.permissionBump,
|
||||
switchboardStateBump: this.switchboardStateBump,
|
||||
}
|
||||
}
|
||||
|
||||
static fromJSON(obj: RequestResultParamsJSON): RequestResultParams {
|
||||
return new RequestResultParams({
|
||||
permissionBump: obj.permissionBump,
|
||||
switchboardStateBump: obj.switchboardStateBump,
|
||||
})
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return RequestResultParams.toEncodable(this)
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
export {
|
||||
InitStateParams,
|
||||
InitStateParamsFields,
|
||||
InitStateParamsJSON,
|
||||
} from "./InitStateParams"
|
||||
export {
|
||||
RequestResultParams,
|
||||
RequestResultParamsFields,
|
||||
RequestResultParamsJSON,
|
||||
} from "./RequestResultParams"
|
File diff suppressed because it is too large
Load Diff
|
@ -19,22 +19,21 @@
|
|||
"@project-serum/borsh": "^0.2.5",
|
||||
"@solana/spl-token-v2": "npm:@solana/spl-token@^0.2.0",
|
||||
"@solana/web3.js": "^1.42.0",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.43",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.135",
|
||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||
"@typescript-eslint/parser": "^5.44.0",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165",
|
||||
"chalk": "^4.1.2",
|
||||
"child_process": "^1.0.2",
|
||||
"dotenv": "^16.0.1",
|
||||
"eslint": "^8.28.0",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@switchboard-xyz/switchboardv2-cli": "^0.2.14",
|
||||
"@switchboard-xyz/cli": "^2.0.21",
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^17.0.45",
|
||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||
"@typescript-eslint/parser": "^5.44.0",
|
||||
"chai": "^4.3.6",
|
||||
"eslint": "^8.28.0",
|
||||
"mocha": "^9.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.4.1",
|
||||
|
|
|
@ -42,6 +42,7 @@ describe("anchor-vrf-parser test", () => {
|
|||
let switchboard: SwitchboardTestContext;
|
||||
|
||||
const vrfSecret = anchor.web3.Keypair.generate();
|
||||
console.log(`VRF Account: ${vrfSecret.publicKey}`);
|
||||
|
||||
const [vrfClientKey, vrfClientBump] =
|
||||
anchor.utils.publicKey.findProgramAddressSync(
|
||||
|
@ -101,26 +102,28 @@ describe("anchor-vrf-parser test", () => {
|
|||
const maxTime = 60000;
|
||||
const retryCount = 10;
|
||||
const retryInterval = maxTime / retryCount;
|
||||
|
||||
let isReady = false;
|
||||
|
||||
const timer = setInterval(async () => {
|
||||
const queue = await switchboard.queue.loadData();
|
||||
const oracles = queue.queueData as anchor.web3.PublicKey[];
|
||||
if (oracles.length) {
|
||||
console.log(`oracle ready, ${oracles.length}`);
|
||||
const oracles = queue.queue as anchor.web3.PublicKey[];
|
||||
if (oracles.length > 0) {
|
||||
// console.log(`oracle ready, ${oracles.length}`);
|
||||
isReady = true;
|
||||
clearTimeout(timer);
|
||||
} else {
|
||||
console.log(`oracle not ready, ${oracles.length}`);
|
||||
// console.log(`oracle not ready, ${oracles.length}`);
|
||||
}
|
||||
}, retryInterval);
|
||||
|
||||
let n = maxTime / 1000;
|
||||
while (!isReady && n > 0) {
|
||||
if (isReady) {
|
||||
console.log(`finally ready`);
|
||||
// console.log(`finally ready`);
|
||||
break;
|
||||
}
|
||||
console.log(`still not ready ${n} ...`);
|
||||
// console.log(`still not ready ${n} ...`);
|
||||
await sleep(1 * 1000);
|
||||
--n;
|
||||
}
|
||||
|
@ -206,6 +209,9 @@ describe("anchor-vrf-parser test", () => {
|
|||
|
||||
const { escrow } = await vrfAccount.loadData();
|
||||
|
||||
// give account time to propagate to oracle RPCs
|
||||
await sleep(2000);
|
||||
|
||||
// Request randomness
|
||||
await vrfClientProgram.methods.requestResult!({
|
||||
switchboardStateBump: programStateBump,
|
||||
|
@ -235,7 +241,7 @@ describe("anchor-vrf-parser test", () => {
|
|||
const result = await awaitCallback(
|
||||
vrfClientProgram.provider.connection,
|
||||
vrfClientKey,
|
||||
155_000
|
||||
45_000
|
||||
);
|
||||
|
||||
console.log(`VrfClient Result: ${result}`);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"strict": false,
|
||||
"strictNullChecks": false,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/solana.js"],
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"],
|
||||
"@solana/spl-token": ["./node_modules/@solana/spl-token"]
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
|||
"include": ["tests/**/*", "./cli.ts", "./client/**/*"],
|
||||
"exclude": ["target", "lib"],
|
||||
"references": [
|
||||
{ "path": "../../javascript/solana.js" },
|
||||
{ "path": "../../javascript/switchboard-v2" },
|
||||
{ "path": "../../javascript/sbv2-utils" }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -12,6 +12,6 @@ no-entrypoint = []
|
|||
|
||||
[dependencies]
|
||||
# switchboard-v2 = { path = "../../rust/switchboard-v2", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.13", features = ["devnet"] }
|
||||
switchboard-v2 = { version = "^0.1.16", features = ["devnet"] }
|
||||
solana-program = "~1.10.29"
|
||||
anchor-lang = "^0.25.0"
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -14,10 +14,10 @@
|
|||
"test": "echo \"For workspace native-feed-parser, use the anchor:test script\" && exit 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@project-serum/anchor": "^0.24.2",
|
||||
"@solana/web3.js": "^1.42.0",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.43",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.134"
|
||||
"@project-serum/anchor": "^0.25.0",
|
||||
"@solana/web3.js": "^1.66.2",
|
||||
"@switchboard-xyz/sbv2-utils": "^0.1.53",
|
||||
"@switchboard-xyz/switchboard-v2": "^0.0.165"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.0",
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"types": ["mocha", "chai"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
|
@ -9,14 +8,13 @@
|
|||
"esModuleInterop": true,
|
||||
"noEmit": true,
|
||||
"paths": {
|
||||
"@switchboard-xyz/switchboard-v2": ["../../../libraries/ts"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../../libraries/sbv2-utils"]
|
||||
"@switchboard-xyz/switchboard-v2": ["../../javascript/switchboard-v2"],
|
||||
"@switchboard-xyz/sbv2-utils": ["../../javascript/sbv2-utils"]
|
||||
}
|
||||
},
|
||||
// "include": ["oldtests/**/**/*"],
|
||||
"exclude": ["target"],
|
||||
"references": [
|
||||
{ "path": "../../../libraries/ts" },
|
||||
{ "path": "../../../libraries/sbv2-utils" }
|
||||
{ "path": ".../../javascript/switchboard-v2" },
|
||||
{ "path": "../../javascript/sbv2-utils" }
|
||||
]
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -47,6 +47,29 @@ pub struct AggregatorRound {
|
|||
pub errors_fulfilled: [bool; 16],
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, AnchorSerialize, AnchorDeserialize, Eq, PartialEq)]
|
||||
#[repr(u8)]
|
||||
pub enum AggregatorResolutionMode {
|
||||
ModeRoundResolution = 0,
|
||||
ModeSlidingResolution = 1,
|
||||
}
|
||||
#[account(zero_copy)]
|
||||
#[repr(packed)]
|
||||
pub struct SlidingResultAccountData {
|
||||
pub data: [SlidingWindowElement; 16],
|
||||
pub bump: u8,
|
||||
pub _ebuf: [u8; 512],
|
||||
}
|
||||
#[zero_copy]
|
||||
#[derive(Default)]
|
||||
#[repr(packed)]
|
||||
pub struct SlidingWindowElement {
|
||||
pub oracle_key: Pubkey,
|
||||
pub value: SwitchboardDecimal,
|
||||
pub slot: u64,
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
// #[zero_copy]
|
||||
#[account(zero_copy)]
|
||||
#[repr(packed)]
|
||||
|
@ -113,8 +136,11 @@ pub struct AggregatorAccountData {
|
|||
pub job_weights: [u8; 16],
|
||||
/// Unix timestamp when the feed was created.
|
||||
pub creation_timestamp: i64,
|
||||
/// Use sliding windoe or round based resolution
|
||||
/// NOTE: This changes result propogation in latest_round_result
|
||||
pub resolution_mode: AggregatorResolutionMode,
|
||||
/// Reserved for future info.
|
||||
pub _ebuf: [u8; 139],
|
||||
pub _ebuf: [u8; 138],
|
||||
}
|
||||
|
||||
impl AggregatorAccountData {
|
||||
|
@ -161,7 +187,12 @@ impl AggregatorAccountData {
|
|||
/// let decimal: f64 = feed_result.try_into()?;
|
||||
/// ```
|
||||
pub fn get_result(&self) -> anchor_lang::Result<SwitchboardDecimal> {
|
||||
if self.min_oracle_results > self.latest_confirmed_round.num_success {
|
||||
if self.resolution_mode == AggregatorResolutionMode::ModeSlidingResolution {
|
||||
return Ok(self.latest_confirmed_round.result);
|
||||
}
|
||||
let min_oracle_results = self.min_oracle_results;
|
||||
let latest_confirmed_round_num_success = self.latest_confirmed_round.num_success;
|
||||
if min_oracle_results > latest_confirmed_round_num_success {
|
||||
return Err(SwitchboardError::InvalidAggregatorRound.into());
|
||||
}
|
||||
Ok(self.latest_confirmed_round.result)
|
||||
|
|
|
@ -29,7 +29,8 @@ pub struct BufferRelayerAccountData {
|
|||
pub result: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, AnchorSerialize, AnchorDeserialize)]
|
||||
#[zero_copy]
|
||||
#[derive(Default, Debug, AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct BufferRelayerRound {
|
||||
/// Number of successful responses.
|
||||
pub num_success: u32,
|
||||
|
|
|
@ -37,6 +37,8 @@ pub const LEASE_SEED: &[u8] = b"LeaseAccountData";
|
|||
pub const ORACLE_SEED: &[u8] = b"OracleAccountData";
|
||||
/// Discriminator used for Switchboard buffer accounts.
|
||||
pub const BUFFER_DISCRIMINATOR: &[u8] = b"BUFFERxx";
|
||||
/// Seed used to derive the SlidingWindow PDA.
|
||||
const SLIDING_RESULT_SEED: &[u8] = b"SlidingResultAccountData";
|
||||
|
||||
/// Mainnet program id for Switchboard v2
|
||||
pub const SWITCHBOARD_V2_MAINNET: Pubkey = pubkey!("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f");
|
||||
|
|
5438
sbv2.devnet.json
5438
sbv2.devnet.json
File diff suppressed because it is too large
Load Diff
5438
sbv2.mainnet.json
5438
sbv2.mainnet.json
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue