Add V3 SGX Program to solana.js (#102)
This commit is contained in:
parent
0cddfe378a
commit
dffd9def99
|
@ -25,7 +25,7 @@ jobs:
|
|||
- name: Setup Workspace
|
||||
uses: ./.github/actions/setup-workspace
|
||||
with:
|
||||
solanaVersion: "v1.14.10"
|
||||
solanaVersion: "v1.14.18"
|
||||
anchorVersion: "0.26.0"
|
||||
nodeVersion: ${{ matrix.nodeVersion }}
|
||||
|
||||
|
@ -68,7 +68,7 @@ jobs:
|
|||
- name: Setup Workspace
|
||||
uses: ./.github/actions/setup-workspace
|
||||
with:
|
||||
solanaVersion: "v1.14.10"
|
||||
solanaVersion: "v1.14.18"
|
||||
anchorVersion: "0.26.0"
|
||||
nodeVersion: ${{ matrix.nodeVersion }}
|
||||
|
||||
|
|
|
@ -44,9 +44,7 @@ jobs:
|
|||
id: cache-solana-sdk-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key:
|
||||
${{ runner.os }}-Solana.js-${{
|
||||
hashFiles('javascript/solana.js/src/**') }}
|
||||
key: ${{ runner.os }}-Solana.js-${{ hashFiles('javascript/solana.js/src/**') }}
|
||||
path: |
|
||||
javascript/solana.js/lib
|
||||
- name: Build solana.js
|
||||
|
@ -90,9 +88,7 @@ jobs:
|
|||
id: cache-solana-sdk-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key:
|
||||
${{ runner.os }}-Solana.js-${{
|
||||
hashFiles('javascript/solana.js/src/**') }}
|
||||
key: ${{ runner.os }}-Solana.js-${{ hashFiles('javascript/solana.js/src/**') }}
|
||||
path: |
|
||||
javascript/solana.js/lib
|
||||
- name: Build solana.js
|
||||
|
@ -104,11 +100,13 @@ jobs:
|
|||
with:
|
||||
solana-version: v1.14.10
|
||||
cluster: devnet
|
||||
args:
|
||||
"--url ${{ secrets.DEVNET_RPC_URL }} --clone
|
||||
args: "--url ${{ secrets.DEVNET_RPC_URL }} --clone
|
||||
SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone
|
||||
7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone
|
||||
Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone
|
||||
2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 --clone
|
||||
BNrpbCMbBFiCEqGdWaDMqjQmwqtGdgmoFFzGJnUexSbj --clone
|
||||
th1SbXMTX3SrWJ1kbiSKqMDpTBaXkESxpcehXRa12T4 --clone
|
||||
CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
|
||||
- name: Run Tests
|
||||
working-directory: javascript/solana.js
|
||||
|
@ -154,9 +152,7 @@ jobs:
|
|||
id: cache-solana-sdk-build
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
key:
|
||||
${{ runner.os }}-Solana.js-${{
|
||||
hashFiles('javascript/solana.js/src/**') }}
|
||||
key: ${{ runner.os }}-Solana.js-${{ hashFiles('javascript/solana.js/src/**') }}
|
||||
path: |
|
||||
javascript/solana.js/lib
|
||||
- name: Build solana.js
|
||||
|
@ -168,11 +164,13 @@ jobs:
|
|||
with:
|
||||
solana-version: v1.14.10
|
||||
cluster: mainnet
|
||||
args:
|
||||
"--url ${{ secrets.MAINNET_RPC_URL }} --clone
|
||||
args: "--url ${{ secrets.MAINNET_RPC_URL }} --clone
|
||||
SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone
|
||||
7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone
|
||||
Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone
|
||||
2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 --clone
|
||||
BNrpbCMbBFiCEqGdWaDMqjQmwqtGdgmoFFzGJnUexSbj --clone
|
||||
th1SbXMTX3SrWJ1kbiSKqMDpTBaXkESxpcehXRa12T4 --clone
|
||||
CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
|
||||
- name: Run Tests
|
||||
working-directory: javascript/solana.js
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
build/
|
||||
node_modules/
|
||||
src/generated
|
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"extends": "@switchboard-xyz",
|
||||
"rules": {
|
||||
"quotes": "off"
|
||||
"quotes": "off",
|
||||
"@typescript-eslint/no-unused-vars": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,48 @@
|
|||
index.cjs
|
||||
index.js
|
||||
index.d.ts
|
||||
SwitchboardProgram.cjs
|
||||
SwitchboardProgram.js
|
||||
SwitchboardProgram.d.ts
|
||||
TransactionObject.cjs
|
||||
TransactionObject.js
|
||||
TransactionObject.d.ts
|
||||
AggregatorAccount.cjs
|
||||
AggregatorAccount.js
|
||||
AggregatorAccount.d.ts
|
||||
generated.cjs
|
||||
generated.js
|
||||
generated.d.ts
|
||||
accounts.cjs
|
||||
accounts.js
|
||||
accounts.d.ts
|
||||
program.cjs
|
||||
program.js
|
||||
program.d.ts
|
||||
generated/accounts.cjs
|
||||
generated/accounts.js
|
||||
generated/accounts.d.ts
|
||||
generated/instructions.cjs
|
||||
generated/instructions.js
|
||||
generated/instructions.d.ts
|
||||
generated/types.cjs
|
||||
generated/types.js
|
||||
generated/types.d.ts
|
||||
generated/oracle.cjs
|
||||
generated/oracle.js
|
||||
generated/oracle.d.ts
|
||||
generated/oracle/accounts.cjs
|
||||
generated/oracle/accounts.js
|
||||
generated/oracle/accounts.d.ts
|
||||
generated/oracle/instructions.cjs
|
||||
generated/oracle/instructions.js
|
||||
generated/oracle/instructions.d.ts
|
||||
generated/oracle/types.cjs
|
||||
generated/oracle/types.js
|
||||
generated/oracle/types.d.ts
|
||||
generated/attestation.cjs
|
||||
generated/attestation.js
|
||||
generated/attestation.d.ts
|
||||
generated/attestation/accounts.cjs
|
||||
generated/attestation/accounts.js
|
||||
generated/attestation/accounts.d.ts
|
||||
generated/attestation/instructions.cjs
|
||||
generated/attestation/instructions.js
|
||||
generated/attestation/instructions.d.ts
|
||||
generated/attestation/types.cjs
|
||||
generated/attestation/types.js
|
||||
generated/attestation/types.d.ts
|
||||
|
|
|
@ -37,9 +37,24 @@ const commonOptions = {
|
|||
|
||||
const entrypoints = {
|
||||
index: "index",
|
||||
SwitchboardProgram: "SwitchboardProgram",
|
||||
TransactionObject: "TransactionObject",
|
||||
AggregatorAccount: "accounts/AggregatorAccount",
|
||||
generated: "generated/index",
|
||||
accounts: "accounts/index",
|
||||
program: "SwitchboardProgram",
|
||||
"generated/accounts": "generated/accounts",
|
||||
"generated/instructions": "generated/instructions",
|
||||
"generated/types": "generated/types",
|
||||
"generated/oracle": "generated/oracle-program/index",
|
||||
"generated/oracle/accounts": "generated/oracle-program/accounts/index",
|
||||
"generated/oracle/instructions":
|
||||
"generated/oracle-program/instructions/index",
|
||||
"generated/oracle/types": "generated/oracle-program/types/index",
|
||||
"generated/attestation": "generated/attestation-program/index",
|
||||
"generated/attestation/accounts":
|
||||
"generated/attestation-program/accounts/index",
|
||||
"generated/attestation/instructions":
|
||||
"generated/attestation-program/instructions/index",
|
||||
"generated/attestation/types": "generated/attestation-program/types/index",
|
||||
};
|
||||
|
||||
const updateJsonFile = (relativePath, updateFunction) => {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@switchboard-xyz/solana.js",
|
||||
"version": "2.2.0",
|
||||
"version": "2.3.0-beta.5",
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"description": "A Typescript client to interact with Switchboard on Solana.",
|
||||
|
@ -13,15 +13,51 @@
|
|||
"index.cjs",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"SwitchboardProgram.cjs",
|
||||
"SwitchboardProgram.js",
|
||||
"SwitchboardProgram.d.ts",
|
||||
"TransactionObject.cjs",
|
||||
"TransactionObject.js",
|
||||
"TransactionObject.d.ts",
|
||||
"AggregatorAccount.cjs",
|
||||
"AggregatorAccount.js",
|
||||
"AggregatorAccount.d.ts",
|
||||
"generated.cjs",
|
||||
"generated.js",
|
||||
"generated.d.ts",
|
||||
"accounts.cjs",
|
||||
"accounts.js",
|
||||
"accounts.d.ts",
|
||||
"program.cjs",
|
||||
"program.js",
|
||||
"program.d.ts"
|
||||
"generated/accounts.cjs",
|
||||
"generated/accounts.js",
|
||||
"generated/accounts.d.ts",
|
||||
"generated/instructions.cjs",
|
||||
"generated/instructions.js",
|
||||
"generated/instructions.d.ts",
|
||||
"generated/types.cjs",
|
||||
"generated/types.js",
|
||||
"generated/types.d.ts",
|
||||
"generated/oracle.cjs",
|
||||
"generated/oracle.js",
|
||||
"generated/oracle.d.ts",
|
||||
"generated/oracle/accounts.cjs",
|
||||
"generated/oracle/accounts.js",
|
||||
"generated/oracle/accounts.d.ts",
|
||||
"generated/oracle/instructions.cjs",
|
||||
"generated/oracle/instructions.js",
|
||||
"generated/oracle/instructions.d.ts",
|
||||
"generated/oracle/types.cjs",
|
||||
"generated/oracle/types.js",
|
||||
"generated/oracle/types.d.ts",
|
||||
"generated/attestation.cjs",
|
||||
"generated/attestation.js",
|
||||
"generated/attestation.d.ts",
|
||||
"generated/attestation/accounts.cjs",
|
||||
"generated/attestation/accounts.js",
|
||||
"generated/attestation/accounts.d.ts",
|
||||
"generated/attestation/instructions.cjs",
|
||||
"generated/attestation/instructions.js",
|
||||
"generated/attestation/instructions.d.ts",
|
||||
"generated/attestation/types.cjs",
|
||||
"generated/attestation/types.js",
|
||||
"generated/attestation/types.d.ts"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
|
@ -29,29 +65,90 @@
|
|||
"import": "./index.js",
|
||||
"require": "./index.cjs"
|
||||
},
|
||||
"./SwitchboardProgram": {
|
||||
"types": "./SwitchboardProgram.d.ts",
|
||||
"import": "./SwitchboardProgram.js",
|
||||
"require": "./SwitchboardProgram.cjs"
|
||||
},
|
||||
"./TransactionObject": {
|
||||
"types": "./TransactionObject.d.ts",
|
||||
"import": "./TransactionObject.js",
|
||||
"require": "./TransactionObject.cjs"
|
||||
},
|
||||
"./AggregatorAccount": {
|
||||
"types": "./AggregatorAccount.d.ts",
|
||||
"import": "./AggregatorAccount.js",
|
||||
"require": "./AggregatorAccount.cjs"
|
||||
},
|
||||
"./generated": {
|
||||
"types": "./generated.d.ts",
|
||||
"import": "./generated.js",
|
||||
"require": "./generated.cjs"
|
||||
},
|
||||
"./accounts": {
|
||||
"types": "./accounts.d.ts",
|
||||
"import": "./accounts.js",
|
||||
"require": "./accounts.cjs"
|
||||
"./generated/accounts": {
|
||||
"types": "./generated/accounts.d.ts",
|
||||
"import": "./generated/accounts.js",
|
||||
"require": "./generated/accounts.cjs"
|
||||
},
|
||||
"./program": {
|
||||
"types": "./program.d.ts",
|
||||
"import": "./program.js",
|
||||
"require": "./program.cjs"
|
||||
"./generated/instructions": {
|
||||
"types": "./generated/instructions.d.ts",
|
||||
"import": "./generated/instructions.js",
|
||||
"require": "./generated/instructions.cjs"
|
||||
},
|
||||
"./generated/types": {
|
||||
"types": "./generated/types.d.ts",
|
||||
"import": "./generated/types.js",
|
||||
"require": "./generated/types.cjs"
|
||||
},
|
||||
"./generated/oracle": {
|
||||
"types": "./generated/oracle.d.ts",
|
||||
"import": "./generated/oracle.js",
|
||||
"require": "./generated/oracle.cjs"
|
||||
},
|
||||
"./generated/oracle/accounts": {
|
||||
"types": "./generated/oracle/accounts.d.ts",
|
||||
"import": "./generated/oracle/accounts.js",
|
||||
"require": "./generated/oracle/accounts.cjs"
|
||||
},
|
||||
"./generated/oracle/instructions": {
|
||||
"types": "./generated/oracle/instructions.d.ts",
|
||||
"import": "./generated/oracle/instructions.js",
|
||||
"require": "./generated/oracle/instructions.cjs"
|
||||
},
|
||||
"./generated/oracle/types": {
|
||||
"types": "./generated/oracle/types.d.ts",
|
||||
"import": "./generated/oracle/types.js",
|
||||
"require": "./generated/oracle/types.cjs"
|
||||
},
|
||||
"./generated/attestation": {
|
||||
"types": "./generated/attestation.d.ts",
|
||||
"import": "./generated/attestation.js",
|
||||
"require": "./generated/attestation.cjs"
|
||||
},
|
||||
"./generated/attestation/accounts": {
|
||||
"types": "./generated/attestation/accounts.d.ts",
|
||||
"import": "./generated/attestation/accounts.js",
|
||||
"require": "./generated/attestation/accounts.cjs"
|
||||
},
|
||||
"./generated/attestation/instructions": {
|
||||
"types": "./generated/attestation/instructions.d.ts",
|
||||
"import": "./generated/attestation/instructions.js",
|
||||
"require": "./generated/attestation/instructions.cjs"
|
||||
},
|
||||
"./generated/attestation/types": {
|
||||
"types": "./generated/attestation/types.d.ts",
|
||||
"import": "./generated/attestation/types.js",
|
||||
"require": "./generated/attestation/types.cjs"
|
||||
},
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"scripts": {
|
||||
"keypair:create": "shx find ~/.config/solana/id.json || solana-keygen new -s --no-bip39-passphrase --outfile ~/.config/solana/id.json",
|
||||
"localnet:down": "kill -9 $(pgrep command solana-test-validator) || exit 0",
|
||||
"local:validator": "shx mkdir -p .anchor/test-ledger || true; solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f `# programId` --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF `# programDataAddress` --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk `# idlAddress` --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd `# programState` --clone 7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie `# switchboardVault`",
|
||||
"local:validator:mainnet": "solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --rpc-port 8899 --url https://api.mainnet-beta.solana.com --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd --clone J7nSEX8ADf3pVVicd6yKy2Skvg8iLePEmkLUisAAaioD",
|
||||
"generate": "node ./scripts/generate-client.js",
|
||||
"localnet": "tsx ./scripts/localnet.ts",
|
||||
"local:validator": "shx mkdir -p .anchor/test-ledger || true; solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f `# programId` --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF `# programDataAddress` --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk `# idlAddress` --clone 2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 `# sgxProgramId` --clone BNrpbCMbBFiCEqGdWaDMqjQmwqtGdgmoFFzGJnUexSbj `# sgxProgramDataAddress` --clone th1SbXMTX3SrWJ1kbiSKqMDpTBaXkESxpcehXRa12T4 `# sgxIdlAddress` --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd `# programState` --clone 7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie `# switchboardVault`",
|
||||
"local:validator:mainnet": "solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --rpc-port 8899 --url https://api.mainnet-beta.solana.com --clone SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --clone 7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF --clone Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk --clone 2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 --clone BNrpbCMbBFiCEqGdWaDMqjQmwqtGdgmoFFzGJnUexSbj --clone th1SbXMTX3SrWJ1kbiSKqMDpTBaXkESxpcehXRa12T4 --clone CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd --clone J7nSEX8ADf3pVVicd6yKy2Skvg8iLePEmkLUisAAaioD",
|
||||
"generate": "tsx ./scripts/generate-client.ts",
|
||||
"build:old": "shx rm -rf lib || true; tsc -p tsconfig.cjs.json && tsc",
|
||||
"build": "node esbuild.js",
|
||||
"watch": "tsc -p tsconfig.cjs.json --watch",
|
||||
|
@ -68,7 +165,8 @@
|
|||
"@coral-xyz/borsh": "^0.27.0",
|
||||
"@solana/spl-token": "^0.3.6",
|
||||
"@solana/web3.js": "^1.73.0",
|
||||
"@switchboard-xyz/common": "^2.2.3",
|
||||
"@switchboard-xyz/common": "^2.1.46",
|
||||
"cron-validator": "^1.3.1",
|
||||
"dotenv": "^16.0.3",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
|
@ -79,6 +177,8 @@
|
|||
"@types/lodash": "^4.14.191",
|
||||
"@types/mocha": "^10.0.0",
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/shelljs": "^0.8.12",
|
||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||
"chai": "^4.3.7",
|
||||
"chalk": "^4.1.2",
|
||||
"esbuild": "^0.17.19",
|
||||
|
@ -89,6 +189,7 @@
|
|||
"shx": "^0.3.4",
|
||||
"ts-mocha": "^10.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
"tsx": "^3.12.7",
|
||||
"typedoc": "^0.23.23",
|
||||
"typescript": "^4.9.4"
|
||||
},
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
import * as sbv2 from '../src';
|
||||
import { AggregatorAccount, CrankAccount, QueueAccount } from '../src';
|
||||
#!/usr/bin/env tsx
|
||||
|
||||
import * as sbv2 from "../src";
|
||||
import { AggregatorAccount, CrankAccount, QueueAccount } from "../src";
|
||||
|
||||
import {
|
||||
Aggregator,
|
||||
CHECK_ICON,
|
||||
|
@ -8,21 +11,21 @@ import {
|
|||
jsonReplacers,
|
||||
PLUS_ICON,
|
||||
setupOutputDir,
|
||||
} from './utils';
|
||||
} from "./utils.js";
|
||||
|
||||
import { clusterApiUrl, Connection, Keypair, PublicKey } from '@solana/web3.js';
|
||||
import { OracleJob, sleep, toUtf8 } from '@switchboard-xyz/common';
|
||||
import assert from 'assert';
|
||||
import { clusterApiUrl, Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import { OracleJob, sleep, toUtf8 } from "@switchboard-xyz/common";
|
||||
import assert from "assert";
|
||||
// import { backOff } from 'exponential-backoff';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
const VERBOSE = process.env.VERBOSE || false;
|
||||
|
||||
// expects a directory of keypairs that corresponds to
|
||||
// aggregatorAccount pubkeys and also the feed authority
|
||||
const keypairDirectory = path.join(os.homedir(), 'aggregator-keypairs');
|
||||
const keypairDirectory = path.join(os.homedir(), "aggregator-keypairs");
|
||||
|
||||
const DEFAULT_FEED_OPTIONS = {
|
||||
slidingWindow: true,
|
||||
|
@ -36,26 +39,26 @@ const DEFAULT_FEED_OPTIONS = {
|
|||
|
||||
const aggregatorMapPath = path.join(
|
||||
os.homedir(),
|
||||
'devnet-migration',
|
||||
sbv2.SBV2_MAINNET_PID.toBase58(),
|
||||
'aggregator_map.csv'
|
||||
"devnet-migration",
|
||||
sbv2.SB_V2_PID.toBase58(),
|
||||
"aggregator_map.csv"
|
||||
);
|
||||
|
||||
async function main() {
|
||||
const [oldDirPath, oldFeedDirPath, oldJobDirPath] = setupOutputDir(
|
||||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
"2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG"
|
||||
);
|
||||
const [newDirPath, newFeedDirPath, newJobDirPath] = setupOutputDir(
|
||||
sbv2.SBV2_MAINNET_PID.toBase58()
|
||||
sbv2.SB_V2_PID.toBase58()
|
||||
);
|
||||
|
||||
const keypairs = new Map<string, Keypair>();
|
||||
// first find all keypairs in directory
|
||||
for (const file of fs.readdirSync(keypairDirectory)) {
|
||||
if (!file.endsWith('.json')) {
|
||||
if (!file.endsWith(".json")) {
|
||||
continue;
|
||||
}
|
||||
const fileName = path.basename(file).replace('.json', '');
|
||||
const fileName = path.basename(file).replace(".json", "");
|
||||
const keypair = sbv2.SwitchboardTestContextV2.loadKeypair(
|
||||
path.join(keypairDirectory, file)
|
||||
);
|
||||
|
@ -73,36 +76,36 @@ async function main() {
|
|||
console.log(`Found ${keypairs.size} keypairs`);
|
||||
|
||||
const devnetConnection = new Connection(
|
||||
process.env.SOLANA_DEVNET_RPC ?? clusterApiUrl('devnet')
|
||||
process.env.SOLANA_DEVNET_RPC ?? clusterApiUrl("devnet")
|
||||
);
|
||||
console.log(`rpcUrl: ${devnetConnection.rpcEndpoint}`);
|
||||
|
||||
const payer = sbv2.SwitchboardTestContextV2.loadKeypair(
|
||||
'~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json'
|
||||
"~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json"
|
||||
);
|
||||
console.log(`payer: ${payer.publicKey.toBase58()}`);
|
||||
|
||||
const oldProgram = await sbv2.SwitchboardProgram.load(
|
||||
'devnet',
|
||||
"devnet",
|
||||
devnetConnection,
|
||||
payer,
|
||||
new PublicKey('2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG')
|
||||
new PublicKey("2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG")
|
||||
);
|
||||
const newProgram = await sbv2.SwitchboardProgram.load(
|
||||
'devnet',
|
||||
"devnet",
|
||||
devnetConnection,
|
||||
payer,
|
||||
sbv2.SBV2_MAINNET_PID
|
||||
sbv2.SB_V2_PID
|
||||
);
|
||||
|
||||
const [oldQueueAccount, oldQueue] = await QueueAccount.load(
|
||||
oldProgram,
|
||||
'GhYg3R1V6DmJbwuc57qZeoYG6gUuvCotUF1zU3WCj98U'
|
||||
"GhYg3R1V6DmJbwuc57qZeoYG6gUuvCotUF1zU3WCj98U"
|
||||
);
|
||||
|
||||
const [oldCrankAccount, oldCrank] = await CrankAccount.load(
|
||||
oldProgram,
|
||||
'85L2cFUvXaeGQ4HrzP8RJEVCL7WvRrXM2msvEmQ82AVr'
|
||||
"85L2cFUvXaeGQ4HrzP8RJEVCL7WvRrXM2msvEmQ82AVr"
|
||||
);
|
||||
|
||||
const [newQueueAccount, newQueue] = await QueueAccount.load(
|
||||
|
@ -128,16 +131,16 @@ async function main() {
|
|||
keypair.publicKey
|
||||
);
|
||||
|
||||
const programType: 'old' | 'new' | undefined =
|
||||
const programType: "old" | "new" | undefined =
|
||||
aggregatorAccountInfo &&
|
||||
aggregatorAccountInfo.owner.equals(oldProgram.programId)
|
||||
? 'old'
|
||||
? "old"
|
||||
: aggregatorAccountInfo &&
|
||||
aggregatorAccountInfo.owner.equals(newProgram.programId)
|
||||
? 'new'
|
||||
? "new"
|
||||
: undefined;
|
||||
|
||||
if (programType === 'new') {
|
||||
if (programType === "new") {
|
||||
console.log(`Aggregator ${pubkey} has already been migrated`);
|
||||
continue;
|
||||
}
|
||||
|
@ -150,7 +153,7 @@ async function main() {
|
|||
feedPath
|
||||
);
|
||||
|
||||
if (programType === 'old') {
|
||||
if (programType === "old") {
|
||||
await closeAggregator(aggregatorAccount, keypair);
|
||||
console.log(`\t${CHECK_ICON} feed closed`);
|
||||
}
|
||||
|
@ -226,14 +229,14 @@ async function main() {
|
|||
feedDefPath: string
|
||||
): Promise<Aggregator> {
|
||||
let feedDefinition: Aggregator | undefined = fs.existsSync(feedDefPath)
|
||||
? JSON.parse(fs.readFileSync(feedDefPath, 'utf-8'))
|
||||
? JSON.parse(fs.readFileSync(feedDefPath, "utf-8"))
|
||||
: undefined;
|
||||
|
||||
if (feedDefinition) {
|
||||
console.log(
|
||||
`\t${CHECK_ICON} feed definition loaded from ${feedDefPath
|
||||
.replace(process.cwd(), '.')
|
||||
.replace(os.homedir(), '~')}`
|
||||
.replace(process.cwd(), ".")
|
||||
.replace(os.homedir(), "~")}`
|
||||
);
|
||||
} else {
|
||||
const aggregator = await aggregatorAccount.loadData();
|
||||
|
@ -304,7 +307,7 @@ async function main() {
|
|||
},
|
||||
lease: lease.toJSON(),
|
||||
balance: leaseBalance,
|
||||
jobs: jobs.map(j => {
|
||||
jobs: jobs.map((j) => {
|
||||
return {
|
||||
account: {
|
||||
publicKey: j.account.publicKey.toBase58(),
|
||||
|
@ -343,7 +346,7 @@ async function main() {
|
|||
pushCrank: true,
|
||||
disableCrank: false,
|
||||
authority: payer.publicKey.toBase58(),
|
||||
jobs: aggregatorDefinition.jobs.map(j => {
|
||||
jobs: aggregatorDefinition.jobs.map((j) => {
|
||||
return {
|
||||
pubkey: j.account.publicKey,
|
||||
weight: 1,
|
||||
|
@ -359,8 +362,8 @@ async function main() {
|
|||
);
|
||||
console.log(
|
||||
`\t${CHECK_ICON} feed definition fetched and saved to ${feedDefPath
|
||||
.replace(process.cwd(), '.')
|
||||
.replace(os.homedir(), '~')}`
|
||||
.replace(process.cwd(), ".")
|
||||
.replace(os.homedir(), "~")}`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -382,7 +385,7 @@ async function main() {
|
|||
const [aggregatorAccount] = await queueAccount.createFeed({
|
||||
...DEFAULT_FEED_OPTIONS,
|
||||
keypair: keypair,
|
||||
authority: queueAuthority, // make queueAuthority the authority
|
||||
authority: queueAuthority.publicKey, // make queueAuthority the authority
|
||||
enable: true,
|
||||
queueAuthority: queueAuthority,
|
||||
name: aggregator.definition.name,
|
||||
|
@ -391,7 +394,7 @@ async function main() {
|
|||
minRequiredOracleResults: aggregator.definition.minRequiredOracleResults,
|
||||
minRequiredJobResults: aggregator.definition.minRequiredJobResults,
|
||||
minUpdateDelaySeconds: aggregator.definition.minUpdateDelaySeconds,
|
||||
jobs: aggregator.data.jobs.map(j => {
|
||||
jobs: aggregator.data.jobs.map((j) => {
|
||||
return {
|
||||
data: OracleJob.encodeDelimited(
|
||||
OracleJob.fromObject(j.oracleJob)
|
||||
|
@ -414,7 +417,7 @@ async function main() {
|
|||
console.log(
|
||||
`${CHECK_ICON} ${aggregator.publicKey.padEnd(
|
||||
44,
|
||||
' '
|
||||
" "
|
||||
)} -> ${aggregatorAccount.publicKey.toBase58()}`
|
||||
);
|
||||
|
||||
|
@ -423,7 +426,7 @@ async function main() {
|
|||
undefined,
|
||||
queueAccount,
|
||||
queue,
|
||||
'processed'
|
||||
"processed"
|
||||
);
|
||||
fs.writeFileSync(
|
||||
newFeedPath,
|
||||
|
@ -461,14 +464,14 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
function writeAggregatorMap(map: Map<string, string>) {
|
||||
const fileString = `oldPubkey, newPubkey\n${Array.from(map.entries())
|
||||
.map(r => r.join(', '))
|
||||
.join('\n')}`;
|
||||
.map((r) => r.join(", "))
|
||||
.join("\n")}`;
|
||||
fs.writeFileSync(aggregatorMapPath, fileString);
|
||||
}
|
||||
|
||||
|
@ -478,10 +481,10 @@ function loadAggregatorMap(): Map<string, string> {
|
|||
}
|
||||
|
||||
const map = new Map();
|
||||
const fileString = fs.readFileSync(aggregatorMapPath, 'utf-8');
|
||||
const fileLines = fileString.split('\n').slice(1);
|
||||
fileLines.forEach(r => {
|
||||
const [oldPubkey, newPubkey] = r.split(', ');
|
||||
const fileString = fs.readFileSync(aggregatorMapPath, "utf-8");
|
||||
const fileLines = fileString.split("\n").slice(1);
|
||||
fileLines.forEach((r) => {
|
||||
const [oldPubkey, newPubkey] = r.split(", ");
|
||||
map.set(oldPubkey, newPubkey);
|
||||
});
|
||||
|
||||
|
|
|
@ -1,175 +0,0 @@
|
|||
import shell from "shelljs";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import { execSync } from "child_process";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const projectRoot = path.join(__dirname, "..");
|
||||
|
||||
// Super hacky. Some files need to be reset to the previous git state and will be manually managed
|
||||
const ignoreFiles = [
|
||||
"./src/generated/types/SwitchboardPermission.ts", // we manually added NONE enumeration
|
||||
"./src/generated/types/SwitchboardDecimal.ts", // added toBig methods
|
||||
"./src/generated/types/Lanes.ts", // anchor-client-gen struggles with dual exports
|
||||
"./src/generated/types/index.ts", // TODO: Need a better way to handle this. anchor-client-gen adds multiple, broken exports (for VRF builder)
|
||||
"./src/generated/errors/index.ts", // need to revert the program ID check
|
||||
];
|
||||
|
||||
/**
|
||||
* Fetch a list of filepaths for a given directory and desired file extension
|
||||
* @param [dirPath] Filesystem path to a directory to search.
|
||||
* @param [arrayOfFiles] An array of existing file paths for recursive calls
|
||||
* @param [extensions] Optional, an array of desired extensions with the leading separator '.'
|
||||
* @throws {String}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
const getAllFiles = (dirPath, arrayOfFiles, extensions) => {
|
||||
const files = fs.readdirSync(dirPath, "utf8");
|
||||
|
||||
arrayOfFiles = arrayOfFiles || [];
|
||||
|
||||
files.forEach((file) => {
|
||||
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
|
||||
arrayOfFiles = getAllFiles(
|
||||
dirPath + "/" + file,
|
||||
arrayOfFiles,
|
||||
extensions
|
||||
);
|
||||
} else {
|
||||
const ext = path.extname(file);
|
||||
if (extensions && Array.isArray(extensions) && extensions.includes(ext)) {
|
||||
arrayOfFiles.push(path.join(dirPath, "/", file));
|
||||
} else {
|
||||
arrayOfFiles.push(path.join(dirPath, "/", file));
|
||||
}
|
||||
// if (!(extensions === undefined) || extensions.includes(ext)) {
|
||||
// arrayOfFiles.push(path.join(dirPath, '/', file));
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
return arrayOfFiles;
|
||||
};
|
||||
|
||||
async function main() {
|
||||
shell.cd(projectRoot);
|
||||
|
||||
const isDev = process.argv.includes("--dev");
|
||||
|
||||
if (!shell.which("anchor")) {
|
||||
shell.echo(
|
||||
"Sorry, this script requires 'anchor' to be installed in your $PATH"
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
fs.rmSync("idl", { recursive: true });
|
||||
fs.mkdirSync("idl", { recursive: true });
|
||||
|
||||
execSync(
|
||||
"anchor idl fetch -o ./idl/mainnet.json SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --provider.cluster mainnet"
|
||||
);
|
||||
execSync(
|
||||
"anchor idl fetch -o ./idl/devnet.json SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --provider.cluster devnet"
|
||||
);
|
||||
|
||||
if (isDev) {
|
||||
execSync(
|
||||
"rm -rf ./src/generated && npx anchor-client-gen --program-id SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f ../../../switchboard-core/switchboard_v2/target/idl/switchboard_v2.json ./src/generated"
|
||||
);
|
||||
} else {
|
||||
execSync(
|
||||
"rm -rf ./src/generated && npx anchor-client-gen --program-id SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f ./idl/mainnet.json ./src/generated"
|
||||
);
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
"./src/generated/index.ts",
|
||||
[
|
||||
"export * from './accounts/index.js';",
|
||||
"export * from './errors/index.js';",
|
||||
"export * from './instructions/index.js';",
|
||||
"export * from './types/index.js';",
|
||||
].join("\n")
|
||||
);
|
||||
|
||||
// loop through directory and run regex replaces
|
||||
for await (const file of [
|
||||
...getAllFiles("./src/generated/accounts"),
|
||||
...getAllFiles("./src/generated/errors"),
|
||||
...getAllFiles("./src/generated/instructions"),
|
||||
...getAllFiles("./src/generated/types"),
|
||||
]) {
|
||||
if (file.includes("index.ts")) {
|
||||
continue;
|
||||
}
|
||||
const fileString = fs.readFileSync(file, "utf-8");
|
||||
fs.writeFileSync(
|
||||
file,
|
||||
`import { SwitchboardProgram } from "../../SwitchboardProgram.js"\n${fileString}`
|
||||
);
|
||||
|
||||
console.log(file);
|
||||
|
||||
// replace BN import
|
||||
shell.sed(
|
||||
"-i",
|
||||
'import BN from "bn.js"',
|
||||
'import { BN } from "@switchboard-xyz/common"',
|
||||
file
|
||||
);
|
||||
// update types import
|
||||
shell.sed(
|
||||
"-i",
|
||||
'import * as types from "../types"',
|
||||
'import * as types from "../types/index.js"',
|
||||
file
|
||||
);
|
||||
// replace borsh import
|
||||
shell.sed("-i", "@project-serum", "@coral-xyz", file);
|
||||
// remove PROGRAM_ID import, we will use SwitchboardProgram instead
|
||||
shell.sed("-i", 'import { PROGRAM_ID } from "../programId"', "", file);
|
||||
|
||||
// replace PROGRAM_ID with program.programId
|
||||
shell.sed("-i", "PROGRAM_ID", "program.programId", file);
|
||||
// replace Connection with SwitchboardProgram
|
||||
shell.sed("-i", "c: Connection,", "program: SwitchboardProgram,", file);
|
||||
// replace c.getAccountInfo with the SwitchboardProgram connection
|
||||
shell.sed(
|
||||
"-i",
|
||||
"c.getAccountInfo",
|
||||
"program.connection.getAccountInfo",
|
||||
file
|
||||
);
|
||||
// replace c.getMultipleAccountsInfo with the SwitchboardProgram connection
|
||||
shell.sed(
|
||||
"-i",
|
||||
"c.getMultipleAccountsInfo",
|
||||
"program.connection.getMultipleAccountsInfo",
|
||||
file
|
||||
);
|
||||
|
||||
// add program as first arguement to instructions
|
||||
if (file.includes("/instructions/")) {
|
||||
shell.sed("-i", "args:", "program: SwitchboardProgram, args:", file);
|
||||
}
|
||||
}
|
||||
|
||||
execSync("npx prettier ./src/generated --write");
|
||||
|
||||
// reset files
|
||||
for (const file of ignoreFiles) {
|
||||
execSync(`git restore ${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => {
|
||||
// console.log("Executed successfully");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
|
@ -0,0 +1,370 @@
|
|||
#!/usr/bin/env tsx
|
||||
|
||||
import { exec, execSync } from "child_process";
|
||||
import fsSync from "fs";
|
||||
import fs from "fs/promises";
|
||||
import _ from "lodash";
|
||||
import path from "path";
|
||||
import shell from "shelljs";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const projectRoot = path.join(__dirname, "..");
|
||||
// const shx = path.join(projectRoot, 'node_modules', '.bin', 'shx');
|
||||
|
||||
const v2DevnetIdlPath = path.join(projectRoot, "./idl/devnet.json");
|
||||
const v2MainnetIdlPath = path.join(projectRoot, "./idl/mainnet.json");
|
||||
const v2GeneratedPath = path.join(
|
||||
projectRoot,
|
||||
"./src/generated/oracle-program"
|
||||
);
|
||||
|
||||
const attestationDevnetIdlPath = path.join(
|
||||
projectRoot,
|
||||
"./idl/attestation-devnet.json"
|
||||
);
|
||||
const attestationGeneratedPath = path.join(
|
||||
projectRoot,
|
||||
"./src/generated/attestation-program"
|
||||
);
|
||||
|
||||
const switchboardCoreDir = path.join(
|
||||
projectRoot,
|
||||
"../../../switchboard-core/switchboard_v2"
|
||||
);
|
||||
const switchboardV2IdlPath = path.join(
|
||||
switchboardCoreDir,
|
||||
"target/idl/switchboard_v2.json"
|
||||
);
|
||||
const switchboardAttestationIdlPath = path.join(
|
||||
switchboardCoreDir,
|
||||
"target/idl/switchboard_attestation_program.json"
|
||||
);
|
||||
|
||||
// Super hacky. Some files need to be reset to the previous git state and will be manually managed
|
||||
const ignoreFiles = [
|
||||
`${v2GeneratedPath}/types/SwitchboardPermission.ts`, // we manually added NONE enumeration
|
||||
`${v2GeneratedPath}/types/SwitchboardDecimal.ts`, // added toBig methods
|
||||
`${v2GeneratedPath}/types/Lanes.ts`, // anchor-client-gen struggles with dual exports
|
||||
`${v2GeneratedPath}/types/index.ts`, // TODO: Need a better way to handle this. anchor-client-gen adds multiple, broken exports (for VRF builder)
|
||||
`${v2GeneratedPath}/errors/index.ts`, // need to revert the program ID check,
|
||||
`${attestationGeneratedPath}/types/VerificationStatus.ts`,
|
||||
`${attestationGeneratedPath}/errors/index.ts`,
|
||||
`${attestationGeneratedPath}/types/SwitchboardAttestationPermission.ts`,
|
||||
// `${v2GeneratedPath}/types/VerificationStatus.ts`,
|
||||
];
|
||||
|
||||
/**
|
||||
* Fetch a list of filepaths for a given directory and desired file extension
|
||||
* @param [dirPath] Filesystem path to a directory to search.
|
||||
* @param [arrayOfFiles] An array of existing file paths for recursive calls
|
||||
* @param [extensions] Optional, an array of desired extensions with the leading separator '.'
|
||||
* @throws {String}
|
||||
* @returns {string[]}
|
||||
*/
|
||||
const getAllFiles = async (
|
||||
dirPath: string,
|
||||
arrayOfFiles: string[] = [],
|
||||
extensions: string[] = []
|
||||
): Promise<string[]> => {
|
||||
const files = await fs.readdir(dirPath, "utf8");
|
||||
|
||||
arrayOfFiles = arrayOfFiles || [];
|
||||
|
||||
for await (const file of files) {
|
||||
if (fsSync.statSync(dirPath + "/" + file).isDirectory()) {
|
||||
arrayOfFiles = await getAllFiles(
|
||||
dirPath + "/" + file,
|
||||
arrayOfFiles,
|
||||
extensions
|
||||
);
|
||||
} else {
|
||||
const ext = path.extname(file);
|
||||
if (extensions && Array.isArray(extensions) && extensions.includes(ext)) {
|
||||
arrayOfFiles.push(path.join(dirPath, "/", file));
|
||||
} else {
|
||||
arrayOfFiles.push(path.join(dirPath, "/", file));
|
||||
}
|
||||
// if (!(extensions === undefined) || extensions.includes(ext)) {
|
||||
// arrayOfFiles.push(path.join(dirPath, '/', file));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
return arrayOfFiles;
|
||||
};
|
||||
|
||||
async function main() {
|
||||
shell.cd(projectRoot);
|
||||
|
||||
// generate IDL types from local directory
|
||||
let devMode = false;
|
||||
if (process.argv.slice(2).includes("--dev")) {
|
||||
devMode = true;
|
||||
}
|
||||
|
||||
if (!shell.which("anchor")) {
|
||||
shell.echo(
|
||||
"Sorry, this script requires 'anchor' to be installed in your $PATH"
|
||||
);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
// Fetch IDLs and cleaning generated directories
|
||||
console.log(`Fetching anchor IDLs ...`);
|
||||
await Promise.all([
|
||||
runCommandAsync(
|
||||
`anchor idl fetch -o ${v2MainnetIdlPath} SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --provider.cluster mainnet`,
|
||||
{
|
||||
encoding: "utf-8",
|
||||
}
|
||||
),
|
||||
runCommandAsync(
|
||||
`anchor idl fetch -o ${v2DevnetIdlPath} SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f --provider.cluster devnet`,
|
||||
{
|
||||
encoding: "utf-8",
|
||||
}
|
||||
),
|
||||
runCommandAsync(
|
||||
`anchor idl fetch -o ${attestationDevnetIdlPath} 2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 --provider.cluster devnet`,
|
||||
{
|
||||
encoding: "utf-8",
|
||||
}
|
||||
),
|
||||
fsSync.existsSync(v2GeneratedPath)
|
||||
? fs.rm(v2GeneratedPath, { recursive: true })
|
||||
: Promise.resolve(),
|
||||
fsSync.existsSync(attestationGeneratedPath)
|
||||
? fs.rm(attestationGeneratedPath, { recursive: true })
|
||||
: Promise.resolve(),
|
||||
]);
|
||||
|
||||
console.log(`Running anchor-client-gen ...`);
|
||||
if (devMode) {
|
||||
await Promise.all([
|
||||
runCommandAsync(
|
||||
`npx anchor-client-gen --program-id SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f ${switchboardV2IdlPath} ${v2GeneratedPath}`,
|
||||
{ encoding: "utf-8" }
|
||||
),
|
||||
runCommandAsync(
|
||||
`npx anchor-client-gen --program-id 2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 ${switchboardAttestationIdlPath} ${attestationGeneratedPath}`,
|
||||
{ encoding: "utf-8" }
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
await Promise.all([
|
||||
runCommandAsync(
|
||||
`npx anchor-client-gen --program-id SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f ${v2DevnetIdlPath} ${v2GeneratedPath}`,
|
||||
{ encoding: "utf-8" }
|
||||
),
|
||||
runCommandAsync(
|
||||
`npx anchor-client-gen --program-id 2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7 ${attestationDevnetIdlPath} ${attestationGeneratedPath}`,
|
||||
{ encoding: "utf-8" }
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
fs.writeFile(
|
||||
`${v2GeneratedPath}/index.ts`,
|
||||
[
|
||||
"export * from './accounts/index.js';",
|
||||
"export * from './errors/index.js';",
|
||||
"export * from './instructions/index.js';",
|
||||
"export * from './types/index.js';",
|
||||
].join("\n")
|
||||
),
|
||||
|
||||
fs.writeFile(
|
||||
`${attestationGeneratedPath}/index.ts`,
|
||||
[
|
||||
"export * from './accounts/index.js';",
|
||||
"export * from './errors/index.js';",
|
||||
"export * from './instructions/index.js';",
|
||||
"export * from './types/index.js';",
|
||||
].join("\n")
|
||||
),
|
||||
]);
|
||||
|
||||
// loop through directory and run regex replaces
|
||||
const allGeneratedFiles = _.flatten(
|
||||
await Promise.all([
|
||||
getAllFiles(`${v2GeneratedPath}/accounts`),
|
||||
getAllFiles(`${v2GeneratedPath}/errors`),
|
||||
getAllFiles(`${v2GeneratedPath}/instructions`),
|
||||
getAllFiles(`${v2GeneratedPath}/types`),
|
||||
getAllFiles(`${attestationGeneratedPath}/accounts`),
|
||||
getAllFiles(`${attestationGeneratedPath}/errors`),
|
||||
getAllFiles(`${attestationGeneratedPath}/instructions`),
|
||||
getAllFiles(`${attestationGeneratedPath}/types`),
|
||||
])
|
||||
);
|
||||
|
||||
console.log(`Processing ${allGeneratedFiles.length} files ...`);
|
||||
|
||||
await Promise.all(allGeneratedFiles.map((f) => processFile(f)));
|
||||
|
||||
console.log(`Formatting generated files ...`);
|
||||
await Promise.all([
|
||||
runCommandAsync(`npx prettier ${v2GeneratedPath} --write`, {
|
||||
encoding: "utf-8",
|
||||
}),
|
||||
runCommandAsync(`npx prettier ${attestationGeneratedPath} --write`, {
|
||||
encoding: "utf-8",
|
||||
}),
|
||||
]);
|
||||
|
||||
// reset ignored files
|
||||
for (const file of ignoreFiles) {
|
||||
execSync(`git restore ${file}`, { encoding: "utf-8" });
|
||||
}
|
||||
|
||||
// delete the extra QuoteAccountData
|
||||
await fs.rm(path.join(v2GeneratedPath, "accounts", "QuoteAccountData.ts"));
|
||||
// delete the extra VerificationStatus
|
||||
await fs.rm(path.join(v2GeneratedPath, "types", "VerificationStatus.ts"));
|
||||
|
||||
// run auto fix for import ordering
|
||||
execSync(`pnpm fix`, { encoding: "utf-8" });
|
||||
}
|
||||
|
||||
main()
|
||||
.then(() => {
|
||||
// console.log("Executed successfully");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
/**
|
||||
* Process the generated file and add the SwitchboardProgram class
|
||||
*/
|
||||
const processFile = async (file: string) => {
|
||||
return await fs
|
||||
.readFile(file, "utf-8")
|
||||
.then(async (fileString: string): Promise<string> => {
|
||||
let updatedFileString = fileString;
|
||||
|
||||
if (file.endsWith("errors/index.ts")) {
|
||||
return updatedFileString
|
||||
.replace(
|
||||
`import { PROGRAM_ID } from "../programId"`,
|
||||
`import { PROGRAM_ID } from "../programId.js"`
|
||||
)
|
||||
.replace(
|
||||
`import * as anchor from "./anchor"`,
|
||||
`import * as anchor from "./anchor.js"`
|
||||
)
|
||||
.replace(
|
||||
`import * as custom from "./custom"`,
|
||||
`import * as custom from "./custom.js"`
|
||||
);
|
||||
}
|
||||
if (file.includes("index.ts")) {
|
||||
if (file === path.join(v2GeneratedPath, "accounts", "index.ts")) {
|
||||
updatedFileString = updatedFileString.replace(
|
||||
`export { QuoteAccountData } from "./QuoteAccountData"
|
||||
export type {
|
||||
QuoteAccountDataFields,
|
||||
QuoteAccountDataJSON,
|
||||
} from "./QuoteAccountData"
|
||||
`,
|
||||
``
|
||||
);
|
||||
}
|
||||
|
||||
// add the .js extension to all local import/export paths
|
||||
return updatedFileString.replace(
|
||||
/((import|export)((\s\w+)?([^'"]*))from\s['"])([^'"]+)(['"])/gm,
|
||||
"$1$6.js$7"
|
||||
);
|
||||
}
|
||||
|
||||
updatedFileString =
|
||||
`import { SwitchboardProgram } from "../../../SwitchboardProgram.js"` +
|
||||
"\n" +
|
||||
fileString;
|
||||
|
||||
// update the types import
|
||||
updatedFileString = updatedFileString
|
||||
// use full path
|
||||
.replace(
|
||||
`import * as types from "../types"`,
|
||||
`import * as types from "../types/index.js"`
|
||||
)
|
||||
|
||||
// use our library to avoid version conflicts
|
||||
.replace(
|
||||
`import BN from "bn.js"`,
|
||||
`import { BN } from "@switchboard-xyz/common"`
|
||||
)
|
||||
// better
|
||||
.replace(
|
||||
`import * as borsh from "@project-serum/borsh"`,
|
||||
`import * as borsh from "@coral-xyz/borsh"`
|
||||
)
|
||||
// remove this import, using SwitchboardProgram
|
||||
.replace(`import { PROGRAM_ID } from "../programId"`, ``)
|
||||
.replaceAll(`PROGRAM_ID`, `program.programId`)
|
||||
.replaceAll(`c: Connection,`, `program: SwitchboardProgram,`)
|
||||
.replaceAll(`c.getAccountInfo`, `program.connection.getAccountInfo`)
|
||||
.replaceAll(
|
||||
`c.getMultipleAccountsInfo`,
|
||||
`program.connection.getMultipleAccountsInfo`
|
||||
);
|
||||
|
||||
if (file.includes("/instructions/")) {
|
||||
updatedFileString = updatedFileString.replaceAll(
|
||||
`args:`,
|
||||
`program: SwitchboardProgram, args:`
|
||||
);
|
||||
}
|
||||
|
||||
if (file.includes("/attestation-program/")) {
|
||||
updatedFileString = updatedFileString.replaceAll(
|
||||
`program.programId`,
|
||||
`program.attestationProgramId`
|
||||
);
|
||||
}
|
||||
|
||||
return updatedFileString;
|
||||
})
|
||||
.then(async (updatedFileString: string) => {
|
||||
return await fs.writeFile(file, updatedFileString, "utf-8");
|
||||
});
|
||||
};
|
||||
|
||||
async function runCommandAsync(
|
||||
command: string,
|
||||
options: Record<string, any>
|
||||
): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = exec(command, options);
|
||||
|
||||
// cmd.stdout.on('data', data => {
|
||||
// console.log(data.toString());
|
||||
// });
|
||||
|
||||
cmd?.stderr?.on("data", (data) => {
|
||||
console.error(data.toString());
|
||||
});
|
||||
|
||||
// cmd.on("message", (data) => {
|
||||
// console.info(data.toString());
|
||||
// });
|
||||
|
||||
cmd.on("error", (error) => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
cmd.on("close", (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Command exited with code ${code}`));
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,338 @@
|
|||
#!/usr/bin/env tsx
|
||||
|
||||
import { clusterApiUrl, Connection, Keypair, PublicKey } from "@solana/web3.js";
|
||||
import { sleep } from "@switchboard-xyz/common";
|
||||
import { exec, execSync, spawn } from "child_process";
|
||||
import fsSync from "fs";
|
||||
import fs from "fs/promises";
|
||||
import _ from "lodash";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const getProgramDataAddress = (programId) => {
|
||||
return PublicKey.findProgramAddressSync(
|
||||
[programId.toBytes()],
|
||||
new PublicKey("BPFLoaderUpgradeab1e11111111111111111111111")
|
||||
)[0];
|
||||
};
|
||||
|
||||
const getIdlAddress = (programId) => {
|
||||
const base = PublicKey.findProgramAddressSync([], programId)[0];
|
||||
|
||||
// const buffer = Buffer.concat([
|
||||
// base.toBuffer(),
|
||||
// Buffer.from('anchor:idl'),
|
||||
// programId.toBuffer(),
|
||||
// ]);
|
||||
// const publicKeyBytes = sha256(buffer);
|
||||
// return new PublicKey(publicKeyBytes);
|
||||
|
||||
return PublicKey.createWithSeed(base, "anchor:idl", new PublicKey(programId));
|
||||
};
|
||||
|
||||
const SWITCHBOARD_PROGRAM_ID = new PublicKey(
|
||||
"SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
|
||||
);
|
||||
// const SWITCHBOARD_PROGRAM_ACCOUNTS = [
|
||||
// SWITCHBOARD_PROGRAM_ID,
|
||||
// getProgramDataAddress(SWITCHBOARD_PROGRAM_ID),
|
||||
// await getIdlAddress(SWITCHBOARD_PROGRAM_ID),
|
||||
// ];
|
||||
|
||||
const SWITCHBOARD_ATTESTATION_PROGRAM_ID = new PublicKey(
|
||||
"2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7"
|
||||
);
|
||||
// const SWITCHBOARD_ATTESTATION_PROGRAM_ACCOUNTS = [
|
||||
// SWITCHBOARD_ATTESTATION_PROGRAM_ID,
|
||||
// getProgramDataAddress(SWITCHBOARD_ATTESTATION_PROGRAM_ID),
|
||||
// await getIdlAddress(SWITCHBOARD_ATTESTATION_PROGRAM_ID),
|
||||
// ];
|
||||
|
||||
const jsSdkRoot = path.join(__dirname, "..");
|
||||
const solanaSdkRoot = path.join(jsSdkRoot, "..", "..");
|
||||
const devSwitchboard = path.join(
|
||||
solanaSdkRoot,
|
||||
"..",
|
||||
"switchboard-core",
|
||||
"switchboard_v2"
|
||||
);
|
||||
|
||||
const defaultPubkeyPath = path.join(
|
||||
os.homedir(),
|
||||
".config",
|
||||
"solana",
|
||||
"id.json"
|
||||
);
|
||||
|
||||
function killPort(port) {
|
||||
execSync(`lsof -t -i :${port} | xargs kill -9 || exit 0`, {
|
||||
encoding: "utf-8",
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// if dev, clone the local program version
|
||||
const isDev = process.argv.slice(2).includes("--dev");
|
||||
if (isDev) {
|
||||
console.log(`Using local switchboard programs`);
|
||||
}
|
||||
|
||||
const isMainnet = process.argv.slice(2).includes("--mainnet");
|
||||
|
||||
const shouldBuild = process.argv.slice(2).includes("--build");
|
||||
|
||||
try {
|
||||
killPort(8899);
|
||||
killPort(8900);
|
||||
} catch (error) {
|
||||
console.error(`Failed to kill port 8899`);
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
if (!fsSync.existsSync(defaultPubkeyPath)) {
|
||||
await fs.writeFile(defaultPubkeyPath, `[${Keypair.generate().secretKey}]`);
|
||||
}
|
||||
|
||||
const payerPubkey = Keypair.fromSecretKey(
|
||||
new Uint8Array(JSON.parse(await fs.readFile(defaultPubkeyPath, "utf-8")))
|
||||
).publicKey;
|
||||
|
||||
await fs.mkdir(".anchor/test-ledger", { recursive: true });
|
||||
|
||||
let rpcUrl = clusterApiUrl(isMainnet ? "mainnet-beta" : "devnet");
|
||||
if (isMainnet && process.env.SOLANA_MAINNET_RPC_URL) {
|
||||
rpcUrl = process.env.SOLANA_MAINNET_RPC_URL;
|
||||
} else if (!isMainnet && process.env.SOLANA_DEVNET_RPC_URL) {
|
||||
rpcUrl = process.env.SOLANA_DEVNET_RPC_URL;
|
||||
}
|
||||
|
||||
if (shouldBuild && isDev) {
|
||||
console.log(`rebuilding anchor programs ...`);
|
||||
execSync(`anchor build`, { cwd: devSwitchboard });
|
||||
}
|
||||
|
||||
if (isDev) {
|
||||
spawn(
|
||||
"solana-test-validator",
|
||||
[
|
||||
"-q",
|
||||
"-r",
|
||||
"--mint",
|
||||
payerPubkey.toBase58(),
|
||||
"--ledger",
|
||||
".anchor/test-ledger",
|
||||
// '--url',
|
||||
// rpcUrl,
|
||||
// ...cloneAccounts,
|
||||
],
|
||||
{ cwd: jsSdkRoot, stdio: "pipe" }
|
||||
);
|
||||
|
||||
await awaitValidator();
|
||||
|
||||
await Promise.all([
|
||||
programDeploy(
|
||||
devSwitchboard,
|
||||
defaultPubkeyPath,
|
||||
"switchboard_v2",
|
||||
"SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
|
||||
),
|
||||
programDeploy(
|
||||
devSwitchboard,
|
||||
defaultPubkeyPath,
|
||||
"switchboard_attestation_program",
|
||||
"2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7"
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
const cloneAccounts = [
|
||||
SWITCHBOARD_PROGRAM_ID,
|
||||
getProgramDataAddress(SWITCHBOARD_PROGRAM_ID),
|
||||
await getIdlAddress(SWITCHBOARD_PROGRAM_ID),
|
||||
SWITCHBOARD_ATTESTATION_PROGRAM_ID,
|
||||
getProgramDataAddress(SWITCHBOARD_ATTESTATION_PROGRAM_ID),
|
||||
await getIdlAddress(SWITCHBOARD_ATTESTATION_PROGRAM_ID),
|
||||
]
|
||||
.map((a) => `--clone ${a.toBase58()}`)
|
||||
.join(" ")
|
||||
.split(" ");
|
||||
|
||||
spawn(
|
||||
"solana-test-validator",
|
||||
[
|
||||
"-q",
|
||||
"-r",
|
||||
"--mint",
|
||||
payerPubkey.toBase58(),
|
||||
"--ledger",
|
||||
".anchor/test-ledger",
|
||||
"--url",
|
||||
rpcUrl,
|
||||
...cloneAccounts,
|
||||
],
|
||||
{ cwd: jsSdkRoot }
|
||||
);
|
||||
|
||||
await awaitValidator();
|
||||
}
|
||||
|
||||
console.log(`\n\nLocal solana validator started ... `);
|
||||
}
|
||||
|
||||
main()
|
||||
.then()
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
async function awaitValidator(timeout = 60) {
|
||||
const connection = new Connection("http://127.0.0.1:8899");
|
||||
let myError;
|
||||
let numRetries = timeout * 2;
|
||||
while (numRetries) {
|
||||
try {
|
||||
const id = await connection.getBlockHeight();
|
||||
if (id) {
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
myError = error;
|
||||
// console.error(error);
|
||||
}
|
||||
|
||||
--numRetries;
|
||||
await sleep(500);
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Failed to start Solana local validator in ${timeout} seconds${
|
||||
myError ? ": " + myError : undefined
|
||||
}`
|
||||
);
|
||||
}
|
||||
|
||||
async function programDeploy(
|
||||
switchboardDir,
|
||||
defaultPubkeyPath,
|
||||
programName,
|
||||
programId
|
||||
) {
|
||||
const sbProgramPath = path.join(
|
||||
switchboardDir,
|
||||
"target",
|
||||
"deploy",
|
||||
`${programName}.so`
|
||||
);
|
||||
if (!fsSync.existsSync(sbProgramPath)) {
|
||||
throw new Error(
|
||||
`Failed to find BPF program ${programName}.so in ${switchboardDir}`
|
||||
);
|
||||
}
|
||||
|
||||
const programKeypairPath = path.join(
|
||||
switchboardDir,
|
||||
"target",
|
||||
"deploy",
|
||||
`${programName}-keypair.json`
|
||||
);
|
||||
if (!fsSync.existsSync(programKeypairPath)) {
|
||||
throw new Error(
|
||||
`Failed to find program keypair for ${programName} in ${switchboardDir}`
|
||||
);
|
||||
}
|
||||
const programKeypair = Keypair.fromSecretKey(
|
||||
new Uint8Array(JSON.parse(await fs.readFile(programKeypairPath, "utf-8")))
|
||||
);
|
||||
if (programKeypair.publicKey.toBase58() !== programId) {
|
||||
throw new Error(
|
||||
`Program ID mismatch for program ${programName}, expected ${programId}, received ${programKeypair.publicKey.toBase58()}`
|
||||
);
|
||||
}
|
||||
|
||||
const idlPath = path.join(
|
||||
switchboardDir,
|
||||
"target",
|
||||
"idl",
|
||||
`${programName}.json`
|
||||
);
|
||||
if (!fsSync.existsSync(idlPath)) {
|
||||
throw new Error(
|
||||
`Failed to find IDL ${programName}.json in ${switchboardDir}`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`Starting program deploy for ${programName} ...`);
|
||||
await runCommandAsync(
|
||||
`solana ${[
|
||||
"program",
|
||||
"deploy",
|
||||
"-u",
|
||||
"l",
|
||||
"-k",
|
||||
"~/.config/solana/id.json",
|
||||
"--program-id",
|
||||
programKeypairPath,
|
||||
"--upgrade-authority",
|
||||
defaultPubkeyPath,
|
||||
sbProgramPath,
|
||||
].join(" ")}`,
|
||||
{
|
||||
cwd: switchboardDir,
|
||||
encoding: "utf8",
|
||||
// stdio: 'pipe',
|
||||
shell: "/bin/zsh",
|
||||
}
|
||||
);
|
||||
|
||||
console.log(`Starting IDL deploy for ${programName} ...`);
|
||||
await runCommandAsync(
|
||||
`anchor ${[
|
||||
"idl",
|
||||
"init",
|
||||
"--provider.cluster",
|
||||
"localnet",
|
||||
"--provider.wallet",
|
||||
defaultPubkeyPath,
|
||||
"-f",
|
||||
idlPath,
|
||||
programId,
|
||||
].join(" ")}`,
|
||||
{
|
||||
cwd: switchboardDir,
|
||||
encoding: "utf8",
|
||||
// stdio: 'pipe',
|
||||
shell: "/bin/zsh",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
async function runCommandAsync(command, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const cmd = spawn(command, options);
|
||||
|
||||
cmd.stdout.on("data", (data) => {
|
||||
console.log(data.toString());
|
||||
});
|
||||
|
||||
cmd.stderr.on("data", (data) => {
|
||||
console.error(data.toString());
|
||||
});
|
||||
|
||||
cmd.on("error", (error) => {
|
||||
reject(error);
|
||||
});
|
||||
|
||||
cmd.on("close", (code) => {
|
||||
if (code !== 0) {
|
||||
reject(new Error(`Command exited with code ${code}`));
|
||||
} else {
|
||||
resolve(undefined);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
|
@ -1,62 +1,63 @@
|
|||
import * as sbv2 from './src';
|
||||
import * as sbv2 from "../src/index.js";
|
||||
import {
|
||||
CrankAccount,
|
||||
QueueAccount,
|
||||
SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_CRANK,
|
||||
SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_QUEUE,
|
||||
} from './src';
|
||||
} from "../src/index.js";
|
||||
|
||||
import {
|
||||
Aggregator,
|
||||
CHECK_ICON,
|
||||
FAILED_ICON,
|
||||
jsonReplacers,
|
||||
setupOutputDir,
|
||||
} from './utils';
|
||||
} from "./utils.js";
|
||||
|
||||
import { clusterApiUrl, Connection, PublicKey } from '@solana/web3.js';
|
||||
import { clusterApiUrl, Connection, PublicKey } from "@solana/web3.js";
|
||||
// import { backOff } from 'exponential-backoff';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import path from "path";
|
||||
|
||||
const VERBOSE = process.env.VERBOSE || false;
|
||||
|
||||
const jobMapPath = path.join(
|
||||
os.homedir(),
|
||||
'devnet-migration',
|
||||
sbv2.SBV2_MAINNET_PID.toBase58(),
|
||||
'job_map.csv'
|
||||
"devnet-migration",
|
||||
sbv2.SB_V2_PID.toBase58(),
|
||||
"job_map.csv"
|
||||
);
|
||||
const aggregatorMapPath = path.join(
|
||||
os.homedir(),
|
||||
'devnet-migration',
|
||||
sbv2.SBV2_MAINNET_PID.toBase58(),
|
||||
'aggregator_map.csv'
|
||||
"devnet-migration",
|
||||
sbv2.SB_V2_PID.toBase58(),
|
||||
"aggregator_map.csv"
|
||||
);
|
||||
|
||||
async function main() {
|
||||
const [oldDirPath, oldFeedDirPath, oldJobDirPath] = setupOutputDir(
|
||||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
"2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG"
|
||||
);
|
||||
const [newDirPath, newFeedDirPath, newJobDirPath] = setupOutputDir(
|
||||
sbv2.SBV2_MAINNET_PID.toBase58()
|
||||
sbv2.SB_V2_PID.toBase58()
|
||||
);
|
||||
|
||||
const devnetConnection = new Connection(
|
||||
process.env.SOLANA_DEVNET_RPC ?? clusterApiUrl('devnet')
|
||||
process.env.SOLANA_DEVNET_RPC ?? clusterApiUrl("devnet")
|
||||
);
|
||||
console.log(`rpcUrl: ${devnetConnection.rpcEndpoint}`);
|
||||
|
||||
const payer = sbv2.SwitchboardTestContextV2.loadKeypair(
|
||||
'~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json'
|
||||
"~/switchboard_environments_v2/devnet/upgrade_authority/upgrade_authority.json"
|
||||
);
|
||||
console.log(`payer: ${payer.publicKey.toBase58()}`);
|
||||
|
||||
const newProgram = await sbv2.SwitchboardProgram.load(
|
||||
'devnet',
|
||||
"devnet",
|
||||
devnetConnection,
|
||||
payer,
|
||||
sbv2.SBV2_MAINNET_PID
|
||||
sbv2.SB_V2_PID
|
||||
);
|
||||
|
||||
const [queueAccount, queue] = await QueueAccount.load(
|
||||
|
@ -75,12 +76,12 @@ async function main() {
|
|||
|
||||
const aggregators = new Map<string, Aggregator>();
|
||||
for (const file of fs.readdirSync(oldFeedDirPath)) {
|
||||
if (!file.endsWith('.json')) {
|
||||
if (!file.endsWith(".json")) {
|
||||
continue;
|
||||
}
|
||||
const fileName = path.basename(file).replace('.json', '');
|
||||
const fileName = path.basename(file).replace(".json", "");
|
||||
const aggregatorDef: Aggregator = JSON.parse(
|
||||
fs.readFileSync(path.join(oldFeedDirPath, file), 'utf-8')
|
||||
fs.readFileSync(path.join(oldFeedDirPath, file), "utf-8")
|
||||
);
|
||||
aggregators.set(fileName, aggregatorDef);
|
||||
}
|
||||
|
@ -107,7 +108,7 @@ async function main() {
|
|||
try {
|
||||
// find job accounts
|
||||
const jobs: Array<{ pubkey: PublicKey; weight: number }> =
|
||||
aggregator.definition.jobs.map(j => {
|
||||
aggregator.definition.jobs.map((j) => {
|
||||
const newJobKey = jobMap.get(j.pubkey);
|
||||
if (!newJobKey) {
|
||||
throw new Error(`Job ${j.pubkey} was not migrated`);
|
||||
|
@ -121,7 +122,7 @@ async function main() {
|
|||
|
||||
// create a feed but keep ourself as the authority until we do all final checks
|
||||
const [aggregatorAccount] = await queueAccount.createFeed({
|
||||
authority: payer,
|
||||
authority: payer.publicKey,
|
||||
name: aggregator.definition.name,
|
||||
metadata: aggregator.definition.metadata,
|
||||
batchSize: aggregator.definition.batchSize,
|
||||
|
@ -162,7 +163,7 @@ async function main() {
|
|||
console.log(
|
||||
`${CHECK_ICON} ${aggregatorKey.padEnd(
|
||||
44,
|
||||
' '
|
||||
" "
|
||||
)} -> ${aggregatorAccount.publicKey.toBase58()}`
|
||||
);
|
||||
|
||||
|
@ -171,7 +172,7 @@ async function main() {
|
|||
undefined,
|
||||
queueAccount,
|
||||
queue,
|
||||
'processed'
|
||||
"processed"
|
||||
);
|
||||
fs.writeFileSync(
|
||||
newFeedPath,
|
||||
|
@ -212,14 +213,14 @@ async function main() {
|
|||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
main().catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
|
||||
function writeAggregatorMap(map: Map<string, string>) {
|
||||
const fileString = `oldPubkey, newPubkey\n${Array.from(map.entries())
|
||||
.map(r => r.join(', '))
|
||||
.join('\n')}`;
|
||||
.map((r) => r.join(", "))
|
||||
.join("\n")}`;
|
||||
fs.writeFileSync(aggregatorMapPath, fileString);
|
||||
}
|
||||
|
||||
|
@ -229,10 +230,10 @@ function loadJobMap(): Map<string, string> {
|
|||
}
|
||||
|
||||
const map = new Map();
|
||||
const fileString = fs.readFileSync(jobMapPath, 'utf-8');
|
||||
const fileLines = fileString.split('\n').slice(1);
|
||||
fileLines.forEach(r => {
|
||||
const [oldPubkey, newPubkey] = r.split(', ');
|
||||
const fileString = fs.readFileSync(jobMapPath, "utf-8");
|
||||
const fileLines = fileString.split("\n").slice(1);
|
||||
fileLines.forEach((r) => {
|
||||
const [oldPubkey, newPubkey] = r.split(", ");
|
||||
map.set(oldPubkey, newPubkey);
|
||||
});
|
||||
|
||||
|
@ -245,10 +246,10 @@ function loadAggregatorMap(): Map<string, string> {
|
|||
}
|
||||
|
||||
const map = new Map();
|
||||
const fileString = fs.readFileSync(aggregatorMapPath, 'utf-8');
|
||||
const fileLines = fileString.split('\n').slice(1);
|
||||
fileLines.forEach(r => {
|
||||
const [oldPubkey, newPubkey] = r.split(', ');
|
||||
const fileString = fs.readFileSync(aggregatorMapPath, "utf-8");
|
||||
const fileLines = fileString.split("\n").slice(1);
|
||||
fileLines.forEach((r) => {
|
||||
const [oldPubkey, newPubkey] = r.split(", ");
|
||||
map.set(oldPubkey, newPubkey);
|
||||
});
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ const VERBOSE = process.env.VERBOSE || false;
|
|||
const jobMapPath = path.join(
|
||||
os.homedir(),
|
||||
'devnet-migration',
|
||||
sbv2.SBV2_MAINNET_PID.toBase58(),
|
||||
sbv2.SB_V2_PID.toBase58(),
|
||||
'job_map.csv'
|
||||
);
|
||||
|
||||
|
@ -21,7 +21,7 @@ async function main() {
|
|||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
);
|
||||
const [newDirPath, newFeedDirPath, newJobDirPath] = setupOutputDir(
|
||||
sbv2.SBV2_MAINNET_PID.toBase58()
|
||||
sbv2.SB_V2_PID.toBase58()
|
||||
);
|
||||
|
||||
const devnetConnection = new Connection(
|
||||
|
@ -38,7 +38,7 @@ async function main() {
|
|||
'devnet',
|
||||
devnetConnection,
|
||||
payer,
|
||||
sbv2.SBV2_MAINNET_PID
|
||||
sbv2.SB_V2_PID
|
||||
);
|
||||
|
||||
const jobs = new Map<string, Job>();
|
||||
|
|
|
@ -14,7 +14,7 @@ import path from 'path';
|
|||
const aggregatorMapPath = path.join(
|
||||
os.homedir(),
|
||||
'devnet-migration',
|
||||
sbv2.SBV2_MAINNET_PID.toBase58(),
|
||||
sbv2.SB_V2_PID.toBase58(),
|
||||
'aggregator_map.csv'
|
||||
);
|
||||
|
||||
|
@ -23,7 +23,7 @@ async function main() {
|
|||
'2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG'
|
||||
);
|
||||
const [newDirPath, newFeedDirPath, newJobDirPath] = setupOutputDir(
|
||||
sbv2.SBV2_MAINNET_PID.toBase58()
|
||||
sbv2.SB_V2_PID.toBase58()
|
||||
);
|
||||
|
||||
const devnetConnection = new Connection(
|
||||
|
@ -40,7 +40,7 @@ async function main() {
|
|||
'devnet',
|
||||
devnetConnection,
|
||||
payer,
|
||||
sbv2.SBV2_MAINNET_PID
|
||||
sbv2.SB_V2_PID
|
||||
);
|
||||
|
||||
const aggregatorMap = loadAggregatorMap();
|
||||
|
@ -71,7 +71,7 @@ async function main() {
|
|||
const aggregators = await fetchAggregators(
|
||||
devnetConnection,
|
||||
newAggregatorKeys,
|
||||
sbv2.SBV2_MAINNET_PID,
|
||||
sbv2.SB_V2_PID,
|
||||
payer.publicKey
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"include": [
|
||||
"**/*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"rootDir": ".",
|
||||
"noEmit": true,
|
||||
"lib": [
|
||||
"ES2022"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import {
|
||||
AttestationProgramStateAccount,
|
||||
BUFFER_DISCRIMINATOR,
|
||||
CrankAccount,
|
||||
DISCRIMINATOR_MAP,
|
||||
|
@ -39,8 +40,16 @@ import { SwitchboardEvents } from "./SwitchboardEvents.js";
|
|||
import { TransactionObject, TransactionOptions } from "./TransactionObject.js";
|
||||
import { LoadedJobDefinition } from "./types.js";
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import { ACCOUNT_DISCRIMINATOR_SIZE } from "@coral-xyz/anchor";
|
||||
import {
|
||||
ACCOUNT_DISCRIMINATOR_SIZE,
|
||||
AccountNamespace,
|
||||
AnchorProvider,
|
||||
BorshAccountsCoder,
|
||||
Idl,
|
||||
Program,
|
||||
utils as AnchorUtils,
|
||||
Wallet,
|
||||
} from "@coral-xyz/anchor";
|
||||
import {
|
||||
AccountInfo,
|
||||
Cluster,
|
||||
|
@ -65,17 +74,17 @@ export const DEFAULT_SEND_TRANSACTION_OPTIONS: SendTransactionOptions = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Switchboard Devnet Program ID
|
||||
* Switchboard's V2 Program ID
|
||||
*/
|
||||
export const SBV2_DEVNET_PID = new PublicKey(
|
||||
export const SB_V2_PID = new PublicKey(
|
||||
"SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
|
||||
);
|
||||
|
||||
/**
|
||||
* Switchboard Mainnet Program ID
|
||||
* Switchboard's Attestation Program ID
|
||||
*/
|
||||
export const SBV2_MAINNET_PID = new PublicKey(
|
||||
"SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
|
||||
export const SB_ATTESTATION_PID = new PublicKey(
|
||||
"2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7"
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -92,12 +101,30 @@ export const getSwitchboardProgramId = (
|
|||
case "localnet":
|
||||
case "devnet":
|
||||
case "mainnet-beta":
|
||||
return SBV2_MAINNET_PID;
|
||||
return SB_V2_PID;
|
||||
case "testnet":
|
||||
default:
|
||||
throw new Error(`Switchboard PID not found for cluster (${cluster})`);
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the Program ID for the Switchboard Attestation Program for the specified Cluster.
|
||||
*/
|
||||
export const getSwitchboardAttestationProgramId = (
|
||||
cluster: Cluster | "localnet"
|
||||
): PublicKey => {
|
||||
switch (cluster) {
|
||||
case "localnet":
|
||||
case "devnet":
|
||||
case "mainnet-beta":
|
||||
return SB_ATTESTATION_PID;
|
||||
case "testnet":
|
||||
default:
|
||||
throw new Error(
|
||||
`Switchboard Attestation PID not found for cluster (${cluster})`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Wrapper class for the Switchboard anchor Program.
|
||||
|
@ -127,7 +154,10 @@ export class SwitchboardProgram {
|
|||
private static readonly _readOnlyKeypair = READ_ONLY_KEYPAIR;
|
||||
|
||||
// The anchor program instance.
|
||||
private readonly _program: anchor.Program;
|
||||
private readonly _program: Program;
|
||||
|
||||
// The anchor program instance for Switchboard's attestation program.
|
||||
private readonly _attestationProgram: Program | undefined;
|
||||
|
||||
/** The Solana cluster to load the Switchboard program for. */
|
||||
readonly cluster: Cluster | "localnet";
|
||||
|
@ -138,6 +168,12 @@ export class SwitchboardProgram {
|
|||
bump: number;
|
||||
};
|
||||
|
||||
// The pubkey and bump of the Switchboard quote verifier program state account.
|
||||
readonly attestationProgramState: {
|
||||
publicKey: PublicKey;
|
||||
bump: number;
|
||||
};
|
||||
|
||||
// The native mint for the Switchboard program.
|
||||
readonly mint: NativeMint;
|
||||
|
||||
|
@ -149,11 +185,13 @@ export class SwitchboardProgram {
|
|||
* @param mint - The native mint for the Switchboard program.
|
||||
*/
|
||||
constructor(
|
||||
program: anchor.Program,
|
||||
program: Program,
|
||||
attestationProgram: Program | undefined,
|
||||
cluster: Cluster | "localnet",
|
||||
mint: NativeMint
|
||||
) {
|
||||
this._program = program;
|
||||
this._attestationProgram = attestationProgram;
|
||||
this.cluster = cluster;
|
||||
|
||||
// Derive the state account from the seed.
|
||||
|
@ -162,6 +200,20 @@ export class SwitchboardProgram {
|
|||
publicKey: stateAccount[0].publicKey,
|
||||
bump: stateAccount[1],
|
||||
};
|
||||
|
||||
this.programState = {
|
||||
publicKey: stateAccount[0].publicKey,
|
||||
bump: stateAccount[1],
|
||||
};
|
||||
|
||||
// TODO: produce the attestation state account from the seed.
|
||||
const attestationStateAccount =
|
||||
AttestationProgramStateAccount.fromSeed(this);
|
||||
this.attestationProgramState = {
|
||||
publicKey: attestationStateAccount[0].publicKey,
|
||||
bump: attestationStateAccount[1],
|
||||
};
|
||||
|
||||
this.mint = mint;
|
||||
}
|
||||
|
||||
|
@ -183,19 +235,19 @@ export class SwitchboardProgram {
|
|||
connection: Connection,
|
||||
payerKeypair: Keypair = READ_ONLY_KEYPAIR,
|
||||
programId?: PublicKey
|
||||
): Promise<anchor.Program> {
|
||||
): Promise<Program> {
|
||||
const pid = programId ?? getSwitchboardProgramId(cluster);
|
||||
const provider = new anchor.AnchorProvider(
|
||||
const provider = new AnchorProvider(
|
||||
connection,
|
||||
// If no keypair is provided, default to dummy keypair
|
||||
new AnchorWallet(payerKeypair ?? SwitchboardProgram._readOnlyKeypair),
|
||||
{ commitment: "confirmed" }
|
||||
);
|
||||
const anchorIdl = await anchor.Program.fetchIdl(pid, provider);
|
||||
const anchorIdl = await Program.fetchIdl(pid, provider);
|
||||
if (!anchorIdl) {
|
||||
throw new Error(`Failed to find IDL for ${pid.toBase58()}`);
|
||||
}
|
||||
const program = new anchor.Program(anchorIdl, pid, provider);
|
||||
const program = new Program(anchorIdl, pid, provider);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
@ -232,21 +284,38 @@ export class SwitchboardProgram {
|
|||
static load = async (
|
||||
cluster: Cluster | "localnet",
|
||||
connection: Connection,
|
||||
payerKeypair: Keypair = READ_ONLY_KEYPAIR,
|
||||
programId: PublicKey = getSwitchboardProgramId(cluster)
|
||||
payerKeypair = READ_ONLY_KEYPAIR,
|
||||
programId = getSwitchboardProgramId(cluster),
|
||||
attestationProgramId = getSwitchboardAttestationProgramId(cluster)
|
||||
): Promise<SwitchboardProgram> => {
|
||||
const program = await SwitchboardProgram.loadAnchorProgram(
|
||||
cluster,
|
||||
connection,
|
||||
payerKeypair,
|
||||
programId
|
||||
);
|
||||
const mint = await NativeMint.load(
|
||||
program.provider as anchor.AnchorProvider
|
||||
);
|
||||
return new SwitchboardProgram(program, cluster, mint);
|
||||
const [program, attestationProgram] = await Promise.all([
|
||||
SwitchboardProgram.loadAnchorProgram(
|
||||
cluster,
|
||||
connection,
|
||||
payerKeypair,
|
||||
programId
|
||||
),
|
||||
SwitchboardProgram.loadAnchorProgram(
|
||||
cluster,
|
||||
connection,
|
||||
payerKeypair,
|
||||
attestationProgramId
|
||||
).catch((err) => {
|
||||
console.error(`Failed to load AttestationProgram`);
|
||||
console.error(err);
|
||||
return undefined;
|
||||
}),
|
||||
]);
|
||||
const mint = await NativeMint.load(program.provider as AnchorProvider);
|
||||
return new SwitchboardProgram(program, attestationProgram, cluster, mint);
|
||||
};
|
||||
|
||||
public verifyAttestation(): void {
|
||||
if (this._attestationProgram === undefined) {
|
||||
throw new Error(`Attestation Program is missing`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and initialize a {@linkcode SwitchboardProgram} connection object.
|
||||
*
|
||||
|
@ -262,7 +331,7 @@ export class SwitchboardProgram {
|
|||
* import { AnchorWallet, SwitchboardProgram, TransactionObject } from '@switchboard-xyz/solana.js';
|
||||
*
|
||||
* const connection = new Connection("https://api.mainnet-beta.solana.com");
|
||||
* const provider = new anchor.AnchorProvider(
|
||||
* const provider = new AnchorProvider(
|
||||
connection,
|
||||
new AnchorWallet(payerKeypair ?? SwitchboardProgram._readOnlyKeypair),
|
||||
{ commitment: 'confirmed' }
|
||||
|
@ -274,14 +343,16 @@ export class SwitchboardProgram {
|
|||
* ```
|
||||
*/
|
||||
static fromProvider = async (
|
||||
provider: anchor.AnchorProvider,
|
||||
programId?: PublicKey
|
||||
provider: AnchorProvider,
|
||||
programId?: PublicKey,
|
||||
attestationProgramId?: PublicKey
|
||||
): Promise<SwitchboardProgram> => {
|
||||
const payer = (provider.wallet as AnchorWallet).payer;
|
||||
const program = await SwitchboardProgram.fromConnection(
|
||||
provider.connection,
|
||||
payer,
|
||||
programId
|
||||
programId,
|
||||
attestationProgramId
|
||||
);
|
||||
return program;
|
||||
};
|
||||
|
@ -309,7 +380,8 @@ export class SwitchboardProgram {
|
|||
static fromConnection = async (
|
||||
connection: Connection,
|
||||
payer = READ_ONLY_KEYPAIR,
|
||||
programId?: PublicKey
|
||||
programId?: PublicKey,
|
||||
attestationProgramId?: PublicKey
|
||||
): Promise<SwitchboardProgram> => {
|
||||
const genesisHash = await connection.getGenesisHash();
|
||||
const cluster =
|
||||
|
@ -319,12 +391,21 @@ export class SwitchboardProgram {
|
|||
? "devnet"
|
||||
: "localnet";
|
||||
|
||||
const pid = programId ?? SBV2_MAINNET_PID;
|
||||
|
||||
const pid = programId ?? SB_V2_PID;
|
||||
const programAccountInfo = await connection.getAccountInfo(pid);
|
||||
if (programAccountInfo === null) {
|
||||
throw new Error(
|
||||
`Failed to load Switchboard at ${pid}, try manually providing a programId`
|
||||
`Failed to load Switchboard V2 program at ${pid}, try manually providing a programId`
|
||||
);
|
||||
}
|
||||
|
||||
const attestationPid = attestationProgramId ?? SB_ATTESTATION_PID;
|
||||
const attestationProgramAccountInfo = await connection.getAccountInfo(
|
||||
attestationPid
|
||||
);
|
||||
if (attestationProgramAccountInfo === null) {
|
||||
throw new Error(
|
||||
`Failed to load Switchboard Attestation program at ${attestationPid}, try manually providing a programId`
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -332,41 +413,66 @@ export class SwitchboardProgram {
|
|||
cluster,
|
||||
connection,
|
||||
payer,
|
||||
pid
|
||||
pid,
|
||||
attestationPid
|
||||
);
|
||||
return program;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard Program ID for the currently connected cluster.
|
||||
* @return The PublicKey of the Switchboard Program ID.
|
||||
* Retrieves the Switchboard V2 Program ID for the currently connected cluster.
|
||||
* @return The PublicKey of the Switchboard V2 Program ID.
|
||||
*/
|
||||
public get programId(): PublicKey {
|
||||
return this._program.programId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard Program IDL.
|
||||
* @return The IDL of the Switchboard Program.
|
||||
* Retrieves the Switchboard Attestation Program ID for the currently connected cluster.
|
||||
* @return The PublicKey of the Switchboard Attestation Program ID.
|
||||
*/
|
||||
public get idl(): anchor.Idl {
|
||||
public get attestationProgramId(): PublicKey {
|
||||
return this._attestationProgram.programId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard V2 Program IDL.
|
||||
* @return The IDL of the Switchboard V2 Program.
|
||||
*/
|
||||
public get idl(): Idl {
|
||||
return this._program.idl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard Borsh Accounts Coder.
|
||||
* @return The BorshAccountsCoder for the Switchboard Program.
|
||||
* Retrieves the Switchboard Attestation Program IDL.
|
||||
* @return The IDL of the Switchboard Attestation Program.
|
||||
*/
|
||||
public get coder(): anchor.BorshAccountsCoder {
|
||||
return new anchor.BorshAccountsCoder(this._program.idl);
|
||||
public get attestationIdl(): Idl {
|
||||
return this._program.idl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard V2 Borsh Accounts Coder.
|
||||
* @return The BorshAccountsCoder for the Switchboard V2 Program.
|
||||
*/
|
||||
public get coder(): BorshAccountsCoder {
|
||||
return new BorshAccountsCoder(this._program.idl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the Switchboard Attestatio Borsh Accounts Coder.
|
||||
* @return The BorshAccountsCoder for the Switchboard Attestation Program.
|
||||
*/
|
||||
public get attestationCoder(): BorshAccountsCoder {
|
||||
return new BorshAccountsCoder(this._attestationProgram.idl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the anchor Provider used by this program to connect with the Solana cluster.
|
||||
* @return The AnchorProvider instance for the Switchboard Program.
|
||||
*/
|
||||
public get provider(): anchor.AnchorProvider {
|
||||
return this._program.provider as anchor.AnchorProvider;
|
||||
public get provider(): AnchorProvider {
|
||||
return this._program.provider as AnchorProvider;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -374,7 +480,7 @@ export class SwitchboardProgram {
|
|||
* @return The Connection instance for the Switchboard Program.
|
||||
*/
|
||||
public get connection(): Connection {
|
||||
return this._program.provider.connection;
|
||||
return this.provider.connection;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -430,13 +536,21 @@ export class SwitchboardProgram {
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves the account namespace for the Switchboard Program.
|
||||
* @return The AccountNamespace instance for the Switchboard Program.
|
||||
* Retrieves the account namespace for the Switchboard V2 Program.
|
||||
* @return The AccountNamespace instance for the Switchboard V2 Program.
|
||||
*/
|
||||
public get account(): anchor.AccountNamespace {
|
||||
public get account(): AccountNamespace {
|
||||
return this._program.account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the account namespace for the Switchboard Attestation Program.
|
||||
* @return The AccountNamespace instance for the Switchboard Attestation Program.
|
||||
*/
|
||||
public get attestationAccount(): AccountNamespace {
|
||||
return this._attestationProgram.account;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the Switchboard Labs permissionless Queue for either devnet or mainnet. The permissionless queue has the following permissions:
|
||||
* - unpermissionedFeedsEnabled: True
|
||||
|
@ -556,6 +670,37 @@ export class SwitchboardProgram {
|
|||
return await this._program.removeEventListener(listenerId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an event listener for the specified AnchorEvent, allowing consumers to monitor the chain for events
|
||||
* emitted from Switchboard's attestation program.
|
||||
*
|
||||
* @param eventName - The name of the event to listen for.
|
||||
* @param callback - A callback function to handle the event data, slot, and signature.
|
||||
* @return A unique listener ID that can be used to remove the event listener.
|
||||
*/
|
||||
public addAttestationEventListener<EventName extends keyof SwitchboardEvents>(
|
||||
eventName: EventName,
|
||||
callback: (
|
||||
data: SwitchboardEvents[EventName],
|
||||
slot: number,
|
||||
signature: string
|
||||
) => void | Promise<void>
|
||||
): number {
|
||||
return this._attestationProgram.addEventListener(
|
||||
eventName as string,
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the event listener with the specified listener ID.
|
||||
*
|
||||
* @param listenerId - The unique ID of the event listener to be removed.
|
||||
*/
|
||||
public async removeAttestationEventListener(listenerId: number) {
|
||||
return await this._attestationProgram.removeEventListener(listenerId);
|
||||
}
|
||||
|
||||
public async signAndSendAll(
|
||||
txns: Array<TransactionObject>,
|
||||
opts: SendTransactionOptions = DEFAULT_SEND_TRANSACTION_OPTIONS,
|
||||
|
@ -588,7 +733,7 @@ export class SwitchboardProgram {
|
|||
{
|
||||
memcmp: {
|
||||
offset: 0,
|
||||
bytes: anchor.utils.bytes.bs58.encode(
|
||||
bytes: AnchorUtils.bytes.bs58.encode(
|
||||
JobAccountData.discriminator
|
||||
),
|
||||
},
|
||||
|
@ -801,7 +946,7 @@ export const isVersionedTransaction = (tx): tx is VersionedTransaction => {
|
|||
return "version" in tx;
|
||||
};
|
||||
|
||||
export class AnchorWallet implements anchor.Wallet {
|
||||
export class AnchorWallet implements Wallet {
|
||||
constructor(readonly payer: Keypair) {}
|
||||
|
||||
get publicKey(): PublicKey {
|
||||
|
@ -835,6 +980,6 @@ export class AnchorWallet implements anchor.Wallet {
|
|||
}
|
||||
|
||||
interface AccountInfoResponse {
|
||||
pubkey: anchor.web3.PublicKey;
|
||||
account: anchor.web3.AccountInfo<Buffer>;
|
||||
pubkey: PublicKey;
|
||||
account: AccountInfo<Buffer>;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { fromTxError } from "./generated/index.js";
|
||||
import * as attestationTypes from "./generated/attestation-program/index.js";
|
||||
import { fromTxError } from "./generated/oracle-program/errors/index.js";
|
||||
import { isBrowser } from "./browser.js";
|
||||
import * as errors from "./errors.js";
|
||||
import {
|
||||
|
@ -628,11 +629,22 @@ export class TransactionObject implements ITransactionObject {
|
|||
});
|
||||
} catch (error) {
|
||||
const err = fromTxError(error);
|
||||
if (err === null) {
|
||||
throw error;
|
||||
if (err) {
|
||||
if (err.logs) {
|
||||
console.error(err.logs);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
throw err;
|
||||
const attestationErr = attestationTypes.fromAttestationTxError(error);
|
||||
if (attestationErr) {
|
||||
if (attestationErr.logs) {
|
||||
console.error(attestationErr.logs);
|
||||
}
|
||||
throw attestationErr;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
SbState,
|
||||
SlidingResultAccountData,
|
||||
VrfAccountData,
|
||||
} from "../generated/index.js";
|
||||
} from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
|
||||
import { AggregatorAccount } from "./aggregatorAccount.js";
|
||||
|
|
|
@ -1,5 +1,35 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import {
|
||||
AggregatorAccountData,
|
||||
AggregatorAccountDataFields,
|
||||
AggregatorAccountDataJSON,
|
||||
} from "../generated/oracle-program/accounts/AggregatorAccountData.js";
|
||||
import {
|
||||
JobAccountData,
|
||||
JobAccountDataJSON,
|
||||
} from "../generated/oracle-program/accounts/JobAccountData.js";
|
||||
import {
|
||||
LeaseAccountData,
|
||||
LeaseAccountDataJSON,
|
||||
} from "../generated/oracle-program/accounts/LeaseAccountData.js";
|
||||
import { OracleAccountData } from "../generated/oracle-program/accounts/OracleAccountData.js";
|
||||
import {
|
||||
OracleQueueAccountData,
|
||||
OracleQueueAccountDataJSON,
|
||||
} from "../generated/oracle-program/accounts/OracleQueueAccountData.js";
|
||||
import {
|
||||
PermissionAccountData,
|
||||
PermissionAccountDataJSON,
|
||||
} from "../generated/oracle-program/accounts/PermissionAccountData.js";
|
||||
import * as ix from "../generated/oracle-program/instructions/index.js";
|
||||
import {
|
||||
AggregatorHistoryRow,
|
||||
AggregatorResolutionMode,
|
||||
AggregatorResolutionModeKind,
|
||||
BorshDecimal,
|
||||
} from "../generated/oracle-program/types/index.js";
|
||||
import { SwitchboardDecimal } from "../generated/oracle-program/types/SwitchboardDecimal.js";
|
||||
import { PermitOracleQueueUsage } from "../generated/oracle-program/types/SwitchboardPermission.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
@ -39,16 +69,16 @@ import {
|
|||
toUtf8,
|
||||
} from "@switchboard-xyz/common";
|
||||
import assert from "assert";
|
||||
import crypto from "crypto";
|
||||
import crypto, { createHash } from "crypto";
|
||||
|
||||
/**
|
||||
* Account type holding a data feed's update configuration, job accounts, and its current result.
|
||||
*
|
||||
* Data: {@linkcode types.AggregatorAccountData}
|
||||
* Data: {@linkcode AggregatorAccountData}
|
||||
*
|
||||
* Result: {@linkcode types.SwitchboardDecimal}
|
||||
* Result: {@linkcode SwitchboardDecimal}
|
||||
*
|
||||
* HistoryBuffer?: Array<{@linkcode types.AggregatorHistoryRow}>
|
||||
* HistoryBuffer?: Array<{@linkcode AggregatorHistoryRow}>
|
||||
*
|
||||
* An aggregator account belongs to a single {@linkcode QueueAccount} but can later be transferred by the aggregator's authority. In order for an {@linkcode OracleAccount} to respond to an aggregator's update request, the aggregator must initialize a {@linkcode PermissionAccount} and {@linkcode LeaseAccount}. These will need to be recreated when transferring queues.
|
||||
*
|
||||
|
@ -56,7 +86,7 @@ import crypto from "crypto";
|
|||
*
|
||||
* Optionally, an aggregator can add a history buffer to store the last N historical samples along with their update timestamp.
|
||||
*/
|
||||
export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
||||
export class AggregatorAccount extends Account<AggregatorAccountData> {
|
||||
static accountName = "AggregatorAccountData";
|
||||
|
||||
public history?: AggregatorHistoryBuffer;
|
||||
|
@ -64,12 +94,12 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
/**
|
||||
* Returns the aggregator's name buffer in a stringified format.
|
||||
*/
|
||||
public static getName = (aggregator: types.AggregatorAccountData) =>
|
||||
public static getName = (aggregator: AggregatorAccountData) =>
|
||||
toUtf8(aggregator.name);
|
||||
/**
|
||||
* Returns the aggregator's metadata buffer in a stringified format.
|
||||
*/
|
||||
public static getMetadata = (aggregator: types.AggregatorAccountData) =>
|
||||
public static getMetadata = (aggregator: AggregatorAccountData) =>
|
||||
toUtf8(aggregator.metadata);
|
||||
|
||||
public static size = 3851;
|
||||
|
@ -79,11 +109,11 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
*/
|
||||
public size = this.program.account.aggregatorAccountData.size;
|
||||
|
||||
public decode(data: Buffer): types.AggregatorAccountData {
|
||||
public decode(data: Buffer): AggregatorAccountData {
|
||||
try {
|
||||
return types.AggregatorAccountData.decode(data);
|
||||
return AggregatorAccountData.decode(data);
|
||||
} catch {
|
||||
return this.program.coder.decode<types.AggregatorAccountData>(
|
||||
return this.program.coder.decode<AggregatorAccountData>(
|
||||
AggregatorAccount.accountName,
|
||||
data
|
||||
);
|
||||
|
@ -93,10 +123,10 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
/**
|
||||
* Return an aggregator account state initialized to the default values.
|
||||
*/
|
||||
public static default(): types.AggregatorAccountData {
|
||||
public static default(): AggregatorAccountData {
|
||||
const buffer = Buffer.alloc(AggregatorAccount.size, 0);
|
||||
types.AggregatorAccountData.discriminator.copy(buffer, 0);
|
||||
return types.AggregatorAccountData.decode(buffer);
|
||||
AggregatorAccountData.discriminator.copy(buffer, 0);
|
||||
return AggregatorAccountData.decode(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,22 +134,22 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
*/
|
||||
public static createMock(
|
||||
programId: PublicKey,
|
||||
data: Partial<types.AggregatorAccountData>,
|
||||
data: Partial<AggregatorAccountData>,
|
||||
options?: {
|
||||
lamports?: number;
|
||||
rentEpoch?: number;
|
||||
}
|
||||
): AccountInfo<Buffer> {
|
||||
const fields: types.AggregatorAccountDataFields = {
|
||||
const fields: AggregatorAccountDataFields = {
|
||||
...AggregatorAccount.default(),
|
||||
...data,
|
||||
// any cleanup actions here
|
||||
};
|
||||
const state = new types.AggregatorAccountData(fields);
|
||||
const state = new AggregatorAccountData(fields);
|
||||
|
||||
const buffer = Buffer.alloc(AggregatorAccount.size, 0);
|
||||
types.AggregatorAccountData.discriminator.copy(buffer, 0);
|
||||
types.AggregatorAccountData.layout.encode(state, buffer, 8);
|
||||
AggregatorAccountData.discriminator.copy(buffer, 0);
|
||||
AggregatorAccountData.layout.encode(state, buffer, 8);
|
||||
|
||||
return {
|
||||
executable: false,
|
||||
|
@ -137,7 +167,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* @returns the websocket subscription id
|
||||
*/
|
||||
public onChange(
|
||||
callback: OnAccountChangeCallback<types.AggregatorAccountData>,
|
||||
callback: OnAccountChangeCallback<AggregatorAccountData>,
|
||||
commitment: Commitment = "confirmed"
|
||||
): number {
|
||||
return this.program.connection.onAccountChange(
|
||||
|
@ -150,10 +180,10 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.AggregatorAccountData} stored in this account.
|
||||
* Retrieve and decode the {@linkcode AggregatorAccountData} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.AggregatorAccountData> {
|
||||
const data = await types.AggregatorAccountData.fetch(
|
||||
public async loadData(): Promise<AggregatorAccountData> {
|
||||
const data = await AggregatorAccountData.fetch(
|
||||
this.program,
|
||||
this.publicKey
|
||||
);
|
||||
|
@ -174,7 +204,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
publicKey: PublicKey | string
|
||||
): Promise<[AggregatorAccount, types.AggregatorAccountData]> {
|
||||
): Promise<[AggregatorAccount, AggregatorAccountData]> {
|
||||
const account = new AggregatorAccount(
|
||||
program,
|
||||
typeof publicKey === "string" ? new PublicKey(publicKey) : publicKey
|
||||
|
@ -244,7 +274,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
);
|
||||
|
||||
ixns.push(
|
||||
types.aggregatorInit(
|
||||
ix.aggregatorInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
|
@ -257,7 +287,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
minJobResults: params.minRequiredJobResults,
|
||||
minUpdateDelaySeconds: params.minUpdateDelaySeconds,
|
||||
startAfter: new BN(params.startAfter ?? 0),
|
||||
varianceThreshold: types.SwitchboardDecimal.fromBig(
|
||||
varianceThreshold: SwitchboardDecimal.fromBig(
|
||||
new Big(params.varianceThreshold ?? 0)
|
||||
).borsh,
|
||||
forceReportPeriod: new BN(params.forceReportPeriod ?? 0),
|
||||
|
@ -275,10 +305,15 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
)
|
||||
);
|
||||
|
||||
const aggregatorInit = new TransactionObject(payer, ixns, signers, options);
|
||||
const aggregatorInitTxn = new TransactionObject(
|
||||
payer,
|
||||
ixns,
|
||||
signers,
|
||||
options
|
||||
);
|
||||
const aggregatorAccount = new AggregatorAccount(program, keypair.publicKey);
|
||||
|
||||
return [aggregatorAccount, aggregatorInit];
|
||||
return [aggregatorAccount, aggregatorInitTxn];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -462,7 +497,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
const permissionSet = permissionAccount.setInstruction(payer, {
|
||||
enable: params.enable,
|
||||
queueAuthority: params.queueAuthority,
|
||||
permission: new types.SwitchboardPermission.PermitOracleQueueUsage(),
|
||||
permission: new PermitOracleQueueUsage(),
|
||||
});
|
||||
|
||||
return [permissionSet, permissionAccount];
|
||||
|
@ -547,7 +582,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
const setQueueTxn = new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.aggregatorSetQueue(
|
||||
ix.aggregatorSetQueue(
|
||||
this.program,
|
||||
{ params: {} },
|
||||
{
|
||||
|
@ -763,7 +798,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* ```
|
||||
*/
|
||||
public static decodeLatestValue(
|
||||
aggregator: types.AggregatorAccountData
|
||||
aggregator: AggregatorAccountData
|
||||
): Big | null {
|
||||
if ((aggregator.latestConfirmedRound?.numSuccess ?? 0) === 0) {
|
||||
return null;
|
||||
|
@ -805,9 +840,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* console.log("Latest confirmed round timestamp:", latestTimestamp.toString());
|
||||
* ```
|
||||
*/
|
||||
public static decodeLatestTimestamp(
|
||||
aggregator: types.AggregatorAccountData
|
||||
): BN {
|
||||
public static decodeLatestTimestamp(aggregator: AggregatorAccountData): BN {
|
||||
if ((aggregator.latestConfirmedRound?.numSuccess ?? 0) === 0) {
|
||||
throw new Error("Aggregator currently holds no value.");
|
||||
}
|
||||
|
@ -831,7 +864,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* ```
|
||||
*/
|
||||
public static decodeConfirmedRoundResults(
|
||||
aggregator: types.AggregatorAccountData
|
||||
aggregator: AggregatorAccountData
|
||||
): Array<{ oraclePubkeys: PublicKey; value: Big }> {
|
||||
if ((aggregator.latestConfirmedRound?.numSuccess ?? 0) === 0) {
|
||||
throw new Error("Aggregator currently holds no value.");
|
||||
|
@ -864,7 +897,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* ```
|
||||
*/
|
||||
public getConfirmedRoundResults(
|
||||
aggregator: types.AggregatorAccountData
|
||||
aggregator: AggregatorAccountData
|
||||
): Array<{ oracleAccount: OracleAccount; value: Big }> {
|
||||
return AggregatorAccount.decodeConfirmedRoundResults(aggregator).map(
|
||||
(o) => {
|
||||
|
@ -902,7 +935,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
public static decodeCurrentRoundOracles(
|
||||
aggregator: types.AggregatorAccountData
|
||||
aggregator: AggregatorAccountData
|
||||
): Array<PublicKey> {
|
||||
return aggregator.currentRound.oraclePubkeysData.slice(
|
||||
0,
|
||||
|
@ -911,10 +944,8 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
public async loadCurrentRoundOracles(
|
||||
aggregator: types.AggregatorAccountData
|
||||
): Promise<
|
||||
Array<{ account: OracleAccount; state: types.OracleAccountData }>
|
||||
> {
|
||||
aggregator: AggregatorAccountData
|
||||
): Promise<Array<{ account: OracleAccount; state: OracleAccountData }>> {
|
||||
return await Promise.all(
|
||||
AggregatorAccount.decodeCurrentRoundOracles(aggregator).map(async (o) => {
|
||||
const oracleAccount = new OracleAccount(this.program, o);
|
||||
|
@ -927,15 +958,15 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
public static decodeJobPubkeys(
|
||||
aggregator: types.AggregatorAccountData
|
||||
aggregator: AggregatorAccountData
|
||||
): Array<PublicKey> {
|
||||
return aggregator.jobPubkeysData.slice(0, aggregator.jobPubkeysSize);
|
||||
}
|
||||
|
||||
public async loadJobs(aggregator: types.AggregatorAccountData): Promise<
|
||||
public async loadJobs(aggregator: AggregatorAccountData): Promise<
|
||||
Array<{
|
||||
account: JobAccount;
|
||||
state: types.JobAccountData;
|
||||
state: JobAccountData;
|
||||
job: OracleJob;
|
||||
weight: number;
|
||||
}>
|
||||
|
@ -959,7 +990,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
);
|
||||
}
|
||||
const jobAccount = new JobAccount(this.program, j.publicKey);
|
||||
const jobState: types.JobAccountData = this.program.coder.decode(
|
||||
const jobState: JobAccountData = this.program.coder.decode(
|
||||
"JobAccountData",
|
||||
j.account.data
|
||||
);
|
||||
|
@ -983,7 +1014,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
public getJobHashes(
|
||||
jobs: Array<{
|
||||
account: JobAccount;
|
||||
state: types.JobAccountData;
|
||||
state: JobAccountData;
|
||||
}>
|
||||
): Array<Buffer> {
|
||||
return jobs.map((j) => Buffer.from(new Uint8Array(j.state.hash)));
|
||||
|
@ -1020,7 +1051,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
*/
|
||||
public static verifyConfig(
|
||||
aggregator:
|
||||
| types.AggregatorAccountData
|
||||
| AggregatorAccountData
|
||||
| {
|
||||
oracleRequestBatchSize: number;
|
||||
minOracleResults: number;
|
||||
|
@ -1028,7 +1059,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
minUpdateDelaySeconds: number;
|
||||
jobPubkeysSize: number;
|
||||
},
|
||||
queue: types.OracleQueueAccountData,
|
||||
queue: OracleQueueAccountData,
|
||||
target: {
|
||||
batchSize?: number;
|
||||
minOracleResults?: number;
|
||||
|
@ -1119,7 +1150,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
*/
|
||||
public verifyConfig(
|
||||
aggregator:
|
||||
| types.AggregatorAccountData
|
||||
| AggregatorAccountData
|
||||
| {
|
||||
oracleRequestBatchSize: number;
|
||||
minOracleResults: number;
|
||||
|
@ -1127,7 +1158,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
minUpdateDelaySeconds: number;
|
||||
jobPubkeysSize: number;
|
||||
},
|
||||
queue: types.OracleQueueAccountData,
|
||||
queue: OracleQueueAccountData,
|
||||
target: {
|
||||
batchSize?: number;
|
||||
minOracleResults?: number;
|
||||
|
@ -1207,7 +1238,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
const varianceThreshold = params.varianceThreshold ?? 0;
|
||||
const setConfigIxn = types.aggregatorSetConfig(
|
||||
const setConfigIxn = ix.aggregatorSetConfig(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
|
@ -1228,8 +1259,8 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
forceReportPeriod: params.forceReportPeriod ?? null,
|
||||
varianceThreshold:
|
||||
varianceThreshold >= 0
|
||||
? new types.BorshDecimal(
|
||||
types.SwitchboardDecimal.fromBig(new Big(varianceThreshold))
|
||||
? new BorshDecimal(
|
||||
SwitchboardDecimal.fromBig(new Big(varianceThreshold))
|
||||
)
|
||||
: null,
|
||||
basePriorityFee: params.basePriorityFee ?? null,
|
||||
|
@ -1320,7 +1351,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
},
|
||||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
const setQueueIxn = types.aggregatorSetQueue(
|
||||
const setQueueIxn = ix.aggregatorSetQueue(
|
||||
this.program,
|
||||
{
|
||||
params: {},
|
||||
|
@ -1365,7 +1396,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
const authority = params.authority ? params.authority.publicKey : payer;
|
||||
const addJobIxn = types.aggregatorAddJob(
|
||||
const addJobIxn = ix.aggregatorAddJob(
|
||||
this.program,
|
||||
{ params: { weight: params.weight ?? 1 } },
|
||||
{
|
||||
|
@ -1409,7 +1440,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
return new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.aggregatorLock(
|
||||
ix.aggregatorLock(
|
||||
this.program,
|
||||
{ params: {} },
|
||||
{
|
||||
|
@ -1449,7 +1480,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
return new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.aggregatorSetAuthority(
|
||||
ix.aggregatorSetAuthority(
|
||||
this.program,
|
||||
{ params: {} },
|
||||
{
|
||||
|
@ -1538,7 +1569,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
const authority = params.authority ? params.authority.publicKey : payer;
|
||||
const removeJobIxn = types.aggregatorRemoveJob(
|
||||
const removeJobIxn = ix.aggregatorRemoveJob(
|
||||
this.program,
|
||||
{ params: { jobIdx: params.jobIdx } },
|
||||
{
|
||||
|
@ -1605,7 +1636,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
ixns.push(
|
||||
types.aggregatorOpenRound(
|
||||
ix.aggregatorOpenRound(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
|
@ -1649,6 +1680,92 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
return txnSignature;
|
||||
}
|
||||
|
||||
public quoteKeypairFromSeed(seed: PublicKey): Keypair {
|
||||
const hash = createHash("sha256");
|
||||
hash.update(Buffer.from("QuoteAccountData"));
|
||||
hash.update(seed.toBuffer());
|
||||
const kp = Keypair.fromSeed(hash.digest());
|
||||
return kp;
|
||||
}
|
||||
|
||||
public teeSaveResultInstructionSync(
|
||||
payer: PublicKey,
|
||||
params: AggregatorSaveResultSyncParams & {
|
||||
quotePubkey?: PublicKey;
|
||||
authority: Keypair;
|
||||
},
|
||||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
const [oraclePermissionAccount, oraclePermissionBump] =
|
||||
params.oraclePermission;
|
||||
|
||||
const quote =
|
||||
params.quotePubkey ??
|
||||
this.quoteKeypairFromSeed(
|
||||
params.oracles[params.oracleIdx].state.oracleAuthority
|
||||
).publicKey;
|
||||
|
||||
const saveResultIxn = ix.aggregatorTeeSaveResult(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
// oracleIdx: params.oracleIdx,
|
||||
// error: params.error ?? false,
|
||||
value: SwitchboardDecimal.fromBig(params.value).borsh,
|
||||
jobsChecksum: [...this.produceJobsHash(params.jobs).digest()],
|
||||
minResponse: SwitchboardDecimal.fromBig(params.minResponse).borsh,
|
||||
maxResponse: SwitchboardDecimal.fromBig(params.maxResponse).borsh,
|
||||
feedPermissionBump: params.permissionBump,
|
||||
oraclePermissionBump: oraclePermissionBump,
|
||||
leaseBump: params.leaseBump,
|
||||
stateBump: this.program.programState.bump,
|
||||
},
|
||||
},
|
||||
{
|
||||
aggregator: this.publicKey,
|
||||
oracle: params.oracles[params.oracleIdx].account.publicKey,
|
||||
oracleAuthority: params.oracles[params.oracleIdx].state.oracleAuthority,
|
||||
oracleQueue: params.queueAccount.publicKey,
|
||||
queueAuthority: params.queueAuthority,
|
||||
feedPermission: params.permissionAccount.publicKey,
|
||||
oraclePermission: oraclePermissionAccount.publicKey,
|
||||
lease: params.leaseAccount.publicKey,
|
||||
escrow: params.leaseEscrow,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
programState: this.program.programState.publicKey,
|
||||
historyBuffer: params.historyBuffer ?? this.publicKey,
|
||||
mint: this.program.mint.address,
|
||||
slider: this.slidingWindowKey,
|
||||
quote: quote,
|
||||
rewardWallet: this.program.mint.getAssociatedAddress(payer),
|
||||
payer: payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
);
|
||||
|
||||
const remainingAccounts: Array<PublicKey> = [];
|
||||
params.oracles.forEach((oracle) =>
|
||||
remainingAccounts.push(oracle.account.publicKey)
|
||||
);
|
||||
params.oracles.forEach((oracle) =>
|
||||
remainingAccounts.push(oracle.state.tokenAccount)
|
||||
);
|
||||
remainingAccounts.push(this.slidingWindowKey);
|
||||
|
||||
saveResultIxn.keys.push(
|
||||
...remainingAccounts.map((pubkey): AccountMeta => {
|
||||
return { isSigner: false, isWritable: true, pubkey };
|
||||
})
|
||||
);
|
||||
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
[saveResultIxn],
|
||||
[params.authority],
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
public saveResultInstructionSync(
|
||||
payer: PublicKey,
|
||||
params: AggregatorSaveResultSyncParams,
|
||||
|
@ -1661,18 +1778,16 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
throw new Error("Failed to find oracle in current round");
|
||||
}
|
||||
|
||||
const saveResultIxn = types.aggregatorSaveResult(
|
||||
const saveResultIxn = ix.aggregatorSaveResult(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
oracleIdx: params.oracleIdx,
|
||||
error: params.error ?? false,
|
||||
value: types.SwitchboardDecimal.fromBig(params.value).borsh,
|
||||
value: SwitchboardDecimal.fromBig(params.value).borsh,
|
||||
jobsChecksum: [...this.produceJobsHash(params.jobs).digest()],
|
||||
minResponse: types.SwitchboardDecimal.fromBig(params.minResponse)
|
||||
.borsh,
|
||||
maxResponse: types.SwitchboardDecimal.fromBig(params.maxResponse)
|
||||
.borsh,
|
||||
minResponse: SwitchboardDecimal.fromBig(params.minResponse).borsh,
|
||||
maxResponse: SwitchboardDecimal.fromBig(params.maxResponse).borsh,
|
||||
feedPermissionBump: params.permissionBump,
|
||||
oraclePermissionBump: oraclePermissionBump,
|
||||
leaseBump: params.leaseBump,
|
||||
|
@ -1801,9 +1916,9 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
public async fetchAccounts(
|
||||
_aggregator?: types.AggregatorAccountData,
|
||||
_aggregator?: AggregatorAccountData,
|
||||
_queueAccount?: QueueAccount,
|
||||
_queue?: types.OracleQueueAccountData,
|
||||
_queue?: OracleQueueAccountData,
|
||||
commitment: Commitment = "confirmed"
|
||||
): Promise<AggregatorAccounts> {
|
||||
const aggregator = _aggregator ?? (await this.loadData());
|
||||
|
@ -1841,7 +1956,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
`PermissionAccount has not been created yet for this aggregator`
|
||||
);
|
||||
}
|
||||
const permission = types.PermissionAccountData.decode(
|
||||
const permission = PermissionAccountData.decode(
|
||||
permissionAccountInfo.account.data
|
||||
);
|
||||
|
||||
|
@ -1851,7 +1966,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
`LeaseAccount has not been created yet for this aggregator`
|
||||
);
|
||||
}
|
||||
const lease = types.LeaseAccountData.decode(leaseAccountInfo.account.data);
|
||||
const lease = LeaseAccountData.decode(leaseAccountInfo.account.data);
|
||||
|
||||
const leaseEscrowAccountInfo = accountInfos.shift();
|
||||
if (!leaseEscrowAccountInfo || !leaseEscrowAccountInfo.account) {
|
||||
|
@ -1866,14 +1981,14 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
|
||||
const jobs: Array<{
|
||||
publicKey: PublicKey;
|
||||
data: types.JobAccountData;
|
||||
data: JobAccountData;
|
||||
tasks: Array<OracleJob.ITask>;
|
||||
}> = [];
|
||||
accountInfos.map((accountInfo) => {
|
||||
if (!accountInfo || !accountInfo.account) {
|
||||
throw new Error(`Failed to fetch JobAccount`);
|
||||
}
|
||||
const job = types.JobAccountData.decode(accountInfo.account.data);
|
||||
const job = JobAccountData.decode(accountInfo.account.data);
|
||||
const oracleJob = OracleJob.decodeDelimited(job.data);
|
||||
jobs.push({
|
||||
publicKey: accountInfo.publicKey,
|
||||
|
@ -1907,9 +2022,9 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
|
||||
public async toAccountsJSON(
|
||||
_aggregator?: types.AggregatorAccountData,
|
||||
_aggregator?: AggregatorAccountData,
|
||||
_queueAccount?: QueueAccount,
|
||||
_queue?: types.OracleQueueAccountData
|
||||
_queue?: OracleQueueAccountData
|
||||
): Promise<AggregatorAccountsJSON> {
|
||||
const accounts = await this.fetchAccounts(
|
||||
_aggregator,
|
||||
|
@ -1949,14 +2064,14 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
payer: PublicKey,
|
||||
params: {
|
||||
authority?: Keypair;
|
||||
mode: types.AggregatorResolutionModeKind;
|
||||
mode: AggregatorResolutionModeKind;
|
||||
},
|
||||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.aggregatorSetResolutionMode(
|
||||
ix.aggregatorSetResolutionMode(
|
||||
this.program,
|
||||
{
|
||||
params: { mode: params.mode.discriminator },
|
||||
|
@ -1978,7 +2093,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
async setSlidingWindow(
|
||||
params: {
|
||||
authority?: Keypair;
|
||||
mode: types.AggregatorResolutionModeKind;
|
||||
mode: AggregatorResolutionModeKind;
|
||||
},
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
|
@ -1993,11 +2108,11 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
|
||||
async openRoundAndAwaitResult(
|
||||
params?: { payoutWallet?: PublicKey } & {
|
||||
aggregator?: types.AggregatorAccountData;
|
||||
aggregator?: AggregatorAccountData;
|
||||
},
|
||||
timeout = 30000,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[types.AggregatorAccountData, TransactionSignature | undefined]> {
|
||||
): Promise<[AggregatorAccountData, TransactionSignature | undefined]> {
|
||||
const aggregator = params?.aggregator ?? (await this.loadData());
|
||||
const currentRoundOpenSlot = aggregator.latestConfirmedRound.roundOpenSlot;
|
||||
|
||||
|
@ -2010,31 +2125,28 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
};
|
||||
|
||||
const statePromise: Promise<types.AggregatorAccountData> =
|
||||
promiseWithTimeout(
|
||||
timeout,
|
||||
new Promise(
|
||||
(resolve: (result: types.AggregatorAccountData) => void) => {
|
||||
ws = this.onChange((aggregator) => {
|
||||
// if confirmed round slot larger than last open slot
|
||||
// AND sliding window mode or sufficient oracle results
|
||||
if (
|
||||
aggregator.latestConfirmedRound.roundOpenSlot.gt(
|
||||
currentRoundOpenSlot
|
||||
) &&
|
||||
(aggregator.resolutionMode.kind ===
|
||||
types.AggregatorResolutionMode.ModeSlidingResolution.kind ||
|
||||
(aggregator.latestConfirmedRound.numSuccess ?? 0) >=
|
||||
aggregator.minOracleResults)
|
||||
) {
|
||||
resolve(aggregator);
|
||||
}
|
||||
});
|
||||
const statePromise: Promise<AggregatorAccountData> = promiseWithTimeout(
|
||||
timeout,
|
||||
new Promise((resolve: (result: AggregatorAccountData) => void) => {
|
||||
ws = this.onChange((aggregator) => {
|
||||
// if confirmed round slot larger than last open slot
|
||||
// AND sliding window mode or sufficient oracle results
|
||||
if (
|
||||
aggregator.latestConfirmedRound.roundOpenSlot.gt(
|
||||
currentRoundOpenSlot
|
||||
) &&
|
||||
(aggregator.resolutionMode.kind ===
|
||||
AggregatorResolutionMode.ModeSlidingResolution.kind ||
|
||||
(aggregator.latestConfirmedRound.numSuccess ?? 0) >=
|
||||
aggregator.minOracleResults)
|
||||
) {
|
||||
resolve(aggregator);
|
||||
}
|
||||
)
|
||||
).finally(async () => {
|
||||
await closeWebsocket();
|
||||
});
|
||||
});
|
||||
})
|
||||
).finally(async () => {
|
||||
await closeWebsocket();
|
||||
});
|
||||
|
||||
const openRoundSignature = await this.openRound(params, options).catch(
|
||||
async (error) => {
|
||||
|
@ -2061,24 +2173,22 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
async nextRound(
|
||||
roundOpenSlot?: BN,
|
||||
timeout = 30000
|
||||
): Promise<types.AggregatorAccountData> {
|
||||
): Promise<AggregatorAccountData> {
|
||||
const slot =
|
||||
roundOpenSlot ?? (await this.loadData()).currentRound.roundOpenSlot;
|
||||
let ws: number | undefined;
|
||||
|
||||
let result: types.AggregatorAccountData;
|
||||
let result: AggregatorAccountData;
|
||||
try {
|
||||
result = await promiseWithTimeout(
|
||||
timeout,
|
||||
new Promise(
|
||||
(resolve: (result: types.AggregatorAccountData) => void) => {
|
||||
ws = this.onChange((aggregator) => {
|
||||
if (aggregator.latestConfirmedRound.roundOpenSlot.eq(slot)) {
|
||||
resolve(aggregator);
|
||||
}
|
||||
});
|
||||
}
|
||||
)
|
||||
new Promise((resolve: (result: AggregatorAccountData) => void) => {
|
||||
ws = this.onChange((aggregator) => {
|
||||
if (aggregator.latestConfirmedRound.roundOpenSlot.eq(slot)) {
|
||||
resolve(aggregator);
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
if (ws) {
|
||||
|
@ -2096,7 +2206,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
async loadHistory(
|
||||
startTimestamp?: number,
|
||||
endTimestamp?: number
|
||||
): Promise<Array<types.AggregatorHistoryRow>> {
|
||||
): Promise<Array<AggregatorHistoryRow>> {
|
||||
if (!this.history) {
|
||||
this.history = new AggregatorHistoryBuffer(
|
||||
this.program,
|
||||
|
@ -2116,12 +2226,12 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
): Promise<
|
||||
Array<{
|
||||
account: AggregatorAccount;
|
||||
data: types.AggregatorAccountData;
|
||||
data: AggregatorAccountData;
|
||||
}>
|
||||
> {
|
||||
const aggregators: Array<{
|
||||
account: AggregatorAccount;
|
||||
data: types.AggregatorAccountData;
|
||||
data: AggregatorAccountData;
|
||||
}> = [];
|
||||
|
||||
const accountInfos = await anchor.utils.rpc.getMultipleAccounts(
|
||||
|
@ -2136,9 +2246,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
}
|
||||
try {
|
||||
const account = new AggregatorAccount(program, accountInfo.publicKey);
|
||||
const data = types.AggregatorAccountData.decode(
|
||||
accountInfo.account.data
|
||||
);
|
||||
const data = AggregatorAccountData.decode(accountInfo.account.data);
|
||||
aggregators.push({ account, data });
|
||||
// eslint-disable-next-line no-empty
|
||||
} catch {}
|
||||
|
@ -2160,7 +2268,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
* @returns the solana priority fee to include in the save_result action
|
||||
*/
|
||||
public static calculatePriorityFee(
|
||||
aggregator: types.AggregatorAccountData,
|
||||
aggregator: AggregatorAccountData,
|
||||
timestamp = Math.round(Date.now() / 1000),
|
||||
baseFee = 0 // base compute unit price
|
||||
): number {
|
||||
|
@ -2586,21 +2694,21 @@ export interface AggregatorSaveResultParams {
|
|||
/**
|
||||
* List of parsed oracles.
|
||||
*/
|
||||
oracles: Array<types.OracleAccountData>;
|
||||
oracles: Array<OracleAccountData>;
|
||||
}
|
||||
|
||||
export type AggregatorAccountsJSON = types.AggregatorAccountDataJSON & {
|
||||
export type AggregatorAccountsJSON = AggregatorAccountDataJSON & {
|
||||
publicKey: PublicKey;
|
||||
queue: types.OracleQueueAccountDataJSON & { publicKey: PublicKey };
|
||||
permission: types.PermissionAccountDataJSON & {
|
||||
queue: OracleQueueAccountDataJSON & { publicKey: PublicKey };
|
||||
permission: PermissionAccountDataJSON & {
|
||||
bump: number;
|
||||
publicKey: PublicKey;
|
||||
};
|
||||
lease: types.LeaseAccountDataJSON & { bump: number; publicKey: PublicKey } & {
|
||||
lease: LeaseAccountDataJSON & { bump: number; publicKey: PublicKey } & {
|
||||
balance: number;
|
||||
};
|
||||
jobs: Array<
|
||||
types.JobAccountDataJSON & {
|
||||
JobAccountDataJSON & {
|
||||
publicKey: PublicKey;
|
||||
tasks: Array<OracleJob.ITask>;
|
||||
}
|
||||
|
@ -2609,26 +2717,26 @@ export type AggregatorAccountsJSON = types.AggregatorAccountDataJSON & {
|
|||
export type AggregatorAccounts = {
|
||||
aggregator: {
|
||||
publicKey: PublicKey;
|
||||
data: types.AggregatorAccountData;
|
||||
data: AggregatorAccountData;
|
||||
};
|
||||
queue: {
|
||||
publicKey: PublicKey;
|
||||
data: types.OracleQueueAccountData;
|
||||
data: OracleQueueAccountData;
|
||||
};
|
||||
permission: {
|
||||
publicKey: PublicKey;
|
||||
bump: number;
|
||||
data: types.PermissionAccountData;
|
||||
data: PermissionAccountData;
|
||||
};
|
||||
lease: {
|
||||
publicKey: PublicKey;
|
||||
bump: number;
|
||||
balance: number;
|
||||
data: types.LeaseAccountData;
|
||||
data: LeaseAccountData;
|
||||
};
|
||||
jobs: Array<{
|
||||
publicKey: PublicKey;
|
||||
data: types.JobAccountData;
|
||||
data: JobAccountData;
|
||||
tasks: Array<OracleJob.ITask>;
|
||||
}>;
|
||||
};
|
||||
|
@ -2651,13 +2759,13 @@ export type SaveResultResponse = {
|
|||
};
|
||||
|
||||
export type SaveResultAccounts = AggregatorPdaAccounts & {
|
||||
aggregator: types.AggregatorAccountData;
|
||||
aggregator: AggregatorAccountData;
|
||||
// queue
|
||||
queueAccount: QueueAccount;
|
||||
queueAuthority: PublicKey;
|
||||
// oracle
|
||||
oraclePermission: [PermissionAccount, number];
|
||||
oracles: Array<{ account: OracleAccount; state: types.OracleAccountData }>;
|
||||
oracles: Array<{ account: OracleAccount; state: OracleAccountData }>;
|
||||
oracleIdx: number;
|
||||
// history
|
||||
historyBuffer?: PublicKey;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -0,0 +1,232 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/attestation-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
TransactionObject,
|
||||
TransactionObjectOptions,
|
||||
} from "../TransactionObject.js";
|
||||
|
||||
import { Account } from "./account.js";
|
||||
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Parameters for initializing an {@linkcode AttestationPermissionAccount}
|
||||
*/
|
||||
export interface AttestationPermissionAccountInitParams {
|
||||
granter: PublicKey;
|
||||
grantee: PublicKey;
|
||||
authority?: PublicKey;
|
||||
}
|
||||
/**
|
||||
* Parameters for setting the permissions of a {@linkcode AttestationPermissionAccount}
|
||||
*/
|
||||
export interface AttestationPermissionSetParams {
|
||||
enable: boolean;
|
||||
/**
|
||||
* The {@linkcode types.SwitchboardPermission} to set for the grantee.
|
||||
*/
|
||||
permission: types.SwitchboardAttestationPermissionKind;
|
||||
/**
|
||||
* The authority for the queue
|
||||
*
|
||||
* @default payer
|
||||
*/
|
||||
queueAuthority?: Keypair;
|
||||
|
||||
queue: PublicKey;
|
||||
node: PublicKey;
|
||||
}
|
||||
/**
|
||||
* Account type dictating the level of permissions between a granter and a grantee.
|
||||
*
|
||||
* Data: {@linkcode types.AttestationPermissionAccountData}
|
||||
*/
|
||||
export class AttestationPermissionAccount extends Account<types.AttestationPermissionAccountData> {
|
||||
static accountName = "AttestationPermissionAccountData";
|
||||
|
||||
/**
|
||||
* Load an existing PermissionAccount with its current on-chain state
|
||||
*/
|
||||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
authority: PublicKey | string,
|
||||
granter: PublicKey | string,
|
||||
grantee: PublicKey | string
|
||||
): Promise<
|
||||
[
|
||||
AttestationPermissionAccount,
|
||||
types.AttestationPermissionAccountData,
|
||||
number
|
||||
]
|
||||
> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const [account, bump] = AttestationPermissionAccount.fromSeed(
|
||||
program,
|
||||
typeof authority === "string" ? new PublicKey(authority) : authority,
|
||||
typeof granter === "string" ? new PublicKey(granter) : granter,
|
||||
typeof grantee === "string" ? new PublicKey(grantee) : grantee
|
||||
);
|
||||
const state = await account.loadData();
|
||||
return [account, state, bump];
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads an AttestationPermissionAccount from the expected PDA seed format.
|
||||
*
|
||||
* @param program The Switchboard program for the current connection.
|
||||
* @param authority The authority pubkey to be incorporated into the account seed.
|
||||
* @param granter The granter pubkey to be incorporated into the account seed.
|
||||
* @param grantee The grantee pubkey to be incorporated into the account seed.
|
||||
*
|
||||
* @return AttestationPermissionAccount and PDA bump.
|
||||
*/
|
||||
public static fromSeed(
|
||||
program: SwitchboardProgram,
|
||||
authority: PublicKey,
|
||||
granter: PublicKey,
|
||||
grantee: PublicKey
|
||||
): [AttestationPermissionAccount, number] {
|
||||
const [publicKey, bump] = PublicKey.findProgramAddressSync(
|
||||
[
|
||||
Buffer.from("PermissionAccountData"),
|
||||
authority.toBytes(),
|
||||
granter.toBytes(),
|
||||
grantee.toBytes(),
|
||||
],
|
||||
program.attestationProgramId
|
||||
);
|
||||
return [new AttestationPermissionAccount(program, publicKey), bump];
|
||||
}
|
||||
|
||||
public static createInstruction(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey,
|
||||
params: AttestationPermissionAccountInitParams,
|
||||
options?: TransactionObjectOptions
|
||||
): [AttestationPermissionAccount, TransactionObject] {
|
||||
program.verifyAttestation();
|
||||
|
||||
const authority = params.authority ?? payer;
|
||||
|
||||
const [account] = AttestationPermissionAccount.fromSeed(
|
||||
program,
|
||||
authority,
|
||||
params.granter,
|
||||
params.grantee
|
||||
);
|
||||
|
||||
const instruction = types.attestationPermissionInit(
|
||||
program,
|
||||
{ params: {} },
|
||||
{
|
||||
permission: account.publicKey,
|
||||
attestationQueue: params.granter,
|
||||
node: params.grantee,
|
||||
authority,
|
||||
payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
);
|
||||
|
||||
return [account, new TransactionObject(payer, [instruction], [], options)];
|
||||
}
|
||||
|
||||
public static async create(
|
||||
program: SwitchboardProgram,
|
||||
params: AttestationPermissionAccountInitParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[AttestationPermissionAccount, TransactionSignature]> {
|
||||
const [account, txnObject] = this.createInstruction(
|
||||
program,
|
||||
program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
const txSignature = await program.signAndSend(txnObject, options);
|
||||
return [account, txSignature];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of an on-chain {@linkcode AttestationPermissionAccount}.
|
||||
*/
|
||||
public readonly size =
|
||||
this.program.attestationAccount.attestationPermissionAccountData.size;
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.AttestationPermissionAccountData} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.AttestationPermissionAccountData> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const data = await types.AttestationPermissionAccountData.fetch(
|
||||
this.program,
|
||||
this.publicKey
|
||||
);
|
||||
if (data) return data;
|
||||
throw new errors.AccountNotFoundError(
|
||||
"Permissions (Attestation)",
|
||||
this.publicKey
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces the instruction to set the permission in the AttestationPermissionAccount
|
||||
*/
|
||||
public setInstruction(
|
||||
payer: PublicKey,
|
||||
params: AttestationPermissionSetParams,
|
||||
options?: TransactionObjectOptions
|
||||
): TransactionObject {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
// const data = await this.loadData();
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.attestationPermissionSet(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
permission: params.permission.discriminator,
|
||||
enable: params.enable,
|
||||
},
|
||||
},
|
||||
{
|
||||
permission: this.publicKey,
|
||||
authority: params.queueAuthority
|
||||
? params.queueAuthority.publicKey
|
||||
: payer,
|
||||
attestationQueue: params.queue,
|
||||
node: params.node,
|
||||
}
|
||||
),
|
||||
],
|
||||
params.queueAuthority ? [params.queueAuthority] : [],
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the permission in the AttestationPermissionAccount
|
||||
*/
|
||||
public async set(
|
||||
params: AttestationPermissionSetParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<string> {
|
||||
const setTxn = await this.setInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
const txnSignature = await this.program.signAndSend(setTxn, options);
|
||||
return txnSignature;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/attestation-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import { TransactionObject } from "../TransactionObject.js";
|
||||
|
||||
import { Account } from "./account.js";
|
||||
|
||||
import {
|
||||
AccountInfo,
|
||||
LAMPORTS_PER_SOL,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Account type representing Switchboard global program state.
|
||||
*
|
||||
* Data: {@linkcode types.State}
|
||||
*/
|
||||
export class AttestationProgramStateAccount extends Account<types.State> {
|
||||
static accountName = "State";
|
||||
|
||||
public static size = 1128;
|
||||
|
||||
/**
|
||||
* @return account size of the global {@linkcode AttestationProgramStateAccount}.
|
||||
*/
|
||||
public readonly size = this.program.account.sbState.size;
|
||||
|
||||
/**
|
||||
* Return a program state account state initialized to the default values.
|
||||
*/
|
||||
public static default(): types.State {
|
||||
const buffer = Buffer.alloc(AttestationProgramStateAccount.size, 0);
|
||||
types.State.discriminator.copy(buffer, 0);
|
||||
return types.State.decode(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock account info for a given program state config. Useful for test integrations.
|
||||
*/
|
||||
public static createMock(
|
||||
programId: PublicKey,
|
||||
data: Partial<types.State>,
|
||||
options?: {
|
||||
lamports?: number;
|
||||
rentEpoch?: number;
|
||||
}
|
||||
): AccountInfo<Buffer> {
|
||||
const fields: types.StateFields = {
|
||||
...AttestationProgramStateAccount.default(),
|
||||
...data,
|
||||
// any cleanup actions here
|
||||
};
|
||||
const state = new types.State(fields);
|
||||
|
||||
const buffer = Buffer.alloc(AttestationProgramStateAccount.size, 0);
|
||||
types.State.discriminator.copy(buffer, 0);
|
||||
types.State.layout.encode(state, buffer, 8);
|
||||
|
||||
return {
|
||||
executable: false,
|
||||
owner: programId,
|
||||
lamports: options?.lamports ?? 1 * LAMPORTS_PER_SOL,
|
||||
data: buffer,
|
||||
rentEpoch: options?.rentEpoch ?? 0,
|
||||
};
|
||||
}
|
||||
|
||||
/** Load the AttestationProgramStateAccount with its current on-chain state */
|
||||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
publicKey: PublicKey | string
|
||||
): Promise<[AttestationProgramStateAccount, types.State]> {
|
||||
const account = new AttestationProgramStateAccount(
|
||||
program,
|
||||
typeof publicKey === "string" ? new PublicKey(publicKey) : publicKey
|
||||
);
|
||||
const state = await account.loadData();
|
||||
return [account, state];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.State} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.State> {
|
||||
const data = await types.State.fetch(this.program, this.publicKey);
|
||||
if (data === null)
|
||||
throw new errors.AccountNotFoundError(
|
||||
"Attestation Program State",
|
||||
this.publicKey
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the {@linkcode AttestationProgramStateAccount}, creates it if it doesn't exist;
|
||||
*/
|
||||
static async getOrCreate(
|
||||
program: SwitchboardProgram
|
||||
): Promise<
|
||||
[AttestationProgramStateAccount, number, TransactionSignature | undefined]
|
||||
> {
|
||||
const [account, bump, txn] =
|
||||
await AttestationProgramStateAccount.getOrCreateInstructions(
|
||||
program,
|
||||
program.walletPubkey
|
||||
);
|
||||
|
||||
if (txn) {
|
||||
const txnSignature = await program.signAndSend(txn);
|
||||
return [account, bump, txnSignature];
|
||||
}
|
||||
|
||||
return [account, bump, undefined];
|
||||
}
|
||||
|
||||
static async getOrCreateInstructions(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey
|
||||
): Promise<
|
||||
[AttestationProgramStateAccount, number, TransactionObject | undefined]
|
||||
> {
|
||||
const [account, bump] = AttestationProgramStateAccount.fromSeed(program);
|
||||
|
||||
try {
|
||||
await account.loadData();
|
||||
return [account, bump, undefined];
|
||||
} catch (e) {
|
||||
const stateInit = types.stateInit(
|
||||
program,
|
||||
{ params: {} },
|
||||
{
|
||||
state: account.publicKey,
|
||||
payer: payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
);
|
||||
|
||||
const programInit = new TransactionObject(payer, [stateInit], []);
|
||||
|
||||
return [account, bump, programInit];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the {@linkcode AttestationProgramStateAccount} from the static seed from which it was generated.
|
||||
* @return AttestationProgramStateAccount and PDA bump tuple.
|
||||
*/
|
||||
public static fromSeed(
|
||||
program: SwitchboardProgram
|
||||
): [AttestationProgramStateAccount, number] {
|
||||
const [publicKey, bump] = PublicKey.findProgramAddressSync(
|
||||
[Buffer.from("STATE")],
|
||||
program.attestationProgramId
|
||||
);
|
||||
return [new AttestationProgramStateAccount(program, publicKey), bump];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,536 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/attestation-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
TransactionObject,
|
||||
TransactionObjectOptions,
|
||||
} from "../TransactionObject.js";
|
||||
import { RawBuffer } from "../types.js";
|
||||
import { parseMrEnclave, parseRawBuffer } from "../utils.js";
|
||||
|
||||
import { Account } from "./account.js";
|
||||
import {
|
||||
AttestationPermissionAccount,
|
||||
AttestationPermissionSetParams,
|
||||
} from "./attestationPermissionAccount.js";
|
||||
import { QuoteAccount, QuoteAccountInitParams } from "./quoteAccount.js";
|
||||
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
/**
|
||||
* Parameters for initializing an {@linkcode QueueAccount}
|
||||
*/
|
||||
export interface AttestationQueueAccountInitParams {
|
||||
/**
|
||||
* Rewards to provide oracles and round openers on this queue.
|
||||
*/
|
||||
reward: number;
|
||||
/**
|
||||
* @TODO: document this param
|
||||
*/
|
||||
allowAuthorityOverrideAfter: number;
|
||||
/**
|
||||
* @TODO: document this param
|
||||
*/
|
||||
maxQuoteVerificationAge: number;
|
||||
/**
|
||||
* A flag indicating whether usage authority is required to heartbeat.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
requireAuthorityHeartbeatPermission: boolean;
|
||||
/**
|
||||
* A flag indicating whether usage permissions are required.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
requireUsagePermissions: boolean;
|
||||
/**
|
||||
* Time period (in seconds) we should remove an oracle after if no response.
|
||||
*
|
||||
* @default 180
|
||||
*/
|
||||
nodeTimeout?: number;
|
||||
/**
|
||||
* A keypair to be used to address this account
|
||||
*
|
||||
* @default Keypair.generate()
|
||||
*/
|
||||
keypair?: Keypair;
|
||||
/**
|
||||
* An authority to be used to control this account.
|
||||
*
|
||||
* @default payer
|
||||
*/
|
||||
authority?: Keypair;
|
||||
}
|
||||
/**
|
||||
* Parameters for an {@linkcode types.queueAddMrEnclave} instruction.
|
||||
*/
|
||||
export interface AttestationQueueAddMrEnclaveParams {
|
||||
mrEnclave: RawBuffer;
|
||||
authority?: Keypair;
|
||||
}
|
||||
/**
|
||||
* Parameters for an {@linkcode types.queueRemoveMrEnclave} instruction.
|
||||
*/
|
||||
export interface AttestationQueueRemoveMrEnclaveParams {
|
||||
mrEnclave: RawBuffer;
|
||||
authority?: Keypair;
|
||||
}
|
||||
|
||||
export type CreateQueueQuoteParams = Omit<
|
||||
QuoteAccountInitParams,
|
||||
"queueAccount"
|
||||
> &
|
||||
Partial<AttestationPermissionSetParams> & {
|
||||
queueAuthorityPubkey?: PublicKey;
|
||||
} & { createPermissions?: boolean };
|
||||
|
||||
/**
|
||||
* Account type representing an oracle queue's configuration along with a buffer account holding a
|
||||
* list of oracles that are actively heartbeating.
|
||||
*
|
||||
* A QueueAccount is responsible for allocating update requests to it's round robin queue of
|
||||
* {@linkcode OracleAccount}'s.
|
||||
*
|
||||
* Data: {@linkcode types.AttestationQueueAccountData}
|
||||
*
|
||||
* Buffer: {@linkcode QueueDataBuffer}
|
||||
*/
|
||||
export class AttestationQueueAccount extends Account<types.AttestationQueueAccountData> {
|
||||
static accountName = "AttestationQueueAccountData";
|
||||
|
||||
/**
|
||||
* Get the size of an {@linkcode QueueAccount} on-chain.
|
||||
*/
|
||||
public readonly size =
|
||||
this.program.attestationAccount.attestationQueueAccountData.size;
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.PermissionAccountData} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.AttestationQueueAccountData> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const data = await types.AttestationQueueAccountData.fetch(
|
||||
this.program,
|
||||
this.publicKey
|
||||
);
|
||||
if (data) return data;
|
||||
throw new errors.AccountNotFoundError("AttestationQueue", this.publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an existing {@linkcode AttestationQueueAccount} with its current on-chain state
|
||||
*/
|
||||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey | string
|
||||
): Promise<[AttestationQueueAccount, types.AttestationQueueAccountData]> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const queueAccount = new AttestationQueueAccount(program, address);
|
||||
const state = await queueAccount.loadData();
|
||||
return [queueAccount, state];
|
||||
}
|
||||
|
||||
public static createInstruction(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey,
|
||||
params: AttestationQueueAccountInitParams,
|
||||
options?: TransactionObjectOptions
|
||||
): [AttestationQueueAccount, TransactionObject] {
|
||||
program.verifyAttestation();
|
||||
|
||||
const queueKeypair = params.keypair ?? Keypair.generate();
|
||||
program.verifyNewKeypair(queueKeypair);
|
||||
|
||||
const instruction = types.attestationQueueInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
reward: params.reward,
|
||||
allowAuthorityOverrideAfter: params.allowAuthorityOverrideAfter,
|
||||
maxQuoteVerificationAge: params.maxQuoteVerificationAge,
|
||||
nodeTimeout: params.nodeTimeout ?? 180,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
params.requireAuthorityHeartbeatPermission ?? false,
|
||||
requireUsagePermissions: params.requireUsagePermissions ?? false,
|
||||
},
|
||||
},
|
||||
{
|
||||
queue: queueKeypair.publicKey,
|
||||
authority: params.authority ? params.authority.publicKey : payer,
|
||||
payer: payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
);
|
||||
return [
|
||||
new AttestationQueueAccount(program, queueKeypair.publicKey),
|
||||
new TransactionObject(payer, [instruction], [queueKeypair], options),
|
||||
];
|
||||
}
|
||||
|
||||
public static async create(
|
||||
program: SwitchboardProgram,
|
||||
params: AttestationQueueAccountInitParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[AttestationQueueAccount, TransactionSignature]> {
|
||||
const [account, txnObject] = this.createInstruction(
|
||||
program,
|
||||
program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
return [account, await program.signAndSend(txnObject, options)];
|
||||
}
|
||||
|
||||
public async createQuoteInstruction(
|
||||
payer: PublicKey,
|
||||
params: CreateQueueQuoteParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[QuoteAccount, TransactionObject]> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const authority = params.authority ?? payer;
|
||||
|
||||
const queueAuthority =
|
||||
params.queueAuthorityPubkey ?? (await this.loadData()).authority;
|
||||
|
||||
const [quoteAccount, quoteInit] = await QuoteAccount.createInstruction(
|
||||
this.program,
|
||||
payer,
|
||||
{ ...params, queueAccount: this, authority },
|
||||
options
|
||||
);
|
||||
|
||||
if (!params.createPermissions && !params.enable) {
|
||||
return [quoteAccount, quoteInit];
|
||||
}
|
||||
|
||||
const [permissionAccount, permissionInit] =
|
||||
AttestationPermissionAccount.createInstruction(
|
||||
this.program,
|
||||
payer,
|
||||
{
|
||||
granter: this.publicKey,
|
||||
grantee: quoteAccount.publicKey,
|
||||
authority: queueAuthority,
|
||||
},
|
||||
options
|
||||
);
|
||||
|
||||
if (params.enable) {
|
||||
const permissionSet = permissionAccount.setInstruction(payer, {
|
||||
enable: true,
|
||||
permission:
|
||||
new types.SwitchboardAttestationPermission.PermitNodeheartbeat(),
|
||||
queue: this.publicKey,
|
||||
node: quoteAccount.publicKey,
|
||||
});
|
||||
permissionInit.combine(permissionSet);
|
||||
}
|
||||
|
||||
return [quoteAccount, quoteInit.combine(permissionInit)];
|
||||
}
|
||||
|
||||
public async createQuote(
|
||||
params: CreateQueueQuoteParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[QuoteAccount, TransactionSignature]> {
|
||||
const [account, txnObject] = await this.createQuoteInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
return [account, await this.program.signAndSend(txnObject, options)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of an enclave in an array and return -1 if not found
|
||||
*/
|
||||
public static findEnclaveIdx(
|
||||
enclaves: Array<Uint8Array>,
|
||||
enclave: Uint8Array
|
||||
): number {
|
||||
for (const [n, e] of enclaves.entries()) {
|
||||
if (Buffer.compare(e, enclave) === 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public async addMrEnclaveInstruction(
|
||||
payer: PublicKey,
|
||||
params: AttestationQueueAddMrEnclaveParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const authority = params.authority?.publicKey ?? payer;
|
||||
const signers = params.authority ? [params.authority] : [];
|
||||
const instruction = types.attestationQueueAddMrEnclave(
|
||||
this.program,
|
||||
{ params: { mrEnclave: Array.from(parseMrEnclave(params.mrEnclave)) } },
|
||||
{ authority, queue: this.publicKey }
|
||||
);
|
||||
return new TransactionObject(payer, [instruction], signers, options);
|
||||
}
|
||||
|
||||
public async addMrEnclave(
|
||||
params: AttestationQueueAddMrEnclaveParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.addMrEnclaveInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
public async removeMrEnclaveInstruction(
|
||||
payer: PublicKey,
|
||||
params: AttestationQueueRemoveMrEnclaveParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const authority = params.authority?.publicKey ?? payer;
|
||||
const signers = params.authority ? [params.authority] : [];
|
||||
const instruction = types.attestationQueueRemoveMrEnclave(
|
||||
this.program,
|
||||
{ params: { mrEnclave: Array.from(parseMrEnclave(params.mrEnclave)) } },
|
||||
{ authority, queue: this.publicKey }
|
||||
);
|
||||
return new TransactionObject(payer, [instruction], signers, options);
|
||||
}
|
||||
|
||||
public async removeMrEnclave(
|
||||
params: AttestationQueueRemoveMrEnclaveParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.removeMrEnclaveInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new attestation queue for internal testing
|
||||
* - Creates AttestationQueue account
|
||||
* - Creates a Quote verifier
|
||||
* - Sets the quote verifier secured signer
|
||||
* - Adds Quote verifier to the queue
|
||||
*/
|
||||
public static async bootstrapNewQueue(
|
||||
program: SwitchboardProgram,
|
||||
params?: CreateBootstrappedQueueParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<
|
||||
BootstrappedAttestationQueue & { signatures?: Array<TransactionSignature> }
|
||||
> {
|
||||
const authority: Keypair = params?.authority ?? program.wallet.payer;
|
||||
|
||||
const attestationQueueKeypair = params?.keypair ?? Keypair.generate();
|
||||
const verifierQuoteKeypair1 = Keypair.generate();
|
||||
const verifierQuoteSigner1 = params?.securedSigner ?? Keypair.generate();
|
||||
|
||||
const ixns: Array<TransactionInstruction> = [];
|
||||
const signers: Array<Keypair> = [
|
||||
authority,
|
||||
attestationQueueKeypair,
|
||||
verifierQuoteKeypair1,
|
||||
verifierQuoteSigner1,
|
||||
];
|
||||
|
||||
// create attestation queue
|
||||
ixns.push(
|
||||
types.attestationQueueInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
reward: params?.reward ?? 0,
|
||||
allowAuthorityOverrideAfter:
|
||||
params?.allowAuthorityOverrideAfter ?? 300,
|
||||
maxQuoteVerificationAge: params?.maxQuoteVerificationAge ?? 604800,
|
||||
nodeTimeout: params?.nodeTimeout ?? 180,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
params?.requireAuthorityHeartbeatPermission ?? false,
|
||||
requireUsagePermissions: params?.requireUsagePermissions ?? false,
|
||||
},
|
||||
},
|
||||
{
|
||||
queue: attestationQueueKeypair.publicKey,
|
||||
authority: authority.publicKey,
|
||||
payer: authority.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// add mrEnclave
|
||||
ixns.push(
|
||||
types.attestationQueueAddMrEnclave(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
mrEnclave: Array.from(
|
||||
parseMrEnclave(params?.quoteVerifierMrEnclave ?? "")
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
queue: attestationQueueKeypair.publicKey,
|
||||
authority: authority.publicKey,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// create quote #1
|
||||
ixns.push(
|
||||
types.quoteInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
registryKey: parseRawBuffer(params?.registryKey ?? "", 64),
|
||||
},
|
||||
},
|
||||
{
|
||||
quote: verifierQuoteKeypair1.publicKey,
|
||||
attestationQueue: attestationQueueKeypair.publicKey,
|
||||
queueAuthority: authority.publicKey,
|
||||
authority: authority.publicKey,
|
||||
payer: authority.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
)
|
||||
);
|
||||
// create & set quote #1 permissions
|
||||
const [verifierQuotePermissions1] = AttestationPermissionAccount.fromSeed(
|
||||
program,
|
||||
authority.publicKey,
|
||||
attestationQueueKeypair.publicKey,
|
||||
verifierQuoteKeypair1.publicKey
|
||||
);
|
||||
ixns.push(
|
||||
types.attestationPermissionInit(
|
||||
program,
|
||||
{ params: {} },
|
||||
{
|
||||
permission: verifierQuotePermissions1.publicKey,
|
||||
attestationQueue: attestationQueueKeypair.publicKey,
|
||||
node: verifierQuoteKeypair1.publicKey,
|
||||
authority: authority.publicKey,
|
||||
payer: authority.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
)
|
||||
);
|
||||
ixns.push(
|
||||
types.attestationPermissionSet(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
permission: 1, // Permit_Node_Heartbeat
|
||||
enable: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
permission: verifierQuotePermissions1.publicKey,
|
||||
authority: authority.publicKey,
|
||||
attestationQueue: attestationQueueKeypair.publicKey,
|
||||
node: verifierQuoteKeypair1.publicKey,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// set quote #1 securedSigner
|
||||
ixns.push(
|
||||
types.quoteRotate(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
registryKey: Array.from(
|
||||
parseRawBuffer(params?.registryKey ?? "", 64)
|
||||
),
|
||||
},
|
||||
},
|
||||
{
|
||||
quote: verifierQuoteKeypair1.publicKey,
|
||||
authority: authority.publicKey,
|
||||
securedSigner: verifierQuoteSigner1.publicKey,
|
||||
attestationQueue: attestationQueueKeypair.publicKey,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
// quote #1 heartbeat
|
||||
ixns.push(
|
||||
types.quoteHeartbeat(
|
||||
program,
|
||||
{ params: {} },
|
||||
{
|
||||
quote: verifierQuoteKeypair1.publicKey,
|
||||
securedSigner: verifierQuoteSigner1.publicKey,
|
||||
attestationQueue: attestationQueueKeypair.publicKey,
|
||||
queueAuthority: authority.publicKey,
|
||||
gcNode: verifierQuoteKeypair1.publicKey,
|
||||
permission: verifierQuotePermissions1.publicKey,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
const txns = TransactionObject.packIxns(
|
||||
program.walletPubkey,
|
||||
ixns,
|
||||
signers,
|
||||
options
|
||||
);
|
||||
|
||||
const signatures = await program.signAndSendAll(txns, options);
|
||||
|
||||
const attestationQueueAccount = new AttestationQueueAccount(
|
||||
program,
|
||||
attestationQueueKeypair.publicKey
|
||||
);
|
||||
|
||||
return {
|
||||
attestationQueueAccount,
|
||||
signatures,
|
||||
verifier: {
|
||||
quoteAccount: new QuoteAccount(
|
||||
program,
|
||||
verifierQuoteKeypair1.publicKey
|
||||
),
|
||||
permissionAccount: verifierQuotePermissions1,
|
||||
signer: verifierQuoteSigner1,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export type CreateBootstrappedQueueParams =
|
||||
AttestationQueueAccountInitParams & {
|
||||
quoteVerifierMrEnclave: RawBuffer;
|
||||
registryKey: RawBuffer;
|
||||
securedSigner?: Keypair;
|
||||
};
|
||||
|
||||
type BootstrappedAttestationQueue = {
|
||||
attestationQueueAccount: AttestationQueueAccount;
|
||||
verifier: {
|
||||
quoteAccount: QuoteAccount;
|
||||
permissionAccount: AttestationPermissionAccount;
|
||||
signer: Keypair;
|
||||
};
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
import * as errors from "../errors.js";
|
||||
import { bufferRelayerSaveResult } from "../generated/index.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import { bufferRelayerSaveResult } from "../generated/oracle-program/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
TransactionObject,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
|
||||
import {
|
||||
|
|
|
@ -0,0 +1,654 @@
|
|||
import { Account } from "../accounts/account.js";
|
||||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/attestation-program/index.js";
|
||||
import {
|
||||
SB_ATTESTATION_PID,
|
||||
SB_V2_PID,
|
||||
SwitchboardProgram,
|
||||
} from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
TransactionObject,
|
||||
TransactionObjectOptions,
|
||||
} from "../TransactionObject.js";
|
||||
import { parseCronSchedule, parseMrEnclave } from "../utils.js";
|
||||
|
||||
import {
|
||||
AttestationPermissionAccount,
|
||||
AttestationQueueAccount,
|
||||
QuoteAccount,
|
||||
} from "./index.js";
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import * as spl from "@solana/spl-token";
|
||||
import {
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
} from "@solana/spl-token";
|
||||
import {
|
||||
AddressLookupTableAccount,
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
import { BN, toUtf8 } from "@switchboard-xyz/common";
|
||||
|
||||
/**
|
||||
* Parameters for initializing an {@linkcode FunctionAccount}
|
||||
*/
|
||||
export interface FunctionAccountInitParams {
|
||||
name?: string;
|
||||
metadata?: string;
|
||||
container: string;
|
||||
version: string;
|
||||
containerRegistry?: string;
|
||||
schedule: string;
|
||||
|
||||
mrEnclave: Buffer | Uint8Array | number[];
|
||||
attestationQueue: AttestationQueueAccount;
|
||||
|
||||
/**
|
||||
* A keypair to be used to address this account.
|
||||
*
|
||||
* @default Keypair.generate()
|
||||
*/
|
||||
keypair?: Keypair;
|
||||
/**
|
||||
* An authority to be used to control this account.
|
||||
*
|
||||
* @default payer
|
||||
*/
|
||||
authority?: Keypair;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.functionFund} instruction.
|
||||
*/
|
||||
export interface FunctionFundParams {
|
||||
/**
|
||||
* The amount to fund this function with.
|
||||
*/
|
||||
fundAmount: number;
|
||||
/**
|
||||
* _OPTIONAL_ The token account to fund the lease from. Defaults to payer's associated token account.
|
||||
*/
|
||||
funderTokenWallet?: PublicKey;
|
||||
/**
|
||||
* _OPTIONAL_ The funderTokenWallet authority if it differs from the provided payer.
|
||||
*/
|
||||
funderAuthority?: Keypair;
|
||||
}
|
||||
|
||||
interface FunctionWithdrawBaseParams {
|
||||
amount: number | "all";
|
||||
unwrap: boolean;
|
||||
}
|
||||
|
||||
export interface FunctionWithdrawUnwrapParams
|
||||
extends FunctionWithdrawBaseParams {
|
||||
unwrap: true;
|
||||
}
|
||||
|
||||
export interface FunctionWithdrawWalletParams
|
||||
extends FunctionWithdrawBaseParams {
|
||||
unwrap: false;
|
||||
withdrawWallet: PublicKey;
|
||||
withdrawAuthority?: Keypair;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.functionWithdraw} instruction.
|
||||
*/
|
||||
export type FunctionWithdrawParams =
|
||||
| FunctionWithdrawUnwrapParams
|
||||
| FunctionWithdrawWalletParams;
|
||||
/**
|
||||
* Parameters for an {@linkcode types.functionVerify} instruction.
|
||||
*/
|
||||
|
||||
export interface FunctionVerifyParams {
|
||||
observedTime: anchor.BN;
|
||||
nextAllowedTimestamp: anchor.BN;
|
||||
isFailure: boolean;
|
||||
mrEnclave: Uint8Array;
|
||||
verifier: QuoteAccount;
|
||||
fnSigner: PublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Account type representing a Switchboard Function.
|
||||
*
|
||||
* Data: {@linkcode types.FunctionAccountData}
|
||||
*/
|
||||
export class FunctionAccount extends Account<types.FunctionAccountData> {
|
||||
static accountName = "FunctionAccountData";
|
||||
/**
|
||||
* Returns the functions's name buffer in a stringified format.
|
||||
*/
|
||||
public static getName = (functionData: types.FunctionAccountData) =>
|
||||
toUtf8(functionData.name);
|
||||
/**
|
||||
* Returns the functions's metadata buffer in a stringified format.
|
||||
*/
|
||||
public static getMetadata = (functionData: types.FunctionAccountData) =>
|
||||
toUtf8(functionData.metadata);
|
||||
/**
|
||||
* Load an existing {@linkcode FunctionAccount} with its current on-chain state
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the size of an {@linkcode FunctionAccount} on-chain.
|
||||
*/
|
||||
public readonly size =
|
||||
this.program.attestationAccount.functionAccountData.size;
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.FunctionAccountData} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.FunctionAccountData> {
|
||||
const data = await types.FunctionAccountData.fetch(
|
||||
this.program,
|
||||
this.publicKey
|
||||
);
|
||||
if (data) return data;
|
||||
throw new errors.AccountNotFoundError("Function", this.publicKey);
|
||||
}
|
||||
|
||||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey | string
|
||||
): Promise<[FunctionAccount, types.FunctionAccountData]> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const functionAccount = new FunctionAccount(program, address);
|
||||
const state = await functionAccount.loadData();
|
||||
return [functionAccount, state];
|
||||
}
|
||||
|
||||
public static async createInstruction(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey,
|
||||
params: FunctionAccountInitParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[FunctionAccount, TransactionObject]> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const functionKeypair = params.keypair ?? Keypair.generate();
|
||||
program.verifyNewKeypair(functionKeypair);
|
||||
|
||||
const authority = params.authority ? params.authority.publicKey : payer;
|
||||
|
||||
const cronSchedule = parseCronSchedule(params.schedule);
|
||||
|
||||
const attestationQueueAccount = params.attestationQueue;
|
||||
const attestationQueue = await attestationQueueAccount.loadData();
|
||||
|
||||
const recentSlot = new BN(
|
||||
(
|
||||
await program.connection.getLatestBlockhashAndContext({
|
||||
commitment: "finalized",
|
||||
})
|
||||
).context.slot
|
||||
);
|
||||
const addressLookupProgram = new PublicKey(
|
||||
"AddressLookupTab1e1111111111111111111111111"
|
||||
);
|
||||
const [addressLookupTable] = PublicKey.findProgramAddressSync(
|
||||
[authority.toBuffer(), recentSlot.toBuffer("le", 8)],
|
||||
addressLookupProgram
|
||||
);
|
||||
|
||||
// get PDA accounts
|
||||
const functionAccount = new FunctionAccount(
|
||||
program,
|
||||
functionKeypair.publicKey
|
||||
);
|
||||
const [permissionAccount] = functionAccount.getPermissionAccount(
|
||||
attestationQueueAccount.publicKey,
|
||||
attestationQueue.authority
|
||||
);
|
||||
const [quoteAccount] = functionAccount.getQuoteAccount();
|
||||
const escrow = functionAccount.getEscrow();
|
||||
|
||||
const instruction = types.functionInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
name: new Uint8Array(Buffer.from(params.name ?? "", "utf8")),
|
||||
metadata: new Uint8Array(Buffer.from(params.metadata ?? "", "utf8")),
|
||||
schedule: new Uint8Array(Buffer.from(cronSchedule, "utf8")),
|
||||
container: new Uint8Array(Buffer.from(params.container, "utf8")),
|
||||
version: new Uint8Array(Buffer.from(params.version, "utf8")),
|
||||
containerRegistry: new Uint8Array(
|
||||
Buffer.from(params.containerRegistry ?? "", "utf8")
|
||||
),
|
||||
mrEnclave: Array.from(parseMrEnclave(params.mrEnclave)),
|
||||
recentSlot: recentSlot,
|
||||
},
|
||||
},
|
||||
{
|
||||
function: functionAccount.publicKey,
|
||||
addressLookupTable: addressLookupTable,
|
||||
authority: authority,
|
||||
quote: quoteAccount.publicKey,
|
||||
attestationQueue: attestationQueueAccount.publicKey,
|
||||
permission: permissionAccount.publicKey,
|
||||
escrow,
|
||||
state: program.attestationProgramState.publicKey,
|
||||
mint: program.mint.address,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
addressLookupProgram: addressLookupProgram,
|
||||
}
|
||||
);
|
||||
return [
|
||||
functionAccount,
|
||||
new TransactionObject(
|
||||
payer,
|
||||
[instruction],
|
||||
params.authority
|
||||
? [params.authority, functionKeypair]
|
||||
: [functionKeypair],
|
||||
options
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
public static async create(
|
||||
program: SwitchboardProgram,
|
||||
params: FunctionAccountInitParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[FunctionAccount, TransactionSignature]> {
|
||||
const [account, txnObject] = await this.createInstruction(
|
||||
program,
|
||||
program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
const txSignature = await program.signAndSend(txnObject, options);
|
||||
return [account, txSignature];
|
||||
}
|
||||
|
||||
public getPermissionAccount(
|
||||
queuePubkey: PublicKey,
|
||||
queueAuthority: PublicKey
|
||||
): [AttestationPermissionAccount, number] {
|
||||
return AttestationPermissionAccount.fromSeed(
|
||||
this.program,
|
||||
queueAuthority,
|
||||
queuePubkey,
|
||||
this.publicKey
|
||||
);
|
||||
}
|
||||
|
||||
public getQuoteAccount(): [QuoteAccount, number] {
|
||||
return QuoteAccount.fromSeed(this.program, this.publicKey);
|
||||
}
|
||||
|
||||
public getEscrow(): PublicKey {
|
||||
return this.program.mint.getAssociatedAddress(this.publicKey);
|
||||
}
|
||||
|
||||
public async fundInstruction(
|
||||
payer: PublicKey,
|
||||
params: FunctionFundParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const fundTokenAmountBN = this.program.mint.toTokenAmountBN(
|
||||
params.fundAmount
|
||||
);
|
||||
|
||||
// TODO: Create funder token wallet if it doesnt exist
|
||||
const funderAuthority = params.funderAuthority
|
||||
? params.funderAuthority.publicKey
|
||||
: payer;
|
||||
const funderTokenWallet =
|
||||
params.funderTokenWallet ??
|
||||
this.program.mint.getAssociatedAddress(funderAuthority);
|
||||
|
||||
const functionData = await this.loadData();
|
||||
const instruction = types.functionFund(
|
||||
this.program,
|
||||
{ params: { amount: fundTokenAmountBN } },
|
||||
{
|
||||
function: this.publicKey,
|
||||
attestationQueue: functionData.attestationQueue,
|
||||
escrow: this.getEscrow(),
|
||||
funder: funderTokenWallet,
|
||||
funderAuthority: funderAuthority,
|
||||
state: this.program.attestationProgramState.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
}
|
||||
);
|
||||
return new TransactionObject(payer, [instruction], [], options);
|
||||
}
|
||||
|
||||
public async fund(
|
||||
params: FunctionFundParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.fundInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
public async withdrawInstruction(
|
||||
payer: PublicKey,
|
||||
params: FunctionWithdrawParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const functionData = await this.loadData();
|
||||
const [queueAccount, queueData] = await AttestationQueueAccount.load(
|
||||
this.program,
|
||||
functionData.attestationQueue
|
||||
);
|
||||
|
||||
const withdrawAmount: number = await (async () => {
|
||||
const minRequiredBalance = queueData.reward * 2;
|
||||
const escrowBalance = await spl
|
||||
.getAccount(this.program.connection, this.getEscrow())
|
||||
.then((escrow) => this.program.mint.fromTokenAmount(escrow.amount));
|
||||
const maxWithdrawAmount = escrowBalance - minRequiredBalance;
|
||||
|
||||
if (params.amount === "all") return maxWithdrawAmount;
|
||||
return Math.min(params.amount, maxWithdrawAmount);
|
||||
})();
|
||||
|
||||
if (params.unwrap) {
|
||||
const ephemeralWallet = Keypair.generate();
|
||||
|
||||
const instructions: TransactionInstruction[] = [
|
||||
// initialize space for ephemeral token account
|
||||
SystemProgram.createAccount({
|
||||
fromPubkey: payer,
|
||||
newAccountPubkey: ephemeralWallet.publicKey,
|
||||
lamports:
|
||||
await this.program.connection.getMinimumBalanceForRentExemption(
|
||||
spl.ACCOUNT_SIZE
|
||||
),
|
||||
space: spl.ACCOUNT_SIZE,
|
||||
programId: spl.TOKEN_PROGRAM_ID,
|
||||
}),
|
||||
// initialize ephemeral token account
|
||||
spl.createInitializeAccountInstruction(
|
||||
ephemeralWallet.publicKey,
|
||||
this.program.mint.address,
|
||||
payer,
|
||||
spl.TOKEN_PROGRAM_ID
|
||||
),
|
||||
// perform withdraw
|
||||
types.functionWithdraw(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
amount: this.program.mint.toTokenAmountBN(withdrawAmount),
|
||||
},
|
||||
},
|
||||
{
|
||||
function: this.publicKey,
|
||||
attestationQueue: queueAccount.publicKey,
|
||||
escrow: this.getEscrow(),
|
||||
authority: payer,
|
||||
receiver: ephemeralWallet.publicKey,
|
||||
state: this.program.attestationProgramState.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
}
|
||||
),
|
||||
// close ephemeral token account
|
||||
spl.createCloseAccountInstruction(
|
||||
ephemeralWallet.publicKey,
|
||||
payer,
|
||||
payer
|
||||
),
|
||||
];
|
||||
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
instructions,
|
||||
[ephemeralWallet],
|
||||
options
|
||||
);
|
||||
} else {
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
[
|
||||
types.functionWithdraw(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
amount: this.program.mint.toTokenAmountBN(withdrawAmount),
|
||||
},
|
||||
},
|
||||
{
|
||||
function: this.publicKey,
|
||||
attestationQueue: queueAccount.publicKey,
|
||||
escrow: this.getEscrow(),
|
||||
authority:
|
||||
"withdrawAuthority" in params && params.withdrawAuthority
|
||||
? params.withdrawAuthority.publicKey
|
||||
: payer,
|
||||
receiver:
|
||||
"withdrawWallet" in params && params.withdrawWallet
|
||||
? params.withdrawWallet
|
||||
: this.program.mint.getAssociatedAddress(payer),
|
||||
state: this.program.attestationProgramState.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
}
|
||||
),
|
||||
],
|
||||
"withdrawAuthority" in params && params.withdrawAuthority
|
||||
? [params.withdrawAuthority]
|
||||
: [],
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public async withdraw(
|
||||
params: FunctionWithdrawParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.withdrawInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
public async getBalance(): Promise<number> {
|
||||
const balance = await this.program.mint.getAssociatedBalance(
|
||||
this.publicKey
|
||||
);
|
||||
if (balance === null) {
|
||||
throw new errors.AccountNotFoundError(
|
||||
`Function escrow`,
|
||||
this.getEscrow()
|
||||
);
|
||||
}
|
||||
return balance;
|
||||
}
|
||||
|
||||
public async getBalanceBN(): Promise<BN> {
|
||||
const balance = await this.getBalance();
|
||||
return this.program.mint.toTokenAmountBN(balance);
|
||||
}
|
||||
|
||||
public async verifyInstruction(
|
||||
payer: PublicKey,
|
||||
params: FunctionVerifyParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const functionData = await this.loadData();
|
||||
const attestationQueueAccount = new AttestationQueueAccount(
|
||||
this.program,
|
||||
functionData.attestationQueue
|
||||
);
|
||||
const attestationQueue = await attestationQueueAccount.loadData();
|
||||
|
||||
const fnPermissionAccount = this.getPermissionAccount(
|
||||
attestationQueueAccount.publicKey,
|
||||
attestationQueue.authority
|
||||
)[0];
|
||||
|
||||
const fnQuoteAccount = this.getQuoteAccount()[0];
|
||||
|
||||
const verifierPermissionAccount = AttestationPermissionAccount.fromSeed(
|
||||
this.program,
|
||||
attestationQueue.authority,
|
||||
attestationQueueAccount.publicKey,
|
||||
payer
|
||||
)[0];
|
||||
|
||||
const quoteVerifier = await params.verifier.loadData();
|
||||
if (!quoteVerifier.authority.equals(payer)) {
|
||||
throw new Error(
|
||||
`The verifier owner must be the payer of this transaction, expected ${quoteVerifier.authority}, received ${payer}`
|
||||
);
|
||||
}
|
||||
|
||||
const receiver = await this.program.mint.getOrCreateAssociatedUser(payer);
|
||||
|
||||
const instruction = types.functionVerify(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
observedTime: params.observedTime,
|
||||
nextAllowedTimestamp: params.nextAllowedTimestamp,
|
||||
isFailure: params.isFailure,
|
||||
mrEnclave: Array.from(params.mrEnclave),
|
||||
},
|
||||
},
|
||||
{
|
||||
function: this.publicKey,
|
||||
fnSigner: params.fnSigner,
|
||||
fnQuote: fnQuoteAccount.publicKey,
|
||||
verifierQuote: params.verifier.publicKey,
|
||||
attestationQueue: functionData.attestationQueue,
|
||||
escrow: this.getEscrow(),
|
||||
receiver: receiver,
|
||||
verifierPermission: verifierPermissionAccount.publicKey,
|
||||
fnPermission: fnPermissionAccount.publicKey,
|
||||
state: this.program.attestationProgramState.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
securedSigner: PublicKey.default, // TODO: update with correct account
|
||||
}
|
||||
);
|
||||
return new TransactionObject(payer, [instruction], [], options);
|
||||
}
|
||||
|
||||
public async verify(
|
||||
params: FunctionVerifyParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.verifyInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
public static decodeAddressLookup(lookupTable: AddressLookupTableAccount) {
|
||||
const addresses = lookupTable.state.addresses;
|
||||
if (addresses.length !== 16) {
|
||||
throw new Error(`Failed to decode address lookup table`);
|
||||
}
|
||||
|
||||
const systemProgram = addresses[0]!;
|
||||
if (!systemProgram.equals(anchor.web3.SystemProgram.programId)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const tokenProgram = addresses[1]!;
|
||||
if (!tokenProgram.equals(anchor.utils.token.TOKEN_PROGRAM_ID)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const assocatedTokenProgram = addresses[2]!;
|
||||
if (
|
||||
!assocatedTokenProgram.equals(anchor.utils.token.ASSOCIATED_PROGRAM_ID)
|
||||
) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const sysVarRent = addresses[3]!;
|
||||
if (!sysVarRent.equals(anchor.web3.SYSVAR_RENT_PUBKEY)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const sysVarRecentBlockhashes = addresses[4]!;
|
||||
if (
|
||||
!sysVarRecentBlockhashes.equals(
|
||||
anchor.web3.SYSVAR_RECENT_BLOCKHASHES_PUBKEY
|
||||
)
|
||||
) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const sysVarInstructions = addresses[5]!;
|
||||
if (!sysVarInstructions.equals(anchor.web3.SYSVAR_INSTRUCTIONS_PUBKEY)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const sysVarSlotHashes = addresses[6]!;
|
||||
if (!sysVarSlotHashes.equals(anchor.web3.SYSVAR_SLOT_HASHES_PUBKEY)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const sysVarSlotHistory = addresses[7]!;
|
||||
if (!sysVarSlotHistory.equals(anchor.web3.SYSVAR_SLOT_HISTORY_PUBKEY)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const switchboardProgram = addresses[8]!;
|
||||
if (!switchboardProgram.equals(SB_V2_PID)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
const attestationProgram = addresses[9]!;
|
||||
if (!attestationProgram.equals(SB_ATTESTATION_PID)) {
|
||||
throw new Error("AddressLookupMismatch");
|
||||
}
|
||||
|
||||
// switchboard accounts, not worth the network calls
|
||||
const statePubkey = addresses[10]!;
|
||||
const attestationQueuePubkey = addresses[11]!;
|
||||
const functionPubkey = addresses[12]!;
|
||||
const escrowPubkey = addresses[13]!;
|
||||
const fnPermission = addresses[14]!;
|
||||
const fnQuote = addresses[15]!;
|
||||
|
||||
return {
|
||||
systemProgram,
|
||||
tokenProgram,
|
||||
assocatedTokenProgram,
|
||||
sysVarRent,
|
||||
sysVarRecentBlockhashes,
|
||||
sysVarInstructions,
|
||||
sysVarSlotHashes,
|
||||
sysVarSlotHistory,
|
||||
switchboardProgram,
|
||||
attestationProgram,
|
||||
statePubkey,
|
||||
attestationQueuePubkey,
|
||||
functionPubkey,
|
||||
escrowPubkey,
|
||||
fnPermission,
|
||||
fnQuote,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,9 +1,13 @@
|
|||
export * from "./account.js";
|
||||
export * from "./aggregatorAccount.js";
|
||||
export * from "./aggregatorHistoryBuffer.js";
|
||||
export * from "./attestationPermissionAccount.js";
|
||||
export * from "./attestationProgramStateAccount.js";
|
||||
export * from "./attestationQueueAccount.js";
|
||||
export * from "./bufferRelayAccount.js";
|
||||
export * from "./crankAccount.js";
|
||||
export * from "./crankDataBuffer.js";
|
||||
export * from "./functionAccount.js";
|
||||
export * from "./jobAccount.js";
|
||||
export * from "./leaseAccount.js";
|
||||
export * from "./oracleAccount.js";
|
||||
|
@ -11,6 +15,7 @@ export * from "./permissionAccount.js";
|
|||
export * from "./programStateAccount.js";
|
||||
export * from "./queueAccount.js";
|
||||
export * from "./queueDataBuffer.js";
|
||||
export * from "./quoteAccount.js";
|
||||
export * from "./vrfAccount.js";
|
||||
export * from "./vrfLiteAccount.js";
|
||||
export * from "./vrfPoolAccount.js";
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
@ -20,6 +20,7 @@ import {
|
|||
LAMPORTS_PER_SOL,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
import { BN } from "@switchboard-xyz/common";
|
||||
|
@ -192,9 +193,7 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
public static async createInstructions(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey,
|
||||
params: {
|
||||
queueAccount: QueueAccount;
|
||||
} & OracleInitParams &
|
||||
params: { queueAccount: QueueAccount } & OracleInitParams &
|
||||
Partial<OracleStakeParams>,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[OracleAccount, Array<TransactionObject>]> {
|
||||
|
@ -498,6 +497,97 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
return txnSignature;
|
||||
}
|
||||
|
||||
teeHeartbeatInstruction(
|
||||
params: OracleTeeHeartbeatSyncParams
|
||||
): TransactionInstruction {
|
||||
const [permissionAccount, permissionBump] = params.permission;
|
||||
const instruction = types.oracleTeeHeartbeat(
|
||||
this.program,
|
||||
{ params: { permissionBump } },
|
||||
{
|
||||
oracle: this.publicKey,
|
||||
oracleAuthority: params.authority,
|
||||
tokenAccount: params.tokenWallet,
|
||||
gcOracle: params.gcOracle ?? this.publicKey,
|
||||
oracleQueue: params.oracleQueue,
|
||||
permission: permissionAccount.publicKey,
|
||||
dataBuffer: params.dataBuffer,
|
||||
quote: params.quote,
|
||||
programState: this.program.programState.publicKey,
|
||||
}
|
||||
);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
async teeHeartbeat(
|
||||
params: OracleTeeHeartbeatParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
const oracle = await this.loadData();
|
||||
const tokenWallet = params?.tokenWallet ?? oracle.tokenAccount;
|
||||
|
||||
const queueAccount =
|
||||
params?.queueAccount ??
|
||||
new QueueAccount(this.program, oracle.queuePubkey);
|
||||
|
||||
const queue = params?.queue ?? (await queueAccount.loadData());
|
||||
const oracles = await queueAccount.loadOracles();
|
||||
|
||||
let lastPubkey = this.publicKey;
|
||||
if (oracles.length !== 0) {
|
||||
lastPubkey = oracles[queue.gcIdx];
|
||||
}
|
||||
|
||||
const [permissionAccount, permissionBump] =
|
||||
params?.permission ??
|
||||
this.getPermissionAccount(
|
||||
queueAccount.publicKey,
|
||||
queue.authority,
|
||||
oracle.oracleAuthority
|
||||
);
|
||||
|
||||
try {
|
||||
await permissionAccount.loadData();
|
||||
} catch (_) {
|
||||
throw new Error(
|
||||
"A requested oracle permission pda account has not been initialized."
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
params?.authority &&
|
||||
!oracle.oracleAuthority.equals(params.authority.publicKey)
|
||||
) {
|
||||
throw new errors.IncorrectAuthority(
|
||||
oracle.oracleAuthority,
|
||||
params.authority.publicKey
|
||||
);
|
||||
}
|
||||
|
||||
const heartbeatTxn = new TransactionObject(
|
||||
this.program.walletPubkey,
|
||||
[
|
||||
this.teeHeartbeatInstruction({
|
||||
tokenWallet: tokenWallet,
|
||||
gcOracle: lastPubkey,
|
||||
oracleQueue: queueAccount.publicKey,
|
||||
dataBuffer: queue.dataBuffer,
|
||||
permission: [permissionAccount, permissionBump],
|
||||
authority: oracle.oracleAuthority,
|
||||
quote: params.quoteKeypair.publicKey,
|
||||
queueAuthority: params.queueAuthority ?? queue.authority,
|
||||
}),
|
||||
],
|
||||
params?.authority
|
||||
? [params.authority, params.quoteKeypair]
|
||||
: [params.quoteKeypair],
|
||||
options
|
||||
);
|
||||
|
||||
const txnSignature = await this.program.signAndSend(heartbeatTxn, options);
|
||||
return txnSignature;
|
||||
}
|
||||
|
||||
async withdrawInstruction(
|
||||
payer: PublicKey,
|
||||
params: OracleWithdrawParams,
|
||||
|
@ -628,13 +718,14 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
|
||||
public getPermissionAccount(
|
||||
queuePubkey: PublicKey,
|
||||
queueAuthority: PublicKey
|
||||
queueAuthority: PublicKey,
|
||||
grantee: PublicKey = this.publicKey
|
||||
): [PermissionAccount, number] {
|
||||
return PermissionAccount.fromSeed(
|
||||
this.program,
|
||||
queueAuthority,
|
||||
queuePubkey,
|
||||
this.publicKey
|
||||
grantee
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -769,3 +860,25 @@ export interface OracleWithdrawWalletParams extends OracleWithdrawBaseParams {
|
|||
export type OracleWithdrawParams =
|
||||
| OracleWithdrawUnwrapParams
|
||||
| OracleWithdrawWalletParams;
|
||||
|
||||
export type OracleTeeHeartbeatSyncParams = {
|
||||
quote: PublicKey;
|
||||
dataBuffer: PublicKey;
|
||||
oracleQueue: PublicKey;
|
||||
tokenWallet: PublicKey;
|
||||
queueAuthority: PublicKey;
|
||||
gcOracle: PublicKey;
|
||||
// queue: types.OracleQueueAccountData;
|
||||
permission: [PermissionAccount, number];
|
||||
authority: PublicKey;
|
||||
};
|
||||
|
||||
export type OracleTeeHeartbeatParams = {
|
||||
quoteKeypair: Keypair;
|
||||
queueAccount?: QueueAccount;
|
||||
tokenWallet?: PublicKey;
|
||||
queueAuthority?: PublicKey;
|
||||
queue?: types.OracleQueueAccountData;
|
||||
permission?: [PermissionAccount, number];
|
||||
authority?: Keypair;
|
||||
};
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import {
|
||||
PermitNone,
|
||||
PermitOracleHeartbeat,
|
||||
PermitOracleQueueUsage,
|
||||
PermitVrfRequests,
|
||||
} from "../generated/types/SwitchboardPermission.js";
|
||||
} from "../generated/oracle-program/types/SwitchboardPermission.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { Mint } from "../mint.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import { TransactionObject } from "../TransactionObject.js";
|
||||
|
@ -9,9 +9,7 @@ import { Account } from "./account.js";
|
|||
import * as anchor from "@coral-xyz/anchor";
|
||||
import * as spl from "@solana/spl-token";
|
||||
import {
|
||||
AccountInfo,
|
||||
Keypair,
|
||||
LAMPORTS_PER_SOL,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
|
@ -35,43 +33,17 @@ export class ProgramStateAccount extends Account<types.SbState> {
|
|||
public readonly size = this.program.account.sbState.size;
|
||||
|
||||
/**
|
||||
* Return a program state account state initialized to the default values.
|
||||
* Finds the {@linkcode ProgramStateAccount} from the static seed from which it was generated.
|
||||
* @return ProgramStateAccount and PDA bump tuple.
|
||||
*/
|
||||
public static default(): types.SbState {
|
||||
const buffer = Buffer.alloc(ProgramStateAccount.size, 0);
|
||||
types.SbState.discriminator.copy(buffer, 0);
|
||||
return types.SbState.decode(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mock account info for a given program state config. Useful for test integrations.
|
||||
*/
|
||||
public static createMock(
|
||||
programId: PublicKey,
|
||||
data: Partial<types.SbState>,
|
||||
options?: {
|
||||
lamports?: number;
|
||||
rentEpoch?: number;
|
||||
}
|
||||
): AccountInfo<Buffer> {
|
||||
const fields: types.SbStateFields = {
|
||||
...ProgramStateAccount.default(),
|
||||
...data,
|
||||
// any cleanup actions here
|
||||
};
|
||||
const state = new types.SbState(fields);
|
||||
|
||||
const buffer = Buffer.alloc(ProgramStateAccount.size, 0);
|
||||
types.SbState.discriminator.copy(buffer, 0);
|
||||
types.SbState.layout.encode(state, buffer, 8);
|
||||
|
||||
return {
|
||||
executable: false,
|
||||
owner: programId,
|
||||
lamports: options?.lamports ?? 1 * LAMPORTS_PER_SOL,
|
||||
data: buffer,
|
||||
rentEpoch: options?.rentEpoch ?? 0,
|
||||
};
|
||||
public static fromSeed(
|
||||
program: SwitchboardProgram
|
||||
): [ProgramStateAccount, number] {
|
||||
const [publicKey, bump] = PublicKey.findProgramAddressSync(
|
||||
[Buffer.from("STATE")],
|
||||
program.programId
|
||||
);
|
||||
return [new ProgramStateAccount(program, publicKey), bump];
|
||||
}
|
||||
|
||||
/** Load the ProgramStateAccount with its current on-chain state */
|
||||
|
@ -234,17 +206,18 @@ export class ProgramStateAccount extends Account<types.SbState> {
|
|||
}
|
||||
|
||||
/**
|
||||
* Finds the {@linkcode ProgramStateAccount} from the static seed from which it was generated.
|
||||
* @return ProgramStateAccount and PDA bump tuple.
|
||||
* Find the index of an enclave in an array and return -1 if not found
|
||||
*/
|
||||
public static fromSeed(
|
||||
program: SwitchboardProgram
|
||||
): [ProgramStateAccount, number] {
|
||||
const [publicKey, bump] = PublicKey.findProgramAddressSync(
|
||||
[Buffer.from("STATE")],
|
||||
program.programId
|
||||
);
|
||||
return [new ProgramStateAccount(program, publicKey), bump];
|
||||
public static findEnclaveIdx(
|
||||
enclaves: Array<Uint8Array>,
|
||||
enclave: Uint8Array
|
||||
): number {
|
||||
for (const [n, e] of enclaves.entries()) {
|
||||
if (Buffer.compare(e, enclave) === 0) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import {
|
||||
PermitOracleHeartbeat,
|
||||
PermitOracleQueueUsage,
|
||||
PermitVrfRequests,
|
||||
} from "../generated/types/SwitchboardPermission.js";
|
||||
} from "../generated/oracle-program/types/SwitchboardPermission.js";
|
||||
import { SolanaClock } from "../SolanaClock.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
|
@ -318,13 +318,22 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
public async createOracleInstructions(
|
||||
/** The publicKey of the account that will pay for the new accounts. Will also be used as the account authority if no other authority is provided. */
|
||||
payer: PublicKey,
|
||||
params: CreateQueueOracleParams,
|
||||
params: CreateQueueOracleParams & { teeOracle?: boolean },
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[OracleAccount, Array<TransactionObject>]> {
|
||||
const queueAuthorityPubkey = params.queueAuthority
|
||||
? params.queueAuthority.publicKey
|
||||
: params.queueAuthorityPubkey ?? (await this.loadData()).authority;
|
||||
|
||||
if (
|
||||
params.teeOracle &&
|
||||
(!params.authority || !(params.authority instanceof Keypair))
|
||||
) {
|
||||
throw new Error(
|
||||
`Need to provide authority keypair when creating a teeOracle`
|
||||
);
|
||||
}
|
||||
|
||||
const [oracleAccount, createOracleTxnObject] =
|
||||
await OracleAccount.createInstructions(
|
||||
this.program,
|
||||
|
@ -336,13 +345,17 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
options
|
||||
);
|
||||
|
||||
const permissionGrantee = params.teeOracle
|
||||
? params.authority.publicKey
|
||||
: oracleAccount.publicKey;
|
||||
|
||||
const [permissionAccount, createPermissionTxnObject] =
|
||||
PermissionAccount.createInstruction(
|
||||
this.program,
|
||||
payer,
|
||||
{
|
||||
granter: this.publicKey,
|
||||
grantee: oracleAccount.publicKey,
|
||||
grantee: permissionGrantee,
|
||||
authority: queueAuthorityPubkey,
|
||||
},
|
||||
options
|
||||
|
@ -393,7 +406,7 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
* ```
|
||||
*/
|
||||
public async createOracle(
|
||||
params: CreateQueueOracleParams,
|
||||
params: CreateQueueOracleParams & { teeOracle?: boolean },
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[OracleAccount, Array<TransactionSignature>]> {
|
||||
const signers: Keypair[] = [];
|
||||
|
@ -1275,6 +1288,7 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
params.unpermissionedFeedsEnabled ?? null,
|
||||
unpermissionedVrfEnabled: params.unpermissionedVrfEnabled ?? null,
|
||||
enableBufferRelayers: params.enableBufferRelayers ?? null,
|
||||
enableTeeOnly: params.enableTeeOnly ?? null,
|
||||
slashingEnabled: params.slashingEnabled ?? null,
|
||||
reward: reward,
|
||||
minStake: minStake,
|
||||
|
@ -1287,7 +1301,6 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
? new BN(params.consecutiveOracleFailureLimit)
|
||||
: null,
|
||||
varianceToleranceMultiplier: multiplier,
|
||||
enableTeeOnly: params.enableTeeOnly ?? false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1417,6 +1430,10 @@ export interface QueueInitParams {
|
|||
* Enabling this setting will allow buffer relayer accounts to call openRound.
|
||||
*/
|
||||
enableBufferRelayers?: boolean;
|
||||
/**
|
||||
* Only allow TEE oracles to heartbeat on this queue.
|
||||
*/
|
||||
enableTeeOnly?: boolean;
|
||||
/**
|
||||
* The account to delegate authority to for creating permissions targeted at the queue.
|
||||
*
|
||||
|
@ -1426,11 +1443,13 @@ export interface QueueInitParams {
|
|||
|
||||
keypair?: Keypair;
|
||||
dataBufferKeypair?: Keypair;
|
||||
enableTeeOnly?: boolean;
|
||||
}
|
||||
|
||||
export interface QueueSetConfigParams {
|
||||
/** Alternative keypair that is the queue authority and is permitted to make account changes. Defaults to the payer if not provided. */
|
||||
/**
|
||||
* Alternative keypair that is the queue authority and is permitted to make account changes.
|
||||
* Defaults to the payer if not provided.
|
||||
*/
|
||||
authority?: anchor.web3.Keypair;
|
||||
/**
|
||||
* A name to assign to this {@linkcode QueueAccount}
|
||||
|
@ -1445,14 +1464,18 @@ export interface QueueSetConfigParams {
|
|||
*/
|
||||
unpermissionedFeedsEnabled?: boolean;
|
||||
/**
|
||||
* Enabling this setting means data feeds do not need explicit permission
|
||||
* to request VRF proofs and verifications from this queue.
|
||||
* Enabling this setting means data feeds do not need explicit permission to request VRF proofs
|
||||
* and verifications from this queue.
|
||||
*/
|
||||
unpermissionedVrfEnabled?: boolean;
|
||||
/**
|
||||
* Enabling this setting will allow buffer relayer accounts to call openRound.
|
||||
*/
|
||||
enableBufferRelayers?: boolean;
|
||||
/**
|
||||
* Only allow TEE oracles to heartbeat on this queue.
|
||||
*/
|
||||
enableTeeOnly?: boolean;
|
||||
/**
|
||||
* Whether slashing is enabled on this queue.
|
||||
*/
|
||||
|
@ -1483,7 +1506,6 @@ export interface QueueSetConfigParams {
|
|||
* Consecutive failure limit for an oracle before oracle permission is revoked.
|
||||
*/
|
||||
consecutiveOracleFailureLimit?: number;
|
||||
enableTeeOnly?: boolean;
|
||||
}
|
||||
|
||||
export type QueueAccountsJSON = Omit<
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
|
||||
import {
|
||||
|
|
|
@ -0,0 +1,425 @@
|
|||
import { Account } from "../accounts/account.js";
|
||||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/attestation-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
TransactionObject,
|
||||
TransactionObjectOptions,
|
||||
} from "../TransactionObject.js";
|
||||
import { RawBuffer } from "../types.js";
|
||||
import { parseMrEnclave, parseRawBuffer } from "../utils.js";
|
||||
|
||||
import {
|
||||
AttestationPermissionAccount,
|
||||
AttestationQueueAccount,
|
||||
} from "./index.js";
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import {
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
export const QUOTE_SEED: string = "QuoteAccountData";
|
||||
|
||||
/**
|
||||
* Parameters for initializing an {@linkcode QuoteAccount}
|
||||
*/
|
||||
export interface QuoteAccountInitParams {
|
||||
/**
|
||||
* Key to lookup the buffer data on IPFS or an alternative decentralized storage solution.
|
||||
*/
|
||||
registryKey: Uint8Array;
|
||||
/**
|
||||
* The queue to which this function account will be linked
|
||||
*/
|
||||
queueAccount: AttestationQueueAccount;
|
||||
/**
|
||||
* A keypair to be used to address this account
|
||||
*
|
||||
* @default Keypair.generate()
|
||||
*/
|
||||
keypair?: Keypair;
|
||||
/**
|
||||
* An authority to be used to control this account.
|
||||
*
|
||||
* @default payer
|
||||
*/
|
||||
authority?: PublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.quoteHeartbeat} instruction.
|
||||
*/
|
||||
export interface QuoteHeartbeatSyncParams {
|
||||
gcOracle: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
permission: [AttestationPermissionAccount, number];
|
||||
queueAuthority: PublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.quoteHeartbeat} instruction.
|
||||
*/
|
||||
export type QuoteHeartbeatParams = Partial<QuoteHeartbeatSyncParams> & {
|
||||
securedSigner: Keypair;
|
||||
} & Partial<{
|
||||
quote: types.QuoteAccountData;
|
||||
queue: types.AttestationQueueAccountData;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.quoteVerify} instruction.
|
||||
*/
|
||||
export interface QuoteVerifyParams {
|
||||
/**
|
||||
* @TODO: Docs for timestamp
|
||||
*/
|
||||
timestamp: anchor.BN;
|
||||
/**
|
||||
* @TODO: Docs for mrEnclave
|
||||
*/
|
||||
mrEnclave: RawBuffer;
|
||||
|
||||
/**
|
||||
* Keypair of the secured signer generated in the verifiers secure enclave
|
||||
*/
|
||||
verifierSecuredSigner: Keypair;
|
||||
verifier: PublicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters for an {@linkcode types.quoteRotate} instruction.
|
||||
*/
|
||||
export interface QuoteRotateParams {
|
||||
authority?: Keypair;
|
||||
securedSigner: Keypair;
|
||||
registryKey: string | Buffer | Uint8Array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Account type representing a Switchboard Attestation quote.
|
||||
*
|
||||
* Data: {@linkcode types.QuoteAccountData}
|
||||
*/
|
||||
export class QuoteAccount extends Account<types.QuoteAccountData> {
|
||||
static accountName = "QuoteAccountData";
|
||||
|
||||
/**
|
||||
* Load an existing {@linkcode QuoteAccount} with its current on-chain state
|
||||
*/
|
||||
public static async load(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey | string
|
||||
): Promise<[QuoteAccount, types.QuoteAccountData]> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const quoteAccount = new QuoteAccount(program, address);
|
||||
const state = await quoteAccount.loadData();
|
||||
return [quoteAccount, state];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the {@linkcode QuoteAccount} from the seed from which it was generated.
|
||||
*
|
||||
* Only applicable for QuoteAccounts tied to a {@linkcode FunctionAccount}. Quotes can also be generated from a keypair.
|
||||
*
|
||||
* @return QuoteAccount and PDA bump tuple.
|
||||
*/
|
||||
public static fromSeed(
|
||||
program: SwitchboardProgram,
|
||||
functionPubkey: PublicKey
|
||||
): [QuoteAccount, number] {
|
||||
const [publicKey, bump] = PublicKey.findProgramAddressSync(
|
||||
[Buffer.from(QUOTE_SEED), functionPubkey.toBytes()],
|
||||
program.attestationProgramId
|
||||
);
|
||||
return [new QuoteAccount(program, publicKey), bump];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a transaction object to initialize a quote account.
|
||||
*/
|
||||
public static async createInstruction(
|
||||
program: SwitchboardProgram,
|
||||
payer: PublicKey,
|
||||
params: QuoteAccountInitParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<[QuoteAccount, TransactionObject]> {
|
||||
program.verifyAttestation();
|
||||
|
||||
const quoteKeypair = params.keypair ?? Keypair.generate();
|
||||
program.verifyNewKeypair(quoteKeypair);
|
||||
|
||||
const queueData = await params.queueAccount.loadData();
|
||||
|
||||
const registryKey = Array.from(params.registryKey)
|
||||
.concat(Array(64).fill(0))
|
||||
.slice(0, 64);
|
||||
|
||||
const instruction = types.quoteInit(
|
||||
program,
|
||||
{ params: { registryKey } },
|
||||
{
|
||||
quote: quoteKeypair.publicKey,
|
||||
attestationQueue: params.queueAccount.publicKey,
|
||||
queueAuthority: queueData.authority,
|
||||
authority: params.authority ?? payer,
|
||||
payer,
|
||||
systemProgram: SystemProgram.programId,
|
||||
}
|
||||
);
|
||||
return [
|
||||
new QuoteAccount(program, quoteKeypair.publicKey),
|
||||
new TransactionObject(payer, [instruction], [quoteKeypair], options),
|
||||
];
|
||||
}
|
||||
|
||||
public static async create(
|
||||
program: SwitchboardProgram,
|
||||
params: QuoteAccountInitParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<[QuoteAccount, TransactionSignature]> {
|
||||
const [account, txnObject] = await this.createInstruction(
|
||||
program,
|
||||
program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
);
|
||||
const txSignature = await program.signAndSend(txnObject, options);
|
||||
return [account, txSignature];
|
||||
}
|
||||
|
||||
public getPermissionAccount(
|
||||
queuePubkey: PublicKey,
|
||||
queueAuthority: PublicKey,
|
||||
owner: PublicKey
|
||||
): [AttestationPermissionAccount, number] {
|
||||
return AttestationPermissionAccount.fromSeed(
|
||||
this.program,
|
||||
queueAuthority,
|
||||
queuePubkey,
|
||||
owner
|
||||
);
|
||||
}
|
||||
|
||||
static getVerificationStatus(
|
||||
state: types.QuoteAccountData
|
||||
): types.VerificationStatusKind {
|
||||
switch (state.verificationStatus) {
|
||||
case types.VerificationStatus.None.discriminator:
|
||||
return new types.VerificationStatus.None();
|
||||
case types.VerificationStatus.VerificationPending.discriminator:
|
||||
return new types.VerificationStatus.VerificationPending();
|
||||
case types.VerificationStatus.VerificationFailure.discriminator:
|
||||
return new types.VerificationStatus.VerificationFailure();
|
||||
case types.VerificationStatus.VerificationSuccess.discriminator:
|
||||
return new types.VerificationStatus.VerificationSuccess();
|
||||
case types.VerificationStatus.VerificationOverride.discriminator:
|
||||
return new types.VerificationStatus.VerificationOverride();
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`Failed to get the verification status, expected [${types.VerificationStatus.None.discriminator}, ${types.VerificationStatus.VerificationPending.discriminator}, ${types.VerificationStatus.VerificationFailure.discriminator}, ${types.VerificationStatus.VerificationSuccess.discriminator}], or ${types.VerificationStatus.VerificationOverride.discriminator}], received ${state.verificationStatus}`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of an {@linkcode QuoteAccount} on-chain.
|
||||
*/
|
||||
public readonly size = this.program.attestationAccount.quoteAccountData.size;
|
||||
|
||||
/**
|
||||
* Retrieve and decode the {@linkcode types.QuoteAccountData} stored in this account.
|
||||
*/
|
||||
public async loadData(): Promise<types.QuoteAccountData> {
|
||||
this.program.verifyAttestation();
|
||||
const data = await types.QuoteAccountData.fetch(
|
||||
this.program,
|
||||
this.publicKey
|
||||
);
|
||||
if (data) return data;
|
||||
throw new errors.AccountNotFoundError("Quote", this.publicKey);
|
||||
}
|
||||
|
||||
public heartbeatInstruction(params: {
|
||||
gcOracle: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
permission: [AttestationPermissionAccount, number];
|
||||
queueAuthority: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
}): TransactionInstruction {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const [permissionAccount, permissionBump] = params.permission;
|
||||
const instruction = types.quoteHeartbeat(
|
||||
this.program,
|
||||
{ params: {} },
|
||||
{
|
||||
quote: this.publicKey,
|
||||
securedSigner: params.securedSigner,
|
||||
attestationQueue: params.attestationQueue,
|
||||
queueAuthority: params.queueAuthority,
|
||||
gcNode: params.gcOracle,
|
||||
permission: permissionAccount.publicKey,
|
||||
}
|
||||
);
|
||||
return instruction;
|
||||
}
|
||||
|
||||
public async heartbeat(
|
||||
params: QuoteHeartbeatParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
const quote = params.quote ?? (await this.loadData());
|
||||
const queue =
|
||||
params.queue ??
|
||||
(await new AttestationQueueAccount(
|
||||
this.program,
|
||||
quote.attestationQueue
|
||||
).loadData());
|
||||
|
||||
const quotes = queue.data.slice(0, queue.dataLen);
|
||||
|
||||
let lastPubkey = this.publicKey;
|
||||
if (quotes.length !== 0 && quotes.length > queue.gcIdx) {
|
||||
lastPubkey = quotes[queue.gcIdx];
|
||||
}
|
||||
|
||||
const heartbeatIxn = this.heartbeatInstruction({
|
||||
queueAuthority: queue.authority,
|
||||
permission:
|
||||
params.permission ??
|
||||
this.getPermissionAccount(
|
||||
quote.attestationQueue,
|
||||
queue.authority,
|
||||
this.publicKey
|
||||
),
|
||||
gcOracle: lastPubkey,
|
||||
attestationQueue: quote.attestationQueue,
|
||||
securedSigner: params.securedSigner.publicKey,
|
||||
});
|
||||
|
||||
const heartbeatTxn = new TransactionObject(
|
||||
this.program.walletPubkey,
|
||||
[heartbeatIxn],
|
||||
[params.securedSigner],
|
||||
options
|
||||
);
|
||||
|
||||
const txnSignature = await this.program.signAndSend(heartbeatTxn, options);
|
||||
return txnSignature;
|
||||
}
|
||||
|
||||
public async rotateInstruction(
|
||||
payer: PublicKey,
|
||||
params: QuoteRotateParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const registryKey = parseRawBuffer(params.registryKey, 64);
|
||||
|
||||
const quoteData = await this.loadData();
|
||||
|
||||
const authority = params.authority ? params.authority.publicKey : payer;
|
||||
if (!quoteData.authority.equals(authority)) {
|
||||
throw new errors.IncorrectAuthority(quoteData.authority, authority);
|
||||
}
|
||||
|
||||
const rotateIxn = types.quoteRotate(
|
||||
this.program,
|
||||
{
|
||||
params: { registryKey: [...registryKey].slice(0, 64) },
|
||||
},
|
||||
{
|
||||
quote: this.publicKey,
|
||||
authority: authority,
|
||||
securedSigner: params.securedSigner.publicKey,
|
||||
attestationQueue: quoteData.attestationQueue,
|
||||
}
|
||||
);
|
||||
|
||||
const rotateTxn: TransactionObject = new TransactionObject(
|
||||
payer,
|
||||
[rotateIxn],
|
||||
params.authority
|
||||
? [params.authority, params.securedSigner]
|
||||
: [params.securedSigner],
|
||||
options
|
||||
);
|
||||
return rotateTxn;
|
||||
}
|
||||
|
||||
public async rotate(
|
||||
params: QuoteRotateParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.rotateInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
|
||||
public async verifyInstruction(
|
||||
payer: PublicKey,
|
||||
params: QuoteVerifyParams,
|
||||
options?: TransactionObjectOptions
|
||||
): Promise<TransactionObject> {
|
||||
this.program.verifyAttestation();
|
||||
|
||||
const quoteData = await this.loadData();
|
||||
|
||||
const attestationQueueAccount = new AttestationQueueAccount(
|
||||
this.program,
|
||||
quoteData.attestationQueue
|
||||
);
|
||||
const attestationQueue = await attestationQueueAccount.loadData();
|
||||
const verifierIdx = attestationQueue.data
|
||||
.slice(0, attestationQueue.dataLen)
|
||||
.findIndex((pubkey) => pubkey.equals(params.verifier));
|
||||
if (verifierIdx === -1) {
|
||||
throw new Error(`Verifier not found on the attestation queue`);
|
||||
}
|
||||
|
||||
const instruction = types.quoteVerify(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
timestamp: params.timestamp,
|
||||
mrEnclave: Array.from(parseMrEnclave(params.mrEnclave)),
|
||||
idx: verifierIdx,
|
||||
},
|
||||
},
|
||||
{
|
||||
quote: this.publicKey,
|
||||
quoteSigner: quoteData.securedSigner,
|
||||
securedSigner: params.verifierSecuredSigner.publicKey,
|
||||
verifier: params.verifier,
|
||||
attestationQueue: quoteData.attestationQueue,
|
||||
}
|
||||
);
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
[instruction],
|
||||
[params.verifierSecuredSigner],
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
public async verify(
|
||||
params: QuoteVerifyParams,
|
||||
options?: SendTransactionObjectOptions
|
||||
): Promise<TransactionSignature> {
|
||||
return await this.verifyInstruction(
|
||||
this.program.walletPubkey,
|
||||
params,
|
||||
options
|
||||
).then((txn) => this.program.signAndSend(txn, options));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import { vrfCloseAction } from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { vrfCloseAction } from "../generated/oracle-program/index.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
SendTransactionObjectOptions,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import * as errors from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import { vrfLiteInit } from "../generated/index.js";
|
||||
import { vrfLiteCloseAction } from "../generated/instructions/vrfLiteCloseAction.js";
|
||||
import { vrfLiteInit } from "../generated/oracle-program/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { vrfLiteCloseAction } from "../generated/oracle-program/instructions/vrfLiteCloseAction.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import {
|
||||
TransactionObject,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { VRF_POOL_REQUEST_AMOUNT } from "../const.js";
|
||||
import { AccountNotFoundError, InsufficientFundsError } from "../errors.js";
|
||||
import * as types from "../generated/index.js";
|
||||
import * as types from "../generated/oracle-program/index.js";
|
||||
import { VrfPoolRequestEvent } from "../SwitchboardEvents.js";
|
||||
import { SwitchboardProgram } from "../SwitchboardProgram.js";
|
||||
import { TransactionObject } from "../TransactionObject.js";
|
||||
|
|
|
@ -100,3 +100,12 @@ export class IncorrectOwner extends Error {
|
|||
Object.setPrototypeOf(this, IncorrectOwner.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidCronSchedule extends Error {
|
||||
constructor(schedule: string) {
|
||||
super(
|
||||
`invalid cron schedule, expected format: '* * * * * *', received: ${schedule}`
|
||||
);
|
||||
Object.setPrototypeOf(this, IncorrectOwner.prototype);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./attestation-program/accounts/index.js";
|
||||
export * from "./oracle-program/accounts/index.js";
|
|
@ -0,0 +1,140 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationPermissionAccountDataFields {
|
||||
authority: PublicKey;
|
||||
permissions: number;
|
||||
granter: PublicKey;
|
||||
grantee: PublicKey;
|
||||
expiration: BN;
|
||||
bump: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface AttestationPermissionAccountDataJSON {
|
||||
authority: string;
|
||||
permissions: number;
|
||||
granter: string;
|
||||
grantee: string;
|
||||
expiration: string;
|
||||
bump: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class AttestationPermissionAccountData {
|
||||
readonly authority: PublicKey;
|
||||
readonly permissions: number;
|
||||
readonly granter: PublicKey;
|
||||
readonly grantee: PublicKey;
|
||||
readonly expiration: BN;
|
||||
readonly bump: number;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
63, 83, 122, 184, 22, 35, 31, 70,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.publicKey("authority"),
|
||||
borsh.u32("permissions"),
|
||||
borsh.publicKey("granter"),
|
||||
borsh.publicKey("grantee"),
|
||||
borsh.i64("expiration"),
|
||||
borsh.u8("bump"),
|
||||
borsh.array(borsh.u8(), 256, "ebuf"),
|
||||
]);
|
||||
|
||||
constructor(fields: AttestationPermissionAccountDataFields) {
|
||||
this.authority = fields.authority;
|
||||
this.permissions = fields.permissions;
|
||||
this.granter = fields.granter;
|
||||
this.grantee = fields.grantee;
|
||||
this.expiration = fields.expiration;
|
||||
this.bump = fields.bump;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey
|
||||
): Promise<AttestationPermissionAccountData | null> {
|
||||
const info = await program.connection.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
program: SwitchboardProgram,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<AttestationPermissionAccountData | null>> {
|
||||
const infos = await program.connection.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): AttestationPermissionAccountData {
|
||||
if (
|
||||
!data.slice(0, 8).equals(AttestationPermissionAccountData.discriminator)
|
||||
) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = AttestationPermissionAccountData.layout.decode(data.slice(8));
|
||||
|
||||
return new AttestationPermissionAccountData({
|
||||
authority: dec.authority,
|
||||
permissions: dec.permissions,
|
||||
granter: dec.granter,
|
||||
grantee: dec.grantee,
|
||||
expiration: dec.expiration,
|
||||
bump: dec.bump,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): AttestationPermissionAccountDataJSON {
|
||||
return {
|
||||
authority: this.authority.toString(),
|
||||
permissions: this.permissions,
|
||||
granter: this.granter.toString(),
|
||||
grantee: this.grantee.toString(),
|
||||
expiration: this.expiration.toString(),
|
||||
bump: this.bump,
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationPermissionAccountDataJSON
|
||||
): AttestationPermissionAccountData {
|
||||
return new AttestationPermissionAccountData({
|
||||
authority: new PublicKey(obj.authority),
|
||||
permissions: obj.permissions,
|
||||
granter: new PublicKey(obj.granter),
|
||||
grantee: new PublicKey(obj.grantee),
|
||||
expiration: new BN(obj.expiration),
|
||||
bump: obj.bump,
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueAccountDataFields {
|
||||
authority: PublicKey;
|
||||
mrEnclaves: Array<Array<number>>;
|
||||
mrEnclavesLen: number;
|
||||
data: Array<PublicKey>;
|
||||
dataLen: number;
|
||||
allowAuthorityOverrideAfter: BN;
|
||||
requireAuthorityHeartbeatPermission: boolean;
|
||||
requireUsagePermissions: boolean;
|
||||
maxQuoteVerificationAge: BN;
|
||||
reward: number;
|
||||
lastHeartbeat: BN;
|
||||
nodeTimeout: BN;
|
||||
currIdx: number;
|
||||
gcIdx: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface AttestationQueueAccountDataJSON {
|
||||
authority: string;
|
||||
mrEnclaves: Array<Array<number>>;
|
||||
mrEnclavesLen: number;
|
||||
data: Array<string>;
|
||||
dataLen: number;
|
||||
allowAuthorityOverrideAfter: string;
|
||||
requireAuthorityHeartbeatPermission: boolean;
|
||||
requireUsagePermissions: boolean;
|
||||
maxQuoteVerificationAge: string;
|
||||
reward: number;
|
||||
lastHeartbeat: string;
|
||||
nodeTimeout: string;
|
||||
currIdx: number;
|
||||
gcIdx: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class AttestationQueueAccountData {
|
||||
readonly authority: PublicKey;
|
||||
readonly mrEnclaves: Array<Array<number>>;
|
||||
readonly mrEnclavesLen: number;
|
||||
readonly data: Array<PublicKey>;
|
||||
readonly dataLen: number;
|
||||
readonly allowAuthorityOverrideAfter: BN;
|
||||
readonly requireAuthorityHeartbeatPermission: boolean;
|
||||
readonly requireUsagePermissions: boolean;
|
||||
readonly maxQuoteVerificationAge: BN;
|
||||
readonly reward: number;
|
||||
readonly lastHeartbeat: BN;
|
||||
readonly nodeTimeout: BN;
|
||||
readonly currIdx: number;
|
||||
readonly gcIdx: number;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
192, 53, 130, 67, 234, 207, 39, 171,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.publicKey("authority"),
|
||||
borsh.array(borsh.array(borsh.u8(), 32), 32, "mrEnclaves"),
|
||||
borsh.u32("mrEnclavesLen"),
|
||||
borsh.array(borsh.publicKey(), 128, "data"),
|
||||
borsh.u32("dataLen"),
|
||||
borsh.i64("allowAuthorityOverrideAfter"),
|
||||
borsh.bool("requireAuthorityHeartbeatPermission"),
|
||||
borsh.bool("requireUsagePermissions"),
|
||||
borsh.i64("maxQuoteVerificationAge"),
|
||||
borsh.u32("reward"),
|
||||
borsh.i64("lastHeartbeat"),
|
||||
borsh.i64("nodeTimeout"),
|
||||
borsh.u32("currIdx"),
|
||||
borsh.u32("gcIdx"),
|
||||
borsh.array(borsh.u8(), 1024, "ebuf"),
|
||||
]);
|
||||
|
||||
constructor(fields: AttestationQueueAccountDataFields) {
|
||||
this.authority = fields.authority;
|
||||
this.mrEnclaves = fields.mrEnclaves;
|
||||
this.mrEnclavesLen = fields.mrEnclavesLen;
|
||||
this.data = fields.data;
|
||||
this.dataLen = fields.dataLen;
|
||||
this.allowAuthorityOverrideAfter = fields.allowAuthorityOverrideAfter;
|
||||
this.requireAuthorityHeartbeatPermission =
|
||||
fields.requireAuthorityHeartbeatPermission;
|
||||
this.requireUsagePermissions = fields.requireUsagePermissions;
|
||||
this.maxQuoteVerificationAge = fields.maxQuoteVerificationAge;
|
||||
this.reward = fields.reward;
|
||||
this.lastHeartbeat = fields.lastHeartbeat;
|
||||
this.nodeTimeout = fields.nodeTimeout;
|
||||
this.currIdx = fields.currIdx;
|
||||
this.gcIdx = fields.gcIdx;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey
|
||||
): Promise<AttestationQueueAccountData | null> {
|
||||
const info = await program.connection.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
program: SwitchboardProgram,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<AttestationQueueAccountData | null>> {
|
||||
const infos = await program.connection.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): AttestationQueueAccountData {
|
||||
if (!data.slice(0, 8).equals(AttestationQueueAccountData.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = AttestationQueueAccountData.layout.decode(data.slice(8));
|
||||
|
||||
return new AttestationQueueAccountData({
|
||||
authority: dec.authority,
|
||||
mrEnclaves: dec.mrEnclaves,
|
||||
mrEnclavesLen: dec.mrEnclavesLen,
|
||||
data: dec.data,
|
||||
dataLen: dec.dataLen,
|
||||
allowAuthorityOverrideAfter: dec.allowAuthorityOverrideAfter,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
dec.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: dec.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: dec.maxQuoteVerificationAge,
|
||||
reward: dec.reward,
|
||||
lastHeartbeat: dec.lastHeartbeat,
|
||||
nodeTimeout: dec.nodeTimeout,
|
||||
currIdx: dec.currIdx,
|
||||
gcIdx: dec.gcIdx,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): AttestationQueueAccountDataJSON {
|
||||
return {
|
||||
authority: this.authority.toString(),
|
||||
mrEnclaves: this.mrEnclaves,
|
||||
mrEnclavesLen: this.mrEnclavesLen,
|
||||
data: this.data.map((item) => item.toString()),
|
||||
dataLen: this.dataLen,
|
||||
allowAuthorityOverrideAfter: this.allowAuthorityOverrideAfter.toString(),
|
||||
requireAuthorityHeartbeatPermission:
|
||||
this.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: this.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: this.maxQuoteVerificationAge.toString(),
|
||||
reward: this.reward,
|
||||
lastHeartbeat: this.lastHeartbeat.toString(),
|
||||
nodeTimeout: this.nodeTimeout.toString(),
|
||||
currIdx: this.currIdx,
|
||||
gcIdx: this.gcIdx,
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationQueueAccountDataJSON
|
||||
): AttestationQueueAccountData {
|
||||
return new AttestationQueueAccountData({
|
||||
authority: new PublicKey(obj.authority),
|
||||
mrEnclaves: obj.mrEnclaves,
|
||||
mrEnclavesLen: obj.mrEnclavesLen,
|
||||
data: obj.data.map((item) => new PublicKey(item)),
|
||||
dataLen: obj.dataLen,
|
||||
allowAuthorityOverrideAfter: new BN(obj.allowAuthorityOverrideAfter),
|
||||
requireAuthorityHeartbeatPermission:
|
||||
obj.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: obj.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: new BN(obj.maxQuoteVerificationAge),
|
||||
reward: obj.reward,
|
||||
lastHeartbeat: new BN(obj.lastHeartbeat),
|
||||
nodeTimeout: new BN(obj.nodeTimeout),
|
||||
currIdx: obj.currIdx,
|
||||
gcIdx: obj.gcIdx,
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionAccountDataFields {
|
||||
name: Array<number>;
|
||||
metadata: Array<number>;
|
||||
authority: PublicKey;
|
||||
/** */
|
||||
containerRegistry: Array<number>;
|
||||
container: Array<number>;
|
||||
version: Array<number>;
|
||||
/** */
|
||||
attestationQueue: PublicKey;
|
||||
queueIdx: number;
|
||||
lastExecutionTimestamp: BN;
|
||||
nextAllowedTimestamp: BN;
|
||||
schedule: Array<number>;
|
||||
escrow: PublicKey;
|
||||
status: types.FunctionStatusKind;
|
||||
createdAt: BN;
|
||||
isTriggered: boolean;
|
||||
addressLookupTable: PublicKey;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface FunctionAccountDataJSON {
|
||||
name: Array<number>;
|
||||
metadata: Array<number>;
|
||||
authority: string;
|
||||
/** */
|
||||
containerRegistry: Array<number>;
|
||||
container: Array<number>;
|
||||
version: Array<number>;
|
||||
/** */
|
||||
attestationQueue: string;
|
||||
queueIdx: number;
|
||||
lastExecutionTimestamp: string;
|
||||
nextAllowedTimestamp: string;
|
||||
schedule: Array<number>;
|
||||
escrow: string;
|
||||
status: types.FunctionStatusJSON;
|
||||
createdAt: string;
|
||||
isTriggered: boolean;
|
||||
addressLookupTable: string;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class FunctionAccountData {
|
||||
readonly name: Array<number>;
|
||||
readonly metadata: Array<number>;
|
||||
readonly authority: PublicKey;
|
||||
/** */
|
||||
readonly containerRegistry: Array<number>;
|
||||
readonly container: Array<number>;
|
||||
readonly version: Array<number>;
|
||||
/** */
|
||||
readonly attestationQueue: PublicKey;
|
||||
readonly queueIdx: number;
|
||||
readonly lastExecutionTimestamp: BN;
|
||||
readonly nextAllowedTimestamp: BN;
|
||||
readonly schedule: Array<number>;
|
||||
readonly escrow: PublicKey;
|
||||
readonly status: types.FunctionStatusKind;
|
||||
readonly createdAt: BN;
|
||||
readonly isTriggered: boolean;
|
||||
readonly addressLookupTable: PublicKey;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
76, 139, 47, 44, 240, 182, 148, 200,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.array(borsh.u8(), 64, "name"),
|
||||
borsh.array(borsh.u8(), 256, "metadata"),
|
||||
borsh.publicKey("authority"),
|
||||
borsh.array(borsh.u8(), 64, "containerRegistry"),
|
||||
borsh.array(borsh.u8(), 64, "container"),
|
||||
borsh.array(borsh.u8(), 32, "version"),
|
||||
borsh.publicKey("attestationQueue"),
|
||||
borsh.u32("queueIdx"),
|
||||
borsh.i64("lastExecutionTimestamp"),
|
||||
borsh.i64("nextAllowedTimestamp"),
|
||||
borsh.array(borsh.u8(), 64, "schedule"),
|
||||
borsh.publicKey("escrow"),
|
||||
types.FunctionStatus.layout("status"),
|
||||
borsh.i64("createdAt"),
|
||||
borsh.bool("isTriggered"),
|
||||
borsh.publicKey("addressLookupTable"),
|
||||
borsh.array(borsh.u8(), 991, "ebuf"),
|
||||
]);
|
||||
|
||||
constructor(fields: FunctionAccountDataFields) {
|
||||
this.name = fields.name;
|
||||
this.metadata = fields.metadata;
|
||||
this.authority = fields.authority;
|
||||
this.containerRegistry = fields.containerRegistry;
|
||||
this.container = fields.container;
|
||||
this.version = fields.version;
|
||||
this.attestationQueue = fields.attestationQueue;
|
||||
this.queueIdx = fields.queueIdx;
|
||||
this.lastExecutionTimestamp = fields.lastExecutionTimestamp;
|
||||
this.nextAllowedTimestamp = fields.nextAllowedTimestamp;
|
||||
this.schedule = fields.schedule;
|
||||
this.escrow = fields.escrow;
|
||||
this.status = fields.status;
|
||||
this.createdAt = fields.createdAt;
|
||||
this.isTriggered = fields.isTriggered;
|
||||
this.addressLookupTable = fields.addressLookupTable;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey
|
||||
): Promise<FunctionAccountData | null> {
|
||||
const info = await program.connection.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
program: SwitchboardProgram,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<FunctionAccountData | null>> {
|
||||
const infos = await program.connection.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): FunctionAccountData {
|
||||
if (!data.slice(0, 8).equals(FunctionAccountData.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = FunctionAccountData.layout.decode(data.slice(8));
|
||||
|
||||
return new FunctionAccountData({
|
||||
name: dec.name,
|
||||
metadata: dec.metadata,
|
||||
authority: dec.authority,
|
||||
containerRegistry: dec.containerRegistry,
|
||||
container: dec.container,
|
||||
version: dec.version,
|
||||
attestationQueue: dec.attestationQueue,
|
||||
queueIdx: dec.queueIdx,
|
||||
lastExecutionTimestamp: dec.lastExecutionTimestamp,
|
||||
nextAllowedTimestamp: dec.nextAllowedTimestamp,
|
||||
schedule: dec.schedule,
|
||||
escrow: dec.escrow,
|
||||
status: types.FunctionStatus.fromDecoded(dec.status),
|
||||
createdAt: dec.createdAt,
|
||||
isTriggered: dec.isTriggered,
|
||||
addressLookupTable: dec.addressLookupTable,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): FunctionAccountDataJSON {
|
||||
return {
|
||||
name: this.name,
|
||||
metadata: this.metadata,
|
||||
authority: this.authority.toString(),
|
||||
containerRegistry: this.containerRegistry,
|
||||
container: this.container,
|
||||
version: this.version,
|
||||
attestationQueue: this.attestationQueue.toString(),
|
||||
queueIdx: this.queueIdx,
|
||||
lastExecutionTimestamp: this.lastExecutionTimestamp.toString(),
|
||||
nextAllowedTimestamp: this.nextAllowedTimestamp.toString(),
|
||||
schedule: this.schedule,
|
||||
escrow: this.escrow.toString(),
|
||||
status: this.status.toJSON(),
|
||||
createdAt: this.createdAt.toString(),
|
||||
isTriggered: this.isTriggered,
|
||||
addressLookupTable: this.addressLookupTable.toString(),
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FunctionAccountDataJSON): FunctionAccountData {
|
||||
return new FunctionAccountData({
|
||||
name: obj.name,
|
||||
metadata: obj.metadata,
|
||||
authority: new PublicKey(obj.authority),
|
||||
containerRegistry: obj.containerRegistry,
|
||||
container: obj.container,
|
||||
version: obj.version,
|
||||
attestationQueue: new PublicKey(obj.attestationQueue),
|
||||
queueIdx: obj.queueIdx,
|
||||
lastExecutionTimestamp: new BN(obj.lastExecutionTimestamp),
|
||||
nextAllowedTimestamp: new BN(obj.nextAllowedTimestamp),
|
||||
schedule: obj.schedule,
|
||||
escrow: new PublicKey(obj.escrow),
|
||||
status: types.FunctionStatus.fromJSON(obj.status),
|
||||
createdAt: new BN(obj.createdAt),
|
||||
isTriggered: obj.isTriggered,
|
||||
addressLookupTable: new PublicKey(obj.addressLookupTable),
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
@ -6,7 +6,7 @@ import { Connection, PublicKey } from "@solana/web3.js";
|
|||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteAccountDataFields {
|
||||
delegatedSecuredSigner: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
bump: number;
|
||||
/** TODO: Add description */
|
||||
quoteRegistry: Array<number>;
|
||||
|
@ -22,11 +22,13 @@ export interface QuoteAccountDataFields {
|
|||
isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
lastHeartbeat: BN;
|
||||
authority: PublicKey;
|
||||
createdAt: BN;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface QuoteAccountDataJSON {
|
||||
delegatedSecuredSigner: string;
|
||||
securedSigner: string;
|
||||
bump: number;
|
||||
/** TODO: Add description */
|
||||
quoteRegistry: Array<number>;
|
||||
|
@ -42,11 +44,13 @@ export interface QuoteAccountDataJSON {
|
|||
isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
lastHeartbeat: string;
|
||||
authority: string;
|
||||
createdAt: string;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class QuoteAccountData {
|
||||
readonly delegatedSecuredSigner: PublicKey;
|
||||
readonly securedSigner: PublicKey;
|
||||
readonly bump: number;
|
||||
/** TODO: Add description */
|
||||
readonly quoteRegistry: Array<number>;
|
||||
|
@ -62,6 +66,8 @@ export class QuoteAccountData {
|
|||
readonly isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
readonly lastHeartbeat: BN;
|
||||
readonly authority: PublicKey;
|
||||
readonly createdAt: BN;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
|
@ -69,7 +75,7 @@ export class QuoteAccountData {
|
|||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.publicKey("delegatedSecuredSigner"),
|
||||
borsh.publicKey("securedSigner"),
|
||||
borsh.u8("bump"),
|
||||
borsh.array(borsh.u8(), 32, "quoteRegistry"),
|
||||
borsh.array(borsh.u8(), 64, "registryKey"),
|
||||
|
@ -80,11 +86,13 @@ export class QuoteAccountData {
|
|||
borsh.i64("validUntil"),
|
||||
borsh.bool("isOnQueue"),
|
||||
borsh.i64("lastHeartbeat"),
|
||||
borsh.array(borsh.u8(), 1024, "ebuf"),
|
||||
borsh.publicKey("authority"),
|
||||
borsh.i64("createdAt"),
|
||||
borsh.array(borsh.u8(), 992, "ebuf"),
|
||||
]);
|
||||
|
||||
constructor(fields: QuoteAccountDataFields) {
|
||||
this.delegatedSecuredSigner = fields.delegatedSecuredSigner;
|
||||
this.securedSigner = fields.securedSigner;
|
||||
this.bump = fields.bump;
|
||||
this.quoteRegistry = fields.quoteRegistry;
|
||||
this.registryKey = fields.registryKey;
|
||||
|
@ -95,6 +103,8 @@ export class QuoteAccountData {
|
|||
this.validUntil = fields.validUntil;
|
||||
this.isOnQueue = fields.isOnQueue;
|
||||
this.lastHeartbeat = fields.lastHeartbeat;
|
||||
this.authority = fields.authority;
|
||||
this.createdAt = fields.createdAt;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
|
@ -107,7 +117,7 @@ export class QuoteAccountData {
|
|||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.programId)) {
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
|
@ -124,7 +134,7 @@ export class QuoteAccountData {
|
|||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.programId)) {
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
|
@ -140,7 +150,7 @@ export class QuoteAccountData {
|
|||
const dec = QuoteAccountData.layout.decode(data.slice(8));
|
||||
|
||||
return new QuoteAccountData({
|
||||
delegatedSecuredSigner: dec.delegatedSecuredSigner,
|
||||
securedSigner: dec.securedSigner,
|
||||
bump: dec.bump,
|
||||
quoteRegistry: dec.quoteRegistry,
|
||||
registryKey: dec.registryKey,
|
||||
|
@ -151,13 +161,15 @@ export class QuoteAccountData {
|
|||
validUntil: dec.validUntil,
|
||||
isOnQueue: dec.isOnQueue,
|
||||
lastHeartbeat: dec.lastHeartbeat,
|
||||
authority: dec.authority,
|
||||
createdAt: dec.createdAt,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): QuoteAccountDataJSON {
|
||||
return {
|
||||
delegatedSecuredSigner: this.delegatedSecuredSigner.toString(),
|
||||
securedSigner: this.securedSigner.toString(),
|
||||
bump: this.bump,
|
||||
quoteRegistry: this.quoteRegistry,
|
||||
registryKey: this.registryKey,
|
||||
|
@ -168,13 +180,15 @@ export class QuoteAccountData {
|
|||
validUntil: this.validUntil.toString(),
|
||||
isOnQueue: this.isOnQueue,
|
||||
lastHeartbeat: this.lastHeartbeat.toString(),
|
||||
authority: this.authority.toString(),
|
||||
createdAt: this.createdAt.toString(),
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteAccountDataJSON): QuoteAccountData {
|
||||
return new QuoteAccountData({
|
||||
delegatedSecuredSigner: new PublicKey(obj.delegatedSecuredSigner),
|
||||
securedSigner: new PublicKey(obj.securedSigner),
|
||||
bump: obj.bump,
|
||||
quoteRegistry: obj.quoteRegistry,
|
||||
registryKey: obj.registryKey,
|
||||
|
@ -185,6 +199,8 @@ export class QuoteAccountData {
|
|||
validUntil: new BN(obj.validUntil),
|
||||
isOnQueue: obj.isOnQueue,
|
||||
lastHeartbeat: new BN(obj.lastHeartbeat),
|
||||
authority: new PublicKey(obj.authority),
|
||||
createdAt: new BN(obj.createdAt),
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { Connection, PublicKey } from "@solana/web3.js";
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface StateFields {
|
||||
bump: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface StateJSON {
|
||||
bump: number;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class State {
|
||||
readonly bump: number;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
216, 146, 107, 94, 104, 75, 182, 177,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.u8("bump"),
|
||||
borsh.array(borsh.u8(), 2048, "ebuf"),
|
||||
]);
|
||||
|
||||
constructor(fields: StateFields) {
|
||||
this.bump = fields.bump;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey
|
||||
): Promise<State | null> {
|
||||
const info = await program.connection.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
program: SwitchboardProgram,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<State | null>> {
|
||||
const infos = await program.connection.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map((info) => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.attestationProgramId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): State {
|
||||
if (!data.slice(0, 8).equals(State.discriminator)) {
|
||||
throw new Error("invalid account discriminator");
|
||||
}
|
||||
|
||||
const dec = State.layout.decode(data.slice(8));
|
||||
|
||||
return new State({
|
||||
bump: dec.bump,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): StateJSON {
|
||||
return {
|
||||
bump: this.bump,
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: StateJSON): State {
|
||||
return new State({
|
||||
bump: obj.bump,
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
export type {
|
||||
AttestationPermissionAccountDataFields,
|
||||
AttestationPermissionAccountDataJSON,
|
||||
} from "./AttestationPermissionAccountData.js";
|
||||
export { AttestationPermissionAccountData } from "./AttestationPermissionAccountData.js";
|
||||
export type {
|
||||
AttestationQueueAccountDataFields,
|
||||
AttestationQueueAccountDataJSON,
|
||||
} from "./AttestationQueueAccountData.js";
|
||||
export { AttestationQueueAccountData } from "./AttestationQueueAccountData.js";
|
||||
export type {
|
||||
FunctionAccountDataFields,
|
||||
FunctionAccountDataJSON,
|
||||
} from "./FunctionAccountData.js";
|
||||
export { FunctionAccountData } from "./FunctionAccountData.js";
|
||||
export type {
|
||||
QuoteAccountDataFields,
|
||||
QuoteAccountDataJSON,
|
||||
} from "./QuoteAccountData.js";
|
||||
export { QuoteAccountData } from "./QuoteAccountData.js";
|
||||
export type { StateFields, StateJSON } from "./State.js";
|
||||
export { State } from "./State.js";
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
export type AnchorError =
|
||||
| InstructionMissing
|
||||
| InstructionFallbackNotFound
|
||||
|
@ -58,68 +58,68 @@ export type AnchorError =
|
|||
export class InstructionMissing extends Error {
|
||||
static readonly code = 100;
|
||||
readonly code = 100;
|
||||
readonly name = 'InstructionMissing';
|
||||
readonly msg = '8 byte instruction identifier not provided';
|
||||
readonly name = "InstructionMissing";
|
||||
readonly msg = "8 byte instruction identifier not provided";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('100: 8 byte instruction identifier not provided');
|
||||
super("100: 8 byte instruction identifier not provided");
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionFallbackNotFound extends Error {
|
||||
static readonly code = 101;
|
||||
readonly code = 101;
|
||||
readonly name = 'InstructionFallbackNotFound';
|
||||
readonly msg = 'Fallback functions are not supported';
|
||||
readonly name = "InstructionFallbackNotFound";
|
||||
readonly msg = "Fallback functions are not supported";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('101: Fallback functions are not supported');
|
||||
super("101: Fallback functions are not supported");
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotDeserialize extends Error {
|
||||
static readonly code = 102;
|
||||
readonly code = 102;
|
||||
readonly name = 'InstructionDidNotDeserialize';
|
||||
readonly msg = 'The program could not deserialize the given instruction';
|
||||
readonly name = "InstructionDidNotDeserialize";
|
||||
readonly msg = "The program could not deserialize the given instruction";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('102: The program could not deserialize the given instruction');
|
||||
super("102: The program could not deserialize the given instruction");
|
||||
}
|
||||
}
|
||||
|
||||
export class InstructionDidNotSerialize extends Error {
|
||||
static readonly code = 103;
|
||||
readonly code = 103;
|
||||
readonly name = 'InstructionDidNotSerialize';
|
||||
readonly msg = 'The program could not serialize the given instruction';
|
||||
readonly name = "InstructionDidNotSerialize";
|
||||
readonly msg = "The program could not serialize the given instruction";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('103: The program could not serialize the given instruction');
|
||||
super("103: The program could not serialize the given instruction");
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionStub extends Error {
|
||||
static readonly code = 1000;
|
||||
readonly code = 1000;
|
||||
readonly name = 'IdlInstructionStub';
|
||||
readonly msg = 'The program was compiled without idl instructions';
|
||||
readonly name = "IdlInstructionStub";
|
||||
readonly msg = "The program was compiled without idl instructions";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('1000: The program was compiled without idl instructions');
|
||||
super("1000: The program was compiled without idl instructions");
|
||||
}
|
||||
}
|
||||
|
||||
export class IdlInstructionInvalidProgram extends Error {
|
||||
static readonly code = 1001;
|
||||
readonly code = 1001;
|
||||
readonly name = 'IdlInstructionInvalidProgram';
|
||||
readonly name = "IdlInstructionInvalidProgram";
|
||||
readonly msg =
|
||||
'The transaction was given an invalid program for the IDL instruction';
|
||||
"The transaction was given an invalid program for the IDL instruction";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super(
|
||||
'1001: The transaction was given an invalid program for the IDL instruction'
|
||||
"1001: The transaction was given an invalid program for the IDL instruction"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -127,387 +127,387 @@ export class IdlInstructionInvalidProgram extends Error {
|
|||
export class ConstraintMut extends Error {
|
||||
static readonly code = 2000;
|
||||
readonly code = 2000;
|
||||
readonly name = 'ConstraintMut';
|
||||
readonly msg = 'A mut constraint was violated';
|
||||
readonly name = "ConstraintMut";
|
||||
readonly msg = "A mut constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2000: A mut constraint was violated');
|
||||
super("2000: A mut constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintHasOne extends Error {
|
||||
static readonly code = 2001;
|
||||
readonly code = 2001;
|
||||
readonly name = 'ConstraintHasOne';
|
||||
readonly msg = 'A has_one constraint was violated';
|
||||
readonly name = "ConstraintHasOne";
|
||||
readonly msg = "A has_one constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2001: A has_one constraint was violated');
|
||||
super("2001: A has_one constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSigner extends Error {
|
||||
static readonly code = 2002;
|
||||
readonly code = 2002;
|
||||
readonly name = 'ConstraintSigner';
|
||||
readonly msg = 'A signer constraint was violated';
|
||||
readonly name = "ConstraintSigner";
|
||||
readonly msg = "A signer constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2002: A signer constraint was violated');
|
||||
super("2002: A signer constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRaw extends Error {
|
||||
static readonly code = 2003;
|
||||
readonly code = 2003;
|
||||
readonly name = 'ConstraintRaw';
|
||||
readonly msg = 'A raw constraint was violated';
|
||||
readonly name = "ConstraintRaw";
|
||||
readonly msg = "A raw constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2003: A raw constraint was violated');
|
||||
super("2003: A raw constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintOwner extends Error {
|
||||
static readonly code = 2004;
|
||||
readonly code = 2004;
|
||||
readonly name = 'ConstraintOwner';
|
||||
readonly msg = 'An owner constraint was violated';
|
||||
readonly name = "ConstraintOwner";
|
||||
readonly msg = "An owner constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2004: An owner constraint was violated');
|
||||
super("2004: An owner constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintRentExempt extends Error {
|
||||
static readonly code = 2005;
|
||||
readonly code = 2005;
|
||||
readonly name = 'ConstraintRentExempt';
|
||||
readonly msg = 'A rent exemption constraint was violated';
|
||||
readonly name = "ConstraintRentExempt";
|
||||
readonly msg = "A rent exemption constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2005: A rent exemption constraint was violated');
|
||||
super("2005: A rent exemption constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSeeds extends Error {
|
||||
static readonly code = 2006;
|
||||
readonly code = 2006;
|
||||
readonly name = 'ConstraintSeeds';
|
||||
readonly msg = 'A seeds constraint was violated';
|
||||
readonly name = "ConstraintSeeds";
|
||||
readonly msg = "A seeds constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2006: A seeds constraint was violated');
|
||||
super("2006: A seeds constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintExecutable extends Error {
|
||||
static readonly code = 2007;
|
||||
readonly code = 2007;
|
||||
readonly name = 'ConstraintExecutable';
|
||||
readonly msg = 'An executable constraint was violated';
|
||||
readonly name = "ConstraintExecutable";
|
||||
readonly msg = "An executable constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2007: An executable constraint was violated');
|
||||
super("2007: An executable constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintState extends Error {
|
||||
static readonly code = 2008;
|
||||
readonly code = 2008;
|
||||
readonly name = 'ConstraintState';
|
||||
readonly msg = 'A state constraint was violated';
|
||||
readonly name = "ConstraintState";
|
||||
readonly msg = "A state constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2008: A state constraint was violated');
|
||||
super("2008: A state constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociated extends Error {
|
||||
static readonly code = 2009;
|
||||
readonly code = 2009;
|
||||
readonly name = 'ConstraintAssociated';
|
||||
readonly msg = 'An associated constraint was violated';
|
||||
readonly name = "ConstraintAssociated";
|
||||
readonly msg = "An associated constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2009: An associated constraint was violated');
|
||||
super("2009: An associated constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAssociatedInit extends Error {
|
||||
static readonly code = 2010;
|
||||
readonly code = 2010;
|
||||
readonly name = 'ConstraintAssociatedInit';
|
||||
readonly msg = 'An associated init constraint was violated';
|
||||
readonly name = "ConstraintAssociatedInit";
|
||||
readonly msg = "An associated init constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2010: An associated init constraint was violated');
|
||||
super("2010: An associated init constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintClose extends Error {
|
||||
static readonly code = 2011;
|
||||
readonly code = 2011;
|
||||
readonly name = 'ConstraintClose';
|
||||
readonly msg = 'A close constraint was violated';
|
||||
readonly name = "ConstraintClose";
|
||||
readonly msg = "A close constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2011: A close constraint was violated');
|
||||
super("2011: A close constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintAddress extends Error {
|
||||
static readonly code = 2012;
|
||||
readonly code = 2012;
|
||||
readonly name = 'ConstraintAddress';
|
||||
readonly msg = 'An address constraint was violated';
|
||||
readonly name = "ConstraintAddress";
|
||||
readonly msg = "An address constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2012: An address constraint was violated');
|
||||
super("2012: An address constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintZero extends Error {
|
||||
static readonly code = 2013;
|
||||
readonly code = 2013;
|
||||
readonly name = 'ConstraintZero';
|
||||
readonly msg = 'Expected zero account discriminant';
|
||||
readonly name = "ConstraintZero";
|
||||
readonly msg = "Expected zero account discriminant";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2013: Expected zero account discriminant');
|
||||
super("2013: Expected zero account discriminant");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenMint extends Error {
|
||||
static readonly code = 2014;
|
||||
readonly code = 2014;
|
||||
readonly name = 'ConstraintTokenMint';
|
||||
readonly msg = 'A token mint constraint was violated';
|
||||
readonly name = "ConstraintTokenMint";
|
||||
readonly msg = "A token mint constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2014: A token mint constraint was violated');
|
||||
super("2014: A token mint constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintTokenOwner extends Error {
|
||||
static readonly code = 2015;
|
||||
readonly code = 2015;
|
||||
readonly name = 'ConstraintTokenOwner';
|
||||
readonly msg = 'A token owner constraint was violated';
|
||||
readonly name = "ConstraintTokenOwner";
|
||||
readonly msg = "A token owner constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2015: A token owner constraint was violated');
|
||||
super("2015: A token owner constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintMintAuthority extends Error {
|
||||
static readonly code = 2016;
|
||||
readonly code = 2016;
|
||||
readonly name = 'ConstraintMintMintAuthority';
|
||||
readonly msg = 'A mint mint authority constraint was violated';
|
||||
readonly name = "ConstraintMintMintAuthority";
|
||||
readonly msg = "A mint mint authority constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2016: A mint mint authority constraint was violated');
|
||||
super("2016: A mint mint authority constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintFreezeAuthority extends Error {
|
||||
static readonly code = 2017;
|
||||
readonly code = 2017;
|
||||
readonly name = 'ConstraintMintFreezeAuthority';
|
||||
readonly msg = 'A mint freeze authority constraint was violated';
|
||||
readonly name = "ConstraintMintFreezeAuthority";
|
||||
readonly msg = "A mint freeze authority constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2017: A mint freeze authority constraint was violated');
|
||||
super("2017: A mint freeze authority constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintMintDecimals extends Error {
|
||||
static readonly code = 2018;
|
||||
readonly code = 2018;
|
||||
readonly name = 'ConstraintMintDecimals';
|
||||
readonly msg = 'A mint decimals constraint was violated';
|
||||
readonly name = "ConstraintMintDecimals";
|
||||
readonly msg = "A mint decimals constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2018: A mint decimals constraint was violated');
|
||||
super("2018: A mint decimals constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class ConstraintSpace extends Error {
|
||||
static readonly code = 2019;
|
||||
readonly code = 2019;
|
||||
readonly name = 'ConstraintSpace';
|
||||
readonly msg = 'A space constraint was violated';
|
||||
readonly name = "ConstraintSpace";
|
||||
readonly msg = "A space constraint was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2019: A space constraint was violated');
|
||||
super("2019: A space constraint was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireViolated extends Error {
|
||||
static readonly code = 2500;
|
||||
readonly code = 2500;
|
||||
readonly name = 'RequireViolated';
|
||||
readonly msg = 'A require expression was violated';
|
||||
readonly name = "RequireViolated";
|
||||
readonly msg = "A require expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2500: A require expression was violated');
|
||||
super("2500: A require expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireEqViolated extends Error {
|
||||
static readonly code = 2501;
|
||||
readonly code = 2501;
|
||||
readonly name = 'RequireEqViolated';
|
||||
readonly msg = 'A require_eq expression was violated';
|
||||
readonly name = "RequireEqViolated";
|
||||
readonly msg = "A require_eq expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2501: A require_eq expression was violated');
|
||||
super("2501: A require_eq expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysEqViolated extends Error {
|
||||
static readonly code = 2502;
|
||||
readonly code = 2502;
|
||||
readonly name = 'RequireKeysEqViolated';
|
||||
readonly msg = 'A require_keys_eq expression was violated';
|
||||
readonly name = "RequireKeysEqViolated";
|
||||
readonly msg = "A require_keys_eq expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2502: A require_keys_eq expression was violated');
|
||||
super("2502: A require_keys_eq expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireNeqViolated extends Error {
|
||||
static readonly code = 2503;
|
||||
readonly code = 2503;
|
||||
readonly name = 'RequireNeqViolated';
|
||||
readonly msg = 'A require_neq expression was violated';
|
||||
readonly name = "RequireNeqViolated";
|
||||
readonly msg = "A require_neq expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2503: A require_neq expression was violated');
|
||||
super("2503: A require_neq expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireKeysNeqViolated extends Error {
|
||||
static readonly code = 2504;
|
||||
readonly code = 2504;
|
||||
readonly name = 'RequireKeysNeqViolated';
|
||||
readonly msg = 'A require_keys_neq expression was violated';
|
||||
readonly name = "RequireKeysNeqViolated";
|
||||
readonly msg = "A require_keys_neq expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2504: A require_keys_neq expression was violated');
|
||||
super("2504: A require_keys_neq expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGtViolated extends Error {
|
||||
static readonly code = 2505;
|
||||
readonly code = 2505;
|
||||
readonly name = 'RequireGtViolated';
|
||||
readonly msg = 'A require_gt expression was violated';
|
||||
readonly name = "RequireGtViolated";
|
||||
readonly msg = "A require_gt expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2505: A require_gt expression was violated');
|
||||
super("2505: A require_gt expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class RequireGteViolated extends Error {
|
||||
static readonly code = 2506;
|
||||
readonly code = 2506;
|
||||
readonly name = 'RequireGteViolated';
|
||||
readonly msg = 'A require_gte expression was violated';
|
||||
readonly name = "RequireGteViolated";
|
||||
readonly msg = "A require_gte expression was violated";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('2506: A require_gte expression was violated');
|
||||
super("2506: A require_gte expression was violated");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorAlreadySet extends Error {
|
||||
static readonly code = 3000;
|
||||
readonly code = 3000;
|
||||
readonly name = 'AccountDiscriminatorAlreadySet';
|
||||
readonly msg = 'The account discriminator was already set on this account';
|
||||
readonly name = "AccountDiscriminatorAlreadySet";
|
||||
readonly msg = "The account discriminator was already set on this account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3000: The account discriminator was already set on this account');
|
||||
super("3000: The account discriminator was already set on this account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorNotFound extends Error {
|
||||
static readonly code = 3001;
|
||||
readonly code = 3001;
|
||||
readonly name = 'AccountDiscriminatorNotFound';
|
||||
readonly msg = 'No 8 byte discriminator was found on the account';
|
||||
readonly name = "AccountDiscriminatorNotFound";
|
||||
readonly msg = "No 8 byte discriminator was found on the account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3001: No 8 byte discriminator was found on the account');
|
||||
super("3001: No 8 byte discriminator was found on the account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDiscriminatorMismatch extends Error {
|
||||
static readonly code = 3002;
|
||||
readonly code = 3002;
|
||||
readonly name = 'AccountDiscriminatorMismatch';
|
||||
readonly msg = '8 byte discriminator did not match what was expected';
|
||||
readonly name = "AccountDiscriminatorMismatch";
|
||||
readonly msg = "8 byte discriminator did not match what was expected";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3002: 8 byte discriminator did not match what was expected');
|
||||
super("3002: 8 byte discriminator did not match what was expected");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotDeserialize extends Error {
|
||||
static readonly code = 3003;
|
||||
readonly code = 3003;
|
||||
readonly name = 'AccountDidNotDeserialize';
|
||||
readonly msg = 'Failed to deserialize the account';
|
||||
readonly name = "AccountDidNotDeserialize";
|
||||
readonly msg = "Failed to deserialize the account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3003: Failed to deserialize the account');
|
||||
super("3003: Failed to deserialize the account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountDidNotSerialize extends Error {
|
||||
static readonly code = 3004;
|
||||
readonly code = 3004;
|
||||
readonly name = 'AccountDidNotSerialize';
|
||||
readonly msg = 'Failed to serialize the account';
|
||||
readonly name = "AccountDidNotSerialize";
|
||||
readonly msg = "Failed to serialize the account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3004: Failed to serialize the account');
|
||||
super("3004: Failed to serialize the account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotEnoughKeys extends Error {
|
||||
static readonly code = 3005;
|
||||
readonly code = 3005;
|
||||
readonly name = 'AccountNotEnoughKeys';
|
||||
readonly msg = 'Not enough account keys given to the instruction';
|
||||
readonly name = "AccountNotEnoughKeys";
|
||||
readonly msg = "Not enough account keys given to the instruction";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3005: Not enough account keys given to the instruction');
|
||||
super("3005: Not enough account keys given to the instruction");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotMutable extends Error {
|
||||
static readonly code = 3006;
|
||||
readonly code = 3006;
|
||||
readonly name = 'AccountNotMutable';
|
||||
readonly msg = 'The given account is not mutable';
|
||||
readonly name = "AccountNotMutable";
|
||||
readonly msg = "The given account is not mutable";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3006: The given account is not mutable');
|
||||
super("3006: The given account is not mutable");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountOwnedByWrongProgram extends Error {
|
||||
static readonly code = 3007;
|
||||
readonly code = 3007;
|
||||
readonly name = 'AccountOwnedByWrongProgram';
|
||||
readonly name = "AccountOwnedByWrongProgram";
|
||||
readonly msg =
|
||||
'The given account is owned by a different program than expected';
|
||||
"The given account is owned by a different program than expected";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super(
|
||||
'3007: The given account is owned by a different program than expected'
|
||||
"3007: The given account is owned by a different program than expected"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -515,101 +515,101 @@ export class AccountOwnedByWrongProgram extends Error {
|
|||
export class InvalidProgramId extends Error {
|
||||
static readonly code = 3008;
|
||||
readonly code = 3008;
|
||||
readonly name = 'InvalidProgramId';
|
||||
readonly msg = 'Program ID was not as expected';
|
||||
readonly name = "InvalidProgramId";
|
||||
readonly msg = "Program ID was not as expected";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3008: Program ID was not as expected');
|
||||
super("3008: Program ID was not as expected");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidProgramExecutable extends Error {
|
||||
static readonly code = 3009;
|
||||
readonly code = 3009;
|
||||
readonly name = 'InvalidProgramExecutable';
|
||||
readonly msg = 'Program account is not executable';
|
||||
readonly name = "InvalidProgramExecutable";
|
||||
readonly msg = "Program account is not executable";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3009: Program account is not executable');
|
||||
super("3009: Program account is not executable");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSigner extends Error {
|
||||
static readonly code = 3010;
|
||||
readonly code = 3010;
|
||||
readonly name = 'AccountNotSigner';
|
||||
readonly msg = 'The given account did not sign';
|
||||
readonly name = "AccountNotSigner";
|
||||
readonly msg = "The given account did not sign";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3010: The given account did not sign');
|
||||
super("3010: The given account did not sign");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotSystemOwned extends Error {
|
||||
static readonly code = 3011;
|
||||
readonly code = 3011;
|
||||
readonly name = 'AccountNotSystemOwned';
|
||||
readonly msg = 'The given account is not owned by the system program';
|
||||
readonly name = "AccountNotSystemOwned";
|
||||
readonly msg = "The given account is not owned by the system program";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3011: The given account is not owned by the system program');
|
||||
super("3011: The given account is not owned by the system program");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotInitialized extends Error {
|
||||
static readonly code = 3012;
|
||||
readonly code = 3012;
|
||||
readonly name = 'AccountNotInitialized';
|
||||
readonly msg = 'The program expected this account to be already initialized';
|
||||
readonly name = "AccountNotInitialized";
|
||||
readonly msg = "The program expected this account to be already initialized";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3012: The program expected this account to be already initialized');
|
||||
super("3012: The program expected this account to be already initialized");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotProgramData extends Error {
|
||||
static readonly code = 3013;
|
||||
readonly code = 3013;
|
||||
readonly name = 'AccountNotProgramData';
|
||||
readonly msg = 'The given account is not a program data account';
|
||||
readonly name = "AccountNotProgramData";
|
||||
readonly msg = "The given account is not a program data account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3013: The given account is not a program data account');
|
||||
super("3013: The given account is not a program data account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountNotAssociatedTokenAccount extends Error {
|
||||
static readonly code = 3014;
|
||||
readonly code = 3014;
|
||||
readonly name = 'AccountNotAssociatedTokenAccount';
|
||||
readonly msg = 'The given account is not the associated token account';
|
||||
readonly name = "AccountNotAssociatedTokenAccount";
|
||||
readonly msg = "The given account is not the associated token account";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3014: The given account is not the associated token account');
|
||||
super("3014: The given account is not the associated token account");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountSysvarMismatch extends Error {
|
||||
static readonly code = 3015;
|
||||
readonly code = 3015;
|
||||
readonly name = 'AccountSysvarMismatch';
|
||||
readonly msg = 'The given public key does not match the required sysvar';
|
||||
readonly name = "AccountSysvarMismatch";
|
||||
readonly msg = "The given public key does not match the required sysvar";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3015: The given public key does not match the required sysvar');
|
||||
super("3015: The given public key does not match the required sysvar");
|
||||
}
|
||||
}
|
||||
|
||||
export class AccountReallocExceedsLimit extends Error {
|
||||
static readonly code = 3016;
|
||||
readonly code = 3016;
|
||||
readonly name = 'AccountReallocExceedsLimit';
|
||||
readonly name = "AccountReallocExceedsLimit";
|
||||
readonly msg =
|
||||
'The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit';
|
||||
"The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super(
|
||||
'3016: The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit'
|
||||
"3016: The account reallocation exceeds the MAX_PERMITTED_DATA_INCREASE limit"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -617,46 +617,46 @@ export class AccountReallocExceedsLimit extends Error {
|
|||
export class AccountDuplicateReallocs extends Error {
|
||||
static readonly code = 3017;
|
||||
readonly code = 3017;
|
||||
readonly name = 'AccountDuplicateReallocs';
|
||||
readonly msg = 'The account was duplicated for more than one reallocation';
|
||||
readonly name = "AccountDuplicateReallocs";
|
||||
readonly msg = "The account was duplicated for more than one reallocation";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('3017: The account was duplicated for more than one reallocation');
|
||||
super("3017: The account was duplicated for more than one reallocation");
|
||||
}
|
||||
}
|
||||
|
||||
export class StateInvalidAddress extends Error {
|
||||
static readonly code = 4000;
|
||||
readonly code = 4000;
|
||||
readonly name = 'StateInvalidAddress';
|
||||
readonly msg = 'The given state account does not have the correct address';
|
||||
readonly name = "StateInvalidAddress";
|
||||
readonly msg = "The given state account does not have the correct address";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('4000: The given state account does not have the correct address');
|
||||
super("4000: The given state account does not have the correct address");
|
||||
}
|
||||
}
|
||||
|
||||
export class DeclaredProgramIdMismatch extends Error {
|
||||
static readonly code = 4100;
|
||||
readonly code = 4100;
|
||||
readonly name = 'DeclaredProgramIdMismatch';
|
||||
readonly msg = 'The declared program id does not match the actual program id';
|
||||
readonly name = "DeclaredProgramIdMismatch";
|
||||
readonly msg = "The declared program id does not match the actual program id";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('4100: The declared program id does not match the actual program id');
|
||||
super("4100: The declared program id does not match the actual program id");
|
||||
}
|
||||
}
|
||||
|
||||
export class Deprecated extends Error {
|
||||
static readonly code = 5000;
|
||||
readonly code = 5000;
|
||||
readonly name = 'Deprecated';
|
||||
readonly name = "Deprecated";
|
||||
readonly msg =
|
||||
'The API being used is deprecated and should no longer be used';
|
||||
"The API being used is deprecated and should no longer be used";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super(
|
||||
'5000: The API being used is deprecated and should no longer be used'
|
||||
"5000: The API being used is deprecated and should no longer be used"
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,308 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
export type CustomError =
|
||||
| GenericError
|
||||
| InvalidQuoteError
|
||||
| QuoteExpiredError
|
||||
| InvalidNodeError
|
||||
| InsufficientQueueError
|
||||
| QueueFullError
|
||||
| InvalidSignerError
|
||||
| MrEnclaveAlreadyExists
|
||||
| MrEnclaveDoesntExist
|
||||
| MrEnclaveAtCapacity
|
||||
| PermissionDenied
|
||||
| InvalidConstraint
|
||||
| InvalidTimestamp
|
||||
| InvalidMrEnclave
|
||||
| InvalidReportData
|
||||
| InsufficientLoadAmountError
|
||||
| IncorrectObservedTimeError
|
||||
| InvalidQuoteMode
|
||||
| InvalidVerifierIdx
|
||||
| InvalidSelfVerifyRequest
|
||||
| IncorrectMrEnclave
|
||||
| InvalidResponder
|
||||
| InvalidAddressLookupAddress;
|
||||
|
||||
export class GenericError extends Error {
|
||||
static readonly code = 6000;
|
||||
readonly code = 6000;
|
||||
readonly name = "GenericError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6000: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidQuoteError extends Error {
|
||||
static readonly code = 6001;
|
||||
readonly code = 6001;
|
||||
readonly name = "InvalidQuoteError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6001: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class QuoteExpiredError extends Error {
|
||||
static readonly code = 6002;
|
||||
readonly code = 6002;
|
||||
readonly name = "QuoteExpiredError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6002: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidNodeError extends Error {
|
||||
static readonly code = 6003;
|
||||
readonly code = 6003;
|
||||
readonly name = "InvalidNodeError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6003: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InsufficientQueueError extends Error {
|
||||
static readonly code = 6004;
|
||||
readonly code = 6004;
|
||||
readonly name = "InsufficientQueueError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6004: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class QueueFullError extends Error {
|
||||
static readonly code = 6005;
|
||||
readonly code = 6005;
|
||||
readonly name = "QueueFullError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6005: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidSignerError extends Error {
|
||||
static readonly code = 6006;
|
||||
readonly code = 6006;
|
||||
readonly name = "InvalidSignerError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6006: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class MrEnclaveAlreadyExists extends Error {
|
||||
static readonly code = 6007;
|
||||
readonly code = 6007;
|
||||
readonly name = "MrEnclaveAlreadyExists";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6007: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class MrEnclaveDoesntExist extends Error {
|
||||
static readonly code = 6008;
|
||||
readonly code = 6008;
|
||||
readonly name = "MrEnclaveDoesntExist";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6008: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class MrEnclaveAtCapacity extends Error {
|
||||
static readonly code = 6009;
|
||||
readonly code = 6009;
|
||||
readonly name = "MrEnclaveAtCapacity";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6009: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class PermissionDenied extends Error {
|
||||
static readonly code = 6010;
|
||||
readonly code = 6010;
|
||||
readonly name = "PermissionDenied";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6010: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidConstraint extends Error {
|
||||
static readonly code = 6011;
|
||||
readonly code = 6011;
|
||||
readonly name = "InvalidConstraint";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6011: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidTimestamp extends Error {
|
||||
static readonly code = 6012;
|
||||
readonly code = 6012;
|
||||
readonly name = "InvalidTimestamp";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6012: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidMrEnclave extends Error {
|
||||
static readonly code = 6013;
|
||||
readonly code = 6013;
|
||||
readonly name = "InvalidMrEnclave";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6013: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidReportData extends Error {
|
||||
static readonly code = 6014;
|
||||
readonly code = 6014;
|
||||
readonly name = "InvalidReportData";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6014: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InsufficientLoadAmountError extends Error {
|
||||
static readonly code = 6015;
|
||||
readonly code = 6015;
|
||||
readonly name = "InsufficientLoadAmountError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6015: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class IncorrectObservedTimeError extends Error {
|
||||
static readonly code = 6016;
|
||||
readonly code = 6016;
|
||||
readonly name = "IncorrectObservedTimeError";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6016: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidQuoteMode extends Error {
|
||||
static readonly code = 6017;
|
||||
readonly code = 6017;
|
||||
readonly name = "InvalidQuoteMode";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6017: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidVerifierIdx extends Error {
|
||||
static readonly code = 6018;
|
||||
readonly code = 6018;
|
||||
readonly name = "InvalidVerifierIdx";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6018: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidSelfVerifyRequest extends Error {
|
||||
static readonly code = 6019;
|
||||
readonly code = 6019;
|
||||
readonly name = "InvalidSelfVerifyRequest";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6019: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class IncorrectMrEnclave extends Error {
|
||||
static readonly code = 6020;
|
||||
readonly code = 6020;
|
||||
readonly name = "IncorrectMrEnclave";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6020: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidResponder extends Error {
|
||||
static readonly code = 6021;
|
||||
readonly code = 6021;
|
||||
readonly name = "InvalidResponder";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6021: ");
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidAddressLookupAddress extends Error {
|
||||
static readonly code = 6022;
|
||||
readonly code = 6022;
|
||||
readonly name = "InvalidAddressLookupAddress";
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super("6022: ");
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number, logs?: string[]): CustomError | null {
|
||||
switch (code) {
|
||||
case 6000:
|
||||
return new GenericError(logs);
|
||||
case 6001:
|
||||
return new InvalidQuoteError(logs);
|
||||
case 6002:
|
||||
return new QuoteExpiredError(logs);
|
||||
case 6003:
|
||||
return new InvalidNodeError(logs);
|
||||
case 6004:
|
||||
return new InsufficientQueueError(logs);
|
||||
case 6005:
|
||||
return new QueueFullError(logs);
|
||||
case 6006:
|
||||
return new InvalidSignerError(logs);
|
||||
case 6007:
|
||||
return new MrEnclaveAlreadyExists(logs);
|
||||
case 6008:
|
||||
return new MrEnclaveDoesntExist(logs);
|
||||
case 6009:
|
||||
return new MrEnclaveAtCapacity(logs);
|
||||
case 6010:
|
||||
return new PermissionDenied(logs);
|
||||
case 6011:
|
||||
return new InvalidConstraint(logs);
|
||||
case 6012:
|
||||
return new InvalidTimestamp(logs);
|
||||
case 6013:
|
||||
return new InvalidMrEnclave(logs);
|
||||
case 6014:
|
||||
return new InvalidReportData(logs);
|
||||
case 6015:
|
||||
return new InsufficientLoadAmountError(logs);
|
||||
case 6016:
|
||||
return new IncorrectObservedTimeError(logs);
|
||||
case 6017:
|
||||
return new InvalidQuoteMode(logs);
|
||||
case 6018:
|
||||
return new InvalidVerifierIdx(logs);
|
||||
case 6019:
|
||||
return new InvalidSelfVerifyRequest(logs);
|
||||
case 6020:
|
||||
return new IncorrectMrEnclave(logs);
|
||||
case 6021:
|
||||
return new InvalidResponder(logs);
|
||||
case 6022:
|
||||
return new InvalidAddressLookupAddress(logs);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
import { PROGRAM_ID } from "../programId.js";
|
||||
|
||||
import * as anchor from "./anchor.js";
|
||||
import * as custom from "./custom.js";
|
||||
|
||||
export function fromAttestationCode(
|
||||
code: number,
|
||||
logs?: string[]
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
return code >= 6000
|
||||
? custom.fromCode(code, logs)
|
||||
: anchor.fromCode(code, logs);
|
||||
}
|
||||
|
||||
function hasOwnProperty<X extends object, Y extends PropertyKey>(
|
||||
obj: X,
|
||||
prop: Y
|
||||
): obj is X & Record<Y, unknown> {
|
||||
return Object.hasOwnProperty.call(obj, prop);
|
||||
}
|
||||
|
||||
const errorRe = /Program (\w+) failed: custom program error: (\w+)/;
|
||||
|
||||
export function fromAttestationTxError(
|
||||
err: unknown
|
||||
): custom.CustomError | anchor.AnchorError | null {
|
||||
if (
|
||||
typeof err !== "object" ||
|
||||
err === null ||
|
||||
!hasOwnProperty(err, "logs") ||
|
||||
!Array.isArray(err.logs)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let firstMatch: RegExpExecArray | null = null;
|
||||
for (const logLine of err.logs) {
|
||||
firstMatch = errorRe.exec(logLine);
|
||||
if (firstMatch !== null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstMatch === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [programIdRaw, codeRaw] = firstMatch.slice(1);
|
||||
if (programIdRaw !== PROGRAM_ID.toString()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let errorCode: number;
|
||||
try {
|
||||
errorCode = parseInt(codeRaw, 16);
|
||||
} catch (parseErr) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return fromAttestationCode(errorCode, err.logs);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
export * from "./accounts/index.js";
|
||||
export * from "./errors/index.js";
|
||||
export * from "./instructions/index.js";
|
||||
export * from "./types/index.js";
|
|
@ -0,0 +1,57 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationPermissionInitArgs {
|
||||
params: types.AttestationPermissionInitParamsFields;
|
||||
}
|
||||
|
||||
export interface AttestationPermissionInitAccounts {
|
||||
permission: PublicKey;
|
||||
authority: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
node: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AttestationPermissionInitParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function attestationPermissionInit(
|
||||
program: SwitchboardProgram,
|
||||
args: AttestationPermissionInitArgs,
|
||||
accounts: AttestationPermissionInitAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.node, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([219, 80, 131, 73, 164, 190, 142, 215]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AttestationPermissionInitParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationPermissionSetArgs {
|
||||
params: types.AttestationPermissionSetParamsFields;
|
||||
}
|
||||
|
||||
export interface AttestationPermissionSetAccounts {
|
||||
permission: PublicKey;
|
||||
authority: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
node: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AttestationPermissionSetParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function attestationPermissionSet(
|
||||
program: SwitchboardProgram,
|
||||
args: AttestationPermissionSetArgs,
|
||||
accounts: AttestationPermissionSetAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.node, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([56, 253, 255, 201, 100, 153, 10, 76]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AttestationPermissionSetParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueAddMrEnclaveArgs {
|
||||
params: types.AttestationQueueAddMrEnclaveParamsFields;
|
||||
}
|
||||
|
||||
export interface AttestationQueueAddMrEnclaveAccounts {
|
||||
queue: PublicKey;
|
||||
authority: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AttestationQueueAddMrEnclaveParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function attestationQueueAddMrEnclave(
|
||||
program: SwitchboardProgram,
|
||||
args: AttestationQueueAddMrEnclaveArgs,
|
||||
accounts: AttestationQueueAddMrEnclaveAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.queue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([62, 27, 24, 221, 30, 240, 63, 167]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AttestationQueueAddMrEnclaveParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueInitArgs {
|
||||
params: types.AttestationQueueInitParamsFields;
|
||||
}
|
||||
|
||||
export interface AttestationQueueInitAccounts {
|
||||
queue: PublicKey;
|
||||
authority: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AttestationQueueInitParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function attestationQueueInit(
|
||||
program: SwitchboardProgram,
|
||||
args: AttestationQueueInitArgs,
|
||||
accounts: AttestationQueueInitAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.queue, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([82, 211, 133, 63, 177, 112, 210, 216]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AttestationQueueInitParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueRemoveMrEnclaveArgs {
|
||||
params: types.AttestationQueueRemoveMrEnclaveParamsFields;
|
||||
}
|
||||
|
||||
export interface AttestationQueueRemoveMrEnclaveAccounts {
|
||||
queue: PublicKey;
|
||||
authority: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AttestationQueueRemoveMrEnclaveParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function attestationQueueRemoveMrEnclave(
|
||||
program: SwitchboardProgram,
|
||||
args: AttestationQueueRemoveMrEnclaveArgs,
|
||||
accounts: AttestationQueueRemoveMrEnclaveAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.queue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([202, 141, 93, 179, 212, 230, 34, 238]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AttestationQueueRemoveMrEnclaveParams.toEncodable(
|
||||
args.params
|
||||
),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionFundArgs {
|
||||
params: types.FunctionFundParamsFields;
|
||||
}
|
||||
|
||||
export interface FunctionFundAccounts {
|
||||
function: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
escrow: PublicKey;
|
||||
funder: PublicKey;
|
||||
funderAuthority: PublicKey;
|
||||
state: PublicKey;
|
||||
tokenProgram: PublicKey;
|
||||
associatedTokenProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.FunctionFundParams.layout("params")]);
|
||||
|
||||
export function functionFund(
|
||||
program: SwitchboardProgram,
|
||||
args: FunctionFundArgs,
|
||||
accounts: FunctionFundAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.function, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.funder, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.funderAuthority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
{
|
||||
pubkey: accounts.associatedTokenProgram,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
const identifier = Buffer.from([216, 39, 120, 216, 124, 169, 163, 62]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.FunctionFundParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionInitArgs {
|
||||
params: types.FunctionInitParamsFields;
|
||||
}
|
||||
|
||||
export interface FunctionInitAccounts {
|
||||
function: PublicKey;
|
||||
addressLookupTable: PublicKey;
|
||||
authority: PublicKey;
|
||||
quote: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
permission: PublicKey;
|
||||
payer: PublicKey;
|
||||
escrow: PublicKey;
|
||||
state: PublicKey;
|
||||
mint: PublicKey;
|
||||
tokenProgram: PublicKey;
|
||||
associatedTokenProgram: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
addressLookupProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.FunctionInitParams.layout("params")]);
|
||||
|
||||
export function functionInit(
|
||||
program: SwitchboardProgram,
|
||||
args: FunctionInitArgs,
|
||||
accounts: FunctionInitAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.function, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.addressLookupTable, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
{
|
||||
pubkey: accounts.associatedTokenProgram,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
{
|
||||
pubkey: accounts.addressLookupProgram,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
];
|
||||
const identifier = Buffer.from([0, 20, 30, 24, 100, 146, 13, 162]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.FunctionInitParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionVerifyArgs {
|
||||
params: types.FunctionVerifyParamsFields;
|
||||
}
|
||||
|
||||
export interface FunctionVerifyAccounts {
|
||||
function: PublicKey;
|
||||
fnSigner: PublicKey;
|
||||
fnQuote: PublicKey;
|
||||
verifierQuote: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
escrow: PublicKey;
|
||||
receiver: PublicKey;
|
||||
verifierPermission: PublicKey;
|
||||
fnPermission: PublicKey;
|
||||
state: PublicKey;
|
||||
tokenProgram: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.FunctionVerifyParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function functionVerify(
|
||||
program: SwitchboardProgram,
|
||||
args: FunctionVerifyArgs,
|
||||
accounts: FunctionVerifyAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.function, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.fnSigner, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.fnQuote, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.verifierQuote, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.securedSigner, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.receiver, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.verifierPermission, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.fnPermission, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([210, 108, 154, 138, 198, 14, 53, 191]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.FunctionVerifyParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionWithdrawArgs {
|
||||
params: types.FunctionWithdrawParamsFields;
|
||||
}
|
||||
|
||||
export interface FunctionWithdrawAccounts {
|
||||
function: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
authority: PublicKey;
|
||||
escrow: PublicKey;
|
||||
receiver: PublicKey;
|
||||
state: PublicKey;
|
||||
tokenProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.FunctionWithdrawParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function functionWithdraw(
|
||||
program: SwitchboardProgram,
|
||||
args: FunctionWithdrawArgs,
|
||||
accounts: FunctionWithdrawAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.function, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.receiver, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([6, 182, 241, 39, 40, 111, 65, 195]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.FunctionWithdrawParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
export type {
|
||||
AttestationPermissionInitAccounts,
|
||||
AttestationPermissionInitArgs,
|
||||
} from "./attestationPermissionInit.js";
|
||||
export { attestationPermissionInit } from "./attestationPermissionInit.js";
|
||||
export type {
|
||||
AttestationPermissionSetAccounts,
|
||||
AttestationPermissionSetArgs,
|
||||
} from "./attestationPermissionSet.js";
|
||||
export { attestationPermissionSet } from "./attestationPermissionSet.js";
|
||||
export type {
|
||||
AttestationQueueAddMrEnclaveAccounts,
|
||||
AttestationQueueAddMrEnclaveArgs,
|
||||
} from "./attestationQueueAddMrEnclave.js";
|
||||
export { attestationQueueAddMrEnclave } from "./attestationQueueAddMrEnclave.js";
|
||||
export type {
|
||||
AttestationQueueInitAccounts,
|
||||
AttestationQueueInitArgs,
|
||||
} from "./attestationQueueInit.js";
|
||||
export { attestationQueueInit } from "./attestationQueueInit.js";
|
||||
export type {
|
||||
AttestationQueueRemoveMrEnclaveAccounts,
|
||||
AttestationQueueRemoveMrEnclaveArgs,
|
||||
} from "./attestationQueueRemoveMrEnclave.js";
|
||||
export { attestationQueueRemoveMrEnclave } from "./attestationQueueRemoveMrEnclave.js";
|
||||
export type { FunctionFundAccounts, FunctionFundArgs } from "./functionFund.js";
|
||||
export { functionFund } from "./functionFund.js";
|
||||
export type { FunctionInitAccounts, FunctionInitArgs } from "./functionInit.js";
|
||||
export { functionInit } from "./functionInit.js";
|
||||
export type {
|
||||
FunctionVerifyAccounts,
|
||||
FunctionVerifyArgs,
|
||||
} from "./functionVerify.js";
|
||||
export { functionVerify } from "./functionVerify.js";
|
||||
export type {
|
||||
FunctionWithdrawAccounts,
|
||||
FunctionWithdrawArgs,
|
||||
} from "./functionWithdraw.js";
|
||||
export { functionWithdraw } from "./functionWithdraw.js";
|
||||
export type {
|
||||
QuoteHeartbeatAccounts,
|
||||
QuoteHeartbeatArgs,
|
||||
} from "./quoteHeartbeat.js";
|
||||
export { quoteHeartbeat } from "./quoteHeartbeat.js";
|
||||
export type { QuoteInitAccounts, QuoteInitArgs } from "./quoteInit.js";
|
||||
export { quoteInit } from "./quoteInit.js";
|
||||
export type { QuoteRotateAccounts, QuoteRotateArgs } from "./quoteRotate.js";
|
||||
export { quoteRotate } from "./quoteRotate.js";
|
||||
export type { QuoteVerifyAccounts, QuoteVerifyArgs } from "./quoteVerify.js";
|
||||
export { quoteVerify } from "./quoteVerify.js";
|
||||
export type { StateInitAccounts, StateInitArgs } from "./stateInit.js";
|
||||
export { stateInit } from "./stateInit.js";
|
|
@ -0,0 +1,57 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteHeartbeatArgs {
|
||||
params: types.QuoteHeartbeatParamsFields;
|
||||
}
|
||||
|
||||
export interface QuoteHeartbeatAccounts {
|
||||
quote: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
queueAuthority: PublicKey;
|
||||
gcNode: PublicKey;
|
||||
permission: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.QuoteHeartbeatParams.layout("params"),
|
||||
]);
|
||||
|
||||
export function quoteHeartbeat(
|
||||
program: SwitchboardProgram,
|
||||
args: QuoteHeartbeatArgs,
|
||||
accounts: QuoteHeartbeatAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.securedSigner, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.gcNode, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([202, 24, 19, 240, 75, 39, 154, 110]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.QuoteHeartbeatParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteInitArgs {
|
||||
params: types.QuoteInitParamsFields;
|
||||
}
|
||||
|
||||
export interface QuoteInitAccounts {
|
||||
quote: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
queueAuthority: PublicKey;
|
||||
authority: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.QuoteInitParams.layout("params")]);
|
||||
|
||||
export function quoteInit(
|
||||
program: SwitchboardProgram,
|
||||
args: QuoteInitArgs,
|
||||
accounts: QuoteInitAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.quote, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([124, 251, 28, 247, 136, 141, 198, 116]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.QuoteInitParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteRotateArgs {
|
||||
params: types.QuoteRotateParamsFields;
|
||||
}
|
||||
|
||||
export interface QuoteRotateAccounts {
|
||||
quote: PublicKey;
|
||||
authority: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.QuoteRotateParams.layout("params")]);
|
||||
|
||||
export function quoteRotate(
|
||||
program: SwitchboardProgram,
|
||||
args: QuoteRotateArgs,
|
||||
accounts: QuoteRotateAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.securedSigner, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: true },
|
||||
];
|
||||
const identifier = Buffer.from([153, 94, 246, 7, 7, 124, 62, 7]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.QuoteRotateParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteVerifyArgs {
|
||||
params: types.QuoteVerifyParamsFields;
|
||||
}
|
||||
|
||||
export interface QuoteVerifyAccounts {
|
||||
quote: PublicKey;
|
||||
quoteSigner: PublicKey;
|
||||
verifier: PublicKey;
|
||||
securedSigner: PublicKey;
|
||||
attestationQueue: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.QuoteVerifyParams.layout("params")]);
|
||||
|
||||
export function quoteVerify(
|
||||
program: SwitchboardProgram,
|
||||
args: QuoteVerifyArgs,
|
||||
accounts: QuoteVerifyAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.quoteSigner, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.verifier, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.securedSigner, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.attestationQueue, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([158, 203, 69, 10, 212, 218, 45, 184]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.QuoteVerifyParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import {
|
||||
AccountMeta,
|
||||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface StateInitArgs {
|
||||
params: types.StateInitParamsFields;
|
||||
}
|
||||
|
||||
export interface StateInitAccounts {
|
||||
state: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([types.StateInitParams.layout("params")]);
|
||||
|
||||
export function stateInit(
|
||||
program: SwitchboardProgram,
|
||||
args: StateInitArgs,
|
||||
accounts: StateInitAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.state, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([103, 241, 106, 190, 217, 153, 87, 105]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.StateInitParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.attestationProgramId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { PublicKey } from "@solana/web3.js";
|
||||
|
||||
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
|
||||
export const PROGRAM_ID_CLI = new PublicKey(
|
||||
"2No5FVKPAAYqytpkEoq93tVh33fo4p6DgAnm4S6oZHo7"
|
||||
);
|
||||
|
||||
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.
|
||||
export const PROGRAM_ID: PublicKey = PROGRAM_ID_CLI;
|
|
@ -0,0 +1,41 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationPermissionInitParamsFields {}
|
||||
|
||||
export interface AttestationPermissionInitParamsJSON {}
|
||||
|
||||
export class AttestationPermissionInitParams {
|
||||
constructor(fields: AttestationPermissionInitParamsFields) {}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AttestationPermissionInitParams({});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AttestationPermissionInitParamsFields) {
|
||||
return {};
|
||||
}
|
||||
|
||||
toJSON(): AttestationPermissionInitParamsJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationPermissionInitParamsJSON
|
||||
): AttestationPermissionInitParams {
|
||||
return new AttestationPermissionInitParams({});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AttestationPermissionInitParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationPermissionSetParamsFields {
|
||||
permission: number;
|
||||
enable: boolean;
|
||||
}
|
||||
|
||||
export interface AttestationPermissionSetParamsJSON {
|
||||
permission: number;
|
||||
enable: boolean;
|
||||
}
|
||||
|
||||
export class AttestationPermissionSetParams {
|
||||
readonly permission: number;
|
||||
readonly enable: boolean;
|
||||
|
||||
constructor(fields: AttestationPermissionSetParamsFields) {
|
||||
this.permission = fields.permission;
|
||||
this.enable = fields.enable;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[borsh.u32("permission"), borsh.bool("enable")],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AttestationPermissionSetParams({
|
||||
permission: obj.permission,
|
||||
enable: obj.enable,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AttestationPermissionSetParamsFields) {
|
||||
return {
|
||||
permission: fields.permission,
|
||||
enable: fields.enable,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): AttestationPermissionSetParamsJSON {
|
||||
return {
|
||||
permission: this.permission,
|
||||
enable: this.enable,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationPermissionSetParamsJSON
|
||||
): AttestationPermissionSetParams {
|
||||
return new AttestationPermissionSetParams({
|
||||
permission: obj.permission,
|
||||
enable: obj.enable,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AttestationPermissionSetParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueAddMrEnclaveParamsFields {
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export interface AttestationQueueAddMrEnclaveParamsJSON {
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export class AttestationQueueAddMrEnclaveParams {
|
||||
readonly mrEnclave: Array<number>;
|
||||
|
||||
constructor(fields: AttestationQueueAddMrEnclaveParamsFields) {
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.array(borsh.u8(), 32, "mrEnclave")], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AttestationQueueAddMrEnclaveParams({
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AttestationQueueAddMrEnclaveParamsFields) {
|
||||
return {
|
||||
mrEnclave: fields.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): AttestationQueueAddMrEnclaveParamsJSON {
|
||||
return {
|
||||
mrEnclave: this.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationQueueAddMrEnclaveParamsJSON
|
||||
): AttestationQueueAddMrEnclaveParams {
|
||||
return new AttestationQueueAddMrEnclaveParams({
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AttestationQueueAddMrEnclaveParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueInitParamsFields {
|
||||
allowAuthorityOverrideAfter: number;
|
||||
requireAuthorityHeartbeatPermission: boolean;
|
||||
requireUsagePermissions: boolean;
|
||||
maxQuoteVerificationAge: number;
|
||||
reward: number;
|
||||
nodeTimeout: number;
|
||||
}
|
||||
|
||||
export interface AttestationQueueInitParamsJSON {
|
||||
allowAuthorityOverrideAfter: number;
|
||||
requireAuthorityHeartbeatPermission: boolean;
|
||||
requireUsagePermissions: boolean;
|
||||
maxQuoteVerificationAge: number;
|
||||
reward: number;
|
||||
nodeTimeout: number;
|
||||
}
|
||||
|
||||
export class AttestationQueueInitParams {
|
||||
readonly allowAuthorityOverrideAfter: number;
|
||||
readonly requireAuthorityHeartbeatPermission: boolean;
|
||||
readonly requireUsagePermissions: boolean;
|
||||
readonly maxQuoteVerificationAge: number;
|
||||
readonly reward: number;
|
||||
readonly nodeTimeout: number;
|
||||
|
||||
constructor(fields: AttestationQueueInitParamsFields) {
|
||||
this.allowAuthorityOverrideAfter = fields.allowAuthorityOverrideAfter;
|
||||
this.requireAuthorityHeartbeatPermission =
|
||||
fields.requireAuthorityHeartbeatPermission;
|
||||
this.requireUsagePermissions = fields.requireUsagePermissions;
|
||||
this.maxQuoteVerificationAge = fields.maxQuoteVerificationAge;
|
||||
this.reward = fields.reward;
|
||||
this.nodeTimeout = fields.nodeTimeout;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[
|
||||
borsh.u32("allowAuthorityOverrideAfter"),
|
||||
borsh.bool("requireAuthorityHeartbeatPermission"),
|
||||
borsh.bool("requireUsagePermissions"),
|
||||
borsh.u32("maxQuoteVerificationAge"),
|
||||
borsh.u32("reward"),
|
||||
borsh.u32("nodeTimeout"),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AttestationQueueInitParams({
|
||||
allowAuthorityOverrideAfter: obj.allowAuthorityOverrideAfter,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
obj.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: obj.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: obj.maxQuoteVerificationAge,
|
||||
reward: obj.reward,
|
||||
nodeTimeout: obj.nodeTimeout,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AttestationQueueInitParamsFields) {
|
||||
return {
|
||||
allowAuthorityOverrideAfter: fields.allowAuthorityOverrideAfter,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
fields.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: fields.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: fields.maxQuoteVerificationAge,
|
||||
reward: fields.reward,
|
||||
nodeTimeout: fields.nodeTimeout,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): AttestationQueueInitParamsJSON {
|
||||
return {
|
||||
allowAuthorityOverrideAfter: this.allowAuthorityOverrideAfter,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
this.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: this.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: this.maxQuoteVerificationAge,
|
||||
reward: this.reward,
|
||||
nodeTimeout: this.nodeTimeout,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationQueueInitParamsJSON
|
||||
): AttestationQueueInitParams {
|
||||
return new AttestationQueueInitParams({
|
||||
allowAuthorityOverrideAfter: obj.allowAuthorityOverrideAfter,
|
||||
requireAuthorityHeartbeatPermission:
|
||||
obj.requireAuthorityHeartbeatPermission,
|
||||
requireUsagePermissions: obj.requireUsagePermissions,
|
||||
maxQuoteVerificationAge: obj.maxQuoteVerificationAge,
|
||||
reward: obj.reward,
|
||||
nodeTimeout: obj.nodeTimeout,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AttestationQueueInitParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AttestationQueueRemoveMrEnclaveParamsFields {
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export interface AttestationQueueRemoveMrEnclaveParamsJSON {
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export class AttestationQueueRemoveMrEnclaveParams {
|
||||
readonly mrEnclave: Array<number>;
|
||||
|
||||
constructor(fields: AttestationQueueRemoveMrEnclaveParamsFields) {
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.array(borsh.u8(), 32, "mrEnclave")], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AttestationQueueRemoveMrEnclaveParams({
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AttestationQueueRemoveMrEnclaveParamsFields) {
|
||||
return {
|
||||
mrEnclave: fields.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): AttestationQueueRemoveMrEnclaveParamsJSON {
|
||||
return {
|
||||
mrEnclave: this.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AttestationQueueRemoveMrEnclaveParamsJSON
|
||||
): AttestationQueueRemoveMrEnclaveParams {
|
||||
return new AttestationQueueRemoveMrEnclaveParams({
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AttestationQueueRemoveMrEnclaveParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionFundParamsFields {
|
||||
amount: BN;
|
||||
}
|
||||
|
||||
export interface FunctionFundParamsJSON {
|
||||
amount: string;
|
||||
}
|
||||
|
||||
export class FunctionFundParams {
|
||||
readonly amount: BN;
|
||||
|
||||
constructor(fields: FunctionFundParamsFields) {
|
||||
this.amount = fields.amount;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.u64("amount")], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new FunctionFundParams({
|
||||
amount: obj.amount,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: FunctionFundParamsFields) {
|
||||
return {
|
||||
amount: fields.amount,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): FunctionFundParamsJSON {
|
||||
return {
|
||||
amount: this.amount.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FunctionFundParamsJSON): FunctionFundParams {
|
||||
return new FunctionFundParams({
|
||||
amount: new BN(obj.amount),
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return FunctionFundParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionInitParamsFields {
|
||||
name: Uint8Array;
|
||||
metadata: Uint8Array;
|
||||
container: Uint8Array;
|
||||
containerRegistry: Uint8Array;
|
||||
version: Uint8Array;
|
||||
schedule: Uint8Array;
|
||||
mrEnclave: Array<number>;
|
||||
recentSlot: BN;
|
||||
}
|
||||
|
||||
export interface FunctionInitParamsJSON {
|
||||
name: Array<number>;
|
||||
metadata: Array<number>;
|
||||
container: Array<number>;
|
||||
containerRegistry: Array<number>;
|
||||
version: Array<number>;
|
||||
schedule: Array<number>;
|
||||
mrEnclave: Array<number>;
|
||||
recentSlot: string;
|
||||
}
|
||||
|
||||
export class FunctionInitParams {
|
||||
readonly name: Uint8Array;
|
||||
readonly metadata: Uint8Array;
|
||||
readonly container: Uint8Array;
|
||||
readonly containerRegistry: Uint8Array;
|
||||
readonly version: Uint8Array;
|
||||
readonly schedule: Uint8Array;
|
||||
readonly mrEnclave: Array<number>;
|
||||
readonly recentSlot: BN;
|
||||
|
||||
constructor(fields: FunctionInitParamsFields) {
|
||||
this.name = fields.name;
|
||||
this.metadata = fields.metadata;
|
||||
this.container = fields.container;
|
||||
this.containerRegistry = fields.containerRegistry;
|
||||
this.version = fields.version;
|
||||
this.schedule = fields.schedule;
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
this.recentSlot = fields.recentSlot;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[
|
||||
borsh.vecU8("name"),
|
||||
borsh.vecU8("metadata"),
|
||||
borsh.vecU8("container"),
|
||||
borsh.vecU8("containerRegistry"),
|
||||
borsh.vecU8("version"),
|
||||
borsh.vecU8("schedule"),
|
||||
borsh.array(borsh.u8(), 32, "mrEnclave"),
|
||||
borsh.u64("recentSlot"),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new FunctionInitParams({
|
||||
name: new Uint8Array(
|
||||
obj.name.buffer,
|
||||
obj.name.byteOffset,
|
||||
obj.name.length
|
||||
),
|
||||
metadata: new Uint8Array(
|
||||
obj.metadata.buffer,
|
||||
obj.metadata.byteOffset,
|
||||
obj.metadata.length
|
||||
),
|
||||
container: new Uint8Array(
|
||||
obj.container.buffer,
|
||||
obj.container.byteOffset,
|
||||
obj.container.length
|
||||
),
|
||||
containerRegistry: new Uint8Array(
|
||||
obj.containerRegistry.buffer,
|
||||
obj.containerRegistry.byteOffset,
|
||||
obj.containerRegistry.length
|
||||
),
|
||||
version: new Uint8Array(
|
||||
obj.version.buffer,
|
||||
obj.version.byteOffset,
|
||||
obj.version.length
|
||||
),
|
||||
schedule: new Uint8Array(
|
||||
obj.schedule.buffer,
|
||||
obj.schedule.byteOffset,
|
||||
obj.schedule.length
|
||||
),
|
||||
mrEnclave: obj.mrEnclave,
|
||||
recentSlot: obj.recentSlot,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: FunctionInitParamsFields) {
|
||||
return {
|
||||
name: Buffer.from(
|
||||
fields.name.buffer,
|
||||
fields.name.byteOffset,
|
||||
fields.name.length
|
||||
),
|
||||
metadata: Buffer.from(
|
||||
fields.metadata.buffer,
|
||||
fields.metadata.byteOffset,
|
||||
fields.metadata.length
|
||||
),
|
||||
container: Buffer.from(
|
||||
fields.container.buffer,
|
||||
fields.container.byteOffset,
|
||||
fields.container.length
|
||||
),
|
||||
containerRegistry: Buffer.from(
|
||||
fields.containerRegistry.buffer,
|
||||
fields.containerRegistry.byteOffset,
|
||||
fields.containerRegistry.length
|
||||
),
|
||||
version: Buffer.from(
|
||||
fields.version.buffer,
|
||||
fields.version.byteOffset,
|
||||
fields.version.length
|
||||
),
|
||||
schedule: Buffer.from(
|
||||
fields.schedule.buffer,
|
||||
fields.schedule.byteOffset,
|
||||
fields.schedule.length
|
||||
),
|
||||
mrEnclave: fields.mrEnclave,
|
||||
recentSlot: fields.recentSlot,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): FunctionInitParamsJSON {
|
||||
return {
|
||||
name: Array.from(this.name.values()),
|
||||
metadata: Array.from(this.metadata.values()),
|
||||
container: Array.from(this.container.values()),
|
||||
containerRegistry: Array.from(this.containerRegistry.values()),
|
||||
version: Array.from(this.version.values()),
|
||||
schedule: Array.from(this.schedule.values()),
|
||||
mrEnclave: this.mrEnclave,
|
||||
recentSlot: this.recentSlot.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FunctionInitParamsJSON): FunctionInitParams {
|
||||
return new FunctionInitParams({
|
||||
name: Uint8Array.from(obj.name),
|
||||
metadata: Uint8Array.from(obj.metadata),
|
||||
container: Uint8Array.from(obj.container),
|
||||
containerRegistry: Uint8Array.from(obj.containerRegistry),
|
||||
version: Uint8Array.from(obj.version),
|
||||
schedule: Uint8Array.from(obj.schedule),
|
||||
mrEnclave: obj.mrEnclave,
|
||||
recentSlot: new BN(obj.recentSlot),
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return FunctionInitParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,212 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface NoneJSON {
|
||||
kind: "None";
|
||||
}
|
||||
|
||||
export class None {
|
||||
static readonly discriminator = 0;
|
||||
static readonly kind = "None";
|
||||
readonly discriminator = 0;
|
||||
readonly kind = "None";
|
||||
|
||||
toJSON(): NoneJSON {
|
||||
return {
|
||||
kind: "None",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
None: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface ActiveJSON {
|
||||
kind: "Active";
|
||||
}
|
||||
|
||||
export class Active {
|
||||
static readonly discriminator = 1;
|
||||
static readonly kind = "Active";
|
||||
readonly discriminator = 1;
|
||||
readonly kind = "Active";
|
||||
|
||||
toJSON(): ActiveJSON {
|
||||
return {
|
||||
kind: "Active",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
Active: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface NonExecutableJSON {
|
||||
kind: "NonExecutable";
|
||||
}
|
||||
|
||||
export class NonExecutable {
|
||||
static readonly discriminator = 2;
|
||||
static readonly kind = "NonExecutable";
|
||||
readonly discriminator = 2;
|
||||
readonly kind = "NonExecutable";
|
||||
|
||||
toJSON(): NonExecutableJSON {
|
||||
return {
|
||||
kind: "NonExecutable",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
NonExecutable: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface ExpiredJSON {
|
||||
kind: "Expired";
|
||||
}
|
||||
|
||||
export class Expired {
|
||||
static readonly discriminator = 3;
|
||||
static readonly kind = "Expired";
|
||||
readonly discriminator = 3;
|
||||
readonly kind = "Expired";
|
||||
|
||||
toJSON(): ExpiredJSON {
|
||||
return {
|
||||
kind: "Expired",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
Expired: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface OutOfFundsJSON {
|
||||
kind: "OutOfFunds";
|
||||
}
|
||||
|
||||
export class OutOfFunds {
|
||||
static readonly discriminator = 4;
|
||||
static readonly kind = "OutOfFunds";
|
||||
readonly discriminator = 4;
|
||||
readonly kind = "OutOfFunds";
|
||||
|
||||
toJSON(): OutOfFundsJSON {
|
||||
return {
|
||||
kind: "OutOfFunds",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
OutOfFunds: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface InvalidPermissionsJSON {
|
||||
kind: "InvalidPermissions";
|
||||
}
|
||||
|
||||
export class InvalidPermissions {
|
||||
static readonly discriminator = 5;
|
||||
static readonly kind = "InvalidPermissions";
|
||||
readonly discriminator = 5;
|
||||
readonly kind = "InvalidPermissions";
|
||||
|
||||
toJSON(): InvalidPermissionsJSON {
|
||||
return {
|
||||
kind: "InvalidPermissions",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
InvalidPermissions: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function fromDecoded(obj: any): types.FunctionStatusKind {
|
||||
if (typeof obj !== "object") {
|
||||
throw new Error("Invalid enum object");
|
||||
}
|
||||
|
||||
if ("None" in obj) {
|
||||
return new None();
|
||||
}
|
||||
if ("Active" in obj) {
|
||||
return new Active();
|
||||
}
|
||||
if ("NonExecutable" in obj) {
|
||||
return new NonExecutable();
|
||||
}
|
||||
if ("Expired" in obj) {
|
||||
return new Expired();
|
||||
}
|
||||
if ("OutOfFunds" in obj) {
|
||||
return new OutOfFunds();
|
||||
}
|
||||
if ("InvalidPermissions" in obj) {
|
||||
return new InvalidPermissions();
|
||||
}
|
||||
|
||||
throw new Error("Invalid enum object");
|
||||
}
|
||||
|
||||
export function fromJSON(
|
||||
obj: types.FunctionStatusJSON
|
||||
): types.FunctionStatusKind {
|
||||
switch (obj.kind) {
|
||||
case "None": {
|
||||
return new None();
|
||||
}
|
||||
case "Active": {
|
||||
return new Active();
|
||||
}
|
||||
case "NonExecutable": {
|
||||
return new NonExecutable();
|
||||
}
|
||||
case "Expired": {
|
||||
return new Expired();
|
||||
}
|
||||
case "OutOfFunds": {
|
||||
return new OutOfFunds();
|
||||
}
|
||||
case "InvalidPermissions": {
|
||||
return new InvalidPermissions();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function layout(property?: string) {
|
||||
const ret = borsh.rustEnum([
|
||||
borsh.struct([], "None"),
|
||||
borsh.struct([], "Active"),
|
||||
borsh.struct([], "NonExecutable"),
|
||||
borsh.struct([], "Expired"),
|
||||
borsh.struct([], "OutOfFunds"),
|
||||
borsh.struct([], "InvalidPermissions"),
|
||||
]);
|
||||
if (property !== undefined) {
|
||||
return ret.replicate(property);
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionVerifyParamsFields {
|
||||
observedTime: BN;
|
||||
nextAllowedTimestamp: BN;
|
||||
isFailure: boolean;
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export interface FunctionVerifyParamsJSON {
|
||||
observedTime: string;
|
||||
nextAllowedTimestamp: string;
|
||||
isFailure: boolean;
|
||||
mrEnclave: Array<number>;
|
||||
}
|
||||
|
||||
export class FunctionVerifyParams {
|
||||
readonly observedTime: BN;
|
||||
readonly nextAllowedTimestamp: BN;
|
||||
readonly isFailure: boolean;
|
||||
readonly mrEnclave: Array<number>;
|
||||
|
||||
constructor(fields: FunctionVerifyParamsFields) {
|
||||
this.observedTime = fields.observedTime;
|
||||
this.nextAllowedTimestamp = fields.nextAllowedTimestamp;
|
||||
this.isFailure = fields.isFailure;
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[
|
||||
borsh.i64("observedTime"),
|
||||
borsh.i64("nextAllowedTimestamp"),
|
||||
borsh.bool("isFailure"),
|
||||
borsh.array(borsh.u8(), 32, "mrEnclave"),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new FunctionVerifyParams({
|
||||
observedTime: obj.observedTime,
|
||||
nextAllowedTimestamp: obj.nextAllowedTimestamp,
|
||||
isFailure: obj.isFailure,
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: FunctionVerifyParamsFields) {
|
||||
return {
|
||||
observedTime: fields.observedTime,
|
||||
nextAllowedTimestamp: fields.nextAllowedTimestamp,
|
||||
isFailure: fields.isFailure,
|
||||
mrEnclave: fields.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): FunctionVerifyParamsJSON {
|
||||
return {
|
||||
observedTime: this.observedTime.toString(),
|
||||
nextAllowedTimestamp: this.nextAllowedTimestamp.toString(),
|
||||
isFailure: this.isFailure,
|
||||
mrEnclave: this.mrEnclave,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FunctionVerifyParamsJSON): FunctionVerifyParams {
|
||||
return new FunctionVerifyParams({
|
||||
observedTime: new BN(obj.observedTime),
|
||||
nextAllowedTimestamp: new BN(obj.nextAllowedTimestamp),
|
||||
isFailure: obj.isFailure,
|
||||
mrEnclave: obj.mrEnclave,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return FunctionVerifyParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface FunctionWithdrawParamsFields {
|
||||
amount: BN;
|
||||
}
|
||||
|
||||
export interface FunctionWithdrawParamsJSON {
|
||||
amount: string;
|
||||
}
|
||||
|
||||
export class FunctionWithdrawParams {
|
||||
readonly amount: BN;
|
||||
|
||||
constructor(fields: FunctionWithdrawParamsFields) {
|
||||
this.amount = fields.amount;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.u64("amount")], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new FunctionWithdrawParams({
|
||||
amount: obj.amount,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: FunctionWithdrawParamsFields) {
|
||||
return {
|
||||
amount: fields.amount,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): FunctionWithdrawParamsJSON {
|
||||
return {
|
||||
amount: this.amount.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: FunctionWithdrawParamsJSON): FunctionWithdrawParams {
|
||||
return new FunctionWithdrawParams({
|
||||
amount: new BN(obj.amount),
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return FunctionWithdrawParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteHeartbeatParamsFields {}
|
||||
|
||||
export interface QuoteHeartbeatParamsJSON {}
|
||||
|
||||
export class QuoteHeartbeatParams {
|
||||
constructor(fields: QuoteHeartbeatParamsFields) {}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new QuoteHeartbeatParams({});
|
||||
}
|
||||
|
||||
static toEncodable(fields: QuoteHeartbeatParamsFields) {
|
||||
return {};
|
||||
}
|
||||
|
||||
toJSON(): QuoteHeartbeatParamsJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteHeartbeatParamsJSON): QuoteHeartbeatParams {
|
||||
return new QuoteHeartbeatParams({});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return QuoteHeartbeatParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteInitParamsFields {}
|
||||
|
||||
export interface QuoteInitParamsJSON {}
|
||||
|
||||
export class QuoteInitParams {
|
||||
constructor(fields: QuoteInitParamsFields) {}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new QuoteInitParams({});
|
||||
}
|
||||
|
||||
static toEncodable(fields: QuoteInitParamsFields) {
|
||||
return {};
|
||||
}
|
||||
|
||||
toJSON(): QuoteInitParamsJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteInitParamsJSON): QuoteInitParams {
|
||||
return new QuoteInitParams({});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return QuoteInitParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteRotateParamsFields {
|
||||
registryKey: Array<number>;
|
||||
}
|
||||
|
||||
export interface QuoteRotateParamsJSON {
|
||||
registryKey: Array<number>;
|
||||
}
|
||||
|
||||
export class QuoteRotateParams {
|
||||
readonly registryKey: Array<number>;
|
||||
|
||||
constructor(fields: QuoteRotateParamsFields) {
|
||||
this.registryKey = fields.registryKey;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.array(borsh.u8(), 64, "registryKey")], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new QuoteRotateParams({
|
||||
registryKey: obj.registryKey,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: QuoteRotateParamsFields) {
|
||||
return {
|
||||
registryKey: fields.registryKey,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): QuoteRotateParamsJSON {
|
||||
return {
|
||||
registryKey: this.registryKey,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteRotateParamsJSON): QuoteRotateParams {
|
||||
return new QuoteRotateParams({
|
||||
registryKey: obj.registryKey,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return QuoteRotateParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteVerifyParamsFields {
|
||||
timestamp: BN;
|
||||
mrEnclave: Array<number>;
|
||||
idx: number;
|
||||
}
|
||||
|
||||
export interface QuoteVerifyParamsJSON {
|
||||
timestamp: string;
|
||||
mrEnclave: Array<number>;
|
||||
idx: number;
|
||||
}
|
||||
|
||||
export class QuoteVerifyParams {
|
||||
readonly timestamp: BN;
|
||||
readonly mrEnclave: Array<number>;
|
||||
readonly idx: number;
|
||||
|
||||
constructor(fields: QuoteVerifyParamsFields) {
|
||||
this.timestamp = fields.timestamp;
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
this.idx = fields.idx;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[
|
||||
borsh.i64("timestamp"),
|
||||
borsh.array(borsh.u8(), 32, "mrEnclave"),
|
||||
borsh.u32("idx"),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new QuoteVerifyParams({
|
||||
timestamp: obj.timestamp,
|
||||
mrEnclave: obj.mrEnclave,
|
||||
idx: obj.idx,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: QuoteVerifyParamsFields) {
|
||||
return {
|
||||
timestamp: fields.timestamp,
|
||||
mrEnclave: fields.mrEnclave,
|
||||
idx: fields.idx,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): QuoteVerifyParamsJSON {
|
||||
return {
|
||||
timestamp: this.timestamp.toString(),
|
||||
mrEnclave: this.mrEnclave,
|
||||
idx: this.idx,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteVerifyParamsJSON): QuoteVerifyParams {
|
||||
return new QuoteVerifyParams({
|
||||
timestamp: new BN(obj.timestamp),
|
||||
mrEnclave: obj.mrEnclave,
|
||||
idx: obj.idx,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return QuoteVerifyParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface StateInitParamsFields {}
|
||||
|
||||
export interface StateInitParamsJSON {}
|
||||
|
||||
export class StateInitParams {
|
||||
constructor(fields: StateInitParamsFields) {}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new StateInitParams({});
|
||||
}
|
||||
|
||||
static toEncodable(fields: StateInitParamsFields) {
|
||||
return {};
|
||||
}
|
||||
|
||||
toJSON(): StateInitParamsJSON {
|
||||
return {};
|
||||
}
|
||||
|
||||
static fromJSON(obj: StateInitParamsJSON): StateInitParams {
|
||||
return new StateInitParams({});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return StateInitParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface PermitNodeheartbeatJSON {
|
||||
kind: "PermitNodeheartbeat";
|
||||
}
|
||||
|
||||
export class PermitNodeheartbeat {
|
||||
static readonly discriminator = 1;
|
||||
static readonly kind = "PermitNodeheartbeat";
|
||||
readonly discriminator = 1;
|
||||
readonly kind = "PermitNodeheartbeat";
|
||||
|
||||
toJSON(): PermitNodeheartbeatJSON {
|
||||
return {
|
||||
kind: "PermitNodeheartbeat",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
PermitNodeheartbeat: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface PermitQueueUsageJSON {
|
||||
kind: "PermitQueueUsage";
|
||||
}
|
||||
|
||||
export class PermitQueueUsage {
|
||||
static readonly discriminator = 2;
|
||||
static readonly kind = "PermitQueueUsage";
|
||||
readonly discriminator = 2;
|
||||
readonly kind = "PermitQueueUsage";
|
||||
|
||||
toJSON(): PermitQueueUsageJSON {
|
||||
return {
|
||||
kind: "PermitQueueUsage",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
PermitQueueUsage: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function fromDecoded(
|
||||
obj: any
|
||||
): types.SwitchboardAttestationPermissionKind {
|
||||
if (typeof obj !== "object") {
|
||||
throw new Error("Invalid enum object");
|
||||
}
|
||||
|
||||
if ("PermitNodeheartbeat" in obj) {
|
||||
return new PermitNodeheartbeat();
|
||||
}
|
||||
if ("PermitQueueUsage" in obj) {
|
||||
return new PermitQueueUsage();
|
||||
}
|
||||
|
||||
throw new Error("Invalid enum object");
|
||||
}
|
||||
|
||||
export function fromJSON(
|
||||
obj: types.SwitchboardAttestationPermissionJSON
|
||||
): types.SwitchboardAttestationPermissionKind {
|
||||
switch (obj.kind) {
|
||||
case "PermitNodeheartbeat": {
|
||||
return new PermitNodeheartbeat();
|
||||
}
|
||||
case "PermitQueueUsage": {
|
||||
return new PermitQueueUsage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function layout(property?: string) {
|
||||
const ret = borsh.rustEnum([
|
||||
borsh.struct([], "PermitNodeheartbeat"),
|
||||
borsh.struct([], "PermitQueueUsage"),
|
||||
]);
|
||||
if (property !== undefined) {
|
||||
return ret.replicate(property);
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -1,17 +1,42 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
|
||||
import * as types from "./index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
import { PublicKey } from "@solana/web3.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import { BN } from "@switchboard-xyz/common"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as borsh from "@coral-xyz/borsh";
|
||||
|
||||
export interface NoneJSON {
|
||||
kind: "None";
|
||||
}
|
||||
|
||||
export class None {
|
||||
static readonly discriminator = 0;
|
||||
static readonly kind = "None";
|
||||
readonly discriminator = 0;
|
||||
readonly kind = "None";
|
||||
|
||||
toJSON(): NoneJSON {
|
||||
return {
|
||||
kind: "None",
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
None: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface VerificationPendingJSON {
|
||||
kind: "VerificationPending";
|
||||
}
|
||||
|
||||
export class VerificationPending {
|
||||
static readonly discriminator = 0;
|
||||
static readonly discriminator = 1;
|
||||
static readonly kind = "VerificationPending";
|
||||
readonly discriminator = 0;
|
||||
readonly discriminator = 1;
|
||||
readonly kind = "VerificationPending";
|
||||
|
||||
toJSON(): VerificationPendingJSON {
|
||||
|
@ -32,9 +57,9 @@ export interface VerificationFailureJSON {
|
|||
}
|
||||
|
||||
export class VerificationFailure {
|
||||
static readonly discriminator = 1;
|
||||
static readonly discriminator = 2;
|
||||
static readonly kind = "VerificationFailure";
|
||||
readonly discriminator = 1;
|
||||
readonly discriminator = 2;
|
||||
readonly kind = "VerificationFailure";
|
||||
|
||||
toJSON(): VerificationFailureJSON {
|
||||
|
@ -55,9 +80,9 @@ export interface VerificationSuccessJSON {
|
|||
}
|
||||
|
||||
export class VerificationSuccess {
|
||||
static readonly discriminator = 2;
|
||||
static readonly discriminator = 4;
|
||||
static readonly kind = "VerificationSuccess";
|
||||
readonly discriminator = 2;
|
||||
readonly discriminator = 4;
|
||||
readonly kind = "VerificationSuccess";
|
||||
|
||||
toJSON(): VerificationSuccessJSON {
|
||||
|
@ -78,9 +103,9 @@ export interface VerificationOverrideJSON {
|
|||
}
|
||||
|
||||
export class VerificationOverride {
|
||||
static readonly discriminator = 3;
|
||||
static readonly discriminator = 8;
|
||||
static readonly kind = "VerificationOverride";
|
||||
readonly discriminator = 3;
|
||||
readonly discriminator = 8;
|
||||
readonly kind = "VerificationOverride";
|
||||
|
||||
toJSON(): VerificationOverrideJSON {
|
||||
|
@ -102,6 +127,9 @@ export function fromDecoded(obj: any): types.VerificationStatusKind {
|
|||
throw new Error("Invalid enum object");
|
||||
}
|
||||
|
||||
if ("None" in obj) {
|
||||
return new None();
|
||||
}
|
||||
if ("VerificationPending" in obj) {
|
||||
return new VerificationPending();
|
||||
}
|
||||
|
@ -122,6 +150,9 @@ export function fromJSON(
|
|||
obj: types.VerificationStatusJSON
|
||||
): types.VerificationStatusKind {
|
||||
switch (obj.kind) {
|
||||
case "None": {
|
||||
return new None();
|
||||
}
|
||||
case "VerificationPending": {
|
||||
return new VerificationPending();
|
||||
}
|
||||
|
@ -139,6 +170,7 @@ export function fromJSON(
|
|||
|
||||
export function layout(property?: string) {
|
||||
const ret = borsh.rustEnum([
|
||||
borsh.struct([], "None"),
|
||||
borsh.struct([], "VerificationPending"),
|
||||
borsh.struct([], "VerificationFailure"),
|
||||
borsh.struct([], "VerificationSuccess"),
|
|
@ -0,0 +1,114 @@
|
|||
import * as FunctionStatus from "./FunctionStatus.js";
|
||||
import * as SwitchboardAttestationPermission from "./SwitchboardAttestationPermission.js";
|
||||
import * as VerificationStatus from "./VerificationStatus.js";
|
||||
|
||||
export type {
|
||||
AttestationPermissionInitParamsFields,
|
||||
AttestationPermissionInitParamsJSON,
|
||||
} from "./AttestationPermissionInitParams.js";
|
||||
export { AttestationPermissionInitParams } from "./AttestationPermissionInitParams.js";
|
||||
export type {
|
||||
AttestationPermissionSetParamsFields,
|
||||
AttestationPermissionSetParamsJSON,
|
||||
} from "./AttestationPermissionSetParams.js";
|
||||
export { AttestationPermissionSetParams } from "./AttestationPermissionSetParams.js";
|
||||
export type {
|
||||
AttestationQueueAddMrEnclaveParamsFields,
|
||||
AttestationQueueAddMrEnclaveParamsJSON,
|
||||
} from "./AttestationQueueAddMrEnclaveParams.js";
|
||||
export { AttestationQueueAddMrEnclaveParams } from "./AttestationQueueAddMrEnclaveParams.js";
|
||||
export type {
|
||||
AttestationQueueInitParamsFields,
|
||||
AttestationQueueInitParamsJSON,
|
||||
} from "./AttestationQueueInitParams.js";
|
||||
export { AttestationQueueInitParams } from "./AttestationQueueInitParams.js";
|
||||
export type {
|
||||
AttestationQueueRemoveMrEnclaveParamsFields,
|
||||
AttestationQueueRemoveMrEnclaveParamsJSON,
|
||||
} from "./AttestationQueueRemoveMrEnclaveParams.js";
|
||||
export { AttestationQueueRemoveMrEnclaveParams } from "./AttestationQueueRemoveMrEnclaveParams.js";
|
||||
export type {
|
||||
FunctionFundParamsFields,
|
||||
FunctionFundParamsJSON,
|
||||
} from "./FunctionFundParams.js";
|
||||
export { FunctionFundParams } from "./FunctionFundParams.js";
|
||||
export type {
|
||||
FunctionInitParamsFields,
|
||||
FunctionInitParamsJSON,
|
||||
} from "./FunctionInitParams.js";
|
||||
export { FunctionInitParams } from "./FunctionInitParams.js";
|
||||
export type {
|
||||
FunctionVerifyParamsFields,
|
||||
FunctionVerifyParamsJSON,
|
||||
} from "./FunctionVerifyParams.js";
|
||||
export { FunctionVerifyParams } from "./FunctionVerifyParams.js";
|
||||
export type {
|
||||
FunctionWithdrawParamsFields,
|
||||
FunctionWithdrawParamsJSON,
|
||||
} from "./FunctionWithdrawParams.js";
|
||||
export { FunctionWithdrawParams } from "./FunctionWithdrawParams.js";
|
||||
export type {
|
||||
QuoteHeartbeatParamsFields,
|
||||
QuoteHeartbeatParamsJSON,
|
||||
} from "./QuoteHeartbeatParams.js";
|
||||
export { QuoteHeartbeatParams } from "./QuoteHeartbeatParams.js";
|
||||
export type {
|
||||
QuoteInitParamsFields,
|
||||
QuoteInitParamsJSON,
|
||||
} from "./QuoteInitParams.js";
|
||||
export { QuoteInitParams } from "./QuoteInitParams.js";
|
||||
export type {
|
||||
QuoteRotateParamsFields,
|
||||
QuoteRotateParamsJSON,
|
||||
} from "./QuoteRotateParams.js";
|
||||
export { QuoteRotateParams } from "./QuoteRotateParams.js";
|
||||
export type {
|
||||
QuoteVerifyParamsFields,
|
||||
QuoteVerifyParamsJSON,
|
||||
} from "./QuoteVerifyParams.js";
|
||||
export { QuoteVerifyParams } from "./QuoteVerifyParams.js";
|
||||
export type {
|
||||
StateInitParamsFields,
|
||||
StateInitParamsJSON,
|
||||
} from "./StateInitParams.js";
|
||||
export { StateInitParams } from "./StateInitParams.js";
|
||||
export { FunctionStatus };
|
||||
|
||||
export type FunctionStatusKind =
|
||||
| FunctionStatus.None
|
||||
| FunctionStatus.Active
|
||||
| FunctionStatus.NonExecutable
|
||||
| FunctionStatus.Expired
|
||||
| FunctionStatus.OutOfFunds
|
||||
| FunctionStatus.InvalidPermissions;
|
||||
export type FunctionStatusJSON =
|
||||
| FunctionStatus.NoneJSON
|
||||
| FunctionStatus.ActiveJSON
|
||||
| FunctionStatus.NonExecutableJSON
|
||||
| FunctionStatus.ExpiredJSON
|
||||
| FunctionStatus.OutOfFundsJSON
|
||||
| FunctionStatus.InvalidPermissionsJSON;
|
||||
|
||||
export { VerificationStatus };
|
||||
|
||||
export type VerificationStatusKind =
|
||||
| VerificationStatus.None
|
||||
| VerificationStatus.VerificationPending
|
||||
| VerificationStatus.VerificationFailure
|
||||
| VerificationStatus.VerificationSuccess
|
||||
| VerificationStatus.VerificationOverride;
|
||||
export type VerificationStatusJSON =
|
||||
| VerificationStatus.NoneJSON
|
||||
| VerificationStatus.VerificationPendingJSON
|
||||
| VerificationStatus.VerificationFailureJSON
|
||||
| VerificationStatus.VerificationSuccessJSON
|
||||
| VerificationStatus.VerificationOverrideJSON;
|
||||
|
||||
export { SwitchboardAttestationPermission };
|
||||
|
||||
export type SwitchboardAttestationPermissionKind =
|
||||
| SwitchboardAttestationPermission.PermitNodeheartbeat
|
||||
| SwitchboardAttestationPermission.PermitQueueUsage;
|
||||
export type SwitchboardAttestationPermissionJSON =
|
||||
| SwitchboardAttestationPermission.PermitNodeheartbeatJSON
|
||||
| SwitchboardAttestationPermission.PermitQueueUsageJSON;
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./attestation-program/errors/index.js";
|
||||
export * from "./oracle-program/errors/index.js";
|
|
@ -1,4 +1,2 @@
|
|||
export * from "./accounts/index.js";
|
||||
export * from "./errors/index.js";
|
||||
export * from "./instructions/index.js";
|
||||
export * from "./types/index.js";
|
||||
export * from "./attestation-program/index.js";
|
||||
export * from "./oracle-program/index.js";
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
export * from "./attestation-program/instructions/index.js";
|
||||
export * from "./oracle-program/instructions/index.js";
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
@ -1,4 +1,4 @@
|
|||
import { SwitchboardProgram } from "../../SwitchboardProgram.js";
|
||||
import { SwitchboardProgram } from "../../../SwitchboardProgram.js";
|
||||
import * as types from "../types/index.js"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from "@coral-xyz/borsh"; // eslint-disable-line @typescript-eslint/no-unused-vars
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue