working generate script
This commit is contained in:
parent
371106f6fb
commit
0697a59469
|
@ -29,7 +29,7 @@
|
|||
"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 generate-client.js",
|
||||
"generate": "node ./generate-client.js",
|
||||
"build": "shx rm -rf lib || true; tsc -p tsconfig.cjs.json && tsc",
|
||||
"watch": "tsc -p tsconfig.cjs.json --watch",
|
||||
"test": "node ./node_modules/mocha/bin/mocha --loader=ts-node/esm --extension ts --timeout 60000 --exit",
|
||||
|
|
|
@ -265,6 +265,7 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
unpermissionedFeeds: params.unpermissionedFeeds ?? false,
|
||||
unpermissionedVrf: params.unpermissionedVrf ?? false,
|
||||
enableBufferRelayers: params.enableBufferRelayers ?? false,
|
||||
enableTeeOnly: params.enableTeeOnly ?? false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1321,6 +1322,7 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
? new anchor.BN(params.consecutiveOracleFailureLimit)
|
||||
: null,
|
||||
varianceToleranceMultiplier: multiplier,
|
||||
enableTeeOnly: params.enableTeeOnly ?? false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -1459,6 +1461,7 @@ export interface QueueInitParams {
|
|||
|
||||
keypair?: Keypair;
|
||||
dataBufferKeypair?: Keypair;
|
||||
enableTeeOnly?: boolean;
|
||||
}
|
||||
|
||||
export interface QueueSetConfigParams {
|
||||
|
@ -1515,6 +1518,7 @@ export interface QueueSetConfigParams {
|
|||
* Consecutive failure limit for an oracle before oracle permission is revoked.
|
||||
*/
|
||||
consecutiveOracleFailureLimit?: number;
|
||||
enableTeeOnly?: boolean;
|
||||
}
|
||||
|
||||
export type QueueAccountsJSON = Omit<
|
||||
|
|
|
@ -12,7 +12,7 @@ import { Account, OnAccountChangeCallback } from './account';
|
|||
import { OracleAccount } from './oracleAccount';
|
||||
import { PermissionAccount } from './permissionAccount';
|
||||
import { QueueAccount } from './queueAccount';
|
||||
import { Callback } from './vrfAccount';
|
||||
import { Callback, VrfResult } from './vrfAccount';
|
||||
|
||||
import {
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
|
@ -22,6 +22,7 @@ import {
|
|||
import {
|
||||
Commitment,
|
||||
Keypair,
|
||||
ParsedTransactionWithMeta,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
SYSVAR_INSTRUCTIONS_PUBKEY,
|
||||
|
@ -417,4 +418,115 @@ export class VrfLiteAccount extends Account<types.VrfLiteAccountData> {
|
|||
public getEscrow(): PublicKey {
|
||||
return this.program.mint.getAssociatedAddress(this.publicKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Await for the next vrf result
|
||||
*
|
||||
* @param roundId - optional, the id associated with the VRF round to watch. If not provided the current round Id will be used.
|
||||
* @param timeout - the number of milliseconds to wait for the round to close
|
||||
*
|
||||
* @throws {string} when the timeout interval is exceeded or when the latestConfirmedRound.roundOpenSlot exceeds the target roundOpenSlot
|
||||
*/
|
||||
public async nextResult(roundId?: BN, timeout = 30000): Promise<VrfResult> {
|
||||
let id: BN;
|
||||
if (roundId) {
|
||||
id = roundId;
|
||||
} else {
|
||||
const vrf = await this.loadData();
|
||||
if (vrf.status.kind === 'StatusVerifying') {
|
||||
id = vrf.counter;
|
||||
} else {
|
||||
// wait for the next round
|
||||
id = vrf.counter.add(new BN(1));
|
||||
}
|
||||
}
|
||||
let ws: number | undefined;
|
||||
|
||||
const closeWebsocket = async () => {
|
||||
if (ws !== undefined) {
|
||||
await this.program.connection.removeAccountChangeListener(ws);
|
||||
ws = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
let result: VrfResult;
|
||||
try {
|
||||
result = await promiseWithTimeout(
|
||||
timeout,
|
||||
new Promise(
|
||||
(
|
||||
resolve: (result: VrfResult) => void,
|
||||
reject: (reason: string) => void
|
||||
) => {
|
||||
ws = this.onChange(vrf => {
|
||||
if (vrf.counter.gt(id)) {
|
||||
reject(`Current counter is higher than requested roundId`);
|
||||
}
|
||||
if (vrf.counter.eq(id)) {
|
||||
switch (vrf.status.kind) {
|
||||
case 'StatusCallbackSuccess': {
|
||||
resolve({
|
||||
success: true,
|
||||
result: new Uint8Array(vrf.result),
|
||||
status: vrf.status,
|
||||
});
|
||||
break;
|
||||
}
|
||||
case 'StatusVerifyFailure': {
|
||||
resolve({
|
||||
success: false,
|
||||
result: new Uint8Array(),
|
||||
status: vrf.status,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
)
|
||||
);
|
||||
} finally {
|
||||
await closeWebsocket();
|
||||
}
|
||||
|
||||
await closeWebsocket();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Return parsed transactions for a VRF request */
|
||||
public async getCallbackTransactions(
|
||||
requestSlot?: BN,
|
||||
txnLimit = 50
|
||||
): Promise<Array<ParsedTransactionWithMeta>> {
|
||||
const slot = requestSlot ?? (await this.loadData()).requestSlot;
|
||||
// TODO: Add options and allow getting signatures by slot
|
||||
const transactions = await this.program.connection.getSignaturesForAddress(
|
||||
this.publicKey,
|
||||
{ limit: txnLimit, minContextSlot: slot.toNumber() },
|
||||
'confirmed'
|
||||
);
|
||||
const signatures = transactions.map(txn => txn.signature);
|
||||
const parsedTransactions =
|
||||
await this.program.connection.getParsedTransactions(
|
||||
signatures,
|
||||
'confirmed'
|
||||
);
|
||||
|
||||
const callbackTransactions: ParsedTransactionWithMeta[] = [];
|
||||
|
||||
for (const txn of parsedTransactions) {
|
||||
if (txn === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const logs = txn.meta?.logMessages?.join('\n') ?? '';
|
||||
if (logs.includes('Invoking callback')) {
|
||||
callbackTransactions.push(txn);
|
||||
}
|
||||
}
|
||||
|
||||
return callbackTransactions;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@ export interface OracleQueueAccountDataFields {
|
|||
mint: PublicKey;
|
||||
/** Whether oracles are permitted to fulfill buffer relayer update request. */
|
||||
enableBufferRelayers: boolean;
|
||||
enableTeeOnly: boolean;
|
||||
/** Reserved for future info. */
|
||||
ebuf: Array<number>;
|
||||
/** Maximum number of oracles a queue can support. */
|
||||
|
@ -112,6 +113,7 @@ export interface OracleQueueAccountDataJSON {
|
|||
mint: string;
|
||||
/** Whether oracles are permitted to fulfill buffer relayer update request. */
|
||||
enableBufferRelayers: boolean;
|
||||
enableTeeOnly: boolean;
|
||||
/** Reserved for future info. */
|
||||
ebuf: Array<number>;
|
||||
/** Maximum number of oracles a queue can support. */
|
||||
|
@ -170,6 +172,7 @@ export class OracleQueueAccountData {
|
|||
readonly mint: PublicKey;
|
||||
/** Whether oracles are permitted to fulfill buffer relayer update request. */
|
||||
readonly enableBufferRelayers: boolean;
|
||||
readonly enableTeeOnly: boolean;
|
||||
/** Reserved for future info. */
|
||||
readonly ebuf: Array<number>;
|
||||
/** Maximum number of oracles a queue can support. */
|
||||
|
@ -202,7 +205,8 @@ export class OracleQueueAccountData {
|
|||
borsh.bool('lockLeaseFunding'),
|
||||
borsh.publicKey('mint'),
|
||||
borsh.bool('enableBufferRelayers'),
|
||||
borsh.array(borsh.u8(), 968, 'ebuf'),
|
||||
borsh.bool('enableTeeOnly'),
|
||||
borsh.array(borsh.u8(), 967, 'ebuf'),
|
||||
borsh.u32('maxSize'),
|
||||
borsh.publicKey('dataBuffer'),
|
||||
]);
|
||||
|
@ -232,6 +236,7 @@ export class OracleQueueAccountData {
|
|||
this.lockLeaseFunding = fields.lockLeaseFunding;
|
||||
this.mint = fields.mint;
|
||||
this.enableBufferRelayers = fields.enableBufferRelayers;
|
||||
this.enableTeeOnly = fields.enableTeeOnly;
|
||||
this.ebuf = fields.ebuf;
|
||||
this.maxSize = fields.maxSize;
|
||||
this.dataBuffer = fields.dataBuffer;
|
||||
|
@ -303,6 +308,7 @@ export class OracleQueueAccountData {
|
|||
lockLeaseFunding: dec.lockLeaseFunding,
|
||||
mint: dec.mint,
|
||||
enableBufferRelayers: dec.enableBufferRelayers,
|
||||
enableTeeOnly: dec.enableTeeOnly,
|
||||
ebuf: dec.ebuf,
|
||||
maxSize: dec.maxSize,
|
||||
dataBuffer: dec.dataBuffer,
|
||||
|
@ -332,6 +338,7 @@ export class OracleQueueAccountData {
|
|||
lockLeaseFunding: this.lockLeaseFunding,
|
||||
mint: this.mint.toString(),
|
||||
enableBufferRelayers: this.enableBufferRelayers,
|
||||
enableTeeOnly: this.enableTeeOnly,
|
||||
ebuf: this.ebuf,
|
||||
maxSize: this.maxSize,
|
||||
dataBuffer: this.dataBuffer.toString(),
|
||||
|
@ -362,6 +369,7 @@ export class OracleQueueAccountData {
|
|||
lockLeaseFunding: obj.lockLeaseFunding,
|
||||
mint: new PublicKey(obj.mint),
|
||||
enableBufferRelayers: obj.enableBufferRelayers,
|
||||
enableTeeOnly: obj.enableTeeOnly,
|
||||
ebuf: obj.ebuf,
|
||||
maxSize: obj.maxSize,
|
||||
dataBuffer: new PublicKey(obj.dataBuffer),
|
||||
|
|
|
@ -0,0 +1,190 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
import { PublicKey, Connection } from '@solana/web3.js';
|
||||
import { BN } from '@switchboard-xyz/common'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as borsh from '@coral-xyz/borsh'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as types from '../types'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface QuoteAccountDataFields {
|
||||
delegatedSecuredSigner: PublicKey;
|
||||
bump: number;
|
||||
/** TODO: Add description */
|
||||
quoteRegistry: Array<number>;
|
||||
/** Key to lookup the buffer data on IPFS or an alternative decentralized storage solution. */
|
||||
registryKey: Array<number>;
|
||||
/** Queue used for attestation to verify a MRENCLAVE measurement. */
|
||||
attestationQueue: PublicKey;
|
||||
/** The quotes MRENCLAVE measurement dictating the contents of the secure enclave. */
|
||||
mrEnclave: Array<number>;
|
||||
verificationStatus: number;
|
||||
verificationTimestamp: BN;
|
||||
validUntil: BN;
|
||||
isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
lastHeartbeat: BN;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export interface QuoteAccountDataJSON {
|
||||
delegatedSecuredSigner: string;
|
||||
bump: number;
|
||||
/** TODO: Add description */
|
||||
quoteRegistry: Array<number>;
|
||||
/** Key to lookup the buffer data on IPFS or an alternative decentralized storage solution. */
|
||||
registryKey: Array<number>;
|
||||
/** Queue used for attestation to verify a MRENCLAVE measurement. */
|
||||
attestationQueue: string;
|
||||
/** The quotes MRENCLAVE measurement dictating the contents of the secure enclave. */
|
||||
mrEnclave: Array<number>;
|
||||
verificationStatus: number;
|
||||
verificationTimestamp: string;
|
||||
validUntil: string;
|
||||
isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
lastHeartbeat: string;
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
||||
export class QuoteAccountData {
|
||||
readonly delegatedSecuredSigner: PublicKey;
|
||||
readonly bump: number;
|
||||
/** TODO: Add description */
|
||||
readonly quoteRegistry: Array<number>;
|
||||
/** Key to lookup the buffer data on IPFS or an alternative decentralized storage solution. */
|
||||
readonly registryKey: Array<number>;
|
||||
/** Queue used for attestation to verify a MRENCLAVE measurement. */
|
||||
readonly attestationQueue: PublicKey;
|
||||
/** The quotes MRENCLAVE measurement dictating the contents of the secure enclave. */
|
||||
readonly mrEnclave: Array<number>;
|
||||
readonly verificationStatus: number;
|
||||
readonly verificationTimestamp: BN;
|
||||
readonly validUntil: BN;
|
||||
readonly isOnQueue: boolean;
|
||||
/** The last time the quote heartbeated. */
|
||||
readonly lastHeartbeat: BN;
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
static readonly discriminator = Buffer.from([
|
||||
205, 205, 167, 232, 0, 74, 44, 160,
|
||||
]);
|
||||
|
||||
static readonly layout = borsh.struct([
|
||||
borsh.publicKey('delegatedSecuredSigner'),
|
||||
borsh.u8('bump'),
|
||||
borsh.array(borsh.u8(), 32, 'quoteRegistry'),
|
||||
borsh.array(borsh.u8(), 64, 'registryKey'),
|
||||
borsh.publicKey('attestationQueue'),
|
||||
borsh.array(borsh.u8(), 32, 'mrEnclave'),
|
||||
borsh.u8('verificationStatus'),
|
||||
borsh.i64('verificationTimestamp'),
|
||||
borsh.i64('validUntil'),
|
||||
borsh.bool('isOnQueue'),
|
||||
borsh.i64('lastHeartbeat'),
|
||||
borsh.array(borsh.u8(), 1024, 'ebuf'),
|
||||
]);
|
||||
|
||||
constructor(fields: QuoteAccountDataFields) {
|
||||
this.delegatedSecuredSigner = fields.delegatedSecuredSigner;
|
||||
this.bump = fields.bump;
|
||||
this.quoteRegistry = fields.quoteRegistry;
|
||||
this.registryKey = fields.registryKey;
|
||||
this.attestationQueue = fields.attestationQueue;
|
||||
this.mrEnclave = fields.mrEnclave;
|
||||
this.verificationStatus = fields.verificationStatus;
|
||||
this.verificationTimestamp = fields.verificationTimestamp;
|
||||
this.validUntil = fields.validUntil;
|
||||
this.isOnQueue = fields.isOnQueue;
|
||||
this.lastHeartbeat = fields.lastHeartbeat;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
static async fetch(
|
||||
program: SwitchboardProgram,
|
||||
address: PublicKey
|
||||
): Promise<QuoteAccountData | null> {
|
||||
const info = await program.connection.getAccountInfo(address);
|
||||
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.programId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
}
|
||||
|
||||
static async fetchMultiple(
|
||||
program: SwitchboardProgram,
|
||||
addresses: PublicKey[]
|
||||
): Promise<Array<QuoteAccountData | null>> {
|
||||
const infos = await program.connection.getMultipleAccountsInfo(addresses);
|
||||
|
||||
return infos.map(info => {
|
||||
if (info === null) {
|
||||
return null;
|
||||
}
|
||||
if (!info.owner.equals(program.programId)) {
|
||||
throw new Error("account doesn't belong to this program");
|
||||
}
|
||||
|
||||
return this.decode(info.data);
|
||||
});
|
||||
}
|
||||
|
||||
static decode(data: Buffer): QuoteAccountData {
|
||||
if (!data.slice(0, 8).equals(QuoteAccountData.discriminator)) {
|
||||
throw new Error('invalid account discriminator');
|
||||
}
|
||||
|
||||
const dec = QuoteAccountData.layout.decode(data.slice(8));
|
||||
|
||||
return new QuoteAccountData({
|
||||
delegatedSecuredSigner: dec.delegatedSecuredSigner,
|
||||
bump: dec.bump,
|
||||
quoteRegistry: dec.quoteRegistry,
|
||||
registryKey: dec.registryKey,
|
||||
attestationQueue: dec.attestationQueue,
|
||||
mrEnclave: dec.mrEnclave,
|
||||
verificationStatus: dec.verificationStatus,
|
||||
verificationTimestamp: dec.verificationTimestamp,
|
||||
validUntil: dec.validUntil,
|
||||
isOnQueue: dec.isOnQueue,
|
||||
lastHeartbeat: dec.lastHeartbeat,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
||||
toJSON(): QuoteAccountDataJSON {
|
||||
return {
|
||||
delegatedSecuredSigner: this.delegatedSecuredSigner.toString(),
|
||||
bump: this.bump,
|
||||
quoteRegistry: this.quoteRegistry,
|
||||
registryKey: this.registryKey,
|
||||
attestationQueue: this.attestationQueue.toString(),
|
||||
mrEnclave: this.mrEnclave,
|
||||
verificationStatus: this.verificationStatus,
|
||||
verificationTimestamp: this.verificationTimestamp.toString(),
|
||||
validUntil: this.validUntil.toString(),
|
||||
isOnQueue: this.isOnQueue,
|
||||
lastHeartbeat: this.lastHeartbeat.toString(),
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: QuoteAccountDataJSON): QuoteAccountData {
|
||||
return new QuoteAccountData({
|
||||
delegatedSecuredSigner: new PublicKey(obj.delegatedSecuredSigner),
|
||||
bump: obj.bump,
|
||||
quoteRegistry: obj.quoteRegistry,
|
||||
registryKey: obj.registryKey,
|
||||
attestationQueue: new PublicKey(obj.attestationQueue),
|
||||
mrEnclave: obj.mrEnclave,
|
||||
verificationStatus: obj.verificationStatus,
|
||||
verificationTimestamp: new BN(obj.verificationTimestamp),
|
||||
validUntil: new BN(obj.validUntil),
|
||||
isOnQueue: obj.isOnQueue,
|
||||
lastHeartbeat: new BN(obj.lastHeartbeat),
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -15,6 +15,8 @@ export interface SbStateFields {
|
|||
daoMint: PublicKey;
|
||||
/** The PDA bump to derive the pubkey. */
|
||||
bump: number;
|
||||
/** Permitted enclave measurements */
|
||||
mrEnclaves: Array<Array<number>>;
|
||||
/** Reserved for future info. */
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
@ -30,6 +32,8 @@ export interface SbStateJSON {
|
|||
daoMint: string;
|
||||
/** The PDA bump to derive the pubkey. */
|
||||
bump: number;
|
||||
/** Permitted enclave measurements */
|
||||
mrEnclaves: Array<Array<number>>;
|
||||
/** Reserved for future info. */
|
||||
ebuf: Array<number>;
|
||||
}
|
||||
|
@ -45,6 +49,8 @@ export class SbState {
|
|||
readonly daoMint: PublicKey;
|
||||
/** The PDA bump to derive the pubkey. */
|
||||
readonly bump: number;
|
||||
/** Permitted enclave measurements */
|
||||
readonly mrEnclaves: Array<Array<number>>;
|
||||
/** Reserved for future info. */
|
||||
readonly ebuf: Array<number>;
|
||||
|
||||
|
@ -58,7 +64,8 @@ export class SbState {
|
|||
borsh.publicKey('tokenVault'),
|
||||
borsh.publicKey('daoMint'),
|
||||
borsh.u8('bump'),
|
||||
borsh.array(borsh.u8(), 991, 'ebuf'),
|
||||
borsh.array(borsh.array(borsh.u8(), 32), 6, 'mrEnclaves'),
|
||||
borsh.array(borsh.u8(), 799, 'ebuf'),
|
||||
]);
|
||||
|
||||
constructor(fields: SbStateFields) {
|
||||
|
@ -67,6 +74,7 @@ export class SbState {
|
|||
this.tokenVault = fields.tokenVault;
|
||||
this.daoMint = fields.daoMint;
|
||||
this.bump = fields.bump;
|
||||
this.mrEnclaves = fields.mrEnclaves;
|
||||
this.ebuf = fields.ebuf;
|
||||
}
|
||||
|
||||
|
@ -117,6 +125,7 @@ export class SbState {
|
|||
tokenVault: dec.tokenVault,
|
||||
daoMint: dec.daoMint,
|
||||
bump: dec.bump,
|
||||
mrEnclaves: dec.mrEnclaves,
|
||||
ebuf: dec.ebuf,
|
||||
});
|
||||
}
|
||||
|
@ -128,6 +137,7 @@ export class SbState {
|
|||
tokenVault: this.tokenVault.toString(),
|
||||
daoMint: this.daoMint.toString(),
|
||||
bump: this.bump,
|
||||
mrEnclaves: this.mrEnclaves,
|
||||
ebuf: this.ebuf,
|
||||
};
|
||||
}
|
||||
|
@ -139,6 +149,7 @@ export class SbState {
|
|||
tokenVault: new PublicKey(obj.tokenVault),
|
||||
daoMint: new PublicKey(obj.daoMint),
|
||||
bump: obj.bump,
|
||||
mrEnclaves: obj.mrEnclaves,
|
||||
ebuf: obj.ebuf,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
export { QuoteAccountData } from './QuoteAccountData';
|
||||
export type {
|
||||
QuoteAccountDataFields,
|
||||
QuoteAccountDataJSON,
|
||||
} from './QuoteAccountData';
|
||||
export { SbState } from './SbState';
|
||||
export type { SbStateFields, SbStateJSON } from './SbState';
|
||||
export { TaskSpecRecord } from './TaskSpecRecord';
|
||||
|
|
|
@ -99,7 +99,10 @@ export type CustomError =
|
|||
| VrfPoolRequestTooSoon
|
||||
| VrfPoolMiss
|
||||
| VrfLiteOwnedByPool
|
||||
| InsufficientTokenBalance;
|
||||
| InsufficientTokenBalance
|
||||
| InvalidQuoteError
|
||||
| InvalidHistoryAccountError
|
||||
| GenericError;
|
||||
|
||||
export class ArrayOperationError extends Error {
|
||||
static readonly code = 6000;
|
||||
|
@ -1235,6 +1238,37 @@ export class InsufficientTokenBalance extends Error {
|
|||
}
|
||||
}
|
||||
|
||||
export class InvalidQuoteError extends Error {
|
||||
static readonly code = 6100;
|
||||
readonly code = 6100;
|
||||
readonly name = 'InvalidQuoteError';
|
||||
readonly msg = 'Invalid SAS quote account';
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('6100: Invalid SAS quote account');
|
||||
}
|
||||
}
|
||||
|
||||
export class InvalidHistoryAccountError extends Error {
|
||||
static readonly code = 6101;
|
||||
readonly code = 6101;
|
||||
readonly name = 'InvalidHistoryAccountError';
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('6101: ');
|
||||
}
|
||||
}
|
||||
|
||||
export class GenericError extends Error {
|
||||
static readonly code = 6102;
|
||||
readonly code = 6102;
|
||||
readonly name = 'GenericError';
|
||||
|
||||
constructor(readonly logs?: string[]) {
|
||||
super('6102: ');
|
||||
}
|
||||
}
|
||||
|
||||
export function fromCode(code: number, logs?: string[]): CustomError | null {
|
||||
switch (code) {
|
||||
case 6000:
|
||||
|
@ -1437,6 +1471,12 @@ export function fromCode(code: number, logs?: string[]): CustomError | null {
|
|||
return new VrfLiteOwnedByPool(logs);
|
||||
case 6099:
|
||||
return new InsufficientTokenBalance(logs);
|
||||
case 6100:
|
||||
return new InvalidQuoteError(logs);
|
||||
case 6101:
|
||||
return new InvalidHistoryAccountError(logs);
|
||||
case 6102:
|
||||
return new GenericError(logs);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { SBV2_DEVNET_PID, SBV2_MAINNET_PID } from '../../SwitchboardProgram';
|
||||
import { PROGRAM_ID } from '../programId';
|
||||
import * as anchor from './anchor';
|
||||
import * as custom from './custom';
|
||||
|
@ -46,10 +45,7 @@ export function fromTxError(
|
|||
}
|
||||
|
||||
const [programIdRaw, codeRaw] = firstMatch.slice(1);
|
||||
if (
|
||||
programIdRaw !== SBV2_DEVNET_PID.toString() &&
|
||||
programIdRaw !== SBV2_MAINNET_PID.toString()
|
||||
) {
|
||||
if (programIdRaw !== PROGRAM_ID.toString()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
import {
|
||||
TransactionInstruction,
|
||||
PublicKey,
|
||||
AccountMeta,
|
||||
} 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 borsh from '@coral-xyz/borsh'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as types from '../types'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface AggregatorTeeSaveResultArgs {
|
||||
params: types.AggregatorTeeSaveResultParamsFields;
|
||||
}
|
||||
|
||||
export interface AggregatorTeeSaveResultAccounts {
|
||||
aggregator: PublicKey;
|
||||
oracle: PublicKey;
|
||||
oracleAuthority: PublicKey;
|
||||
oracleQueue: PublicKey;
|
||||
queueAuthority: PublicKey;
|
||||
feedPermission: PublicKey;
|
||||
oraclePermission: PublicKey;
|
||||
lease: PublicKey;
|
||||
escrow: PublicKey;
|
||||
tokenProgram: PublicKey;
|
||||
programState: PublicKey;
|
||||
historyBuffer: PublicKey;
|
||||
mint: PublicKey;
|
||||
slider: PublicKey;
|
||||
quote: PublicKey;
|
||||
rewardWallet: PublicKey;
|
||||
payer: PublicKey;
|
||||
systemProgram: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.AggregatorTeeSaveResultParams.layout('params'),
|
||||
]);
|
||||
|
||||
export function aggregatorTeeSaveResult(
|
||||
program: SwitchboardProgram,
|
||||
args: AggregatorTeeSaveResultArgs,
|
||||
accounts: AggregatorTeeSaveResultAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.aggregator, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oracle, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oracleAuthority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.oracleQueue, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.feedPermission, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oraclePermission, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.lease, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.programState, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.historyBuffer, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.slider, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.rewardWallet, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.payer, isSigner: true, isWritable: true },
|
||||
{ pubkey: accounts.systemProgram, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([43, 192, 193, 209, 121, 90, 186, 135]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.AggregatorTeeSaveResultParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.programId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -40,6 +40,11 @@ export type {
|
|||
AggregatorSaveResultV2Args,
|
||||
AggregatorSaveResultV2Accounts,
|
||||
} from './aggregatorSaveResultV2';
|
||||
export { aggregatorTeeSaveResult } from './aggregatorTeeSaveResult';
|
||||
export type {
|
||||
AggregatorTeeSaveResultArgs,
|
||||
AggregatorTeeSaveResultAccounts,
|
||||
} from './aggregatorTeeSaveResult';
|
||||
export { aggregatorSetAuthority } from './aggregatorSetAuthority';
|
||||
export type {
|
||||
AggregatorSetAuthorityArgs,
|
||||
|
@ -108,6 +113,11 @@ export type {
|
|||
OracleHeartbeatArgs,
|
||||
OracleHeartbeatAccounts,
|
||||
} from './oracleHeartbeat';
|
||||
export { oracleTeeHeartbeat } from './oracleTeeHeartbeat';
|
||||
export type {
|
||||
OracleTeeHeartbeatArgs,
|
||||
OracleTeeHeartbeatAccounts,
|
||||
} from './oracleTeeHeartbeat';
|
||||
export { oracleInit } from './oracleInit';
|
||||
export type { OracleInitArgs, OracleInitAccounts } from './oracleInit';
|
||||
export { oracleQueueInit } from './oracleQueueInit';
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
import {
|
||||
TransactionInstruction,
|
||||
PublicKey,
|
||||
AccountMeta,
|
||||
} 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 borsh from '@coral-xyz/borsh'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as types from '../types'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
export interface OracleTeeHeartbeatArgs {
|
||||
params: types.OracleTeeHeartbeatParamsFields;
|
||||
}
|
||||
|
||||
export interface OracleTeeHeartbeatAccounts {
|
||||
oracle: PublicKey;
|
||||
oracleAuthority: PublicKey;
|
||||
tokenAccount: PublicKey;
|
||||
gcOracle: PublicKey;
|
||||
oracleQueue: PublicKey;
|
||||
permission: PublicKey;
|
||||
dataBuffer: PublicKey;
|
||||
quote: PublicKey;
|
||||
programState: PublicKey;
|
||||
}
|
||||
|
||||
export const layout = borsh.struct([
|
||||
types.OracleTeeHeartbeatParams.layout('params'),
|
||||
]);
|
||||
|
||||
export function oracleTeeHeartbeat(
|
||||
program: SwitchboardProgram,
|
||||
args: OracleTeeHeartbeatArgs,
|
||||
accounts: OracleTeeHeartbeatAccounts
|
||||
) {
|
||||
const keys: Array<AccountMeta> = [
|
||||
{ pubkey: accounts.oracle, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oracleAuthority, isSigner: true, isWritable: false },
|
||||
{ pubkey: accounts.tokenAccount, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.gcOracle, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.oracleQueue, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.permission, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.dataBuffer, isSigner: false, isWritable: true },
|
||||
{ pubkey: accounts.quote, isSigner: false, isWritable: false },
|
||||
{ pubkey: accounts.programState, isSigner: false, isWritable: false },
|
||||
];
|
||||
const identifier = Buffer.from([92, 64, 133, 138, 16, 62, 245, 251]);
|
||||
const buffer = Buffer.alloc(1000);
|
||||
const len = layout.encode(
|
||||
{
|
||||
params: types.OracleTeeHeartbeatParams.toEncodable(args.params),
|
||||
},
|
||||
buffer
|
||||
);
|
||||
const data = Buffer.concat([identifier, buffer]).slice(0, 8 + len);
|
||||
const ix = new TransactionInstruction({
|
||||
keys,
|
||||
programId: program.programId,
|
||||
data,
|
||||
});
|
||||
return ix;
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
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'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as borsh from '@coral-xyz/borsh';
|
||||
|
||||
export interface AggregatorTeeSaveResultParamsFields {
|
||||
value: types.BorshDecimalFields;
|
||||
jobsChecksum: Array<number>;
|
||||
minResponse: types.BorshDecimalFields;
|
||||
maxResponse: types.BorshDecimalFields;
|
||||
feedPermissionBump: number;
|
||||
oraclePermissionBump: number;
|
||||
leaseBump: number;
|
||||
stateBump: number;
|
||||
}
|
||||
|
||||
export interface AggregatorTeeSaveResultParamsJSON {
|
||||
value: types.BorshDecimalJSON;
|
||||
jobsChecksum: Array<number>;
|
||||
minResponse: types.BorshDecimalJSON;
|
||||
maxResponse: types.BorshDecimalJSON;
|
||||
feedPermissionBump: number;
|
||||
oraclePermissionBump: number;
|
||||
leaseBump: number;
|
||||
stateBump: number;
|
||||
}
|
||||
|
||||
export class AggregatorTeeSaveResultParams {
|
||||
readonly value: types.BorshDecimal;
|
||||
readonly jobsChecksum: Array<number>;
|
||||
readonly minResponse: types.BorshDecimal;
|
||||
readonly maxResponse: types.BorshDecimal;
|
||||
readonly feedPermissionBump: number;
|
||||
readonly oraclePermissionBump: number;
|
||||
readonly leaseBump: number;
|
||||
readonly stateBump: number;
|
||||
|
||||
constructor(fields: AggregatorTeeSaveResultParamsFields) {
|
||||
this.value = new types.BorshDecimal({ ...fields.value });
|
||||
this.jobsChecksum = fields.jobsChecksum;
|
||||
this.minResponse = new types.BorshDecimal({ ...fields.minResponse });
|
||||
this.maxResponse = new types.BorshDecimal({ ...fields.maxResponse });
|
||||
this.feedPermissionBump = fields.feedPermissionBump;
|
||||
this.oraclePermissionBump = fields.oraclePermissionBump;
|
||||
this.leaseBump = fields.leaseBump;
|
||||
this.stateBump = fields.stateBump;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[
|
||||
types.BorshDecimal.layout('value'),
|
||||
borsh.array(borsh.u8(), 32, 'jobsChecksum'),
|
||||
types.BorshDecimal.layout('minResponse'),
|
||||
types.BorshDecimal.layout('maxResponse'),
|
||||
borsh.u8('feedPermissionBump'),
|
||||
borsh.u8('oraclePermissionBump'),
|
||||
borsh.u8('leaseBump'),
|
||||
borsh.u8('stateBump'),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new AggregatorTeeSaveResultParams({
|
||||
value: types.BorshDecimal.fromDecoded(obj.value),
|
||||
jobsChecksum: obj.jobsChecksum,
|
||||
minResponse: types.BorshDecimal.fromDecoded(obj.minResponse),
|
||||
maxResponse: types.BorshDecimal.fromDecoded(obj.maxResponse),
|
||||
feedPermissionBump: obj.feedPermissionBump,
|
||||
oraclePermissionBump: obj.oraclePermissionBump,
|
||||
leaseBump: obj.leaseBump,
|
||||
stateBump: obj.stateBump,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: AggregatorTeeSaveResultParamsFields) {
|
||||
return {
|
||||
value: types.BorshDecimal.toEncodable(fields.value),
|
||||
jobsChecksum: fields.jobsChecksum,
|
||||
minResponse: types.BorshDecimal.toEncodable(fields.minResponse),
|
||||
maxResponse: types.BorshDecimal.toEncodable(fields.maxResponse),
|
||||
feedPermissionBump: fields.feedPermissionBump,
|
||||
oraclePermissionBump: fields.oraclePermissionBump,
|
||||
leaseBump: fields.leaseBump,
|
||||
stateBump: fields.stateBump,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): AggregatorTeeSaveResultParamsJSON {
|
||||
return {
|
||||
value: this.value.toJSON(),
|
||||
jobsChecksum: this.jobsChecksum,
|
||||
minResponse: this.minResponse.toJSON(),
|
||||
maxResponse: this.maxResponse.toJSON(),
|
||||
feedPermissionBump: this.feedPermissionBump,
|
||||
oraclePermissionBump: this.oraclePermissionBump,
|
||||
leaseBump: this.leaseBump,
|
||||
stateBump: this.stateBump,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(
|
||||
obj: AggregatorTeeSaveResultParamsJSON
|
||||
): AggregatorTeeSaveResultParams {
|
||||
return new AggregatorTeeSaveResultParams({
|
||||
value: types.BorshDecimal.fromJSON(obj.value),
|
||||
jobsChecksum: obj.jobsChecksum,
|
||||
minResponse: types.BorshDecimal.fromJSON(obj.minResponse),
|
||||
maxResponse: types.BorshDecimal.fromJSON(obj.maxResponse),
|
||||
feedPermissionBump: obj.feedPermissionBump,
|
||||
oraclePermissionBump: obj.oraclePermissionBump,
|
||||
leaseBump: obj.leaseBump,
|
||||
stateBump: obj.stateBump,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return AggregatorTeeSaveResultParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
import * as borsh from '@coral-xyz/borsh';
|
||||
import * as types from '../types'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
|
||||
import * as borsh from '@coral-xyz/borsh';
|
||||
|
||||
export interface DJSON {
|
||||
kind: 'D';
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ export interface OracleQueueInitParamsFields {
|
|||
unpermissionedFeeds: boolean;
|
||||
unpermissionedVrf: boolean;
|
||||
enableBufferRelayers: boolean;
|
||||
enableTeeOnly: boolean;
|
||||
}
|
||||
|
||||
export interface OracleQueueInitParamsJSON {
|
||||
|
@ -36,6 +37,7 @@ export interface OracleQueueInitParamsJSON {
|
|||
unpermissionedFeeds: boolean;
|
||||
unpermissionedVrf: boolean;
|
||||
enableBufferRelayers: boolean;
|
||||
enableTeeOnly: boolean;
|
||||
}
|
||||
|
||||
export class OracleQueueInitParams {
|
||||
|
@ -53,6 +55,7 @@ export class OracleQueueInitParams {
|
|||
readonly unpermissionedFeeds: boolean;
|
||||
readonly unpermissionedVrf: boolean;
|
||||
readonly enableBufferRelayers: boolean;
|
||||
readonly enableTeeOnly: boolean;
|
||||
|
||||
constructor(fields: OracleQueueInitParamsFields) {
|
||||
this.name = fields.name;
|
||||
|
@ -71,6 +74,7 @@ export class OracleQueueInitParams {
|
|||
this.unpermissionedFeeds = fields.unpermissionedFeeds;
|
||||
this.unpermissionedVrf = fields.unpermissionedVrf;
|
||||
this.enableBufferRelayers = fields.enableBufferRelayers;
|
||||
this.enableTeeOnly = fields.enableTeeOnly;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
|
@ -90,6 +94,7 @@ export class OracleQueueInitParams {
|
|||
borsh.bool('unpermissionedFeeds'),
|
||||
borsh.bool('unpermissionedVrf'),
|
||||
borsh.bool('enableBufferRelayers'),
|
||||
borsh.bool('enableTeeOnly'),
|
||||
],
|
||||
property
|
||||
);
|
||||
|
@ -114,6 +119,7 @@ export class OracleQueueInitParams {
|
|||
unpermissionedFeeds: obj.unpermissionedFeeds,
|
||||
unpermissionedVrf: obj.unpermissionedVrf,
|
||||
enableBufferRelayers: obj.enableBufferRelayers,
|
||||
enableTeeOnly: obj.enableTeeOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -135,6 +141,7 @@ export class OracleQueueInitParams {
|
|||
unpermissionedFeeds: fields.unpermissionedFeeds,
|
||||
unpermissionedVrf: fields.unpermissionedVrf,
|
||||
enableBufferRelayers: fields.enableBufferRelayers,
|
||||
enableTeeOnly: fields.enableTeeOnly,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -155,6 +162,7 @@ export class OracleQueueInitParams {
|
|||
unpermissionedFeeds: this.unpermissionedFeeds,
|
||||
unpermissionedVrf: this.unpermissionedVrf,
|
||||
enableBufferRelayers: this.enableBufferRelayers,
|
||||
enableTeeOnly: this.enableTeeOnly,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -176,6 +184,7 @@ export class OracleQueueInitParams {
|
|||
unpermissionedFeeds: obj.unpermissionedFeeds,
|
||||
unpermissionedVrf: obj.unpermissionedVrf,
|
||||
enableBufferRelayers: obj.enableBufferRelayers,
|
||||
enableTeeOnly: obj.enableTeeOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ export interface OracleQueueSetConfigParamsFields {
|
|||
oracleTimeout: number | null;
|
||||
consecutiveFeedFailureLimit: BN | null;
|
||||
consecutiveOracleFailureLimit: BN | null;
|
||||
enableTeeOnly: boolean | null;
|
||||
}
|
||||
|
||||
export interface OracleQueueSetConfigParamsJSON {
|
||||
|
@ -32,6 +33,7 @@ export interface OracleQueueSetConfigParamsJSON {
|
|||
oracleTimeout: number | null;
|
||||
consecutiveFeedFailureLimit: string | null;
|
||||
consecutiveOracleFailureLimit: string | null;
|
||||
enableTeeOnly: boolean | null;
|
||||
}
|
||||
|
||||
export class OracleQueueSetConfigParams {
|
||||
|
@ -47,6 +49,7 @@ export class OracleQueueSetConfigParams {
|
|||
readonly oracleTimeout: number | null;
|
||||
readonly consecutiveFeedFailureLimit: BN | null;
|
||||
readonly consecutiveOracleFailureLimit: BN | null;
|
||||
readonly enableTeeOnly: boolean | null;
|
||||
|
||||
constructor(fields: OracleQueueSetConfigParamsFields) {
|
||||
this.name = fields.name;
|
||||
|
@ -64,6 +67,7 @@ export class OracleQueueSetConfigParams {
|
|||
this.oracleTimeout = fields.oracleTimeout;
|
||||
this.consecutiveFeedFailureLimit = fields.consecutiveFeedFailureLimit;
|
||||
this.consecutiveOracleFailureLimit = fields.consecutiveOracleFailureLimit;
|
||||
this.enableTeeOnly = fields.enableTeeOnly;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
|
@ -84,6 +88,7 @@ export class OracleQueueSetConfigParams {
|
|||
borsh.option(borsh.u32(), 'oracleTimeout'),
|
||||
borsh.option(borsh.u64(), 'consecutiveFeedFailureLimit'),
|
||||
borsh.option(borsh.u64(), 'consecutiveOracleFailureLimit'),
|
||||
borsh.option(borsh.bool(), 'enableTeeOnly'),
|
||||
],
|
||||
property
|
||||
);
|
||||
|
@ -107,6 +112,7 @@ export class OracleQueueSetConfigParams {
|
|||
oracleTimeout: obj.oracleTimeout,
|
||||
consecutiveFeedFailureLimit: obj.consecutiveFeedFailureLimit,
|
||||
consecutiveOracleFailureLimit: obj.consecutiveOracleFailureLimit,
|
||||
enableTeeOnly: obj.enableTeeOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -127,6 +133,7 @@ export class OracleQueueSetConfigParams {
|
|||
oracleTimeout: fields.oracleTimeout,
|
||||
consecutiveFeedFailureLimit: fields.consecutiveFeedFailureLimit,
|
||||
consecutiveOracleFailureLimit: fields.consecutiveOracleFailureLimit,
|
||||
enableTeeOnly: fields.enableTeeOnly,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -153,6 +160,7 @@ export class OracleQueueSetConfigParams {
|
|||
(this.consecutiveOracleFailureLimit &&
|
||||
this.consecutiveOracleFailureLimit.toString()) ||
|
||||
null,
|
||||
enableTeeOnly: this.enableTeeOnly,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -181,6 +189,7 @@ export class OracleQueueSetConfigParams {
|
|||
(obj.consecutiveOracleFailureLimit &&
|
||||
new BN(obj.consecutiveOracleFailureLimit)) ||
|
||||
null,
|
||||
enableTeeOnly: obj.enableTeeOnly,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
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'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as borsh from '@coral-xyz/borsh';
|
||||
|
||||
export interface OracleTeeHeartbeatParamsFields {
|
||||
permissionBump: number;
|
||||
}
|
||||
|
||||
export interface OracleTeeHeartbeatParamsJSON {
|
||||
permissionBump: number;
|
||||
}
|
||||
|
||||
export class OracleTeeHeartbeatParams {
|
||||
readonly permissionBump: number;
|
||||
|
||||
constructor(fields: OracleTeeHeartbeatParamsFields) {
|
||||
this.permissionBump = fields.permissionBump;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct([borsh.u8('permissionBump')], property);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
static fromDecoded(obj: any) {
|
||||
return new OracleTeeHeartbeatParams({
|
||||
permissionBump: obj.permissionBump,
|
||||
});
|
||||
}
|
||||
|
||||
static toEncodable(fields: OracleTeeHeartbeatParamsFields) {
|
||||
return {
|
||||
permissionBump: fields.permissionBump,
|
||||
};
|
||||
}
|
||||
|
||||
toJSON(): OracleTeeHeartbeatParamsJSON {
|
||||
return {
|
||||
permissionBump: this.permissionBump,
|
||||
};
|
||||
}
|
||||
|
||||
static fromJSON(obj: OracleTeeHeartbeatParamsJSON): OracleTeeHeartbeatParams {
|
||||
return new OracleTeeHeartbeatParams({
|
||||
permissionBump: obj.permissionBump,
|
||||
});
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return OracleTeeHeartbeatParams.toEncodable(this);
|
||||
}
|
||||
}
|
|
@ -8,28 +8,42 @@ export interface ProgramConfigParamsFields {
|
|||
token: PublicKey;
|
||||
bump: number;
|
||||
daoMint: PublicKey;
|
||||
addEnclaves: Array<Array<number>>;
|
||||
rmEnclaves: Array<Array<number>>;
|
||||
}
|
||||
|
||||
export interface ProgramConfigParamsJSON {
|
||||
token: string;
|
||||
bump: number;
|
||||
daoMint: string;
|
||||
addEnclaves: Array<Array<number>>;
|
||||
rmEnclaves: Array<Array<number>>;
|
||||
}
|
||||
|
||||
export class ProgramConfigParams {
|
||||
readonly token: PublicKey;
|
||||
readonly bump: number;
|
||||
readonly daoMint: PublicKey;
|
||||
readonly addEnclaves: Array<Array<number>>;
|
||||
readonly rmEnclaves: Array<Array<number>>;
|
||||
|
||||
constructor(fields: ProgramConfigParamsFields) {
|
||||
this.token = fields.token;
|
||||
this.bump = fields.bump;
|
||||
this.daoMint = fields.daoMint;
|
||||
this.addEnclaves = fields.addEnclaves;
|
||||
this.rmEnclaves = fields.rmEnclaves;
|
||||
}
|
||||
|
||||
static layout(property?: string) {
|
||||
return borsh.struct(
|
||||
[borsh.publicKey('token'), borsh.u8('bump'), borsh.publicKey('daoMint')],
|
||||
[
|
||||
borsh.publicKey('token'),
|
||||
borsh.u8('bump'),
|
||||
borsh.publicKey('daoMint'),
|
||||
borsh.vec(borsh.array(borsh.u8(), 32), 'addEnclaves'),
|
||||
borsh.vec(borsh.array(borsh.u8(), 32), 'rmEnclaves'),
|
||||
],
|
||||
property
|
||||
);
|
||||
}
|
||||
|
@ -40,6 +54,8 @@ export class ProgramConfigParams {
|
|||
token: obj.token,
|
||||
bump: obj.bump,
|
||||
daoMint: obj.daoMint,
|
||||
addEnclaves: obj.addEnclaves,
|
||||
rmEnclaves: obj.rmEnclaves,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -48,6 +64,8 @@ export class ProgramConfigParams {
|
|||
token: fields.token,
|
||||
bump: fields.bump,
|
||||
daoMint: fields.daoMint,
|
||||
addEnclaves: fields.addEnclaves,
|
||||
rmEnclaves: fields.rmEnclaves,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -56,6 +74,8 @@ export class ProgramConfigParams {
|
|||
token: this.token.toString(),
|
||||
bump: this.bump,
|
||||
daoMint: this.daoMint.toString(),
|
||||
addEnclaves: this.addEnclaves,
|
||||
rmEnclaves: this.rmEnclaves,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -64,6 +84,8 @@ export class ProgramConfigParams {
|
|||
token: new PublicKey(obj.token),
|
||||
bump: obj.bump,
|
||||
daoMint: new PublicKey(obj.daoMint),
|
||||
addEnclaves: obj.addEnclaves,
|
||||
rmEnclaves: obj.rmEnclaves,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
import { SwitchboardProgram } from '../../SwitchboardProgram';
|
||||
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'; // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
import * as borsh from '@coral-xyz/borsh';
|
||||
|
||||
export interface VerificationPendingJSON {
|
||||
kind: 'VerificationPending';
|
||||
}
|
||||
|
||||
export class VerificationPending {
|
||||
static readonly discriminator = 0;
|
||||
static readonly kind = 'VerificationPending';
|
||||
readonly discriminator = 0;
|
||||
readonly kind = 'VerificationPending';
|
||||
|
||||
toJSON(): VerificationPendingJSON {
|
||||
return {
|
||||
kind: 'VerificationPending',
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
VerificationPending: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface VerificationFailureJSON {
|
||||
kind: 'VerificationFailure';
|
||||
}
|
||||
|
||||
export class VerificationFailure {
|
||||
static readonly discriminator = 1;
|
||||
static readonly kind = 'VerificationFailure';
|
||||
readonly discriminator = 1;
|
||||
readonly kind = 'VerificationFailure';
|
||||
|
||||
toJSON(): VerificationFailureJSON {
|
||||
return {
|
||||
kind: 'VerificationFailure',
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
VerificationFailure: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface VerificationSuccessJSON {
|
||||
kind: 'VerificationSuccess';
|
||||
}
|
||||
|
||||
export class VerificationSuccess {
|
||||
static readonly discriminator = 2;
|
||||
static readonly kind = 'VerificationSuccess';
|
||||
readonly discriminator = 2;
|
||||
readonly kind = 'VerificationSuccess';
|
||||
|
||||
toJSON(): VerificationSuccessJSON {
|
||||
return {
|
||||
kind: 'VerificationSuccess',
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
VerificationSuccess: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export interface VerificationOverrideJSON {
|
||||
kind: 'VerificationOverride';
|
||||
}
|
||||
|
||||
export class VerificationOverride {
|
||||
static readonly discriminator = 3;
|
||||
static readonly kind = 'VerificationOverride';
|
||||
readonly discriminator = 3;
|
||||
readonly kind = 'VerificationOverride';
|
||||
|
||||
toJSON(): VerificationOverrideJSON {
|
||||
return {
|
||||
kind: 'VerificationOverride',
|
||||
};
|
||||
}
|
||||
|
||||
toEncodable() {
|
||||
return {
|
||||
VerificationOverride: {},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export function fromDecoded(obj: any): types.VerificationStatusKind {
|
||||
if (typeof obj !== 'object') {
|
||||
throw new Error('Invalid enum object');
|
||||
}
|
||||
|
||||
if ('VerificationPending' in obj) {
|
||||
return new VerificationPending();
|
||||
}
|
||||
if ('VerificationFailure' in obj) {
|
||||
return new VerificationFailure();
|
||||
}
|
||||
if ('VerificationSuccess' in obj) {
|
||||
return new VerificationSuccess();
|
||||
}
|
||||
if ('VerificationOverride' in obj) {
|
||||
return new VerificationOverride();
|
||||
}
|
||||
|
||||
throw new Error('Invalid enum object');
|
||||
}
|
||||
|
||||
export function fromJSON(
|
||||
obj: types.VerificationStatusJSON
|
||||
): types.VerificationStatusKind {
|
||||
switch (obj.kind) {
|
||||
case 'VerificationPending': {
|
||||
return new VerificationPending();
|
||||
}
|
||||
case 'VerificationFailure': {
|
||||
return new VerificationFailure();
|
||||
}
|
||||
case 'VerificationSuccess': {
|
||||
return new VerificationSuccess();
|
||||
}
|
||||
case 'VerificationOverride': {
|
||||
return new VerificationOverride();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function layout(property?: string) {
|
||||
const ret = borsh.rustEnum([
|
||||
borsh.struct([], 'VerificationPending'),
|
||||
borsh.struct([], 'VerificationFailure'),
|
||||
borsh.struct([], 'VerificationSuccess'),
|
||||
borsh.struct([], 'VerificationOverride'),
|
||||
]);
|
||||
if (property !== undefined) {
|
||||
return ret.replicate(property);
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -4,400 +4,384 @@ import * as Lanes from './Lanes';
|
|||
import * as OracleResponseType from './OracleResponseType';
|
||||
import * as Shuffle from './Shuffle';
|
||||
import * as SwitchboardPermission from './SwitchboardPermission';
|
||||
import * as VerificationStatus from './VerificationStatus';
|
||||
import * as VrfStatus from './VrfStatus';
|
||||
|
||||
export { AccountMetaBorsh } from './AccountMetaBorsh';
|
||||
export type {
|
||||
AccountMetaBorshFields,
|
||||
AccountMetaBorshJSON,
|
||||
} from './AccountMetaBorsh';
|
||||
export { AccountMetaZC } from './AccountMetaZC';
|
||||
export { AccountMetaBorsh } from './AccountMetaBorsh';
|
||||
export type { AccountMetaZCFields, AccountMetaZCJSON } from './AccountMetaZC';
|
||||
export { AggregatorAddJobParams } from './AggregatorAddJobParams';
|
||||
export { AccountMetaZC } from './AccountMetaZC';
|
||||
export type {
|
||||
AggregatorAddJobParamsFields,
|
||||
AggregatorAddJobParamsJSON,
|
||||
} from './AggregatorAddJobParams';
|
||||
export { AggregatorCloseParams } from './AggregatorCloseParams';
|
||||
export { AggregatorAddJobParams } from './AggregatorAddJobParams';
|
||||
export type {
|
||||
AggregatorCloseParamsFields,
|
||||
AggregatorCloseParamsJSON,
|
||||
} from './AggregatorCloseParams';
|
||||
export { AggregatorHistoryRow } from './AggregatorHistoryRow';
|
||||
export { AggregatorCloseParams } from './AggregatorCloseParams';
|
||||
export type {
|
||||
AggregatorHistoryRowFields,
|
||||
AggregatorHistoryRowJSON,
|
||||
} from './AggregatorHistoryRow';
|
||||
export { AggregatorInitParams } from './AggregatorInitParams';
|
||||
export { AggregatorHistoryRow } from './AggregatorHistoryRow';
|
||||
export type {
|
||||
AggregatorInitParamsFields,
|
||||
AggregatorInitParamsJSON,
|
||||
} from './AggregatorInitParams';
|
||||
export { AggregatorLockParams } from './AggregatorLockParams';
|
||||
export { AggregatorInitParams } from './AggregatorInitParams';
|
||||
export type {
|
||||
AggregatorLockParamsFields,
|
||||
AggregatorLockParamsJSON,
|
||||
} from './AggregatorLockParams';
|
||||
export { AggregatorOpenRoundParams } from './AggregatorOpenRoundParams';
|
||||
export { AggregatorLockParams } from './AggregatorLockParams';
|
||||
export type {
|
||||
AggregatorOpenRoundParamsFields,
|
||||
AggregatorOpenRoundParamsJSON,
|
||||
} from './AggregatorOpenRoundParams';
|
||||
export { AggregatorRemoveJobParams } from './AggregatorRemoveJobParams';
|
||||
export { AggregatorOpenRoundParams } from './AggregatorOpenRoundParams';
|
||||
export type {
|
||||
AggregatorRemoveJobParamsFields,
|
||||
AggregatorRemoveJobParamsJSON,
|
||||
} from './AggregatorRemoveJobParams';
|
||||
export { AggregatorRound } from './AggregatorRound';
|
||||
export { AggregatorRemoveJobParams } from './AggregatorRemoveJobParams';
|
||||
export type {
|
||||
AggregatorRoundFields,
|
||||
AggregatorRoundJSON,
|
||||
} from './AggregatorRound';
|
||||
export { AggregatorSaveResultParams } from './AggregatorSaveResultParams';
|
||||
export { AggregatorRound } from './AggregatorRound';
|
||||
export type {
|
||||
AggregatorSaveResultParamsFields,
|
||||
AggregatorSaveResultParamsJSON,
|
||||
} from './AggregatorSaveResultParams';
|
||||
export { AggregatorSaveResultParamsV2 } from './AggregatorSaveResultParamsV2';
|
||||
export { AggregatorSaveResultParams } from './AggregatorSaveResultParams';
|
||||
export type {
|
||||
AggregatorSaveResultParamsV2Fields,
|
||||
AggregatorSaveResultParamsV2JSON,
|
||||
} from './AggregatorSaveResultParamsV2';
|
||||
export { AggregatorSetAuthorityParams } from './AggregatorSetAuthorityParams';
|
||||
export { AggregatorSaveResultParamsV2 } from './AggregatorSaveResultParamsV2';
|
||||
export type {
|
||||
AggregatorSetAuthorityParamsFields,
|
||||
AggregatorSetAuthorityParamsJSON,
|
||||
} from './AggregatorSetAuthorityParams';
|
||||
export { AggregatorSetBatchSizeParams } from './AggregatorSetBatchSizeParams';
|
||||
export { AggregatorSetAuthorityParams } from './AggregatorSetAuthorityParams';
|
||||
export type {
|
||||
AggregatorSetBatchSizeParamsFields,
|
||||
AggregatorSetBatchSizeParamsJSON,
|
||||
} from './AggregatorSetBatchSizeParams';
|
||||
export { AggregatorSetConfigParams } from './AggregatorSetConfigParams';
|
||||
export { AggregatorSetBatchSizeParams } from './AggregatorSetBatchSizeParams';
|
||||
export type {
|
||||
AggregatorSetConfigParamsFields,
|
||||
AggregatorSetConfigParamsJSON,
|
||||
} from './AggregatorSetConfigParams';
|
||||
export { AggregatorSetForceReportPeriodParams } from './AggregatorSetForceReportPeriodParams';
|
||||
export { AggregatorSetConfigParams } from './AggregatorSetConfigParams';
|
||||
export type {
|
||||
AggregatorSetForceReportPeriodParamsFields,
|
||||
AggregatorSetForceReportPeriodParamsJSON,
|
||||
} from './AggregatorSetForceReportPeriodParams';
|
||||
export { AggregatorSetHistoryBufferParams } from './AggregatorSetHistoryBufferParams';
|
||||
export { AggregatorSetForceReportPeriodParams } from './AggregatorSetForceReportPeriodParams';
|
||||
export type {
|
||||
AggregatorSetHistoryBufferParamsFields,
|
||||
AggregatorSetHistoryBufferParamsJSON,
|
||||
} from './AggregatorSetHistoryBufferParams';
|
||||
export { AggregatorSetMinJobsParams } from './AggregatorSetMinJobsParams';
|
||||
export { AggregatorSetHistoryBufferParams } from './AggregatorSetHistoryBufferParams';
|
||||
export type {
|
||||
AggregatorSetMinJobsParamsFields,
|
||||
AggregatorSetMinJobsParamsJSON,
|
||||
} from './AggregatorSetMinJobsParams';
|
||||
export { AggregatorSetMinOraclesParams } from './AggregatorSetMinOraclesParams';
|
||||
export { AggregatorSetMinJobsParams } from './AggregatorSetMinJobsParams';
|
||||
export type {
|
||||
AggregatorSetMinOraclesParamsFields,
|
||||
AggregatorSetMinOraclesParamsJSON,
|
||||
} from './AggregatorSetMinOraclesParams';
|
||||
export { AggregatorSetQueueParams } from './AggregatorSetQueueParams';
|
||||
export { AggregatorSetMinOraclesParams } from './AggregatorSetMinOraclesParams';
|
||||
export type {
|
||||
AggregatorSetQueueParamsFields,
|
||||
AggregatorSetQueueParamsJSON,
|
||||
} from './AggregatorSetQueueParams';
|
||||
export { AggregatorSetResolutionModeParams } from './AggregatorSetResolutionModeParams';
|
||||
export { AggregatorSetQueueParams } from './AggregatorSetQueueParams';
|
||||
export type {
|
||||
AggregatorSetResolutionModeParamsFields,
|
||||
AggregatorSetResolutionModeParamsJSON,
|
||||
} from './AggregatorSetResolutionModeParams';
|
||||
export { AggregatorSetUpdateIntervalParams } from './AggregatorSetUpdateIntervalParams';
|
||||
export { AggregatorSetResolutionModeParams } from './AggregatorSetResolutionModeParams';
|
||||
export type {
|
||||
AggregatorSetUpdateIntervalParamsFields,
|
||||
AggregatorSetUpdateIntervalParamsJSON,
|
||||
} from './AggregatorSetUpdateIntervalParams';
|
||||
export { AggregatorSetVarianceThresholdParams } from './AggregatorSetVarianceThresholdParams';
|
||||
export { AggregatorSetUpdateIntervalParams } from './AggregatorSetUpdateIntervalParams';
|
||||
export type {
|
||||
AggregatorSetVarianceThresholdParamsFields,
|
||||
AggregatorSetVarianceThresholdParamsJSON,
|
||||
} from './AggregatorSetVarianceThresholdParams';
|
||||
export { BorshDecimal } from './BorshDecimal';
|
||||
export { AggregatorSetVarianceThresholdParams } from './AggregatorSetVarianceThresholdParams';
|
||||
export type {
|
||||
AggregatorTeeSaveResultParamsFields,
|
||||
AggregatorTeeSaveResultParamsJSON,
|
||||
} from './AggregatorTeeSaveResultParams';
|
||||
export { AggregatorTeeSaveResultParams } from './AggregatorTeeSaveResultParams';
|
||||
export type { BorshDecimalFields, BorshDecimalJSON } from './BorshDecimal';
|
||||
export { BufferRelayerInitParams } from './BufferRelayerInitParams';
|
||||
export { BorshDecimal } from './BorshDecimal';
|
||||
export type {
|
||||
BufferRelayerInitParamsFields,
|
||||
BufferRelayerInitParamsJSON,
|
||||
} from './BufferRelayerInitParams';
|
||||
export { BufferRelayerOpenRoundParams } from './BufferRelayerOpenRoundParams';
|
||||
export { BufferRelayerInitParams } from './BufferRelayerInitParams';
|
||||
export type {
|
||||
BufferRelayerOpenRoundParamsFields,
|
||||
BufferRelayerOpenRoundParamsJSON,
|
||||
} from './BufferRelayerOpenRoundParams';
|
||||
export { BufferRelayerRound } from './BufferRelayerRound';
|
||||
export { BufferRelayerOpenRoundParams } from './BufferRelayerOpenRoundParams';
|
||||
export type {
|
||||
BufferRelayerRoundFields,
|
||||
BufferRelayerRoundJSON,
|
||||
} from './BufferRelayerRound';
|
||||
export { BufferRelayerSaveResultParams } from './BufferRelayerSaveResultParams';
|
||||
export { BufferRelayerRound } from './BufferRelayerRound';
|
||||
export type {
|
||||
BufferRelayerSaveResultParamsFields,
|
||||
BufferRelayerSaveResultParamsJSON,
|
||||
} from './BufferRelayerSaveResultParams';
|
||||
export { Callback } from './Callback';
|
||||
export { BufferRelayerSaveResultParams } from './BufferRelayerSaveResultParams';
|
||||
export type { CallbackFields, CallbackJSON } from './Callback';
|
||||
export { CallbackZC } from './CallbackZC';
|
||||
export { Callback } from './Callback';
|
||||
export type { CallbackZCFields, CallbackZCJSON } from './CallbackZC';
|
||||
export { CompletedPointZC } from './CompletedPointZC';
|
||||
export { CallbackZC } from './CallbackZC';
|
||||
export type {
|
||||
CompletedPointZCFields,
|
||||
CompletedPointZCJSON,
|
||||
} from './CompletedPointZC';
|
||||
export { CrankInitParams } from './CrankInitParams';
|
||||
export { CompletedPointZC } from './CompletedPointZC';
|
||||
export type {
|
||||
CrankInitParamsFields,
|
||||
CrankInitParamsJSON,
|
||||
} from './CrankInitParams';
|
||||
export { CrankPopParams } from './CrankPopParams';
|
||||
export { CrankInitParams } from './CrankInitParams';
|
||||
export type {
|
||||
CrankPopParamsFields,
|
||||
CrankPopParamsJSON,
|
||||
} from './CrankPopParams';
|
||||
export { CrankPopParamsV2 } from './CrankPopParamsV2';
|
||||
export { CrankPopParams } from './CrankPopParams';
|
||||
export type {
|
||||
CrankPopParamsV2Fields,
|
||||
CrankPopParamsV2JSON,
|
||||
} from './CrankPopParamsV2';
|
||||
export { CrankPushParams } from './CrankPushParams';
|
||||
export { CrankPopParamsV2 } from './CrankPopParamsV2';
|
||||
export type {
|
||||
CrankPushParamsFields,
|
||||
CrankPushParamsJSON,
|
||||
} from './CrankPushParams';
|
||||
export { CrankRow } from './CrankRow';
|
||||
export { CrankPushParams } from './CrankPushParams';
|
||||
export type { CrankRowFields, CrankRowJSON } from './CrankRow';
|
||||
export { EcvrfIntermediate } from './EcvrfIntermediate';
|
||||
export { CrankRow } from './CrankRow';
|
||||
export type {
|
||||
EcvrfIntermediateFields,
|
||||
EcvrfIntermediateJSON,
|
||||
} from './EcvrfIntermediate';
|
||||
export { EcvrfProofZC } from './EcvrfProofZC';
|
||||
export { EcvrfIntermediate } from './EcvrfIntermediate';
|
||||
export type { EcvrfProofZCFields, EcvrfProofZCJSON } from './EcvrfProofZC';
|
||||
export { EdwardsPointZC } from './EdwardsPointZC';
|
||||
export { EcvrfProofZC } from './EcvrfProofZC';
|
||||
export type {
|
||||
EdwardsPointZCFields,
|
||||
EdwardsPointZCJSON,
|
||||
} from './EdwardsPointZC';
|
||||
export { FieldElementZC } from './FieldElementZC';
|
||||
export { EdwardsPointZC } from './EdwardsPointZC';
|
||||
export type {
|
||||
FieldElementZCFields,
|
||||
FieldElementZCJSON,
|
||||
} from './FieldElementZC';
|
||||
export { Hash } from './Hash';
|
||||
export { FieldElementZC } from './FieldElementZC';
|
||||
export type { HashFields, HashJSON } from './Hash';
|
||||
export { JobInitParams } from './JobInitParams';
|
||||
export { Hash } from './Hash';
|
||||
export type { JobInitParamsFields, JobInitParamsJSON } from './JobInitParams';
|
||||
export { JobSetDataParams } from './JobSetDataParams';
|
||||
export { JobInitParams } from './JobInitParams';
|
||||
export type {
|
||||
JobSetDataParamsFields,
|
||||
JobSetDataParamsJSON,
|
||||
} from './JobSetDataParams';
|
||||
export { LeaseExtendParams } from './LeaseExtendParams';
|
||||
export { JobSetDataParams } from './JobSetDataParams';
|
||||
export type {
|
||||
LeaseExtendParamsFields,
|
||||
LeaseExtendParamsJSON,
|
||||
} from './LeaseExtendParams';
|
||||
export { LeaseInitParams } from './LeaseInitParams';
|
||||
export { LeaseExtendParams } from './LeaseExtendParams';
|
||||
export type {
|
||||
LeaseInitParamsFields,
|
||||
LeaseInitParamsJSON,
|
||||
} from './LeaseInitParams';
|
||||
export { LeaseSetAuthorityParams } from './LeaseSetAuthorityParams';
|
||||
export { LeaseInitParams } from './LeaseInitParams';
|
||||
export type {
|
||||
LeaseSetAuthorityParamsFields,
|
||||
LeaseSetAuthorityParamsJSON,
|
||||
} from './LeaseSetAuthorityParams';
|
||||
export { LeaseWithdrawParams } from './LeaseWithdrawParams';
|
||||
export { LeaseSetAuthorityParams } from './LeaseSetAuthorityParams';
|
||||
export type {
|
||||
LeaseWithdrawParamsFields,
|
||||
LeaseWithdrawParamsJSON,
|
||||
} from './LeaseWithdrawParams';
|
||||
export { OracleHeartbeatParams } from './OracleHeartbeatParams';
|
||||
export { LeaseWithdrawParams } from './LeaseWithdrawParams';
|
||||
export type {
|
||||
OracleHeartbeatParamsFields,
|
||||
OracleHeartbeatParamsJSON,
|
||||
} from './OracleHeartbeatParams';
|
||||
export { OracleInitParams } from './OracleInitParams';
|
||||
export { OracleHeartbeatParams } from './OracleHeartbeatParams';
|
||||
export type {
|
||||
OracleInitParamsFields,
|
||||
OracleInitParamsJSON,
|
||||
} from './OracleInitParams';
|
||||
export { OracleMetrics } from './OracleMetrics';
|
||||
export { OracleInitParams } from './OracleInitParams';
|
||||
export type { OracleMetricsFields, OracleMetricsJSON } from './OracleMetrics';
|
||||
export { OracleQueueInitParams } from './OracleQueueInitParams';
|
||||
export { OracleMetrics } from './OracleMetrics';
|
||||
export type {
|
||||
OracleQueueInitParamsFields,
|
||||
OracleQueueInitParamsJSON,
|
||||
} from './OracleQueueInitParams';
|
||||
export { OracleQueueSetConfigParams } from './OracleQueueSetConfigParams';
|
||||
export { OracleQueueInitParams } from './OracleQueueInitParams';
|
||||
export type {
|
||||
OracleQueueSetConfigParamsFields,
|
||||
OracleQueueSetConfigParamsJSON,
|
||||
} from './OracleQueueSetConfigParams';
|
||||
export { OracleQueueSetRewardsParams } from './OracleQueueSetRewardsParams';
|
||||
export { OracleQueueSetConfigParams } from './OracleQueueSetConfigParams';
|
||||
export type {
|
||||
OracleQueueSetRewardsParamsFields,
|
||||
OracleQueueSetRewardsParamsJSON,
|
||||
} from './OracleQueueSetRewardsParams';
|
||||
export { OracleWithdrawParams } from './OracleWithdrawParams';
|
||||
export { OracleQueueSetRewardsParams } from './OracleQueueSetRewardsParams';
|
||||
export type {
|
||||
OracleTeeHeartbeatParamsFields,
|
||||
OracleTeeHeartbeatParamsJSON,
|
||||
} from './OracleTeeHeartbeatParams';
|
||||
export { OracleTeeHeartbeatParams } from './OracleTeeHeartbeatParams';
|
||||
export type {
|
||||
OracleWithdrawParamsFields,
|
||||
OracleWithdrawParamsJSON,
|
||||
} from './OracleWithdrawParams';
|
||||
export { PermissionInitParams } from './PermissionInitParams';
|
||||
export { OracleWithdrawParams } from './OracleWithdrawParams';
|
||||
export type {
|
||||
PermissionInitParamsFields,
|
||||
PermissionInitParamsJSON,
|
||||
} from './PermissionInitParams';
|
||||
export { PermissionSetParams } from './PermissionSetParams';
|
||||
export { PermissionInitParams } from './PermissionInitParams';
|
||||
export type {
|
||||
PermissionSetParamsFields,
|
||||
PermissionSetParamsJSON,
|
||||
} from './PermissionSetParams';
|
||||
export { ProgramConfigParams } from './ProgramConfigParams';
|
||||
export { PermissionSetParams } from './PermissionSetParams';
|
||||
export type {
|
||||
ProgramConfigParamsFields,
|
||||
ProgramConfigParamsJSON,
|
||||
} from './ProgramConfigParams';
|
||||
export { ProgramInitParams } from './ProgramInitParams';
|
||||
export { ProgramConfigParams } from './ProgramConfigParams';
|
||||
export type {
|
||||
ProgramInitParamsFields,
|
||||
ProgramInitParamsJSON,
|
||||
} from './ProgramInitParams';
|
||||
export { ProjectivePointZC } from './ProjectivePointZC';
|
||||
export { ProgramInitParams } from './ProgramInitParams';
|
||||
export type {
|
||||
ProjectivePointZCFields,
|
||||
ProjectivePointZCJSON,
|
||||
} from './ProjectivePointZC';
|
||||
export { Scalar } from './Scalar';
|
||||
export { ProjectivePointZC } from './ProjectivePointZC';
|
||||
export type { ScalarFields, ScalarJSON } from './Scalar';
|
||||
export { SetBumpsParams } from './SetBumpsParams';
|
||||
export { Scalar } from './Scalar';
|
||||
export type {
|
||||
SetBumpsParamsFields,
|
||||
SetBumpsParamsJSON,
|
||||
} from './SetBumpsParams';
|
||||
export { SlidingWindowElement } from './SlidingWindowElement';
|
||||
export { SetBumpsParams } from './SetBumpsParams';
|
||||
export type {
|
||||
SlidingWindowElementFields,
|
||||
SlidingWindowElementJSON,
|
||||
} from './SlidingWindowElement';
|
||||
export { SwitchboardDecimal } from './SwitchboardDecimal';
|
||||
export { SlidingWindowElement } from './SlidingWindowElement';
|
||||
export type {
|
||||
SwitchboardDecimalFields,
|
||||
SwitchboardDecimalJSON,
|
||||
} from './SwitchboardDecimal';
|
||||
export {
|
||||
PermitNone,
|
||||
PermitOracleHeartbeat,
|
||||
PermitOracleQueueUsage,
|
||||
PermitVrfRequests,
|
||||
} from './SwitchboardPermission';
|
||||
export { VaultTransferParams } from './VaultTransferParams';
|
||||
export { SwitchboardDecimal } from './SwitchboardDecimal';
|
||||
export type {
|
||||
VaultTransferParamsFields,
|
||||
VaultTransferParamsJSON,
|
||||
} from './VaultTransferParams';
|
||||
export { VrfBuilder } from './VrfBuilder';
|
||||
export { VaultTransferParams } from './VaultTransferParams';
|
||||
export type { VrfBuilderFields, VrfBuilderJSON } from './VrfBuilder';
|
||||
export { VrfCloseParams } from './VrfCloseParams';
|
||||
export { VrfBuilder } from './VrfBuilder';
|
||||
export type {
|
||||
VrfCloseParamsFields,
|
||||
VrfCloseParamsJSON,
|
||||
} from './VrfCloseParams';
|
||||
export { VrfInitParams } from './VrfInitParams';
|
||||
export { VrfCloseParams } from './VrfCloseParams';
|
||||
export type { VrfInitParamsFields, VrfInitParamsJSON } from './VrfInitParams';
|
||||
export { VrfLiteCloseParams } from './VrfLiteCloseParams';
|
||||
export { VrfInitParams } from './VrfInitParams';
|
||||
export type {
|
||||
VrfLiteCloseParamsFields,
|
||||
VrfLiteCloseParamsJSON,
|
||||
} from './VrfLiteCloseParams';
|
||||
export { VrfLiteInitParams } from './VrfLiteInitParams';
|
||||
export { VrfLiteCloseParams } from './VrfLiteCloseParams';
|
||||
export type {
|
||||
VrfLiteInitParamsFields,
|
||||
VrfLiteInitParamsJSON,
|
||||
} from './VrfLiteInitParams';
|
||||
export { VrfLiteProveAndVerifyParams } from './VrfLiteProveAndVerifyParams';
|
||||
export { VrfLiteInitParams } from './VrfLiteInitParams';
|
||||
export type {
|
||||
VrfLiteProveAndVerifyParamsFields,
|
||||
VrfLiteProveAndVerifyParamsJSON,
|
||||
} from './VrfLiteProveAndVerifyParams';
|
||||
export { VrfLiteRequestRandomnessParams } from './VrfLiteRequestRandomnessParams';
|
||||
export { VrfLiteProveAndVerifyParams } from './VrfLiteProveAndVerifyParams';
|
||||
export type {
|
||||
VrfLiteRequestRandomnessParamsFields,
|
||||
VrfLiteRequestRandomnessParamsJSON,
|
||||
} from './VrfLiteRequestRandomnessParams';
|
||||
export { VrfPoolAddParams } from './VrfPoolAddParams';
|
||||
export { VrfLiteRequestRandomnessParams } from './VrfLiteRequestRandomnessParams';
|
||||
export type {
|
||||
VrfPoolAddParamsFields,
|
||||
VrfPoolAddParamsJSON,
|
||||
} from './VrfPoolAddParams';
|
||||
export { VrfPoolInitParams } from './VrfPoolInitParams';
|
||||
export { VrfPoolAddParams } from './VrfPoolAddParams';
|
||||
export type {
|
||||
VrfPoolInitParamsFields,
|
||||
VrfPoolInitParamsJSON,
|
||||
} from './VrfPoolInitParams';
|
||||
export { VrfPoolRemoveParams } from './VrfPoolRemoveParams';
|
||||
export { VrfPoolInitParams } from './VrfPoolInitParams';
|
||||
export type {
|
||||
VrfPoolRemoveParamsFields,
|
||||
VrfPoolRemoveParamsJSON,
|
||||
} from './VrfPoolRemoveParams';
|
||||
export { VrfPoolRequestParams } from './VrfPoolRequestParams';
|
||||
export { VrfPoolRemoveParams } from './VrfPoolRemoveParams';
|
||||
export type {
|
||||
VrfPoolRequestParamsFields,
|
||||
VrfPoolRequestParamsJSON,
|
||||
} from './VrfPoolRequestParams';
|
||||
export { VrfPoolRow } from './VrfPoolRow';
|
||||
export { VrfPoolRequestParams } from './VrfPoolRequestParams';
|
||||
export type { VrfPoolRowFields, VrfPoolRowJSON } from './VrfPoolRow';
|
||||
export { VrfProveAndVerifyParams } from './VrfProveAndVerifyParams';
|
||||
export { VrfPoolRow } from './VrfPoolRow';
|
||||
export type {
|
||||
VrfProveAndVerifyParamsFields,
|
||||
VrfProveAndVerifyParamsJSON,
|
||||
} from './VrfProveAndVerifyParams';
|
||||
export { VrfProveParams } from './VrfProveParams';
|
||||
export { VrfProveAndVerifyParams } from './VrfProveAndVerifyParams';
|
||||
export type {
|
||||
VrfProveParamsFields,
|
||||
VrfProveParamsJSON,
|
||||
} from './VrfProveParams';
|
||||
export { VrfRequestRandomnessParams } from './VrfRequestRandomnessParams';
|
||||
export { VrfProveParams } from './VrfProveParams';
|
||||
export type {
|
||||
VrfRequestRandomnessParamsFields,
|
||||
VrfRequestRandomnessParamsJSON,
|
||||
} from './VrfRequestRandomnessParams';
|
||||
export { VrfRound } from './VrfRound';
|
||||
export { VrfRequestRandomnessParams } from './VrfRequestRandomnessParams';
|
||||
export type { VrfRoundFields, VrfRoundJSON } from './VrfRound';
|
||||
export { VrfSetCallbackParams } from './VrfSetCallbackParams';
|
||||
export { VrfRound } from './VrfRound';
|
||||
export type {
|
||||
VrfSetCallbackParamsFields,
|
||||
VrfSetCallbackParamsJSON,
|
||||
} from './VrfSetCallbackParams';
|
||||
export { Lanes };
|
||||
export { Shuffle };
|
||||
export { Error };
|
||||
export { AggregatorResolutionMode };
|
||||
export { SwitchboardPermission };
|
||||
export { OracleResponseType };
|
||||
export { VrfStatus };
|
||||
export { VrfSetCallbackParams } from './VrfSetCallbackParams';
|
||||
|
||||
/**
|
||||
* The `Lanes` enum represents a subset of the lanes `A,B,C,D` of a
|
||||
* `FieldElement2625x4`.
|
||||
*
|
||||
* It's used to specify blend operations without
|
||||
* having to know details about the data layout of the
|
||||
* `FieldElement2625x4`.
|
||||
*/
|
||||
export type LanesKind = Lanes.C | Lanes.D | Lanes.AB | Lanes.AC | Lanes.AD;
|
||||
export type LanesJSON =
|
||||
| Lanes.CJSON
|
||||
| Lanes.DJSON
|
||||
| Lanes.ABJSON
|
||||
| Lanes.ACJSON
|
||||
| Lanes.ADJSON;
|
||||
export { Shuffle };
|
||||
|
||||
/**
|
||||
* The `Shuffle` enum represents a shuffle of a `FieldElement2625x4`.
|
||||
|
@ -429,6 +413,26 @@ export type ShuffleJSON =
|
|||
| Shuffle.BACDJSON
|
||||
| Shuffle.ABDCJSON;
|
||||
|
||||
export { Lanes };
|
||||
|
||||
/**
|
||||
* The `Lanes` enum represents a subset of the lanes `A,B,C,D` of a
|
||||
* `FieldElement2625x4`.
|
||||
*
|
||||
* It's used to specify blend operations without
|
||||
* having to know details about the data layout of the
|
||||
* `FieldElement2625x4`.
|
||||
*/
|
||||
export type LanesKind = Lanes.C | Lanes.D | Lanes.AB | Lanes.AC | Lanes.AD;
|
||||
export type LanesJSON =
|
||||
| Lanes.CJSON
|
||||
| Lanes.DJSON
|
||||
| Lanes.ABJSON
|
||||
| Lanes.ACJSON
|
||||
| Lanes.ADJSON;
|
||||
|
||||
export { Error };
|
||||
|
||||
export type ErrorKind =
|
||||
| Error.InvalidPublicKey
|
||||
| Error.SerializationError
|
||||
|
@ -440,6 +444,21 @@ export type ErrorJSON =
|
|||
| Error.DeserializationErrorJSON
|
||||
| Error.InvalidDataErrorJSON;
|
||||
|
||||
export { VerificationStatus };
|
||||
|
||||
export type VerificationStatusKind =
|
||||
| VerificationStatus.VerificationPending
|
||||
| VerificationStatus.VerificationFailure
|
||||
| VerificationStatus.VerificationSuccess
|
||||
| VerificationStatus.VerificationOverride;
|
||||
export type VerificationStatusJSON =
|
||||
| VerificationStatus.VerificationPendingJSON
|
||||
| VerificationStatus.VerificationFailureJSON
|
||||
| VerificationStatus.VerificationSuccessJSON
|
||||
| VerificationStatus.VerificationOverrideJSON;
|
||||
|
||||
export { AggregatorResolutionMode };
|
||||
|
||||
export type AggregatorResolutionModeKind =
|
||||
| AggregatorResolutionMode.ModeRoundResolution
|
||||
| AggregatorResolutionMode.ModeSlidingResolution;
|
||||
|
@ -447,6 +466,8 @@ export type AggregatorResolutionModeJSON =
|
|||
| AggregatorResolutionMode.ModeRoundResolutionJSON
|
||||
| AggregatorResolutionMode.ModeSlidingResolutionJSON;
|
||||
|
||||
export { SwitchboardPermission };
|
||||
|
||||
export type SwitchboardPermissionKind =
|
||||
| SwitchboardPermission.PermitNone
|
||||
| SwitchboardPermission.PermitOracleHeartbeat
|
||||
|
@ -458,6 +479,8 @@ export type SwitchboardPermissionJSON =
|
|||
| SwitchboardPermission.PermitOracleQueueUsageJSON
|
||||
| SwitchboardPermission.PermitVrfRequestsJSON;
|
||||
|
||||
export { OracleResponseType };
|
||||
|
||||
export type OracleResponseTypeKind =
|
||||
| OracleResponseType.TypeSuccess
|
||||
| OracleResponseType.TypeError
|
||||
|
@ -469,6 +492,8 @@ export type OracleResponseTypeJSON =
|
|||
| OracleResponseType.TypeDisagreementJSON
|
||||
| OracleResponseType.TypeNoResponseJSON;
|
||||
|
||||
export { VrfStatus };
|
||||
|
||||
export type VrfStatusKind =
|
||||
| VrfStatus.StatusNone
|
||||
| VrfStatus.StatusRequesting
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -445,6 +445,109 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "aggregatorTeeSaveResult",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "aggregator",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracleAuthority",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "oracleQueue",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "queueAuthority",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "feedPermission",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oraclePermission",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "lease",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "escrow",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "tokenProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "programState",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "historyBuffer",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "mint",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "slider",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "quote",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "rewardWallet",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "payer",
|
||||
"isMut": true,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "systemProgram",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "params",
|
||||
"type": {
|
||||
"defined": "AggregatorTeeSaveResultParams"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "aggregatorSetAuthority",
|
||||
"accounts": [
|
||||
|
@ -1307,6 +1410,64 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "oracleTeeHeartbeat",
|
||||
"accounts": [
|
||||
{
|
||||
"name": "oracle",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracleAuthority",
|
||||
"isMut": false,
|
||||
"isSigner": true
|
||||
},
|
||||
{
|
||||
"name": "tokenAccount",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "gcOracle",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "oracleQueue",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "permission",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "dataBuffer",
|
||||
"isMut": true,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "quote",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
},
|
||||
{
|
||||
"name": "programState",
|
||||
"isMut": false,
|
||||
"isSigner": false
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
{
|
||||
"name": "params",
|
||||
"type": {
|
||||
"defined": "OracleTeeHeartbeatParams"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "oracleInit",
|
||||
"accounts": [
|
||||
|
@ -2390,6 +2551,97 @@
|
|||
}
|
||||
],
|
||||
"accounts": [
|
||||
{
|
||||
"name": "QuoteAccountData",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "delegatedSecuredSigner",
|
||||
"type": "publicKey"
|
||||
},
|
||||
{
|
||||
"name": "bump",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "quoteRegistry",
|
||||
"docs": [
|
||||
"TODO: Add description"
|
||||
],
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "registryKey",
|
||||
"docs": [
|
||||
"Key to lookup the buffer data on IPFS or an alternative decentralized storage solution."
|
||||
],
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
64
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "attestationQueue",
|
||||
"docs": [
|
||||
"Queue used for attestation to verify a MRENCLAVE measurement."
|
||||
],
|
||||
"type": "publicKey"
|
||||
},
|
||||
{
|
||||
"name": "mrEnclave",
|
||||
"docs": [
|
||||
"The quotes MRENCLAVE measurement dictating the contents of the secure enclave."
|
||||
],
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "verificationStatus",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "verificationTimestamp",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "validUntil",
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "isOnQueue",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "lastHeartbeat",
|
||||
"docs": [
|
||||
"The last time the quote heartbeated."
|
||||
],
|
||||
"type": "i64"
|
||||
},
|
||||
{
|
||||
"name": "ebuf",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
1024
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "SbState",
|
||||
"type": {
|
||||
|
@ -2430,6 +2682,23 @@
|
|||
],
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "mrEnclaves",
|
||||
"docs": [
|
||||
"Permitted enclave measurements"
|
||||
],
|
||||
"type": {
|
||||
"array": [
|
||||
{
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
},
|
||||
6
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "ebuf",
|
||||
"docs": [
|
||||
|
@ -2438,7 +2707,7 @@
|
|||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
991
|
||||
799
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -3119,6 +3388,10 @@
|
|||
],
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "enableTeeOnly",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "ebuf",
|
||||
"docs": [
|
||||
|
@ -3127,7 +3400,7 @@
|
|||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
968
|
||||
967
|
||||
]
|
||||
}
|
||||
},
|
||||
|
@ -4292,6 +4565,57 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AggregatorTeeSaveResultParams",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"defined": "BorshDecimal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "jobsChecksum",
|
||||
"type": {
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "minResponse",
|
||||
"type": {
|
||||
"defined": "BorshDecimal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "maxResponse",
|
||||
"type": {
|
||||
"defined": "BorshDecimal"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "feedPermissionBump",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "oraclePermissionBump",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "leaseBump",
|
||||
"type": "u8"
|
||||
},
|
||||
{
|
||||
"name": "stateBump",
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "BufferRelayerInitParams",
|
||||
"type": {
|
||||
|
@ -4712,6 +5036,10 @@
|
|||
{
|
||||
"name": "enableBufferRelayers",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"name": "enableTeeOnly",
|
||||
"type": "bool"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -4804,6 +5132,12 @@
|
|||
"type": {
|
||||
"option": "u64"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "enableTeeOnly",
|
||||
"type": {
|
||||
"option": "bool"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -4820,6 +5154,18 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OracleTeeHeartbeatParams",
|
||||
"type": {
|
||||
"kind": "struct",
|
||||
"fields": [
|
||||
{
|
||||
"name": "permissionBump",
|
||||
"type": "u8"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "OracleWithdrawParams",
|
||||
"type": {
|
||||
|
@ -4881,6 +5227,28 @@
|
|||
{
|
||||
"name": "daoMint",
|
||||
"type": "publicKey"
|
||||
},
|
||||
{
|
||||
"name": "addEnclaves",
|
||||
"type": {
|
||||
"vec": {
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "rmEnclaves",
|
||||
"type": {
|
||||
"vec": {
|
||||
"array": [
|
||||
"u8",
|
||||
32
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -6396,6 +6764,26 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "VerificationStatus",
|
||||
"type": {
|
||||
"kind": "enum",
|
||||
"variants": [
|
||||
{
|
||||
"name": "VerificationPending"
|
||||
},
|
||||
{
|
||||
"name": "VerificationFailure"
|
||||
},
|
||||
{
|
||||
"name": "VerificationSuccess"
|
||||
},
|
||||
{
|
||||
"name": "VerificationOverride"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "AggregatorResolutionMode",
|
||||
"type": {
|
||||
|
@ -6671,6 +7059,38 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AggregatorTeeSaveResultEvent",
|
||||
"fields": [
|
||||
{
|
||||
"name": "feedPubkey",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": {
|
||||
"defined": "BorshDecimal"
|
||||
},
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "slot",
|
||||
"type": "u64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "timestamp",
|
||||
"type": "i64",
|
||||
"index": false
|
||||
},
|
||||
{
|
||||
"name": "oraclePubkey",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "AggregatorValueUpdateEvent",
|
||||
"fields": [
|
||||
|
@ -7224,6 +7644,16 @@
|
|||
"index": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "QuoteVerifyRequestEvent",
|
||||
"fields": [
|
||||
{
|
||||
"name": "quotePubkey",
|
||||
"type": "publicKey",
|
||||
"index": false
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"errors": [
|
||||
|
@ -7726,6 +8156,21 @@
|
|||
"code": 6099,
|
||||
"name": "InsufficientTokenBalance",
|
||||
"msg": "Escrow has insufficient funds to perform this action."
|
||||
},
|
||||
{
|
||||
"code": 6100,
|
||||
"name": "InvalidQuoteError",
|
||||
"msg": "Invalid SAS quote account"
|
||||
},
|
||||
{
|
||||
"code": 6101,
|
||||
"name": "InvalidHistoryAccountError",
|
||||
"msg": ""
|
||||
},
|
||||
{
|
||||
"code": 6102,
|
||||
"name": "GenericError",
|
||||
"msg": ""
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
.anchor
|
||||
.DS_Store
|
||||
target
|
||||
**/*.rs.bk
|
||||
node_modules
|
||||
test-ledger
|
||||
client/
|
|
@ -0,0 +1,38 @@
|
|||
[workspace]
|
||||
members = ["."]
|
||||
|
||||
[provider]
|
||||
# cluster = "devnet"
|
||||
cluster = "localnet"
|
||||
wallet = "~/.config/solana/id.json"
|
||||
|
||||
[programs.localnet]
|
||||
anchor_vrf_lite_parser = "5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb"
|
||||
|
||||
[programs.devnet]
|
||||
anchor_vrf_lite_parser = "5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb"
|
||||
|
||||
[registry]
|
||||
url = "https://anchor.projectserum.com"
|
||||
|
||||
[scripts]
|
||||
test = "yarn run ts-mocha -p ./tsconfig.json -t 60000 ./tests/*.test.ts --exit"
|
||||
"test:devnet" = "USE_SWITCHBOARD_DEVNET_QUEUE=true yarn run ts-mocha -p ./tsconfig.json -t 60000 ./tests/*.test.ts --exit"
|
||||
|
||||
[test.validator]
|
||||
url = "https://api.devnet.solana.com"
|
||||
|
||||
[test]
|
||||
startup_wait = 15000
|
||||
|
||||
[[test.validator.clone]] # sbv2 devnet programID
|
||||
address = "SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f"
|
||||
|
||||
[[test.validator.clone]] # sbv2 devnet IDL
|
||||
address = "Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk"
|
||||
|
||||
[[test.validator.clone]] # sbv2 devnet SbState
|
||||
address = "CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd"
|
||||
|
||||
[[test.validator.clone]] # sbv2 devnet tokenVault
|
||||
address = "7hkp1xfPBcD2t1vZMoWWQPzipHVcXeLAAaiGXdPSfDie"
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "anchor-vrf-lite-parser"
|
||||
version = "0.1.0"
|
||||
description = "Created with Anchor"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "lib"]
|
||||
name = "anchor_vrf_lite_parser"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
no-entrypoint = []
|
||||
no-idl = []
|
||||
no-log-ix-name = []
|
||||
cpi = ["no-entrypoint"]
|
||||
|
||||
[dependencies]
|
||||
switchboard-v2 = { path = "../../rust/switchboard-v2" }
|
||||
# switchboard-v2 = { version = "^0.1.23" }
|
||||
anchor-lang = "^0.27.0"
|
||||
anchor-spl = "^0.27.0"
|
||||
solana-program = "~1.14.0"
|
||||
bytemuck = "1.7.2"
|
|
@ -0,0 +1,38 @@
|
|||
<div align="center">
|
||||
|
||||
![Switchboard Logo](https://github.com/switchboard-xyz/sbv2-core/raw/main/website/static/img/icons/switchboard/avatar.png)
|
||||
|
||||
# anchor-vrf-parser
|
||||
|
||||
> An example program written in Anchor demonstrating how to deserialize and read
|
||||
> a Switchboard VRF account on Solana.
|
||||
|
||||
[![Anchor Test Status](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml/badge.svg)](https://github.com/switchboard-xyz/sbv2-solana/actions/workflows/anchor-test.yml)
|
||||
|
||||
</div>
|
||||
|
||||
<!-- install -->
|
||||
|
||||
<!-- installstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
Build the example program
|
||||
|
||||
```bash
|
||||
anchor build
|
||||
```
|
||||
|
||||
Get your program ID and update `Anchor.toml` and `src/lib.rs` with your pubkey
|
||||
|
||||
```bash
|
||||
export ANCHOR_VRF_PARSER_PUBKEY=$(solana-keygen pubkey target/deploy/anchor_vrf_parser-keypair.json)
|
||||
sed -i '' s/4wTeTACfwiXqqvy44bNBB3V2rFjmSTXVoEr4ZAYamJEN/"$ANCHOR_VRF_PARSER_PUBKEY"/g Anchor.toml
|
||||
sed -i '' s/4wTeTACfwiXqqvy44bNBB3V2rFjmSTXVoEr4ZAYamJEN/"$ANCHOR_VRF_PARSER_PUBKEY"/g src/lib.rs
|
||||
```
|
||||
|
||||
Then run Anchor test
|
||||
|
||||
```bash
|
||||
anchor test
|
||||
```
|
|
@ -0,0 +1,2 @@
|
|||
[target.bpfel-unknown-unknown.dependencies.std]
|
||||
features = []
|
|
@ -0,0 +1,46 @@
|
|||
{
|
||||
"name": "anchor-vrf-lite-parser",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/switchboard-xyz/sbv2-solana",
|
||||
"directory": "programs/anchor-vrf-lite-parser"
|
||||
},
|
||||
"scripts": {
|
||||
"lint": "eslint --ext .js,.json,.ts 'src/**' --fix",
|
||||
"build": "node ../build.js anchor-vrf-parser 5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb",
|
||||
"test": "npm run localnet && npm run network:create && npm run network:start & sleep 60 && anchor test --skip-local-validator",
|
||||
"test:dev": "npm run localnet && npm run network:create && npm run network:start:dev & sleep 15 && anchor test --skip-local-validator"
|
||||
},
|
||||
"dependencies": {
|
||||
"@coral-xyz/anchor": "^0.27.0",
|
||||
"@coral-xyz/borsh": "^0.27.0",
|
||||
"@project-serum/borsh": "^0.2.5",
|
||||
"@solana/spl-token": "^0.3.6",
|
||||
"@solana/web3.js": "^1.73.3",
|
||||
"@switchboard-xyz/common": "^2.2.0",
|
||||
"@switchboard-xyz/oracle": "^2.1.13",
|
||||
"@switchboard-xyz/solana.js": "workspace:*",
|
||||
"chalk": "^4.1.2",
|
||||
"dotenv": "^16.0.1",
|
||||
"yargs": "^17.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/chai": "^4.3.0",
|
||||
"@types/mocha": "^9.0.0",
|
||||
"@types/node": "^17.0.45",
|
||||
"@typescript-eslint/eslint-plugin": "^5.44.0",
|
||||
"@typescript-eslint/parser": "^5.44.0",
|
||||
"chai": "^4.3.6",
|
||||
"eslint": "^8.28.0",
|
||||
"mocha": "^9.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^2.4.1",
|
||||
"prettier-plugin-organize-imports": "^2.3.4",
|
||||
"shx": "^0.3.4",
|
||||
"ts-mocha": "^9.0.2",
|
||||
"ts-node": "^10.9.1",
|
||||
"typescript": "^4.9.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
use crate::*;
|
||||
use anchor_lang::prelude::*;
|
||||
use anchor_lang::solana_program::clock;
|
||||
use anchor_spl::token::Token;
|
||||
pub use switchboard_v2::{VrfLiteAccountData, VrfLiteClose, VrfCloseParams, PERMISSION_SEED};
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(params: CloseStateParams)]
|
||||
pub struct CloseState<'info> {
|
||||
#[account(
|
||||
mut,
|
||||
close = sol_dest,
|
||||
seeds = [
|
||||
STATE_SEED,
|
||||
vrf.key().as_ref(),
|
||||
authority.key().as_ref(),
|
||||
],
|
||||
bump = state.load()?.bump,
|
||||
has_one = vrf
|
||||
)]
|
||||
pub state: AccountLoader<'info, VrfClient>,
|
||||
/// CHECK:
|
||||
#[account(signer)]
|
||||
pub authority: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
#[account(mut, signer)]
|
||||
pub payer: AccountInfo<'info>,
|
||||
#[account(mut)]
|
||||
pub vrf: AccountLoader<'info, VrfLiteAccountData>,
|
||||
#[account(
|
||||
mut,
|
||||
constraint = escrow.mint == escrow_dest.mint && escrow.owner == program_state.key()
|
||||
)]
|
||||
pub escrow: Account<'info, TokenAccount>,
|
||||
|
||||
/// SWITCHBOARD ACCOUNTS
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [
|
||||
PERMISSION_SEED,
|
||||
queue_authority.key().as_ref(),
|
||||
oracle_queue.key().as_ref(),
|
||||
vrf.key().as_ref()
|
||||
],
|
||||
bump = state.load()?.permission_bump,
|
||||
seeds::program = switchboard_program.key()
|
||||
)]
|
||||
pub permission: AccountLoader<'info, PermissionAccountData>,
|
||||
#[account(
|
||||
constraint = oracle_queue.load()?.authority == queue_authority.key()
|
||||
)]
|
||||
pub oracle_queue: AccountLoader<'info, OracleQueueAccountData>,
|
||||
/// CHECK:
|
||||
pub queue_authority: AccountInfo<'info>,
|
||||
#[account(
|
||||
seeds = [STATE_SEED],
|
||||
bump = state.load()?.switchboard_state_bump,
|
||||
seeds::program = switchboard_program.key()
|
||||
)]
|
||||
pub program_state: AccountLoader<'info, SbState>,
|
||||
|
||||
/// CHECK:
|
||||
pub sol_dest: SystemAccount<'info>,
|
||||
/// CHECK:
|
||||
#[account(mut)]
|
||||
pub escrow_dest: Account<'info, TokenAccount>,
|
||||
|
||||
/// CHECK:
|
||||
#[account(
|
||||
constraint =
|
||||
switchboard_program.executable == true
|
||||
&& *switchboard_program.key == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub switchboard_program: AccountInfo<'info>,
|
||||
|
||||
/// SYSTEM ACCOUNTS
|
||||
#[account(address = anchor_spl::token::ID)]
|
||||
pub token_program: Program<'info, Token>,
|
||||
}
|
||||
|
||||
#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct CloseStateParams {}
|
||||
|
||||
impl CloseState<'_> {
|
||||
pub fn validate(&self, ctx: &Context<Self>, params: &CloseStateParams) -> Result<()> {
|
||||
msg!("Validate init");
|
||||
|
||||
// TODO: Validate the current user doesnt have an open request
|
||||
|
||||
// 1500 slots, 400ms/slot = about 10min
|
||||
if ctx.accounts.vrf.load()?.request_slot != 0 && ctx.accounts.vrf.load()?.request_slot + 1500 > clock::Clock::get()?.slot {
|
||||
return Err(error!(VrfErrorCode::VrfCloseNotReady));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn actuate(ctx: &Context<Self>, params: &CloseStateParams) -> Result<()> {
|
||||
msg!("Actuate init");
|
||||
let client_state = ctx.accounts.state.load()?;
|
||||
let bump = client_state.bump.clone();
|
||||
let max_result = client_state.max_result;
|
||||
|
||||
let permission_bump = client_state.permission_bump.clone();
|
||||
let switchboard_state_bump = client_state.switchboard_state_bump.clone();
|
||||
drop(client_state);
|
||||
|
||||
// get pda seeds
|
||||
let vrf_key = ctx.accounts.vrf.key();
|
||||
let authority_key = ctx.accounts.authority.key.clone();
|
||||
msg!("bump: {}", bump);
|
||||
msg!("authority: {}", authority_key);
|
||||
msg!("vrf: {}", vrf_key);
|
||||
let state_seeds: &[&[&[u8]]] = &[&[
|
||||
&STATE_SEED,
|
||||
vrf_key.as_ref(),
|
||||
authority_key.as_ref(),
|
||||
&[bump],
|
||||
]];
|
||||
|
||||
let vrf_close = VrfLiteClose {
|
||||
authority: ctx.accounts.state.to_account_info(),
|
||||
vrf_lite: ctx.accounts.vrf.to_account_info(),
|
||||
permission: ctx.accounts.permission.to_account_info(),
|
||||
queue: ctx.accounts.oracle_queue.to_account_info(),
|
||||
queue_authority: ctx.accounts.queue_authority.to_account_info(),
|
||||
program_state: ctx.accounts.program_state.to_account_info(),
|
||||
escrow: ctx.accounts.escrow.clone(),
|
||||
sol_dest: ctx.accounts.sol_dest.to_account_info(),
|
||||
escrow_dest: ctx.accounts.escrow_dest.clone(),
|
||||
token_program: ctx.accounts.token_program.to_account_info(),
|
||||
};
|
||||
|
||||
msg!("closing VRF account");
|
||||
vrf_close.invoke_signed(
|
||||
ctx.accounts.switchboard_program.to_account_info(),
|
||||
state_seeds,
|
||||
)?;
|
||||
msg!("VRF account closed!");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
use crate::*;
|
||||
use anchor_lang::prelude::*;
|
||||
pub use switchboard_v2::VrfLiteAccountData;
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(params: InitStateParams)]
|
||||
pub struct InitState<'info> {
|
||||
#[account(
|
||||
init,
|
||||
seeds = [
|
||||
STATE_SEED,
|
||||
vrf.key().as_ref(),
|
||||
authority.key().as_ref(),
|
||||
],
|
||||
payer = payer,
|
||||
space = 8 + std::mem::size_of::<VrfClient>(),
|
||||
bump,
|
||||
)]
|
||||
pub state: AccountLoader<'info, VrfClient>,
|
||||
/// CHECK:
|
||||
pub authority: AccountInfo<'info>,
|
||||
/// CHECK:
|
||||
#[account(mut, signer)]
|
||||
/// CHECK:
|
||||
pub payer: AccountInfo<'info>,
|
||||
#[account(
|
||||
constraint =
|
||||
*vrf.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub vrf: AccountLoader<'info, VrfLiteAccountData>,
|
||||
#[account(address = solana_program::system_program::ID)]
|
||||
pub system_program: Program<'info, System>,
|
||||
}
|
||||
|
||||
#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct InitStateParams {
|
||||
pub max_result: u64,
|
||||
pub permission_bump: u8,
|
||||
pub switchboard_state_bump: u8,
|
||||
}
|
||||
|
||||
impl InitState<'_> {
|
||||
pub fn validate(&self, _ctx: &Context<Self>, params: &InitStateParams) -> Result<()> {
|
||||
msg!("Validate init");
|
||||
if params.max_result > MAX_RESULT {
|
||||
return Err(error!(VrfErrorCode::MaxResultExceedsMaximum));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn actuate(ctx: &Context<Self>, params: &InitStateParams) -> Result<()> {
|
||||
msg!("Actuate init");
|
||||
|
||||
msg!("Checking VRF Account");
|
||||
let vrf = ctx.accounts.vrf.load()?;
|
||||
// client state needs to be authority in order to sign request randomness instruction
|
||||
if vrf.authority != ctx.accounts.state.key() {
|
||||
return Err(error!(VrfErrorCode::InvalidAuthorityError));
|
||||
}
|
||||
drop(vrf);
|
||||
|
||||
msg!("Setting VrfClient state");
|
||||
let mut state = ctx.accounts.state.load_init()?;
|
||||
*state = VrfClient::default();
|
||||
state.bump = ctx.bumps.get("state").unwrap().clone();
|
||||
state.authority = ctx.accounts.authority.key.clone();
|
||||
state.vrf = ctx.accounts.vrf.key();
|
||||
state.permission_bump = params.permission_bump;
|
||||
state.switchboard_state_bump = params.switchboard_state_bump;
|
||||
|
||||
msg!("Setting VrfClient max_result");
|
||||
if params.max_result == 0 {
|
||||
state.max_result = MAX_RESULT;
|
||||
} else {
|
||||
state.max_result = params.max_result;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
pub mod init_state;
|
||||
pub use init_state::*;
|
||||
|
||||
pub mod update_result;
|
||||
pub use update_result::*;
|
||||
|
||||
pub mod request_result;
|
||||
pub use request_result::*;
|
||||
|
||||
pub mod close_state;
|
||||
pub use close_state::*;
|
|
@ -0,0 +1,161 @@
|
|||
use crate::*;
|
||||
use anchor_lang::prelude::*;
|
||||
use anchor_lang::solana_program::clock;
|
||||
use anchor_spl::token::Token;
|
||||
pub use switchboard_v2::{
|
||||
OracleQueueAccountData, PermissionAccountData, SbState, VrfLiteAccountData, VrfLiteRequestRandomness,
|
||||
VrfSetCallback,
|
||||
};
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(params: RequestResultParams)] // rpc parameters hint
|
||||
pub struct RequestResult<'info> {
|
||||
#[account(
|
||||
mut,
|
||||
seeds = [
|
||||
STATE_SEED,
|
||||
vrf.key().as_ref(),
|
||||
authority.key().as_ref(),
|
||||
],
|
||||
bump = state.load()?.bump,
|
||||
has_one = vrf @ VrfErrorCode::InvalidVrfAccount,
|
||||
has_one = authority @ VrfErrorCode::InvalidAuthorityError
|
||||
)]
|
||||
pub state: AccountLoader<'info, VrfClient>,
|
||||
/// CHECK:
|
||||
#[account(signer)]
|
||||
pub authority: AccountInfo<'info>,
|
||||
|
||||
// SWITCHBOARD ACCOUNTS
|
||||
#[account(mut,
|
||||
has_one = escrow,
|
||||
constraint =
|
||||
*vrf.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub vrf: AccountLoader<'info, VrfLiteAccountData>,
|
||||
/// CHECK
|
||||
#[account(mut,
|
||||
has_one = data_buffer,
|
||||
constraint =
|
||||
oracle_queue.load()?.authority == queue_authority.key()
|
||||
&& *oracle_queue.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub oracle_queue: AccountLoader<'info, OracleQueueAccountData>,
|
||||
/// CHECK: Will be checked in the CPI instruction
|
||||
pub queue_authority: UncheckedAccount<'info>,
|
||||
/// CHECK
|
||||
#[account(mut,
|
||||
constraint =
|
||||
*data_buffer.owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub data_buffer: AccountInfo<'info>,
|
||||
/// CHECK
|
||||
#[account(mut,
|
||||
constraint =
|
||||
*permission.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub permission: AccountLoader<'info, PermissionAccountData>,
|
||||
#[account(mut,
|
||||
constraint =
|
||||
escrow.owner == program_state.key()
|
||||
&& escrow.mint == program_state.load()?.token_mint
|
||||
)]
|
||||
pub escrow: Account<'info, TokenAccount>,
|
||||
/// CHECK: Will be checked in the CPI instruction
|
||||
#[account(mut,
|
||||
constraint =
|
||||
*program_state.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub program_state: AccountLoader<'info, SbState>,
|
||||
/// CHECK:
|
||||
#[account(
|
||||
constraint =
|
||||
switchboard_program.executable == true
|
||||
&& *switchboard_program.key == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub switchboard_program: AccountInfo<'info>,
|
||||
|
||||
// SYSTEM ACCOUNTS
|
||||
/// CHECK:
|
||||
#[account(address = solana_program::sysvar::recent_blockhashes::ID)]
|
||||
pub recent_blockhashes: AccountInfo<'info>,
|
||||
#[account(address = anchor_spl::token::ID)]
|
||||
pub token_program: Program<'info, Token>,
|
||||
}
|
||||
|
||||
#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct RequestResultParams {
|
||||
}
|
||||
|
||||
impl RequestResult<'_> {
|
||||
pub fn validate(&self, _ctx: &Context<Self>, _params: &RequestResultParams) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn actuate(ctx: &Context<Self>, _params: &RequestResultParams) -> Result<()> {
|
||||
let client_state = ctx.accounts.state.load()?;
|
||||
let bump = client_state.bump.clone();
|
||||
let max_result = client_state.max_result;
|
||||
|
||||
let permission_bump = client_state.permission_bump.clone();
|
||||
let switchboard_state_bump = client_state.switchboard_state_bump.clone();
|
||||
drop(client_state);
|
||||
|
||||
// get pda seeds
|
||||
let vrf_key = ctx.accounts.vrf.key();
|
||||
let authority_key = ctx.accounts.authority.key.clone();
|
||||
msg!("bump: {}", bump);
|
||||
msg!("authority: {}", authority_key);
|
||||
msg!("vrf: {}", vrf_key);
|
||||
let state_seeds: &[&[&[u8]]] = &[&[
|
||||
&STATE_SEED,
|
||||
vrf_key.as_ref(),
|
||||
authority_key.as_ref(),
|
||||
&[bump],
|
||||
]];
|
||||
|
||||
// first set callback
|
||||
let vrf_set_callback = VrfSetCallback {
|
||||
authority: ctx.accounts.state.to_account_info(),
|
||||
vrf: ctx.accounts.vrf.to_account_info(),
|
||||
};
|
||||
let callback = UpdateResult::to_callback(
|
||||
&vrf_set_callback.authority,
|
||||
&vrf_set_callback.vrf.key(),
|
||||
&UpdateResultParams {},
|
||||
)?;
|
||||
|
||||
// then request randomness
|
||||
let vrf_request_randomness = VrfLiteRequestRandomness {
|
||||
authority: ctx.accounts.state.to_account_info(),
|
||||
vrf_lite: ctx.accounts.vrf.to_account_info(),
|
||||
queue: ctx.accounts.oracle_queue.to_account_info(),
|
||||
queue_authority: ctx.accounts.queue_authority.to_account_info(),
|
||||
data_buffer: ctx.accounts.data_buffer.to_account_info(),
|
||||
permission: ctx.accounts.permission.to_account_info(),
|
||||
escrow: ctx.accounts.escrow.clone(),
|
||||
recent_blockhashes: ctx.accounts.recent_blockhashes.to_account_info(),
|
||||
program_state: ctx.accounts.program_state.to_account_info(),
|
||||
token_program: ctx.accounts.token_program.to_account_info(),
|
||||
};
|
||||
|
||||
msg!("requesting randomness");
|
||||
vrf_request_randomness.invoke_signed(
|
||||
ctx.accounts.switchboard_program.to_account_info(),
|
||||
Some(callback),
|
||||
state_seeds,
|
||||
)?;
|
||||
|
||||
let mut client_state = ctx.accounts.state.load_mut()?;
|
||||
client_state.result = 0;
|
||||
|
||||
emit!(RequestingRandomness {
|
||||
vrf_client: ctx.accounts.state.key(),
|
||||
max_result: max_result,
|
||||
timestamp: clock::Clock::get().unwrap().unix_timestamp
|
||||
});
|
||||
|
||||
msg!("randomness requested successfully");
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
use crate::*;
|
||||
use anchor_lang::prelude::*;
|
||||
use anchor_lang::solana_program::clock;
|
||||
use anchor_lang::{Discriminator};
|
||||
|
||||
#[derive(Accounts)]
|
||||
#[instruction(params: UpdateResultParams)] // rpc parameters hint
|
||||
pub struct UpdateResult<'info> {
|
||||
#[account(mut,
|
||||
has_one = vrf @ VrfErrorCode::InvalidVrfAccount
|
||||
)]
|
||||
pub state: AccountLoader<'info, VrfClient>,
|
||||
#[account(
|
||||
constraint =
|
||||
*vrf.to_account_info().owner == SWITCHBOARD_PROGRAM_ID @ VrfErrorCode::InvalidSwitchboardAccount
|
||||
)]
|
||||
pub vrf: AccountLoader<'info, VrfLiteAccountData>,
|
||||
}
|
||||
|
||||
#[derive(Clone, AnchorSerialize, AnchorDeserialize)]
|
||||
pub struct UpdateResultParams {}
|
||||
|
||||
impl Discriminator for UpdateResult<'_> {
|
||||
const DISCRIMINATOR: [u8; 8] = [145, 72, 9, 94, 61, 97, 126, 106];
|
||||
}
|
||||
|
||||
impl UpdateResult<'_> {
|
||||
pub fn try_to_vec(params: &UpdateResultParams) -> Result<Vec<u8>> {
|
||||
let ix_data = params.try_to_vec()?;
|
||||
let data: Vec<u8> = UpdateResult::discriminator().into_iter().chain(ix_data.into_iter()).collect();
|
||||
assert_eq!(data.len(), 8 + std::mem::size_of::<UpdateResultParams>());
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn to_callback(
|
||||
client_state: &AccountInfo,
|
||||
vrf: &Pubkey,
|
||||
params: &UpdateResultParams,
|
||||
) -> Result<Callback> {
|
||||
let program_id = client_state.owner.clone();
|
||||
let accounts: Vec<switchboard_v2::AccountMetaBorsh> = vec![
|
||||
switchboard_v2::AccountMetaBorsh {
|
||||
pubkey: client_state.key.clone(),
|
||||
is_signer: false,
|
||||
is_writable: true,
|
||||
},
|
||||
switchboard_v2::AccountMetaBorsh {
|
||||
pubkey: vrf.clone(),
|
||||
is_signer: false,
|
||||
is_writable: false,
|
||||
},
|
||||
];
|
||||
let ix_data = UpdateResult::try_to_vec(params)?;
|
||||
let callback = Callback {
|
||||
program_id,
|
||||
accounts,
|
||||
ix_data
|
||||
};
|
||||
Ok(callback)
|
||||
}
|
||||
|
||||
pub fn validate(&self, _ctx: &Context<Self>, _params: &UpdateResultParams) -> Result<()> {
|
||||
// We should check VRF account passed is equal to the pubkey stored in our client state
|
||||
// But skipping so we can re-use this program instruction for CI testing
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn actuate(ctx: &Context<Self>, _params: &UpdateResultParams) -> Result<()> {
|
||||
let clock = clock::Clock::get().unwrap();
|
||||
|
||||
emit!(VrfClientInvoked {
|
||||
vrf_client: ctx.accounts.state.key(),
|
||||
timestamp: clock.unix_timestamp,
|
||||
});
|
||||
|
||||
let vrf = ctx.accounts.vrf.load()?;
|
||||
let result_buffer = vrf.get_result()?;
|
||||
if result_buffer == [0u8; 32] {
|
||||
msg!("vrf buffer empty");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let state = &mut ctx.accounts.state.load_mut()?;
|
||||
let max_result = state.max_result;
|
||||
if result_buffer == state.result_buffer {
|
||||
msg!("existing result_buffer");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
msg!("Result buffer is {:?}", result_buffer);
|
||||
let value: &[u128] = bytemuck::cast_slice(&result_buffer[..]);
|
||||
msg!("u128 buffer {:?}", value);
|
||||
let result = value[0] % max_result as u128 + 1;
|
||||
msg!("Current VRF Value [1 - {}) = {}!", max_result, result);
|
||||
|
||||
if state.result != result {
|
||||
state.result_buffer = result_buffer;
|
||||
state.result = result;
|
||||
state.last_timestamp = clock.unix_timestamp;
|
||||
|
||||
emit!(VrfClientResultUpdated {
|
||||
vrf_client: ctx.accounts.state.key(),
|
||||
result: state.result,
|
||||
result_buffer: result_buffer,
|
||||
timestamp: clock.unix_timestamp,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
pub mod actions;
|
||||
pub use actions::*;
|
||||
|
||||
pub use anchor_lang::prelude::*;
|
||||
use anchor_spl::token::TokenAccount;
|
||||
|
||||
pub use switchboard_v2::SWITCHBOARD_PROGRAM_ID;
|
||||
|
||||
pub use switchboard_v2::Callback;
|
||||
|
||||
declare_id!("5Hhm5xKDiThfidbpqjJpKmMJEcKmjj5tEUNFpi2DzSvb");
|
||||
|
||||
const MAX_RESULT: u64 = u64::MAX;
|
||||
|
||||
const STATE_SEED: &[u8] = b"STATE";
|
||||
|
||||
#[program]
|
||||
pub mod anchor_vrf_lite_parser {
|
||||
use super::*;
|
||||
|
||||
#[access_control(ctx.accounts.validate(&ctx, ¶ms))]
|
||||
pub fn init_state(ctx: Context<InitState>, params: InitStateParams) -> Result<()> {
|
||||
InitState::actuate(&ctx, ¶ms)
|
||||
}
|
||||
|
||||
#[access_control(ctx.accounts.validate(&ctx, ¶ms))]
|
||||
pub fn update_result(ctx: Context<UpdateResult>, params: UpdateResultParams) -> Result<()> {
|
||||
UpdateResult::actuate(&ctx, ¶ms)
|
||||
}
|
||||
|
||||
#[access_control(ctx.accounts.validate(&ctx, ¶ms))]
|
||||
pub fn request_result(ctx: Context<RequestResult>, params: RequestResultParams) -> Result<()> {
|
||||
RequestResult::actuate(&ctx, ¶ms)
|
||||
}
|
||||
|
||||
#[access_control(ctx.accounts.validate(&ctx, ¶ms))]
|
||||
pub fn close_state(ctx: Context<CloseState>, params: CloseStateParams) -> Result<()> {
|
||||
CloseState::actuate(&ctx, ¶ms)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(packed)]
|
||||
#[account(zero_copy(unsafe))]
|
||||
pub struct VrfClient {
|
||||
pub bump: u8,
|
||||
pub max_result: u64,
|
||||
pub result_buffer: [u8; 32],
|
||||
pub result: u128,
|
||||
pub last_timestamp: i64,
|
||||
pub authority: Pubkey,
|
||||
pub vrf: Pubkey,
|
||||
pub permission_bump: u8,
|
||||
pub switchboard_state_bump: u8,
|
||||
}
|
||||
impl Default for VrfClient {
|
||||
fn default() -> Self {
|
||||
unsafe { std::mem::zeroed() }
|
||||
}
|
||||
}
|
||||
|
||||
#[event]
|
||||
pub struct RequestingRandomness {
|
||||
pub vrf_client: Pubkey,
|
||||
pub max_result: u64,
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
#[event]
|
||||
pub struct VrfClientInvoked {
|
||||
pub vrf_client: Pubkey,
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
#[event]
|
||||
pub struct VrfClientResultUpdated {
|
||||
pub vrf_client: Pubkey,
|
||||
pub result: u128,
|
||||
pub result_buffer: [u8; 32],
|
||||
pub timestamp: i64,
|
||||
}
|
||||
|
||||
#[error_code]
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub enum VrfErrorCode {
|
||||
#[msg("Not a valid Switchboard account")]
|
||||
InvalidSwitchboardAccount,
|
||||
#[msg("The max result must not exceed u64")]
|
||||
MaxResultExceedsMaximum,
|
||||
#[msg("Current round result is empty")]
|
||||
EmptyCurrentRoundResult,
|
||||
#[msg("Invalid authority account provided.")]
|
||||
InvalidAuthorityError,
|
||||
#[msg("Invalid VRF account provided.")]
|
||||
InvalidVrfAccount,
|
||||
#[msg("VRF client is not ready to be closed.")]
|
||||
VrfClientCloseNotReady,
|
||||
#[msg("VRF account is not ready to be closed.")]
|
||||
VrfCloseNotReady,
|
||||
}
|
|
@ -0,0 +1,368 @@
|
|||
import assert from "assert";
|
||||
import "mocha";
|
||||
|
||||
import * as anchor from "@coral-xyz/anchor";
|
||||
import { AnchorProvider } from "@coral-xyz/anchor";
|
||||
import {
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
} from "@solana/web3.js";
|
||||
|
||||
import { TOKEN_PROGRAM_ID } from "@solana/spl-token";
|
||||
import { sleep } from "@switchboard-xyz/common";
|
||||
import {
|
||||
AnchorWallet,
|
||||
Callback,
|
||||
PermissionAccount,
|
||||
QueueAccount,
|
||||
SwitchboardProgram,
|
||||
SwitchboardTestContext,
|
||||
SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_QUEUE,
|
||||
types,
|
||||
} from "@switchboard-xyz/solana.js";
|
||||
|
||||
import { AnchorVrfLiteParser } from "../target/types/anchor_vrf_lite_parser";
|
||||
import { NodeOracle } from "@switchboard-xyz/oracle";
|
||||
|
||||
describe("anchor-vrf-lite-parser test", () => {
|
||||
const provider = AnchorProvider.env();
|
||||
anchor.setProvider(provider);
|
||||
|
||||
const vrfClientProgram: anchor.Program<AnchorVrfLiteParser> =
|
||||
anchor.workspace.AnchorVrfLiteParser;
|
||||
|
||||
const payer = (provider.wallet as AnchorWallet).payer;
|
||||
|
||||
const vrfSecret = anchor.web3.Keypair.generate();
|
||||
console.log(`VRF Account: ${vrfSecret.publicKey}`);
|
||||
|
||||
const [vrfClientKey, vrfClientBump] = PublicKey.findProgramAddressSync(
|
||||
[
|
||||
Buffer.from("STATE"),
|
||||
vrfSecret.publicKey.toBytes(),
|
||||
payer.publicKey.toBytes(),
|
||||
],
|
||||
vrfClientProgram.programId
|
||||
);
|
||||
|
||||
const vrfIxCoder = new anchor.BorshInstructionCoder(vrfClientProgram.idl);
|
||||
const vrfClientCallback: Callback = {
|
||||
programId: vrfClientProgram.programId,
|
||||
accounts: [
|
||||
// ensure all accounts in updateResult are populated
|
||||
{ pubkey: vrfClientKey, isSigner: false, isWritable: true },
|
||||
{ pubkey: vrfSecret.publicKey, isSigner: false, isWritable: false },
|
||||
],
|
||||
ixData: vrfIxCoder.encode("updateResult", ""), // pass any params for instruction here
|
||||
};
|
||||
|
||||
let switchboard: SwitchboardTestContext;
|
||||
let oracle: NodeOracle;
|
||||
|
||||
let queueAccount: QueueAccount;
|
||||
let queue: types.OracleQueueAccountData;
|
||||
|
||||
before(async () => {
|
||||
if (process.env.USE_SWITCHBOARD_DEVNET_QUEUE) {
|
||||
const switchboardProgram = await SwitchboardProgram.fromProvider(
|
||||
vrfClientProgram.provider as anchor.AnchorProvider
|
||||
);
|
||||
[queueAccount, queue] = await QueueAccount.load(
|
||||
switchboardProgram,
|
||||
SWITCHBOARD_LABS_DEVNET_PERMISSIONLESS_QUEUE
|
||||
);
|
||||
} else {
|
||||
switchboard = await SwitchboardTestContext.loadFromProvider(provider, {
|
||||
// You can provide a keypair to so the PDA schemes dont change between test runs
|
||||
name: "Test Queue",
|
||||
keypair: SwitchboardTestContext.loadKeypair("~/.keypairs/queue.json"),
|
||||
queueSize: 10,
|
||||
reward: 0,
|
||||
minStake: 0,
|
||||
oracleTimeout: 900,
|
||||
unpermissionedFeeds: true,
|
||||
unpermissionedVrf: true,
|
||||
enableBufferRelayers: true,
|
||||
oracle: {
|
||||
name: "Test Oracle",
|
||||
enable: true,
|
||||
stakingWalletKeypair: SwitchboardTestContext.loadKeypair(
|
||||
"~/.keypairs/oracleWallet.json"
|
||||
),
|
||||
},
|
||||
});
|
||||
queueAccount = switchboard.queue;
|
||||
queue = await queueAccount.loadData();
|
||||
|
||||
oracle = await NodeOracle.fromReleaseChannel({
|
||||
chain: "solana",
|
||||
releaseChannel: "testnet",
|
||||
network: "localnet", // disables production capabilities like monitoring and alerts
|
||||
rpcUrl: switchboard.program.connection.rpcEndpoint,
|
||||
oracleKey: switchboard.oracle.publicKey.toBase58(),
|
||||
secretPath: switchboard.walletPath,
|
||||
silent: false, // set to true to suppress oracle logs in the console
|
||||
envVariables: {
|
||||
VERBOSE: "1",
|
||||
DEBUG: "1",
|
||||
DISABLE_NONCE_QUEUE: "1",
|
||||
DISABLE_METRICS: "1",
|
||||
},
|
||||
});
|
||||
|
||||
await oracle.startAndAwait();
|
||||
}
|
||||
});
|
||||
|
||||
after(() => {
|
||||
oracle?.stop();
|
||||
});
|
||||
|
||||
it("Creates a vrfClient account", async () => {
|
||||
const { unpermissionedVrfEnabled, authority, dataBuffer } = queue;
|
||||
|
||||
console.log("creating vrfLite");
|
||||
|
||||
// Create Switchboard VRF and Permission account
|
||||
const [vrfAccount] = await queueAccount.createVrfLite({
|
||||
callback: vrfClientCallback,
|
||||
authority: vrfClientKey, // vrf authority
|
||||
keypair: vrfSecret,
|
||||
enable: false,
|
||||
});
|
||||
|
||||
console.log(`Created VRF Account: ${vrfAccount.publicKey}`);
|
||||
|
||||
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
|
||||
queueAccount.program,
|
||||
authority,
|
||||
queueAccount.publicKey,
|
||||
vrfAccount.publicKey
|
||||
);
|
||||
|
||||
console.log(`Created Permission Account: ${permissionAccount.publicKey}`);
|
||||
|
||||
// If queue requires permissions to use VRF, check the correct authority was provided
|
||||
if (!unpermissionedVrfEnabled) {
|
||||
if (!payer.publicKey.equals(authority)) {
|
||||
throw new Error(
|
||||
`queue requires PERMIT_VRF_REQUESTS and wrong queue authority provided`
|
||||
);
|
||||
}
|
||||
|
||||
await permissionAccount.set({
|
||||
queueAuthority: payer,
|
||||
permission: new types.SwitchboardPermission.PermitVrfRequests(),
|
||||
enable: true,
|
||||
});
|
||||
console.log(`Set VRF Permissions`);
|
||||
}
|
||||
|
||||
// Create VRF Client account
|
||||
await vrfClientProgram.methods
|
||||
.initState({
|
||||
maxResult: new anchor.BN(1337000),
|
||||
permissionBump: permissionBump,
|
||||
switchboardStateBump: queueAccount.program.programState.bump,
|
||||
})
|
||||
.accounts({
|
||||
state: vrfClientKey,
|
||||
vrf: vrfAccount.publicKey,
|
||||
payer: payer.publicKey,
|
||||
authority: payer.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
})
|
||||
.rpc();
|
||||
console.log(`Created VrfClient Account: ${vrfClientKey}`);
|
||||
|
||||
const [payerTokenWallet] =
|
||||
await queueAccount.program.mint.getOrCreateWrappedUser(
|
||||
queueAccount.program.walletPubkey,
|
||||
{ fundUpTo: 0.002 }
|
||||
);
|
||||
|
||||
const vrf = await vrfAccount.loadData();
|
||||
|
||||
// give account time to propagate to oracle RPCs
|
||||
await sleep(2000);
|
||||
|
||||
try {
|
||||
// Request randomness
|
||||
await vrfClientProgram.methods.requestResult!({})
|
||||
.accounts({
|
||||
state: vrfClientKey,
|
||||
authority: payer.publicKey,
|
||||
switchboardProgram: queueAccount.program.programId,
|
||||
vrf: vrfAccount.publicKey,
|
||||
oracleQueue: queueAccount.publicKey,
|
||||
queueAuthority: authority,
|
||||
dataBuffer,
|
||||
permission: permissionAccount.publicKey,
|
||||
escrow: vrf.escrow,
|
||||
recentBlockhashes: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
programState: queueAccount.program.programState.publicKey,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
})
|
||||
.rpc();
|
||||
|
||||
const result = await vrfAccount.nextResult(
|
||||
new anchor.BN(vrf.counter.toNumber() + 1),
|
||||
45_000
|
||||
);
|
||||
if (!result.success) {
|
||||
throw new Error(`Failed to get VRF Result: ${result.status}`);
|
||||
}
|
||||
|
||||
const vrfClient = await vrfClientProgram.account.vrfClient.fetch(
|
||||
vrfClientKey
|
||||
);
|
||||
|
||||
console.log(`VrfClient Result: ${vrfClient.result}`);
|
||||
} catch (error) {
|
||||
const callbackTxn = await vrfAccount.getCallbackTransactions();
|
||||
if (callbackTxn.length && callbackTxn[0].meta?.logMessages?.length) {
|
||||
console.log(
|
||||
JSON.stringify(callbackTxn[0].meta.logMessages, undefined, 2)
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
it("Creates and closes a vrfClient account", async () => {
|
||||
// we create a new client & VRF because a VRF must wait at least 1500 slots
|
||||
// after a request before it can be closed
|
||||
const newVrfSecret = anchor.web3.Keypair.generate();
|
||||
|
||||
const [newVrfClientKey, newVrfClientBump] =
|
||||
PublicKey.findProgramAddressSync(
|
||||
[
|
||||
Buffer.from("STATE"),
|
||||
newVrfSecret.publicKey.toBytes(),
|
||||
payer.publicKey.toBytes(),
|
||||
],
|
||||
vrfClientProgram.programId
|
||||
);
|
||||
|
||||
const vrfIxCoder = new anchor.BorshInstructionCoder(vrfClientProgram.idl);
|
||||
const vrfClientCallback: Callback = {
|
||||
programId: vrfClientProgram.programId,
|
||||
accounts: [
|
||||
// ensure all accounts in updateResult are populated
|
||||
{ pubkey: newVrfClientKey, isSigner: false, isWritable: true },
|
||||
{ pubkey: newVrfSecret.publicKey, isSigner: false, isWritable: false },
|
||||
],
|
||||
ixData: vrfIxCoder.encode("updateResult", ""), // pass any params for instruction here
|
||||
};
|
||||
|
||||
const { unpermissionedVrfEnabled, authority, dataBuffer } = queue;
|
||||
|
||||
// Create Switchboard VRF and Permission account
|
||||
const [newVrfAccount] = await queueAccount.createVrf({
|
||||
callback: vrfClientCallback,
|
||||
authority: newVrfClientKey, // vrf authority
|
||||
vrfKeypair: newVrfSecret,
|
||||
enable: false,
|
||||
});
|
||||
|
||||
console.log(`Created New VRF Account: ${newVrfAccount.publicKey}`);
|
||||
|
||||
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
|
||||
queueAccount.program,
|
||||
authority,
|
||||
queueAccount.publicKey,
|
||||
newVrfAccount.publicKey
|
||||
);
|
||||
|
||||
console.log(
|
||||
`Created New Permission Account: ${permissionAccount.publicKey}`
|
||||
);
|
||||
|
||||
// If queue requires permissions to use VRF, check the correct authority was provided
|
||||
if (!unpermissionedVrfEnabled) {
|
||||
if (!payer.publicKey.equals(authority)) {
|
||||
throw new Error(
|
||||
`queue requires PERMIT_VRF_REQUESTS and wrong queue authority provided`
|
||||
);
|
||||
}
|
||||
|
||||
await permissionAccount.set({
|
||||
queueAuthority: payer,
|
||||
permission: new types.SwitchboardPermission.PermitVrfRequests(),
|
||||
enable: true,
|
||||
});
|
||||
console.log(`Set New VRF Permissions`);
|
||||
}
|
||||
|
||||
// Create VRF Client account
|
||||
await vrfClientProgram.methods
|
||||
.initState({
|
||||
maxResult: new anchor.BN(1337000),
|
||||
permissionBump: permissionBump,
|
||||
switchboardStateBump: queueAccount.program.programState.bump,
|
||||
})
|
||||
.accounts({
|
||||
state: newVrfClientKey,
|
||||
vrf: newVrfAccount.publicKey,
|
||||
payer: payer.publicKey,
|
||||
authority: payer.publicKey,
|
||||
systemProgram: SystemProgram.programId,
|
||||
})
|
||||
.rpc();
|
||||
console.log(`Created New VrfClient Account: ${newVrfClientKey}`);
|
||||
|
||||
await sleep(5000);
|
||||
|
||||
const newVrfClientState = await vrfClientProgram.account.vrfClient.fetch(
|
||||
newVrfClientKey
|
||||
);
|
||||
assert(
|
||||
newVrfClientState.vrf.equals(newVrfAccount.publicKey),
|
||||
`Vrf Client VRF account mismatch, expected ${newVrfAccount.publicKey}, received ${newVrfClientState.vrf}`
|
||||
);
|
||||
|
||||
const newVrfInitialState = await newVrfAccount.loadData();
|
||||
|
||||
// send any wrapped SOL to the payers associated wSOL wallet
|
||||
const [payerTokenAccount] =
|
||||
await queueAccount.program.mint.getOrCreateWrappedUser(payer.publicKey, {
|
||||
fundUpTo: 0,
|
||||
});
|
||||
|
||||
// close the client and VRF account
|
||||
await vrfClientProgram.methods
|
||||
.closeState({})
|
||||
.accounts({
|
||||
state: newVrfClientKey,
|
||||
authority: payer.publicKey,
|
||||
payer: payer.publicKey,
|
||||
vrf: newVrfAccount.publicKey,
|
||||
escrow: newVrfInitialState.escrow,
|
||||
permission: permissionAccount.publicKey,
|
||||
oracleQueue: queueAccount.publicKey,
|
||||
queueAuthority: queue.authority,
|
||||
programState: queueAccount.program.programState.publicKey,
|
||||
solDest: payer.publicKey,
|
||||
escrowDest: payerTokenAccount,
|
||||
switchboardProgram: queueAccount.program.programId,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
})
|
||||
.rpc();
|
||||
|
||||
const vrfClientAccountInfo =
|
||||
await vrfClientProgram.provider.connection.getAccountInfo(
|
||||
newVrfClientKey,
|
||||
"processed"
|
||||
);
|
||||
assert(vrfClientAccountInfo === null, "VrfClientNotClosed");
|
||||
|
||||
const vrfAccountInfo =
|
||||
await vrfClientProgram.provider.connection.getAccountInfo(
|
||||
newVrfAccount.publicKey,
|
||||
"processed"
|
||||
);
|
||||
assert(vrfAccountInfo === null, "VrfAccountNotClosed");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
"module": "commonjs"
|
||||
}
|
||||
},
|
||||
"compilerOptions": {
|
||||
"types": ["mocha", "chai", "node"],
|
||||
"typeRoots": ["./node_modules/@types"],
|
||||
"module": "commonjs",
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"strict": false,
|
||||
"strictNullChecks": false,
|
||||
"target": "es6",
|
||||
"paths": {
|
||||
"@switchboard-xyz/solana.js": ["../../javascript/solana.js"]
|
||||
}
|
||||
},
|
||||
"include": ["tests/**/*", "./cli.ts", "./client/**/*"],
|
||||
"exclude": ["target", "lib"],
|
||||
"references": [{ "path": "../../javascript/solana.js" }]
|
||||
}
|
|
@ -304,6 +304,8 @@ pub struct VrfLiteClose<'info> {
|
|||
#[account(mut)]
|
||||
pub queue: AccountInfo<'info>,
|
||||
pub queue_authority: AccountInfo<'info>,
|
||||
|
||||
// #[account(seeds = [b"STATE"], bump = params.state_bump)]
|
||||
/// CHECK:
|
||||
pub program_state: AccountInfo<'info>,
|
||||
|
||||
|
@ -314,8 +316,6 @@ pub struct VrfLiteClose<'info> {
|
|||
#[account(mut, constraint = escrow.mint == escrow_dest.mint )]
|
||||
pub escrow_dest: Account<'info, TokenAccount>,
|
||||
|
||||
pub recent_blockhashes: AccountInfo<'info>,
|
||||
// #[account(seeds = [b"STATE"], bump = params.state_bump)]
|
||||
pub token_program: AccountInfo<'info>,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue