From 37a21ee6f6112e6729df63be36f0bc76f3ecb54c Mon Sep 17 00:00:00 2001 From: Conner Gallagher Date: Wed, 18 May 2022 15:00:17 -0600 Subject: [PATCH] refactored example programs wip wip example program cleanup example programs cleanup --- .eslintignore | 4 - .eslintrc.json | 1 + .gitignore | 2 + Anchor.toml | 27 + Cargo.toml | 6 + cli/README.md | 12 + cli/src/commands/print/vrf.ts | 2 +- cli/src/commands/vrf/create/index.ts | 5 + libraries/sbv2-lite/tsconfig.json | 1 + .../sbv2-utils/src/{anchor => }/anchor.ts | 4 +- libraries/sbv2-utils/src/anchor/index.ts | 1 - libraries/sbv2-utils/src/{math => }/big.ts | 0 libraries/sbv2-utils/src/feeds.ts | 326 ++ libraries/sbv2-utils/src/index.ts | 2 +- libraries/sbv2-utils/src/instruction.ts | 98 + libraries/sbv2-utils/src/math/index.ts | 1 - libraries/sbv2-utils/src/print.ts | 2 + libraries/sbv2-utils/src/test/context.ts | 92 +- libraries/sbv2-utils/tsconfig.json | 2 + package.json | 7 + programs/anchor-feed-parser/.gitignore | 6 - programs/anchor-feed-parser/Anchor.toml | 20 - programs/anchor-feed-parser/Cargo.toml | 26 +- .../anchor-feed-parser => }/Xargo.toml | 0 .../client/errors/anchor.ts | 690 +++ .../anchor-feed-parser/client/errors/index.ts | 52 + .../client/instructions/index.ts | 1 + .../client/instructions/readResult.ts | 16 + .../anchor-feed-parser/client/programId.ts | 9 + programs/anchor-feed-parser/package.json | 16 +- .../programs/anchor-feed-parser/Cargo.toml | 21 - .../anchor-feed-parser/scripts/generate.ts | 52 - programs/anchor-feed-parser/solita.ts | 58 - .../anchor-feed-parser/src/generated/index.ts | 18 - .../src/generated/instructions/index.ts | 1 - .../src/generated/instructions/readResult.ts | 69 - programs/anchor-feed-parser/src/index.ts | 1 - .../anchor-feed-parser => }/src/lib.rs | 2 +- .../tests/anchor-feed-parser.ts | 41 +- programs/anchor-feed-parser/tsconfig.json | 3 +- programs/anchor-vrf-parser/.gitignore | 6 - programs/anchor-vrf-parser/Anchor.toml | 14 - programs/anchor-vrf-parser/Cargo.toml | 28 +- .../anchor-vrf-parser => }/Xargo.toml | 0 .../client/accounts/VrfClient.ts | 134 + .../client/accounts/index.ts | 1 + .../anchor-vrf-parser/client/errors/anchor.ts | 690 +++ .../anchor-vrf-parser/client/errors/custom.ts | 60 + .../anchor-vrf-parser/client/errors/index.ts | 57 + .../client/instructions/index.ts | 7 + .../client/instructions/initState.ts | 39 + .../client/instructions/requestResult.ts | 60 + .../client/instructions/updateResult.ts | 18 + .../anchor-vrf-parser/client/programId.ts | 9 + .../client/types/InitStateParams.ts | 51 + .../client/types/RequestResultParams.ts | 61 + .../anchor-vrf-parser/client/types/index.ts | 10 + programs/anchor-vrf-parser/package.json | 19 +- .../programs/anchor-vrf-parser/Cargo.toml | 23 - .../anchor-vrf-parser/scripts/generate.ts | 55 - programs/anchor-vrf-parser/solita.ts | 58 - .../src/actions/init_state.rs | 0 .../anchor-vrf-parser => }/src/actions/mod.rs | 0 .../src/actions/request_result.rs | 0 .../src/actions/update_result.rs | 2 + programs/anchor-vrf-parser/src/api.ts | 39 - .../src/generated/accounts/VrfClient.ts | 179 - .../src/generated/accounts/index.ts | 1 - .../src/generated/errors/index.ts | 135 - .../anchor-vrf-parser/src/generated/index.ts | 21 - .../src/generated/instructions/index.ts | 3 - .../src/generated/instructions/initState.ts | 107 - .../generated/instructions/requestResult.ts | 181 - .../generated/instructions/updateResult.ts | 73 - .../src/generated/types/InitStateParams.ts | 20 - .../generated/types/RequestResultParams.ts | 25 - .../src/generated/types/index.ts | 2 - programs/anchor-vrf-parser/src/index.ts | 2 - .../anchor-vrf-parser => }/src/lib.rs | 2 +- .../tests/permissionless-queue.test.ts | 205 - .../anchor-vrf-parser/tests/test-utils.ts | 17 - .../anchor-vrf-parser/tests/vrc-cpi.test.ts | 213 +- programs/anchor-vrf-parser/tsconfig.json | 12 +- programs/spl-feed-parser/.gitignore | 6 - programs/spl-feed-parser/Cargo.toml | 9 +- programs/spl-feed-parser/package.json | 8 +- .../tests/anchor-feed-parser.ts | 54 + .../spl-feed-parser/tests/spl-feed-parser.ts | 2 - programs/spl-feed-parser/tsconfig.json | 3 +- scripts/setup-example-programs.js | 159 + switchboard_v2.json | 4766 +++++++++++++++++ tsconfig.json | 3 +- website/idl/errors.md | 150 +- website/package.json | 2 +- yarn.lock | 188 +- 95 files changed, 7939 insertions(+), 1747 deletions(-) delete mode 100644 .eslintignore create mode 100644 Anchor.toml create mode 100644 Cargo.toml rename libraries/sbv2-utils/src/{anchor => }/anchor.ts (98%) delete mode 100644 libraries/sbv2-utils/src/anchor/index.ts rename libraries/sbv2-utils/src/{math => }/big.ts (100%) create mode 100644 libraries/sbv2-utils/src/feeds.ts create mode 100644 libraries/sbv2-utils/src/instruction.ts delete mode 100644 libraries/sbv2-utils/src/math/index.ts delete mode 100644 programs/anchor-feed-parser/.gitignore delete mode 100644 programs/anchor-feed-parser/Anchor.toml rename programs/anchor-feed-parser/{programs/anchor-feed-parser => }/Xargo.toml (100%) create mode 100644 programs/anchor-feed-parser/client/errors/anchor.ts create mode 100644 programs/anchor-feed-parser/client/errors/index.ts create mode 100644 programs/anchor-feed-parser/client/instructions/index.ts create mode 100644 programs/anchor-feed-parser/client/instructions/readResult.ts create mode 100644 programs/anchor-feed-parser/client/programId.ts delete mode 100644 programs/anchor-feed-parser/programs/anchor-feed-parser/Cargo.toml delete mode 100644 programs/anchor-feed-parser/scripts/generate.ts delete mode 100644 programs/anchor-feed-parser/solita.ts delete mode 100644 programs/anchor-feed-parser/src/generated/index.ts delete mode 100644 programs/anchor-feed-parser/src/generated/instructions/index.ts delete mode 100644 programs/anchor-feed-parser/src/generated/instructions/readResult.ts delete mode 100644 programs/anchor-feed-parser/src/index.ts rename programs/anchor-feed-parser/{programs/anchor-feed-parser => }/src/lib.rs (91%) delete mode 100644 programs/anchor-vrf-parser/.gitignore delete mode 100644 programs/anchor-vrf-parser/Anchor.toml rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/Xargo.toml (100%) create mode 100644 programs/anchor-vrf-parser/client/accounts/VrfClient.ts create mode 100644 programs/anchor-vrf-parser/client/accounts/index.ts create mode 100644 programs/anchor-vrf-parser/client/errors/anchor.ts create mode 100644 programs/anchor-vrf-parser/client/errors/custom.ts create mode 100644 programs/anchor-vrf-parser/client/errors/index.ts create mode 100644 programs/anchor-vrf-parser/client/instructions/index.ts create mode 100644 programs/anchor-vrf-parser/client/instructions/initState.ts create mode 100644 programs/anchor-vrf-parser/client/instructions/requestResult.ts create mode 100644 programs/anchor-vrf-parser/client/instructions/updateResult.ts create mode 100644 programs/anchor-vrf-parser/client/programId.ts create mode 100644 programs/anchor-vrf-parser/client/types/InitStateParams.ts create mode 100644 programs/anchor-vrf-parser/client/types/RequestResultParams.ts create mode 100644 programs/anchor-vrf-parser/client/types/index.ts delete mode 100644 programs/anchor-vrf-parser/programs/anchor-vrf-parser/Cargo.toml delete mode 100644 programs/anchor-vrf-parser/scripts/generate.ts delete mode 100644 programs/anchor-vrf-parser/solita.ts rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/src/actions/init_state.rs (100%) rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/src/actions/mod.rs (100%) rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/src/actions/request_result.rs (100%) rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/src/actions/update_result.rs (91%) delete mode 100644 programs/anchor-vrf-parser/src/api.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/accounts/VrfClient.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/accounts/index.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/errors/index.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/index.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/instructions/index.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/instructions/initState.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/instructions/requestResult.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/instructions/updateResult.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/types/InitStateParams.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/types/RequestResultParams.ts delete mode 100644 programs/anchor-vrf-parser/src/generated/types/index.ts delete mode 100644 programs/anchor-vrf-parser/src/index.ts rename programs/anchor-vrf-parser/{programs/anchor-vrf-parser => }/src/lib.rs (96%) delete mode 100644 programs/anchor-vrf-parser/tests/permissionless-queue.test.ts delete mode 100644 programs/anchor-vrf-parser/tests/test-utils.ts delete mode 100644 programs/spl-feed-parser/.gitignore create mode 100644 programs/spl-feed-parser/tests/anchor-feed-parser.ts delete mode 100644 programs/spl-feed-parser/tests/spl-feed-parser.ts create mode 100644 scripts/setup-example-programs.js create mode 100644 switchboard_v2.json diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 582c5ed..0000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -lib -dist -node_modules -scripts \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index af217e6..53d1a55 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,6 +3,7 @@ "es2020": true, "node": true }, + "ignorePatterns": ["**/*/node_modules", "**/*/lib", "**/*/dist"], "root": true, "extends": [ "airbnb-typescript/base", diff --git a/.gitignore b/.gitignore index 7cf4278..6edf352 100644 --- a/.gitignore +++ b/.gitignore @@ -21,12 +21,14 @@ programs/**/target Cargo.lock .anchor target +.crates # Misc .keypairs secrets *-keypair*.json .archive +*-error.log # Root level jsons ignored job-directory/*.json diff --git a/Anchor.toml b/Anchor.toml new file mode 100644 index 0000000..d7fee78 --- /dev/null +++ b/Anchor.toml @@ -0,0 +1,27 @@ +[provider] +cluster = "devnet" +wallet = "../payer-keypair.json" +# wallet = "~/.config/solana/id.json" + + +[programs.localnet] +anchor_feed_parser = "H7frfaL4ZjRW6NAyBvuGgsi9P2G1CgVgqFqzFSDS521f" +anchor_vrf_parser = "HWCUJF1GgCrS1fWNyJdWSBEVNXtdjRwQy7HohdQ5n31o" +# spl_feed_parser = "9dqf4Z9oKRJ6TDGHWyfArV7VtcFNsZWz1wZwWWQmWPHW" +[programs.devnet] +anchor_feed_parser = "H7frfaL4ZjRW6NAyBvuGgsi9P2G1CgVgqFqzFSDS521f" +anchor_vrf_parser = "HWCUJF1GgCrS1fWNyJdWSBEVNXtdjRwQy7HohdQ5n31o" +# spl_feed_parser = "9dqf4Z9oKRJ6TDGHWyfArV7VtcFNsZWz1wZwWWQmWPHW" + +[registry] +url = "https://anchor.projectserum.com" + +[scripts] +test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 programs/*/tests/**/*.test.ts" + + +[test.validator] +url="https://api.devnet.solana.com" + +[[testnet.validator.clone]] +address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" # sbv2 SOL/USD Feed \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..8ece59f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,6 @@ +[workspace] +members = [ + "programs/anchor-feed-parser", + "programs/anchor-vrf-parser", + "programs/spl-feed-parser", +] \ No newline at end of file diff --git a/cli/README.md b/cli/README.md index 428a21a..1502d32 100644 --- a/cli/README.md +++ b/cli/README.md @@ -2408,6 +2408,18 @@ OPTIONS --queueAuthority=queueAuthority alternative keypair to use for queue authority --vrfKeypair=vrfKeypair filesystem path of existing keypair to use for VRF Account + +EXAMPLES + sbv2 vrf:create 9WZ59yz95bd3XwJxDPVE2PjvVWmSy9WM1NgGD2Hqsohw --keypair ../payer-keypair.json -v --enable + --queueAuthority queue-authority-keypair.json --callbackPid 6MLk7G54uHZ7JuzNxpBAVENANrgM9BZ51pKkzGwPYBCE --ixData + "[145,72,9,94,61,97,126,106]" -a "{"pubkey": "HpQoFL5kxPp2JCFvjsVTvBd7navx4THLefUU68SXAyd6","isSigner": + false,"isWritable": true}" -a "{"pubkey": "8VdBtS8ufkXMCa6Yr9E4KVCfX2inVZVwU4KGg2CL1q7P","isSigner": + false,"isWritable": false}" + sbv2 vrf:create 9WZ59yz95bd3XwJxDPVE2PjvVWmSy9WM1NgGD2Hqsohw --keypair ../payer-keypair.json -v --enable + --queueAuthority oracle-keypair.json --callbackPid 6MLk7G54uHZ7JuzNxpBAVENANrgM9BZ51pKkzGwPYBCE --ixData + "[145,72,9,94,61,97,126,106]" -a "{"pubkey": "HYKi1grticLXPe5vqapUHhm976brwqRob8vqRnWMKWL5","isSigner": + false,"isWritable": true}" -a "{"pubkey": "6vG9QLMgSvsfjvSpDxWfZ2MGPYGzEYoBxviLG7cr4go","isSigner": + false,"isWritable": false}" ``` _See code: [src/commands/vrf/create/index.ts](https://github.com/switchboard-xyz/switchboard-v2/blob/v0.1.18/src/commands/vrf/create/index.ts)_ diff --git a/cli/src/commands/print/vrf.ts b/cli/src/commands/print/vrf.ts index dc0f948..7b464bb 100644 --- a/cli/src/commands/print/vrf.ts +++ b/cli/src/commands/print/vrf.ts @@ -35,7 +35,7 @@ export default class VrfPrint extends BaseCommand { publicKey: args.vrfKey, }); - this.logger.log(await prettyPrintVrf(vrfAccount)); + this.logger.log(await prettyPrintVrf(vrfAccount, undefined, true)); } async catch(error) { diff --git a/cli/src/commands/vrf/create/index.ts b/cli/src/commands/vrf/create/index.ts index 81940eb..283208d 100644 --- a/cli/src/commands/vrf/create/index.ts +++ b/cli/src/commands/vrf/create/index.ts @@ -61,6 +61,11 @@ export default class VrfCreate extends BaseCommand { }, ]; + static examples = [ + 'sbv2 vrf:create 9WZ59yz95bd3XwJxDPVE2PjvVWmSy9WM1NgGD2Hqsohw --keypair ../payer-keypair.json -v --enable --queueAuthority queue-authority-keypair.json --callbackPid 6MLk7G54uHZ7JuzNxpBAVENANrgM9BZ51pKkzGwPYBCE --ixData "[145,72,9,94,61,97,126,106]" -a "{"pubkey": "HpQoFL5kxPp2JCFvjsVTvBd7navx4THLefUU68SXAyd6","isSigner": false,"isWritable": true}" -a "{"pubkey": "8VdBtS8ufkXMCa6Yr9E4KVCfX2inVZVwU4KGg2CL1q7P","isSigner": false,"isWritable": false}"', + 'sbv2 vrf:create 9WZ59yz95bd3XwJxDPVE2PjvVWmSy9WM1NgGD2Hqsohw --keypair ../payer-keypair.json -v --enable --queueAuthority oracle-keypair.json --callbackPid 6MLk7G54uHZ7JuzNxpBAVENANrgM9BZ51pKkzGwPYBCE --ixData "[145,72,9,94,61,97,126,106]" -a "{"pubkey": "HYKi1grticLXPe5vqapUHhm976brwqRob8vqRnWMKWL5","isSigner": false,"isWritable": true}" -a "{"pubkey": "6vG9QLMgSvsfjvSpDxWfZ2MGPYGzEYoBxviLG7cr4go","isSigner": false,"isWritable": false}"', + ]; + async run() { const { args, flags } = this.parse(VrfCreate); verifyProgramHasPayer(this.program); diff --git a/libraries/sbv2-lite/tsconfig.json b/libraries/sbv2-lite/tsconfig.json index 6e6c6c4..4fb2bf5 100644 --- a/libraries/sbv2-lite/tsconfig.json +++ b/libraries/sbv2-lite/tsconfig.json @@ -7,6 +7,7 @@ "rootDir": "src", "skipLibCheck": true, "esModuleInterop": true, + "noEmit": false, "strict": true }, "include": ["src/**/*"], diff --git a/libraries/sbv2-utils/src/anchor/anchor.ts b/libraries/sbv2-utils/src/anchor.ts similarity index 98% rename from libraries/sbv2-utils/src/anchor/anchor.ts rename to libraries/sbv2-utils/src/anchor.ts index 34bde3c..a15f7c8 100644 --- a/libraries/sbv2-utils/src/anchor/anchor.ts +++ b/libraries/sbv2-utils/src/anchor.ts @@ -11,8 +11,8 @@ import { import fs from "fs"; import path from "path"; import toml from "toml"; -import { DEFAULT_KEYPAIR } from "../const"; -import { NoPayerKeypairProvided } from "../errors"; +import { DEFAULT_KEYPAIR } from "./const"; +import { NoPayerKeypairProvided } from "./errors"; export function programWallet(program: anchor.Program): Keypair { return ((program.provider as anchor.AnchorProvider).wallet as NodeWallet) diff --git a/libraries/sbv2-utils/src/anchor/index.ts b/libraries/sbv2-utils/src/anchor/index.ts deleted file mode 100644 index 44ca6fb..0000000 --- a/libraries/sbv2-utils/src/anchor/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./anchor"; diff --git a/libraries/sbv2-utils/src/math/big.ts b/libraries/sbv2-utils/src/big.ts similarity index 100% rename from libraries/sbv2-utils/src/math/big.ts rename to libraries/sbv2-utils/src/big.ts diff --git a/libraries/sbv2-utils/src/feeds.ts b/libraries/sbv2-utils/src/feeds.ts new file mode 100644 index 0000000..c45e419 --- /dev/null +++ b/libraries/sbv2-utils/src/feeds.ts @@ -0,0 +1,326 @@ +import * as anchor from "@project-serum/anchor"; +import * as spl from "@solana/spl-token"; +import { + Keypair, + PublicKey, + SystemProgram, + TransactionInstruction, +} from "@solana/web3.js"; +import { + AggregatorAccount, + CrankAccount, + JobAccount, + LeaseAccount, + OracleJob, + OracleQueueAccount, + PermissionAccount, + ProgramStateAccount, + SwitchboardDecimal, +} from "@switchboard-xyz/switchboard-v2"; +import type Big from "big.js"; + +interface CopyAggregatorParameters { + authority?: PublicKey; + minOracles?: number; + batchSize?: number; + minJobs?: number; + minUpdateDelay?: number; + forceReportPeriod?: number; + varianceThreshold?: Big; + crankKey?: PublicKey; +} + +export async function copyAggregatorTxn( + payerKeypair: Keypair, + sourceAggregatorAccount: AggregatorAccount, + targetQueue: OracleQueueAccount, + params: CopyAggregatorParameters +) { + // load source environment + const sourceAggregator = await sourceAggregatorAccount.loadData(); + const sourceJobPubkeys: PublicKey[] = sourceAggregator.jobPubkeysData.slice( + 0, + sourceAggregator.jobPubkeysSize + ); + const sourceJobAccounts = sourceJobPubkeys.map((publicKey) => { + return new JobAccount({ + program: sourceAggregatorAccount.program, + publicKey: publicKey, + }); + }); + const sourceJobs = await Promise.all( + sourceJobAccounts.map(async (jobAccount) => { + const data = await jobAccount.loadData(); + const job = OracleJob.decodeDelimited(data.data); + return { job, data }; + }) + ); + + const program = targetQueue.program; + + const [programStateAccount, stateBump] = + ProgramStateAccount.fromSeed(program); + const programState = await programStateAccount.loadData(); + const queue = await targetQueue.loadData(); + + const tokenMint = await targetQueue.loadMint(); + const tokenWallet = ( + await tokenMint.getOrCreateAssociatedAccountInfo(payerKeypair.publicKey) + ).address; + + const createAccountInstructions: ( + | TransactionInstruction + | TransactionInstruction[] + )[] = []; + const createAccountSigners: Keypair[] = [payerKeypair]; + + const jobAccounts = await Promise.all( + sourceJobs.map(async ({ job, data }) => { + const jobKeypair = Keypair.generate(); + createAccountSigners.push(jobKeypair); + + const jobData = Buffer.from( + OracleJob.encodeDelimited( + OracleJob.create({ + tasks: job.tasks, + }) + ).finish() + ); + const size = + 280 + jobData.length + (data.variables?.join("")?.length ?? 0); + + createAccountInstructions.push([ + SystemProgram.createAccount({ + fromPubkey: payerKeypair.publicKey, + newAccountPubkey: jobKeypair.publicKey, + space: size, + lamports: + await this.program.provider.connection.getMinimumBalanceForRentExemption( + size + ), + programId: this.program.programId, + }), + await this.program.methods + .jobInit({ + name: Buffer.from(data.name), + data: jobData, + variables: + data.variables?.map((item) => Buffer.from("")) ?? + new Array(), + authorWallet: payerKeypair.publicKey, + stateBump, + }) + .accounts({ + job: jobKeypair.publicKey, + authorWallet: tokenWallet, + authority: payerKeypair.publicKey, + programState: programStateAccount.publicKey, + }) + // .signers([jobKeypair]) + .instruction(), + ]); + + return new JobAccount({ + program: this.program, + publicKey: jobKeypair.publicKey, + }); + }) + ); + + const aggregatorKeypair = Keypair.generate(); + this.logger.debug(`Aggregator: ${aggregatorKeypair.publicKey}`); + createAccountSigners.push(aggregatorKeypair); + const aggregatorSize = this.program.account.aggregatorAccountData.size; + const permissionAccountSize = this.program.account.permissionAccountData.size; + const [permissionAccount, permissionBump] = PermissionAccount.fromSeed( + this.program, + queue.authority, + targetQueue.publicKey, + aggregatorKeypair.publicKey + ); + + const aggregatorAccount = new AggregatorAccount({ + program: this.program, + publicKey: aggregatorKeypair.publicKey, + }); + + // Create lease and push to crank + const [leaseAccount, leaseBump] = LeaseAccount.fromSeed( + this.program, + targetQueue, + aggregatorAccount + ); + const leaseEscrow = await spl.Token.getAssociatedTokenAddress( + spl.ASSOCIATED_TOKEN_PROGRAM_ID, + spl.TOKEN_PROGRAM_ID, + tokenMint.publicKey, + leaseAccount.publicKey, + true + ); + + const jobPubkeys: Array = []; + const jobWallets: Array = []; + const walletBumps: Array = []; + for (const idx in jobAccounts) { + const [jobWallet, bump] = anchor.utils.publicKey.findProgramAddressSync( + [ + payerKeypair.publicKey.toBuffer(), + spl.TOKEN_PROGRAM_ID.toBuffer(), + tokenMint.publicKey.toBuffer(), + ], + spl.ASSOCIATED_TOKEN_PROGRAM_ID + ); + jobPubkeys.push(jobAccounts[idx].publicKey); + jobWallets.push(jobWallet); + walletBumps.push(bump); + } + + createAccountInstructions.push( + [ + // allocate aggregator space + SystemProgram.createAccount({ + fromPubkey: payerKeypair.publicKey, + newAccountPubkey: aggregatorKeypair.publicKey, + space: aggregatorSize, + lamports: + await this.program.provider.connection.getMinimumBalanceForRentExemption( + aggregatorSize + ), + programId: this.program.programId, + }), + // create aggregator + await this.program.methods + .aggregatorInit({ + name: sourceAggregator.name, + metadata: sourceAggregator.metadata, + batchSize: + params.batchSize ?? sourceAggregator.oracleRequestBatchSize, + minOracleResults: + params.minOracles ?? sourceAggregator.minOracleResults, + minJobResults: params.minJobs ?? sourceAggregator.minJobResults, + minUpdateDelaySeconds: + params.minUpdateDelay ?? sourceAggregator.minUpdateDelaySeconds, + varianceThreshold: params.varianceThreshold + ? SwitchboardDecimal.fromBig(params.varianceThreshold) + : sourceAggregator.varianceThreshold, + forceReportPeriod: + params.forceReportPeriod ?? sourceAggregator.forceReportPeriod, + stateBump, + }) + .accounts({ + aggregator: aggregatorKeypair.publicKey, + authority: payerKeypair.publicKey, + queue: targetQueue.publicKey, + authorWallet: tokenWallet, + programState: programStateAccount.publicKey, + }) + .instruction(), + // create permissions + await this.program.methods + .permissionInit({}) + .accounts({ + permission: permissionAccount.publicKey, + authority: queue.authority, + granter: targetQueue.publicKey, + grantee: aggregatorKeypair.publicKey, + payer: payerKeypair.publicKey, + systemProgram: SystemProgram.programId, + }) + .instruction(), + payerKeypair.publicKey.equals(queue.authority) + ? await this.program.methods + .permissionSet({ + permission: { permitOracleQueueUsage: null }, + enable: true, + }) + .accounts({ + permission: permissionAccount.publicKey, + authority: queue.authority, + }) + .instruction() + : undefined, + spl.Token.createAssociatedTokenAccountInstruction( + spl.ASSOCIATED_TOKEN_PROGRAM_ID, + spl.TOKEN_PROGRAM_ID, + tokenMint.publicKey, + leaseEscrow, + leaseAccount.publicKey, + payerKeypair.publicKey + ), + await this.program.methods + .leaseInit({ + loadAmount: new anchor.BN(0), + stateBump, + leaseBump, + withdrawAuthority: payerKeypair.publicKey, + walletBumps: Buffer.from([]), + }) + .accounts({ + programState: programStateAccount.publicKey, + lease: leaseAccount.publicKey, + queue: targetQueue.publicKey, + aggregator: aggregatorAccount.publicKey, + systemProgram: SystemProgram.programId, + funder: tokenWallet, + payer: payerKeypair.publicKey, + tokenProgram: spl.TOKEN_PROGRAM_ID, + escrow: leaseEscrow, + owner: payerKeypair.publicKey, + mint: tokenMint.publicKey, + }) + // .remainingAccounts( + // jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => { + // return { isSigner: false, isWritable: true, pubkey }; + // }) + // ) + .instruction(), + params.crankKey + ? await this.program.methods + .crankPush({ + stateBump, + permissionBump, + }) + .accounts({ + crank: new PublicKey(params.crankKey), + aggregator: aggregatorAccount.publicKey, + oracleQueue: targetQueue.publicKey, + queueAuthority: queue.authority, + permission: permissionAccount.publicKey, + lease: leaseAccount.publicKey, + escrow: leaseEscrow, + programState: programStateAccount.publicKey, + dataBuffer: ( + await new CrankAccount({ + program: this.program, + publicKey: new PublicKey(params.crankKey), + }).loadData() + ).dataBuffer, + }) + .instruction() + : undefined, + ].filter((item) => item) + ); + + const finalInstructions: ( + | TransactionInstruction + | TransactionInstruction[] + )[] = []; + + finalInstructions.push( + ...(await Promise.all( + jobAccounts.map(async (jobAccount) => { + return this.program.methods + .aggregatorAddJob({ + weight: 1, + }) + .accounts({ + aggregator: aggregatorKeypair.publicKey, + authority: payerKeypair.publicKey, + job: jobAccount.publicKey, + }) + .instruction(); + }) + )) + ); + return ""; +} diff --git a/libraries/sbv2-utils/src/index.ts b/libraries/sbv2-utils/src/index.ts index ab57fc7..89286e0 100644 --- a/libraries/sbv2-utils/src/index.ts +++ b/libraries/sbv2-utils/src/index.ts @@ -1,9 +1,9 @@ export * from "./anchor"; export * from "./async"; +export * from "./big"; export * from "./const"; export * from "./date"; export * from "./errors"; -export * from "./math"; export * from "./nonce"; export * from "./print"; export * from "./solana"; diff --git a/libraries/sbv2-utils/src/instruction.ts b/libraries/sbv2-utils/src/instruction.ts new file mode 100644 index 0000000..2ea7d1d --- /dev/null +++ b/libraries/sbv2-utils/src/instruction.ts @@ -0,0 +1,98 @@ +import * as anchor from "@project-serum/anchor"; +import { + Keypair, + PublicKey, + SystemProgram, + TransactionInstruction, +} from "@solana/web3.js"; +import { + OracleJob, + ProgramStateAccount, + programWallet, +} from "@switchboard-xyz/switchboard-v2"; + +export interface SwitchboardInstructionResult { + ixns: (TransactionInstruction | Promise)[]; + signers: Keypair[]; +} + +export class SwitchboardTransaction { + program: anchor.Program; + + payerKeypair: Keypair; + + programStateAccount: ProgramStateAccount; + + // programState: Promise; + + // programMint: Promise; + + stateBump: number; + + constructor(program: anchor.Program) { + this.program = program; + this.payerKeypair = programWallet(program); + const [programStateAccount, stateBump] = + ProgramStateAccount.fromSeed(program); + this.programStateAccount = programStateAccount; + this.stateBump = stateBump; + // this.programState = programStateAccount.loadData(); + // this.programMint = programStateAccount.getTokenMint(); + } + + createInitJobInstruction( + job: OracleJob, + rentExemption: number, + authorWallet: PublicKey, + params: { + name?: string; + metadata?: string; + authority?: PublicKey; + expiration?: anchor.BN; + variables?: string[]; + } + ): SwitchboardInstructionResult { + const jobKeypair = Keypair.generate(); + const jobData = Buffer.from( + OracleJob.encodeDelimited( + OracleJob.create({ + tasks: job.tasks, + }) + ).finish() + ); + const size = + 280 + jobData.length + (params.variables?.join("")?.length ?? 0); + + const ixns: (TransactionInstruction | Promise)[] = [ + SystemProgram.createAccount({ + fromPubkey: this.payerKeypair.publicKey, + newAccountPubkey: jobKeypair.publicKey, + space: size, + lamports: rentExemption, + programId: this.program.programId, + }), + this.program.methods + .jobInit({ + name: Buffer.from(params.name ?? ""), + data: jobData, + variables: + params.variables?.map((item) => Buffer.from("")) ?? + new Array(), + stateBump: this.stateBump, + }) + .accounts({ + job: jobKeypair.publicKey, + authorWallet: authorWallet, + authority: this.payerKeypair.publicKey, + programState: this.programStateAccount.publicKey, + }) + // .signers([jobKeypair]) + .instruction(), + ]; + + return { + ixns, + signers: [jobKeypair], + }; + } +} diff --git a/libraries/sbv2-utils/src/math/index.ts b/libraries/sbv2-utils/src/math/index.ts deleted file mode 100644 index 7366376..0000000 --- a/libraries/sbv2-utils/src/math/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./big"; diff --git a/libraries/sbv2-utils/src/print.ts b/libraries/sbv2-utils/src/print.ts index 097a800..87304b9 100644 --- a/libraries/sbv2-utils/src/print.ts +++ b/libraries/sbv2-utils/src/print.ts @@ -65,6 +65,8 @@ export const toPermissionString = ( return "PERMIT_ORACLE_HEARTBEAT"; case SwitchboardPermissionValue.PERMIT_ORACLE_QUEUE_USAGE: return "PERMIT_ORACLE_QUEUE_USAGE"; + case SwitchboardPermissionValue.PERMIT_VRF_REQUESTS: + return "PERMIT_VRF_REQUESTS"; default: return "NONE"; } diff --git a/libraries/sbv2-utils/src/test/context.ts b/libraries/sbv2-utils/src/test/context.ts index 558d3f5..cc7d73b 100644 --- a/libraries/sbv2-utils/src/test/context.ts +++ b/libraries/sbv2-utils/src/test/context.ts @@ -1,6 +1,7 @@ /* eslint-disable @typescript-eslint/no-shadow */ /* eslint-disable @typescript-eslint/no-var-requires */ import * as anchor from "@project-serum/anchor"; +import type NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet"; import * as spl from "@solana/spl-token"; import { Keypair, PublicKey } from "@solana/web3.js"; import * as sbv2 from "@switchboard-xyz/switchboard-v2"; @@ -13,9 +14,9 @@ import { DEFAULT_PUBKEY, promiseWithTimeout } from "../"; export interface ISwitchboardTestContext { program: anchor.Program; mint: spl.Token; - tokenWallet: PublicKey; + payerTokenWallet: PublicKey; queue: sbv2.OracleQueueAccount; - oracle: sbv2.OracleAccount; + oracle?: sbv2.OracleAccount; } export class SwitchboardTestContext implements ISwitchboardTestContext { @@ -23,16 +24,16 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { mint: spl.Token; - tokenWallet: PublicKey; + payerTokenWallet: PublicKey; queue: sbv2.OracleQueueAccount; - oracle: sbv2.OracleAccount; + oracle?: sbv2.OracleAccount; constructor(ctx: ISwitchboardTestContext) { this.program = ctx.program; this.mint = ctx.mint; - this.tokenWallet = ctx.tokenWallet; + this.payerTokenWallet = ctx.payerTokenWallet; this.queue = ctx.queue; this.oracle = ctx.oracle; } @@ -52,6 +53,65 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { ); } + static async loadDevnetQueue( + provider: anchor.AnchorProvider, + queueKey = "F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy" + ) { + const payerKeypair = (provider.wallet as NodeWallet).payer; + let program: anchor.Program; + try { + program = await sbv2.loadSwitchboardProgram( + "devnet", + provider.connection, + payerKeypair + ); + } catch (error) { + throw new Error( + `Failed to load the SBV2 program for the given cluster, ${error.message}` + ); + } + let queue: sbv2.OracleQueueAccount; + let queueData: any; + try { + queue = new sbv2.OracleQueueAccount({ + program, + publicKey: new PublicKey(queueKey), + }); + queueData = await queue.loadData(); + if (queueData.queue.length < 1) { + throw new Error(`OracleQueue has no active oracles heartbeating`); + } + } catch (error) { + throw new Error( + `Failed to load the SBV2 queue for the given cluster, ${error.message}` + ); + } + let mint: spl.Token; + try { + mint = await queue.loadMint(); + } catch (error) { + throw new Error( + `Failed to load the SBV2 mint for the given cluster, ${error.message}` + ); + } + let payerTokenWallet: PublicKey; + try { + payerTokenWallet = ( + await mint.getOrCreateAssociatedAccountInfo(payerKeypair.publicKey) + ).address; + } catch (error) { + throw new Error( + `Failed to load the SBV2 mint for the given cluster, ${error.message}` + ); + } + return new SwitchboardTestContext({ + program, + queue, + mint, + payerTokenWallet, + }); + } + // public static async depositSwitchboardWallet( // program: anchor.Program, // wallet: PublicKey, @@ -141,8 +201,11 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { program: switchboardProgram, publicKey: SWITCHBOARD_QUEUE, }); + const queueData = await queue.loadData(); + if (queueData.queue.length < 1) { + throw new Error(`OracleQueue has no active oracles heartbeating`); + } - // TODO: Check oracle is heartbeating when context starts let oracle: sbv2.OracleAccount; if (process.env.ORACLE) { const SWITCHBOARD_ORACLE = new PublicKey(process.env.ORACLE); @@ -156,14 +219,13 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { sbv2.ProgramStateAccount.fromSeed(switchboardProgram); const switchboardMint = await switchboardProgramState.getTokenMint(); - const tokenWallet = await SwitchboardTestContext.createSwitchboardWallet( - switchboardProgram - ); + const payerTokenWallet = + await SwitchboardTestContext.createSwitchboardWallet(switchboardProgram); const context: ISwitchboardTestContext = { program: switchboardProgram, mint: switchboardMint, - tokenWallet, + payerTokenWallet, queue, oracle, }; @@ -187,7 +249,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { minRequiredOracleResults: 1, minUpdateDelaySeconds: 5, queueAccount: this.queue, - authorWallet: this.tokenWallet, + authorWallet: this.payerTokenWallet, } ); @@ -216,7 +278,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { // create lease contract const leaseAccount = await sbv2.LeaseAccount.create(this.program, { aggregatorAccount, - funder: this.tokenWallet, + funder: this.payerTokenWallet, funderAuthority: payerKeypair, loadAmount: new anchor.BN(0), oracleQueueAccount: this.queue, @@ -225,7 +287,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { // create and add job account const staticJob = await sbv2.JobAccount.create(this.program, { name: Buffer.from(`Value ${value}`), - authority: this.tokenWallet, + authority: this.payerTokenWallet, data: Buffer.from( sbv2.OracleJob.encodeDelimited( sbv2.OracleJob.create({ @@ -245,7 +307,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { // open new round and request new result await aggregatorAccount.openRound({ oracleQueueAccount: this.queue, - payoutWallet: this.tokenWallet, + payoutWallet: this.payerTokenWallet, }); return aggregatorAccount; @@ -339,7 +401,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext { await aggregatorAccount.openRound({ oracleQueueAccount: this.queue, - payoutWallet: this.tokenWallet, + payoutWallet: this.payerTokenWallet, }); await updatedValuePromise; diff --git a/libraries/sbv2-utils/tsconfig.json b/libraries/sbv2-utils/tsconfig.json index 43f4e17..37a7f26 100644 --- a/libraries/sbv2-utils/tsconfig.json +++ b/libraries/sbv2-utils/tsconfig.json @@ -10,7 +10,9 @@ "skipLibCheck": true, "esModuleInterop": true, "noImplicitReturns": false, + "importsNotUsedAsValues": "preserve", "strict": false, + "noEmit": false, "emitDeclarationOnly": false, "paths": { "@switchboard-xyz/switchboard-v2": ["../ts"] diff --git a/package.json b/package.json index 089aa61..55af73a 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,16 @@ }, "devDependencies": { "@gallynaut/rawrtools": "^0.0.1", + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "anchor-client-gen": "^0.24.0", + "chai": "^4.3.6", "lerna": "^4.0.0", + "mocha": "^10.0.0", "npm-run-all": "^4.1.5", + "shelljs": "^0.8.5", "shx": "^0.3.4", + "ts-mocha": "^10.0.0", "ts-node": "^10.7.0", "typedoc": "^0.22.15", "typescript": "^4.6.3" diff --git a/programs/anchor-feed-parser/.gitignore b/programs/anchor-feed-parser/.gitignore deleted file mode 100644 index 51448d4..0000000 --- a/programs/anchor-feed-parser/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules diff --git a/programs/anchor-feed-parser/Anchor.toml b/programs/anchor-feed-parser/Anchor.toml deleted file mode 100644 index b6a6eea..0000000 --- a/programs/anchor-feed-parser/Anchor.toml +++ /dev/null @@ -1,20 +0,0 @@ -[features] -seeds = false -[programs.localnet] -anchor_feed_parser = "3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5" - -[registry] -url = "https://anchor.projectserum.com" - -[provider] -cluster = "localnet" -wallet = "../../../payer-keypair.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" - -# Clone devnet SOL/USD feed -[test.validator] -url = "https://api.devnet.solana.com" -[[test.validator.clone]] -address="GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" \ No newline at end of file diff --git a/programs/anchor-feed-parser/Cargo.toml b/programs/anchor-feed-parser/Cargo.toml index a60de98..64848ba 100644 --- a/programs/anchor-feed-parser/Cargo.toml +++ b/programs/anchor-feed-parser/Cargo.toml @@ -1,4 +1,22 @@ -[workspace] -members = [ - "programs/*" -] +[package] +name = "anchor-feed-parser" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "anchor_feed_parser" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +switchboard-v2 = { path = "../../libraries/rs" } +# switchboard-v2 = "^0.1.10" +anchor-lang = "^0.24.2" +solana-program = "~1.9.13" \ No newline at end of file diff --git a/programs/anchor-feed-parser/programs/anchor-feed-parser/Xargo.toml b/programs/anchor-feed-parser/Xargo.toml similarity index 100% rename from programs/anchor-feed-parser/programs/anchor-feed-parser/Xargo.toml rename to programs/anchor-feed-parser/Xargo.toml diff --git a/programs/anchor-feed-parser/client/errors/anchor.ts b/programs/anchor-feed-parser/client/errors/anchor.ts new file mode 100644 index 0000000..06103a3 --- /dev/null +++ b/programs/anchor-feed-parser/client/errors/anchor.ts @@ -0,0 +1,690 @@ +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 +} diff --git a/programs/anchor-feed-parser/client/errors/index.ts b/programs/anchor-feed-parser/client/errors/index.ts new file mode 100644 index 0000000..d64e13e --- /dev/null +++ b/programs/anchor-feed-parser/client/errors/index.ts @@ -0,0 +1,52 @@ +import { PROGRAM_ID } from "../programId" +import * as anchor from "./anchor" + +export function fromCode(code: number): anchor.AnchorError | null { + return anchor.fromCode(code) +} + +function hasOwnProperty( + obj: X, + prop: Y +): obj is X & Record { + return Object.hasOwnProperty.call(obj, prop) +} + +const errorRe = /Program (\w+) failed: custom program error: (\w+)/ + +export function fromTxError(err: unknown): 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) +} diff --git a/programs/anchor-feed-parser/client/instructions/index.ts b/programs/anchor-feed-parser/client/instructions/index.ts new file mode 100644 index 0000000..fd6623b --- /dev/null +++ b/programs/anchor-feed-parser/client/instructions/index.ts @@ -0,0 +1 @@ +export { readResult, ReadResultAccounts } from "./readResult" diff --git a/programs/anchor-feed-parser/client/instructions/readResult.ts b/programs/anchor-feed-parser/client/instructions/readResult.ts new file mode 100644 index 0000000..825cc97 --- /dev/null +++ b/programs/anchor-feed-parser/client/instructions/readResult.ts @@ -0,0 +1,16 @@ +import { PublicKey, TransactionInstruction } from "@solana/web3.js" // eslint-disable-line @typescript-eslint/no-unused-vars +import { PROGRAM_ID } from "../programId" + +export interface ReadResultAccounts { + aggregator: PublicKey +} + +export function readResult(accounts: ReadResultAccounts) { + const keys = [ + { pubkey: accounts.aggregator, isSigner: false, isWritable: false }, + ] + const identifier = Buffer.from([130, 229, 115, 203, 180, 191, 240, 90]) + const data = identifier + const ix = new TransactionInstruction({ keys, programId: PROGRAM_ID, data }) + return ix +} diff --git a/programs/anchor-feed-parser/client/programId.ts b/programs/anchor-feed-parser/client/programId.ts new file mode 100644 index 0000000..8d5386d --- /dev/null +++ b/programs/anchor-feed-parser/client/programId.ts @@ -0,0 +1,9 @@ +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( + "H7frfaL4ZjRW6NAyBvuGgsi9P2G1CgVgqFqzFSDS521f" +) + +// 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 diff --git a/programs/anchor-feed-parser/package.json b/programs/anchor-feed-parser/package.json index 64642d8..752c398 100644 --- a/programs/anchor-feed-parser/package.json +++ b/programs/anchor-feed-parser/package.json @@ -8,23 +8,15 @@ "directory": "programs/anchor-feed-parser" }, "scripts": { - "generate:api": "ts-node solita", - "build": "anchor build && yarn run generate:api && yarn run pid", - "pid": "shx echo \"\n\nPROGRAM ID: \"$(solana-keygen pubkey target/deploy/anchor_feed_parser-keypair.json) \"\n\nUpdate Anchor.toml and src/lib.rs with your PID above.\" || exit 0", - "lint": "eslint --ext .js,.json,.ts 'src/**' --fix", - "test": "anchor test", - "anchor:test": "anchor test --skip-local-validator" + "build": "echo \"For workspace anchor-feed-parser, run 'anchor build' from the project root\" && exit 0", + "lint": "eslint --ext .js,.json,.ts 'src/**' --fix" }, "dependencies": { - "@metaplex-foundation/beet": "^0.1.0", - "@metaplex-foundation/beet-solana": "^0.1.1", - "@metaplex-foundation/solita": "^0.2.1", "@project-serum/anchor": "^0.24.2", - "@switchboard-xyz/switchboard-v2": "^0.0.95", - "@solana/web3.js": "^1.37.1" + "@solana/web3.js": "^1.37.1", + "@switchboard-xyz/switchboard-v2": "^0.0.95" }, "devDependencies": { - "@metaplex-foundation/solita": "^0.2.1", "@types/chai": "^4.3.0", "@types/mocha": "^9.1.0", "chai": "^4.3.4", diff --git a/programs/anchor-feed-parser/programs/anchor-feed-parser/Cargo.toml b/programs/anchor-feed-parser/programs/anchor-feed-parser/Cargo.toml deleted file mode 100644 index 70cf79f..0000000 --- a/programs/anchor-feed-parser/programs/anchor-feed-parser/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "anchor-feed-parser" -version = "0.1.0" -description = "Created with Anchor" -edition = "2018" - -[lib] -crate-type = ["cdylib", "lib"] -name = "anchor_feed_parser" - -[features] -no-entrypoint = [] -no-idl = [] -no-log-ix-name = [] -cpi = ["no-entrypoint"] -default = [] - -[dependencies] -anchor-lang = "^0.24.2" -switchboard-v2 = "^0.1.10" -solana-program = "~1.9.13" \ No newline at end of file diff --git a/programs/anchor-feed-parser/scripts/generate.ts b/programs/anchor-feed-parser/scripts/generate.ts deleted file mode 100644 index b6f59a9..0000000 --- a/programs/anchor-feed-parser/scripts/generate.ts +++ /dev/null @@ -1,52 +0,0 @@ -const PROGRAM_NAME = "anchor_feed_parser"; -const PROGRAM_ID = "3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5"; - -import { Solita } from "@metaplex-foundation/solita"; -import { spawn } from "child_process"; -import { writeFile } from "fs/promises"; -import * as path from "path"; - -const programDir = path.join(__dirname, ".."); -const generatedIdlDir = path.join(__dirname, "..", "target", "idl"); -const generatedSDKDir = path.join(__dirname, "..", "src", "generated"); - -const anchor = spawn("anchor", ["build", "--idl", generatedIdlDir], { - cwd: programDir, -}) - .on("error", (err) => { - console.error(err); - // @ts-ignore this err does have a code - if (err.code === "ENOENT") { - console.error( - "Ensure that `anchor` is installed and in your path, see:\n https://project-serum.github.io/anchor/getting-started/installation.html#install-anchor\n" - ); - } - process.exit(1); - }) - .on("exit", () => { - console.log( - "IDL written to: %s", - path.join(generatedIdlDir, `${PROGRAM_NAME}.json`) - ); - generateTypeScriptSDK(); - }); - -anchor.stdout.on("data", (buf) => console.log(buf.toString("utf8"))); -anchor.stderr.on("data", (buf) => console.error(buf.toString("utf8"))); - -async function generateTypeScriptSDK() { - console.error("Generating TypeScript SDK to %s", generatedSDKDir); - const generatedIdlPath = path.join(generatedIdlDir, `${PROGRAM_NAME}.json`); - - const idl = require(generatedIdlPath); - if (idl.metadata?.address == null) { - idl.metadata = { ...idl.metadata, address: PROGRAM_ID }; - await writeFile(generatedIdlPath, JSON.stringify(idl, null, 2)); - } - const gen = new Solita(idl, { formatCode: true }); - await gen.renderAndWriteTo(generatedSDKDir); - - console.error("Success!"); - - process.exit(0); -} diff --git a/programs/anchor-feed-parser/solita.ts b/programs/anchor-feed-parser/solita.ts deleted file mode 100644 index 58cc0b2..0000000 --- a/programs/anchor-feed-parser/solita.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable unicorn/no-process-exit */ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -/* eslint-disable unicorn/prevent-abbreviations */ -/* eslint-disable unicorn/prefer-module */ -const PROGRAM_NAME = "anchor_feed_parser"; -const PROGRAM_ID = "3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5"; - -import { Solita } from "@metaplex-foundation/solita"; -import { spawn } from "child_process"; -import { writeFile } from "fs/promises"; -import path from "path"; -const programDir = path.join(__dirname, "programs"); -const generatedIdlDir = path.join(__dirname, "target", "idl"); -const generatedSDKDir = path.join(__dirname, "src", "generated"); - -const anchor = spawn("anchor", ["build", "--idl", generatedIdlDir], { - cwd: programDir, -}) - .on("error", (err) => { - console.error(err); - // @ts-ignore this err does have a code - if (err.code === "ENOENT") { - console.error( - "Ensure that `anchor` is installed and in your path, see:\n https://project-serum.github.io/anchor/getting-started/installation.html#install-anchor\n" - ); - } - process.exit(1); - }) - .on("exit", () => { - console.log( - "IDL written to: %s", - path.join(generatedIdlDir, `${PROGRAM_NAME}.json`) - ); - generateTypeScriptSDK(); - }); - -anchor.stdout.on("data", (buf) => console.log(buf.toString("utf8"))); -anchor.stderr.on("data", (buf) => console.error(buf.toString("utf8"))); - -async function generateTypeScriptSDK() { - console.error("Generating TypeScript SDK to %s", generatedSDKDir); - const generatedIdlPath = path.join(generatedIdlDir, `${PROGRAM_NAME}.json`); - - // eslint-disable-next-line @typescript-eslint/no-var-requires - const idl = require(generatedIdlPath); - if (idl.metadata?.address == undefined) { - idl.metadata = { ...idl.metadata, address: PROGRAM_ID }; - await writeFile(generatedIdlPath, JSON.stringify(idl, undefined, 2)); - } - const gen = new Solita(idl, { formatCode: true }); - await gen.renderAndWriteTo(generatedSDKDir); - - console.error("Success!"); - - process.exit(0); -} - -export {}; diff --git a/programs/anchor-feed-parser/src/generated/index.ts b/programs/anchor-feed-parser/src/generated/index.ts deleted file mode 100644 index 9569f98..0000000 --- a/programs/anchor-feed-parser/src/generated/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { PublicKey } from '@solana/web3.js' -export * from './instructions' - -/** - * Program address - * - * @category constants - * @category generated - */ -export const PROGRAM_ADDRESS = '3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5' - -/** - * Program publick key - * - * @category constants - * @category generated - */ -export const PROGRAM_ID = new PublicKey(PROGRAM_ADDRESS) diff --git a/programs/anchor-feed-parser/src/generated/instructions/index.ts b/programs/anchor-feed-parser/src/generated/instructions/index.ts deleted file mode 100644 index cc925b6..0000000 --- a/programs/anchor-feed-parser/src/generated/instructions/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './readResult'; \ No newline at end of file diff --git a/programs/anchor-feed-parser/src/generated/instructions/readResult.ts b/programs/anchor-feed-parser/src/generated/instructions/readResult.ts deleted file mode 100644 index bf97c40..0000000 --- a/programs/anchor-feed-parser/src/generated/instructions/readResult.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from '@metaplex-foundation/beet' -import * as web3 from '@solana/web3.js' - -/** - * @category Instructions - * @category ReadResult - * @category generated - */ -const readResultStruct = new beet.BeetArgsStruct<{ - instructionDiscriminator: number[] /* size: 8 */ -}>( - [['instructionDiscriminator', beet.uniformFixedSizeArray(beet.u8, 8)]], - 'ReadResultInstructionArgs' -) -/** - * Accounts required by the _readResult_ instruction - * @category Instructions - * @category ReadResult - * @category generated - */ -export type ReadResultInstructionAccounts = { - aggregator: web3.PublicKey -} - -const readResultInstructionDiscriminator = [ - 130, 229, 115, 203, 180, 191, 240, 90, -] - -/** - * Creates a _ReadResult_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * - * @category Instructions - * @category ReadResult - * @category generated - */ -export function createReadResultInstruction( - accounts: ReadResultInstructionAccounts -) { - const { aggregator } = accounts - - const [data] = readResultStruct.serialize({ - instructionDiscriminator: readResultInstructionDiscriminator, - }) - const keys: web3.AccountMeta[] = [ - { - pubkey: aggregator, - isWritable: false, - isSigner: false, - }, - ] - - const ix = new web3.TransactionInstruction({ - programId: new web3.PublicKey( - '3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5' - ), - keys, - data, - }) - return ix -} diff --git a/programs/anchor-feed-parser/src/index.ts b/programs/anchor-feed-parser/src/index.ts deleted file mode 100644 index e84c86c..0000000 --- a/programs/anchor-feed-parser/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./generated"; diff --git a/programs/anchor-feed-parser/programs/anchor-feed-parser/src/lib.rs b/programs/anchor-feed-parser/src/lib.rs similarity index 91% rename from programs/anchor-feed-parser/programs/anchor-feed-parser/src/lib.rs rename to programs/anchor-feed-parser/src/lib.rs index c9ad2a0..365e85f 100644 --- a/programs/anchor-feed-parser/programs/anchor-feed-parser/src/lib.rs +++ b/programs/anchor-feed-parser/src/lib.rs @@ -3,7 +3,7 @@ use anchor_lang::prelude::*; use std::convert::TryInto; pub use switchboard_v2::AggregatorAccountData; -declare_id!("3Y2v9gVaFAKTDqcxxs8oSRWV8K9ctkCB8yiC6KA4sFz5"); +declare_id!("H7frfaL4ZjRW6NAyBvuGgsi9P2G1CgVgqFqzFSDS521f"); #[derive(Accounts)] pub struct ReadResult<'info> { diff --git a/programs/anchor-feed-parser/tests/anchor-feed-parser.ts b/programs/anchor-feed-parser/tests/anchor-feed-parser.ts index 9e43086..a5ba4e8 100644 --- a/programs/anchor-feed-parser/tests/anchor-feed-parser.ts +++ b/programs/anchor-feed-parser/tests/anchor-feed-parser.ts @@ -2,32 +2,30 @@ import type { Program } from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor"; import { PublicKey } from "@solana/web3.js"; import { SwitchboardTestContext } from "@switchboard-xyz/switchboard-v2"; -import { createReadResultInstruction } from "../src"; -import type { AnchorFeedParser } from "../target/types/anchor_feed_parser"; +import type { AnchorFeedParser } from "../../../target/types/anchor_feed_parser"; const sleep = (ms: number): Promise => new Promise((s) => setTimeout(s, ms)); +// Anchor.toml will copy this to localnet when we start our tests const DEFAULT_SOL_USD_FEED = new PublicKey( "GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" ); - +console.log("checking1"); describe("anchor-feed-parser", () => { - const provider = anchor.AnchorProvider.env(); - anchor.setProvider(provider); + anchor.setProvider(anchor.AnchorProvider.env()); - const program = anchor.workspace + const feedParserProgram = anchor.workspace .AnchorFeedParser as Program; + const provider = feedParserProgram.provider as anchor.AnchorProvider; let aggregatorKey: PublicKey; - const connection = new anchor.web3.Connection( - provider.connection.rpcEndpoint, - { commitment: "finalized" } - ); - before(async () => { - const accountInfo = await connection.getAccountInfo(DEFAULT_SOL_USD_FEED); + console.log("checking"); + const accountInfo = await provider.connection.getAccountInfo( + DEFAULT_SOL_USD_FEED + ); if (accountInfo) { aggregatorKey = DEFAULT_SOL_USD_FEED; return; @@ -52,21 +50,10 @@ describe("anchor-feed-parser", () => { }); it("Read SOL/USD Feed", async () => { - const instruction = createReadResultInstruction({ - aggregator: aggregatorKey, - }); - - const transaction = new anchor.web3.Transaction(); - transaction.add(instruction); - - const tx = await provider.sendAndConfirm(transaction); - - // // Using Anchor Program to send transaction - // const tx = await program.rpc.readResult({ - // accounts: { - // aggregator: aggregatorKey, - // }, - // }); + const tx = await feedParserProgram.methods + .readResult() + .accounts({ aggregator: aggregatorKey }) + .rpc(); // wait for RPC await sleep(2000); diff --git a/programs/anchor-feed-parser/tsconfig.json b/programs/anchor-feed-parser/tsconfig.json index 3e817d2..4488d76 100644 --- a/programs/anchor-feed-parser/tsconfig.json +++ b/programs/anchor-feed-parser/tsconfig.json @@ -6,12 +6,11 @@ "lib": ["es2015"], "module": "commonjs", "target": "es6", + "noEmit": true, "esModuleInterop": true, "paths": { "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"] } }, - "include": ["tests/**/*"], - "exclude": ["target"], "references": [{ "path": "../../libraries/ts" }] } diff --git a/programs/anchor-vrf-parser/.gitignore b/programs/anchor-vrf-parser/.gitignore deleted file mode 100644 index 51448d4..0000000 --- a/programs/anchor-vrf-parser/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules diff --git a/programs/anchor-vrf-parser/Anchor.toml b/programs/anchor-vrf-parser/Anchor.toml deleted file mode 100644 index d934b34..0000000 --- a/programs/anchor-vrf-parser/Anchor.toml +++ /dev/null @@ -1,14 +0,0 @@ -[programs.localnet] -anchor_vrf_parser = "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib" - -[registry] -url = "https://anchor.projectserum.com" - -[provider] -cluster = "devnet" -wallet = "../../../payer-keypair.json" -# cluster = "devnet" -# wallet = "secrets/payer-keypair.json" - -[scripts] -test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.test.ts" diff --git a/programs/anchor-vrf-parser/Cargo.toml b/programs/anchor-vrf-parser/Cargo.toml index 7aa6203..dfd26fa 100644 --- a/programs/anchor-vrf-parser/Cargo.toml +++ b/programs/anchor-vrf-parser/Cargo.toml @@ -1,4 +1,24 @@ -[workspace] -members = [ - "programs/*" -] \ No newline at end of file +[package] +name = "anchor-vrf-parser" +version = "0.1.0" +description = "Created with Anchor" +edition = "2018" + +[lib] +crate-type = ["cdylib", "lib"] +name = "anchor_vrf_parser" + +[features] +no-entrypoint = [] +no-idl = [] +no-log-ix-name = [] +cpi = ["no-entrypoint"] +default = [] + +[dependencies] +switchboard-v2 = { path = "../../libraries/rs" } +# switchboard-v2 = "^0.1.10" +anchor-lang = "^0.24.2" +anchor-spl = "^0.24.2" +solana-program = "~1.9.13" +bytemuck = "1.7.2" diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/Xargo.toml b/programs/anchor-vrf-parser/Xargo.toml similarity index 100% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/Xargo.toml rename to programs/anchor-vrf-parser/Xargo.toml diff --git a/programs/anchor-vrf-parser/client/accounts/VrfClient.ts b/programs/anchor-vrf-parser/client/accounts/VrfClient.ts new file mode 100644 index 0000000..e337213 --- /dev/null +++ b/programs/anchor-vrf-parser/client/accounts/VrfClient.ts @@ -0,0 +1,134 @@ +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 + result: BN + lastTimestamp: BN + authority: PublicKey + vrf: PublicKey +} + +export interface VrfClientJSON { + bump: number + maxResult: string + resultBuffer: Array + result: string + lastTimestamp: string + authority: string + vrf: string +} + +export class VrfClient { + readonly bump: number + readonly maxResult: BN + readonly resultBuffer: Array + 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, + address: PublicKey + ): Promise { + 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> { + 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), + }) + } +} diff --git a/programs/anchor-vrf-parser/client/accounts/index.ts b/programs/anchor-vrf-parser/client/accounts/index.ts new file mode 100644 index 0000000..668dc91 --- /dev/null +++ b/programs/anchor-vrf-parser/client/accounts/index.ts @@ -0,0 +1 @@ +export { VrfClient, VrfClientFields, VrfClientJSON } from "./VrfClient" diff --git a/programs/anchor-vrf-parser/client/errors/anchor.ts b/programs/anchor-vrf-parser/client/errors/anchor.ts new file mode 100644 index 0000000..06103a3 --- /dev/null +++ b/programs/anchor-vrf-parser/client/errors/anchor.ts @@ -0,0 +1,690 @@ +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 +} diff --git a/programs/anchor-vrf-parser/client/errors/custom.ts b/programs/anchor-vrf-parser/client/errors/custom.ts new file mode 100644 index 0000000..2ee36e2 --- /dev/null +++ b/programs/anchor-vrf-parser/client/errors/custom.ts @@ -0,0 +1,60 @@ +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 +} diff --git a/programs/anchor-vrf-parser/client/errors/index.ts b/programs/anchor-vrf-parser/client/errors/index.ts new file mode 100644 index 0000000..0772c1c --- /dev/null +++ b/programs/anchor-vrf-parser/client/errors/index.ts @@ -0,0 +1,57 @@ +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( + obj: X, + prop: Y +): obj is X & Record { + 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) +} diff --git a/programs/anchor-vrf-parser/client/instructions/index.ts b/programs/anchor-vrf-parser/client/instructions/index.ts new file mode 100644 index 0000000..c645fe6 --- /dev/null +++ b/programs/anchor-vrf-parser/client/instructions/index.ts @@ -0,0 +1,7 @@ +export { initState, InitStateAccounts, InitStateArgs } from "./initState" +export { + requestResult, + RequestResultAccounts, + RequestResultArgs, +} from "./requestResult" +export { updateResult, UpdateResultAccounts } from "./updateResult" diff --git a/programs/anchor-vrf-parser/client/instructions/initState.ts b/programs/anchor-vrf-parser/client/instructions/initState.ts new file mode 100644 index 0000000..af4d92a --- /dev/null +++ b/programs/anchor-vrf-parser/client/instructions/initState.ts @@ -0,0 +1,39 @@ +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 +} diff --git a/programs/anchor-vrf-parser/client/instructions/requestResult.ts b/programs/anchor-vrf-parser/client/instructions/requestResult.ts new file mode 100644 index 0000000..84386f6 --- /dev/null +++ b/programs/anchor-vrf-parser/client/instructions/requestResult.ts @@ -0,0 +1,60 @@ +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 +} diff --git a/programs/anchor-vrf-parser/client/instructions/updateResult.ts b/programs/anchor-vrf-parser/client/instructions/updateResult.ts new file mode 100644 index 0000000..af5c411 --- /dev/null +++ b/programs/anchor-vrf-parser/client/instructions/updateResult.ts @@ -0,0 +1,18 @@ +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 +} diff --git a/programs/anchor-vrf-parser/client/programId.ts b/programs/anchor-vrf-parser/client/programId.ts new file mode 100644 index 0000000..6058a2e --- /dev/null +++ b/programs/anchor-vrf-parser/client/programId.ts @@ -0,0 +1,9 @@ +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( + "HWCUJF1GgCrS1fWNyJdWSBEVNXtdjRwQy7HohdQ5n31o" +) + +// 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 diff --git a/programs/anchor-vrf-parser/client/types/InitStateParams.ts b/programs/anchor-vrf-parser/client/types/InitStateParams.ts new file mode 100644 index 0000000..72a2508 --- /dev/null +++ b/programs/anchor-vrf-parser/client/types/InitStateParams.ts @@ -0,0 +1,51 @@ +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) + } +} diff --git a/programs/anchor-vrf-parser/client/types/RequestResultParams.ts b/programs/anchor-vrf-parser/client/types/RequestResultParams.ts new file mode 100644 index 0000000..d021a5c --- /dev/null +++ b/programs/anchor-vrf-parser/client/types/RequestResultParams.ts @@ -0,0 +1,61 @@ +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) + } +} diff --git a/programs/anchor-vrf-parser/client/types/index.ts b/programs/anchor-vrf-parser/client/types/index.ts new file mode 100644 index 0000000..a2352e6 --- /dev/null +++ b/programs/anchor-vrf-parser/client/types/index.ts @@ -0,0 +1,10 @@ +export { + InitStateParams, + InitStateParamsFields, + InitStateParamsJSON, +} from "./InitStateParams" +export { + RequestResultParams, + RequestResultParamsFields, + RequestResultParamsJSON, +} from "./RequestResultParams" diff --git a/programs/anchor-vrf-parser/package.json b/programs/anchor-vrf-parser/package.json index d8befd9..028cb88 100644 --- a/programs/anchor-vrf-parser/package.json +++ b/programs/anchor-vrf-parser/package.json @@ -8,25 +8,14 @@ "directory": "programs/anchor-vrf-parser" }, "scripts": { - "generate:api": "ts-node solita", - "pid": "shx echo \"\n\nPROGRAM ID: \"$(solana-keygen pubkey target/deploy/anchor_vrf_parser-keypair.json) \"\n\nUpdate Anchor.toml, src/lib.rs, and solita.ts with your PID above.\" || exit 0", - "setup:authority": "run-s create:authority airdrop:authority", - "setup:switchboard": "sbv2 localnet:env --keypair secrets/payer-keypair.json", - "create:authority": "shx find secrets/payer-keypair.json || solana-keygen new -s --no-bip39-passphrase --outfile secrets/payer-keypair.json", - "airdrop": "solana airdrop 1 secrets/payer-keypair.json", - "airdrop:authority": "run-s airdrop && run-s airdrop && run-s airdrop && run-s airdrop || true", - "build": "rm -rf lib && tsc -p tsconfig.json", - "lint": "eslint --ext .js,.json,.ts 'src/**' --fix", - "anchor:test": "anchor test --skip-local-validator", - "test": "echo \"For workspace anchor-vrf-parser, use the anchor:test script\" && exit 0" + "build": "echo \"For workspace anchor-vrf-parser, run 'anchor build' from the project root\" && exit 0", + "lint": "eslint --ext .js,.json,.ts 'src/**' --fix" }, "dependencies": { - "@metaplex-foundation/beet": "^0.1.0", - "@metaplex-foundation/beet-solana": "^0.1.1", - "@metaplex-foundation/solita": "^0.2.1", "@project-serum/anchor": "^0.24.2", "@solana/spl-token": "^0.1.8", - "@solana/web3.js": "^1.33.0", + "@solana/web3.js": "^1.42.0", + "@switchboard-xyz/sbv2-utils": "^0.0.10", "@switchboard-xyz/switchboard-v2": "^0.0.95", "chalk": "^4.1.2", "child_process": "^1.0.2", diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/Cargo.toml b/programs/anchor-vrf-parser/programs/anchor-vrf-parser/Cargo.toml deleted file mode 100644 index 67c3aa6..0000000 --- a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/Cargo.toml +++ /dev/null @@ -1,23 +0,0 @@ -[package] -name = "anchor-vrf-parser" -version = "0.1.0" -description = "Created with Anchor" -edition = "2018" - -[lib] -crate-type = ["cdylib", "lib"] -name = "anchor_vrf_parser" - -[features] -no-entrypoint = [] -no-idl = [] -no-log-ix-name = [] -cpi = ["no-entrypoint"] -default = [] - -[dependencies] -anchor-lang = "^0.24.2" -anchor-spl = "^0.24.2" -solana-program = "~1.9.13" -switchboard-v2 = "^0.1.10" -bytemuck = "1.7.2" diff --git a/programs/anchor-vrf-parser/scripts/generate.ts b/programs/anchor-vrf-parser/scripts/generate.ts deleted file mode 100644 index 7cddad5..0000000 --- a/programs/anchor-vrf-parser/scripts/generate.ts +++ /dev/null @@ -1,55 +0,0 @@ -const PROGRAM_NAME = "anchor_vrf_parser"; -const PROGRAM_ID = "7PoPs442NYqZwfrFhMuVDTzpWfaZi8dCtRFwqydnj5Gt"; - -import { Solita } from "@metaplex-foundation/solita"; -import { spawn } from "child_process"; -import { writeFile } from "fs/promises"; -import * as path from "path"; - -const programDir = path.join(__dirname, ".."); -// console.log(`programDir ${programDir}`); -const generatedIdlDir = path.join(__dirname, "..", "target", "idl"); -// console.log(`generatedIdlDir ${generatedIdlDir}`); -const generatedSDKDir = path.join(__dirname, "..", "src", "generated"); -// console.log(`generatedSDKDir ${generatedSDKDir}`); - -const anchor = spawn("anchor", ["build", "--idl", generatedIdlDir], { - cwd: programDir, -}) - .on("error", (err) => { - console.error(err); - // @ts-ignore this err does have a code - if (err.code === "ENOENT") { - console.error( - "Ensure that `anchor` is installed and in your path, see:\n https://project-serum.github.io/anchor/getting-started/installation.html#install-anchor\n" - ); - } - process.exit(1); - }) - .on("exit", () => { - console.log( - "IDL written to: %s", - path.join(generatedIdlDir, `${PROGRAM_NAME}.json`) - ); - generateTypeScriptSDK(); - }); - -anchor.stdout.on("data", (buf) => console.log(buf.toString("utf8"))); -anchor.stderr.on("data", (buf) => console.error(buf.toString("utf8"))); - -async function generateTypeScriptSDK() { - console.error("Generating TypeScript SDK to %s", generatedSDKDir); - const generatedIdlPath = path.join(generatedIdlDir, `${PROGRAM_NAME}.json`); - - const idl = require(generatedIdlPath); - if (idl.metadata?.address == null) { - idl.metadata = { ...idl.metadata, address: PROGRAM_ID }; - await writeFile(generatedIdlPath, JSON.stringify(idl, null, 2)); - } - const gen = new Solita(idl, { formatCode: true }); - await gen.renderAndWriteTo(generatedSDKDir); - - console.error("Success!"); - - process.exit(0); -} diff --git a/programs/anchor-vrf-parser/solita.ts b/programs/anchor-vrf-parser/solita.ts deleted file mode 100644 index 862d410..0000000 --- a/programs/anchor-vrf-parser/solita.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* eslint-disable unicorn/no-process-exit */ -/* eslint-disable @typescript-eslint/ban-ts-comment */ -/* eslint-disable unicorn/prevent-abbreviations */ -/* eslint-disable unicorn/prefer-module */ -const PROGRAM_NAME = "anchor_vrf_parser"; -const PROGRAM_ID = "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib"; - -import { Solita } from "@metaplex-foundation/solita"; -import { spawn } from "child_process"; -import { writeFile } from "fs/promises"; -import path from "path"; -const programDir = path.join(__dirname, "programs"); -const generatedIdlDir = path.join(__dirname, "target", "idl"); -const generatedSDKDir = path.join(__dirname, "src", "generated"); - -const anchor = spawn("anchor", ["build", "--idl", generatedIdlDir], { - cwd: programDir, -}) - .on("error", (err) => { - console.error(err); - // @ts-ignore this err does have a code - if (err.code === "ENOENT") { - console.error( - "Ensure that `anchor` is installed and in your path, see:\n https://project-serum.github.io/anchor/getting-started/installation.html#install-anchor\n" - ); - } - process.exit(1); - }) - .on("exit", () => { - console.log( - "IDL written to: %s", - path.join(generatedIdlDir, `${PROGRAM_NAME}.json`) - ); - generateTypeScriptSDK(); - }); - -anchor.stdout.on("data", (buf) => console.log(buf.toString("utf8"))); -anchor.stderr.on("data", (buf) => console.error(buf.toString("utf8"))); - -async function generateTypeScriptSDK() { - console.error("Generating TypeScript SDK to %s", generatedSDKDir); - const generatedIdlPath = path.join(generatedIdlDir, `${PROGRAM_NAME}.json`); - - // eslint-disable-next-line @typescript-eslint/no-var-requires - const idl = require(generatedIdlPath); - if (idl.metadata?.address == undefined) { - idl.metadata = { ...idl.metadata, address: PROGRAM_ID }; - await writeFile(generatedIdlPath, JSON.stringify(idl, undefined, 2)); - } - const gen = new Solita(idl, { formatCode: true }); - await gen.renderAndWriteTo(generatedSDKDir); - - console.error("Success!"); - - process.exit(0); -} - -export {}; diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/init_state.rs b/programs/anchor-vrf-parser/src/actions/init_state.rs similarity index 100% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/init_state.rs rename to programs/anchor-vrf-parser/src/actions/init_state.rs diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/mod.rs b/programs/anchor-vrf-parser/src/actions/mod.rs similarity index 100% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/mod.rs rename to programs/anchor-vrf-parser/src/actions/mod.rs diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/request_result.rs b/programs/anchor-vrf-parser/src/actions/request_result.rs similarity index 100% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/request_result.rs rename to programs/anchor-vrf-parser/src/actions/request_result.rs diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/update_result.rs b/programs/anchor-vrf-parser/src/actions/update_result.rs similarity index 91% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/update_result.rs rename to programs/anchor-vrf-parser/src/actions/update_result.rs index f5ea315..97fbdd3 100644 --- a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/actions/update_result.rs +++ b/programs/anchor-vrf-parser/src/actions/update_result.rs @@ -13,6 +13,8 @@ pub struct UpdateResult<'info> { impl UpdateResult<'_> { pub fn validate(&self, _ctx: &Context) -> Result<()> { + // We should check VRF account passed is equal to the pubkey stored in our client state + // But skipping so we can re-use this program instruction for CI testing Ok(()) } diff --git a/programs/anchor-vrf-parser/src/api.ts b/programs/anchor-vrf-parser/src/api.ts deleted file mode 100644 index 55660f3..0000000 --- a/programs/anchor-vrf-parser/src/api.ts +++ /dev/null @@ -1,39 +0,0 @@ -import * as anchor from "@project-serum/anchor"; -import type { PublicKey } from "@solana/web3.js"; -import type { Callback } from "@switchboard-xyz/switchboard-v2"; - -export function getVrfClientFromSeed( - program: anchor.Program, - vrfPubkey: PublicKey, - authority: PublicKey -): [PublicKey, number] { - const [statePubkey, stateBump] = - anchor.utils.publicKey.findProgramAddressSync( - [Buffer.from("STATE"), vrfPubkey.toBytes(), authority.toBytes()], - program.programId - ); - return [statePubkey, stateBump]; -} - -export function getVrfClientCallback( - vrfClientProgram: anchor.Program, - clientKey: PublicKey, - vrfKey: PublicKey -): Callback { - const vrfIxCoder = new anchor.BorshInstructionCoder(vrfClientProgram.idl); - const callback: Callback = { - programId: vrfClientProgram.programId, - accounts: [ - // ensure all accounts in updateResult are populated - { pubkey: clientKey, isSigner: false, isWritable: true }, - { pubkey: vrfKey, isSigner: false, isWritable: false }, - ], - ixData: vrfIxCoder.encode("updateResult", ""), // pass any params for instruction here - }; - return callback; -} - -// export async function createVrfClient( -// switchboardProgram: anchor.Program, -// vrfKeypair: Keypair -// ): Promise {} diff --git a/programs/anchor-vrf-parser/src/generated/accounts/VrfClient.ts b/programs/anchor-vrf-parser/src/generated/accounts/VrfClient.ts deleted file mode 100644 index 82806ba..0000000 --- a/programs/anchor-vrf-parser/src/generated/accounts/VrfClient.ts +++ /dev/null @@ -1,179 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as beetSolana from "@metaplex-foundation/beet-solana"; -import * as web3 from "@solana/web3.js"; - -/** - * Arguments used to create {@link VrfClient} - * @category Accounts - * @category generated - */ -export type VrfClientArgs = { - bump: number; - maxResult: beet.bignum; - resultBuffer: number[] /* size: 32 */; - result: beet.bignum; - lastTimestamp: beet.bignum; - authority: web3.PublicKey; - vrf: web3.PublicKey; -}; - -const vrfClientDiscriminator = [230, 174, 157, 153, 51, 18, 230, 163]; -/** - * Holds the data for the {@link VrfClient} Account and provides de/serialization - * functionality for that data - * - * @category Accounts - * @category generated - */ -export class VrfClient implements VrfClientArgs { - private constructor( - readonly bump: number, - readonly maxResult: beet.bignum, - readonly resultBuffer: number[] /* size: 32 */, - readonly result: beet.bignum, - readonly lastTimestamp: beet.bignum, - readonly authority: web3.PublicKey, - readonly vrf: web3.PublicKey - ) {} - - /** - * Creates a {@link VrfClient} instance from the provided args. - */ - static fromArgs(args: VrfClientArgs) { - return new VrfClient( - args.bump, - args.maxResult, - args.resultBuffer, - args.result, - args.lastTimestamp, - args.authority, - args.vrf - ); - } - - /** - * Deserializes the {@link VrfClient} from the data of the provided {@link web3.AccountInfo}. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static fromAccountInfo( - accountInfo: web3.AccountInfo, - offset = 0 - ): [VrfClient, number] { - return VrfClient.deserialize(accountInfo.data, offset); - } - - /** - * Retrieves the account info from the provided address and deserializes - * the {@link VrfClient} from its data. - * - * @throws Error if no account info is found at the address or if deserialization fails - */ - static async fromAccountAddress( - connection: web3.Connection, - address: web3.PublicKey - ): Promise { - const accountInfo = await connection.getAccountInfo(address); - if (accountInfo == null) { - throw new Error(`Unable to find VrfClient account at ${address}`); - } - return VrfClient.fromAccountInfo(accountInfo, 0)[0]; - } - - /** - * Deserializes the {@link VrfClient} from the provided data Buffer. - * @returns a tuple of the account data and the offset up to which the buffer was read to obtain it. - */ - static deserialize(buf: Buffer, offset = 0): [VrfClient, number] { - return vrfClientBeet.deserialize(buf, offset); - } - - /** - * Serializes the {@link VrfClient} into a Buffer. - * @returns a tuple of the created Buffer and the offset up to which the buffer was written to store it. - */ - serialize(): [Buffer, number] { - return vrfClientBeet.serialize({ - accountDiscriminator: vrfClientDiscriminator, - ...this, - }); - } - - /** - * Returns the byteSize of a {@link Buffer} holding the serialized data of - * {@link VrfClient} - */ - static get byteSize() { - return vrfClientBeet.byteSize; - } - - /** - * Fetches the minimum balance needed to exempt an account holding - * {@link VrfClient} data from rent - * - * @param connection used to retrieve the rent exemption information - */ - static async getMinimumBalanceForRentExemption( - connection: web3.Connection, - commitment?: web3.Commitment - ): Promise { - return connection.getMinimumBalanceForRentExemption( - VrfClient.byteSize, - commitment - ); - } - - /** - * Determines if the provided {@link Buffer} has the correct byte size to - * hold {@link VrfClient} data. - */ - static hasCorrectByteSize(buf: Buffer, offset = 0) { - return buf.byteLength - offset === VrfClient.byteSize; - } - - /** - * Returns a readable version of {@link VrfClient} properties - * and can be used to convert to JSON and/or logging - */ - pretty() { - return { - bump: this.bump, - maxResult: this.maxResult, - resultBuffer: this.resultBuffer, - result: this.result, - lastTimestamp: this.lastTimestamp, - authority: this.authority.toBase58(), - vrf: this.vrf.toBase58(), - }; - } -} - -/** - * @category Accounts - * @category generated - */ -export const vrfClientBeet = new beet.BeetStruct< - VrfClient, - VrfClientArgs & { - accountDiscriminator: number[] /* size: 8 */; - } ->( - [ - ["accountDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], - ["bump", beet.u8], - ["maxResult", beet.u64], - ["resultBuffer", beet.uniformFixedSizeArray(beet.u8, 32)], - ["result", beet.u128], - ["lastTimestamp", beet.i64], - ["authority", beetSolana.publicKey], - ["vrf", beetSolana.publicKey], - ], - VrfClient.fromArgs, - "VrfClient" -); diff --git a/programs/anchor-vrf-parser/src/generated/accounts/index.ts b/programs/anchor-vrf-parser/src/generated/accounts/index.ts deleted file mode 100644 index ab88bd6..0000000 --- a/programs/anchor-vrf-parser/src/generated/accounts/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./VrfClient"; diff --git a/programs/anchor-vrf-parser/src/generated/errors/index.ts b/programs/anchor-vrf-parser/src/generated/errors/index.ts deleted file mode 100644 index cf237a3..0000000 --- a/programs/anchor-vrf-parser/src/generated/errors/index.ts +++ /dev/null @@ -1,135 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -type ErrorWithCode = Error & { code: number }; -type MaybeErrorWithCode = ErrorWithCode | null | undefined; - -const createErrorFromCodeLookup: Map ErrorWithCode> = new Map(); -const createErrorFromNameLookup: Map ErrorWithCode> = new Map(); - -/** - * InvalidSwitchboardVrfAccount: 'Not a valid Switchboard VRF account' - * - * @category Errors - * @category generated - */ -export class InvalidSwitchboardVrfAccountError extends Error { - readonly code: number = 0x1770; - - readonly name: string = "InvalidSwitchboardVrfAccount"; - - constructor() { - super("Not a valid Switchboard VRF account"); - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, InvalidSwitchboardVrfAccountError); - } - } -} - -createErrorFromCodeLookup.set( - 0x1770, - () => new InvalidSwitchboardVrfAccountError() -); -createErrorFromNameLookup.set( - "InvalidSwitchboardVrfAccount", - () => new InvalidSwitchboardVrfAccountError() -); - -/** - * MaxResultExceedsMaximum: 'The max result must not exceed u64' - * - * @category Errors - * @category generated - */ -export class MaxResultExceedsMaximumError extends Error { - readonly code: number = 0x1771; - - readonly name: string = "MaxResultExceedsMaximum"; - - constructor() { - super("The max result must not exceed u64"); - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, MaxResultExceedsMaximumError); - } - } -} - -createErrorFromCodeLookup.set(0x1771, () => new MaxResultExceedsMaximumError()); -createErrorFromNameLookup.set( - "MaxResultExceedsMaximum", - () => new MaxResultExceedsMaximumError() -); - -/** - * EmptyCurrentRoundResult: 'Current round result is empty' - * - * @category Errors - * @category generated - */ -export class EmptyCurrentRoundResultError extends Error { - readonly code: number = 0x1772; - - readonly name: string = "EmptyCurrentRoundResult"; - - constructor() { - super("Current round result is empty"); - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, EmptyCurrentRoundResultError); - } - } -} - -createErrorFromCodeLookup.set(0x1772, () => new EmptyCurrentRoundResultError()); -createErrorFromNameLookup.set( - "EmptyCurrentRoundResult", - () => new EmptyCurrentRoundResultError() -); - -/** - * InvalidAuthorityError: 'Invalid authority account provided.' - * - * @category Errors - * @category generated - */ -export class InvalidAuthorityErrorError extends Error { - readonly code: number = 0x1773; - - readonly name: string = "InvalidAuthorityError"; - - constructor() { - super("Invalid authority account provided."); - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, InvalidAuthorityErrorError); - } - } -} - -createErrorFromCodeLookup.set(0x1773, () => new InvalidAuthorityErrorError()); -createErrorFromNameLookup.set( - "InvalidAuthorityError", - () => new InvalidAuthorityErrorError() -); - -/** - * Attempts to resolve a custom program error from the provided error code. - * @category Errors - * @category generated - */ -export function errorFromCode(code: number): MaybeErrorWithCode { - const createError = createErrorFromCodeLookup.get(code); - return createError != null ? createError() : null; -} - -/** - * Attempts to resolve a custom program error from the provided error name, i.e. 'Unauthorized'. - * @category Errors - * @category generated - */ -export function errorFromName(name: string): MaybeErrorWithCode { - const createError = createErrorFromNameLookup.get(name); - return createError != null ? createError() : null; -} diff --git a/programs/anchor-vrf-parser/src/generated/index.ts b/programs/anchor-vrf-parser/src/generated/index.ts deleted file mode 100644 index 244bc80..0000000 --- a/programs/anchor-vrf-parser/src/generated/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { PublicKey } from "@solana/web3.js"; -export * from "./accounts"; -export * from "./errors"; -export * from "./instructions"; -export * from "./types"; - -/** - * Program address - * - * @category constants - * @category generated - */ -export const PROGRAM_ADDRESS = "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib"; - -/** - * Program publick key - * - * @category constants - * @category generated - */ -export const PROGRAM_ID = new PublicKey(PROGRAM_ADDRESS); diff --git a/programs/anchor-vrf-parser/src/generated/instructions/index.ts b/programs/anchor-vrf-parser/src/generated/instructions/index.ts deleted file mode 100644 index 1a7d199..0000000 --- a/programs/anchor-vrf-parser/src/generated/instructions/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from "./initState"; -export * from "./requestResult"; -export * from "./updateResult"; diff --git a/programs/anchor-vrf-parser/src/generated/instructions/initState.ts b/programs/anchor-vrf-parser/src/generated/instructions/initState.ts deleted file mode 100644 index 93a5bf6..0000000 --- a/programs/anchor-vrf-parser/src/generated/instructions/initState.ts +++ /dev/null @@ -1,107 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; -import { InitStateParams, initStateParamsBeet } from "../types/InitStateParams"; - -/** - * @category Instructions - * @category InitState - * @category generated - */ -export type InitStateInstructionArgs = { - params: InitStateParams; -}; -/** - * @category Instructions - * @category InitState - * @category generated - */ -const initStateStruct = new beet.BeetArgsStruct< - InitStateInstructionArgs & { - instructionDiscriminator: number[] /* size: 8 */; - } ->( - [ - ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], - ["params", initStateParamsBeet], - ], - "InitStateInstructionArgs" -); -/** - * Accounts required by the _initState_ instruction - * @category Instructions - * @category InitState - * @category generated - */ -export type InitStateInstructionAccounts = { - state: web3.PublicKey; - authority: web3.PublicKey; - payer: web3.PublicKey; - vrf: web3.PublicKey; -}; - -const initStateInstructionDiscriminator = [124, 213, 73, 136, 80, 37, 141, 54]; - -/** - * Creates a _InitState_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @param args to provide as instruction data to the program - * - * @category Instructions - * @category InitState - * @category generated - */ -export function createInitStateInstruction( - accounts: InitStateInstructionAccounts, - args: InitStateInstructionArgs -) { - const { state, authority, payer, vrf } = accounts; - - const [data] = initStateStruct.serialize({ - instructionDiscriminator: initStateInstructionDiscriminator, - ...args, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: state, - isWritable: true, - isSigner: false, - }, - { - pubkey: authority, - isWritable: false, - isSigner: false, - }, - { - pubkey: payer, - isWritable: true, - isSigner: true, - }, - { - pubkey: vrf, - isWritable: false, - isSigner: false, - }, - { - pubkey: web3.SystemProgram.programId, - isWritable: false, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId: new web3.PublicKey( - "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib" - ), - keys, - data, - }); - return ix; -} diff --git a/programs/anchor-vrf-parser/src/generated/instructions/requestResult.ts b/programs/anchor-vrf-parser/src/generated/instructions/requestResult.ts deleted file mode 100644 index 46b1c26..0000000 --- a/programs/anchor-vrf-parser/src/generated/instructions/requestResult.ts +++ /dev/null @@ -1,181 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as splToken from "@solana/spl-token"; -import * as web3 from "@solana/web3.js"; -import { - RequestResultParams, - requestResultParamsBeet, -} from "../types/RequestResultParams"; - -/** - * @category Instructions - * @category RequestResult - * @category generated - */ -export type RequestResultInstructionArgs = { - params: RequestResultParams; -}; -/** - * @category Instructions - * @category RequestResult - * @category generated - */ -const requestResultStruct = new beet.BeetArgsStruct< - RequestResultInstructionArgs & { - instructionDiscriminator: number[] /* size: 8 */; - } ->( - [ - ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)], - ["params", requestResultParamsBeet], - ], - "RequestResultInstructionArgs" -); -/** - * Accounts required by the _requestResult_ instruction - * @category Instructions - * @category RequestResult - * @category generated - */ -export type RequestResultInstructionAccounts = { - state: web3.PublicKey; - authority: web3.PublicKey; - switchboardProgram: web3.PublicKey; - vrf: web3.PublicKey; - oracleQueue: web3.PublicKey; - queueAuthority: web3.PublicKey; - dataBuffer: web3.PublicKey; - permission: web3.PublicKey; - escrow: web3.PublicKey; - payerWallet: web3.PublicKey; - payerAuthority: web3.PublicKey; - recentBlockhashes: web3.PublicKey; - programState: web3.PublicKey; -}; - -const requestResultInstructionDiscriminator = [ - 52, 47, 170, 99, 27, 80, 113, 141, -]; - -/** - * Creates a _RequestResult_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * @param args to provide as instruction data to the program - * - * @category Instructions - * @category RequestResult - * @category generated - */ -export function createRequestResultInstruction( - accounts: RequestResultInstructionAccounts, - args: RequestResultInstructionArgs -) { - const { - state, - authority, - switchboardProgram, - vrf, - oracleQueue, - queueAuthority, - dataBuffer, - permission, - escrow, - payerWallet, - payerAuthority, - recentBlockhashes, - programState, - } = accounts; - - const [data] = requestResultStruct.serialize({ - instructionDiscriminator: requestResultInstructionDiscriminator, - ...args, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: state, - isWritable: true, - isSigner: false, - }, - { - pubkey: authority, - isWritable: false, - isSigner: true, - }, - { - pubkey: switchboardProgram, - isWritable: false, - isSigner: false, - }, - { - pubkey: vrf, - isWritable: true, - isSigner: false, - }, - { - pubkey: oracleQueue, - isWritable: true, - isSigner: false, - }, - { - pubkey: queueAuthority, - isWritable: false, - isSigner: false, - }, - { - pubkey: dataBuffer, - isWritable: false, - isSigner: false, - }, - { - pubkey: permission, - isWritable: true, - isSigner: false, - }, - { - pubkey: escrow, - isWritable: true, - isSigner: false, - }, - { - pubkey: payerWallet, - isWritable: true, - isSigner: false, - }, - { - pubkey: payerAuthority, - isWritable: false, - isSigner: true, - }, - { - pubkey: recentBlockhashes, - isWritable: false, - isSigner: false, - }, - { - pubkey: programState, - isWritable: false, - isSigner: false, - }, - { - pubkey: splToken.TOKEN_PROGRAM_ID, - isWritable: false, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId: new web3.PublicKey( - "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib" - ), - keys, - data, - }); - return ix; -} diff --git a/programs/anchor-vrf-parser/src/generated/instructions/updateResult.ts b/programs/anchor-vrf-parser/src/generated/instructions/updateResult.ts deleted file mode 100644 index e6f2524..0000000 --- a/programs/anchor-vrf-parser/src/generated/instructions/updateResult.ts +++ /dev/null @@ -1,73 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -import * as web3 from "@solana/web3.js"; - -/** - * @category Instructions - * @category UpdateResult - * @category generated - */ -const updateResultStruct = new beet.BeetArgsStruct<{ - instructionDiscriminator: number[] /* size: 8 */; -}>( - [["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)]], - "UpdateResultInstructionArgs" -); -/** - * Accounts required by the _updateResult_ instruction - * @category Instructions - * @category UpdateResult - * @category generated - */ -export type UpdateResultInstructionAccounts = { - state: web3.PublicKey; - vrf: web3.PublicKey; -}; - -const updateResultInstructionDiscriminator = [145, 72, 9, 94, 61, 97, 126, 106]; - -/** - * Creates a _UpdateResult_ instruction. - * - * @param accounts that will be accessed while the instruction is processed - * - * @category Instructions - * @category UpdateResult - * @category generated - */ -export function createUpdateResultInstruction( - accounts: UpdateResultInstructionAccounts -) { - const { state, vrf } = accounts; - - const [data] = updateResultStruct.serialize({ - instructionDiscriminator: updateResultInstructionDiscriminator, - }); - const keys: web3.AccountMeta[] = [ - { - pubkey: state, - isWritable: true, - isSigner: false, - }, - { - pubkey: vrf, - isWritable: false, - isSigner: false, - }, - ]; - - const ix = new web3.TransactionInstruction({ - programId: new web3.PublicKey( - "FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib" - ), - keys, - data, - }); - return ix; -} diff --git a/programs/anchor-vrf-parser/src/generated/types/InitStateParams.ts b/programs/anchor-vrf-parser/src/generated/types/InitStateParams.ts deleted file mode 100644 index 21ca980..0000000 --- a/programs/anchor-vrf-parser/src/generated/types/InitStateParams.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -export type InitStateParams = { - maxResult: beet.bignum; -}; - -/** - * @category userTypes - * @category generated - */ -export const initStateParamsBeet = new beet.BeetArgsStruct( - [["maxResult", beet.u64]], - "InitStateParams" -); diff --git a/programs/anchor-vrf-parser/src/generated/types/RequestResultParams.ts b/programs/anchor-vrf-parser/src/generated/types/RequestResultParams.ts deleted file mode 100644 index 478d184..0000000 --- a/programs/anchor-vrf-parser/src/generated/types/RequestResultParams.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This code was GENERATED using the solita package. - * Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality. - * - * See: https://github.com/metaplex-foundation/solita - */ - -import * as beet from "@metaplex-foundation/beet"; -export type RequestResultParams = { - permissionBump: number; - switchboardStateBump: number; -}; - -/** - * @category userTypes - * @category generated - */ -export const requestResultParamsBeet = - new beet.BeetArgsStruct( - [ - ["permissionBump", beet.u8], - ["switchboardStateBump", beet.u8], - ], - "RequestResultParams" - ); diff --git a/programs/anchor-vrf-parser/src/generated/types/index.ts b/programs/anchor-vrf-parser/src/generated/types/index.ts deleted file mode 100644 index c8b2fa4..0000000 --- a/programs/anchor-vrf-parser/src/generated/types/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./InitStateParams"; -export * from "./RequestResultParams"; diff --git a/programs/anchor-vrf-parser/src/index.ts b/programs/anchor-vrf-parser/src/index.ts deleted file mode 100644 index eb6cabc..0000000 --- a/programs/anchor-vrf-parser/src/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./api"; -export * from "./generated"; diff --git a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/lib.rs b/programs/anchor-vrf-parser/src/lib.rs similarity index 96% rename from programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/lib.rs rename to programs/anchor-vrf-parser/src/lib.rs index cea1e72..116727e 100644 --- a/programs/anchor-vrf-parser/programs/anchor-vrf-parser/src/lib.rs +++ b/programs/anchor-vrf-parser/src/lib.rs @@ -4,7 +4,7 @@ pub use actions::*; pub use anchor_lang::prelude::*; use anchor_spl::token::TokenAccount; -declare_id!("FAnbznqZvZ7eijxQ6mKPoyDdM33o8cdM6wsUZtv2dFib"); +declare_id!("HWCUJF1GgCrS1fWNyJdWSBEVNXtdjRwQy7HohdQ5n31o"); const MAX_RESULT: u64 = u64::MAX; diff --git a/programs/anchor-vrf-parser/tests/permissionless-queue.test.ts b/programs/anchor-vrf-parser/tests/permissionless-queue.test.ts deleted file mode 100644 index 613cc61..0000000 --- a/programs/anchor-vrf-parser/tests/permissionless-queue.test.ts +++ /dev/null @@ -1,205 +0,0 @@ -import * as anchor from "@project-serum/anchor"; -import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet"; -import * as spl from "@solana/spl-token"; -import { - PublicKey, - SystemProgram, - SYSVAR_RECENT_BLOCKHASHES_PUBKEY, -} from "@solana/web3.js"; -import { - loadSwitchboardProgram, - OracleQueueAccount, - PermissionAccount, - ProgramStateAccount, - SwitchboardPermission, - VrfAccount, -} from "@switchboard-xyz/switchboard-v2"; -import chai from "chai"; -import "mocha"; -import { getVrfClientCallback, getVrfClientFromSeed } from "../src/api"; -import { VrfClient } from "../src/generated"; -import type { AnchorVrfParser } from "../target/types/anchor_vrf_parser"; -import { promiseWithTimeout } from "./test-utils"; -const expect = chai.expect; - -describe("creates a vrf account on the devnet permissionless queue", async () => { - anchor.setProvider(anchor.AnchorProvider.env()); - - const vrfClientProgram = anchor.workspace - .AnchorVrfParser as anchor.Program; - - const payer = ( - (vrfClientProgram.provider as anchor.AnchorProvider).wallet as NodeWallet - ).payer; - - const vrfSecret = anchor.web3.Keypair.generate(); - - // create state account but dont send instruction - // need public key for VRF CPI - const [vrfClientKey, vrfClientBump] = getVrfClientFromSeed( - vrfClientProgram as any, - vrfSecret.publicKey, - payer.publicKey // client state authority - ); - - const vrfClientCallback = getVrfClientCallback( - vrfClientProgram as any, - vrfClientKey, - vrfSecret.publicKey - ); - - it("Creates a vrfClient account", async () => { - let switchboardProgram: anchor.Program; - try { - switchboardProgram = await loadSwitchboardProgram( - "devnet", - vrfClientProgram.provider.connection, - payer - ); - } catch { - console.log(`might not be connected to devnet - test exiting`); - return; - } - - // override queue - const queue = new OracleQueueAccount({ - program: switchboardProgram, - publicKey: new PublicKey("F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy"), - }); - - const { unpermissionedVrfEnabled, authority, dataBuffer } = - await queue.loadData(); - - // Create Switchboard VRF and Permission account - const vrfAccount = await VrfAccount.create(switchboardProgram, { - queue, - callback: vrfClientCallback, - authority: vrfClientKey, // vrf authority - keypair: vrfSecret, - }); - const { escrow } = await vrfAccount.loadData(); - console.log(`Created VRF Account: ${vrfAccount.publicKey}`); - - const permissionAccount = await PermissionAccount.create( - switchboardProgram, - { - authority, - granter: queue.publicKey, - grantee: vrfAccount.publicKey, - } - ); - console.log(`Created Permission Account: ${permissionAccount.publicKey}`); - - // If queue requires permissions to use VRF, check the correct authority was provided - if (!unpermissionedVrfEnabled) { - if (!payer.publicKey.equals(authority)) { - throw new Error( - `queue requires PERMIT_VRF_REQUESTS and wrong queue authority provided` - ); - } - - await permissionAccount.set({ - authority: payer, - permission: SwitchboardPermission.PERMIT_VRF_REQUESTS, - enable: true, - }); - console.log(`Set VRF Permissions`); - } - - // Create VRF Client account - await vrfClientProgram.rpc.initState( - { - maxResult: new anchor.BN(1), - }, - { - accounts: { - state: vrfClientKey, - vrf: vrfAccount.publicKey, - payer: payer.publicKey, - authority: payer.publicKey, - systemProgram: SystemProgram.programId, - }, - } - ); - console.log(`Created VrfClient Account: ${vrfClientKey}`); - - // Get required switchboard accounts - const [programStateAccount, programStateBump] = - ProgramStateAccount.fromSeed(switchboardProgram); - const [permissionKey, permissionBump] = PermissionAccount.fromSeed( - switchboardProgram, - authority, - queue.publicKey, - vrfAccount.publicKey - ); - const switchboardMint = await programStateAccount.getTokenMint(); - const payerTokenAccount = - await switchboardMint.getOrCreateAssociatedAccountInfo(payer.publicKey); - - // Request randomness - console.log(`Sending RequestRandomness instruction`); - const requestTxn = await vrfClientProgram.rpc.requestResult( - { - switchboardStateBump: programStateBump, - permissionBump, - }, - { - accounts: { - state: vrfClientKey, - authority: payer.publicKey, - switchboardProgram: switchboardProgram.programId, - vrf: vrfAccount.publicKey, - oracleQueue: queue.publicKey, - queueAuthority: authority, - dataBuffer, - permission: permissionAccount.publicKey, - escrow, - payerWallet: payerTokenAccount.address, - payerAuthority: payer.publicKey, - recentBlockhashes: SYSVAR_RECENT_BLOCKHASHES_PUBKEY, - programState: programStateAccount.publicKey, - tokenProgram: spl.TOKEN_PROGRAM_ID, - }, - signers: [payer, payer], - } - ); - - const vrfClientAccountDecoder = new anchor.BorshAccountsCoder( - vrfClientProgram.idl - ); - - let ws: number; - const waitForEventPromise = new Promise( - (resolve: (result: anchor.BN) => void) => { - ws = vrfClientProgram.addEventListener( - "VrfClientResultUpdated", - async (event: any, slot: number) => { - console.log("VrfClientResultUpdated invoked"); - resolve(event.result as anchor.BN); - } - ); - } - ); - - const awaitResult = await promiseWithTimeout( - 30_000, - waitForEventPromise - ).finally(() => { - try { - vrfClientProgram.provider.connection.removeAccountChangeListener(ws); - } catch {} - }); - if (!awaitResult) { - throw new Error(`failed to get a VRF result`); - } - - console.log(JSON.stringify(awaitResult, undefined, 2)); - - const vrfClient = await VrfClient.fromAccountAddress( - vrfClientProgram.provider.connection, - vrfClientKey - ); - - console.log(`VrfClient Result: ${vrfClient.result}`); - }); -}); diff --git a/programs/anchor-vrf-parser/tests/test-utils.ts b/programs/anchor-vrf-parser/tests/test-utils.ts deleted file mode 100644 index 6281620..0000000 --- a/programs/anchor-vrf-parser/tests/test-utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const sleep = (ms: number): Promise => - new Promise((s) => setTimeout(s, ms)); - -export async function promiseWithTimeout( - ms: number, - promise: Promise, - timeoutError = new Error("timeoutError") -): Promise { - // create a promise that rejects in milliseconds - const timeout = new Promise((_, reject) => { - setTimeout(() => { - reject(timeoutError); - }, ms); - }); - - return Promise.race([promise, timeout]); -} diff --git a/programs/anchor-vrf-parser/tests/vrc-cpi.test.ts b/programs/anchor-vrf-parser/tests/vrc-cpi.test.ts index afa6d5f..9030c19 100644 --- a/programs/anchor-vrf-parser/tests/vrc-cpi.test.ts +++ b/programs/anchor-vrf-parser/tests/vrc-cpi.test.ts @@ -1,58 +1,95 @@ import * as anchor from "@project-serum/anchor"; -import NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet"; +import type NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet"; import * as spl from "@solana/spl-token"; import { + AccountInfo, + Context, + PublicKey, SystemProgram, SYSVAR_RECENT_BLOCKHASHES_PUBKEY, } from "@solana/web3.js"; import { - OracleAccount, + promiseWithTimeout, + SwitchboardTestContext, +} from "@switchboard-xyz/sbv2-utils"; +import { + Callback, PermissionAccount, ProgramStateAccount, SwitchboardPermission, - SwitchboardTestContext, VrfAccount, } from "@switchboard-xyz/switchboard-v2"; import chai from "chai"; import "mocha"; -import { getVrfClientCallback, getVrfClientFromSeed } from "../src/api"; -import { VrfClient } from "../src/generated"; -import type { AnchorVrfParser } from "../target/types/anchor_vrf_parser"; -import { promiseWithTimeout } from "./test-utils"; +import type { AnchorVrfParser } from "../../../target/types/anchor_vrf_parser"; + const expect = chai.expect; +interface VrfClientState { + bump: number; + maxResult: anchor.BN; + resultBuffer: number[]; + result: anchor.BN; + lastTimestamp: anchor.BN; + authority: PublicKey; + vrf: PublicKey; +} + describe("vrfClient test", async () => { anchor.setProvider(anchor.AnchorProvider.env()); const vrfClientProgram = anchor.workspace .AnchorVrfParser as anchor.Program; - - const payer = ( - (vrfClientProgram.provider as anchor.AnchorProvider).wallet as NodeWallet - ).payer; + const provider = vrfClientProgram.provider as anchor.AnchorProvider; + const payer = (provider.wallet as NodeWallet).payer; let switchboard: SwitchboardTestContext; const vrfSecret = anchor.web3.Keypair.generate(); - // create state account but dont send instruction - // need public key for VRF CPI - const [vrfClientKey, vrfClientBump] = getVrfClientFromSeed( - vrfClientProgram as any, - vrfSecret.publicKey, - payer.publicKey // client state authority - ); + const [vrfClientKey, vrfClientBump] = + anchor.utils.publicKey.findProgramAddressSync( + [ + Buffer.from("STATE"), + vrfSecret.publicKey.toBytes(), + payer.publicKey.toBytes(), + ], + vrfClientProgram.programId + ); - const vrfClientCallback = getVrfClientCallback( - vrfClientProgram as any, - vrfClientKey, - vrfSecret.publicKey - ); + const vrfIxCoder = new anchor.BorshInstructionCoder(vrfClientProgram.idl); + const vrfClientCallback: Callback = { + programId: vrfClientProgram.programId, + accounts: [ + // ensure all accounts in updateResult are populated + { pubkey: vrfClientKey, isSigner: false, isWritable: true }, + { pubkey: vrfSecret.publicKey, isSigner: false, isWritable: false }, + ], + ixData: vrfIxCoder.encode("updateResult", ""), // pass any params for instruction here + }; before(async () => { + // First, attempt to load the switchboard devnet PID + try { + switchboard = await SwitchboardTestContext.loadDevnetQueue(provider); + console.log("devnet detected"); + return; + } catch (error) { + console.log(error); + } + // If exists, try to load the devnet permissionless queue + // If fails, fallback to looking for a local env file + try { + switchboard = await SwitchboardTestContext.loadFromEnv(provider); + console.log("localnet detected"); + return; + } catch (error) { + console.log(error); + } + // If fails, throw error // TODO: Add try catch block to check devnet environment accounts - switchboard = await SwitchboardTestContext.loadFromEnv( - vrfClientProgram.provider as anchor.AnchorProvider + throw new Error( + `Failed to load the SwitchboardTestContext from devnet or from a switchboard.env file` ); }); @@ -129,85 +166,77 @@ describe("vrfClient test", async () => { // Request randomness console.log(`Sending RequestRandomness instruction`); - const requestTxn = await vrfClientProgram.rpc.requestResult( - { + const requestTxn = await vrfClientProgram.methods + .requestResult({ switchboardStateBump: programStateBump, permissionBump, - }, - { - accounts: { - state: vrfClientKey, - authority: payer.publicKey, - switchboardProgram: switchboard.program.programId, - vrf: vrfAccount.publicKey, - oracleQueue: queue.publicKey, - queueAuthority: authority, - dataBuffer, - permission: permissionAccount.publicKey, - escrow, - payerWallet: payerTokenAccount.address, - payerAuthority: payer.publicKey, - recentBlockhashes: SYSVAR_RECENT_BLOCKHASHES_PUBKEY, - programState: programStateAccount.publicKey, - tokenProgram: spl.TOKEN_PROGRAM_ID, - }, - signers: [payer, payer], - } - ); + }) + .accounts({ + state: vrfClientKey, + authority: payer.publicKey, + switchboardProgram: switchboard.program.programId, + vrf: vrfAccount.publicKey, + oracleQueue: queue.publicKey, + queueAuthority: authority, + dataBuffer, + permission: permissionAccount.publicKey, + escrow, + payerWallet: payerTokenAccount.address, + payerAuthority: payer.publicKey, + recentBlockhashes: SYSVAR_RECENT_BLOCKHASHES_PUBKEY, + programState: programStateAccount.publicKey, + tokenProgram: spl.TOKEN_PROGRAM_ID, + }) + .signers([payer, payer]) + .rpc(); - const vrfClientAccountDecoder = new anchor.BorshAccountsCoder( + const vrfClientAccountCoder = new anchor.BorshAccountsCoder( vrfClientProgram.idl ); - let ws: number; - - const waitToCrankPromise = new Promise( - (resolve: (result: string[]) => void) => { - ws = switchboard.program.addEventListener( - "VrfProveEvent", - async (event: any, slot: number) => { - console.log("VrfProveEvent invoked"); - if (!vrfSecret.publicKey.equals(event.vrfPubkey)) { - console.log(`not the same vrfKey`); - return; + // watch VrfClientState for a populated result + let ws: number | undefined = undefined; + const waitForResultPromise = new Promise( + ( + resolve: (result: anchor.BN) => void, + reject: (reason: string) => void + ) => { + try { + ws = vrfClientProgram.provider.connection.onAccountChange( + vrfClientKey, + async (accountInfo: AccountInfo, context: Context) => { + const clientState: VrfClientState = vrfClientAccountCoder.decode( + "VrfClient", + accountInfo.data + ); + if (clientState.result.gt(new anchor.BN(0))) { + resolve(clientState.result); + } } - - const vrf = await vrfAccount.loadData(); - const round = vrf.builders[0]; - - if (round.status.statusVerifying) { - console.log(`Ready to turn the crank`); - const oracle = new OracleAccount({ - program: switchboard.program, - publicKey: round.producer, - }); - const txns = await vrfAccount.verify(oracle); - resolve(txns); - } - } - ); + ); + } catch (error: any) { + reject(error); + } } ); - const awaitResult = await promiseWithTimeout( - 20_000, - waitToCrankPromise - ).finally(() => { - try { - vrfClientProgram.provider.connection.removeAccountChangeListener(ws); - } catch {} - }); - if (!awaitResult) { + let result: anchor.BN; + try { + result = await promiseWithTimeout(30_000, waitForResultPromise); + } catch (error) { + throw error; + } finally { + if (ws) { + await vrfClientProgram.provider.connection.removeAccountChangeListener( + ws + ); + } + } + + if (!result) { throw new Error(`failed to get a VRF result`); } - console.log(JSON.stringify(awaitResult, undefined, 2)); - - const vrfClient = await VrfClient.fromAccountAddress( - vrfClientProgram.provider.connection, - vrfClientKey - ); - - console.log(`VrfClient Result: ${vrfClient.result}`); + console.log(`VrfClient Result: ${result}`); }); }); diff --git a/programs/anchor-vrf-parser/tsconfig.json b/programs/anchor-vrf-parser/tsconfig.json index 95489e3..ba11aed 100644 --- a/programs/anchor-vrf-parser/tsconfig.json +++ b/programs/anchor-vrf-parser/tsconfig.json @@ -9,16 +9,20 @@ "types": ["mocha", "chai", "node"], "typeRoots": ["./node_modules/@types"], "lib": ["es2015"], - "outDir": "lib", "module": "commonjs", "target": "es6", "esModuleInterop": true, "importsNotUsedAsValues": "remove", + "noEmit": true, "paths": { - "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"] + "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"], + "@switchboard-xyz/sbv2-utils": ["../../libraries/sbv2-utils"] } }, - "include": ["src/**/*"], + "include": ["client/**/*"], "exclude": ["target", "lib"], - "references": [{ "path": "../../libraries/ts" }] + "references": [ + { "path": "../../libraries/ts" }, + { "path": "../../libraries/sbv2-utils" } + ] } diff --git a/programs/spl-feed-parser/.gitignore b/programs/spl-feed-parser/.gitignore deleted file mode 100644 index 51448d4..0000000 --- a/programs/spl-feed-parser/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ - -.anchor -.DS_Store -target -**/*.rs.bk -node_modules diff --git a/programs/spl-feed-parser/Cargo.toml b/programs/spl-feed-parser/Cargo.toml index eab4269..e601b41 100644 --- a/programs/spl-feed-parser/Cargo.toml +++ b/programs/spl-feed-parser/Cargo.toml @@ -3,12 +3,15 @@ name = "spl-feed-parser" version = "0.1.0" edition = "2018" +[lib] +crate-type = ["cdylib", "lib"] +name = "spl_feed_parser" + [features] no-entrypoint = [] [dependencies] -switchboard-v2 = "^0.1.10" +switchboard-v2 = { path = "../../libraries/rs" } +# switchboard-v2 = "^0.1.10" solana-program = "~1.9.13" -[lib] -crate-type = ["cdylib", "lib"] diff --git a/programs/spl-feed-parser/package.json b/programs/spl-feed-parser/package.json index c881042..da0cb00 100644 --- a/programs/spl-feed-parser/package.json +++ b/programs/spl-feed-parser/package.json @@ -8,13 +8,15 @@ "directory": "programs/spl-feed-parser" }, "scripts": { - "build": "cargo build-bpf --manifest-path=Cargo.toml", + "build": "echo \"For workspace spl-feed-parser, run 'anchor build' from the project root\" && exit 0", + "build:bpf": "cargo build-bpf --manifest-path=Cargo.toml", "deploy": "solana program deploy target/deploy/spl_feed_parser.so", - "anchor:test": "echo \"No anchor:test script for spl-feed-parser\" && exit 0", "test": "echo \"For workspace spl-feed-parser, use the anchor:test script\" && exit 0" }, "dependencies": { - "@solana/web3.js": "^1.37.1" + "@project-serum/anchor": "^0.24.2", + "@solana/web3.js": "^1.37.1", + "@switchboard-xyz/switchboard-v2": "^0.0.97" }, "devDependencies": { "@types/chai": "^4.3.0", diff --git a/programs/spl-feed-parser/tests/anchor-feed-parser.ts b/programs/spl-feed-parser/tests/anchor-feed-parser.ts new file mode 100644 index 0000000..2aa7f01 --- /dev/null +++ b/programs/spl-feed-parser/tests/anchor-feed-parser.ts @@ -0,0 +1,54 @@ +import type { Program } from "@project-serum/anchor"; +import * as anchor from "@project-serum/anchor"; +import { PublicKey } from "@solana/web3.js"; +import { SwitchboardTestContext } from "@switchboard-xyz/switchboard-v2"; +import type { AnchorFeedParser } from "../../../target/types/anchor_feed_parser"; + +const sleep = (ms: number): Promise => + new Promise((s) => setTimeout(s, ms)); + +// Anchor.toml will copy this to localnet when we start our tests +const DEFAULT_SOL_USD_FEED = new PublicKey( + "GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR" +); + +describe("anchor-feed-parser", () => { + anchor.setProvider(anchor.AnchorProvider.env()); + + const feedParserProgram = anchor.workspace + .AnchorFeedParser as Program; + const provider = feedParserProgram.provider as anchor.AnchorProvider; + + let aggregatorKey: PublicKey; + + before(async () => { + const accountInfo = await provider.connection.getAccountInfo( + DEFAULT_SOL_USD_FEED + ); + if (accountInfo) { + aggregatorKey = DEFAULT_SOL_USD_FEED; + return; + } + + // create an aggregator + try { + const switchboard = await SwitchboardTestContext.loadFromEnv(provider); + const staticFeed = await switchboard.createStaticFeed(100); + if (!staticFeed.publicKey) { + throw new Error("failed to read aggregatorKey"); + } + aggregatorKey = staticFeed.publicKey; + console.log(`created aggregator ${aggregatorKey}`); + await sleep(2000); + } catch (error) { + console.error(error); + throw new Error( + `failed to load switchboard aggregator or switchboard.env` + ); + } + }); + + it("Read SOL/USD Feed", async () => { + return; + }); +}); diff --git a/programs/spl-feed-parser/tests/spl-feed-parser.ts b/programs/spl-feed-parser/tests/spl-feed-parser.ts deleted file mode 100644 index 17d9757..0000000 --- a/programs/spl-feed-parser/tests/spl-feed-parser.ts +++ /dev/null @@ -1,2 +0,0 @@ -// TODO: Add mocha test -export {}; diff --git a/programs/spl-feed-parser/tsconfig.json b/programs/spl-feed-parser/tsconfig.json index 3e817d2..e17c4ec 100644 --- a/programs/spl-feed-parser/tsconfig.json +++ b/programs/spl-feed-parser/tsconfig.json @@ -7,11 +7,12 @@ "module": "commonjs", "target": "es6", "esModuleInterop": true, + "noEmit": true, "paths": { "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"] } }, - "include": ["tests/**/*"], + "include": ["oldtests/**/**/*"], "exclude": ["target"], "references": [{ "path": "../../libraries/ts" }] } diff --git a/scripts/setup-example-programs.js b/scripts/setup-example-programs.js new file mode 100644 index 0000000..035e833 --- /dev/null +++ b/scripts/setup-example-programs.js @@ -0,0 +1,159 @@ +#!/usr/bin/env node +/* eslint-disable @typescript-eslint/no-var-requires */ +/* eslint-disable import/no-extraneous-dependencies */ +const shell = require("shelljs"); +const { exec, spawn, execSync, spawnSync } = require("child_process"); +const web3 = require("@solana/web3.js"); +const fs = require("fs"); +const path = require("path"); + +const projectRoot = path.join(__dirname, ".."); +const targetDir = path.join(projectRoot, "target"); +const idlDir = path.join(targetDir, "idl"); +const anchorToml = path.join(projectRoot, "Anchor.toml"); + +const anchorClientGen = path.join( + projectRoot, + "node_modules", + ".bin", + "anchor-client-gen" +); +const shx = path.join(projectRoot, "node_modules", ".bin", "shx"); + +const anchorVrfKeypairPath = path.join( + targetDir, + "deploy", + "anchor_vrf_parser-keypair.json" +); + +const anchorFeedKeypairPath = path.join( + targetDir, + "deploy", + "anchor_feed_parser-keypair.json" +); + +const splFeedKeypairPath = path.join( + targetDir, + "deploy", + "spl_feed_parser-keypair.json" +); + +async function main() { + shell.cd(projectRoot); + + if (!shell.which("solana")) { + shell.echo( + "Sorry, this script requires 'solana' to be installed in your $PATH" + ); + shell.exit(1); + } + + if (!shell.which("anchor")) { + shell.echo( + "Sorry, this script requires 'anchor' to be installed in your $PATH" + ); + shell.exit(1); + } + + if (!fs.existsSync(path.join(targetDir, "deploy"))) { + shell.echo("Missing program deploy keypairs, building projects"); + const anchorBuildSpawn = spawn("anchor", ["build"]); + anchorBuildSpawn.stdout.on("data", function (msg) { + console.log(msg.toString()); + }); + await new Promise((resolve) => { + anchorBuildSpawn.on("close", resolve); + }); + } + + const anchorVrfParserPid = web3.Keypair.fromSecretKey( + new Uint8Array(JSON.parse(fs.readFileSync(anchorVrfKeypairPath, "utf8"))) + ).publicKey; + const anchorFeedParserPid = web3.Keypair.fromSecretKey( + new Uint8Array(JSON.parse(fs.readFileSync(anchorFeedKeypairPath, "utf8"))) + ).publicKey; + const splFeedParserPid = web3.Keypair.fromSecretKey( + new Uint8Array(JSON.parse(fs.readFileSync(splFeedKeypairPath, "utf8"))) + ).publicKey; + + // REPLACE ANCHOR-VRF-PROGRAM IDS + console.log(`Anchor VRF Parser PID: ${anchorVrfParserPid}`); + shell.sed( + "-i", + /declare_id!(.*);/, + `declare_id!("${anchorVrfParserPid.toString()}");`, + path.join(projectRoot, "programs", "anchor-vrf-parser", "src", "lib.rs") + ); + shell.sed( + "-i", + /anchor_vrf_parser = "(.*)"/, + `anchor_vrf_parser = "${anchorVrfParserPid.toString()}"`, + anchorToml + ); + + console.log(`Anchor Feed Parser PID: ${anchorFeedParserPid}`); + shell.sed( + "-i", + /declare_id!(.*);/, + `declare_id!("${anchorFeedParserPid.toString()}");`, + path.join(projectRoot, "programs", "anchor-feed-parser", "src", "lib.rs") + ); + shell.sed( + "-i", + /anchor_feed_parser = "(.*)"/, + `anchor_feed_parser = "${anchorFeedParserPid.toString()}"`, + anchorToml + ); + + console.log(`SPL Feed Parser PID: ${splFeedParserPid}`); + shell.sed( + "-i", + /declare_id!(.*);/, + `declare_id!("${splFeedParserPid.toString()}");`, + path.join(projectRoot, "programs", "spl-feed-parser", "src", "lib.rs") + ); + shell.sed( + "-i", + /spl_feed_parser = "(.*)"/, + `spl_feed_parser = "${splFeedParserPid.toString()}"`, + anchorToml + ); + + // Build Anchor APIs + const vrfClientPath = path.join( + projectRoot, + "programs", + "anchor-vrf-parser", + "client" + ); + shell.rm("-rf", vrfClientPath); + fs.mkdirSync(vrfClientPath, { recursive: true }); + execSync( + `node ${anchorClientGen} ${path.join( + idlDir, + "anchor_vrf_parser.json" + )} ${vrfClientPath} --program-id ${anchorVrfParserPid.toString()}` + ); + const feedClientPath = path.join( + projectRoot, + "programs", + "anchor-feed-parser", + "client" + ); + shell.rm("-rf", feedClientPath); + fs.mkdirSync(feedClientPath, { recursive: true }); + execSync( + `node ${anchorClientGen} ${path.join( + idlDir, + "anchor_feed_parser.json" + )} ${feedClientPath} --program-id ${anchorFeedParserPid.toString()}` + ); +} + +main() + .then(() => { + // console.log("Executed successfully"); + }) + .catch((err) => { + console.error(err); + }); diff --git a/switchboard_v2.json b/switchboard_v2.json new file mode 100644 index 0000000..b6f8edf --- /dev/null +++ b/switchboard_v2.json @@ -0,0 +1,4766 @@ +{ + "version": "0.1.0", + "name": "switchboard_v2", + "instructions": [ + { + "name": "aggregatorAddJob", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "job", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorAddJobParams" + } + } + ] + }, + { + "name": "aggregatorInit", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + }, + { + "name": "authorWallet", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorInitParams" + } + } + ] + }, + { + "name": "aggregatorLock", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": true, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorLockParams" + } + } + ] + }, + { + "name": "aggregatorOpenRound", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "payoutWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "dataBuffer", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorOpenRoundParams" + } + } + ] + }, + { + "name": "aggregatorRemoveJob", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "job", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorRemoveJobParams" + } + } + ] + }, + { + "name": "aggregatorSaveResult", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "oracle", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "oracleQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "feedPermission", + "isMut": true, + "isSigner": false + }, + { + "name": "oraclePermission", + "isMut": false, + "isSigner": false + }, + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "historyBuffer", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSaveResultParams" + } + } + ] + }, + { + "name": "aggregatorSetAuthority", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "newAuthority", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetAuthorityParams" + } + } + ] + }, + { + "name": "aggregatorSetBatchSize", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetBatchSizeParams" + } + } + ] + }, + { + "name": "aggregatorSetHistoryBuffer", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "buffer", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetHistoryBufferParams" + } + } + ] + }, + { + "name": "aggregatorSetMinJobs", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetMinJobsParams" + } + } + ] + }, + { + "name": "aggregatorSetMinOracles", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetMinOraclesParams" + } + } + ] + }, + { + "name": "aggregatorSetQueue", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetQueueParams" + } + } + ] + }, + { + "name": "aggregatorSetUpdateInterval", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetUpdateIntervalParams" + } + } + ] + }, + { + "name": "aggregatorSetVarianceThreshold", + "accounts": [ + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "AggregatorSetVarianceThresholdParams" + } + } + ] + }, + { + "name": "crankInit", + "accounts": [ + { + "name": "crank", + "isMut": true, + "isSigner": true + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + }, + { + "name": "buffer", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "CrankInitParams" + } + } + ] + }, + { + "name": "crankPop", + "accounts": [ + { + "name": "crank", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "payoutWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "crankDataBuffer", + "isMut": true, + "isSigner": false + }, + { + "name": "queueDataBuffer", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "CrankPopParams" + } + } + ] + }, + { + "name": "crankPush", + "accounts": [ + { + "name": "crank", + "isMut": true, + "isSigner": false + }, + { + "name": "aggregator", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "permission", + "isMut": false, + "isSigner": false + }, + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "dataBuffer", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "CrankPushParams" + } + } + ] + }, + { + "name": "jobInit", + "accounts": [ + { + "name": "job", + "isMut": true, + "isSigner": false + }, + { + "name": "authorWallet", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "JobInitParams" + } + } + ] + }, + { + "name": "leaseExtend", + "accounts": [ + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "aggregator", + "isMut": false, + "isSigner": false + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + }, + { + "name": "funder", + "isMut": true, + "isSigner": false + }, + { + "name": "owner", + "isMut": true, + "isSigner": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "LeaseExtendParams" + } + } + ] + }, + { + "name": "leaseInit", + "accounts": [ + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "queue", + "isMut": true, + "isSigner": false + }, + { + "name": "aggregator", + "isMut": false, + "isSigner": false + }, + { + "name": "funder", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "owner", + "isMut": true, + "isSigner": true + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "LeaseInitParams" + } + } + ] + }, + { + "name": "leaseSetAuthority", + "accounts": [ + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "newAuthority", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "LeaseSetAuthorityParams" + } + } + ] + }, + { + "name": "leaseWithdraw", + "accounts": [ + { + "name": "lease", + "isMut": true, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "aggregator", + "isMut": false, + "isSigner": false + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + }, + { + "name": "withdrawAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "withdrawAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "LeaseWithdrawParams" + } + } + ] + }, + { + "name": "oracleHeartbeat", + "accounts": [ + { + "name": "oracle", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "tokenAccount", + "isMut": false, + "isSigner": false + }, + { + "name": "gcOracle", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "permission", + "isMut": false, + "isSigner": false + }, + { + "name": "dataBuffer", + "isMut": true, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleHeartbeatParams" + } + } + ] + }, + { + "name": "oracleInit", + "accounts": [ + { + "name": "oracle", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "wallet", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "queue", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleInitParams" + } + } + ] + }, + { + "name": "oracleQueueInit", + "accounts": [ + { + "name": "oracleQueue", + "isMut": true, + "isSigner": true + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "buffer", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleQueueInitParams" + } + } + ] + }, + { + "name": "oracleQueueSetRewards", + "accounts": [ + { + "name": "queue", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleQueueSetRewardsParams" + } + } + ] + }, + { + "name": "oracleQueueVrfConfig", + "accounts": [ + { + "name": "queue", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleQueueVrfConfigParams" + } + } + ] + }, + { + "name": "oracleWithdraw", + "accounts": [ + { + "name": "oracle", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "tokenAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "withdrawAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "OracleWithdrawParams" + } + } + ] + }, + { + "name": "permissionInit", + "accounts": [ + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "granter", + "isMut": false, + "isSigner": false + }, + { + "name": "grantee", + "isMut": false, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": true + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "PermissionInitParams" + } + } + ] + }, + { + "name": "permissionSet", + "accounts": [ + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "PermissionSetParams" + } + } + ] + }, + { + "name": "programConfig", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "ProgramConfigParams" + } + } + ] + }, + { + "name": "programInit", + "accounts": [ + { + "name": "state", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenMint", + "isMut": true, + "isSigner": false + }, + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "payer", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "ProgramInitParams" + } + } + ] + }, + { + "name": "vaultTransfer", + "accounts": [ + { + "name": "state", + "isMut": false, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "to", + "isMut": true, + "isSigner": false + }, + { + "name": "vault", + "isMut": true, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VaultTransferParams" + } + } + ] + }, + { + "name": "vrfInit", + "accounts": [ + { + "name": "vrf", + "isMut": true, + "isSigner": false + }, + { + "name": "authority", + "isMut": false, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": false, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VrfInitParams" + } + } + ] + }, + { + "name": "vrfProve", + "accounts": [ + { + "name": "vrf", + "isMut": true, + "isSigner": false + }, + { + "name": "oracle", + "isMut": false, + "isSigner": false + }, + { + "name": "randomnessProducer", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VrfProveParams" + } + } + ] + }, + { + "name": "vrfProveAndVerify", + "accounts": [ + { + "name": "vrf", + "isMut": true, + "isSigner": false + }, + { + "name": "callbackPid", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "oracle", + "isMut": false, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "oracleWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "instructionsSysvar", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VrfProveAndVerifyParams" + } + } + ] + }, + { + "name": "vrfRequestRandomness", + "accounts": [ + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "vrf", + "isMut": true, + "isSigner": false + }, + { + "name": "oracleQueue", + "isMut": true, + "isSigner": false + }, + { + "name": "queueAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "dataBuffer", + "isMut": false, + "isSigner": false + }, + { + "name": "permission", + "isMut": true, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "payerWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "payerAuthority", + "isMut": false, + "isSigner": true + }, + { + "name": "recentBlockhashes", + "isMut": false, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VrfRequestRandomnessParams" + } + } + ] + }, + { + "name": "vrfVerify", + "accounts": [ + { + "name": "vrf", + "isMut": true, + "isSigner": false + }, + { + "name": "callbackPid", + "isMut": false, + "isSigner": false + }, + { + "name": "tokenProgram", + "isMut": false, + "isSigner": false + }, + { + "name": "escrow", + "isMut": true, + "isSigner": false + }, + { + "name": "programState", + "isMut": false, + "isSigner": false + }, + { + "name": "oracle", + "isMut": false, + "isSigner": false + }, + { + "name": "oracleAuthority", + "isMut": false, + "isSigner": false + }, + { + "name": "oracleWallet", + "isMut": true, + "isSigner": false + }, + { + "name": "instructionsSysvar", + "isMut": false, + "isSigner": false + } + ], + "args": [ + { + "name": "params", + "type": { + "defined": "VrfVerifyParams" + } + } + ] + } + ], + "accounts": [ + { + "name": "SbState", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "tokenMint", + "type": "publicKey" + }, + { + "name": "tokenVault", + "type": "publicKey" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 1024 + ] + } + } + ] + } + }, + { + "name": "AggregatorAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 128 + ] + } + }, + { + "name": "authorWallet", + "type": "publicKey" + }, + { + "name": "queuePubkey", + "type": "publicKey" + }, + { + "name": "oracleRequestBatchSize", + "type": "u32" + }, + { + "name": "minOracleResults", + "type": "u32" + }, + { + "name": "minJobResults", + "type": "u32" + }, + { + "name": "minUpdateDelaySeconds", + "type": "u32" + }, + { + "name": "startAfter", + "type": "i64" + }, + { + "name": "varianceThreshold", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "forceReportPeriod", + "type": "i64" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "consecutiveFailureCount", + "type": "u64" + }, + { + "name": "nextAllowedUpdateTime", + "type": "i64" + }, + { + "name": "isLocked", + "type": "bool" + }, + { + "name": "crankPubkey", + "type": "publicKey" + }, + { + "name": "latestConfirmedRound", + "type": { + "defined": "AggregatorRound" + } + }, + { + "name": "currentRound", + "type": { + "defined": "AggregatorRound" + } + }, + { + "name": "jobPubkeysData", + "type": { + "array": [ + "publicKey", + 16 + ] + } + }, + { + "name": "jobHashes", + "type": { + "array": [ + { + "defined": "Hash" + }, + 16 + ] + } + }, + { + "name": "jobPubkeysSize", + "type": "u32" + }, + { + "name": "jobsChecksum", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "historyBuffer", + "type": "publicKey" + }, + { + "name": "previousConfirmedRoundResult", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "previousConfirmedRoundSlot", + "type": "u64" + }, + { + "name": "disableCrank", + "type": "bool" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 163 + ] + } + } + ] + } + }, + { + "name": "PermissionAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "permissions", + "type": "u32" + }, + { + "name": "granter", + "type": "publicKey" + }, + { + "name": "grantee", + "type": "publicKey" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "LeaseAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "escrow", + "type": "publicKey" + }, + { + "name": "queue", + "type": "publicKey" + }, + { + "name": "aggregator", + "type": "publicKey" + }, + { + "name": "tokenProgram", + "type": "publicKey" + }, + { + "name": "isActive", + "type": "bool" + }, + { + "name": "crankRowCount", + "type": "u32" + }, + { + "name": "createdAt", + "type": "i64" + }, + { + "name": "updateCount", + "type": "u128" + }, + { + "name": "withdrawAuthority", + "type": "publicKey" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "OracleQueueAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "oracleTimeout", + "type": "u32" + }, + { + "name": "reward", + "type": "u64" + }, + { + "name": "minStake", + "type": "u64" + }, + { + "name": "slashingEnabled", + "type": "bool" + }, + { + "name": "varianceToleranceMultiplier", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "feedProbationPeriod", + "type": "u32" + }, + { + "name": "currIdx", + "type": "u32" + }, + { + "name": "size", + "type": "u32" + }, + { + "name": "gcIdx", + "type": "u32" + }, + { + "name": "consecutiveFeedFailureLimit", + "type": "u64" + }, + { + "name": "consecutiveOracleFailureLimit", + "type": "u64" + }, + { + "name": "unpermissionedFeedsEnabled", + "type": "bool" + }, + { + "name": "unpermissionedVrfEnabled", + "type": "bool" + }, + { + "name": "curatorRewardCut", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "lockLeaseFunding", + "type": "bool" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 1001 + ] + } + }, + { + "name": "maxSize", + "type": "u32" + }, + { + "name": "dataBuffer", + "type": "publicKey" + } + ] + } + }, + { + "name": "CrankAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "queuePubkey", + "type": "publicKey" + }, + { + "name": "pqSize", + "type": "u32" + }, + { + "name": "maxRows", + "type": "u32" + }, + { + "name": "jitterModifier", + "type": "u8" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 255 + ] + } + }, + { + "name": "dataBuffer", + "type": "publicKey" + } + ] + } + }, + { + "name": "OracleAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 128 + ] + } + }, + { + "name": "oracleAuthority", + "type": "publicKey" + }, + { + "name": "lastHeartbeat", + "type": "i64" + }, + { + "name": "numInUse", + "type": "u32" + }, + { + "name": "tokenAccount", + "type": "publicKey" + }, + { + "name": "queuePubkey", + "type": "publicKey" + }, + { + "name": "metrics", + "type": { + "defined": "OracleMetrics" + } + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "JobAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "authorWallet", + "type": "publicKey" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "hash", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "data", + "type": "bytes" + }, + { + "name": "referenceCount", + "type": "u32" + }, + { + "name": "totalSpent", + "type": "u128" + } + ] + } + }, + { + "name": "VrfAccountData", + "type": { + "kind": "struct", + "fields": [ + { + "name": "status", + "type": { + "defined": "VrfStatus" + } + }, + { + "name": "counter", + "type": "u128" + }, + { + "name": "authority", + "type": "publicKey" + }, + { + "name": "oracleQueue", + "type": "publicKey" + }, + { + "name": "escrow", + "type": "publicKey" + }, + { + "name": "callback", + "type": { + "defined": "CallbackZC" + } + }, + { + "name": "batchSize", + "type": "u32" + }, + { + "name": "builders", + "type": { + "array": [ + { + "defined": "VrfBuilder" + }, + 8 + ] + } + }, + { + "name": "buildersLen", + "type": "u32" + }, + { + "name": "testMode", + "type": "bool" + }, + { + "name": "currentRound", + "type": { + "defined": "VrfRound" + } + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 1024 + ] + } + } + ] + } + } + ], + "types": [ + { + "name": "AggregatorAddJobParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AggregatorInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 128 + ] + } + }, + { + "name": "batchSize", + "type": "u32" + }, + { + "name": "minOracleResults", + "type": "u32" + }, + { + "name": "minJobResults", + "type": "u32" + }, + { + "name": "minUpdateDelaySeconds", + "type": "u32" + }, + { + "name": "startAfter", + "type": "i64" + }, + { + "name": "varianceThreshold", + "type": { + "defined": "BorshDecimal" + } + }, + { + "name": "forceReportPeriod", + "type": "i64" + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "AggregatorLockParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AggregatorOpenRoundParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "leaseBump", + "type": "u8" + }, + { + "name": "permissionBump", + "type": "u8" + }, + { + "name": "jitter", + "type": "u8" + } + ] + } + }, + { + "name": "AggregatorRemoveJobParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "jobIdx", + "type": "u32" + } + ] + } + }, + { + "name": "AggregatorSaveResultParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "oracleIdx", + "type": "u32" + }, + { + "name": "error", + "type": "bool" + }, + { + "name": "value", + "type": { + "defined": "BorshDecimal" + } + }, + { + "name": "jobsChecksum", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "minResponse", + "type": { + "defined": "BorshDecimal" + } + }, + { + "name": "maxResponse", + "type": { + "defined": "BorshDecimal" + } + }, + { + "name": "feedPermissionBump", + "type": "u8" + }, + { + "name": "oraclePermissionBump", + "type": "u8" + }, + { + "name": "leaseBump", + "type": "u8" + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "AggregatorSetAuthorityParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AggregatorSetBatchSizeParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "batchSize", + "type": "u32" + } + ] + } + }, + { + "name": "AggregatorSetHistoryBufferParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AggregatorSetMinJobsParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "minJobResults", + "type": "u32" + } + ] + } + }, + { + "name": "AggregatorSetMinOraclesParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "minOracleResults", + "type": "u32" + } + ] + } + }, + { + "name": "AggregatorSetQueueParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "AggregatorSetUpdateIntervalParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "newInterval", + "type": "u32" + } + ] + } + }, + { + "name": "AggregatorSetVarianceThresholdParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "varianceThreshold", + "type": { + "defined": "BorshDecimal" + } + } + ] + } + }, + { + "name": "CrankInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": "bytes" + }, + { + "name": "metadata", + "type": "bytes" + }, + { + "name": "crankSize", + "type": "u32" + } + ] + } + }, + { + "name": "CrankPopParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "leaseBumps", + "type": "bytes" + }, + { + "name": "permissionBumps", + "type": "bytes" + }, + { + "name": "nonce", + "type": { + "option": "u32" + } + }, + { + "name": "failOpenOnAccountMismatch", + "type": { + "option": "bool" + } + } + ] + } + }, + { + "name": "CrankPushParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "permissionBump", + "type": "u8" + } + ] + } + }, + { + "name": "JobInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "expiration", + "type": "i64" + }, + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "data", + "type": "bytes" + } + ] + } + }, + { + "name": "LeaseExtendParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "loadAmount", + "type": "u64" + }, + { + "name": "leaseBump", + "type": "u8" + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "LeaseInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "loadAmount", + "type": "u64" + }, + { + "name": "withdrawAuthority", + "type": "publicKey" + }, + { + "name": "leaseBump", + "type": "u8" + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "LeaseSetAuthorityParams", + "type": { + "kind": "struct", + "fields": [] + } + }, + { + "name": "LeaseWithdrawParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "leaseBump", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "OracleHeartbeatParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "permissionBump", + "type": "u8" + } + ] + } + }, + { + "name": "OracleInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": "bytes" + }, + { + "name": "metadata", + "type": "bytes" + }, + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "oracleBump", + "type": "u8" + } + ] + } + }, + { + "name": "OracleQueueInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "name", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "metadata", + "type": { + "array": [ + "u8", + 64 + ] + } + }, + { + "name": "reward", + "type": "u64" + }, + { + "name": "minStake", + "type": "u64" + }, + { + "name": "feedProbationPeriod", + "type": "u32" + }, + { + "name": "oracleTimeout", + "type": "u32" + }, + { + "name": "slashingEnabled", + "type": "bool" + }, + { + "name": "varianceToleranceMultiplier", + "type": { + "defined": "BorshDecimal" + } + }, + { + "name": "consecutiveFeedFailureLimit", + "type": "u64" + }, + { + "name": "consecutiveOracleFailureLimit", + "type": "u64" + }, + { + "name": "queueSize", + "type": "u32" + }, + { + "name": "unpermissionedFeeds", + "type": "bool" + }, + { + "name": "unpermissionedVrf", + "type": "bool" + } + ] + } + }, + { + "name": "OracleQueueSetRewardsParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "rewards", + "type": "u64" + } + ] + } + }, + { + "name": "OracleQueueVrfConfigParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "unpermissionedVrfEnabled", + "type": "bool" + } + ] + } + }, + { + "name": "OracleWithdrawParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "permissionBump", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "PermissionInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "permissionBump", + "type": "u8" + } + ] + } + }, + { + "name": "PermissionSetParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "permission", + "type": { + "defined": "SwitchboardPermission" + } + }, + { + "name": "enable", + "type": "bool" + } + ] + } + }, + { + "name": "ProgramConfigParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "token", + "type": "publicKey" + }, + { + "name": "bump", + "type": "u8" + } + ] + } + }, + { + "name": "ProgramInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "VaultTransferParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "amount", + "type": "u64" + } + ] + } + }, + { + "name": "VrfInitParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "callback", + "type": { + "defined": "Callback" + } + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "VrfProveParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "proof", + "type": "bytes" + }, + { + "name": "idx", + "type": "u32" + } + ] + } + }, + { + "name": "VrfProveAndVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "nonce", + "type": { + "option": "u32" + } + }, + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "idx", + "type": "u32" + }, + { + "name": "proof", + "type": "bytes" + } + ] + } + }, + { + "name": "VrfRequestRandomnessParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "permissionBump", + "type": "u8" + }, + { + "name": "stateBump", + "type": "u8" + } + ] + } + }, + { + "name": "VrfVerifyParams", + "type": { + "kind": "struct", + "fields": [ + { + "name": "nonce", + "type": { + "option": "u32" + } + }, + { + "name": "stateBump", + "type": "u8" + }, + { + "name": "idx", + "type": "u32" + } + ] + } + }, + { + "name": "Hash", + "type": { + "kind": "struct", + "fields": [ + { + "name": "data", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "AggregatorRound", + "type": { + "kind": "struct", + "fields": [ + { + "name": "numSuccess", + "type": "u32" + }, + { + "name": "numError", + "type": "u32" + }, + { + "name": "isClosed", + "type": "bool" + }, + { + "name": "roundOpenSlot", + "type": "u64" + }, + { + "name": "roundOpenTimestamp", + "type": "i64" + }, + { + "name": "result", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "stdDeviation", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "minResponse", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "maxResponse", + "type": { + "defined": "SwitchboardDecimal" + } + }, + { + "name": "oraclePubkeysData", + "type": { + "array": [ + "publicKey", + 16 + ] + } + }, + { + "name": "mediansData", + "type": { + "array": [ + { + "defined": "SwitchboardDecimal" + }, + 16 + ] + } + }, + { + "name": "currentPayout", + "type": { + "array": [ + "i64", + 16 + ] + } + }, + { + "name": "mediansFulfilled", + "type": { + "array": [ + "bool", + 16 + ] + } + }, + { + "name": "errorsFulfilled", + "type": { + "array": [ + "bool", + 16 + ] + } + } + ] + } + }, + { + "name": "AggregatorHistoryRow", + "type": { + "kind": "struct", + "fields": [ + { + "name": "timestamp", + "type": "i64" + }, + { + "name": "value", + "type": { + "defined": "SwitchboardDecimal" + } + } + ] + } + }, + { + "name": "SwitchboardDecimal", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mantissa", + "type": "i128" + }, + { + "name": "scale", + "type": "u32" + } + ] + } + }, + { + "name": "CrankRow", + "type": { + "kind": "struct", + "fields": [ + { + "name": "pubkey", + "type": "publicKey" + }, + { + "name": "nextTimestamp", + "type": "i64" + } + ] + } + }, + { + "name": "OracleMetrics", + "type": { + "kind": "struct", + "fields": [ + { + "name": "consecutiveSuccess", + "type": "u64" + }, + { + "name": "consecutiveError", + "type": "u64" + }, + { + "name": "consecutiveDisagreement", + "type": "u64" + }, + { + "name": "consecutiveLateResponse", + "type": "u64" + }, + { + "name": "consecutiveFailure", + "type": "u64" + }, + { + "name": "totalSuccess", + "type": "u128" + }, + { + "name": "totalError", + "type": "u128" + }, + { + "name": "totalDisagreement", + "type": "u128" + }, + { + "name": "totalLateResponse", + "type": "u128" + } + ] + } + }, + { + "name": "BorshDecimal", + "type": { + "kind": "struct", + "fields": [ + { + "name": "mantissa", + "type": "i128" + }, + { + "name": "scale", + "type": "u32" + } + ] + } + }, + { + "name": "EcvrfProofZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "gamma", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "c", + "type": { + "defined": "Scalar" + } + }, + { + "name": "s", + "type": { + "defined": "Scalar" + } + } + ] + } + }, + { + "name": "Scalar", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bytes", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "FieldElementZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "bytes", + "type": { + "array": [ + "u64", + 5 + ] + } + } + ] + } + }, + { + "name": "CompletedPointZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "y", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "z", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "t", + "type": { + "defined": "FieldElementZC" + } + } + ] + } + }, + { + "name": "EdwardsPointZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "y", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "z", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "t", + "type": { + "defined": "FieldElementZC" + } + } + ] + } + }, + { + "name": "ProjectivePointZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "x", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "y", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "z", + "type": { + "defined": "FieldElementZC" + } + } + ] + } + }, + { + "name": "EcvrfIntermediate", + "type": { + "kind": "struct", + "fields": [ + { + "name": "r", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "nS", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "d", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "t13", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "t15", + "type": { + "defined": "FieldElementZC" + } + } + ] + } + }, + { + "name": "VrfBuilder", + "type": { + "kind": "struct", + "fields": [ + { + "name": "producer", + "type": "publicKey" + }, + { + "name": "status", + "type": { + "defined": "VrfStatus" + } + }, + { + "name": "reprProof", + "type": { + "array": [ + "u8", + 80 + ] + } + }, + { + "name": "proof", + "type": { + "defined": "EcvrfProofZC" + } + }, + { + "name": "yPoint", + "type": "publicKey" + }, + { + "name": "stage", + "type": "u32" + }, + { + "name": "stage1Out", + "type": { + "defined": "EcvrfIntermediate" + } + }, + { + "name": "r1", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "r2", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "stage3Out", + "type": { + "defined": "EcvrfIntermediate" + } + }, + { + "name": "hPoint", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "sReduced", + "type": { + "defined": "Scalar" + } + }, + { + "name": "yPointBuilder", + "type": { + "array": [ + { + "defined": "FieldElementZC" + }, + 3 + ] + } + }, + { + "name": "yRistrettoPoint", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "mulRound", + "type": "u8" + }, + { + "name": "hashPointsRound", + "type": "u8" + }, + { + "name": "mulTmp1", + "type": { + "defined": "CompletedPointZC" + } + }, + { + "name": "uPoint1", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "uPoint2", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "vPoint1", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "vPoint2", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "uPoint", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "vPoint", + "type": { + "defined": "EdwardsPointZC" + } + }, + { + "name": "u1", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "u2", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "invertee", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "y", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "z", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "p1Bytes", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "p2Bytes", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "p3Bytes", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "p4Bytes", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "cPrimeHashbuf", + "type": { + "array": [ + "u8", + 16 + ] + } + }, + { + "name": "m1", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "m2", + "type": { + "defined": "FieldElementZC" + } + }, + { + "name": "txRemaining", + "type": "u32" + }, + { + "name": "verified", + "type": "bool" + }, + { + "name": "result", + "type": { + "array": [ + "u8", + 32 + ] + } + } + ] + } + }, + { + "name": "AccountMetaZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "pubkey", + "type": "publicKey" + }, + { + "name": "isSigner", + "type": "bool" + }, + { + "name": "isWritable", + "type": "bool" + } + ] + } + }, + { + "name": "AccountMetaBorsh", + "type": { + "kind": "struct", + "fields": [ + { + "name": "pubkey", + "type": "publicKey" + }, + { + "name": "isSigner", + "type": "bool" + }, + { + "name": "isWritable", + "type": "bool" + } + ] + } + }, + { + "name": "CallbackZC", + "type": { + "kind": "struct", + "fields": [ + { + "name": "programId", + "type": "publicKey" + }, + { + "name": "accounts", + "type": { + "array": [ + { + "defined": "AccountMetaZC" + }, + 32 + ] + } + }, + { + "name": "accountsLen", + "type": "u32" + }, + { + "name": "ixData", + "type": { + "array": [ + "u8", + 1024 + ] + } + }, + { + "name": "ixDataLen", + "type": "u32" + } + ] + } + }, + { + "name": "Callback", + "type": { + "kind": "struct", + "fields": [ + { + "name": "programId", + "type": "publicKey" + }, + { + "name": "accounts", + "type": { + "vec": { + "defined": "AccountMetaBorsh" + } + } + }, + { + "name": "ixData", + "type": "bytes" + } + ] + } + }, + { + "name": "VrfRound", + "type": { + "kind": "struct", + "fields": [ + { + "name": "alpha", + "type": { + "array": [ + "u8", + 256 + ] + } + }, + { + "name": "alphaLen", + "type": "u32" + }, + { + "name": "requestSlot", + "type": "u64" + }, + { + "name": "requestTimestamp", + "type": "i64" + }, + { + "name": "result", + "type": { + "array": [ + "u8", + 32 + ] + } + }, + { + "name": "numVerified", + "type": "u32" + }, + { + "name": "ebuf", + "type": { + "array": [ + "u8", + 256 + ] + } + } + ] + } + }, + { + "name": "Lanes", + "type": { + "kind": "enum", + "variants": [ + { + "name": "C" + }, + { + "name": "D" + }, + { + "name": "AB" + }, + { + "name": "AC" + }, + { + "name": "CD" + }, + { + "name": "AD" + }, + { + "name": "BC" + }, + { + "name": "ABCD" + } + ] + } + }, + { + "name": "Shuffle", + "type": { + "kind": "enum", + "variants": [ + { + "name": "AAAA" + }, + { + "name": "BBBB" + }, + { + "name": "CACA" + }, + { + "name": "DBBD" + }, + { + "name": "ADDA" + }, + { + "name": "CBCB" + }, + { + "name": "ABAB" + }, + { + "name": "BADC" + }, + { + "name": "BACD" + }, + { + "name": "ABDC" + } + ] + } + }, + { + "name": "Shuffle", + "type": { + "kind": "enum", + "variants": [ + { + "name": "AAAA" + }, + { + "name": "BBBB" + }, + { + "name": "BADC" + }, + { + "name": "BACD" + }, + { + "name": "ADDA" + }, + { + "name": "CBCB" + }, + { + "name": "ABDC" + }, + { + "name": "ABAB" + }, + { + "name": "DBBD" + }, + { + "name": "CACA" + } + ] + } + }, + { + "name": "Lanes", + "type": { + "kind": "enum", + "variants": [ + { + "name": "D" + }, + { + "name": "C" + }, + { + "name": "AB" + }, + { + "name": "AC" + }, + { + "name": "AD" + }, + { + "name": "BCD" + } + ] + } + }, + { + "name": "Error", + "type": { + "kind": "enum", + "variants": [ + { + "name": "InvalidPublicKey" + }, + { + "name": "SerializationError", + "fields": [ + { + "defined": "bincode::Error" + } + ] + }, + { + "name": "DeserializationError", + "fields": [ + { + "defined": "bincode::Error" + } + ] + }, + { + "name": "InvalidDataError" + } + ] + } + }, + { + "name": "SwitchboardPermission", + "type": { + "kind": "enum", + "variants": [ + { + "name": "PermitOracleHeartbeat" + }, + { + "name": "PermitOracleQueueUsage" + }, + { + "name": "PermitVrfRequests" + } + ] + } + }, + { + "name": "OracleResponseType", + "type": { + "kind": "enum", + "variants": [ + { + "name": "TypeSuccess" + }, + { + "name": "TypeError" + }, + { + "name": "TypeDisagreement" + }, + { + "name": "TypeNoResponse" + } + ] + } + }, + { + "name": "VrfStatus", + "type": { + "kind": "enum", + "variants": [ + { + "name": "StatusNone" + }, + { + "name": "StatusRequesting" + }, + { + "name": "StatusVerifying" + }, + { + "name": "StatusVerified" + }, + { + "name": "StatusCallbackSuccess" + }, + { + "name": "StatusVerifyFailure" + } + ] + } + } + ], + "events": [ + { + "name": "AggregatorInitEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VrfRequestRandomnessEvent", + "fields": [ + { + "name": "vrfPubkey", + "type": "publicKey", + "index": true + }, + { + "name": "oraclePubkeys", + "type": { + "vec": "publicKey" + }, + "index": false + }, + { + "name": "loadAmount", + "type": "u64", + "index": false + }, + { + "name": "existingAmount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "VrfRequestEvent", + "fields": [ + { + "name": "vrfPubkey", + "type": "publicKey", + "index": true + }, + { + "name": "oraclePubkeys", + "type": { + "vec": "publicKey" + }, + "index": false + } + ] + }, + { + "name": "VrfProveEvent", + "fields": [ + { + "name": "vrfPubkey", + "type": "publicKey", + "index": true + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": true + }, + { + "name": "authorityPubkey", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "VrfVerifyEvent", + "fields": [ + { + "name": "vrfPubkey", + "type": "publicKey", + "index": true + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": true + }, + { + "name": "authorityPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "VrfCallbackPerformedEvent", + "fields": [ + { + "name": "vrfPubkey", + "type": "publicKey", + "index": true + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": true + }, + { + "name": "amount", + "type": "u64", + "index": false + } + ] + }, + { + "name": "AggregatorOpenRoundEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "oraclePubkeys", + "type": { + "vec": "publicKey" + }, + "index": false + }, + { + "name": "jobPubkeys", + "type": { + "vec": "publicKey" + }, + "index": false + }, + { + "name": "remainingFunds", + "type": "u64", + "index": false + }, + { + "name": "queueAuthority", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "AggregatorValueUpdateEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "value", + "type": { + "defined": "BorshDecimal" + }, + "index": false + }, + { + "name": "slot", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + }, + { + "name": "oraclePubkeys", + "type": { + "vec": "publicKey" + }, + "index": false + }, + { + "name": "oracleValues", + "type": { + "vec": { + "defined": "BorshDecimal" + } + }, + "index": false + } + ] + }, + { + "name": "OracleRewardEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "walletPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + }, + { + "name": "roundSlot", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "OracleWithdrawEvent", + "fields": [ + { + "name": "oraclePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "walletPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "destinationWallet", + "type": "publicKey", + "index": false + }, + { + "name": "previousAmount", + "type": "u64", + "index": false + }, + { + "name": "newAmount", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "LeaseWithdrawEvent", + "fields": [ + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "walletPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "previousAmount", + "type": "u64", + "index": false + }, + { + "name": "newAmount", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "OracleSlashEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "walletPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + }, + { + "name": "roundSlot", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "LeaseFundEvent", + "fields": [ + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "funder", + "type": "publicKey", + "index": false + }, + { + "name": "amount", + "type": "u64", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "ProbationBrokenEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "queuePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "FeedPermissionRevokedEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "timestamp", + "type": "i64", + "index": false + } + ] + }, + { + "name": "GarbageCollectFailureEvent", + "fields": [ + { + "name": "queuePubkey", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "OracleBootedEvent", + "fields": [ + { + "name": "queuePubkey", + "type": "publicKey", + "index": false + }, + { + "name": "oraclePubkey", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "CrankLeaseInsufficientFundsEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + } + ] + }, + { + "name": "CrankPopExpectedFailureEvent", + "fields": [ + { + "name": "feedPubkey", + "type": "publicKey", + "index": false + }, + { + "name": "leasePubkey", + "type": "publicKey", + "index": false + } + ] + } + ], + "errors": [ + { + "code": 6000, + "name": "ArrayOperationError", + "msg": "Illegal operation on a Switchboard array." + }, + { + "code": 6001, + "name": "QueueOperationError", + "msg": "Illegal operation on a Switchboard queue." + }, + { + "code": 6002, + "name": "IncorrectProgramOwnerError", + "msg": "An account required to be owned by the program has a different owner." + }, + { + "code": 6003, + "name": "InvalidAggregatorRound", + "msg": "Aggregator is not currently populated with a valid round." + }, + { + "code": 6004, + "name": "TooManyAggregatorJobs", + "msg": "Aggregator cannot fit any more jobs." + }, + { + "code": 6005, + "name": "AggregatorCurrentRoundClosed", + "msg": "Aggregator's current round is closed. No results are being accepted." + }, + { + "code": 6006, + "name": "AggregatorInvalidSaveResult", + "msg": "Aggregator received an invalid save result instruction." + }, + { + "code": 6007, + "name": "InvalidStrDecimalConversion", + "msg": "Failed to convert string to decimal format." + }, + { + "code": 6008, + "name": "AccountLoaderMissingSignature", + "msg": "AccountLoader account is missing a required signature." + }, + { + "code": 6009, + "name": "MissingRequiredSignature", + "msg": "Account is missing a required signature." + }, + { + "code": 6010, + "name": "ArrayOverflowError", + "msg": "The attempted action will overflow a zero-copy account array." + }, + { + "code": 6011, + "name": "ArrayUnderflowError", + "msg": "The attempted action will underflow a zero-copy account array." + }, + { + "code": 6012, + "name": "PubkeyNotFoundError", + "msg": "The queried public key was not found." + }, + { + "code": 6013, + "name": "AggregatorIllegalRoundOpenCall", + "msg": "Aggregator round open called too early." + }, + { + "code": 6014, + "name": "AggregatorIllegalRoundCloseCall", + "msg": "Aggregator round close called too early." + }, + { + "code": 6015, + "name": "AggregatorClosedError", + "msg": "Aggregator is closed. Illegal action." + }, + { + "code": 6016, + "name": "IllegalOracleIdxError", + "msg": "Illegal oracle index." + }, + { + "code": 6017, + "name": "OracleAlreadyRespondedError", + "msg": "The provided oracle has already responded this round." + }, + { + "code": 6018, + "name": "ProtoDeserializeError", + "msg": "Failed to deserialize protocol buffer." + }, + { + "code": 6019, + "name": "UnauthorizedStateUpdateError", + "msg": "Unauthorized program state modification attempted." + }, + { + "code": 6020, + "name": "MissingOracleAccountsError", + "msg": "Not enough oracle accounts provided to closeRounds." + }, + { + "code": 6021, + "name": "OracleMismatchError", + "msg": "An unexpected oracle account was provided for the transaction." + }, + { + "code": 6022, + "name": "CrankMaxCapacityError", + "msg": "Attempted to push to a Crank that's at capacity" + }, + { + "code": 6023, + "name": "AggregatorLeaseInsufficientFunds", + "msg": "Aggregator update call attempted but attached lease has insufficient funds." + }, + { + "code": 6024, + "name": "IncorrectTokenAccountMint", + "msg": "The provided token account does not point to the Switchboard token mint." + }, + { + "code": 6025, + "name": "InvalidEscrowAccount", + "msg": "An invalid escrow account was provided." + }, + { + "code": 6026, + "name": "CrankEmptyError", + "msg": "Crank empty. Pop failed." + }, + { + "code": 6027, + "name": "PdaDeriveError", + "msg": "Failed to derive a PDA from the provided seed." + }, + { + "code": 6028, + "name": "AggregatorAccountNotFound", + "msg": "Aggregator account missing from provided account list." + }, + { + "code": 6029, + "name": "PermissionAccountNotFound", + "msg": "Permission account missing from provided account list." + }, + { + "code": 6030, + "name": "LeaseAccountDeriveFailure", + "msg": "Failed to derive a lease account." + }, + { + "code": 6031, + "name": "PermissionAccountDeriveFailure", + "msg": "Failed to derive a permission account." + }, + { + "code": 6032, + "name": "EscrowAccountNotFound", + "msg": "Escrow account missing from provided account list." + }, + { + "code": 6033, + "name": "LeaseAccountNotFound", + "msg": "Lease account missing from provided account list." + }, + { + "code": 6034, + "name": "DecimalConversionError", + "msg": "Decimal conversion method failed." + }, + { + "code": 6035, + "name": "PermissionDenied", + "msg": "Permission account is missing required flags for the given action." + }, + { + "code": 6036, + "name": "QueueAtCapacity", + "msg": "Oracle queue is at lease capacity." + }, + { + "code": 6037, + "name": "ExcessiveCrankRowsError", + "msg": "Data feed is already pushed on a crank." + }, + { + "code": 6038, + "name": "AggregatorLockedError", + "msg": "Aggregator is locked, no setting modifications or job additions allowed." + }, + { + "code": 6039, + "name": "AggregatorInvalidBatchSizeError", + "msg": "Aggregator invalid batch size." + }, + { + "code": 6040, + "name": "AggregatorJobChecksumMismatch", + "msg": "Oracle provided an incorrect aggregator job checksum." + }, + { + "code": 6041, + "name": "IntegerOverflowError", + "msg": "An integer overflow occurred." + }, + { + "code": 6042, + "name": "InvalidUpdatePeriodError", + "msg": "Minimum update period is 5 seconds." + }, + { + "code": 6043, + "name": "NoResultsError", + "msg": "Aggregator round evaluation attempted with no results." + }, + { + "code": 6044, + "name": "InvalidExpirationError", + "msg": "An expiration constraint was broken." + }, + { + "code": 6045, + "name": "InsufficientStakeError", + "msg": "An account provided insufficient stake for action." + }, + { + "code": 6046, + "name": "LeaseInactiveError", + "msg": "The provided lease account is not active." + }, + { + "code": 6047, + "name": "NoAggregatorJobsFound", + "msg": "No jobs are currently included in the aggregator." + }, + { + "code": 6048, + "name": "IntegerUnderflowError", + "msg": "An integer underflow occurred." + }, + { + "code": 6049, + "name": "OracleQueueMismatch", + "msg": "An invalid oracle queue account was provided." + }, + { + "code": 6050, + "name": "OracleWalletMismatchError", + "msg": "An unexpected oracle wallet account was provided for the transaction." + }, + { + "code": 6051, + "name": "InvalidBufferAccountError", + "msg": "An invalid buffer account was provided." + }, + { + "code": 6052, + "name": "InsufficientOracleQueueError", + "msg": "Insufficient oracle queue size." + }, + { + "code": 6053, + "name": "InvalidAuthorityError", + "msg": "Invalid authority account provided." + }, + { + "code": 6054, + "name": "InvalidTokenAccountMintError", + "msg": "A provided token wallet is associated with an incorrect mint." + }, + { + "code": 6055, + "name": "ExcessiveLeaseWithdrawlError", + "msg": "You must leave enough funds to perform at least 1 update in the lease." + }, + { + "code": 6056, + "name": "InvalideHistoryAccountError", + "msg": "Invalid history account provided." + }, + { + "code": 6057, + "name": "InvalidLeaseAccountEscrowError", + "msg": "Invalid lease account escrow." + }, + { + "code": 6058, + "name": "InvalidCrankAccountError", + "msg": "Invalid crank provided." + }, + { + "code": 6059, + "name": "CrankNoElementsReadyError", + "msg": "No elements ready to be popped." + }, + { + "code": 6060, + "name": "IndexOutOfBoundsError", + "msg": "Index out of bounds" + }, + { + "code": 6061, + "name": "VrfInvalidRequestError", + "msg": "Invalid vrf request params" + }, + { + "code": 6062, + "name": "VrfInvalidProofSubmissionError", + "msg": "Vrf proof failed to verify" + }, + { + "code": 6063, + "name": "VrfVerifyError", + "msg": "Error in verifying vrf proof." + }, + { + "code": 6064, + "name": "VrfCallbackError", + "msg": "Vrf callback function failed." + }, + { + "code": 6065, + "name": "VrfCallbackParamsError", + "msg": "Invalid vrf callback params provided." + }, + { + "code": 6066, + "name": "VrfCallbackAlreadyCalledError", + "msg": "Vrf callback has already been triggered." + }, + { + "code": 6067, + "name": "VrfInvalidPubkeyError", + "msg": "The provided pubkey is invalid to use in ecvrf proofs" + }, + { + "code": 6068, + "name": "VrfTooManyVerifyCallsError", + "msg": "Number of required verify calls exceeded" + }, + { + "code": 6069, + "name": "VrfRequestAlreadyLaunchedError", + "msg": "Vrf request is already pending" + }, + { + "code": 6070, + "name": "VrfInsufficientVerificationError", + "msg": "Insufficient amount of proofs collected for VRF callback" + }, + { + "code": 6071, + "name": "InvalidVrfProducerError", + "msg": "An incorrect oracle attempted to submit a proof" + }, + { + "code": 6072, + "name": "NoopError", + "msg": "Noop error" + } + ] +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 4ef1ff3..0a9c85e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -52,6 +52,7 @@ "types": [ "node", "mocha", + "chai", "long" ] /* Specify type package names to be included without being referenced in a source file. */, // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ @@ -71,7 +72,7 @@ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ // "outDir": "./", /* Specify an output folder for all emitted files. */ // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ + "noEmit": true /* Disable emitting files from a compilation. */, "importHelpers": true /* Allow importing helper functions from tslib once per project, instead of including them per-file. */, "importsNotUsedAsValues": "error" /* Specify emit/checking behavior for imports that are only used for types */, // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ diff --git a/website/idl/errors.md b/website/idl/errors.md index af33939..6de314d 100644 --- a/website/idl/errors.md +++ b/website/idl/errors.md @@ -5,82 +5,82 @@ title: Errors ## Anchor Errors -See [@project-serum/anchor/src/error.ts#L53](https://github.com/project-serum/anchor/blob/HEAD/ts/src/error.ts#L53) for a list of built-in Anchor errors. +See [docs.rs/anchor-lang/latest/anchor_lang/error](https://docs.rs/anchor-lang/latest/anchor_lang/error/enum.ErrorCode.html) for a list of built-in Anchor errors. ## Switchboard Errors -| Code | Hex | Name | Message | -| ---- | ------ | -------------------------------- | --------------------------------------------------------------------------- | -| 6000 | 0x0x1770 | ArrayOperationError | Illegal operation on a Switchboard array. | -| 6001 | 0x0x1771 | QueueOperationError | Illegal operation on a Switchboard queue. | -| 6002 | 0x0x1772 | IncorrectProgramOwnerError | An account required to be owned by the program has a different owner. | -| 6003 | 0x0x1773 | InvalidAggregatorRound | Aggregator is not currently populated with a valid round. | -| 6004 | 0x0x1774 | TooManyAggregatorJobs | Aggregator cannot fit any more jobs. | -| 6005 | 0x0x1775 | AggregatorCurrentRoundClosed | Aggregator's current round is closed. No results are being accepted. | -| 6006 | 0x0x1776 | AggregatorInvalidSaveResult | Aggregator received an invalid save result instruction. | -| 6007 | 0x0x1777 | InvalidStrDecimalConversion | Failed to convert string to decimal format. | -| 6008 | 0x0x1778 | AccountLoaderMissingSignature | AccountLoader account is missing a required signature. | -| 6009 | 0x0x1779 | MissingRequiredSignature | Account is missing a required signature. | -| 6010 | 0x0x177a | ArrayOverflowError | The attempted action will overflow a zero-copy account array. | -| 6011 | 0x0x177b | ArrayUnderflowError | The attempted action will underflow a zero-copy account array. | -| 6012 | 0x0x177c | PubkeyNotFoundError | The queried public key was not found. | -| 6013 | 0x0x177d | AggregatorIllegalRoundOpenCall | Aggregator round open called too early. | -| 6014 | 0x0x177e | AggregatorIllegalRoundCloseCall | Aggregator round close called too early. | -| 6015 | 0x0x177f | AggregatorClosedError | Aggregator is closed. Illegal action. | -| 6016 | 0x0x1780 | IllegalOracleIdxError | Illegal oracle index. | -| 6017 | 0x0x1781 | OracleAlreadyRespondedError | The provided oracle has already responded this round. | -| 6018 | 0x0x1782 | ProtoDeserializeError | Failed to deserialize protocol buffer. | -| 6019 | 0x0x1783 | UnauthorizedStateUpdateError | Unauthorized program state modification attempted. | -| 6020 | 0x0x1784 | MissingOracleAccountsError | Not enough oracle accounts provided to closeRounds. | -| 6021 | 0x0x1785 | OracleMismatchError | An unexpected oracle account was provided for the transaction. | -| 6022 | 0x0x1786 | CrankMaxCapacityError | Attempted to push to a Crank that's at capacity | +| Code | Hex | Name | Message | +| ---- | -------- | -------------------------------- | --------------------------------------------------------------------------- | +| 6000 | 0x0x1770 | ArrayOperationError | Illegal operation on a Switchboard array. | +| 6001 | 0x0x1771 | QueueOperationError | Illegal operation on a Switchboard queue. | +| 6002 | 0x0x1772 | IncorrectProgramOwnerError | An account required to be owned by the program has a different owner. | +| 6003 | 0x0x1773 | InvalidAggregatorRound | Aggregator is not currently populated with a valid round. | +| 6004 | 0x0x1774 | TooManyAggregatorJobs | Aggregator cannot fit any more jobs. | +| 6005 | 0x0x1775 | AggregatorCurrentRoundClosed | Aggregator's current round is closed. No results are being accepted. | +| 6006 | 0x0x1776 | AggregatorInvalidSaveResult | Aggregator received an invalid save result instruction. | +| 6007 | 0x0x1777 | InvalidStrDecimalConversion | Failed to convert string to decimal format. | +| 6008 | 0x0x1778 | AccountLoaderMissingSignature | AccountLoader account is missing a required signature. | +| 6009 | 0x0x1779 | MissingRequiredSignature | Account is missing a required signature. | +| 6010 | 0x0x177a | ArrayOverflowError | The attempted action will overflow a zero-copy account array. | +| 6011 | 0x0x177b | ArrayUnderflowError | The attempted action will underflow a zero-copy account array. | +| 6012 | 0x0x177c | PubkeyNotFoundError | The queried public key was not found. | +| 6013 | 0x0x177d | AggregatorIllegalRoundOpenCall | Aggregator round open called too early. | +| 6014 | 0x0x177e | AggregatorIllegalRoundCloseCall | Aggregator round close called too early. | +| 6015 | 0x0x177f | AggregatorClosedError | Aggregator is closed. Illegal action. | +| 6016 | 0x0x1780 | IllegalOracleIdxError | Illegal oracle index. | +| 6017 | 0x0x1781 | OracleAlreadyRespondedError | The provided oracle has already responded this round. | +| 6018 | 0x0x1782 | ProtoDeserializeError | Failed to deserialize protocol buffer. | +| 6019 | 0x0x1783 | UnauthorizedStateUpdateError | Unauthorized program state modification attempted. | +| 6020 | 0x0x1784 | MissingOracleAccountsError | Not enough oracle accounts provided to closeRounds. | +| 6021 | 0x0x1785 | OracleMismatchError | An unexpected oracle account was provided for the transaction. | +| 6022 | 0x0x1786 | CrankMaxCapacityError | Attempted to push to a Crank that's at capacity | | 6023 | 0x0x1787 | AggregatorLeaseInsufficientFunds | Aggregator update call attempted but attached lease has insufficient funds. | -| 6024 | 0x0x1788 | IncorrectTokenAccountMint | The provided token account does not point to the Switchboard token mint. | -| 6025 | 0x0x1789 | InvalidEscrowAccount | An invalid escrow account was provided. | -| 6026 | 0x0x178a | CrankEmptyError | Crank empty. Pop failed. | -| 6027 | 0x0x178b | PdaDeriveError | Failed to derive a PDA from the provided seed. | -| 6028 | 0x0x178c | AggregatorAccountNotFound | Aggregator account missing from provided account list. | -| 6029 | 0x0x178d | PermissionAccountNotFound | Permission account missing from provided account list. | -| 6030 | 0x0x178e | LeaseAccountDeriveFailure | Failed to derive a lease account. | -| 6031 | 0x0x178f | PermissionAccountDeriveFailure | Failed to derive a permission account. | -| 6032 | 0x0x1790 | EscrowAccountNotFound | Escrow account missing from provided account list. | -| 6033 | 0x0x1791 | LeaseAccountNotFound | Lease account missing from provided account list. | -| 6034 | 0x0x1792 | DecimalConversionError | Decimal conversion method failed. | -| 6035 | 0x0x1793 | PermissionDenied | Permission account is missing required flags for the given action. | -| 6036 | 0x0x1794 | QueueAtCapacity | Oracle queue is at lease capacity. | -| 6037 | 0x0x1795 | ExcessiveCrankRowsError | Data feed is already pushed on a crank. | -| 6038 | 0x0x1796 | AggregatorLockedError | Aggregator is locked, no setting modifications or job additions allowed. | -| 6039 | 0x0x1797 | AggregatorInvalidBatchSizeError | Aggregator invalid batch size. | -| 6040 | 0x0x1798 | AggregatorJobChecksumMismatch | Oracle provided an incorrect aggregator job checksum. | -| 6041 | 0x0x1799 | IntegerOverflowError | An integer overflow occurred. | -| 6042 | 0x0x179a | InvalidUpdatePeriodError | Minimum update period is 5 seconds. | -| 6043 | 0x0x179b | NoResultsError | Aggregator round evaluation attempted with no results. | -| 6044 | 0x0x179c | InvalidExpirationError | An expiration constraint was broken. | -| 6045 | 0x0x179d | InsufficientStakeError | An account provided insufficient stake for action. | -| 6046 | 0x0x179e | LeaseInactiveError | The provided lease account is not active. | -| 6047 | 0x0x179f | NoAggregatorJobsFound | No jobs are currently included in the aggregator. | -| 6048 | 0x0x17a0 | IntegerUnderflowError | An integer underflow occurred. | -| 6049 | 0x0x17a1 | OracleQueueMismatch | An invalid oracle queue account was provided. | -| 6050 | 0x0x17a2 | OracleWalletMismatchError | An unexpected oracle wallet account was provided for the transaction. | -| 6051 | 0x0x17a3 | InvalidBufferAccountError | An invalid buffer account was provided. | -| 6052 | 0x0x17a4 | InsufficientOracleQueueError | Insufficient oracle queue size. | -| 6053 | 0x0x17a5 | InvalidAuthorityError | Invalid authority account provided. | -| 6054 | 0x0x17a6 | InvalidTokenAccountMintError | A provided token wallet is associated with an incorrect mint. | -| 6055 | 0x0x17a7 | ExcessiveLeaseWithdrawlError | You must leave enough funds to perform at least 1 update in the lease. | -| 6056 | 0x0x17a8 | InvalideHistoryAccountError | Invalid history account provided. | -| 6057 | 0x0x17a9 | InvalidLeaseAccountEscrowError | Invalid lease account escrow. | -| 6058 | 0x0x17aa | InvalidCrankAccountError | Invalid crank provided. | -| 6059 | 0x0x17ab | CrankNoElementsReadyError | No elements ready to be popped. | -| 6060 | 0x0x17ac | IndexOutOfBoundsError | Index out of bounds | -| 6061 | 0x0x17ad | VrfInvalidRequestError | Invalid vrf request params | -| 6062 | 0x0x17ae | VrfInvalidProofSubmissionError | Vrf proof failed to verify | -| 6063 | 0x0x17af | VrfVerifyError | Error in verifying vrf proof. | -| 6064 | 0x0x17b0 | VrfCallbackError | Vrf callback function failed. | -| 6065 | 0x0x17b1 | VrfCallbackParamsError | Invalid vrf callback params provided. | -| 6066 | 0x0x17b2 | VrfCallbackAlreadyCalledError | Vrf callback has already been triggered. | -| 6067 | 0x0x17b3 | VrfInvalidPubkeyError | The provided pubkey is invalid to use in ecvrf proofs | -| 6068 | 0x0x17b4 | VrfTooManyVerifyCallsError | Number of required verify calls exceeded | -| 6069 | 0x0x17b5 | VrfRequestAlreadyLaunchedError | Vrf request is already pending | -| 6070 | 0x0x17b6 | VrfInsufficientVerificationError | Insufficient amount of proofs collected for VRF callback | -| 6071 | 0x0x17b7 | InvalidVrfProducerError | An incorrect oracle attempted to submit a proof | -| 6072 | 0x0x17b8 | NoopError | Noop error | +| 6024 | 0x0x1788 | IncorrectTokenAccountMint | The provided token account does not point to the Switchboard token mint. | +| 6025 | 0x0x1789 | InvalidEscrowAccount | An invalid escrow account was provided. | +| 6026 | 0x0x178a | CrankEmptyError | Crank empty. Pop failed. | +| 6027 | 0x0x178b | PdaDeriveError | Failed to derive a PDA from the provided seed. | +| 6028 | 0x0x178c | AggregatorAccountNotFound | Aggregator account missing from provided account list. | +| 6029 | 0x0x178d | PermissionAccountNotFound | Permission account missing from provided account list. | +| 6030 | 0x0x178e | LeaseAccountDeriveFailure | Failed to derive a lease account. | +| 6031 | 0x0x178f | PermissionAccountDeriveFailure | Failed to derive a permission account. | +| 6032 | 0x0x1790 | EscrowAccountNotFound | Escrow account missing from provided account list. | +| 6033 | 0x0x1791 | LeaseAccountNotFound | Lease account missing from provided account list. | +| 6034 | 0x0x1792 | DecimalConversionError | Decimal conversion method failed. | +| 6035 | 0x0x1793 | PermissionDenied | Permission account is missing required flags for the given action. | +| 6036 | 0x0x1794 | QueueAtCapacity | Oracle queue is at lease capacity. | +| 6037 | 0x0x1795 | ExcessiveCrankRowsError | Data feed is already pushed on a crank. | +| 6038 | 0x0x1796 | AggregatorLockedError | Aggregator is locked, no setting modifications or job additions allowed. | +| 6039 | 0x0x1797 | AggregatorInvalidBatchSizeError | Aggregator invalid batch size. | +| 6040 | 0x0x1798 | AggregatorJobChecksumMismatch | Oracle provided an incorrect aggregator job checksum. | +| 6041 | 0x0x1799 | IntegerOverflowError | An integer overflow occurred. | +| 6042 | 0x0x179a | InvalidUpdatePeriodError | Minimum update period is 5 seconds. | +| 6043 | 0x0x179b | NoResultsError | Aggregator round evaluation attempted with no results. | +| 6044 | 0x0x179c | InvalidExpirationError | An expiration constraint was broken. | +| 6045 | 0x0x179d | InsufficientStakeError | An account provided insufficient stake for action. | +| 6046 | 0x0x179e | LeaseInactiveError | The provided lease account is not active. | +| 6047 | 0x0x179f | NoAggregatorJobsFound | No jobs are currently included in the aggregator. | +| 6048 | 0x0x17a0 | IntegerUnderflowError | An integer underflow occurred. | +| 6049 | 0x0x17a1 | OracleQueueMismatch | An invalid oracle queue account was provided. | +| 6050 | 0x0x17a2 | OracleWalletMismatchError | An unexpected oracle wallet account was provided for the transaction. | +| 6051 | 0x0x17a3 | InvalidBufferAccountError | An invalid buffer account was provided. | +| 6052 | 0x0x17a4 | InsufficientOracleQueueError | Insufficient oracle queue size. | +| 6053 | 0x0x17a5 | InvalidAuthorityError | Invalid authority account provided. | +| 6054 | 0x0x17a6 | InvalidTokenAccountMintError | A provided token wallet is associated with an incorrect mint. | +| 6055 | 0x0x17a7 | ExcessiveLeaseWithdrawlError | You must leave enough funds to perform at least 1 update in the lease. | +| 6056 | 0x0x17a8 | InvalideHistoryAccountError | Invalid history account provided. | +| 6057 | 0x0x17a9 | InvalidLeaseAccountEscrowError | Invalid lease account escrow. | +| 6058 | 0x0x17aa | InvalidCrankAccountError | Invalid crank provided. | +| 6059 | 0x0x17ab | CrankNoElementsReadyError | No elements ready to be popped. | +| 6060 | 0x0x17ac | IndexOutOfBoundsError | Index out of bounds | +| 6061 | 0x0x17ad | VrfInvalidRequestError | Invalid vrf request params | +| 6062 | 0x0x17ae | VrfInvalidProofSubmissionError | Vrf proof failed to verify | +| 6063 | 0x0x17af | VrfVerifyError | Error in verifying vrf proof. | +| 6064 | 0x0x17b0 | VrfCallbackError | Vrf callback function failed. | +| 6065 | 0x0x17b1 | VrfCallbackParamsError | Invalid vrf callback params provided. | +| 6066 | 0x0x17b2 | VrfCallbackAlreadyCalledError | Vrf callback has already been triggered. | +| 6067 | 0x0x17b3 | VrfInvalidPubkeyError | The provided pubkey is invalid to use in ecvrf proofs | +| 6068 | 0x0x17b4 | VrfTooManyVerifyCallsError | Number of required verify calls exceeded | +| 6069 | 0x0x17b5 | VrfRequestAlreadyLaunchedError | Vrf request is already pending | +| 6070 | 0x0x17b6 | VrfInsufficientVerificationError | Insufficient amount of proofs collected for VRF callback | +| 6071 | 0x0x17b7 | InvalidVrfProducerError | An incorrect oracle attempted to submit a proof | +| 6072 | 0x0x17b8 | NoopError | Noop error | diff --git a/website/package.json b/website/package.json index a3eeaf1..fcd0fc7 100644 --- a/website/package.json +++ b/website/package.json @@ -11,7 +11,7 @@ "scripts": { "docusaurus": "docusaurus", "start": "docusaurus start", - "build": "echo \"Use 'npm run build:site' to build the docusaurus project\" && exit 0", + "build": "For workspace website, run 'yarn docs:build' from the project root", "build:site": "docusaurus build --out-dir public", "swizzle": "docusaurus swizzle", "deploy": "docusaurus build --out-dir public && docusaurus deploy --out-dir public", diff --git a/yarn.lock b/yarn.lock index f25d1f7..d5c571b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2846,38 +2846,6 @@ resolved "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz" integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== -"@metaplex-foundation/beet-solana@^0.1.1": - version "0.1.1" - resolved "https://registry.npmjs.org/@metaplex-foundation/beet-solana/-/beet-solana-0.1.1.tgz" - integrity sha512-QV2DbxjaJWLkMvn12OC09g+r7a6R0uNwf8msYuOUSw4cG7amXzvFb7s0bh4IxY3Rk8/0ma0PfKi/FEdC7Hi4Pg== - dependencies: - "@metaplex-foundation/beet" ">=0.1.0" - "@solana/web3.js" "^1.31.0" - -"@metaplex-foundation/beet@>=0.1.0", "@metaplex-foundation/beet@^0.1.0": - version "0.1.0" - resolved "https://registry.npmjs.org/@metaplex-foundation/beet/-/beet-0.1.0.tgz" - integrity sha512-6SKV0Tp1+onU1vjBA26wvgPIKpxhnYINNpnpxvBpK9Cl8dNfz5+sfdx6opaKcljpCSaRpQqHfdtEn6qlYVCO8A== - dependencies: - ansicolors "^0.3.2" - bn.js "^5.2.0" - debug "^4.3.3" - -"@metaplex-foundation/solita@^0.2.1": - version "0.2.1" - resolved "https://registry.npmjs.org/@metaplex-foundation/solita/-/solita-0.2.1.tgz" - integrity sha512-dEC5g2/9MK9io+sglYmItjmmERkw/yKqQNEPHac5aW/QFQRdzRySggulE0UbCiuVegqwIKMEPxqOKf4/w7n86A== - dependencies: - "@metaplex-foundation/beet" "^0.1.0" - "@metaplex-foundation/beet-solana" "^0.1.1" - "@solana/web3.js" "^1.36.0" - camelcase "^6.2.1" - debug "^4.3.3" - js-sha256 "^0.9.0" - prettier "^2.5.1" - snake-case "^3.0.4" - spok "^1.4.3" - "@mui/base@5.0.0-alpha.78": version "5.0.0-alpha.78" resolved "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.78.tgz" @@ -3571,9 +3539,9 @@ snake-case "^3.0.4" toml "^3.0.0" -"@project-serum/anchor@^0.24.2": +"@project-serum/anchor@^0.24.1", "@project-serum/anchor@^0.24.2": version "0.24.2" - resolved "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz" + resolved "https://registry.npmjs.org/@project-serum/anchor/-/anchor-0.24.2.tgz#a3c52a99605c80735f446ca9b3a4885034731004" integrity sha512-0/718g8/DnEuwAidUwh5wLYphUYXhUbiClkuRNhvNoa+1Y8a4g2tJyxoae+emV+PG/Gikd/QUBNMkIcimiIRTA== dependencies: "@project-serum/borsh" "^0.2.5" @@ -3917,7 +3885,7 @@ tweetnacl "^1.0.0" ws "^7.0.0" -"@solana/web3.js@^1.10.0", "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.20.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.24.1", "@solana/web3.js@^1.31.0", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.33.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.37.1": +"@solana/web3.js@^1.10.0", "@solana/web3.js@^1.17.0", "@solana/web3.js@^1.20.0", "@solana/web3.js@^1.21.0", "@solana/web3.js@^1.22.0", "@solana/web3.js@^1.24.1", "@solana/web3.js@^1.32.0", "@solana/web3.js@^1.33.0", "@solana/web3.js@^1.35.1", "@solana/web3.js@^1.36.0", "@solana/web3.js@^1.37.1": version "1.37.1" resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.37.1.tgz" integrity sha512-1zm1blRU6ANb8bOfONibKkNKoMyzE1e0Z88MagyRLF1AmfHc+18lFvqxSQKUdazLMHcioZ28h+GfyAaeCT63iA== @@ -3981,6 +3949,28 @@ superstruct "^0.14.2" tweetnacl "^1.0.0" +"@solana/web3.js@^1.42.0": + version "1.42.0" + resolved "https://registry.npmjs.org/@solana/web3.js/-/web3.js-1.42.0.tgz#296e4bbab1fbfc198b3e9c3d94016c3876eb6a2c" + integrity sha512-QqGh5DWzrgsWRx4sCPDQIm3390b7buPR16tZI61slQaQwJ2ymrSXPQCe4PPTJEIlzGjCV3dkn2vpT2R32BfK2Q== + dependencies: + "@babel/runtime" "^7.12.5" + "@ethersproject/sha2" "^5.5.0" + "@solana/buffer-layout" "^4.0.0" + "@solana/buffer-layout-utils" "^0.2.0" + bn.js "^5.0.0" + borsh "^0.7.0" + bs58 "^4.0.1" + buffer "6.0.1" + cross-fetch "^3.1.4" + fast-stable-stringify "^1.0.0" + jayson "^3.4.4" + js-sha3 "^0.8.0" + rpc-websockets "^7.4.2" + secp256k1 "^4.0.2" + superstruct "^0.14.2" + tweetnacl "^1.0.0" + "@svgr/babel-plugin-add-jsx-attribute@^5.4.0": version "5.4.0" resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz" @@ -4275,6 +4265,16 @@ resolved "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@ts-morph/common@~0.12.3": + version "0.12.3" + resolved "https://registry.npmjs.org/@ts-morph/common/-/common-0.12.3.tgz#a96e250217cd30e480ab22ec6a0ebbe65fd784ff" + integrity sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w== + dependencies: + fast-glob "^3.2.7" + minimatch "^3.0.4" + mkdirp "^1.0.4" + path-browserify "^1.0.1" + "@tsconfig/docusaurus@^1.0.4": version "1.0.5" resolved "https://registry.npmjs.org/@tsconfig/docusaurus/-/docusaurus-1.0.5.tgz" @@ -4473,9 +4473,9 @@ resolved "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz" integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== -"@types/mocha@^9.0.0", "@types/mocha@^9.1.0": +"@types/mocha@^9.0.0", "@types/mocha@^9.1.0", "@types/mocha@^9.1.1": version "9.1.1" - resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz" + resolved "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz#e7c4f1001eefa4b8afbd1eee27a237fee3bf29c4" integrity sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw== "@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0", "@types/node@^17.0.23", "@types/node@^17.0.25", "@types/node@^17.0.5": @@ -5119,6 +5119,22 @@ algoliasearch@^4.0.0, algoliasearch@^4.13.0: "@algolia/requester-node-http" "4.13.0" "@algolia/transporter" "4.13.0" +anchor-client-gen@^0.24.0: + version "0.24.0" + resolved "https://registry.npmjs.org/anchor-client-gen/-/anchor-client-gen-0.24.0.tgz#25aebebf93a7d6032866fff821260158338f06c4" + integrity sha512-FGGPrvek3l2mNXmU1fmFR09QIUR4bi8PlcM+pqRBox5GonOkR6UQ3Z1+NlVvEaW3CQMxfHxHTyWFEEPZPmpD2A== + dependencies: + "@project-serum/anchor" "^0.24.1" + "@project-serum/borsh" "^0.2.5" + "@solana/web3.js" "^1.36.0" + bn.js "^5.1.2" + camelcase "^5.3.1" + commander "^9.0.0" + js-sha256 "^0.9.0" + prettier "^2.5.1" + snake-case "^3.0.4" + ts-morph "^13.0.3" + ansi-align@^3.0.0, ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz" @@ -5192,7 +5208,7 @@ ansi-styles@^6.1.0: resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz" integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ== -ansicolors@^0.3.2, ansicolors@~0.3.2: +ansicolors@~0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz" integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= @@ -5973,7 +5989,7 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -camelcase@^6.0.0, camelcase@^6.2.0, camelcase@^6.2.1: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== @@ -6354,6 +6370,13 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" +code-block-writer@^11.0.0: + version "11.0.0" + resolved "https://registry.npmjs.org/code-block-writer/-/code-block-writer-11.0.0.tgz#5956fb186617f6740e2c3257757fea79315dd7d4" + integrity sha512-GEqWvEWWsOvER+g9keO4ohFoD3ymwyCnqY3hoTr7GZipYFwEhMHJw+TtV0rfgRhNImM6QWZGO2XYjlJVyYT62w== + dependencies: + tslib "2.3.1" + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" @@ -6480,7 +6503,7 @@ commander@^8.3.0: resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== -commander@^9.1.0: +commander@^9.0.0, commander@^9.1.0: version "9.2.0" resolved "https://registry.npmjs.org/commander/-/commander-9.2.0.tgz" integrity sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w== @@ -7104,7 +7127,7 @@ debug@2.6.9, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: +debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -11372,6 +11395,13 @@ minimatch@4.2.1: dependencies: brace-expansion "^1.1.7" +minimatch@5.0.1, minimatch@^5.0.1: + version "5.0.1" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" @@ -11379,13 +11409,6 @@ minimatch@^3.0.4, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - minimist-options@4.1.0: version "4.1.0" resolved "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz" @@ -11503,6 +11526,34 @@ mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1: dependencies: minimist "^1.2.6" +mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + mocha@^9.0.3, mocha@^9.1.1, mocha@^9.1.3, mocha@^9.2.2: version "9.2.2" resolved "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz" @@ -11609,6 +11660,11 @@ nanoid@3.3.1, nanoid@^3.3.1: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -12565,6 +12621,11 @@ password-prompt@^1.1.2: ansi-escapes "^3.1.0" cross-spawn "^6.0.5" +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz" @@ -14395,7 +14456,7 @@ shell-quote@^1.6.1, shell-quote@^1.7.3: shelljs@^0.8.5: version "0.8.5" - resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz" + resolved "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== dependencies: glob "^7.0.0" @@ -14682,13 +14743,6 @@ split@^1.0.0: dependencies: through "2" -spok@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/spok/-/spok-1.4.3.tgz" - integrity sha512-5wFGctwrk638aDs+44u99kohxFNByUq2wo0uShQ9yqxSmsxqx7zKbMo1Busy4s7stZQXU+PhJ/BlVf2XWFEGIw== - dependencies: - ansicolors "~0.3.2" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" @@ -15380,6 +15434,15 @@ trough@^1.0.0: resolved "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz" integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== +ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + ts-mocha@^9.0.2: version "9.0.2" resolved "https://registry.npmjs.org/ts-mocha/-/ts-mocha-9.0.2.tgz" @@ -15389,6 +15452,14 @@ ts-mocha@^9.0.2: optionalDependencies: tsconfig-paths "^3.5.0" +ts-morph@^13.0.3: + version "13.0.3" + resolved "https://registry.npmjs.org/ts-morph/-/ts-morph-13.0.3.tgz#c0c51d1273ae2edb46d76f65161eb9d763444c1d" + integrity sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw== + dependencies: + "@ts-morph/common" "~0.12.3" + code-block-writer "^11.0.0" + ts-node@7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/ts-node/-/ts-node-7.0.1.tgz" @@ -16350,6 +16421,11 @@ workerpool@6.2.0: resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz" integrity sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A== +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz"