├── .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 | [![Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg)](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml) 13 | 14 | [![Types Badge](https://img.shields.io/badge/types-docs.switchboard.xyz-blue)](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 | [![Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml/badge.svg)](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/solana-js-test.yml) 12 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml) 13 | 14 | [![NPM Badge](https://img.shields.io/github/package-json/v/switchboard-xyz/sbv2-solana?color=red&filename=javascript%2Fsolana.js%2Fpackage.json&label=%40switchboard-xyz%2Fsolana.js&logo=npm)](https://www.npmjs.com/package/@switchboard-xyz/solana.js) 15 | [![Types Badge](https://img.shields.io/badge/types-docs.switchboard.xyz-blue)](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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | [![Crates.io](https://img.shields.io/crates/v/switchboard-v2?label=switchboard-v2&logo=rust)](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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | [![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](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 | ![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png) 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 | [![npm](https://img.shields.io/npm/v/@switchboard-xyz/sbv2-lite)](https://www.npmjs.com/package/@switchboard-xyz/sbv2-lite)   6 | [![twitter](https://badgen.net/twitter/follow/switchboardxyz)](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 | --------------------------------------------------------------------------------