├── .changeset
├── README.md
└── config.json
├── .docs
├── README.template.md
├── clients.yaml
├── examples.yaml
├── javascript
│ ├── feed-walkthrough
│ │ ├── README.template.md
│ │ └── usage
│ │ │ ├── create-a-feed-with-cli.md
│ │ │ ├── create-devnet-feed.md
│ │ │ ├── create-private-network.md
│ │ │ ├── meta.yaml
│ │ │ └── simulate-an-oracle-job.md
│ └── solana.js
│ │ ├── README.template.md
│ │ └── usage
│ │ ├── add-an-oracle.ts
│ │ ├── add-history-buffer.ts
│ │ ├── create-a-data-feed.ts
│ │ ├── create-queue.ts
│ │ ├── load-program.ts
│ │ ├── meta.yaml
│ │ ├── read-data-feed.ts
│ │ ├── request-a-new-value.ts
│ │ └── watch-data-feed.ts
├── programs
│ ├── anchor-buffer-parser
│ │ └── README.template.md
│ ├── anchor-feed-parser
│ │ └── README.template.md
│ ├── anchor-history-parser
│ │ └── README.template.md
│ ├── anchor-vrf-lite-parser
│ │ └── README.template.md
│ ├── anchor-vrf-parser
│ │ └── README.template.md
│ └── native-feed-parser
│ │ └── README.template.md
└── rust
│ └── switchboard-v2
│ ├── README.template.md
│ └── usage
│ ├── meta.yaml
│ ├── read-buffer.rs
│ ├── read-history.rs
│ ├── read-result.rs
│ ├── read-vrf.rs
│ └── request-randomness.rs
├── .github
├── actions
│ └── setup-workspace
│ │ └── action.yaml
├── dependabot
│ ├── dependabot.yml
│ └── rebase.yml
└── workflows
│ ├── anchor-test.yml
│ ├── copybara.yml
│ └── solana-js-test.yml
├── .gitignore
├── .npmrc
├── .vscode
├── extensions.json
└── settings.json
├── LICENSE
├── README.md
├── examples
├── feeds
│ ├── 01_feed_client
│ │ ├── .gitignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── src
│ │ │ └── lib.rs
│ │ ├── tests
│ │ │ └── switchboard-feed-client.test.ts
│ │ └── tsconfig.json
│ └── 02_spl_native
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── src
│ │ └── lib.rs
│ │ ├── tests
│ │ └── spl-feed-parser.test.ts
│ │ └── tsconfig.json
├── functions
│ ├── 01_basic_oracle
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── scripts
│ │ │ ├── devnet.ts
│ │ │ └── fnCreate.ts
│ │ ├── src
│ │ │ ├── actions
│ │ │ │ ├── initialize.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── refresh_prices.rs
│ │ │ │ └── set_function.rs
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── model.rs
│ │ │ └── utils.rs
│ │ ├── switchboard-function
│ │ │ ├── .gitignore
│ │ │ ├── Cargo.lock
│ │ │ ├── Cargo.toml
│ │ │ ├── Dockerfile
│ │ │ ├── Dockerfile.dev
│ │ │ ├── Makefile
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── binance.rs
│ │ │ │ └── main.rs
│ │ ├── tests
│ │ │ ├── basic_oracle.ts
│ │ │ └── utils.ts
│ │ └── tsconfig.json
│ ├── 02_liquidity_oracle
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── scripts
│ │ │ ├── devnet.ts
│ │ │ └── init_program.ts
│ │ ├── src
│ │ │ ├── actions
│ │ │ │ ├── initialize.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── refresh_prices.rs
│ │ │ │ ├── set_function.rs
│ │ │ │ └── trigger_function.rs
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── model.rs
│ │ │ └── utils.rs
│ │ ├── switchboard-function
│ │ │ ├── .gitignore
│ │ │ ├── Cargo.lock
│ │ │ ├── Cargo.toml
│ │ │ ├── Dockerfile
│ │ │ ├── Dockerfile.dev
│ │ │ ├── Makefile
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── binance.rs
│ │ │ │ ├── bitfinex.rs
│ │ │ │ ├── coinbase.rs
│ │ │ │ ├── kraken.rs
│ │ │ │ └── main.rs
│ │ ├── tests
│ │ │ ├── basic_oracle.ts
│ │ │ └── utils.ts
│ │ └── tsconfig.json
│ ├── 03_candles_oracle
│ │ ├── .dockerignore
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── scripts
│ │ │ ├── devnet.ts
│ │ │ └── init_program.ts
│ │ ├── src
│ │ │ ├── actions
│ │ │ │ ├── initialize.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── refresh_prices.rs
│ │ │ │ ├── set_function.rs
│ │ │ │ └── trigger_function.rs
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── model.rs
│ │ │ └── utils.rs
│ │ ├── switchboard-function
│ │ │ ├── .gitignore
│ │ │ ├── Cargo.lock
│ │ │ ├── Cargo.toml
│ │ │ ├── Dockerfile
│ │ │ ├── Dockerfile.dev
│ │ │ ├── Makefile
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── binance.rs
│ │ │ │ ├── bitfinex.rs
│ │ │ │ ├── coinbase.rs
│ │ │ │ ├── kraken.rs
│ │ │ │ └── main.rs
│ │ ├── tests
│ │ │ ├── basic_oracle.ts
│ │ │ └── utils.ts
│ │ └── tsconfig.json
│ ├── 04_randomness_callback
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── request.ts
│ │ ├── src
│ │ │ ├── error.rs
│ │ │ ├── lib.rs
│ │ │ ├── state.rs
│ │ │ └── utils.rs
│ │ ├── switchboard-function
│ │ │ ├── .dockerignore
│ │ │ ├── .gitignore
│ │ │ ├── Cargo.lock
│ │ │ ├── Cargo.toml
│ │ │ ├── Dockerfile
│ │ │ ├── Dockerfile.dev
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ └── src
│ │ │ │ ├── main.rs
│ │ │ │ └── params.rs
│ │ ├── tests
│ │ │ ├── custom_randomness_request.ts
│ │ │ └── utils.ts
│ │ └── tsconfig.json
│ └── 05_raffle_program
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── Anchor.toml
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── Xargo.toml
│ │ ├── package.json
│ │ ├── src
│ │ ├── actions
│ │ │ ├── close_round.rs
│ │ │ ├── initialize.rs
│ │ │ ├── mod.rs
│ │ │ └── start_round.rs
│ │ ├── error.rs
│ │ └── lib.rs
│ │ ├── switchboard-function
│ │ ├── .dockerignore
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── Dockerfile
│ │ ├── Makefile
│ │ ├── README.md
│ │ └── src
│ │ │ ├── main.rs
│ │ │ └── params.rs
│ │ ├── tests
│ │ ├── raffle-program.ts
│ │ └── utils.ts
│ │ └── tsconfig.json
└── vrf
│ ├── 01_vrf_client
│ ├── .gitignore
│ ├── Anchor.toml
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── Xargo.toml
│ ├── package.json
│ ├── src
│ │ ├── actions
│ │ │ ├── close_state.rs
│ │ │ ├── init_state.rs
│ │ │ ├── mod.rs
│ │ │ ├── request_result.rs
│ │ │ └── update_result.rs
│ │ └── lib.rs
│ ├── tests
│ │ └── anchor-vrf-lite-parser.test.ts
│ └── tsconfig.json
│ └── 02_vrf_flip
│ └── README.md
├── javascript
├── sbv2-lite
│ ├── .gitignore
│ ├── .npmignore
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ ├── idl
│ │ │ ├── index.ts
│ │ │ ├── switchboard_v2.json
│ │ │ └── switchboard_v2.ts
│ │ └── index.ts
│ ├── tests
│ │ ├── sbv2.test.ts
│ │ └── tsconfig.json
│ ├── tsconfig.base.json
│ ├── tsconfig.cjs.json
│ └── tsconfig.json
└── solana.js
│ ├── .editorconfig
│ ├── .gitignore
│ ├── .mocharc.json
│ ├── README.md
│ ├── esbuild.js
│ ├── idl
│ ├── attestation-devnet.json
│ ├── attestation-mainnet.json
│ ├── devnet.json
│ └── mainnet.json
│ ├── package.json
│ ├── scripts
│ ├── close-and-migrate.ts
│ ├── close-functions.ts
│ ├── generate-client.ts
│ ├── localnet.ts
│ ├── migrate-feeds.ts
│ ├── migrate-jobs.ts
│ ├── move-cjs-to-lib.ts
│ ├── prepare.ts
│ ├── release.ts
│ ├── set-bumps.ts
│ ├── tsconfig.json
│ └── utils.ts
│ ├── src
│ ├── SolanaClock.ts
│ ├── SwitchboardError.ts
│ ├── SwitchboardEvents.ts
│ ├── SwitchboardNetwork.ts
│ ├── SwitchboardProgram.ts
│ ├── SwitchboardTestContext.ts
│ ├── TransactionObject.ts
│ ├── accounts
│ │ ├── account.ts
│ │ ├── aggregatorAccount.ts
│ │ ├── aggregatorHistoryBuffer.ts
│ │ ├── attestationPermissionAccount.ts
│ │ ├── attestationProgramStateAccount.ts
│ │ ├── attestationQueueAccount.ts
│ │ ├── bufferRelayAccount.ts
│ │ ├── crankAccount.ts
│ │ ├── crankDataBuffer.ts
│ │ ├── functionAccount.ts
│ │ ├── functionRequestAccount.ts
│ │ ├── functionRoutineAccount.ts
│ │ ├── index.ts
│ │ ├── jobAccount.ts
│ │ ├── leaseAccount.ts
│ │ ├── oracleAccount.ts
│ │ ├── permissionAccount.ts
│ │ ├── programStateAccount.ts
│ │ ├── queueAccount.ts
│ │ ├── queueDataBuffer.ts
│ │ ├── switchboardWallet.ts
│ │ ├── verifierAccount.ts
│ │ ├── vrfAccount.ts
│ │ ├── vrfLiteAccount.ts
│ │ └── vrfPoolAccount.ts
│ ├── browser.ts
│ ├── const.ts
│ ├── errors.ts
│ ├── generated
│ │ ├── accounts.ts
│ │ ├── attestation-program
│ │ │ ├── accounts
│ │ │ │ ├── AttestationPermissionAccountData.ts
│ │ │ │ ├── AttestationProgramState.ts
│ │ │ │ ├── AttestationQueueAccountData.ts
│ │ │ │ ├── FunctionAccountData.ts
│ │ │ │ ├── FunctionRequestAccountData.ts
│ │ │ │ ├── FunctionRoutineAccountData.ts
│ │ │ │ ├── SwitchboardWallet.ts
│ │ │ │ ├── VerifierAccountData.ts
│ │ │ │ └── index.ts
│ │ │ ├── errors
│ │ │ │ ├── anchor.ts
│ │ │ │ ├── custom.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── instructions
│ │ │ │ ├── accountCloseOverride.ts
│ │ │ │ ├── attestationPermissionInit.ts
│ │ │ │ ├── attestationPermissionSet.ts
│ │ │ │ ├── attestationQueueAddMrEnclave.ts
│ │ │ │ ├── attestationQueueInit.ts
│ │ │ │ ├── attestationQueueRemoveMrEnclave.ts
│ │ │ │ ├── functionClose.ts
│ │ │ │ ├── functionDeactivateLookup.ts
│ │ │ │ ├── functionExtendLookup.ts
│ │ │ │ ├── functionInit.ts
│ │ │ │ ├── functionRequestClose.ts
│ │ │ │ ├── functionRequestInit.ts
│ │ │ │ ├── functionRequestInitAndTrigger.ts
│ │ │ │ ├── functionRequestSetConfig.ts
│ │ │ │ ├── functionRequestTrigger.ts
│ │ │ │ ├── functionRequestVerify.ts
│ │ │ │ ├── functionResetEscrow.ts
│ │ │ │ ├── functionRoutineDisable.ts
│ │ │ │ ├── functionRoutineInit.ts
│ │ │ │ ├── functionRoutineSetConfig.ts
│ │ │ │ ├── functionRoutineVerify.ts
│ │ │ │ ├── functionSetAuthority.ts
│ │ │ │ ├── functionSetConfig.ts
│ │ │ │ ├── functionSetEscrow.ts
│ │ │ │ ├── functionTrigger.ts
│ │ │ │ ├── functionVerify.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── stateInit.ts
│ │ │ │ ├── verifierHeartbeat.ts
│ │ │ │ ├── verifierInit.ts
│ │ │ │ ├── verifierQuoteRotate.ts
│ │ │ │ ├── verifierQuoteVerify.ts
│ │ │ │ ├── viewVersion.ts
│ │ │ │ ├── walletFund.ts
│ │ │ │ ├── walletInit.ts
│ │ │ │ └── walletWithdraw.ts
│ │ │ ├── programId.ts
│ │ │ └── types
│ │ │ │ ├── AttestationPermissionInitParams.ts
│ │ │ │ ├── AttestationPermissionSetParams.ts
│ │ │ │ ├── AttestationQueueAddMrEnclaveParams.ts
│ │ │ │ ├── AttestationQueueInitParams.ts
│ │ │ │ ├── AttestationQueueRemoveMrEnclaveParams.ts
│ │ │ │ ├── BoolWithLock.ts
│ │ │ │ ├── FunctionCloseParams.ts
│ │ │ │ ├── FunctionExtendLookupParams.ts
│ │ │ │ ├── FunctionInitParams.ts
│ │ │ │ ├── FunctionRequestCloseParams.ts
│ │ │ │ ├── FunctionRequestInitAndTriggerParams.ts
│ │ │ │ ├── FunctionRequestInitParams.ts
│ │ │ │ ├── FunctionRequestSetConfigParams.ts
│ │ │ │ ├── FunctionRequestTriggerParams.ts
│ │ │ │ ├── FunctionRequestTriggerRound.ts
│ │ │ │ ├── FunctionRequestVerifyParams.ts
│ │ │ │ ├── FunctionResetEscrowParams.ts
│ │ │ │ ├── FunctionRoutineDisableParams.ts
│ │ │ │ ├── FunctionRoutineInitParams.ts
│ │ │ │ ├── FunctionRoutineSetConfigParams.ts
│ │ │ │ ├── FunctionRoutineVerifyParams.ts
│ │ │ │ ├── FunctionSetAuthorityParams.ts
│ │ │ │ ├── FunctionSetConfigParams.ts
│ │ │ │ ├── FunctionSetEscrowParams.ts
│ │ │ │ ├── FunctionStatus.ts
│ │ │ │ ├── FunctionTriggerParams.ts
│ │ │ │ ├── FunctionVerifyParams.ts
│ │ │ │ ├── FundingStatus.ts
│ │ │ │ ├── Quote.ts
│ │ │ │ ├── RequestStatus.ts
│ │ │ │ ├── ResourceLevel.ts
│ │ │ │ ├── RoutineStatus.ts
│ │ │ │ ├── StateInitParams.ts
│ │ │ │ ├── SwitchboardAttestationPermission.ts
│ │ │ │ ├── VerificationStatus.ts
│ │ │ │ ├── VerifierHeartbeatParams.ts
│ │ │ │ ├── VerifierInitParams.ts
│ │ │ │ ├── VerifierQuoteRotateParams.ts
│ │ │ │ ├── VerifierQuoteVerifyParams.ts
│ │ │ │ ├── WalletCloseParams.ts
│ │ │ │ ├── WalletFundParams.ts
│ │ │ │ ├── WalletInitParams.ts
│ │ │ │ ├── WalletWithdrawParams.ts
│ │ │ │ └── index.ts
│ │ ├── errors.ts
│ │ ├── index.ts
│ │ ├── instructions.ts
│ │ ├── oracle-program
│ │ │ ├── accounts
│ │ │ │ ├── AggregatorAccountData.ts
│ │ │ │ ├── BufferRelayerAccountData.ts
│ │ │ │ ├── CrankAccountData.ts
│ │ │ │ ├── JobAccountData.ts
│ │ │ │ ├── LeaseAccountData.ts
│ │ │ │ ├── OracleAccountData.ts
│ │ │ │ ├── OracleQueueAccountData.ts
│ │ │ │ ├── PermissionAccountData.ts
│ │ │ │ ├── RealmSpawnRecordAccountData.ts
│ │ │ │ ├── SbState.ts
│ │ │ │ ├── SlidingResultAccountData.ts
│ │ │ │ ├── TaskSpecRecord.ts
│ │ │ │ ├── VrfAccountData.ts
│ │ │ │ ├── VrfLiteAccountData.ts
│ │ │ │ ├── VrfPoolAccountData.ts
│ │ │ │ └── index.ts
│ │ │ ├── errors
│ │ │ │ ├── anchor.ts
│ │ │ │ ├── custom.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── instructions
│ │ │ │ ├── aggregatorAddJob.ts
│ │ │ │ ├── aggregatorClose.ts
│ │ │ │ ├── aggregatorInit.ts
│ │ │ │ ├── aggregatorLock.ts
│ │ │ │ ├── aggregatorOpenRound.ts
│ │ │ │ ├── aggregatorRemoveJob.ts
│ │ │ │ ├── aggregatorSaveResult.ts
│ │ │ │ ├── aggregatorSaveResultV2.ts
│ │ │ │ ├── aggregatorSetAuthority.ts
│ │ │ │ ├── aggregatorSetConfig.ts
│ │ │ │ ├── aggregatorSetHistoryBuffer.ts
│ │ │ │ ├── aggregatorSetQueue.ts
│ │ │ │ ├── aggregatorSetResolutionMode.ts
│ │ │ │ ├── aggregatorTeeSaveResult.ts
│ │ │ │ ├── bufferRelayerInit.ts
│ │ │ │ ├── bufferRelayerOpenRound.ts
│ │ │ │ ├── bufferRelayerSaveResult.ts
│ │ │ │ ├── crankInit.ts
│ │ │ │ ├── crankPop.ts
│ │ │ │ ├── crankPopV2.ts
│ │ │ │ ├── crankPush.ts
│ │ │ │ ├── index.ts
│ │ │ │ ├── jobInit.ts
│ │ │ │ ├── jobSetData.ts
│ │ │ │ ├── leaseExtend.ts
│ │ │ │ ├── leaseInit.ts
│ │ │ │ ├── leaseSetAuthority.ts
│ │ │ │ ├── leaseWithdraw.ts
│ │ │ │ ├── oracleHeartbeat.ts
│ │ │ │ ├── oracleInit.ts
│ │ │ │ ├── oracleQueueInit.ts
│ │ │ │ ├── oracleQueueSetConfig.ts
│ │ │ │ ├── oracleTeeHeartbeat.ts
│ │ │ │ ├── oracleWithdraw.ts
│ │ │ │ ├── permissionInit.ts
│ │ │ │ ├── permissionSet.ts
│ │ │ │ ├── programConfig.ts
│ │ │ │ ├── programInit.ts
│ │ │ │ ├── setBumps.ts
│ │ │ │ ├── vaultTransfer.ts
│ │ │ │ ├── viewVersion.ts
│ │ │ │ ├── vrfCloseAction.ts
│ │ │ │ ├── vrfInit.ts
│ │ │ │ ├── vrfLiteCloseAction.ts
│ │ │ │ ├── vrfLiteInit.ts
│ │ │ │ ├── vrfLiteProveAndVerify.ts
│ │ │ │ ├── vrfLiteRequestRandomness.ts
│ │ │ │ ├── vrfPoolAdd.ts
│ │ │ │ ├── vrfPoolInit.ts
│ │ │ │ ├── vrfPoolRemove.ts
│ │ │ │ ├── vrfPoolRequest.ts
│ │ │ │ ├── vrfProveAndVerify.ts
│ │ │ │ ├── vrfRequestRandomness.ts
│ │ │ │ └── vrfSetCallback.ts
│ │ │ ├── programId.ts
│ │ │ └── types
│ │ │ │ ├── AccountMetaBorsh.ts
│ │ │ │ ├── AccountMetaZC.ts
│ │ │ │ ├── AggregatorAddJobParams.ts
│ │ │ │ ├── AggregatorCloseParams.ts
│ │ │ │ ├── AggregatorHistoryRow.ts
│ │ │ │ ├── AggregatorInitParams.ts
│ │ │ │ ├── AggregatorLockParams.ts
│ │ │ │ ├── AggregatorOpenRoundParams.ts
│ │ │ │ ├── AggregatorRemoveJobParams.ts
│ │ │ │ ├── AggregatorResolutionMode.ts
│ │ │ │ ├── AggregatorRound.ts
│ │ │ │ ├── AggregatorSaveResultParams.ts
│ │ │ │ ├── AggregatorSaveResultParamsV2.ts
│ │ │ │ ├── AggregatorSetAuthorityParams.ts
│ │ │ │ ├── AggregatorSetBatchSizeParams.ts
│ │ │ │ ├── AggregatorSetConfigParams.ts
│ │ │ │ ├── AggregatorSetForceReportPeriodParams.ts
│ │ │ │ ├── AggregatorSetHistoryBufferParams.ts
│ │ │ │ ├── AggregatorSetMinJobsParams.ts
│ │ │ │ ├── AggregatorSetMinOraclesParams.ts
│ │ │ │ ├── AggregatorSetQueueParams.ts
│ │ │ │ ├── AggregatorSetResolutionModeParams.ts
│ │ │ │ ├── AggregatorSetUpdateIntervalParams.ts
│ │ │ │ ├── AggregatorSetVarianceThresholdParams.ts
│ │ │ │ ├── AggregatorTeeSaveResultParams.ts
│ │ │ │ ├── BorshDecimal.ts
│ │ │ │ ├── BufferRelayerInitParams.ts
│ │ │ │ ├── BufferRelayerOpenRoundParams.ts
│ │ │ │ ├── BufferRelayerRound.ts
│ │ │ │ ├── BufferRelayerSaveResultParams.ts
│ │ │ │ ├── Callback.ts
│ │ │ │ ├── CallbackZC.ts
│ │ │ │ ├── CompletedPointZC.ts
│ │ │ │ ├── CrankInitParams.ts
│ │ │ │ ├── CrankPopParams.ts
│ │ │ │ ├── CrankPopParamsV2.ts
│ │ │ │ ├── CrankPushParams.ts
│ │ │ │ ├── CrankRow.ts
│ │ │ │ ├── EcvrfIntermediate.ts
│ │ │ │ ├── EcvrfProofZC.ts
│ │ │ │ ├── EdwardsPointZC.ts
│ │ │ │ ├── Error.ts
│ │ │ │ ├── FieldElementZC.ts
│ │ │ │ ├── Hash.ts
│ │ │ │ ├── JobInitParams.ts
│ │ │ │ ├── JobSetDataParams.ts
│ │ │ │ ├── Lanes.ts
│ │ │ │ ├── LeaseExtendParams.ts
│ │ │ │ ├── LeaseInitParams.ts
│ │ │ │ ├── LeaseSetAuthorityParams.ts
│ │ │ │ ├── LeaseWithdrawParams.ts
│ │ │ │ ├── OracleHeartbeatParams.ts
│ │ │ │ ├── OracleInitParams.ts
│ │ │ │ ├── OracleMetrics.ts
│ │ │ │ ├── OracleQueueInitParams.ts
│ │ │ │ ├── OracleQueueSetConfigParams.ts
│ │ │ │ ├── OracleQueueSetRewardsParams.ts
│ │ │ │ ├── OracleResponseType.ts
│ │ │ │ ├── OracleTeeHeartbeatParams.ts
│ │ │ │ ├── OracleWithdrawParams.ts
│ │ │ │ ├── PermissionInitParams.ts
│ │ │ │ ├── PermissionSetParams.ts
│ │ │ │ ├── ProgramConfigParams.ts
│ │ │ │ ├── ProgramInitParams.ts
│ │ │ │ ├── ProjectivePointZC.ts
│ │ │ │ ├── Scalar.ts
│ │ │ │ ├── SetBumpsParams.ts
│ │ │ │ ├── Shuffle.ts
│ │ │ │ ├── SlidingWindowElement.ts
│ │ │ │ ├── SwitchboardDecimal.ts
│ │ │ │ ├── SwitchboardPermission.ts
│ │ │ │ ├── VaultTransferParams.ts
│ │ │ │ ├── VrfBuilder.ts
│ │ │ │ ├── VrfCloseParams.ts
│ │ │ │ ├── VrfInitParams.ts
│ │ │ │ ├── VrfLiteCloseParams.ts
│ │ │ │ ├── VrfLiteInitParams.ts
│ │ │ │ ├── VrfLiteProveAndVerifyParams.ts
│ │ │ │ ├── VrfLiteRequestRandomnessParams.ts
│ │ │ │ ├── VrfPoolAddParams.ts
│ │ │ │ ├── VrfPoolInitParams.ts
│ │ │ │ ├── VrfPoolRemoveParams.ts
│ │ │ │ ├── VrfPoolRequestParams.ts
│ │ │ │ ├── VrfPoolRow.ts
│ │ │ │ ├── VrfProveAndVerifyParams.ts
│ │ │ │ ├── VrfProveParams.ts
│ │ │ │ ├── VrfRequestRandomnessParams.ts
│ │ │ │ ├── VrfRound.ts
│ │ │ │ ├── VrfSetCallbackParams.ts
│ │ │ │ ├── VrfStatus.ts
│ │ │ │ └── index.ts
│ │ └── types.ts
│ ├── index.ts
│ ├── mint.ts
│ ├── runner
│ │ ├── env.ts
│ │ ├── functionResult.ts
│ │ ├── index.ts
│ │ └── runner.ts
│ ├── types.ts
│ └── utils.ts
│ ├── test
│ ├── aggregator.spec.ts
│ ├── attestation-function.spec.ts
│ ├── attestation-oracle.spec.ts
│ ├── attestation-queue.spec.ts
│ ├── buffer-relayer.spec.ts
│ ├── close.spec.ts
│ ├── crank.spec.ts
│ ├── crankV2.spec.ts
│ ├── cron.spec.ts
│ ├── data
│ │ └── history_buffer_account_info.json
│ ├── history.spec.ts
│ ├── job.spec.ts
│ ├── lease.spec.ts
│ ├── mint.spec.ts
│ ├── new_wallet.spec.ts
│ ├── open-round.spec.ts
│ ├── oracle.spec.ts
│ ├── priority-fees.spec.ts
│ ├── queue.spec.ts
│ ├── transaction-object.spec.ts
│ ├── transfer.spec.ts
│ ├── tsconfig.json
│ ├── utils.ts
│ ├── version.spec.ts
│ ├── vrf-pool.spec.ts
│ └── wallet.spec.ts
│ ├── tsconfig.base.json
│ ├── tsconfig.cjs.json
│ └── tsconfig.json
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── rust
├── switchboard-solana
│ ├── Cargo.anchor27.lock
│ ├── Cargo.anchor27.toml
│ ├── Cargo.anchor28.lock
│ ├── Cargo.anchor28.toml
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── README.md
│ ├── fixtures
│ │ └── v2_quote.bin
│ ├── package.json
│ ├── set-anchor.sh
│ └── src
│ │ ├── accounts.rs
│ │ ├── clock.rs
│ │ ├── decimal.rs
│ │ ├── error.rs
│ │ ├── events.rs
│ │ ├── instructions.rs
│ │ ├── lib.rs
│ │ ├── macros.rs
│ │ ├── oracle_program
│ │ ├── accounts
│ │ │ ├── aggregator.rs
│ │ │ ├── aggregator1.rs
│ │ │ ├── buffer_relayer.rs
│ │ │ ├── crank.rs
│ │ │ ├── history_buffer.rs
│ │ │ ├── job.rs
│ │ │ ├── lease.rs
│ │ │ ├── mod.rs
│ │ │ ├── oracle.rs
│ │ │ ├── permission.rs
│ │ │ ├── queue.rs
│ │ │ ├── sb_state.rs
│ │ │ └── sliding_window.rs
│ │ ├── instructions
│ │ │ ├── aggregator_save_result.rs
│ │ │ ├── mod.rs
│ │ │ ├── oracle_heartbeat.rs
│ │ │ └── permission_set.rs
│ │ └── mod.rs
│ │ ├── prelude.rs
│ │ ├── program_id.rs
│ │ ├── seeds.rs
│ │ ├── types.rs
│ │ └── utils.rs
└── switchboard-v2
│ ├── .gitignore
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ └── src
│ ├── aggregator.rs
│ ├── buffer_relayer.rs
│ ├── crank.rs
│ ├── decimal.rs
│ ├── ecvrf.rs
│ ├── error.rs
│ ├── history_buffer.rs
│ ├── job.rs
│ ├── lease.rs
│ ├── lib.rs
│ ├── oracle.rs
│ ├── permission.rs
│ ├── queue.rs
│ ├── sb_state.rs
│ ├── vrf.rs
│ ├── vrf_lite.rs
│ └── vrf_pool.rs
├── scripts
├── anchor-test.sh
├── build.js
├── setup-anchor.sh
└── setup-js.sh
├── tsconfig.json
└── turbo.json
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json",
3 | "changelog": "@changesets/cli/changelog",
4 | "commit": false,
5 | "fixed": [],
6 | "linked": [],
7 | "access": "restricted",
8 | "baseBranch": "main",
9 | "updateInternalDependencies": "patch",
10 | "ignore": []
11 | }
12 |
--------------------------------------------------------------------------------
/.docs/clients.yaml:
--------------------------------------------------------------------------------
1 | clients:
2 | - name: "switchboard-v2"
3 | slug: "./"
4 | description: "A Rust library to interact with Switchboard V2 accounts on Solana."
5 | language: "rust"
6 | path: "rust/switchboard-v2"
7 | - name: "@switchboard-xyz/solana.js"
8 | slug: "./"
9 | description: "A Typescript client to interact with Switchboard on Solana."
10 | language: "javascript"
11 | path: "javascript/solana.js"
12 |
--------------------------------------------------------------------------------
/.docs/examples.yaml:
--------------------------------------------------------------------------------
1 | examples:
2 | - name: "native-feed-parser"
3 | description: "Read a Switchboard feed using Solana's native program library"
4 | language: "rust"
5 | path: "programs/native-feed-parser"
6 | - name: "anchor-feed-parser"
7 | description: "Read a Switchboard feed using Anchor"
8 | language: "anchor"
9 | path: "programs/anchor-feed-parser"
10 | - name: "anchor-history-parser"
11 | description:
12 | "Read a data feeds history buffer and get the closest historical sample to
13 | a given timestamp"
14 | language: "anchor"
15 | path: "programs/anchor-history-parser"
16 | - name: "anchor-vrf-parser"
17 | description:
18 | "Read a Switchboard VRF account and make a Cross Program Invocation (CPI)
19 | to request a new randomness value"
20 | language: "anchor"
21 | path: "programs/anchor-vrf-parser"
22 | - name: "anchor-vrf-lite-parser"
23 | description:
24 | "Read a Switchboard VRF Lite account and make a Cross Program Invocation
25 | (CPI) to request a new randomness value"
26 | language: "anchor"
27 | path: "programs/anchor-vrf-lite-parser"
28 | - name: "anchor-buffer-parser"
29 | description: "Read a Switchboard buffer relayer using Anchor"
30 | language: "anchor"
31 | path: "programs/anchor-buffer-parser"
32 | - name: "javascript-feed-walkthrough"
33 | description:
34 | "Create a private Switchboard queue and oracle and fulfill your own oracle
35 | updates"
36 | language: "javascript"
37 | path: "javascript/feed-walkthrough"
38 |
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # Javascript Feed Walkthrough
8 |
9 | > Create a private Switchboard queue and oracle and fulfill your own oracle
10 | > updates
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
13 |
14 | [](https://docs.switchboard.xyz/api/solana.js)
15 |
16 |
17 |
18 | ## Install
19 |
20 | ```bash
21 | npm i
22 | ```
23 |
24 | ## Usage
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/usage/create-a-feed-with-cli.md:
--------------------------------------------------------------------------------
1 | First install the sbv2 cli
2 |
3 | ```bash
4 | npm install -g @switchboard-xyz
5 | ```
6 |
7 | Then run the following command to create your own feed using the devnet
8 | permissionless queue and crank
9 |
10 | ```bash
11 | export QUEUE_KEY=uPeRMdfPmrPqgRWSrjAnAkH78RqAhe5kXoW6vBYRqFX
12 | export CRANK_KEY=GN9jjCy2THzZxhYqZETmPM3my8vg4R5JyNkgULddUMa5
13 | sbv2 solana aggregator create "$QUEUE_KEY" \
14 | --keypair ~/.config/solana/id.json \
15 | --crankKey "$CRANK_KEY" \
16 | --name "My_Test_Feed" \
17 | --updateInterval 10 \
18 | --minOracles 1 \
19 | --batchSize 1 \
20 | --leaseAmount 0.1 \
21 | --job ./src/oracle-job.json \
22 | --verbose
23 | ```
24 |
25 | Then request an update for your new feed
26 |
27 | ```bash
28 | sbv2 solana aggregator update $AGGREGATOR_KEY \
29 | --keypair ~/.config/solana/id.json
30 | ```
31 |
32 | **_NOTE:_** You can provide multiple `--job` flags to add additional oracle jobs
33 | to your data feed
34 |
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/usage/create-devnet-feed.md:
--------------------------------------------------------------------------------
1 | You can create your own feeds using the devnet permissionless network. This
2 | network does _NOT_ require the queue authority to grant you permissions so you
3 | are free to use it as a testing environment.
4 |
5 | You do **_NOT_** need to run your own oracles for this network.
6 |
7 | Edit the OracleJob file `src/oracle-job.json`, then run
8 |
9 | ```bash
10 | ts-node src/devnet
11 | ```
12 |
13 | Optionally, provide these env variables
14 |
15 | ```bash
16 | RPC_URL=https://my_custom_rpc_url.com \
17 | PAYER_KEYPAIR=~/my_keypair.json \
18 | ts-node src/devnet
19 | ```
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/usage/create-private-network.md:
--------------------------------------------------------------------------------
1 | You can also create your own private Switchboard network and run your own
2 | oracles. This requires you to run your own oracles for this network.
3 |
4 | The following script will
5 |
6 | - Create a private queue and crank
7 | - Create a new data feed on this network
8 | - Start a local oracle
9 | - Call OpenRound and await the updated result from your local oracle
10 |
11 | ```bash
12 | ts-node src/private-queue
13 | ```
14 |
15 | Optionally, provide these env variables
16 |
17 | ```bash
18 | RPC_URL=https://my_custom_rpc_url.com \
19 | PAYER_KEYPAIR=~/my_keypair.json \
20 | ts-node src/private-queue
21 | ```
22 |
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/usage/meta.yaml:
--------------------------------------------------------------------------------
1 | snippets:
2 | - name: "Simulate an OracleJob"
3 | description: ""
4 | filename: "simulate-an-oracle-job.md"
5 | - name: "Create a Devnet Feed"
6 | description: ""
7 | filename: "create-devnet-feed.md"
8 | - name: "Create a Private Switchboard Network"
9 | description: ""
10 | filename: "create-private-network.md"
11 | - name: "Create a Feed with the CLI"
12 | description: ""
13 | filename: "create-a-feed-with-cli.md"
14 |
--------------------------------------------------------------------------------
/.docs/javascript/feed-walkthrough/usage/simulate-an-oracle-job.md:
--------------------------------------------------------------------------------
1 | Edit the OracleJob file `src/oracle-job.json`, then run
2 |
3 | ```bash
4 | ts-node src/simulate
5 | ```
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # @switchboard-xyz/solana.js
8 |
9 | > A Typescript client to interact with Switchboard V2 on Solana.
10 |
11 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml)
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 | [](https://www.npmjs.com/package/@switchboard-xyz/solana.js)
15 | [](https://docs.switchboard.xyz/api/solana.js)
16 |
17 |
18 |
19 | ## Install
20 |
21 | ```bash
22 | npm i --save @switchboard-xyz/solana.js
23 | ```
24 |
25 | ## Usage
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/add-an-oracle.ts:
--------------------------------------------------------------------------------
1 | import { QueueAccount } from "@switchboard-xyz/solana.js";
2 |
3 | const queueAccount = new QueueAccount(program, queuePubkey);
4 |
5 | const [oracleAccount, oracleInitSignature] = await queueAccount.createOracle({
6 | name: "My Oracle",
7 | metadata: "Oracle #1",
8 | stakeAmount: 10,
9 | });
10 | const oracle = await oracleAccount.loadData();
11 |
12 | await oracleAccount.heartbeat();
13 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/add-history-buffer.ts:
--------------------------------------------------------------------------------
1 | import {
2 | AggregatorAccount,
3 | AggregatorHistoryBuffer,
4 | } from "@switchboard-xyz/solana.js";
5 |
6 | const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
7 | const aggregator = await aggregatorAccount.loadData();
8 |
9 | const [historyBuffer, addHistorySignature] =
10 | await AggregatorHistoryBuffer.create(program, {
11 | aggregatorAccount,
12 | maxSamples: 10000,
13 | });
14 | const history = await historyBuffer.loadData();
15 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/create-a-data-feed.ts:
--------------------------------------------------------------------------------
1 | import { QueueAccount } from "@switchboard-xyz/solana.js";
2 | import { OracleJob } from "@switchboard-xyz/common";
3 |
4 | const queueAccount = new QueueAccount(program, queuePubkey);
5 |
6 | const [aggregatorAccount, aggregatorInitSignatures] =
7 | await queueAccount.createFeed({
8 | batchSize: 1,
9 | minRequiredOracleResults: 1,
10 | minRequiredJobResults: 1,
11 | minUpdateDelaySeconds: 60,
12 | fundAmount: 2.5, // deposit 2.5 wSOL into the leaseAccount escrow
13 | jobs: [
14 | { pubkey: jobAccount.publicKey },
15 | {
16 | weight: 2,
17 | data: OracleJob.encodeDelimited(
18 | OracleJob.fromObject({
19 | tasks: [
20 | {
21 | valueTask: {
22 | value: 1,
23 | },
24 | },
25 | ],
26 | })
27 | ).finish(),
28 | },
29 | ],
30 | });
31 | const aggregator = await aggregatorAccount.loadData();
32 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/create-queue.ts:
--------------------------------------------------------------------------------
1 | import { QueueAccount } from '@switchboard-xyz/solana.js';
2 |
3 | const [queueAccount, txnSignature] = await QueueAccount.create(program, {
4 | name: 'My Queue',
5 | metadata: 'Top Secret',
6 | queueSize: 100,
7 | reward: 0.00001337,
8 | minStake: 10,
9 | oracleTimeout: 60,
10 | slashingEnabled: false,
11 | unpermissionedFeeds: true,
12 | unpermissionedVrf: true,
13 | enableBufferRelayers: false,
14 | });
15 | const queue = await queueAccount.loadData();
16 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/load-program.ts:
--------------------------------------------------------------------------------
1 | import { Connection } from '@solana/web3.js';
2 | import {
3 | SwitchboardProgram,
4 | TransactionObject,
5 | } from '@switchboard-xyz/solana.js';
6 |
7 | const program = await SwitchboardProgram.load(
8 | 'mainnet-beta',
9 | new Connection('https://api.mainnet-beta.solana.com'),
10 | payerKeypair /** Optional, READ-ONLY if not provided */
11 | );
12 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/meta.yaml:
--------------------------------------------------------------------------------
1 | snippets:
2 | - name: "Load Switchboard Program"
3 | description: ""
4 | filename: "load-program.ts"
5 | - name: "Create a Queue"
6 | description: ""
7 | filename: "create-queue.ts"
8 | - name: "Add an Oracle"
9 | description: ""
10 | filename: "add-an-oracle.ts"
11 | - name: "Create a Data Feed"
12 | description: ""
13 | filename: "create-a-data-feed.ts"
14 | - name: "Request a New Value"
15 | description: ""
16 | filename: "request-a-new-value.ts"
17 | - name: "Read a Data Feed"
18 | description: "After the oracles respond, read the feed result"
19 | filename: "read-data-feed.ts"
20 | - name: "Add a History Buffer"
21 | description:
22 | "Optionally, add a history buffer to your feed to store the last N
23 | historical samples"
24 | filename: "add-history-buffer.ts"
25 | - name: "Watch Data Feed"
26 | description:
27 | "Setup a websocket listener to invoke a callback whenever an aggregator is
28 | updated"
29 | filename: "watch-data-feed.ts"
30 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/read-data-feed.ts:
--------------------------------------------------------------------------------
1 | import Big from "big.js";
2 | import { AggregatorAccount } from "@switchboard-xyz/solana.js";
3 |
4 | const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
5 |
6 | const result: Big | null = await aggregatorAccount.fetchLatestValue();
7 | if (result === null) {
8 | throw new Error("Aggregator holds no value");
9 | }
10 | console.log(result.toString());
11 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/request-a-new-value.ts:
--------------------------------------------------------------------------------
1 | import { AggregatorAccount } from "@switchboard-xyz/solana.js";
2 |
3 | const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
4 |
5 | await aggregatorAccount.openRound();
6 |
--------------------------------------------------------------------------------
/.docs/javascript/solana.js/usage/watch-data-feed.ts:
--------------------------------------------------------------------------------
1 | import Big from 'big.js';
2 | import { AggregatorAccount } from '@switchboard-xyz/solana.js';
3 |
4 | const aggregatorAccount = new AggregatorAccount(program, aggregatorPubkey);
5 |
6 | const ws = aggregatorAccount.onChange(aggregator => {
7 | const result = AggregatorAccount.decodeLatestValue(aggregator);
8 | if (result !== null) {
9 | console.log(result.toString());
10 | }
11 | });
--------------------------------------------------------------------------------
/.docs/programs/anchor-buffer-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # anchor-buffer-parser
8 |
9 | > An example program written in Anchor demonstrating how to deserialize and read
10 | > a Switchboard buffer relayer on Solana.
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Usage
21 |
22 | Build the example program
23 |
24 | ```bash
25 | anchor build
26 | ```
27 |
28 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
29 |
30 | ```bash
31 | export ANCHOR_BUFFER_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_buffer_parser-keypair.json)
32 | sed -i '' s/96punQGZDShZGkzsBa3SsfTxfUnwu4XGpzXbhF7NTgcP/"$ANCHOR_BUFFER_PARSER_PUBKEY"/g Anchor.toml
33 | sed -i '' s/96punQGZDShZGkzsBa3SsfTxfUnwu4XGpzXbhF7NTgcP/"$ANCHOR_BUFFER_PARSER_PUBKEY"/g src/lib.rs
34 | ```
35 |
36 | Then run Anchor test
37 |
38 | ```bash
39 | anchor test
40 | ```
41 |
--------------------------------------------------------------------------------
/.docs/programs/anchor-feed-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # anchor-feed-parser
8 |
9 | > An example program written in Anchor demonstrating how to deserialize and read
10 | > a Switchboard data feed on Solana.
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Usage
21 |
22 | Build the example program
23 |
24 | ```bash
25 | anchor build
26 | ```
27 |
28 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
29 |
30 | ```bash
31 | export ANCHOR_FEED_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_feed_parser-keypair.json)
32 | sed -i '' s/EE4NqG3B1N54tTbJ8VTtebdE88j4qjfVsbDXUUVFHegk/"$ANCHOR_FEED_PARSER_PUBKEY"/g Anchor.toml
33 | sed -i '' s/EE4NqG3B1N54tTbJ8VTtebdE88j4qjfVsbDXUUVFHegk/"$ANCHOR_FEED_PARSER_PUBKEY"/g src/lib.rs
34 | ```
35 |
36 | Then run Anchor test
37 |
38 | ```bash
39 | anchor test
40 | ```
41 |
--------------------------------------------------------------------------------
/.docs/programs/anchor-history-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # anchor-history-parser
8 |
9 | > An example program written in Anchor demonstrating how to deserialize and read
10 | > a Switchboard data feed's history buffer on Solana.
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Usage
21 |
22 | Build the example program
23 |
24 | ```bash
25 | anchor build
26 | ```
27 |
28 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
29 |
30 | ```bash
31 | export ANCHOR_HISTORY_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_history_parser-keypair.json)
32 | sed -i '' s/C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS/"$ANCHOR_HISTORY_PARSER_PUBKEY"/g Anchor.toml
33 | sed -i '' s/C7rn1qJkq9FjTwV86RrY5Uih91NgymRVLdJ81rqLNXRS/"$ANCHOR_HISTORY_PARSER_PUBKEY"/g src/lib.rs
34 | ```
35 |
36 | Then run Anchor test
37 |
38 | ```bash
39 | anchor test
40 | ```
41 |
--------------------------------------------------------------------------------
/.docs/programs/anchor-vrf-lite-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # anchor-vrf-lite-parser
8 |
9 | > An example program written in Anchor demonstrating how to deserialize and read
10 | > a Switchboard VRF Lite account on Solana.
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Usage
21 |
22 | Build the example program
23 |
24 | ```bash
25 | anchor build
26 | ```
27 |
28 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
29 |
30 | ```bash
31 | export ANCHOR_VRF_LITE_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_lite_parser-keypair.json)
32 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g Anchor.toml
33 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g src/lib.rs
34 | ```
35 |
36 | Then run Anchor test
37 |
38 | ```bash
39 | anchor test
40 | ```
41 |
--------------------------------------------------------------------------------
/.docs/programs/anchor-vrf-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # anchor-vrf-parser
8 |
9 | > An example program written in Anchor demonstrating how to deserialize and read
10 | > a Switchboard VRF account on Solana.
11 |
12 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ## Usage
21 |
22 | Build the example program
23 |
24 | ```bash
25 | anchor build
26 | ```
27 |
28 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
29 |
30 | ```bash
31 | export ANCHOR_VRF_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_parser-keypair.json)
32 | sed -i '' s/4wTeTACfwiXqqvy44bNBB3V2rFjmSTXVoEr4ZAYamJEN/"$ANCHOR_VRF_PARSER_PUBKEY"/g Anchor.toml
33 | sed -i '' s/4wTeTACfwiXqqvy44bNBB3V2rFjmSTXVoEr4ZAYamJEN/"$ANCHOR_VRF_PARSER_PUBKEY"/g src/lib.rs
34 | ```
35 |
36 | Then run Anchor test
37 |
38 | ```bash
39 | anchor test
40 | ```
41 |
--------------------------------------------------------------------------------
/.docs/programs/native-feed-parser/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # native-feed-parser
8 |
9 | > An example program written in native Rust demonstrating how to deserialize and
10 | > read a Switchboard data feed on Solana.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## Usage
19 |
20 | Build the example program
21 |
22 | ```bash
23 | cargo build-bpf --manifest-path=Cargo.toml
24 | solana program deploy target/deploy/native_feed_parser.so
25 | ```
26 |
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/README.template.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # switchboard-v2
8 |
9 | > A Rust library to interact with Switchboard accounts on Solana.
10 |
11 | [](https://crates.io/crates/switchboard-v2)
12 |
13 |
14 |
15 | ## Install
16 |
17 | Run the following Cargo command in your project directory:
18 |
19 | ```bash
20 | cargo add switchboard-v2
21 | ```
22 |
23 | Or add the following line to your Cargo.toml:
24 |
25 | ```toml
26 | [dependencies]
27 | switchboard-v2 = "0.1.23"
28 | ```
29 |
30 | ## Usage
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/usage/read-buffer.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::solana_program::clock;
2 | use std::convert::TryInto;
3 | use switchboard_v2::{BufferRelayerAccountData, SWITCHBOARD_PROGRAM_ID};
4 |
5 | // check feed owner
6 | let owner = *aggregator.owner;
7 | if owner != SWITCHBOARD_PROGRAM_ID {
8 | return Err(error!(ErrorCode::InvalidSwitchboardAccount));
9 | }
10 |
11 | // deserialize account info
12 | let buffer = BufferRelayerAccountData::new(feed_account_info)?;
13 |
14 | // get result
15 | let buffer_result = buffer.get_result();
16 |
17 | // check if feed has been updated in the last 5 minutes
18 | buffer.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
19 |
20 | // convert buffer to a string
21 | let result_string = String::from_utf8(buffer.result)
22 | .map_err(|_| error!(ErrorCode::StringConversionFailed))?;
23 | msg!("Buffer string {:?}!", result_string);
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/usage/read-history.rs:
--------------------------------------------------------------------------------
1 | use switchboard_v2::AggregatorHistoryBuffer;
2 | use std::convert::TryInto;
3 |
4 | let history_buffer = AggregatorHistoryBuffer::new(history_account_info)?;
5 | let current_timestamp = Clock::get()?.unix_timestamp;
6 | let one_hour_ago: f64 = history_buffer.lower_bound(current_timestamp - 3600).unwrap().try_into()?;
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/usage/read-result.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::solana_program::clock;
2 | use std::convert::TryInto;
3 | use switchboard_v2::{AggregatorAccountData, SwitchboardDecimal, SWITCHBOARD_PROGRAM_ID};
4 |
5 | // check feed owner
6 | let owner = *aggregator.owner;
7 | if owner != SWITCHBOARD_PROGRAM_ID {
8 | return Err(error!(ErrorCode::InvalidSwitchboardAccount));
9 | }
10 |
11 | // deserialize account info
12 | let feed = ctx.accounts.aggregator.load()?;
13 | // OR
14 | let feed = AggregatorAccountData::new(feed_account_info)?;
15 |
16 | // get result
17 | let decimal: f64 = feed.get_result()?.try_into()?;
18 |
19 | // check if feed has been updated in the last 5 minutes
20 | feed.check_staleness(clock::Clock::get().unwrap().unix_timestamp, 300)?;
21 |
22 | // check if feed exceeds a confidence interval of +/i $0.80
23 | feed.check_confidence_interval(SwitchboardDecimal::from_f64(0.80))?;
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/usage/read-vrf.rs:
--------------------------------------------------------------------------------
1 | use switchboard_v2::VrfAccountData;
2 |
3 | // deserialize the account info
4 | let vrf = ctx.accounts.vrf.load()?;
5 | // OR
6 | let vrf = VrfAccountData::new(vrf_account_info)?;
7 |
8 | // read the result
9 | let result_buffer = vrf.get_result()?;
10 | let value: &[u128] = bytemuck::cast_slice(&result_buffer[..]);
11 | let result = value[0] % 256000 as u128;
--------------------------------------------------------------------------------
/.docs/rust/switchboard-v2/usage/request-randomness.rs:
--------------------------------------------------------------------------------
1 | pub use switchboard_v2::{VrfAccountData, VrfRequestRandomness};
2 |
3 | let switchboard_program = ctx.accounts.switchboard_program.to_account_info();
4 |
5 | let vrf_request_randomness = VrfRequestRandomness {
6 | authority: ctx.accounts.state.to_account_info(),
7 | vrf: ctx.accounts.vrf.to_account_info(),
8 | oracle_queue: ctx.accounts.oracle_queue.to_account_info(),
9 | queue_authority: ctx.accounts.queue_authority.to_account_info(),
10 | data_buffer: ctx.accounts.data_buffer.to_account_info(),
11 | permission: ctx.accounts.permission.to_account_info(),
12 | escrow: ctx.accounts.escrow.clone(),
13 | payer_wallet: ctx.accounts.payer_wallet.clone(),
14 | payer_authority: ctx.accounts.payer_authority.to_account_info(),
15 | recent_blockhashes: ctx.accounts.recent_blockhashes.to_account_info(),
16 | program_state: ctx.accounts.program_state.to_account_info(),
17 | token_program: ctx.accounts.token_program.to_account_info(),
18 | };
19 |
20 | let vrf_key = ctx.accounts.vrf.key.clone();
21 | let authority_key = ctx.accounts.authority.key.clone();
22 |
23 | let state_seeds: &[&[&[u8]]] = &[&[
24 | &STATE_SEED,
25 | vrf_key.as_ref(),
26 | authority_key.as_ref(),
27 | &[bump],
28 | ]];
29 | msg!("requesting randomness");
30 | vrf_request_randomness.invoke_signed(
31 | switchboard_program,
32 | params.switchboard_state_bump,
33 | params.permission_bump,
34 | state_seeds,
35 | )?;
36 |
--------------------------------------------------------------------------------
/.github/dependabot/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "npm"
4 | versioning-strategy: increase
5 | directory: "/"
6 | schedule:
7 | interval: "monthly"
8 | labels:
9 | - "dependencies"
10 | open-pull-requests-limit: 100
11 | pull-request-branch-name:
12 | separator: "-"
13 | ignore:
14 | - dependency-name: "fs-extra"
15 | - dependency-name: "*"
16 | update-types: ["version-update:semver-major"]
17 |
--------------------------------------------------------------------------------
/.github/dependabot/rebase.yml:
--------------------------------------------------------------------------------
1 | name: rebase pull requests
2 | on:
3 | push:
4 | release:
5 | types: [published]
6 | jobs:
7 | auto-rebase:
8 | name: rebase dependabot PRs
9 | runs-on: ubuntu-latest
10 | if: github.ref == 'refs/heads/main' || github.event == 'release'
11 | timeout-minutes: 5
12 | steps:
13 | - name: rebase
14 | uses: "bbeesley/gha-auto-dependabot-rebase@main"
15 | env:
16 | GITHUB_TOKEN: ${{ secrets.GH_PA_TOKEN }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/copybara.yml:
--------------------------------------------------------------------------------
1 | name: Update pnpm lockfile
2 |
3 | on:
4 | push:
5 | branches:
6 | - copybara-solana-sdk-push
7 |
8 | jobs:
9 | update-lockfile:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Check out code
14 | uses: actions/checkout@v3
15 |
16 | - name: Use Node.js
17 | uses: actions/setup-node@v3
18 | with:
19 | node-version: 18
20 |
21 | - name: Install pnpm
22 | uses: pnpm/action-setup@v2
23 | with:
24 | version: 8.6.0
25 |
26 | - name: Get pnpm store directory
27 | id: pnpm-cache
28 | shell: bash
29 | run: |
30 | echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT
31 |
32 | - uses: actions/cache@v3
33 | name: Setup pnpm cache
34 | with:
35 | path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
36 | key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
37 | restore-keys: |
38 | ${{ runner.os }}-pnpm-store-
39 |
40 | - name: Update pnpm lockfile
41 | run: pnpm install --no-frozen-lockfile
42 |
43 | - name: Push changes
44 | uses: stefanzweifel/git-auto-commit-action@v4
45 | with:
46 | commit_message: "chore: Update pnpm lockfile"
47 | skip_dirty_check: false
48 | file_pattern: "pnpm-lock.yaml"
49 | branch: copybara-solana-sdk-push
50 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | auto-install-peers=true
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | // See https://go.microsoft.com/fwlink/?LinkId=827846
3 | // for the documentation about the extensions.json format
4 | "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
5 | }
6 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll.eslint": true
4 | },
5 | "files.eol": "\n",
6 | "editor.formatOnSave": true,
7 | "editor.wordWrap": "on",
8 | "[typescript]": {
9 | "editor.codeActionsOnSave": {
10 | "source.organizeImports": false
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Switchboard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | client/
9 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "switchboard-feed-client"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "switchboard_feed_client"
12 |
13 | [features]
14 | default = []
15 | no-entrypoint = []
16 | no-idl = []
17 | no-log-ix-name = []
18 | cpi = ["no-entrypoint"]
19 |
20 | [dependencies]
21 | # switchboard-solana = "0.28.4"
22 | switchboard-solana = { version = "0.28.4", path = "../../../rust/switchboard-solana" }
23 | bytemuck = "1.13.1"
24 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # switchboard-feed-client
6 |
7 | > An example program written in Anchor demonstrating how to deserialize and read
8 | > a Switchboard VRF account on Solana.
9 |
10 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## Usage
19 |
20 | Build the example program
21 |
22 | ```bash
23 | anchor build
24 | ```
25 |
26 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
27 |
28 | ```bash
29 | export ANCHOR_VRF_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_parser-keypair.json)
30 | sed -i '' s/4hfkS97f5P6zauWeJF5dcZDFaJwYwbMPvKrANVAuKN4p/"$ANCHOR_VRF_PARSER_PUBKEY"/g Anchor.toml
31 | sed -i '' s/4hfkS97f5P6zauWeJF5dcZDFaJwYwbMPvKrANVAuKN4p/"$ANCHOR_VRF_PARSER_PUBKEY"/g src/lib.rs
32 | ```
33 |
34 | Then run Anchor test
35 |
36 | ```bash
37 | anchor test
38 | ```
39 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "switchboard-feed-client",
3 | "version": "1.0.0",
4 | "private": true,
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
8 | "directory": "examples/feeds/01_feed_client"
9 | },
10 | "scripts": {
11 | "build:cargo": "anchor build",
12 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
13 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
14 | },
15 | "dependencies": {
16 | "@coral-xyz/anchor": "^0.28.0",
17 | "@coral-xyz/borsh": "^0.28.0",
18 | "@project-serum/borsh": "^0.2.5",
19 | "@solana/spl-token": "^0.3.8",
20 | "@solana/web3.js": "^1.78.3",
21 | "@switchboard-xyz/common": "*",
22 | "@switchboard-xyz/oracle": "*",
23 | "@switchboard-xyz/solana.js": "*",
24 | "chalk": "^4.1.2",
25 | "dotenv": "^16.0.1",
26 | "yargs": "^17.5.1"
27 | },
28 | "devDependencies": {
29 | "@types/chai": "^4.3.0",
30 | "@types/mocha": "^9.0.0",
31 | "chai": "^4.3.6",
32 | "mocha": "^9.0.3",
33 | "npm-run-all": "^4.1.5",
34 | "prettier-plugin-organize-imports": "^2.3.4",
35 | "ts-mocha": "^9.0.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/feeds/01_feed_client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "strict": false,
20 | "strictNullChecks": false,
21 | "target": "es6",
22 | "paths": {
23 | "@switchboard-xyz/solana.js": [
24 | "../../../../../javascript/solana.js"
25 | ]
26 | }
27 | },
28 | "include": [
29 | "tests/**/*",
30 | "./cli.ts",
31 | "./client/**/*"
32 | ],
33 | "exclude": [
34 | "target",
35 | "lib"
36 | ],
37 | "references": [
38 | {
39 | "path": "../../../../../javascript/solana.js"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "native-feed-parser"
5 | version = "0.1.0"
6 | edition = "2018"
7 |
8 | [lib]
9 | crate-type = ["cdylib", "lib"]
10 | name = "native_feed_parser"
11 |
12 | [features]
13 | no-entrypoint = []
14 |
15 | [dependencies]
16 | # switchboard-solana = "0.28.4"
17 | switchboard-solana = { version = "0.28.4", path = "../../../rust/switchboard-solana" }
18 |
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # native-feed-parser
6 |
7 | > An example program written in native Rust demonstrating how to deserialize and
8 | > read a Switchboard data feed on Solana.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | ## Usage
17 |
18 | Build the example program
19 |
20 | ```bash
21 | cargo build-bpf --manifest-path=Cargo.toml
22 | solana program deploy target/deploy/native_feed_parser.so
23 | ```
24 |
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "native-feed-parser",
3 | "version": "1.0.0",
4 | "private": true,
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
8 | "directory": "programs/native-feed-parser"
9 | },
10 | "scripts": {
11 | "build:cargo": "cargo-build-sbf",
12 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
13 | "clean": "pnpm exec rimraf node_modules .anchor .turbo",
14 | "deploy": "solana program deploy target/deploy/native_feed_parser.so",
15 | "test:program": "echo \"For workspace native-feed-parser, use the anchor:test script\" && exit 0"
16 | },
17 | "dependencies": {
18 | "@coral-xyz/anchor": "^0.28.0",
19 | "@solana/web3.js": "^1.77.3",
20 | "@switchboard-xyz/common": "*",
21 | "@switchboard-xyz/oracle": "*",
22 | "@switchboard-xyz/solana.js": "*"
23 | },
24 | "devDependencies": {
25 | "@types/chai": "^4.3.0",
26 | "@types/mocha": "^9.0.0",
27 | "chai": "^4.3.6",
28 | "mocha": "^9.0.3",
29 | "ts-mocha": "^9.0.2"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/src/lib.rs:
--------------------------------------------------------------------------------
1 | use std::convert::TryInto;
2 | use switchboard_solana::prelude::*;
3 |
4 | use solana_program::{
5 | account_info::{next_account_info, AccountInfo},
6 | entrypoint,
7 | entrypoint::ProgramResult,
8 | msg,
9 | program_error::ProgramError,
10 | pubkey::Pubkey,
11 | };
12 |
13 | entrypoint!(process_instruction);
14 |
15 | fn process_instruction<'a>(
16 | _program_id: &'a Pubkey,
17 | accounts: &'a [AccountInfo<'a>],
18 | _instruction_data: &'a [u8],
19 | ) -> ProgramResult {
20 | let accounts_iter = &mut accounts.iter();
21 | let aggregator = next_account_info(accounts_iter)?;
22 |
23 | let clock = Clock::get()?;
24 |
25 | // check feed owner
26 | let owner = *aggregator.owner;
27 | if owner != SWITCHBOARD_PROGRAM_ID {
28 | return Err(ProgramError::IncorrectProgramId);
29 | }
30 |
31 | // load and deserialize feed
32 | let feed = AggregatorAccountData::new(aggregator)?;
33 |
34 | // check if feed has updated in the last 5 minutes
35 | let staleness = clock.unix_timestamp - feed.latest_confirmed_round.round_open_timestamp;
36 | if staleness > 300 {
37 | msg!("Feed has not been updated in {} seconds!", staleness);
38 | return Err(ProgramError::InvalidAccountData);
39 | }
40 |
41 | // get result
42 | let val: f64 = feed.get_result()?.try_into()?;
43 | msg!("Current feed result is {}!", val);
44 |
45 | Ok(())
46 | }
47 |
--------------------------------------------------------------------------------
/examples/feeds/02_spl_native/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "types": [
4 | "mocha",
5 | "chai"
6 | ],
7 | "typeRoots": [
8 | "./node_modules/@types"
9 | ],
10 | "lib": [
11 | "es2015"
12 | ],
13 | "module": "commonjs",
14 | "target": "es6",
15 | "esModuleInterop": true,
16 | "noEmit": true,
17 | "paths": {
18 | "@switchboard-xyz/solana.js": [
19 | "../../../../../javascript/solana.js"
20 | ]
21 | }
22 | },
23 | "exclude": [
24 | "target"
25 | ],
26 | "references": [
27 | {
28 | "path": "../../../../../javascript/solana.js"
29 | }
30 | ]
31 | }
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
2 | Makefile
3 | README.md
4 | node_modules
5 | .turbo
6 | measurement.txt
7 | .anchor
8 | scripts
9 | .prettierignore
10 | .gitignore
11 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | .yarn
9 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic_oracle"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "basic_oracle"
12 | path = "src/lib.rs"
13 |
14 | [features]
15 | no-entrypoint = []
16 | no-idl = []
17 | no-log-ix-name = []
18 | cpi = ["no-entrypoint"]
19 | default = []
20 |
21 | [dependencies]
22 | # switchboard-solana = { version = "0.29.70" }
23 | switchboard-solana = { path = "../../../rust/switchboard-solana" }
24 | bytemuck = "^1"
25 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | ## Usage
6 |
7 | Deploy function:
8 |
9 | ```bash
10 | sb solana function create "CkvizjVnm2zA5Wuwan34NhVT3zFc7vqUyGnA6tuEF5aE" --container ${CONTAINER_NAME} --cluster devnet --schedule "15 * * * * *" --containerRegistry dockerhub --keypair /Users/mgild/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json --mrEnclave 0x63ba8df478b4a74795a79a73b8f0a6f792f88e95f9ed6202289091e6e1b65fa1 --fundAmount 0.25
11 |
12 | sb solana function create "2ie3JZfKcvsRLsJaP5fSo43gUo1vsurnUAtAgUdUAiDG" --container ${CONTAINER_NAME} --schedule "30 * * * * *" --containerRegistry dockerhub --keypair /Users/mgild/switchboard_environments_v2/mainnet/upgrade_authority/upgrade_authority.json --mainnetBeta --mrEnclave 0x63ba8df478b4a74795a79a73b8f0a6f792f88e95f9ed6202289091e6e1b65fa1 --fundAmount 0.25
13 | ```
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-basic-oracle",
3 | "private": true,
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
7 | "directory": "examples/functions/01_basic_oracle"
8 | },
9 | "scripts": {
10 | "build:cargo": "anchor build",
11 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
12 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
13 | },
14 | "dependencies": {
15 | "@coral-xyz/anchor": "^0.28.0",
16 | "@solana/spl-token": "^0.3.6",
17 | "@solana/web3.js": "^1.78.0",
18 | "@switchboard-xyz/solana.js": "^3"
19 | },
20 | "devDependencies": {
21 | "@types/bn.js": "^5.1.0",
22 | "@types/chai": "^4.3.0",
23 | "@types/mocha": "^9.0.0",
24 | "@types/node": "^20.4.0",
25 | "chai": "^4.3.4",
26 | "mocha": "^9.0.3",
27 | "ts-mocha": "^10.0.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/actions/initialize.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | #[instruction(params: InitializeParams)] // rpc parameters hint
5 | pub struct Initialize<'info> {
6 | #[account(
7 | init,
8 | space = 8 + std::mem::size_of::
(),
9 | payer = payer,
10 | seeds = [PROGRAM_SEED],
11 | bump
12 | )]
13 | pub program: AccountLoader<'info, MyProgramState>,
14 |
15 | #[account(
16 | init,
17 | space = 8 + std::mem::size_of::(),
18 | payer = payer,
19 | seeds = [ORACLE_SEED],
20 | bump
21 | )]
22 | pub oracle: AccountLoader<'info, MyOracleState>,
23 |
24 | pub authority: Signer<'info>,
25 |
26 | #[account(mut)]
27 | pub payer: Signer<'info>,
28 |
29 | pub system_program: Program<'info, System>,
30 | }
31 |
32 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
33 | pub struct InitializeParams {}
34 |
35 | impl Initialize<'_> {
36 | pub fn validate(
37 | &self,
38 | _ctx: &Context,
39 | _params: &InitializeParams
40 | ) -> anchor_lang::Result<()> {
41 | Ok(())
42 | }
43 |
44 | pub fn actuate(ctx: &Context, _params: &InitializeParams) -> anchor_lang::Result<()> {
45 | let program = &mut ctx.accounts.program.load_init()?;
46 | program.bump = ctx.bumps.program;
47 | program.authority = ctx.accounts.authority.key();
48 |
49 | let oracle = &mut ctx.accounts.oracle.load_init()?;
50 | oracle.bump = ctx.bumps.oracle;
51 | Ok(())
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/actions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod initialize;
2 | pub use initialize::*;
3 |
4 | pub mod refresh_prices;
5 | pub use refresh_prices::*;
6 |
7 | pub mod set_function;
8 | pub use set_function::*;
9 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/actions/refresh_prices.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | pub struct RefreshPrices<'info> {
5 | #[account(
6 | mut,
7 | seeds = [ORACLE_SEED],
8 | bump = oracle.load()?.bump
9 | )]
10 | pub oracle: AccountLoader<'info, MyOracleState>,
11 |
12 | // We use this to verify the functions enclave state
13 | #[account(
14 | constraint = function.load()?.validate_routine(
15 | &routine,
16 | &enclave_signer.to_account_info(),
17 | )?
18 | )]
19 | pub function: AccountLoader<'info, FunctionAccountData>,
20 | #[account(
21 | has_one = function,
22 | )]
23 | pub routine: Box>,
24 | pub enclave_signer: Signer<'info>,
25 | }
26 |
27 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
28 | pub struct RefreshPricesParams {
29 | pub rows: Vec,
30 | }
31 |
32 | impl RefreshPrices<'_> {
33 | pub fn validate(
34 | &self,
35 | _ctx: &Context,
36 | _params: &RefreshPricesParams,
37 | ) -> anchor_lang::Result<()> {
38 | Ok(())
39 | }
40 |
41 | pub fn actuate(ctx: &Context, params: &RefreshPricesParams) -> anchor_lang::Result<()> {
42 | let oracle = &mut ctx.accounts.oracle.load_mut()?;
43 | msg!("saving oracle data");
44 | oracle.save_rows(¶ms.rows)?;
45 |
46 | Ok(())
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/actions/set_function.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | #[instruction(params: SetFunctionParams)] // rpc parameters hint
5 | pub struct SetFunction<'info> {
6 | #[account(
7 | mut,
8 | // seeds = [PROGRAM_SEED],
9 | // bump = program.load()?.bump,
10 | has_one = authority
11 | )]
12 | pub program: AccountLoader<'info, MyProgramState>,
13 |
14 | // Make sure the function has at least one MrEnclave measurement defined.
15 | pub switchboard_function: AccountLoader<'info, FunctionAccountData>,
16 | #[account(
17 | constraint = switchboard_routine.function == switchboard_function.key()
18 | )]
19 | pub switchboard_routine: Box>,
20 |
21 | pub authority: Signer<'info>,
22 | }
23 |
24 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
25 | pub struct SetFunctionParams {}
26 |
27 | impl SetFunction<'_> {
28 | pub fn validate(
29 | &self,
30 | _ctx: &Context,
31 | _params: &SetFunctionParams,
32 | ) -> anchor_lang::Result<()> {
33 | Ok(())
34 | }
35 |
36 | pub fn actuate(ctx: &Context, _params: &SetFunctionParams) -> anchor_lang::Result<()> {
37 | let program = &mut ctx.accounts.program.load_mut()?;
38 | program.switchboard_function = ctx.accounts.switchboard_function.key();
39 | program.switchboard_routine = ctx.accounts.switchboard_routine.key();
40 | Ok(())
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/error.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum BasicOracleError {
6 | #[msg("Invalid authority account")]
7 | InvalidAuthority,
8 | #[msg("Array overflow")]
9 | ArrayOverflow,
10 | #[msg("Stale data")]
11 | StaleData,
12 | #[msg("Invalid trusted signer")]
13 | InvalidTrustedSigner,
14 | #[msg("Invalid MRENCLAVE")]
15 | InvalidMrEnclave,
16 | #[msg("Failed to find a valid trading symbol for this price")]
17 | InvalidSymbol,
18 | #[msg("FunctionAccount pubkey did not match program_state.function")]
19 | IncorrectSwitchboardFunction,
20 | #[msg("FunctionAccount pubkey did not match program_state.function")]
21 | InvalidSwitchboardFunction,
22 | #[msg("FunctionAccount was not validated successfully")]
23 | FunctionValidationFailed,
24 | }
25 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/lib.rs:
--------------------------------------------------------------------------------
1 | pub use switchboard_solana::prelude::*;
2 |
3 | pub mod actions;
4 | pub use actions::*;
5 |
6 | pub mod error;
7 | pub use error::*;
8 |
9 | pub mod model;
10 | pub use model::*;
11 |
12 | pub mod utils;
13 | pub use utils::*;
14 |
15 | declare_id!("8cagvrMvnhcVpVuAxYajqBGSrrjCbhJBL3954UjttwuJ");
16 |
17 | pub const PROGRAM_SEED: &[u8] = b"BASICORACLE";
18 |
19 | pub const ORACLE_SEED: &[u8] = b"ORACLE_V1_SEED";
20 |
21 | #[program]
22 | pub mod basic_oracle {
23 | use super::*;
24 |
25 | #[access_control(ctx.accounts.validate(&ctx, ¶ms))]
26 | pub fn initialize(
27 | ctx: Context,
28 | params: InitializeParams,
29 | ) -> anchor_lang::Result<()> {
30 | Initialize::actuate(&ctx, ¶ms)
31 | }
32 |
33 | #[access_control(ctx.accounts.validate(&ctx, ¶ms))]
34 | pub fn set_function(
35 | ctx: Context,
36 | params: SetFunctionParams,
37 | ) -> anchor_lang::Result<()> {
38 | SetFunction::actuate(&ctx, ¶ms)
39 | }
40 |
41 | #[access_control(ctx.accounts.validate(&ctx, ¶ms))]
42 | pub fn refresh_oracles(
43 | ctx: Context,
44 | params: RefreshPricesParams,
45 | ) -> anchor_lang::Result<()> {
46 | RefreshPrices::actuate(&ctx, ¶ms)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub use crate::*;
2 |
3 | pub fn parse_mr_enclaves(enclaves: &Vec<[u8; 32]>) -> anchor_lang::Result<[[u8; 32]; 32]> {
4 | // enclaves
5 | // .clone()
6 | // .try_into()
7 | // .map_err(|_| error!(BasicOracleError::ArrayOverflow))
8 | if enclaves.len() > 32 {
9 | return Err(error!(BasicOracleError::ArrayOverflow));
10 | }
11 | let mut result: [[u8; 32]; 32] = [[0; 32]; 32];
12 |
13 | for (i, enclave) in enclaves.iter().enumerate() {
14 | result[i] = *enclave;
15 | }
16 |
17 | Ok(result)
18 | }
19 |
20 | #[cfg(test)]
21 | mod tests {
22 | use super::*;
23 |
24 | #[test]
25 | fn test_parse_mr_enclaves_success() {
26 | let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 10];
27 | let result = parse_mr_enclaves(&enclaves).unwrap();
28 |
29 | // Check first 10 elements are [1; 32]
30 | for i in 0..10 {
31 | assert_eq!(result[i], [1; 32]);
32 | }
33 |
34 | // Check the remaining elements are [0; 32] (default)
35 | for i in 10..32 {
36 | assert_eq!(result[i], [0; 32]);
37 | }
38 | }
39 |
40 | // #[test]
41 | // fn test_parse_mr_enclaves_overflow() {
42 | // let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 33];
43 | // match parse_mr_enclaves(&enclaves) {
44 | // Err(BasicOracleError::ArrayOverflow) => {} // test passes
45 | // _ => panic!("Unexpected result"), // test fails
46 | // };
47 | // }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/switchboard-function/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # These are backup files generated by rustfmt
7 | **/*.rs.bk
8 |
9 | # MSVC Windows builds of rustc generate these, which store debugging information
10 | *.pdb
11 |
12 |
13 | # Added by cargo
14 |
15 | /target
16 |
17 | *measurement.txt
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/switchboard-function/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic-oracle-function"
5 | version = "0.1.0"
6 | edition = "2021"
7 |
8 | [[bin]]
9 | name = "basic-oracle-function"
10 | path = "src/main.rs"
11 |
12 | [dependencies]
13 | basic_oracle = { path = "../", features = ["no-entrypoint"] }
14 | tokio = "^1"
15 | futures = "0.3"
16 | serde = "^1"
17 | serde_json = "^1"
18 | switchboard-utils = "0.8.5"
19 | # switchboard-solana = { version = "0.28.43" }
20 | switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [
21 | "macros",
22 | ] }
23 | # switchboard-utils = { path = "../../../../../../rust/switchboard-utils" }
24 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/switchboard-function/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1.4
2 | FROM switchboardlabs/sgx-function AS builder
3 |
4 | WORKDIR /home/root/switchboard-function
5 | COPY ./Cargo.lock ./Cargo.toml ./
6 | COPY ./src ./src
7 |
8 | WORKDIR /home/root/switchboard-function/switchboard-function
9 | COPY ./switchboard-function/Cargo.lock ./switchboard-function/Cargo.toml ./
10 | COPY ./switchboard-function/src ./src
11 |
12 | RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} \
13 | --mount=type=cache,target=target,id=${TARGETPLATFORM} \
14 | cargo build --release && \
15 | cargo strip && \
16 | mv target/release/basic-oracle-function /sgx/app
17 |
18 | FROM switchboardlabs/sgx-function
19 |
20 | # Copy the binary
21 | WORKDIR /sgx
22 | COPY --from=builder /sgx/app /sgx
23 |
24 | # Get the measurement from the enclave
25 | RUN rm -f /measurement.txt && \
26 | /get_measurement.sh && \
27 | cat /measurement.txt
28 |
29 | ENTRYPOINT ["bash", "/boot.sh"]
30 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/switchboard-function/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "basic-oracle-function",
3 | "scripts": {
4 | "build:cargo": "make",
5 | "fix": "cargo fmt"
6 | },
7 | "dependencies": {
8 | "solana-basic-oracle": "latest"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/switchboard-function/src/main.rs:
--------------------------------------------------------------------------------
1 | pub use switchboard_solana::switchboard_function;
2 |
3 | pub mod binance;
4 | pub use binance::*;
5 |
6 | pub use basic_oracle::{
7 | self, OracleData, OracleDataWithTradingSymbol, RefreshPrices, RefreshPricesParams,
8 | SwitchboardDecimal, TradingSymbol, ID as PROGRAM_ID,
9 | };
10 |
11 | #[switchboard_function]
12 | pub async fn binance_oracle_function(
13 | runner: FunctionRunner,
14 | _params: Vec,
15 | ) -> Result, SbFunctionError> {
16 | msg!("function runner loaded!");
17 |
18 | // Then, write your own Rust logic and build a Vec of instructions.
19 | // Should be under 700 bytes after serialization
20 | let binance = Binance::fetch().await?;
21 | let ixs: Vec = binance.to_ixns(&runner);
22 |
23 | // Emit the instructions for the oracle to validate and relay on-chain
24 | Ok(ixs)
25 | }
26 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import type { Connection } from "@solana/web3.js";
2 | import { sleep } from "@switchboard-xyz/common";
3 |
4 | export async function printLogs(
5 | connection: Connection,
6 | tx: string,
7 | v0Txn?: boolean,
8 | delay = 3000
9 | ) {
10 | await sleep(delay);
11 | const parsed = await connection.getParsedTransaction(tx, {
12 | commitment: "confirmed",
13 | maxSupportedTransactionVersion: v0Txn ? 0 : undefined,
14 | });
15 | console.log(parsed?.meta?.logMessages?.join("\n"));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/functions/01_basic_oracle/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "moduleResolution": "node",
18 | "noEmit": true,
19 | "esModuleInterop": true,
20 | "strict": false,
21 | "strictNullChecks": false,
22 | "target": "es6"
23 | },
24 | "include": [
25 | "tests/**/*",
26 | "target/types/*.ts"
27 | ],
28 | "exclude": [
29 | "target",
30 | "lib"
31 | ]
32 | }
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
2 | Makefile
3 | README.md
4 | node_modules
5 | .turbo
6 | measurement.txt
7 | .anchor
8 | scripts
9 | .prettierignore
10 | .gitignore
11 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | .yarn
9 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic_oracle"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "basic_oracle"
12 | path = "src/lib.rs"
13 |
14 | [features]
15 | no-entrypoint = []
16 | no-idl = []
17 | no-log-ix-name = []
18 | cpi = ["no-entrypoint"]
19 | default = []
20 |
21 | [dependencies]
22 | switchboard-solana = "0.28.19"
23 | # switchboard-solana = { version = "0.28.19", path = "../../../rust/switchboard-solana" }
24 | bytemuck = "^1"
25 | anchor-lang = { version = "0.28.0", features = [
26 | "init-if-needed",
27 | "allow-missing-optionals",
28 | ] }
29 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # anchor-vrf-lite-parser
6 |
7 | > An example program written in Anchor demonstrating how to integrate Switchboard Functions and verify attestation on-chain.
8 |
9 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Usage
18 |
19 | Build the example program
20 |
21 | ```bash
22 | anchor build
23 | ```
24 |
25 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
26 |
27 | ```bash
28 | export ANCHOR_VRF_LITE_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_lite_parser-keypair.json)
29 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g Anchor.toml
30 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g src/lib.rs
31 | ```
32 |
33 | Then run Anchor test
34 |
35 | ```bash
36 | anchor test
37 | ```
38 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-liquidity-oracle",
3 | "private": true,
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
7 | "directory": "examples/functions/01_basic_oracle"
8 | },
9 | "scripts": {
10 | "build:anchor": "anchor build",
11 | "clean": "pnpm exec rimraf node_modules .anchor lib .turbo"
12 | },
13 | "dependencies": {
14 | "@coral-xyz/anchor": "^0.28.0",
15 | "@solana/spl-token": "^0.3.8",
16 | "@solana/web3.js": "^1.78.3",
17 | "@switchboard-xyz/common": "*",
18 | "@switchboard-xyz/solana.js": "*"
19 | },
20 | "devDependencies": {
21 | "@types/bn.js": "^5.1.0",
22 | "@types/chai": "^4.3.0",
23 | "@types/mocha": "^9.0.0",
24 | "@types/node": "^20.4.0",
25 | "chai": "^4.3.4",
26 | "mocha": "^9.0.3",
27 | "ts-mocha": "^10.0.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/scripts/devnet.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env tsx
2 | import * as anchor from "@coral-xyz/anchor";
3 | import { BasicOracle } from "../target/types/basic_oracle";
4 |
5 | async function main() {
6 | const program = anchor.workspace.BasicOracle as anchor.Program;
7 | }
8 |
9 | main().catch((err) => {
10 | console.error(err);
11 | process.exit(1);
12 | });
13 |
14 | const getStringArg = (arg: string): string => {
15 | const args = process.argv.slice(2);
16 | const argIdx = args.findIndex((v) => v === arg || v === `--${arg}`);
17 | if (argIdx === -1) {
18 | return "";
19 | }
20 | if (argIdx + 1 > args.length) {
21 | throw new Error(`Failed to find arg`);
22 | }
23 | return args[argIdx + 1];
24 | };
25 |
26 | const getFlag = (arg: string): boolean => {
27 | const args = process.argv.slice(2);
28 | const argIdx = args.findIndex((v) => v === arg || v === `--${arg}`);
29 | if (argIdx === -1) {
30 | return false;
31 | }
32 | return true;
33 | };
34 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/src/actions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod initialize;
2 | pub use initialize::*;
3 |
4 | pub mod refresh_prices;
5 | pub use refresh_prices::*;
6 |
7 | pub mod set_function;
8 | pub use set_function::*;
9 |
10 | pub mod trigger_function;
11 | pub use trigger_function::*;
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/src/actions/refresh_prices.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | pub struct RefreshPrices<'info> {
5 | #[account(
6 | mut,
7 | seeds = [ORACLE_SEED],
8 | bump = oracle.load()?.bump
9 | )]
10 | pub oracle: AccountLoader<'info, MyOracleState>,
11 |
12 | // We use this to verify the functions enclave state
13 | #[account(
14 | constraint =
15 | function.load()?.validate(
16 | &enclave_signer.to_account_info()
17 | )? @ BasicOracleError::FunctionValidationFailed
18 | // FunctionAccountData::validate(
19 | // &function.to_account_info(),
20 | // &enclave_signer.to_account_info()
21 | // )? @ BasicOracleError::FunctionValidationFailed
22 | )]
23 | pub function: AccountLoader<'info, FunctionAccountData>,
24 | pub enclave_signer: Signer<'info>,
25 | }
26 |
27 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
28 | pub struct RefreshPricesParams {
29 | pub rows: Vec,
30 | }
31 |
32 | impl RefreshPrices<'_> {
33 | pub fn validate(
34 | &self,
35 | _ctx: &Context,
36 | _params: &RefreshPricesParams,
37 | ) -> anchor_lang::Result<()> {
38 | Ok(())
39 | }
40 |
41 | pub fn actuate(ctx: &Context, params: &RefreshPricesParams) -> anchor_lang::Result<()> {
42 | let oracle = &mut ctx.accounts.oracle.load_mut()?;
43 | msg!("saving oracle data");
44 | oracle.save_rows(¶ms.rows)?;
45 |
46 | Ok(())
47 | }
48 | }
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/src/actions/set_function.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | #[instruction(params: SetFunctionParams)] // rpc parameters hint
5 | pub struct SetFunction<'info> {
6 | #[account(
7 | mut,
8 | seeds = [PROGRAM_SEED],
9 | bump = program.load()?.bump,
10 | has_one = authority
11 | )]
12 | pub program: AccountLoader<'info, MyProgramState>,
13 |
14 | pub function: AccountLoader<'info, FunctionAccountData>,
15 |
16 | /// CHECK:
17 | pub authority: Signer<'info>,
18 | }
19 |
20 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
21 | pub struct SetFunctionParams { }
22 |
23 | impl SetFunction<'_> {
24 | pub fn validate(
25 | &self,
26 | _ctx: &Context,
27 | _params: &SetFunctionParams,
28 | ) -> anchor_lang::Result<()> {
29 | Ok(())
30 | }
31 |
32 | pub fn actuate(ctx: &Context, _params: &SetFunctionParams) -> anchor_lang::Result<()> {
33 | let program = &mut ctx.accounts.program.load_init()?;
34 | program.function = ctx.accounts.function.key();
35 | Ok(())
36 | }
37 | }
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/src/error.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum BasicOracleError {
6 | #[msg("Invalid authority account")]
7 | InvalidAuthority,
8 | #[msg("Array overflow")]
9 | ArrayOverflow,
10 | #[msg("Stale data")]
11 | StaleData,
12 | #[msg("Invalid trusted signer")]
13 | InvalidTrustedSigner,
14 | #[msg("Invalid MRENCLAVE")]
15 | InvalidMrEnclave,
16 | #[msg("Failed to find a valid trading symbol for this price")]
17 | InvalidSymbol,
18 | #[msg("FunctionAccount pubkey did not match program_state.function")]
19 | IncorrectSwitchboardFunction,
20 | #[msg("FunctionAccount pubkey did not match program_state.function")]
21 | InvalidSwitchboardFunction,
22 | #[msg("FunctionAccount was not validated successfully")]
23 | FunctionValidationFailed,
24 | }
25 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub use crate::*;
2 |
3 | pub fn parse_mr_enclaves(enclaves: &Vec<[u8; 32]>) -> anchor_lang::Result<[[u8; 32]; 32]> {
4 | // enclaves
5 | // .clone()
6 | // .try_into()
7 | // .map_err(|_| error!(BasicOracleError::ArrayOverflow))
8 | if enclaves.len() > 32 {
9 | return Err(error!(BasicOracleError::ArrayOverflow));
10 | }
11 | let mut result: [[u8; 32]; 32] = [[0; 32]; 32];
12 |
13 | for (i, enclave) in enclaves.iter().enumerate() {
14 | result[i] = *enclave;
15 | }
16 |
17 | Ok(result)
18 | }
19 |
20 | #[cfg(test)]
21 | mod tests {
22 | use super::*;
23 |
24 | #[test]
25 | fn test_parse_mr_enclaves_success() {
26 | let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 10];
27 | let result = parse_mr_enclaves(&enclaves).unwrap();
28 |
29 | // Check first 10 elements are [1; 32]
30 | for i in 0..10 {
31 | assert_eq!(result[i], [1; 32]);
32 | }
33 |
34 | // Check the remaining elements are [0; 32] (default)
35 | for i in 10..32 {
36 | assert_eq!(result[i], [0; 32]);
37 | }
38 | }
39 |
40 | // #[test]
41 | // fn test_parse_mr_enclaves_overflow() {
42 | // let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 33];
43 | // match parse_mr_enclaves(&enclaves) {
44 | // Err(BasicOracleError::ArrayOverflow) => {} // test passes
45 | // _ => panic!("Unexpected result"), // test fails
46 | // };
47 | // }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
8 | # Cargo.lock
9 |
10 | # These are backup files generated by rustfmt
11 | **/*.rs.bk
12 |
13 | # MSVC Windows builds of rustc generate these, which store debugging information
14 | *.pdb
15 |
16 |
17 | # Added by cargo
18 |
19 | /target
20 |
21 | *measurement.txt
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic-oracle-function"
5 | version = "0.1.0"
6 | edition = "2021"
7 |
8 | [[bin]]
9 | name = "basic-oracle-function"
10 | path = "src/main.rs"
11 |
12 | [dependencies]
13 | basic_oracle = { path = "../", features = ["no-entrypoint"] }
14 | tokio = "^1"
15 | futures = "0.3"
16 | serde = "^1"
17 | serde_json = "^1"
18 | switchboard-utils = { version = "0.8.0" }
19 | switchboard-solana = "0.28.19"
20 | # switchboard-solana = { version = "0.28.19", path = "../../../../rust/switchboard-solana" }
21 | bytemuck = "1.13.1"
22 | rust_decimal = "1.30.0"
23 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1.4
2 | FROM switchboardlabs/sgx-function:main AS builder
3 |
4 | ARG CARGO_NAME=switchboard-function
5 | ENV CARGO_NAME=$CARGO_NAME
6 |
7 | WORKDIR /home/root/switchboard-function
8 | COPY ./Anchor.toml ./Cargo.lock ./Cargo.toml ./
9 | COPY ./src ./src
10 |
11 | WORKDIR /home/root/switchboard-function/switchboard-function
12 | COPY ./switchboard-function/Cargo.lock ./switchboard-function/Cargo.toml ./
13 | COPY ./switchboard-function/src ./src
14 |
15 | RUN --mount=target=/home/root/.cargo/git,type=cache \
16 | --mount=target=/home/root/.cargo/registry,type=cache \
17 | --mount=type=cache,target=/home/root/switchboard-function/switchboard-function/target \
18 | cargo build --release && \
19 | cargo strip && \
20 | mv target/release/basic-oracle-function /sgx/app
21 |
22 | FROM switchboardlabs/sgx-function:main
23 |
24 | # Copy the binary
25 | WORKDIR /sgx
26 | COPY --from=builder /sgx/app /sgx
27 |
28 | # Get the measurement from the enclave
29 | RUN /get_measurement.sh
30 |
31 | ENTRYPOINT ["bash", "/boot.sh"]
32 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-liquidity-oracle-function",
3 | "scripts": {
4 | "build:function": "make"
5 | },
6 | "dependencies": {
7 | "solana-liquidity-oracle": "latest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/src/binance.rs:
--------------------------------------------------------------------------------
1 | // Note: Binance API requires a non-US IP address
2 |
3 | use crate::*;
4 |
5 | pub use switchboard_utils::reqwest;
6 |
7 |
8 | use serde::Deserialize;
9 |
10 | #[allow(non_snake_case)]
11 | #[derive(Deserialize, Default, Clone, Debug)]
12 | pub struct BinanceBook {
13 | pub bids: Vec<(String, String)>,
14 | pub asks: Vec<(String, String)>,
15 | }
16 | impl Into for BinanceBook {
17 | fn into(self) -> NormalizedBook {
18 | let book = self;
19 | let mut res = NormalizedBook::default();
20 | for bid in book.bids.iter() {
21 | res.bids.push(NormalizedOrdersRow {
22 | price: Decimal::try_from(bid.0.as_str()).unwrap(),
23 | amount: Decimal::try_from(bid.1.as_str()).unwrap(),
24 | });
25 | }
26 | for ask in book.asks.iter() {
27 | res.asks.push(NormalizedOrdersRow {
28 | price: Decimal::try_from(ask.0.as_str()).unwrap(),
29 | amount: Decimal::try_from(ask.1.as_str()).unwrap(),
30 | });
31 | }
32 | res.price = res.bids[0]
33 | .price
34 | .checked_add(res.asks[0].price)
35 | .unwrap()
36 | .checked_div(2.into())
37 | .unwrap();
38 | res
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/src/bitfinex.rs:
--------------------------------------------------------------------------------
1 | // Note: Binance API requires a non-US IP address
2 |
3 | use crate::*;
4 |
5 | pub use switchboard_utils::reqwest;
6 |
7 |
8 | use serde::Deserialize;
9 |
10 | #[allow(non_snake_case)]
11 | #[derive(Deserialize, Default, Clone, Debug)]
12 | pub struct BitfinexOrdersRow {
13 | price: String,
14 | amount: String,
15 | timestamp: String,
16 | }
17 | #[allow(non_snake_case)]
18 | #[derive(Deserialize, Default, Clone, Debug)]
19 | pub struct BitfinexBook {
20 | pub bids: Vec,
21 | pub asks: Vec,
22 | }
23 | impl Into for BitfinexBook {
24 | fn into(self) -> NormalizedBook {
25 | let book = self;
26 | let mut res = NormalizedBook::default();
27 | for bid in book.bids.iter() {
28 | res.bids.push(NormalizedOrdersRow {
29 | price: Decimal::try_from(bid.price.as_str()).unwrap(),
30 | amount: Decimal::try_from(bid.amount.as_str()).unwrap(),
31 | });
32 | }
33 | for ask in book.asks.iter() {
34 | res.asks.push(NormalizedOrdersRow {
35 | price: Decimal::try_from(ask.price.as_str()).unwrap(),
36 | amount: Decimal::try_from(ask.amount.as_str()).unwrap(),
37 | });
38 | }
39 | res.price = res.bids[0]
40 | .price
41 | .checked_add(res.asks[0].price)
42 | .unwrap()
43 | .checked_div(2.into())
44 | .unwrap();
45 | res
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/src/coinbase.rs:
--------------------------------------------------------------------------------
1 | // Note: Binance API requires a non-US IP address
2 |
3 | use crate::*;
4 |
5 | pub use switchboard_utils::reqwest;
6 |
7 |
8 | use serde::Deserialize;
9 |
10 | #[allow(non_snake_case)]
11 | #[derive(Deserialize, Default, Clone, Debug)]
12 | pub struct CoinbaseBook {
13 | pub bids: Vec<(String, String, i64)>,
14 | pub asks: Vec<(String, String, i64)>,
15 | }
16 | impl Into for CoinbaseBook {
17 | fn into(self) -> NormalizedBook {
18 | let book = self;
19 | let mut res = NormalizedBook::default();
20 | for bid in book.bids.iter() {
21 | res.bids.push(NormalizedOrdersRow {
22 | price: Decimal::try_from(bid.0.as_str()).unwrap(),
23 | amount: Decimal::try_from(bid.1.as_str()).unwrap(),
24 | });
25 | }
26 | for ask in book.asks.iter() {
27 | res.asks.push(NormalizedOrdersRow {
28 | price: Decimal::try_from(ask.0.as_str()).unwrap(),
29 | amount: Decimal::try_from(ask.1.as_str()).unwrap(),
30 | });
31 | }
32 | res.price = res.bids[0]
33 | .price
34 | .checked_add(res.asks[0].price)
35 | .unwrap()
36 | .checked_div(2.into())
37 | .unwrap();
38 | res
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/switchboard-function/src/kraken.rs:
--------------------------------------------------------------------------------
1 | // Note: Binance API requires a non-US IP address
2 |
3 | use crate::*;
4 |
5 | pub use switchboard_utils::reqwest;
6 |
7 |
8 | use serde::Deserialize;
9 |
10 | #[allow(non_snake_case)]
11 | #[derive(Deserialize, Default, Clone, Debug)]
12 | pub struct KrakenBookInternal {
13 | pub bids: Vec<(String, String, i64)>,
14 | pub asks: Vec<(String, String, i64)>,
15 | }
16 | #[allow(non_snake_case)]
17 | #[derive(Deserialize, Default, Clone, Debug)]
18 | pub struct KrakenBook {
19 | pub result: HashMap,
20 | }
21 | impl Into for KrakenBook {
22 | fn into(self) -> NormalizedBook {
23 | let book = self.result.values().next().unwrap();
24 | let mut res = NormalizedBook::default();
25 | for bid in book.bids.iter() {
26 | res.bids.push(NormalizedOrdersRow {
27 | price: Decimal::try_from(bid.0.as_str()).unwrap(),
28 | amount: Decimal::try_from(bid.1.as_str()).unwrap(),
29 | });
30 | }
31 | for ask in book.asks.iter() {
32 | res.asks.push(NormalizedOrdersRow {
33 | price: Decimal::try_from(ask.0.as_str()).unwrap(),
34 | amount: Decimal::try_from(ask.1.as_str()).unwrap(),
35 | });
36 | }
37 | res.price = res.bids[0]
38 | .price
39 | .checked_add(res.asks[0].price)
40 | .unwrap()
41 | .checked_div(2.into())
42 | .unwrap();
43 | res
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import type { Connection } from "@solana/web3.js";
2 | import { sleep } from "@switchboard-xyz/common";
3 |
4 | export async function printLogs(
5 | connection: Connection,
6 | tx: string,
7 | v0Txn?: boolean,
8 | delay = 3000
9 | ) {
10 | await sleep(delay);
11 | const parsed = await connection.getParsedTransaction(tx, {
12 | commitment: "confirmed",
13 | maxSupportedTransactionVersion: v0Txn ? 0 : undefined,
14 | });
15 | console.log(parsed?.meta?.logMessages?.join("\n"));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/functions/02_liquidity_oracle/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "strict": false,
20 | "strictNullChecks": false,
21 | "target": "es6",
22 | "paths": {
23 | "@switchboard-xyz/solana.js": [
24 | "../../../../../javascript/solana.js"
25 | ]
26 | }
27 | },
28 | "include": [
29 | "tests/**/*",
30 | "target/types/*.ts"
31 | ],
32 | "exclude": [
33 | "target",
34 | "lib"
35 | ],
36 | "references": [
37 | {
38 | "path": "../../../../../javascript/solana.js"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
2 | Makefile
3 | README.md
4 | node_modules
5 | .turbo
6 | measurement.txt
7 | .anchor
8 | scripts
9 | .prettierignore
10 | .gitignore
11 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | .yarn
9 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/Anchor.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["."]
3 |
4 | [features]
5 | seeds = false
6 | skip-lint = false
7 |
8 | [programs.localnet]
9 | basic_oracle = "BkTMjFhosJ1xKtLMV2xchGtnTDBABLJ45aXzs7x9FdeX"
10 |
11 | [programs.devnet]
12 | basic_oracle = "BkTMjFhosJ1xKtLMV2xchGtnTDBABLJ45aXzs7x9FdeX"
13 |
14 | [provider]
15 | # cluster = "https://api.devnet.solana.com"
16 | # wallet = "~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json"
17 | cluster = "Localnet"
18 | wallet = "~/.config/solana/id.json"
19 |
20 | # cluster = "devnet"
21 | [scripts]
22 | test = "pnpm exec ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
23 |
24 | [test]
25 | startup_wait = 15000
26 |
27 | [test.validator]
28 | url = "https://api.devnet.solana.com"
29 |
30 | [[test.validator.clone]] # sb devnet oracle programID
31 | address = "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
32 |
33 | [[test.validator.clone]] # sb devnet oracle IDL
34 | address = "Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk"
35 |
36 | [[test.validator.clone]] # sb devnet oracle SbState
37 | address = "CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
38 |
39 | [[test.validator.clone]] # sb devnet oracle tokenVault
40 | address = "7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie"
41 |
42 | [[test.validator.clone]] # sb devnet attestation programID
43 | address = "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"
44 |
45 | [[test.validator.clone]] # sb devnet attestation IDL
46 | address = "5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz"
47 |
48 | [[test.validator.clone]] # sb devnet attestation State
49 | address = "BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK"
50 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic_oracle"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "basic_oracle"
12 | path = "src/lib.rs"
13 |
14 | [features]
15 | no-entrypoint = []
16 | no-idl = []
17 | no-log-ix-name = []
18 | cpi = ["no-entrypoint"]
19 | default = []
20 |
21 | [dependencies]
22 | switchboard-solana = "0.28.19"
23 | # switchboard-solana = { version = "0.28.19", path = "../../../rust/switchboard-solana" }
24 | bytemuck = "^1"
25 | anchor-lang = { version = "0.28.0", features = [
26 | "init-if-needed",
27 | "allow-missing-optionals",
28 | ] }
29 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # anchor-vrf-lite-parser
6 |
7 | > An example program written in Anchor demonstrating how to integrate Switchboard Functions and verify attestation on-chain.
8 |
9 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Usage
18 |
19 | Build the example program
20 |
21 | ```bash
22 | anchor build
23 | ```
24 |
25 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
26 |
27 | ```bash
28 | export ANCHOR_VRF_LITE_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_lite_parser-keypair.json)
29 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g Anchor.toml
30 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g src/lib.rs
31 | ```
32 |
33 | Then run Anchor test
34 |
35 | ```bash
36 | anchor test
37 | ```
38 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-candles-oracle-example",
3 | "private": true,
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
7 | "directory": "examples/functions/01_basic_oracle"
8 | },
9 | "scripts": {
10 | "build:cargo": "anchor build",
11 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
12 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
13 | },
14 | "dependencies": {
15 | "@coral-xyz/anchor": "^0.28.0",
16 | "@solana/spl-token": "^0.3.8",
17 | "@solana/web3.js": "^1.78.3",
18 | "@switchboard-xyz/common": "*",
19 | "@switchboard-xyz/solana.js": "*"
20 | },
21 | "devDependencies": {
22 | "@types/bn.js": "^5.1.0",
23 | "@types/chai": "^4.3.0",
24 | "@types/mocha": "^9.0.0",
25 | "@types/node": "^20.4.0",
26 | "chai": "^4.3.4",
27 | "mocha": "^9.0.3",
28 | "ts-mocha": "^10.0.0"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/scripts/devnet.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env tsx
2 | import * as anchor from "@coral-xyz/anchor";
3 | import { BasicOracle } from "../target/types/basic_oracle";
4 |
5 | async function main() {
6 | const program = anchor.workspace.BasicOracle as anchor.Program;
7 | }
8 |
9 | main().catch((err) => {
10 | console.error(err);
11 | process.exit(1);
12 | });
13 |
14 | const getStringArg = (arg: string): string => {
15 | const args = process.argv.slice(2);
16 | const argIdx = args.findIndex((v) => v === arg || v === `--${arg}`);
17 | if (argIdx === -1) {
18 | return "";
19 | }
20 | if (argIdx + 1 > args.length) {
21 | throw new Error(`Failed to find arg`);
22 | }
23 | return args[argIdx + 1];
24 | };
25 |
26 | const getFlag = (arg: string): boolean => {
27 | const args = process.argv.slice(2);
28 | const argIdx = args.findIndex((v) => v === arg || v === `--${arg}`);
29 | if (argIdx === -1) {
30 | return false;
31 | }
32 | return true;
33 | };
34 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/src/actions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod initialize;
2 | pub use initialize::*;
3 |
4 | pub mod refresh_prices;
5 | pub use refresh_prices::*;
6 |
7 | pub mod set_function;
8 | pub use set_function::*;
9 |
10 | pub mod trigger_function;
11 | pub use trigger_function::*;
12 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/src/actions/refresh_prices.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | pub struct RefreshPrices<'info> {
5 | #[account(
6 | mut,
7 | seeds = [ORACLE_SEED],
8 | bump = oracle.load()?.bump
9 | )]
10 | pub oracle: AccountLoader<'info, MyOracleState>,
11 |
12 | // We use this to verify the functions enclave state
13 | #[account(
14 | constraint =
15 | function.load()?.validate(
16 | &enclave_signer.to_account_info()
17 | )? @ BasicOracleError::FunctionValidationFailed
18 | // FunctionAccountData::validate(
19 | // &function.to_account_info(),
20 | // &enclave_signer.to_account_info()
21 | // )? @ BasicOracleError::FunctionValidationFailed
22 | )]
23 | pub function: AccountLoader<'info, FunctionAccountData>,
24 | pub enclave_signer: Signer<'info>,
25 | }
26 |
27 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
28 | pub struct RefreshPricesParams {
29 | pub rows: Vec,
30 | }
31 |
32 | impl RefreshPrices<'_> {
33 | pub fn validate(
34 | &self,
35 | _ctx: &Context,
36 | _params: &RefreshPricesParams,
37 | ) -> anchor_lang::Result<()> {
38 | Ok(())
39 | }
40 |
41 | pub fn actuate(ctx: &Context, params: &RefreshPricesParams) -> anchor_lang::Result<()> {
42 | let oracle = &mut ctx.accounts.oracle.load_mut()?;
43 | msg!("saving oracle data");
44 | oracle.save_rows(¶ms.rows)?;
45 |
46 | Ok(())
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/src/actions/set_function.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | #[instruction(params: SetFunctionParams)] // rpc parameters hint
5 | pub struct SetFunction<'info> {
6 | #[account(
7 | mut,
8 | seeds = [PROGRAM_SEED],
9 | bump = program.load()?.bump,
10 | has_one = authority
11 | )]
12 | pub program: AccountLoader<'info, MyProgramState>,
13 |
14 | pub function: AccountLoader<'info, FunctionAccountData>,
15 |
16 | /// CHECK:
17 | pub authority: Signer<'info>,
18 | }
19 |
20 | #[derive(Clone, AnchorSerialize, AnchorDeserialize)]
21 | pub struct SetFunctionParams {}
22 |
23 | impl SetFunction<'_> {
24 | pub fn validate(
25 | &self,
26 | _ctx: &Context,
27 | _params: &SetFunctionParams,
28 | ) -> anchor_lang::Result<()> {
29 | Ok(())
30 | }
31 |
32 | pub fn actuate(ctx: &Context, _params: &SetFunctionParams) -> anchor_lang::Result<()> {
33 | let program = &mut ctx.accounts.program.load_init()?;
34 | program.function = ctx.accounts.function.key();
35 | Ok(())
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/src/error.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum BasicOracleError {
6 | #[msg("Invalid authority account")]
7 | InvalidAuthority,
8 | #[msg("Array overflow")]
9 | ArrayOverflow,
10 | #[msg("Stale data")]
11 | StaleData,
12 | #[msg("Invalid trusted signer")]
13 | InvalidTrustedSigner,
14 | #[msg("Invalid MRENCLAVE")]
15 | InvalidMrEnclave,
16 | #[msg("Failed to find a valid trading symbol for this price")]
17 | InvalidSymbol,
18 | #[msg("FunctionAccount pubkey did not match program_state.function")]
19 | IncorrectSwitchboardFunction,
20 | #[msg("FunctionAccount pubkey did not match program_state.function")]
21 | InvalidSwitchboardFunction,
22 | #[msg("FunctionAccount was not validated successfully")]
23 | FunctionValidationFailed,
24 | }
25 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub use crate::*;
2 |
3 | pub fn parse_mr_enclaves(enclaves: &Vec<[u8; 32]>) -> anchor_lang::Result<[[u8; 32]; 32]> {
4 | // enclaves
5 | // .clone()
6 | // .try_into()
7 | // .map_err(|_| error!(BasicOracleError::ArrayOverflow))
8 | if enclaves.len() > 32 {
9 | return Err(error!(BasicOracleError::ArrayOverflow));
10 | }
11 | let mut result: [[u8; 32]; 32] = [[0; 32]; 32];
12 |
13 | for (i, enclave) in enclaves.iter().enumerate() {
14 | result[i] = *enclave;
15 | }
16 |
17 | Ok(result)
18 | }
19 |
20 | #[cfg(test)]
21 | mod tests {
22 | use super::*;
23 |
24 | #[test]
25 | fn test_parse_mr_enclaves_success() {
26 | let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 10];
27 | let result = parse_mr_enclaves(&enclaves).unwrap();
28 |
29 | // Check first 10 elements are [1; 32]
30 | for i in 0..10 {
31 | assert_eq!(result[i], [1; 32]);
32 | }
33 |
34 | // Check the remaining elements are [0; 32] (default)
35 | for i in 10..32 {
36 | assert_eq!(result[i], [0; 32]);
37 | }
38 | }
39 |
40 | // #[test]
41 | // fn test_parse_mr_enclaves_overflow() {
42 | // let enclaves: Vec<[u8; 32]> = vec![[1; 32]; 33];
43 | // match parse_mr_enclaves(&enclaves) {
44 | // Err(BasicOracleError::ArrayOverflow) => {} // test passes
45 | // _ => panic!("Unexpected result"), // test fails
46 | // };
47 | // }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
7 | # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
8 | # Cargo.lock
9 |
10 | # These are backup files generated by rustfmt
11 | **/*.rs.bk
12 |
13 | # MSVC Windows builds of rustc generate these, which store debugging information
14 | *.pdb
15 |
16 |
17 | # Added by cargo
18 |
19 | /target
20 |
21 | *measurement.txt
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "basic-oracle-function"
5 | version = "0.1.0"
6 | edition = "2021"
7 |
8 | [[bin]]
9 | name = "basic-oracle-function"
10 | path = "src/main.rs"
11 |
12 | [dependencies]
13 | basic_oracle = { path = "../", features = ["no-entrypoint"] }
14 | tokio = "^1"
15 | futures = "0.3"
16 | serde = "^1"
17 | serde_json = "^1"
18 | switchboard-utils = { version = "0.8" }
19 | switchboard-solana = "0.28.19"
20 | # switchboard-solana = { version = "0.28.19", path = "../../../../rust/switchboard-solana" }
21 | bytemuck = "1.13.1"
22 | rust_decimal = "1.30.0"
23 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1.4
2 | FROM switchboardlabs/sgx-function:main AS builder
3 |
4 | ARG CARGO_NAME=switchboard-function
5 | ENV CARGO_NAME=$CARGO_NAME
6 |
7 | WORKDIR /home/root/switchboard-function
8 | COPY ./Anchor.toml ./Cargo.lock ./Cargo.toml ./
9 | COPY ./src ./src
10 |
11 | WORKDIR /home/root/switchboard-function/switchboard-function
12 | COPY ./switchboard-function/Cargo.lock ./switchboard-function/Cargo.toml ./
13 | COPY ./switchboard-function/src ./src
14 |
15 | RUN --mount=target=/home/root/.cargo/git,type=cache \
16 | --mount=target=/home/root/.cargo/registry,type=cache \
17 | --mount=type=cache,target=/home/root/switchboard-function/switchboard-function/target \
18 | cargo build --release && \
19 | cargo strip && \
20 | mv target/release/basic-oracle-function /sgx/app
21 |
22 | FROM switchboardlabs/sgx-function:main
23 |
24 | # Copy the binary
25 | WORKDIR /sgx
26 | COPY --from=builder /sgx/app /sgx
27 |
28 | # Get the measurement from the enclave
29 | RUN /get_measurement.sh
30 |
31 | ENTRYPOINT ["bash", "/boot.sh"]
32 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-candles-oracle-function",
3 | "scripts": {
4 | "build:function": "make"
5 | },
6 | "dependencies": {
7 | "solana-candles-oracle-example": "latest"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/src/binance.rs:
--------------------------------------------------------------------------------
1 | // Note: Binance API requires a non-US IP address
2 |
3 | use crate::*;
4 |
5 | pub use switchboard_utils::reqwest;
6 | use serde::Deserialize;
7 |
8 | #[derive(Deserialize, Default, Clone, Debug)]
9 | pub struct BinanceCandle(
10 | i64, // Kline open time
11 | String, // Open price
12 | String, // High price
13 | String, // Low price
14 | String, // Close price
15 | String, // Volume
16 | i64, // Kline Close time
17 | String, // Quote asset volume
18 | i64, // Number of trades
19 | String, // Taker buy base asset volume
20 | String, // Taker buy quote asset volume
21 | String, // - Unused -
22 | );
23 |
24 | impl Into for BinanceCandle {
25 | fn into(self) -> NormalizedCandle {
26 | NormalizedCandle {
27 | open_time: self.0,
28 | open_price: Decimal::try_from(self.1.as_str()).unwrap(),
29 | high_price: Decimal::try_from(self.2.as_str()).unwrap(),
30 | low_price: Decimal::try_from(self.3.as_str()).unwrap(),
31 | close_price: Decimal::try_from(self.4.as_str()).unwrap(),
32 | volume: Decimal::try_from(self.5.as_str()).unwrap(),
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/src/bitfinex.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | pub use switchboard_utils::reqwest;
4 | use serde::Deserialize;
5 |
6 | #[derive(Deserialize, Default, Clone, Debug)]
7 | pub struct BitfinexCandle(
8 | i64, // open time
9 | String, // Open price
10 | String, // High price
11 | String, // Low price
12 | String, // Close price
13 | String, // Volume
14 | );
15 |
16 | impl Into for BitfinexCandle {
17 | fn into(self) -> NormalizedCandle {
18 | NormalizedCandle {
19 | open_time: self.0,
20 | open_price: Decimal::try_from(self.1.as_str()).unwrap(),
21 | high_price: Decimal::try_from(self.2.as_str()).unwrap(),
22 | low_price: Decimal::try_from(self.3.as_str()).unwrap(),
23 | close_price: Decimal::try_from(self.4.as_str()).unwrap(),
24 | volume: Decimal::try_from(self.5.as_str()).unwrap(),
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/src/coinbase.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | pub use switchboard_utils::reqwest;
4 | use serde::Deserialize;
5 |
6 | #[derive(Deserialize, Default, Clone, Debug)]
7 | pub struct CoinbaseCandle(
8 | i64, // open time
9 | f64, // Low price
10 | f64, // High price
11 | f64, // Open price
12 | f64, // Close price
13 | f64, // Volume
14 | );
15 |
16 | impl Into for CoinbaseCandle {
17 | fn into(self) -> NormalizedCandle {
18 | NormalizedCandle {
19 | open_time: self.0,
20 | low_price: Decimal::try_from(self.1).unwrap(),
21 | high_price: Decimal::try_from(self.2).unwrap(),
22 | open_price: Decimal::try_from(self.3).unwrap(),
23 | close_price: Decimal::try_from(self.4).unwrap(),
24 | volume: Decimal::try_from(self.5).unwrap(),
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/switchboard-function/src/kraken.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | pub use switchboard_utils::reqwest;
4 | use serde::Deserialize;
5 |
6 | #[derive(Deserialize, Default, Clone, Debug)]
7 | pub struct KrakenCandle(
8 | String, // Open time
9 | String, // Low price
10 | String, // High price
11 | String, // Open price
12 | String, // Close price
13 | String, // VWAP // TODO: surface this
14 | String, // Volume
15 | String, // Count
16 | );
17 |
18 | #[derive(Deserialize, Default, Clone, Debug)]
19 | pub struct KrakenCandleResponse {
20 | pub result: HashMap>,
21 | }
22 |
23 | impl Into> for KrakenCandleResponse {
24 | fn into(self) -> Vec {
25 | let candles = self.result.values().next().unwrap();
26 | let mut res = vec![];
27 | for candle in candles {
28 | res.push(NormalizedCandle {
29 | open_time: candle.0.parse().unwrap(),
30 | low_price: Decimal::try_from(candle.1.as_str()).unwrap(),
31 | high_price: Decimal::try_from(candle.2.as_str()).unwrap(),
32 | open_price: Decimal::try_from(candle.3.as_str()).unwrap(),
33 | close_price: Decimal::try_from(candle.4.as_str()).unwrap(),
34 | volume: Decimal::try_from(candle.5.as_str()).unwrap(),
35 | });
36 | }
37 | res
38 | }
39 | }
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import type { Connection } from "@solana/web3.js";
2 | import { sleep } from "@switchboard-xyz/common";
3 |
4 | export async function printLogs(
5 | connection: Connection,
6 | tx: string,
7 | v0Txn?: boolean,
8 | delay = 3000
9 | ) {
10 | await sleep(delay);
11 | const parsed = await connection.getParsedTransaction(tx, {
12 | commitment: "confirmed",
13 | maxSupportedTransactionVersion: v0Txn ? 0 : undefined,
14 | });
15 | console.log(parsed?.meta?.logMessages?.join("\n"));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/functions/03_candles_oracle/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "strict": false,
20 | "strictNullChecks": false,
21 | "target": "es6",
22 | "paths": {
23 | "@switchboard-xyz/solana.js": [
24 | "../../../../../javascript/solana.js"
25 | ]
26 | }
27 | },
28 | "include": [
29 | "tests/**/*",
30 | "target/types/*.ts"
31 | ],
32 | "exclude": [
33 | "target",
34 | "lib"
35 | ],
36 | "references": [
37 | {
38 | "path": "../../../../../javascript/solana.js"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | .yarn
9 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "custom-randomness-request"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "custom_randomness_request"
12 |
13 | [features]
14 | no-entrypoint = []
15 | no-idl = []
16 | no-log-ix-name = []
17 | cpi = ["no-entrypoint"]
18 | default = []
19 |
20 | [dependencies]
21 | bytemuck = "^1"
22 | anchor-spl = "0.29.0"
23 | # switchboard-solana = "0.29.70"
24 | switchboard-solana = { path = "../../../rust/switchboard-solana" }
25 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-randomness-callback-example",
3 | "scripts": {
4 | "request": "tsx ./request.ts",
5 | "build:anchor": "anchor build",
6 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
7 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
8 | },
9 | "dependencies": {
10 | "@coral-xyz/anchor": "^0.28.0",
11 | "@solana/spl-token": "^0.3.8",
12 | "@solana/web3.js": "^1.78.4",
13 | "@switchboard-xyz/common": "*",
14 | "@switchboard-xyz/solana.js": "*",
15 | "dotenv": "^16.3.1"
16 | },
17 | "devDependencies": {
18 | "@types/bn.js": "^5.1.0",
19 | "@types/chai": "^4.3.0",
20 | "@types/dotenv": "^8.2.0",
21 | "@types/mocha": "^9.0.0",
22 | "@types/node": "^20.4.2",
23 | "chai": "^4.3.4",
24 | "mocha": "^9.0.3",
25 | "ts-mocha": "^10.0.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/src/error.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum RandomnessRequestError {
6 | #[msg("Invalid authority account")]
7 | InvalidAuthority,
8 | #[msg("Invalid escrow account")]
9 | InvalidEscrow,
10 | #[msg("Array overflow")]
11 | ArrayOverflow,
12 | #[msg("Stale data")]
13 | StaleData,
14 | #[msg("Invalid trusted signer")]
15 | InvalidTrustedSigner,
16 | #[msg("Invalid MRENCLAVE")]
17 | InvalidMrEnclave,
18 | #[msg("Failed to find a valid trading symbol for this price")]
19 | InvalidSymbol,
20 | #[msg("FunctionAccount pubkey did not match program_state.function")]
21 | IncorrectSwitchboardFunction,
22 | #[msg("FunctionAccount pubkey did not match program_state.function")]
23 | InvalidSwitchboardFunction,
24 | #[msg("FunctionAccount was not validated successfully")]
25 | FunctionValidationFailed,
26 | #[msg("FunctionRequestAccount status should be 'RequestSuccess'")]
27 | SwitchboardRequestNotSuccessful,
28 | #[msg("Round is inactive")]
29 | RoundInactive,
30 | #[msg("House has insufficient funds to payout winners")]
31 | HouseInsufficientFunds,
32 | }
33 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/src/state.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[account(zero_copy(unsafe))]
4 | pub struct HouseState {
5 | pub bump: u8,
6 | pub max_guess: u8,
7 | pub authority: Pubkey,
8 | pub function: Pubkey,
9 | pub token_wallet: Pubkey,
10 | }
11 |
12 | #[repr(u8)]
13 | #[derive(Copy, Clone, Default, Debug, Eq, PartialEq, AnchorSerialize, AnchorDeserialize)]
14 | pub enum RoundStatus {
15 | #[default]
16 | None = 0,
17 | Pending,
18 | Settled,
19 | }
20 | impl From for u8 {
21 | fn from(value: RoundStatus) -> Self {
22 | match value {
23 | RoundStatus::Pending => 1,
24 | RoundStatus::Settled => 2,
25 | _ => 0,
26 | }
27 | }
28 | }
29 | impl From for RoundStatus {
30 | fn from(value: u8) -> Self {
31 | match value {
32 | 1 => RoundStatus::Pending,
33 | 2 => RoundStatus::Settled,
34 | _ => RoundStatus::default(),
35 | }
36 | }
37 | }
38 |
39 | #[zero_copy(unsafe)]
40 | pub struct UserRound {
41 | pub request: Pubkey,
42 | pub guess: u8,
43 | pub status: RoundStatus,
44 | pub result: u8,
45 | pub wager: u64,
46 | pub slot: u64,
47 | pub timestamp: i64,
48 | }
49 |
50 | #[account(zero_copy(unsafe))]
51 | pub struct UserState {
52 | pub bump: u8,
53 | pub authority: Pubkey,
54 | pub token_wallet: Pubkey,
55 | pub current_round: UserRound,
56 | pub last_round: UserRound,
57 | }
58 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
2 | Makefile
3 | README.md
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # These are backup files generated by rustfmt
7 | **/*.rs.bk
8 |
9 | # MSVC Windows builds of rustc generate these, which store debugging information
10 | *.pdb
11 |
12 |
13 | # Added by cargo
14 |
15 | /target
16 |
17 | measurement.txt
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "randomness-function"
5 | version = "0.1.0"
6 | edition = "2021"
7 |
8 | [[bin]]
9 | name = "randomness-function"
10 | path = "src/main.rs"
11 |
12 | [dependencies]
13 | tokio = "^1"
14 | futures = "0.3"
15 | # switchboard-solana = "0.29.70"
16 | switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [
17 | "macros",
18 | ] }
19 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1.4
2 | FROM switchboardlabs/sgx-function AS builder
3 |
4 | ARG CARGO_NAME=switchboard-function
5 | ENV CARGO_NAME=$CARGO_NAME
6 |
7 | WORKDIR /home/root/switchboard-function/switchboard-function
8 | COPY ./Cargo.lock ./Cargo.toml ./
9 | COPY ./src ./src
10 |
11 | RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} --mount=type=cache,target=target,id=${TARGETPLATFORM} \
12 | cargo build --release && \
13 | cargo strip && \
14 | mv target/release/${CARGO_NAME} /sgx/app
15 |
16 | FROM switchboardlabs/sgx-function
17 |
18 | # Copy the binary
19 | WORKDIR /sgx
20 | COPY --from=builder /sgx/app /sgx
21 |
22 | # Get the measurement from the enclave
23 | RUN /get_measurement.sh
24 |
25 | ENTRYPOINT ["bash", "/boot.sh"]
26 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: build clean publish test
2 |
3 | # Variables
4 | CARGO_NAME=randomness-function
5 | DOCKER_IMAGE_NAME=gallynaut/randomness-function
6 |
7 | DOCKER_BUILD_COMMAND=DOCKER_BUILDKIT=1 docker buildx build --platform linux/amd64 --build-arg CARGO_NAME=${CARGO_NAME}
8 |
9 | # Default make task
10 | all: build
11 |
12 | docker_build:
13 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile -t ${DOCKER_IMAGE_NAME}:dev --load ./
14 | docker_publish:
15 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile -t ${DOCKER_IMAGE_NAME} --push ./
16 |
17 | dev_docker_build:
18 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile.dev -t ${DOCKER_IMAGE_NAME}:dev --load ../../../../../../
19 | dev_docker_publish:
20 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile.dev -t ${DOCKER_IMAGE_NAME} --push ../../../../../../
21 |
22 | build: docker_build measurement
23 |
24 | dev: dev_docker_build measurement
25 |
26 | publish: docker_publish measurement
27 |
28 | measurement:
29 | @docker run -d --platform=linux/amd64 --name=my-switchboard-function ${DOCKER_IMAGE_NAME}:dev > /dev/null
30 | @docker cp my-switchboard-function:/measurement.txt measurement.txt
31 | @docker stop my-switchboard-function > /dev/null
32 | @docker rm my-switchboard-function > /dev/null
33 |
34 | # Task to clean up the compiled rust application
35 | clean:
36 | cargo clean
37 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/switchboard-function/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-randomness-callback-function",
3 | "scripts": {
4 | "build:cargo": "make",
5 | "fix": "cargo fmt"
6 | },
7 | "dependencies": {}
8 | }
9 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import type { Connection } from "@solana/web3.js";
2 | import { sleep } from "@switchboard-xyz/common";
3 |
4 | export async function printLogs(
5 | connection: Connection,
6 | tx: string,
7 | v0Txn?: boolean,
8 | delay = 3000
9 | ) {
10 | await sleep(delay);
11 | const parsed = await connection.getParsedTransaction(tx, {
12 | commitment: "confirmed",
13 | maxSupportedTransactionVersion: v0Txn ? 0 : undefined,
14 | });
15 | console.log(parsed?.meta?.logMessages?.join("\n"));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/functions/04_randomness_callback/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "strict": false,
20 | "strictNullChecks": false,
21 | "target": "es6",
22 | "paths": {
23 | "@switchboard-xyz/solana.js": [
24 | "../../../../../javascript/solana.js"
25 | ]
26 | }
27 | },
28 | "include": [
29 | "tests/**/*",
30 | "target/types/*.ts",
31 | "./request.ts"
32 | ],
33 | "exclude": [
34 | "target",
35 | "lib"
36 | ],
37 | "references": [
38 | {
39 | "path": "../../../../../javascript/solana.js"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | debug/
4 | target/
5 |
6 | # These are backup files generated by rustfmt
7 | **/*.rs.bk
8 |
9 | # MSVC Windows builds of rustc generate these, which store debugging information
10 | *.pdb
11 |
12 | # Added by cargo
13 | /target
14 |
15 | # you can remove this but it may be unclear which image tag this belongs to
16 | measurement.txt
17 |
18 | .anchor
19 | .DS_Store
20 | target
21 | **/*.rs.bk
22 | node_modules
23 | test-ledger
24 | .yarn
25 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/.prettierignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | node_modules
6 | dist
7 | build
8 | test-ledger
9 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/Anchor.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["."]
3 |
4 | [features]
5 | seeds = false
6 | skip-lint = false
7 | [programs.localnet]
8 | raffle_program = "3uMC4KCYHsY1WopPoGpTWqZdqoNxm6f8EVA4XLZpKYzw"
9 |
10 | [provider]
11 | cluster = "Localnet"
12 | wallet = "~/.config/solana/id.json"
13 |
14 | [scripts]
15 | test = "pnpm exec ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts --exit"
16 |
17 | # [test.validator]
18 | # url = "https://api.devnet.solana.com"
19 |
20 | # [test]
21 | # startup_wait = 15000
22 |
23 | # [[test.validator.clone]] # sb devnet oracle programID
24 | # address = "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
25 |
26 | # [[test.validator.clone]] # sb devnet oracle IDL
27 | # address = "Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk"
28 |
29 | # [[test.validator.clone]] # sb devnet oracle SbState
30 | # address = "CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
31 |
32 | # [[test.validator.clone]] # sb devnet oracle tokenVault
33 | # address = "7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie"
34 |
35 | # [[test.validator.clone]] # sb devnet attestation programID
36 | # address = "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"
37 |
38 | # [[test.validator.clone]] # sb devnet attestation IDL
39 | # address = "5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz"
40 |
41 | # [[test.validator.clone]] # sb devnet programState
42 | # address = "5MFs7RGTjLi1wtKNBFRtuLipCkkjs4YQwRRU9sjnbQbS"
43 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["."]
3 |
4 | [package]
5 | name = "raffle-program"
6 | version = "0.1.0"
7 | description = "Created with Anchor"
8 | edition = "2021"
9 |
10 | [profile.release]
11 | overflow-checks = true
12 | lto = "fat"
13 | codegen-units = 1
14 | [profile.release.build-override]
15 | opt-level = 3
16 | incremental = false
17 | codegen-units = 1
18 |
19 | [lib]
20 | crate-type = ["cdylib", "lib"]
21 | name = "raffle_program"
22 |
23 | [features]
24 | no-entrypoint = []
25 | no-idl = []
26 | no-log-ix-name = []
27 | cpi = ["no-entrypoint"]
28 | default = []
29 |
30 | [dependencies]
31 | switchboard-solana = "0.28.43"
32 | # switchboard-solana = { path = "../../../rust/switchboard-solana" }
33 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-raffle-program",
3 | "scripts": {
4 | "build:cargo": "anchor build",
5 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
6 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
7 | },
8 | "dependencies": {
9 | "@coral-xyz/anchor": "^0.28.0",
10 | "@switchboard-xyz/common": "*",
11 | "@switchboard-xyz/solana.js": "*"
12 | },
13 | "devDependencies": {
14 | "@types/bn.js": "^5.1.0",
15 | "@types/chai": "^4.3.0",
16 | "@types/mocha": "^9.0.0",
17 | "chai": "^4.3.4",
18 | "mocha": "^9.0.3",
19 | "prettier": "^2.6.2",
20 | "ts-mocha": "^10.0.0",
21 | "tsx": "^3.12.7",
22 | "typescript": "^4.3.5"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/src/actions/close_round.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[derive(Accounts)]
4 | pub struct CloseRound<'info> {
5 | #[account(
6 | mut,
7 | seeds = [b"MY_RAFFLE", raffle.load()?.authority.as_ref()],
8 | bump = raffle.load()?.bump,
9 | has_one = function,
10 | constraint = raffle.load()?.current_round.request == request.key() @ MyError::InvalidRequest
11 | )]
12 | pub raffle: AccountLoader<'info, RaffleAccount>,
13 |
14 | // SWITCHBOARD ACCOUNTS
15 | pub function: AccountLoader<'info, FunctionAccountData>,
16 | #[account(
17 | constraint = request.validate_signer(
18 | &function.to_account_info(),
19 | &enclave_signer.to_account_info()
20 | )?
21 | )]
22 | pub request: Box>,
23 | pub enclave_signer: Signer<'info>,
24 | }
25 |
26 | impl CloseRound<'_> {
27 | pub fn validate(&self, _ctx: &Context) -> Result<()> {
28 | Ok(())
29 | }
30 |
31 | pub fn actuate(ctx: &Context) -> Result<()> {
32 | let mut raffle = ctx.accounts.raffle.load_mut()?;
33 |
34 | if !raffle.ready_to_close() {
35 | return Err(error!(MyError::RoundCloseNotReady));
36 | }
37 |
38 | raffle.current_round.is_closed = true;
39 |
40 | // Implement your custom logic here
41 |
42 | Ok(())
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/src/actions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod initialize;
2 | pub use initialize::*;
3 |
4 | pub mod start_round;
5 | pub use start_round::*;
6 |
7 | pub mod close_round;
8 | pub use close_round::*;
9 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/src/error.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum MyError {
6 | #[msg("Invalid authority account")]
7 | InvalidAuthority,
8 | #[msg("Invalid round len")]
9 | InvalidRoundLen,
10 | #[msg("Invalid escrow account")]
11 | InvalidEscrow,
12 | #[msg("round_start not ready")]
13 | RoundStartNotReady,
14 | #[msg("round_close not ready")]
15 | RoundCloseNotReady,
16 | #[msg("Invalid request account")]
17 | InvalidRequest,
18 | }
19 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/switchboard-function/.dockerignore:
--------------------------------------------------------------------------------
1 | target/
2 | Makefile
3 | README.md
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/switchboard-function/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "solana-raffle-program"
5 | version = "0.1.0"
6 | edition = "2021"
7 |
8 | [dependencies]
9 | tokio = "^1"
10 | futures = "0.3"
11 | # switchboard-solana = "0.28.43"
12 | switchboard-solana = { path = "../../../../rust/switchboard-solana", features = [
13 | "macros",
14 | ] }
15 | switchboard-utils = { path = "../../../../../../rust/switchboard-utils" }
16 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/switchboard-function/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1.4
2 | FROM switchboardlabs/sgx-function AS builder
3 |
4 | ARG CARGO_NAME=switchboard-function
5 | ENV CARGO_NAME=$CARGO_NAME
6 |
7 | WORKDIR /home/root/switchboard-function
8 | COPY ./Cargo.lock ./Cargo.toml ./
9 | COPY ./src ./src
10 |
11 | RUN --mount=type=cache,target=/usr/local/cargo/registry,id=${TARGETPLATFORM} \
12 | --mount=type=cache,target=/home/root/switchboard-function/target,id=${TARGETPLATFORM} \
13 | cargo build --release && \
14 | cargo strip && \
15 | mv target/release/${CARGO_NAME} /sgx/app
16 |
17 | FROM switchboardlabs/sgx-function
18 |
19 | # Copy the binary
20 | COPY --from=builder /sgx/app /sgx
21 |
22 | # Get the measurement from the enclave
23 | RUN /get_measurement.sh
24 |
25 | ENTRYPOINT ["/bin/bash", "/boot.sh"]
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/switchboard-function/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: build clean publish test
2 |
3 | # Variables
4 | CARGO_NAME=solana-raffle-program # Cargo.toml name
5 | DOCKER_IMAGE_NAME=gallynaut/solana-raffle-program # Docker registry image name
6 |
7 | DOCKER_BUILD_COMMAND=DOCKER_BUILDKIT=1 docker buildx build --platform linux/amd64 --build-arg CARGO_NAME=${CARGO_NAME}
8 |
9 | # Default make task
10 | all: build
11 |
12 | docker_build:
13 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile -t ${DOCKER_IMAGE_NAME} --load ./
14 | docker_publish:
15 | ${DOCKER_BUILD_COMMAND} --pull -f Dockerfile -t ${DOCKER_IMAGE_NAME} --push ./
16 |
17 | build: docker_build measurement
18 |
19 | publish: docker_publish measurement
20 |
21 | measurement:
22 | @docker run -d --name my-switchboard-function $(DOCKER_IMAGE_NAME) > /dev/null
23 | @docker cp my-switchboard-function:/measurement.txt measurement.txt
24 | @docker stop my-switchboard-function > /dev/null
25 | @docker rm my-switchboard-function > /dev/null
26 |
27 | # Task to clean up the compiled rust application
28 | clean:
29 | cargo clean
30 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/switchboard-function/src/main.rs:
--------------------------------------------------------------------------------
1 | pub use switchboard_solana::prelude::*;
2 |
3 | pub mod params;
4 | pub use params::*;
5 |
6 | #[switchboard_function]
7 | pub async fn raffle_callback(
8 | runner: FunctionRunner,
9 | params: Vec
10 | ) -> Result, SbFunctionError> {
11 | // parse and validate user provided request params
12 | let params = ContainerParams::decode(¶ms).unwrap();
13 |
14 | // Then, write your own Rust logic and build a Vec of instructions.
15 | // Should be under 700 bytes after serialization
16 | let ixs: Vec = vec![];
17 |
18 | Ok(ixs)
19 | }
20 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/tests/utils.ts:
--------------------------------------------------------------------------------
1 | import type * as anchor from "@coral-xyz/anchor";
2 | import { sleep } from "@switchboard-xyz/common";
3 |
4 | export async function printLogs(
5 | connection: anchor.web3.Connection,
6 | tx: string,
7 | v0Txn?: boolean,
8 | delay = 3000
9 | ) {
10 | await sleep(delay);
11 | const parsed = await connection.getParsedTransaction(tx, {
12 | commitment: "confirmed",
13 | maxSupportedTransactionVersion: v0Txn ? 0 : undefined,
14 | });
15 | console.log(parsed?.meta?.logMessages?.join("\n"));
16 | }
17 |
--------------------------------------------------------------------------------
/examples/functions/05_raffle_program/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "types": [
4 | "mocha",
5 | "chai"
6 | ],
7 | "typeRoots": [
8 | "./node_modules/@types"
9 | ],
10 | "lib": [
11 | "es2015"
12 | ],
13 | "module": "commonjs",
14 | "target": "es6",
15 | "esModuleInterop": true,
16 | "paths": {
17 | "@switchboard-xyz/common": [
18 | "../../../../../javascript/common"
19 | ],
20 | "@switchboard-xyz/solana.js": [
21 | "../../../../../javascript/solana.js"
22 | ]
23 | }
24 | },
25 | "references": [
26 | {
27 | "path": "../../../../../javascript/common"
28 | },
29 | {
30 | "path": "../../../../../javascript/solana.js"
31 | }
32 | ]
33 | }
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | .anchor
3 | .DS_Store
4 | target
5 | **/*.rs.bk
6 | node_modules
7 | test-ledger
8 | client/
9 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/Anchor.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | members = ["."]
3 |
4 | [provider]
5 | # cluster = "devnet"
6 | cluster = "localnet"
7 | wallet = "~/.config/solana/id.json"
8 |
9 | [programs.localnet]
10 | anchor_vrf_lite_parser = "5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb"
11 |
12 | [programs.devnet]
13 | anchor_vrf_lite_parser = "5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb"
14 |
15 | [scripts]
16 | test = "pnpm exec ts-mocha -p ./tsconfig.json -t 60000 ./tests/*.test.ts --exit"
17 | "test:devnet" = "USE_SWITCHBOARD_DEVNET_QUEUE=true pnpm exec ts-mocha -p ./tsconfig.json -t 60000 ./tests/*.test.ts --exit"
18 |
19 | [test.validator]
20 | url = "https://api.devnet.solana.com"
21 |
22 | [test]
23 | startup_wait = 15000
24 |
25 | [[test.validator.clone]] # sbv2 devnet programID
26 | address = "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
27 |
28 | [[test.validator.clone]] # sbv2 devnet IDL
29 | address = "Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk"
30 |
31 | [[test.validator.clone]] # sbv2 devnet SbState
32 | address = "CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
33 |
34 | [[test.validator.clone]] # sbv2 devnet tokenVault
35 | address = "7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie"
36 |
37 | [[test.validator.clone]] # sb devnet attestation programID
38 | address = "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"
39 |
40 | [[test.validator.clone]] # sb devnet attestation IDL
41 | address = "5ExuoQR69trmKQfB95fDsUGsUrrChbGq9PFgt8qouncz"
42 |
43 | [[test.validator.clone]] # sb devnet programState
44 | address = "BzqtGXZPiDSinP4xMFgPf6FLgSa6iPufK4m4JJFgMnTK"
45 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 |
3 | [package]
4 | name = "anchor-vrf-lite-parser"
5 | version = "0.1.0"
6 | description = "Created with Anchor"
7 | edition = "2021"
8 |
9 | [lib]
10 | crate-type = ["cdylib", "lib"]
11 | name = "anchor_vrf_lite_parser"
12 |
13 | [features]
14 | default = []
15 | no-entrypoint = []
16 | no-idl = []
17 | no-log-ix-name = []
18 | cpi = ["no-entrypoint"]
19 |
20 | [dependencies]
21 | bytemuck = "1.13.1"
22 | # switchboard-solana = "0.28.4"
23 | switchboard-solana = { version = "0.28.4", path = "../../../rust/switchboard-solana" }
24 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # anchor-vrf-lite-parser
6 |
7 | > An example program written in Anchor demonstrating how to deserialize and read
8 | > a Switchboard VRF Lite account on Solana.
9 |
10 | [](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | ## Usage
19 |
20 | Build the example program
21 |
22 | ```bash
23 | anchor build
24 | ```
25 |
26 | Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
27 |
28 | ```bash
29 | export ANCHOR_VRF_LITE_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_lite_parser-keypair.json)
30 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g Anchor.toml
31 | sed -i '' s/5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb/"$ANCHOR_VRF_LITE_PARSER_PUBKEY"/g src/lib.rs
32 | ```
33 |
34 | Then run Anchor test
35 |
36 | ```bash
37 | anchor test
38 | ```
39 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/Xargo.toml:
--------------------------------------------------------------------------------
1 | [target.bpfel-unknown-unknown.dependencies.std]
2 | features = []
3 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "anchor-vrf-lite-parser",
3 | "version": "1.0.0",
4 | "private": true,
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/switchboard-xyz/sbv2-solana",
8 | "directory": "programs/anchor-vrf-lite-parser"
9 | },
10 | "scripts": {
11 | "build:cargo": "anchor build",
12 | "fix": "cargo fmt && pnpm exec prettier ./tests/*.ts -w",
13 | "clean": "pnpm exec rimraf node_modules .anchor .turbo"
14 | },
15 | "dependencies": {
16 | "@coral-xyz/anchor": "^0.28.0",
17 | "@coral-xyz/borsh": "^0.28.0",
18 | "@project-serum/borsh": "^0.2.5",
19 | "@solana/spl-token": "^0.3.6",
20 | "@solana/web3.js": "^1.77.3",
21 | "@switchboard-xyz/common": "*",
22 | "@switchboard-xyz/oracle": "*",
23 | "@switchboard-xyz/solana.js": "*",
24 | "chalk": "^4.1.2",
25 | "dotenv": "^16.0.1",
26 | "yargs": "^17.5.1"
27 | },
28 | "devDependencies": {
29 | "@types/chai": "^4.3.0",
30 | "@types/mocha": "^9.0.0",
31 | "chai": "^4.3.6",
32 | "mocha": "^9.0.3",
33 | "npm-run-all": "^4.1.5",
34 | "prettier-plugin-organize-imports": "^2.3.4",
35 | "ts-mocha": "^9.0.2"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/src/actions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod init_state;
2 | pub use init_state::*;
3 |
4 | pub mod update_result;
5 | pub use update_result::*;
6 |
7 | pub mod request_result;
8 | pub use request_result::*;
9 |
10 | pub mod close_state;
11 | pub use close_state::*;
12 |
--------------------------------------------------------------------------------
/examples/vrf/01_vrf_client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "ts-node": {
3 | "compilerOptions": {
4 | "module": "commonjs"
5 | }
6 | },
7 | "compilerOptions": {
8 | "types": [
9 | "mocha",
10 | "chai",
11 | "node"
12 | ],
13 | "typeRoots": [
14 | "./node_modules/@types"
15 | ],
16 | "module": "commonjs",
17 | "noEmit": true,
18 | "esModuleInterop": true,
19 | "strict": false,
20 | "strictNullChecks": false,
21 | "target": "es6",
22 | "paths": {
23 | "@switchboard-xyz/solana.js": [
24 | "../../../../../javascript/solana.js"
25 | ]
26 | }
27 | },
28 | "include": [
29 | "tests/**/*",
30 | "./cli.ts",
31 | "./client/**/*"
32 | ],
33 | "exclude": [
34 | "target",
35 | "lib"
36 | ],
37 | "references": [
38 | {
39 | "path": "../../../../../javascript/solana.js"
40 | }
41 | ]
42 | }
--------------------------------------------------------------------------------
/examples/vrf/02_vrf_flip/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | 
4 |
5 | # VRF Flip
6 |
7 | > An example project showing how to integrate Switchboard into an application to
8 | > simulate a heads or tails coin toss.
9 |
10 |
11 |
12 | **Repository**:
13 | [https://github.com/switchboard-xyz/vrf-flip](https://github.com/switchboard-xyz/vrf-flip)
14 |
15 | **Demo**: [https://vrf-demo.switchboard.xyz](https://vrf-demo.switchboard.xyz)
16 |
--------------------------------------------------------------------------------
/javascript/sbv2-lite/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
--------------------------------------------------------------------------------
/javascript/sbv2-lite/.npmignore:
--------------------------------------------------------------------------------
1 | *.tsbuildinfo
--------------------------------------------------------------------------------
/javascript/sbv2-lite/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Switchboard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/javascript/sbv2-lite/README.md:
--------------------------------------------------------------------------------
1 | # Switchboard V2 Lite
2 |
3 | A lightweight library to decode and parse aggregator accounts
4 |
5 | [](https://www.npmjs.com/package/@switchboard-xyz/sbv2-lite)
6 | [](https://twitter.com/switchboardxyz)
7 |
8 | ## Install
9 |
10 | ```
11 | npm i @switchboard-xyz/sbv2-lite
12 | ```
13 |
14 | ## Example
15 |
16 | ```ts
17 | import SwitchboardProgram from "@switchboard-xyz/sbv2-lite";
18 |
19 | //
20 |
21 | const sbv2 = await SwitchboardProgram.loadDevnet();
22 |
23 | // SOL_USD Aggregator https://switchboard.xyz/explorer
24 | const solAggregator = new anchor.web3.PublicKey(
25 | "GvDMxPzN1sCj7L26YDK2HnMRXEQmQ2aemov8YBtPS7vR"
26 | );
27 |
28 | const accountInfo = await sbv2.program.provider.connection.getAccountInfo(
29 | solAggregator
30 | );
31 | if (!accountInfo) {
32 | throw new Error(`failed to fetch account info`);
33 | }
34 |
35 | // Get latest value if its been updated in the last 300 seconds
36 | const latestResult = sbv2.decodeLatestAggregatorValue(accountInfo, 300);
37 | if (latestResult === null) {
38 | throw new Error(`failed to fetch latest result for aggregator`);
39 | }
40 | console.log(`latestResult: ${latestResult}`);
41 | // latestResult: 105.673205
42 | ```
43 |
--------------------------------------------------------------------------------
/javascript/sbv2-lite/src/idl/index.ts:
--------------------------------------------------------------------------------
1 | export { IDL as SWITCHBOARD_V2_IDL, SwitchboardV2 } from "./switchboard_v2";
2 |
--------------------------------------------------------------------------------
/javascript/sbv2-lite/tests/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [
4 | "../src",
5 | "../test",
6 | "../test/data/**.json"
7 | ],
8 | "exclude": [
9 | "**/node_modules"
10 | ],
11 | "compilerOptions": {
12 | "types": [
13 | "node",
14 | "mocha"
15 | ],
16 | "module": "ESNext",
17 | "allowJs": true,
18 | "rootDir": "../",
19 | "resolveJsonModule": true
20 | }
21 | }
--------------------------------------------------------------------------------
/javascript/sbv2-lite/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "include": [
4 | "./src/**/*",
5 | "./src/**/*.json"
6 | ],
7 | "compilerOptions": {
8 | "lib": [
9 | "ES2021",
10 | "ES2022.Object",
11 | "DOM"
12 | ],
13 | "moduleResolution": "nodenext",
14 | "inlineSourceMap": false,
15 | "inlineSources": false,
16 | "declaration": true,
17 | "declarationMap": true,
18 | "allowSyntheticDefaultImports": true,
19 | "experimentalDecorators": true,
20 | "emitDecoratorMetadata": true,
21 | "resolveJsonModule": true,
22 | "skipLibCheck": true,
23 | // strict
24 | "strict": true,
25 | "noImplicitThis": true,
26 | "alwaysStrict": true,
27 | "noImplicitAny": false,
28 | "strictNullChecks": false,
29 | "strictFunctionTypes": true,
30 | "noImplicitReturns": true,
31 | "esModuleInterop": true
32 | }
33 | }
--------------------------------------------------------------------------------
/javascript/sbv2-lite/tsconfig.cjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/tests/**/*.ts", "dist"],
4 | "compilerOptions": {
5 | "module": "commonjs",
6 | "composite": false,
7 | "declaration": false,
8 | "declarationMap": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/javascript/sbv2-lite/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.base.json",
3 | "exclude": [
4 | "node_modules",
5 | "**/tests/**/*.ts",
6 | "lib"
7 | ],
8 | "include": [
9 | "src/**/*",
10 | "src/**/*.json"
11 | ],
12 | "compilerOptions": {
13 | "module": "ESNext",
14 | "target": "es2022",
15 | "lib": [
16 | "ES2021",
17 | "ES2022.Object",
18 | "DOM"
19 | ],
20 | "outDir": "lib",
21 | "rootDir": "./src",
22 | "declaration": true,
23 | "experimentalDecorators": true,
24 | "noImplicitReturns": true,
25 | "noFallthroughCasesInSwitch": true,
26 | "noUnusedLocals": false,
27 | "noUnusedParameters": false,
28 | "useDefineForClassFields": true,
29 | "strictPropertyInitialization": false,
30 | "strict": true,
31 | "strictNullChecks": true,
32 | "allowJs": true,
33 | }
34 | }
--------------------------------------------------------------------------------
/javascript/solana.js/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | insert_final_newline = true
9 |
--------------------------------------------------------------------------------
/javascript/solana.js/.gitignore:
--------------------------------------------------------------------------------
1 | index.cjs
2 | index.js
3 | index.d.ts
4 | SwitchboardProgram.cjs
5 | SwitchboardProgram.js
6 | SwitchboardProgram.d.ts
7 | TransactionObject.cjs
8 | TransactionObject.js
9 | TransactionObject.d.ts
10 | AggregatorAccount.cjs
11 | AggregatorAccount.js
12 | AggregatorAccount.d.ts
13 | generated.cjs
14 | generated.js
15 | generated.d.ts
16 | runner.cjs
17 | runner.js
18 | runner.d.ts
19 | generated/accounts.cjs
20 | generated/accounts.js
21 | generated/accounts.d.ts
22 | generated/instructions.cjs
23 | generated/instructions.js
24 | generated/instructions.d.ts
25 | generated/types.cjs
26 | generated/types.js
27 | generated/types.d.ts
28 | generated/oracle.cjs
29 | generated/oracle.js
30 | generated/oracle.d.ts
31 | generated/oracle/accounts.cjs
32 | generated/oracle/accounts.js
33 | generated/oracle/accounts.d.ts
34 | generated/oracle/instructions.cjs
35 | generated/oracle/instructions.js
36 | generated/oracle/instructions.d.ts
37 | generated/oracle/types.cjs
38 | generated/oracle/types.js
39 | generated/oracle/types.d.ts
40 | generated/attestation.cjs
41 | generated/attestation.js
42 | generated/attestation.d.ts
43 | generated/attestation/accounts.cjs
44 | generated/attestation/accounts.js
45 | generated/attestation/accounts.d.ts
46 | generated/attestation/instructions.cjs
47 | generated/attestation/instructions.js
48 | generated/attestation/instructions.d.ts
49 | generated/attestation/types.cjs
50 | generated/attestation/types.js
51 | generated/attestation/types.d.ts
52 |
--------------------------------------------------------------------------------
/javascript/solana.js/.mocharc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extension": ["ts"],
3 | "node-option": [
4 | "experimental-specifier-resolution=node",
5 | "loader=ts-node/esm"
6 | ],
7 | "spec": ["test/**/*.spec.ts"],
8 | "timeout": "60000"
9 | }
10 |
--------------------------------------------------------------------------------
/javascript/solana.js/scripts/move-cjs-to-lib.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ts-node-script
2 |
3 | import { readdir, readFile, writeFile } from "node:fs/promises";
4 | import { dirname, format, parse, resolve } from "node:path";
5 | import { fileURLToPath } from "node:url";
6 |
7 | function abs(relativePath) {
8 | return resolve(dirname(fileURLToPath(import.meta.url)), relativePath);
9 | }
10 |
11 | async function moveAndRename(source, dest) {
12 | for (const file of await readdir(abs(source), { withFileTypes: true })) {
13 | if (file.isDirectory()) {
14 | await moveAndRename(`${source}/${file.name}`, `${dest}/${file.name}`);
15 | } else if (file.isFile()) {
16 | const parsed = parse(file.name);
17 |
18 | // Ignore anything that's not a .js file
19 | if (parsed.ext !== ".js") {
20 | continue;
21 | }
22 |
23 | // Rewrite any require statements to use .cjs
24 | const content = await readFile(abs(`${source}/${file.name}`), "utf8");
25 | const rewritten = content.replace(/require\("(\..+?).js"\)/g, (_, p1) => {
26 | return `require("${p1}.cjs")`;
27 | });
28 |
29 | // Rename the file to .cjs
30 | const renamed = format({ name: parsed.name, ext: ".cjs" });
31 |
32 | await writeFile(abs(`${dest}/${renamed}`), rewritten, "utf8");
33 | }
34 | }
35 | }
36 |
37 | moveAndRename("../lib-cjs", "../lib").catch((err) => {
38 | console.error(err);
39 | process.exit(1);
40 | });
41 |
--------------------------------------------------------------------------------
/javascript/solana.js/scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [
4 | "./*.ts",
5 | "scripts"
6 | ],
7 | "compilerOptions": {
8 | "rootDir": "../",
9 | "noEmit": true,
10 | "lib": [
11 | "ES2022"
12 | ]
13 | }
14 | }
--------------------------------------------------------------------------------
/javascript/solana.js/src/accounts/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./account.js";
2 | export * from "./aggregatorAccount.js";
3 | export * from "./aggregatorHistoryBuffer.js";
4 | export * from "./attestationPermissionAccount.js";
5 | export * from "./attestationProgramStateAccount.js";
6 | export * from "./attestationQueueAccount.js";
7 | export * from "./bufferRelayAccount.js";
8 | export * from "./crankAccount.js";
9 | export * from "./crankDataBuffer.js";
10 | export * from "./functionAccount.js";
11 | export * from "./functionRequestAccount.js";
12 | export * from "./functionRoutineAccount.js";
13 | export * from "./jobAccount.js";
14 | export * from "./leaseAccount.js";
15 | export * from "./oracleAccount.js";
16 | export * from "./permissionAccount.js";
17 | export * from "./programStateAccount.js";
18 | export * from "./queueAccount.js";
19 | export * from "./queueDataBuffer.js";
20 | export * from "./switchboardWallet.js";
21 | export * from "./verifierAccount.js";
22 | export * from "./vrfAccount.js";
23 | export * from "./vrfLiteAccount.js";
24 | export * from "./vrfPoolAccount.js";
25 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/browser.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Returns true if being run inside a web browser, false if in a Node process or electron app.
3 | *
4 | * Taken from @coral-xyz/anchor implementation.
5 | */
6 | export const isBrowser =
7 | process.env.ANCHOR_BROWSER ||
8 | (typeof window !== "undefined" && !window.process?.hasOwnProperty("type")); // eslint-disable-line no-prototype-builtins
9 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/accounts.ts:
--------------------------------------------------------------------------------
1 | export * from "./attestation-program/accounts/index.js";
2 | export * from "./oracle-program/accounts/index.js";
3 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./accounts/index.js";
2 | export * from "./errors/index.js";
3 | export * from "./instructions/index.js";
4 | export * from "./types/index.js";
5 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/instructions/accountCloseOverride.ts:
--------------------------------------------------------------------------------
1 | import type { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
5 | import type { AccountMeta, PublicKey } from "@solana/web3.js";
6 | import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
8 |
9 | export interface AccountCloseOverrideAccounts {
10 | enclave: PublicKey;
11 | function: PublicKey;
12 | solDest: PublicKey;
13 | systemProgram: PublicKey;
14 | }
15 |
16 | export function accountCloseOverride(
17 | program: SwitchboardProgram,
18 | accounts: AccountCloseOverrideAccounts
19 | ) {
20 | const keys: Array = [
21 | { pubkey: accounts.enclave, isSigner: false, isWritable: true },
22 | { pubkey: accounts.function, isSigner: false, isWritable: true },
23 | { pubkey: accounts.solDest, isSigner: false, isWritable: false },
24 | { pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
25 | ];
26 | const identifier = Buffer.from([65, 72, 78, 213, 38, 245, 58, 189]);
27 | const data = identifier;
28 | const ix = new TransactionInstruction({
29 | keys,
30 | programId: program.attestationProgramId,
31 | data,
32 | });
33 | return ix;
34 | }
35 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/instructions/viewVersion.ts:
--------------------------------------------------------------------------------
1 | import type { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
5 | import type { AccountMeta, PublicKey } from "@solana/web3.js";
6 | import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
8 |
9 | export function viewVersion(programId: PublicKey) {
10 | const keys: Array = [];
11 | const identifier = Buffer.from([213, 222, 182, 245, 222, 107, 62, 71]);
12 | const data = identifier;
13 | const ix = new TransactionInstruction({ keys, programId, data });
14 | return ix;
15 | }
16 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/programId.ts:
--------------------------------------------------------------------------------
1 | import { PublicKey } from "@solana/web3.js";
2 |
3 | // Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
4 | export const PROGRAM_ID_CLI = new PublicKey(
5 | "sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx"
6 | );
7 |
8 | // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
9 | export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI;
10 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/AttestationPermissionInitParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface AttestationPermissionInitParamsFields {}
9 |
10 | export interface AttestationPermissionInitParamsJSON {}
11 |
12 | export class AttestationPermissionInitParams {
13 | constructor(fields: AttestationPermissionInitParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new AttestationPermissionInitParams({});
22 | }
23 |
24 | static toEncodable(fields: AttestationPermissionInitParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): AttestationPermissionInitParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: AttestationPermissionInitParamsJSON
34 | ): AttestationPermissionInitParams {
35 | return new AttestationPermissionInitParams({});
36 | }
37 |
38 | toEncodable() {
39 | return AttestationPermissionInitParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionCloseParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionCloseParamsFields {}
9 |
10 | export interface FunctionCloseParamsJSON {}
11 |
12 | export class FunctionCloseParams {
13 | constructor(fields: FunctionCloseParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionCloseParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionCloseParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionCloseParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: FunctionCloseParamsJSON): FunctionCloseParams {
33 | return new FunctionCloseParams({});
34 | }
35 |
36 | toEncodable() {
37 | return FunctionCloseParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionRequestCloseParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionRequestCloseParamsFields {}
9 |
10 | export interface FunctionRequestCloseParamsJSON {}
11 |
12 | export class FunctionRequestCloseParams {
13 | constructor(fields: FunctionRequestCloseParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionRequestCloseParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionRequestCloseParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionRequestCloseParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: FunctionRequestCloseParamsJSON
34 | ): FunctionRequestCloseParams {
35 | return new FunctionRequestCloseParams({});
36 | }
37 |
38 | toEncodable() {
39 | return FunctionRequestCloseParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionResetEscrowParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionResetEscrowParamsFields {}
9 |
10 | export interface FunctionResetEscrowParamsJSON {}
11 |
12 | export class FunctionResetEscrowParams {
13 | constructor(fields: FunctionResetEscrowParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionResetEscrowParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionResetEscrowParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionResetEscrowParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: FunctionResetEscrowParamsJSON
34 | ): FunctionResetEscrowParams {
35 | return new FunctionResetEscrowParams({});
36 | }
37 |
38 | toEncodable() {
39 | return FunctionResetEscrowParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionSetAuthorityParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionSetAuthorityParamsFields {}
9 |
10 | export interface FunctionSetAuthorityParamsJSON {}
11 |
12 | export class FunctionSetAuthorityParams {
13 | constructor(fields: FunctionSetAuthorityParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionSetAuthorityParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionSetAuthorityParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionSetAuthorityParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: FunctionSetAuthorityParamsJSON
34 | ): FunctionSetAuthorityParams {
35 | return new FunctionSetAuthorityParams({});
36 | }
37 |
38 | toEncodable() {
39 | return FunctionSetAuthorityParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionSetEscrowParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionSetEscrowParamsFields {}
9 |
10 | export interface FunctionSetEscrowParamsJSON {}
11 |
12 | export class FunctionSetEscrowParams {
13 | constructor(fields: FunctionSetEscrowParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionSetEscrowParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionSetEscrowParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionSetEscrowParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: FunctionSetEscrowParamsJSON): FunctionSetEscrowParams {
33 | return new FunctionSetEscrowParams({});
34 | }
35 |
36 | toEncodable() {
37 | return FunctionSetEscrowParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/FunctionTriggerParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface FunctionTriggerParamsFields {}
9 |
10 | export interface FunctionTriggerParamsJSON {}
11 |
12 | export class FunctionTriggerParams {
13 | constructor(fields: FunctionTriggerParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new FunctionTriggerParams({});
22 | }
23 |
24 | static toEncodable(fields: FunctionTriggerParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): FunctionTriggerParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: FunctionTriggerParamsJSON): FunctionTriggerParams {
33 | return new FunctionTriggerParams({});
34 | }
35 |
36 | toEncodable() {
37 | return FunctionTriggerParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/StateInitParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface StateInitParamsFields {}
9 |
10 | export interface StateInitParamsJSON {}
11 |
12 | export class StateInitParams {
13 | constructor(fields: StateInitParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new StateInitParams({});
22 | }
23 |
24 | static toEncodable(fields: StateInitParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): StateInitParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: StateInitParamsJSON): StateInitParams {
33 | return new StateInitParams({});
34 | }
35 |
36 | toEncodable() {
37 | return StateInitParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/VerifierHeartbeatParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface VerifierHeartbeatParamsFields {}
9 |
10 | export interface VerifierHeartbeatParamsJSON {}
11 |
12 | export class VerifierHeartbeatParams {
13 | constructor(fields: VerifierHeartbeatParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new VerifierHeartbeatParams({});
22 | }
23 |
24 | static toEncodable(fields: VerifierHeartbeatParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): VerifierHeartbeatParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: VerifierHeartbeatParamsJSON): VerifierHeartbeatParams {
33 | return new VerifierHeartbeatParams({});
34 | }
35 |
36 | toEncodable() {
37 | return VerifierHeartbeatParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/VerifierInitParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface VerifierInitParamsFields {}
9 |
10 | export interface VerifierInitParamsJSON {}
11 |
12 | export class VerifierInitParams {
13 | constructor(fields: VerifierInitParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new VerifierInitParams({});
22 | }
23 |
24 | static toEncodable(fields: VerifierInitParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): VerifierInitParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: VerifierInitParamsJSON): VerifierInitParams {
33 | return new VerifierInitParams({});
34 | }
35 |
36 | toEncodable() {
37 | return VerifierInitParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/attestation-program/types/WalletCloseParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface WalletCloseParamsFields {}
9 |
10 | export interface WalletCloseParamsJSON {}
11 |
12 | export class WalletCloseParams {
13 | constructor(fields: WalletCloseParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new WalletCloseParams({});
22 | }
23 |
24 | static toEncodable(fields: WalletCloseParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): WalletCloseParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: WalletCloseParamsJSON): WalletCloseParams {
33 | return new WalletCloseParams({});
34 | }
35 |
36 | toEncodable() {
37 | return WalletCloseParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/errors.ts:
--------------------------------------------------------------------------------
1 | export * from "./attestation-program/errors/index.js";
2 | export * from "./oracle-program/errors/index.js";
3 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./attestation-program/index.js";
2 | export * from "./oracle-program/index.js";
3 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/instructions.ts:
--------------------------------------------------------------------------------
1 | export * from "./attestation-program/instructions/index.js";
2 | export * from "./oracle-program/instructions/index.js";
3 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./accounts/index.js";
2 | export * from "./errors/index.js";
3 | export * from "./instructions/index.js";
4 | export * from "./types/index.js";
5 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/instructions/setBumps.ts:
--------------------------------------------------------------------------------
1 | import type { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
5 | import type { AccountMeta, PublicKey } from "@solana/web3.js";
6 | import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
8 |
9 | export interface SetBumpsArgs {
10 | params: types.SetBumpsParamsFields;
11 | }
12 |
13 | export interface SetBumpsAccounts {
14 | state: PublicKey;
15 | }
16 |
17 | export const layout = borsh.struct([types.SetBumpsParams.layout("params")]);
18 |
19 | export function setBumps(
20 | program: SwitchboardProgram,
21 | args: SetBumpsArgs,
22 | accounts: SetBumpsAccounts,
23 | programId: PublicKey = program.oracleProgramId
24 | ) {
25 | const keys: Array = [
26 | { pubkey: accounts.state, isSigner: false, isWritable: true },
27 | ];
28 | const identifier = Buffer.from([19, 216, 193, 244, 22, 47, 180, 64]);
29 | const buffer = Buffer.alloc(1000);
30 | const len = layout.encode(
31 | {
32 | params: types.SetBumpsParams.toEncodable(args.params),
33 | },
34 | buffer
35 | );
36 | const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
37 | const ix = new TransactionInstruction({ keys, programId, data });
38 | return ix;
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/instructions/viewVersion.ts:
--------------------------------------------------------------------------------
1 | import type { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
5 | import type { AccountMeta, PublicKey } from "@solana/web3.js";
6 | import { TransactionInstruction } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
8 |
9 | export function viewVersion(programId: PublicKey) {
10 | const keys: Array = [];
11 | const identifier = Buffer.from([213, 222, 182, 245, 222, 107, 62, 71]);
12 | const data = identifier;
13 | const ix = new TransactionInstruction({ keys, programId, data });
14 | return ix;
15 | }
16 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/programId.ts:
--------------------------------------------------------------------------------
1 | import { PublicKey } from "@solana/web3.js";
2 |
3 | // Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
4 | export const PROGRAM_ID_CLI = new PublicKey(
5 | "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
6 | );
7 |
8 | // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
9 | export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI;
10 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/AggregatorLockParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface AggregatorLockParamsFields {}
9 |
10 | export interface AggregatorLockParamsJSON {}
11 |
12 | export class AggregatorLockParams {
13 | constructor(fields: AggregatorLockParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new AggregatorLockParams({});
22 | }
23 |
24 | static toEncodable(fields: AggregatorLockParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): AggregatorLockParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: AggregatorLockParamsJSON): AggregatorLockParams {
33 | return new AggregatorLockParams({});
34 | }
35 |
36 | toEncodable() {
37 | return AggregatorLockParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/AggregatorSetAuthorityParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface AggregatorSetAuthorityParamsFields {}
9 |
10 | export interface AggregatorSetAuthorityParamsJSON {}
11 |
12 | export class AggregatorSetAuthorityParams {
13 | constructor(fields: AggregatorSetAuthorityParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new AggregatorSetAuthorityParams({});
22 | }
23 |
24 | static toEncodable(fields: AggregatorSetAuthorityParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): AggregatorSetAuthorityParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: AggregatorSetAuthorityParamsJSON
34 | ): AggregatorSetAuthorityParams {
35 | return new AggregatorSetAuthorityParams({});
36 | }
37 |
38 | toEncodable() {
39 | return AggregatorSetAuthorityParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/AggregatorSetHistoryBufferParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface AggregatorSetHistoryBufferParamsFields {}
9 |
10 | export interface AggregatorSetHistoryBufferParamsJSON {}
11 |
12 | export class AggregatorSetHistoryBufferParams {
13 | constructor(fields: AggregatorSetHistoryBufferParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new AggregatorSetHistoryBufferParams({});
22 | }
23 |
24 | static toEncodable(fields: AggregatorSetHistoryBufferParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): AggregatorSetHistoryBufferParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(
33 | obj: AggregatorSetHistoryBufferParamsJSON
34 | ): AggregatorSetHistoryBufferParams {
35 | return new AggregatorSetHistoryBufferParams({});
36 | }
37 |
38 | toEncodable() {
39 | return AggregatorSetHistoryBufferParams.toEncodable(this);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/AggregatorSetQueueParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface AggregatorSetQueueParamsFields {}
9 |
10 | export interface AggregatorSetQueueParamsJSON {}
11 |
12 | export class AggregatorSetQueueParams {
13 | constructor(fields: AggregatorSetQueueParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new AggregatorSetQueueParams({});
22 | }
23 |
24 | static toEncodable(fields: AggregatorSetQueueParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): AggregatorSetQueueParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: AggregatorSetQueueParamsJSON): AggregatorSetQueueParams {
33 | return new AggregatorSetQueueParams({});
34 | }
35 |
36 | toEncodable() {
37 | return AggregatorSetQueueParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/LeaseSetAuthorityParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface LeaseSetAuthorityParamsFields {}
9 |
10 | export interface LeaseSetAuthorityParamsJSON {}
11 |
12 | export class LeaseSetAuthorityParams {
13 | constructor(fields: LeaseSetAuthorityParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new LeaseSetAuthorityParams({});
22 | }
23 |
24 | static toEncodable(fields: LeaseSetAuthorityParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): LeaseSetAuthorityParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: LeaseSetAuthorityParamsJSON): LeaseSetAuthorityParams {
33 | return new LeaseSetAuthorityParams({});
34 | }
35 |
36 | toEncodable() {
37 | return LeaseSetAuthorityParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/PermissionInitParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface PermissionInitParamsFields {}
9 |
10 | export interface PermissionInitParamsJSON {}
11 |
12 | export class PermissionInitParams {
13 | constructor(fields: PermissionInitParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new PermissionInitParams({});
22 | }
23 |
24 | static toEncodable(fields: PermissionInitParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): PermissionInitParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: PermissionInitParamsJSON): PermissionInitParams {
33 | return new PermissionInitParams({});
34 | }
35 |
36 | toEncodable() {
37 | return PermissionInitParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/VrfLiteCloseParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface VrfLiteCloseParamsFields {}
9 |
10 | export interface VrfLiteCloseParamsJSON {}
11 |
12 | export class VrfLiteCloseParams {
13 | constructor(fields: VrfLiteCloseParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new VrfLiteCloseParams({});
22 | }
23 |
24 | static toEncodable(fields: VrfLiteCloseParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): VrfLiteCloseParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: VrfLiteCloseParamsJSON): VrfLiteCloseParams {
33 | return new VrfLiteCloseParams({});
34 | }
35 |
36 | toEncodable() {
37 | return VrfLiteCloseParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/VrfPoolAddParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface VrfPoolAddParamsFields {}
9 |
10 | export interface VrfPoolAddParamsJSON {}
11 |
12 | export class VrfPoolAddParams {
13 | constructor(fields: VrfPoolAddParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new VrfPoolAddParams({});
22 | }
23 |
24 | static toEncodable(fields: VrfPoolAddParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): VrfPoolAddParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: VrfPoolAddParamsJSON): VrfPoolAddParams {
33 | return new VrfPoolAddParams({});
34 | }
35 |
36 | toEncodable() {
37 | return VrfPoolAddParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/oracle-program/types/VrfPoolRemoveParams.ts:
--------------------------------------------------------------------------------
1 | import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
2 | import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
3 |
4 | import * as borsh from "@coral-xyz/borsh";
5 | import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
6 | import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
7 |
8 | export interface VrfPoolRemoveParamsFields {}
9 |
10 | export interface VrfPoolRemoveParamsJSON {}
11 |
12 | export class VrfPoolRemoveParams {
13 | constructor(fields: VrfPoolRemoveParamsFields) {}
14 |
15 | static layout(property?: string) {
16 | return borsh.struct([], property);
17 | }
18 |
19 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
20 | static fromDecoded(obj: any) {
21 | return new VrfPoolRemoveParams({});
22 | }
23 |
24 | static toEncodable(fields: VrfPoolRemoveParamsFields) {
25 | return {};
26 | }
27 |
28 | toJSON(): VrfPoolRemoveParamsJSON {
29 | return {};
30 | }
31 |
32 | static fromJSON(obj: VrfPoolRemoveParamsJSON): VrfPoolRemoveParams {
33 | return new VrfPoolRemoveParams({});
34 | }
35 |
36 | toEncodable() {
37 | return VrfPoolRemoveParams.toEncodable(this);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/generated/types.ts:
--------------------------------------------------------------------------------
1 | export * from "./attestation-program/types/index.js";
2 | export * from "./oracle-program/types/index.js";
3 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from "./accounts/index.js";
2 | export * from "./const.js";
3 | export * from "./errors.js";
4 | export * as attestationTypes from "./generated/attestation-program/index.js";
5 | export * as types from "./generated/oracle-program/index.js";
6 | export * from "./mint.js";
7 | export * from "./SolanaClock.js";
8 | export * from "./SwitchboardError.js";
9 | export * from "./SwitchboardEvents.js";
10 | export * from "./SwitchboardNetwork.js";
11 | export * from "./SwitchboardProgram.js";
12 | export * from "./SwitchboardTestContext.js";
13 | export * from "./TransactionObject.js";
14 | export * from "./types.js";
15 | export * from "./utils.js";
16 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/runner/functionResult.ts:
--------------------------------------------------------------------------------
1 | export interface EvmTransaction {
2 | expiration_time_seconds: number;
3 | gas_limit: string;
4 | value: string;
5 | to: number[];
6 | from: number[];
7 | data: number[];
8 | }
9 |
10 | export interface EVMFunctionResult {
11 | txs: EvmTransaction[];
12 | signatures: number[][];
13 | call_ids: number[][];
14 | checksums: number[][];
15 | }
16 |
17 | export interface SOLFunctionResult {
18 | serialized_tx: number[];
19 | }
20 |
21 | export type ChainResultInfo = EVMFunctionResult | SOLFunctionResult;
22 |
23 | export interface FunctionResult {
24 | version: number;
25 | quote: number[];
26 | fn_key: number[];
27 | signer: number[];
28 | fn_request_key: number[];
29 | fn_request_hash: number[];
30 | chain_result_info: ChainResultInfo;
31 | }
32 |
--------------------------------------------------------------------------------
/javascript/solana.js/src/runner/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | functionClose,
3 | functionRequestClose,
4 | functionRequestVerify,
5 | functionVerify,
6 | } from "../generated/attestation-program/instructions/index.js";
7 | export * from "./functionResult.js";
8 | export * from "./runner.js";
9 |
--------------------------------------------------------------------------------
/javascript/solana.js/test/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [
4 | "../src",
5 | "../test",
6 | "../test/data/**.json"
7 | ],
8 | "exclude": [
9 | "**/node_modules"
10 | ],
11 | "compilerOptions": {
12 | "types": [
13 | "node",
14 | "mocha"
15 | ],
16 | "module": "NodeNext",
17 | "allowJs": true,
18 | "rootDir": "../",
19 | "resolveJsonModule": true
20 | }
21 | }
--------------------------------------------------------------------------------
/javascript/solana.js/test/version.spec.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import "mocha";
3 |
4 | import type { TestContext } from "./utils.js";
5 | import { setupTest } from "./utils.js";
6 |
7 | import assert from "assert";
8 |
9 | describe("Git Version Tests", () => {
10 | let ctx: TestContext;
11 |
12 | before(async () => {
13 | ctx = await setupTest();
14 | });
15 |
16 | it("Gets the oracle program's git version", async () => {
17 | const version = await ctx.program.getGitVersion();
18 | console.log(`Oracle Version: ${version}`);
19 | });
20 |
21 | it("Gets the attestation program's git version", async () => {
22 | const version = await ctx.program.getAttestationGitVersion();
23 | console.log(`Attestation Version: ${version}`);
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/javascript/solana.js/tsconfig.base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "include": [
4 | "./src/**/*"
5 | ],
6 | "compilerOptions": {
7 | "lib": [
8 | "ES2021",
9 | "ES2022.Object",
10 | "DOM"
11 | ],
12 | "moduleResolution": "nodenext",
13 | "inlineSourceMap": false,
14 | "inlineSources": false,
15 | "declaration": true,
16 | "declarationMap": true,
17 | "allowSyntheticDefaultImports": true,
18 | "experimentalDecorators": true,
19 | "emitDecoratorMetadata": true,
20 | "resolveJsonModule": true,
21 | "composite": true,
22 | "skipLibCheck": true,
23 | // strict
24 | "strict": true,
25 | "noImplicitThis": true,
26 | "alwaysStrict": true,
27 | "noImplicitAny": false,
28 | "strictNullChecks": false,
29 | "strictFunctionTypes": true,
30 | "noImplicitReturns": true,
31 | "esModuleInterop": true
32 | },
33 | "references": [
34 | {
35 | "path": "../common"
36 | },
37 | {
38 | "path": "../oracle"
39 | }
40 | ]
41 | }
--------------------------------------------------------------------------------
/javascript/solana.js/tsconfig.cjs.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.json",
3 | "exclude": ["node_modules", "**/tests/**/*.ts", "dist"],
4 | "compilerOptions": {
5 | "module": "commonjs",
6 | "composite": false,
7 | "declaration": false,
8 | "declarationMap": false
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solana-sdk",
3 | "private": true,
4 | "scripts": {
5 | "preinstall": "npx only-allow pnpm",
6 | "build": "turbo run build",
7 | "dev": "turbo run dev",
8 | "test": "turbo run test",
9 | "lint": "turbo run lint",
10 | "fix": "pnpm -r fix",
11 | "clean": "turbo run clean && rm -rf node_modules",
12 | "clean:cargo": "find . -type d \\( -name \"target\" -o -name \"test-ledger\" -o -name \".anchor\" \\) -exec rm -rf {} +",
13 | "clean:js": "find . -type d -name \"node_modules\" -exec rm -rf {} +",
14 | "format": "prettier --write \"**/*.{ts,tsx,md}\"",
15 | "changeset": "changeset",
16 | "version-packages": "changeset version",
17 | "release": "turbo run build --filter=docs^... && changeset publish"
18 | },
19 | "devDependencies": {
20 | "@changesets/cli": "^2.26.1",
21 | "@commitlint/config-conventional": "^17.4.4",
22 | "@switchboard-xyz/eslint-config": "latest",
23 | "@types/node": "^20.2.5",
24 | "commitlint": "^17.4.4",
25 | "eslint": "^8.42.0",
26 | "shelljs": "^0.8.5",
27 | "shx": "^0.3.4",
28 | "ts-node": "^10.9.1",
29 | "tsx": "^3.12.7",
30 | "turbo": "^1.10.3",
31 | "typescript": "^5.0.4"
32 | },
33 | "engines": {
34 | "node": ">=16.0.0"
35 | },
36 | "repository": {
37 | "type": "git",
38 | "url": "https://github.com/switchboard-xyz/solana-sdk.git"
39 | },
40 | "packageManager": "pnpm@8.6.0"
41 | }
42 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - "javascript/*"
3 | - "rust/*"
4 | - "examples/feeds/*"
5 | - "examples/functions/*"
6 | - "examples/functions/*/sgx-function"
7 | - "examples/vrf/*"
8 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "switchboard-solana"
3 | documentation = "https://switchboard-solana-rust-docs.web.app"
4 | version = "0.30.4"
5 | edition = "2021"
6 | resolver = "2"
7 | description = "A Rust library to interact with Switchboard accounts."
8 | readme = "README.md"
9 | keywords = ["switchboard", "oracle", "solana"]
10 | homepage = "https://switchboard.xyz"
11 | repository = "https://github.com/switchboard-xyz/solana-sdk/tree/main/rust/switchboard-solana"
12 | license = "MIT"
13 |
14 | [lib]
15 | crate-type = ["cdylib", "lib"]
16 | name = "switchboard_solana"
17 | doctest = false
18 |
19 | [features]
20 | default = ["cpi"]
21 | no-entrypoint = []
22 | cpi = ["no-entrypoint"]
23 | pid_override = []
24 |
25 | [dependencies]
26 | solana-program = "1.17.13,<2"
27 | anchor-lang = "0.30.1"
28 | bytemuck = "1.16.1"
29 | rust_decimal = "1.32.0"
30 | superslice = "1.0.0"
31 | lazy_static = "1.5.0"
32 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/fixtures/v2_quote.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/switchboard-xyz/solana-sdk/9e40fab2b7ca79b145652995b1c4bfc6df1159cc/rust/switchboard-solana/fixtures/v2_quote.bin
--------------------------------------------------------------------------------
/rust/switchboard-solana/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "switchboard-solana",
3 | "scripts": {
4 | "cargo:build": "cargo build --features all",
5 | "lint": "cargo fmt -- --check",
6 | "fix": "cargo fmt",
7 | "test": "cargo test --features all -- --nocapture",
8 | "docgen": "cargo doc --all-features --no-deps",
9 | "docgen:compile": "pnpm docgen && ts-node ./scripts/compile_docs.ts",
10 | "docgen:deploy": "pnpm docgen:compile && firebase deploy --project docs --only hosting:switchboard-solana-rust-docs"
11 | },
12 | "dependencies": {
13 | "fs-extra": "^11.2.0",
14 | "@types/fs-extra": "^11.0.4"
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/accounts.rs:
--------------------------------------------------------------------------------
1 | pub use crate::oracle_program::accounts::{
2 | AggregatorAccountData, AggregatorHistoryBuffer, BufferRelayerAccountData, CrankAccountData,
3 | JobAccountData, LeaseAccountData, OracleAccountData, OracleQueueAccountData,
4 | PermissionAccountData, SbState, SlidingResultAccountData,
5 | };
6 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/clock.rs:
--------------------------------------------------------------------------------
1 | use switchboard_common::SbError;
2 | use futures::TryFutureExt;
3 | use crate::solana_sdk::clock::Clock;
4 |
5 | pub async fn fetch_async(
6 | client: &solana_client::nonblocking::rpc_client::RpcClient,
7 | ) -> std::result::Result {
8 | let pubkey = crate::solana_sdk::sysvar::clock::id();
9 | let data = client
10 | .get_account_data(&pubkey)
11 | .map_err(|_| SbError::AccountNotFound)
12 | .await?
13 | .to_vec();
14 | bincode::deserialize(&data).map_err(|_| SbError::AccountNotFound)
15 | }
16 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/events.rs:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/instructions.rs:
--------------------------------------------------------------------------------
1 | pub use crate::oracle_program::instructions::PermissionSet;
2 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/accounts/crank.rs:
--------------------------------------------------------------------------------
1 | use crate::prelude::*;
2 | use bytemuck::{Pod, Zeroable};
3 |
4 | #[zero_copy(unsafe)]
5 | #[derive(Default)]
6 | #[repr(packed)]
7 | pub struct CrankRow {
8 | /// The PublicKey of the AggregatorAccountData.
9 | pub pubkey: Pubkey,
10 | /// The aggregator's next available update time.
11 | pub next_timestamp: i64,
12 | }
13 | unsafe impl Pod for CrankRow {}
14 | unsafe impl Zeroable for CrankRow {}
15 |
16 | #[account(zero_copy(unsafe))]
17 | #[repr(packed)]
18 | pub struct CrankAccountData {
19 | /// Name of the crank to store on-chain.
20 | pub name: [u8; 32],
21 | /// Metadata of the crank to store on-chain.
22 | pub metadata: [u8; 64],
23 | /// Public key of the oracle queue who owns the crank.
24 | pub queue_pubkey: Pubkey,
25 | /// Number of aggregators added to the crank.
26 | pub pq_size: u32,
27 | /// Maximum number of aggregators allowed to be added to a crank.
28 | pub max_rows: u32,
29 | /// Pseudorandom value added to next aggregator update time.
30 | pub jitter_modifier: u8,
31 | /// Reserved for future info.
32 | pub _ebuf: [u8; 255],
33 | /// The public key of the CrankBuffer account holding a collection of Aggregator pubkeys and their next allowed update time.
34 | pub data_buffer: Pubkey,
35 | }
36 |
37 | impl CrankAccountData {
38 | pub fn size() -> usize {
39 | 8 + std::mem::size_of::()
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/accounts/job.rs:
--------------------------------------------------------------------------------
1 | use crate::prelude::*;
2 |
3 | #[account]
4 | pub struct JobAccountData {
5 | /// Name of the job to store on-chain.
6 | pub name: [u8; 32],
7 | /// Metadata of the job to store on-chain.
8 | pub metadata: [u8; 64],
9 | /// The account delegated as the authority for making account changes.
10 | pub authority: Pubkey,
11 | /// Unix timestamp when the job is considered invalid
12 | pub expiration: i64,
13 | /// Hash of the serialized data to prevent tampering.
14 | pub hash: [u8; 32],
15 | /// Serialized protobuf containing the collection of task to retrieve data off-chain.
16 | pub data: Vec,
17 | /// The number of data feeds referencing the job account..
18 | pub reference_count: u32,
19 | /// The token amount funded into a feed that contains this job account.
20 | pub total_spent: u64,
21 | /// Unix timestamp when the job was created on-chain.
22 | pub created_at: i64,
23 | pub is_initializing: u8,
24 | }
25 |
26 | impl JobAccountData {}
27 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/accounts/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod aggregator;
2 | pub mod buffer_relayer;
3 | pub mod crank;
4 | pub mod history_buffer;
5 | pub mod job;
6 | pub mod lease;
7 | pub mod oracle;
8 | pub mod permission;
9 | pub mod queue;
10 | pub mod sb_state;
11 | pub mod sliding_window;
12 |
13 | pub use aggregator::*;
14 | pub use buffer_relayer::*;
15 | pub use crank::*;
16 | pub use history_buffer::*;
17 | pub use job::*;
18 | pub use lease::*;
19 | pub use oracle::*;
20 | pub use permission::*;
21 | pub use queue::*;
22 | pub use sb_state::*;
23 | pub use sliding_window::*;
24 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/accounts/sb_state.rs:
--------------------------------------------------------------------------------
1 | use crate::prelude::*;
2 |
3 | #[account(zero_copy(unsafe))]
4 | #[repr(packed)]
5 | pub struct SbState {
6 | /// The account authority permitted to make account changes.
7 | pub authority: Pubkey,
8 | /// The token mint used for oracle rewards, aggregator leases, and other reward incentives.
9 | pub token_mint: Pubkey,
10 | /// Token vault used by the program to receive kickbacks.
11 | pub token_vault: Pubkey,
12 | /// The token mint used by the DAO.
13 | pub dao_mint: Pubkey,
14 | /// The PDA bump to derive the pubkey.
15 | pub bump: u8,
16 | /// Reserved for future info.
17 | pub _ebuf: [u8; 991],
18 | }
19 |
20 | impl SbState {
21 | pub fn size() -> usize {
22 | 8 + std::mem::size_of::()
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/accounts/sliding_window.rs:
--------------------------------------------------------------------------------
1 | use crate::prelude::*;
2 |
3 | #[zero_copy(unsafe)]
4 | #[derive(Default)]
5 | #[repr(packed)]
6 | pub struct SlidingWindowElement {
7 | pub oracle_key: Pubkey,
8 | pub value: SwitchboardDecimal,
9 | pub slot: u64,
10 | pub timestamp: i64,
11 | }
12 |
13 | #[account(zero_copy(unsafe))]
14 | #[repr(packed)]
15 | pub struct SlidingResultAccountData {
16 | pub data: [SlidingWindowElement; 16],
17 | pub bump: u8,
18 | pub _ebuf: [u8; 512],
19 | }
20 |
21 | impl SlidingResultAccountData {
22 | pub fn size() -> usize {
23 | 8 + std::mem::size_of::()
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/instructions/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod aggregator_save_result;
2 | pub mod oracle_heartbeat;
3 | pub mod permission_set;
4 |
5 | pub use aggregator_save_result::*;
6 | pub use oracle_heartbeat::*;
7 | pub use permission_set::*;
8 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/oracle_program/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod accounts;
2 | pub use accounts::*;
3 |
4 | pub mod instructions;
5 | pub use instructions::*;
6 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/prelude.rs:
--------------------------------------------------------------------------------
1 | use crate::{cfg_macros, cfg_program};
2 |
3 | pub use crate::accounts::*;
4 | pub use crate::decimal::*;
5 | pub use crate::error::*;
6 | pub use crate::instructions::*;
7 | pub use crate::seeds::*;
8 | pub use crate::types::*;
9 |
10 | pub use crate::{SWITCHBOARD_ATTESTATION_PROGRAM_ID, SWITCHBOARD_PROGRAM_ID};
11 |
12 | pub use rust_decimal;
13 |
14 | cfg_program! {
15 | pub use anchor_lang;
16 | pub use anchor_lang::solana_program;
17 |
18 | pub use anchor_lang::prelude::*;
19 |
20 | pub use anchor_lang::prelude::Result;
21 | }
22 |
23 | cfg_macros! {
24 | // Futures crate is needed by the proc_macro
25 | pub use futures;
26 | pub use futures::Future;
27 | pub use switchboard_solana_macros::switchboard_function;
28 | pub use switchboard_solana_macros::sb_error;
29 | }
30 |
31 | pub use anchor_lang::{
32 | AccountDeserialize, AccountSerialize, AnchorDeserialize, AnchorSerialize, Discriminator,
33 | InstructionData, Owner, ZeroCopy,
34 | };
35 |
36 | // pub use anchor_spl::associated_token::AssociatedToken;
37 | // pub use anchor_spl::token::spl_token::native_mint as NativeMint;
38 | // pub use anchor_spl::token::{Mint, Token, TokenAccount};
39 | pub use solana_program::entrypoint::ProgramResult;
40 | pub use solana_program::instruction::{AccountMeta, Instruction};
41 | pub use solana_program::program::{invoke, invoke_signed};
42 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/program_id.rs:
--------------------------------------------------------------------------------
1 | use crate::*;
2 | pub use anchor_lang::prelude::*;
3 | pub use anchor_lang::solana_program;
4 | pub use anchor_lang::solana_program::*;
5 | pub use anchor_lang::solana_program::{pubkey, pubkey::Pubkey};
6 | use lazy_static::lazy_static;
7 | #[allow(unused_imports)]
8 | use std::str::FromStr;
9 |
10 | /// Program id for the Switchboard oracle program
11 | /// SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f
12 | lazy_static! {
13 | pub static ref SWITCHBOARD_PROGRAM_ID: Pubkey =
14 | Pubkey::from_str("SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f").unwrap();
15 | }
16 |
17 | // Program id for the Switchboard oracle program
18 | // sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx
19 | #[cfg(not(feature = "pid_override"))]
20 | lazy_static! {
21 | pub static ref SWITCHBOARD_ATTESTATION_PROGRAM_ID: Pubkey =
22 | Pubkey::from_str("sbattyXrzedoNATfc4L31wC9Mhxsi1BmFhTiN8gDshx").unwrap();
23 | }
24 | #[cfg(feature = "pid_override")]
25 | lazy_static! {
26 | pub static ref SWITCHBOARD_ATTESTATION_PROGRAM_ID: Pubkey =
27 | Pubkey::from_str(&std::env::var("SWITCHBOARD_ATTESTATION_PROGRAM_ID").unwrap()).unwrap();
28 | }
29 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/seeds.rs:
--------------------------------------------------------------------------------
1 | /// Seed used to derive the SbState PDA.
2 | pub const STATE_SEED: &[u8] = b"STATE";
3 |
4 | /// Seed used to derive the PermissionAccountData PDA.
5 | pub const PERMISSION_SEED: &[u8] = b"PermissionAccountData";
6 |
7 | /// Seed used to derive the LeaseAccountData PDA.
8 | pub const LEASE_SEED: &[u8] = b"LeaseAccountData";
9 |
10 | /// Seed used to derive the OracleAccountData PDA.
11 | pub const ORACLE_SEED: &[u8] = b"OracleAccountData";
12 |
13 | /// Seed used to derive the SlidingWindow PDA.
14 | pub const SLIDING_RESULT_SEED: &[u8] = b"SlidingResultAccountData";
15 |
16 | /// Discriminator used for Switchboard buffer accounts.
17 | pub const BUFFER_DISCRIMINATOR: &[u8] = b"BUFFERxx";
18 |
19 | /// Seed used to derive the FunctionAccountData PDA.
20 | pub const FUNCTION_SEED: &[u8] = b"FunctionAccountData";
21 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/types.rs:
--------------------------------------------------------------------------------
1 | pub use crate::decimal::SwitchboardDecimal;
2 |
3 | pub use crate::oracle_program::{
4 | AggregatorHistoryRow, AggregatorResolutionMode, AggregatorRound, BufferRelayerRound, CrankRow,
5 | OracleMetrics, OracleResponseType, PermissionSetParams, SlidingWindowElement,
6 | SwitchboardPermission,
7 | };
8 |
--------------------------------------------------------------------------------
/rust/switchboard-solana/src/utils.rs:
--------------------------------------------------------------------------------
1 | pub use crate::error::SwitchboardError;
2 | pub use crate::prelude::*;
3 | use lazy_static::lazy_static;
4 | use std::str::FromStr;
5 |
6 | lazy_static! {
7 | pub static ref ATOKEN_PID: Pubkey =
8 | Pubkey::from_str("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL").unwrap();
9 | pub static ref TOKEN_PID: Pubkey =
10 | Pubkey::from_str("TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA").unwrap();
11 | }
12 |
13 | pub fn find_associated_token_address(owner: &Pubkey, mint: &Pubkey) -> Pubkey {
14 | let (akey, _bump) = Pubkey::find_program_address(
15 | &[owner.as_ref(), TOKEN_PID.as_ref(), mint.as_ref()],
16 | &ATOKEN_PID,
17 | );
18 | akey
19 | }
20 |
21 | pub fn get_ixn_discriminator(ixn_name: &str) -> [u8; 8] {
22 | let preimage = format!("global:{}", ixn_name);
23 | let mut sighash = [0u8; 8];
24 | sighash.copy_from_slice(
25 | &anchor_lang::solana_program::hash::hash(preimage.as_bytes()).to_bytes()[..8],
26 | );
27 | sighash
28 | }
29 |
30 | pub fn build_ix(
31 | program_id: &Pubkey,
32 | accounts: &A,
33 | params: &I,
34 | ) -> Instruction {
35 | Instruction {
36 | program_id: *program_id,
37 | accounts: accounts.to_account_metas(None),
38 | data: params.data(),
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "switchboard-v2"
3 | version = "0.3.1"
4 | edition = "2021"
5 | description = "A Rust library to interact with Switchboard V2 accounts."
6 | readme = "README.md"
7 | keywords = ["switchboard", "oracle", "solana"]
8 | homepage = "https://docs.switchboard.xyz"
9 | repository = "https://github.com/switchboard-xyz/sbv2-solana/tree/main/rust/switchboard-v2"
10 | license = "MIT"
11 | documentation = "https://docs.rs/switchboard-v2/"
12 |
13 | [lib]
14 | crate-type = ["cdylib", "lib"]
15 | name = "switchboard_v2"
16 | doctest = false
17 |
18 | [features]
19 | default = ["cpi"]
20 | no-entrypoint = []
21 | cpi = ["no-entrypoint"]
22 |
23 | [dependencies]
24 | rust_decimal = "=1.26.1"
25 | bytemuck = "1.13.1"
26 | superslice = "1"
27 | solana-program = ">= 1.14.16, < 1.15.0"
28 | # anchor-lang = "0.27.0"
29 | # anchor-spl = "0.27.0"
30 | # https://github.com/coral-xyz/anchor/issues/2502
31 | anchor-lang = { git = "https://github.com/coral-xyz/anchor", version = "0.27.0", tag = "v0.27.0" }
32 | anchor-spl = { git = "https://github.com/coral-xyz/anchor", version = "0.27.0", tag = "v0.27.0" }
33 | # toml_datetime = "=0.6.1"
34 | # winnow = "=0.4.1"
35 | # toml_edit = "=0.19.8"
36 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Switchboard
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "switchboard-v2",
3 | "scripts": {
4 | "cargo:build": "cargo build",
5 | "cargo:fix": "cargo fmt",
6 | "test": "cargo test"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/src/crank.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 | use bytemuck::{Pod, Zeroable};
3 |
4 | #[zero_copy]
5 | #[derive(Default)]
6 | #[repr(packed)]
7 | pub struct CrankRow {
8 | /// The PublicKey of the AggregatorAccountData.
9 | pub pubkey: Pubkey,
10 | /// The aggregator's next available update time.
11 | pub next_timestamp: i64,
12 | }
13 | unsafe impl Pod for CrankRow {}
14 | unsafe impl Zeroable for CrankRow {}
15 |
16 | #[account(zero_copy)]
17 | #[repr(packed)]
18 | pub struct CrankAccountData {
19 | /// Name of the crank to store on-chain.
20 | pub name: [u8; 32],
21 | /// Metadata of the crank to store on-chain.
22 | pub metadata: [u8; 64],
23 | /// Public key of the oracle queue who owns the crank.
24 | pub queue_pubkey: Pubkey,
25 | /// Number of aggregators added to the crank.
26 | pub pq_size: u32,
27 | /// Maximum number of aggregators allowed to be added to a crank.
28 | pub max_rows: u32,
29 | /// Pseudorandom value added to next aggregator update time.
30 | pub jitter_modifier: u8,
31 | /// Reserved for future info.
32 | pub _ebuf: [u8; 255],
33 | /// The public key of the CrankBuffer account holding a collection of Aggregator pubkeys and their next allowed update time.
34 | pub data_buffer: Pubkey,
35 | }
36 |
37 | impl CrankAccountData {}
38 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/src/error.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[error_code]
4 | #[derive(Eq, PartialEq)]
5 | pub enum SwitchboardError {
6 | #[msg("Aggregator is not currently populated with a valid round")]
7 | InvalidAggregatorRound,
8 | #[msg("Failed to convert string to decimal format")]
9 | InvalidStrDecimalConversion,
10 | #[msg("Decimal conversion method failed")]
11 | DecimalConversionError,
12 | #[msg("An integer overflow occurred")]
13 | IntegerOverflowError,
14 | #[msg("Account discriminator did not match")]
15 | AccountDiscriminatorMismatch,
16 | #[msg("Vrf value is empty")]
17 | VrfEmptyError,
18 | #[msg("Failed to send requestRandomness instruction")]
19 | VrfCpiError,
20 | #[msg("Failed to send signed requestRandomness instruction")]
21 | VrfCpiSignedError,
22 | #[msg("Failed to deserialize account")]
23 | AccountDeserializationError,
24 | #[msg("Switchboard feed exceeded the staleness threshold")]
25 | StaleFeed,
26 | #[msg("Switchboard feed exceeded the confidence interval threshold")]
27 | ConfidenceIntervalExceeded,
28 | #[msg("Invalid authority provided to Switchboard account")]
29 | InvalidAuthority,
30 | #[msg("Switchboard value variance exceeded threshold")]
31 | AllowedVarianceExceeded,
32 | #[msg("Invalid function input")]
33 | InvalidFunctionInput,
34 | }
35 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/src/job.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[account]
4 | pub struct JobAccountData {
5 | /// Name of the job to store on-chain.
6 | pub name: [u8; 32],
7 | /// Metadata of the job to store on-chain.
8 | pub metadata: [u8; 64],
9 | /// The account delegated as the authority for making account changes.
10 | pub authority: Pubkey,
11 | /// Unix timestamp when the job is considered invalid
12 | pub expiration: i64,
13 | /// Hash of the serialized data to prevent tampering.
14 | pub hash: [u8; 32],
15 | /// Serialized protobuf containing the collection of task to retrieve data off-chain.
16 | pub data: Vec,
17 | /// The number of data feeds referencing the job account..
18 | pub reference_count: u32,
19 | /// The token amount funded into a feed that contains this job account.
20 | pub total_spent: u64,
21 | /// Unix timestamp when the job was created on-chain.
22 | pub created_at: i64,
23 | pub is_initializing: u8,
24 | }
25 |
26 | impl JobAccountData {}
27 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/src/lease.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[account(zero_copy)]
4 | #[repr(packed)]
5 | pub struct LeaseAccountData {
6 | /// Public key of the token account holding the lease contract funds until rewarded to oracles for successfully processing updates
7 | pub escrow: Pubkey, // Needed, maybe derived, key + "update_escrow"?
8 | /// Public key of the oracle queue that the lease contract is applicable for.
9 | pub queue: Pubkey,
10 | /// Public key of the aggregator that the lease contract is applicable for
11 | pub aggregator: Pubkey,
12 | /// Public key of the Solana token program ID.
13 | pub token_program: Pubkey,
14 | /// Whether the lease contract is still active.
15 | pub is_active: bool,
16 | /// Index of an aggregators position on a crank.
17 | pub crank_row_count: u32,
18 | /// Timestamp when the lease contract was created.
19 | pub created_at: i64,
20 | /// Counter keeping track of the number of updates for the given aggregator.
21 | pub update_count: u128,
22 | /// Public key of keypair that may withdraw funds from the lease at any time
23 | pub withdraw_authority: Pubkey,
24 | /// The PDA bump to derive the pubkey.
25 | pub bump: u8,
26 | // Reserved for future info.
27 | pub _ebuf: [u8; 255],
28 | }
29 |
30 | impl LeaseAccountData {}
31 |
--------------------------------------------------------------------------------
/rust/switchboard-v2/src/sb_state.rs:
--------------------------------------------------------------------------------
1 | use anchor_lang::prelude::*;
2 |
3 | #[account(zero_copy)]
4 | #[repr(packed)]
5 | pub struct SbState {
6 | /// The account authority permitted to make account changes.
7 | pub authority: Pubkey,
8 | /// The token mint used for oracle rewards, aggregator leases, and other reward incentives.
9 | pub token_mint: Pubkey,
10 | /// Token vault used by the program to receive kickbacks.
11 | pub token_vault: Pubkey,
12 | /// The token mint used by the DAO.
13 | pub dao_mint: Pubkey,
14 | /// The PDA bump to derive the pubkey.
15 | pub bump: u8,
16 | /// Reserved for future info.
17 | pub _ebuf: [u8; 991],
18 | }
19 |
20 | impl SbState {}
21 |
--------------------------------------------------------------------------------
/scripts/anchor-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Imports
6 | script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
7 | project_dir="$(dirname "${script_dir}")"
8 | program_dir="$project_dir"/programs
9 |
10 | cd "$program_dir"/anchor-buffer-parser
11 | anchor test
12 |
13 | cd "$program_dir"/anchor-feed-parser
14 | anchor test
15 |
16 | cd "$program_dir"/anchor-history-parser
17 | anchor test
18 |
19 | cd "$program_dir"/anchor-vrf-parser
20 | anchor test
--------------------------------------------------------------------------------
/scripts/setup-anchor.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Imports
6 | script_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
7 | project_dir="$(dirname "${script_dir}")"
8 | program_dir="$project_dir"/programs
9 |
10 | cd "$program_dir"/anchor-buffer-parser
11 | anchor build
12 | npx anchor-client-gen target/idl/anchor_buffer_parser.json client --program-id "$(solana-keygen pubkey target/deploy/anchor_buffer_parser-keypair.json)"
13 |
14 | cd "$program_dir"/anchor-feed-parser
15 | anchor build
16 | npx anchor-client-gen target/idl/anchor_feed_parser.json client --program-id "$(solana-keygen pubkey target/deploy/anchor_feed_parser-keypair.json)"
17 |
18 | cd "$program_dir"/anchor-history-parser
19 | anchor build
20 | npx anchor-client-gen target/idl/anchor_history_parser.json client --program-id "$(solana-keygen pubkey target/deploy/anchor_history_parser-keypair.json)"
21 |
22 | cd "$program_dir"/anchor-vrf-parser
23 | anchor build
24 | npx anchor-client-gen target/idl/anchor_vrf_parser.json client --program-id "$(solana-keygen pubkey target/deploy/anchor_vrf_parser-keypair.json)"
--------------------------------------------------------------------------------
/scripts/setup-js.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | # Imports
6 | project_dir=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
7 | javascript_dir="$project_dir"/javascript
8 | program_dir="$project_dir"/programs
9 |
10 | cd "$javascript_dir"/solana.js
11 | npm ci && npm run build
12 |
13 | cd "$javascript_dir"/sbv2-utils
14 | npm ci && npm run build
15 |
16 | cd "$javascript_dir"/sbv2-lite
17 | npm ci && npm run build
18 |
19 | cd "$javascript_dir"/feed-parser
20 | npm ci && npm run build
21 |
22 | cd "$javascript_dir"/feed-walkthrough
23 | npm ci && npm run build
24 |
25 | cd "$javascript_dir"/lease-observer
26 | npm ci && npm run build
27 |
28 | cd "$program_dir"/anchor-buffer-parser
29 | npm ci && anchor build
30 |
31 | cd "$program_dir"/anchor-feed-parser
32 | npm ci && anchor build
33 |
34 | cd "$program_dir"/anchor-vrf-parser
35 | npm ci && anchor build
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "files": [],
4 | "references": [
5 | {
6 | "path": "javascript/solana.js"
7 | },
8 | {
9 | "path": "javascript/feed-walkthrough"
10 | },
11 | {
12 | "path": "examples/feeds/01_feed_client"
13 | },
14 | {
15 | "path": "examples/feeds/02_spl_native"
16 | },
17 | {
18 | "path": "examples/functions/01_basic_oracle"
19 | },
20 | {
21 | "path": "examples/vrf/01_vrf_client"
22 | }
23 | ]
24 | }
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": ["**/.env.*local"],
4 | "pipeline": {
5 | "lint": {},
6 | "dev": {
7 | "cache": false,
8 | "persistent": true
9 | },
10 | "build": {
11 | "dependsOn": ["^build"],
12 | "inputs": ["src/**/*.tsx", "src/**/*.ts", "src/**/*.rs"],
13 | "outputs": [
14 | "dist/**",
15 | "lib/**",
16 | "target/debug/*.d",
17 | "target/debug/*.rlib"
18 | ]
19 | },
20 | "test": {
21 | "dependsOn": ["^build"],
22 | "inputs": [
23 | "test/**/*.ts",
24 | "tests/**/*.ts",
25 | "tests/**/*.move",
26 | "test/**/*.sol"
27 | ]
28 | },
29 | "localnet": {
30 | "dependsOn": ["build", "test", "lint"]
31 | },
32 | "deploy": {
33 | "dependsOn": ["build", "test", "lint"]
34 | },
35 | "clean": {
36 | "cache": false
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------