vrf lite changes

This commit is contained in:
Conner Gallagher 2023-02-09 12:31:41 -07:00
parent cfefb4dd37
commit d7cd678bca
27 changed files with 750 additions and 286 deletions

View File

@ -1,12 +1,12 @@
{
"name": "@switchboard-xyz/solana.js",
"version": "2.0.122",
"version": "2.0.125",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "@switchboard-xyz/solana.js",
"version": "2.0.122",
"version": "2.0.125",
"license": "MIT",
"dependencies": {
"@coral-xyz/anchor": "^0.26.0",

View File

@ -1,6 +1,6 @@
{
"name": "@switchboard-xyz/solana.js",
"version": "2.0.122",
"version": "2.0.125",
"author": "",
"license": "MIT",
"description": "API wrapper for integrating with the Switchboard V2 program on Solana",

View File

@ -27,6 +27,7 @@ import { SwitchboardProgram } from '../SwitchboardProgram';
import {
TransactionObject,
TransactionObjectOptions,
TransactionPackOptions,
} from '../TransactionObject';
import { Account, OnAccountChangeCallback } from './account';
import { AggregatorHistoryBuffer } from './aggregatorHistoryBuffer';
@ -313,12 +314,11 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
const jobs = await this.loadJobs(aggregator);
const jobAuthorities = jobs.map(job => job.state.authority);
const [newPermissionAccount] = PermissionAccount.fromSeed(
this.program,
newQueue.authority,
const [newPermissionAccount] = this.getPermissionAccount(
params.newQueue.publicKey,
this.publicKey
newQueue.authority
);
const newPermissionAccountInfo =
await this.program.connection.getAccountInfo(
newPermissionAccount.publicKey
@ -336,11 +336,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
txns.push(permissionInitTxn);
}
const [newLeaseAccount] = LeaseAccount.fromSeed(
this.program,
params.newQueue.publicKey,
this.publicKey
);
const [newLeaseAccount] = this.getLeaseAccount(params.newQueue.publicKey);
const newLeaseAccountInfo = await this.program.connection.getAccountInfo(
newLeaseAccount.publicKey
);
@ -418,11 +414,9 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
}
): Promise<[TransactionObject | undefined, PermissionAccount]> {
const newQueue = await params.newQueue.loadData();
const [permissionAccount] = PermissionAccount.fromSeed(
this.program,
newQueue.authority,
const [permissionAccount] = this.getPermissionAccount(
params.newQueue.publicKey,
this.publicKey
newQueue.authority
);
if (!params.enable) {
@ -498,12 +492,11 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
const aggregator = await this.loadData();
// new permission account needs to be created and approved
const [permissionAccount] = PermissionAccount.fromSeed(
this.program,
newQueue.authority,
const [permissionAccount] = this.getPermissionAccount(
params.newQueue.publicKey,
this.publicKey
newQueue.authority
);
if (!params.force) {
await permissionAccount
.loadData()
@ -523,11 +516,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
}
// check the new lease has been created
const [newLeaseAccount] = LeaseAccount.fromSeed(
this.program,
params.newQueue.publicKey,
this.publicKey
);
const [newLeaseAccount] = this.getLeaseAccount(params.newQueue.publicKey);
if (!params.force) {
await newLeaseAccount.loadData().catch(() => {
throw new Error(`Expected leaseAccount to be created already`);
@ -567,11 +556,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
}
// remove any funds from the old lease account
const [oldLeaseAccount] = LeaseAccount.fromSeed(
this.program,
aggregator.queuePubkey,
this.publicKey
);
const [oldLeaseAccount] = this.getLeaseAccount(aggregator.queuePubkey);
const oldLease = await oldLeaseAccount.loadData();
const oldLeaseBalance = await oldLeaseAccount.fetchBalance(oldLease.escrow);
if (oldLease.withdrawAuthority.equals(payer) && oldLeaseBalance > 0) {
@ -674,25 +659,44 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
return [permissionAccount, leaseAccount, signatures];
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
public getLeaseAccount(
queuePubkey: PublicKey
): [LeaseAccount, PublicKey, number] {
const [leaseAccount, leaseBump] = LeaseAccount.fromSeed(
this.program,
queuePubkey,
this.publicKey
);
const leaseEscrow = this.program.mint.getAssociatedAddress(
leaseAccount.publicKey
);
return [leaseAccount, leaseEscrow, leaseBump];
}
public getAccounts(
queueAccount: QueueAccount,
queueAuthority: PublicKey
): AggregatorPdaAccounts {
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
queueAuthority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queueAuthority
);
const [leaseAccount, leaseBump] = LeaseAccount.fromSeed(
this.program,
queueAccount.publicKey,
this.publicKey
);
const leaseEscrow = this.program.mint.getAssociatedAddress(
leaseAccount.publicKey
const [leaseAccount, leaseEscrow, leaseBump] = this.getLeaseAccount(
queueAccount.publicKey
);
return {
@ -1474,12 +1478,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
const [oraclePermissionAccount, oraclePermissionBump] =
params.oraclePermission ??
PermissionAccount.fromSeed(
this.program,
queueAuthority,
queueAccount.publicKey,
params.oracleAccount.publicKey
);
this.getPermissionAccount(queueAccount.publicKey, queueAuthority);
const accounts: AggregatorPdaAccounts =
params.permissionAccount === undefined ||
@ -1919,6 +1918,126 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
// Probably not, gives MEV bots a floor
return Math.round(fee);
}
/** Fetch the balance of an aggregator's lease */
public async fetchBalance(
leaseEscrow?: PublicKey,
queuePubkey?: PublicKey
): Promise<number> {
const escrowPubkey =
leaseEscrow ??
this.getLeaseAccount(
queuePubkey ?? (await this.loadData()).queuePubkey
)[1];
const escrowBalance = await this.program.mint.fetchBalance(escrowPubkey);
if (escrowBalance === null) {
throw new errors.AccountNotFoundError('Lease Escrow', escrowPubkey);
}
return escrowBalance;
}
/** Create a transaction object that will fund an aggregator's lease up to a given balance */
public async fundUpToInstruction(
payer: PublicKey,
fundUpTo: number,
disableWrap = false
): Promise<[TransactionObject | undefined, number | undefined]> {
const [leaseAccount, leaseEscrow] = this.getLeaseAccount(
(await this.loadData()).queuePubkey
);
const balance = await this.fetchBalance(leaseEscrow);
if (balance >= fundUpTo) {
return [undefined, undefined];
}
const fundAmount = fundUpTo - balance;
const leaseExtend = await leaseAccount.extendInstruction(payer, {
fundAmount,
disableWrap,
});
return [leaseExtend, fundAmount];
}
/** Fund an aggregator's lease up to a given balance */
public async fundUpTo(
payer: PublicKey,
fundUpTo: number,
disableWrap = false
): Promise<[TransactionSignature | undefined, number | undefined]> {
const [fundUpToTxn, fundAmount] = await this.fundUpToInstruction(
payer,
fundUpTo,
disableWrap
);
if (!fundUpToTxn) {
return [undefined, undefined];
}
const txnSignature = await this.program.signAndSend(fundUpToTxn);
return [txnSignature, fundAmount!];
}
/** Create a set of transactions that will fund an aggregator's lease up to a given balance */
public static async fundMultipleUpToInstructions(
payer: PublicKey,
fundUpTo: number,
aggregators: Array<AggregatorAccount>,
options?: TransactionPackOptions | undefined
): Promise<Array<TransactionObject>> {
if (aggregators.length === 0) {
throw new Error(`No aggregator accounts provided`);
}
const program = aggregators[0].program;
const txns: Array<TransactionObject> = [];
let wrapAmount = 0;
for (const aggregator of aggregators) {
const [depositTxn, depositAmount] = await aggregator.fundUpToInstruction(
payer,
fundUpTo,
true
);
if (depositTxn && depositAmount) {
txns.push(depositTxn);
wrapAmount = wrapAmount + depositAmount;
}
}
const [_, wrapTxn] = await program.mint.getOrCreateWrappedUserInstructions(
payer,
{
fundUpTo: wrapAmount,
}
);
if (wrapTxn) {
txns.unshift(wrapTxn);
}
return TransactionObject.pack(txns, options);
}
/** Fund multiple aggregator account lease's up to a given balance */
public static async fundMultipleUpTo(
fundUpTo: number,
aggregators: Array<AggregatorAccount>,
options?: TransactionPackOptions | undefined
): Promise<Array<TransactionSignature>> {
if (aggregators.length === 0) {
throw new Error(`No aggregator accounts provided`);
}
const program = aggregators[0].program;
const txns = await AggregatorAccount.fundMultipleUpToInstructions(
program.walletPubkey,
fundUpTo,
aggregators,
options
);
const txnSignatures = await program.signAndSendAll(txns);
return txnSignatures;
}
}
/**

View File

@ -228,11 +228,9 @@ export class BufferRelayerAccount extends Account<types.BufferRelayerAccountData
}
}
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
queue.authority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queue.authority
);
const openRoundTxn = new TransactionObject(
@ -434,11 +432,9 @@ export class BufferRelayerAccount extends Account<types.BufferRelayerAccountData
}
public getAccounts(queueAccount: QueueAccount, queueAuthority: PublicKey) {
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
queueAuthority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queueAuthority
);
return {
@ -521,6 +517,22 @@ export class BufferRelayerAccount extends Account<types.BufferRelayerAccountData
},
};
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
public getEscrow(): PublicKey {
return this.program.mint.getAssociatedAddress(this.publicKey);
}
}
export interface BufferRelayerInit {

View File

@ -175,11 +175,9 @@ export class OracleAccount extends Account<types.OracleAccountData> {
const queueAccount =
_queueAccount ?? new QueueAccount(this.program, oracle.queuePubkey);
const queue = _queue ?? (await queueAccount.loadData());
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
queue.authority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queue.authority
);
const permission = await permissionAccount.loadData();
return [permissionAccount, permissionBump, permission];
@ -439,12 +437,8 @@ export class OracleAccount extends Account<types.OracleAccountData> {
const [permissionAccount, permissionBump] =
params?.permission ??
PermissionAccount.fromSeed(
this.program,
queue.authority,
queueAccount.publicKey,
this.publicKey
);
this.getPermissionAccount(queueAccount.publicKey, queue.authority);
try {
await permissionAccount.loadData();
} catch (_) {
@ -540,6 +534,18 @@ export class OracleAccount extends Account<types.OracleAccountData> {
return txnSignature;
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
public async toAccountsJSON(
_oracle?: types.OracleAccountData & { balance: number },
_permissionAccount?: PermissionAccount,
@ -551,11 +557,9 @@ export class OracleAccount extends Account<types.OracleAccountData> {
if (!permissionAccount || !permission) {
const queueAccount = new QueueAccount(this.program, oracle.queuePubkey);
const queue = await queueAccount.loadData();
[permissionAccount] = PermissionAccount.fromSeed(
this.program,
queue.authority,
[permissionAccount] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queue.authority
);
permission = await permissionAccount.loadData();
}

View File

@ -70,18 +70,18 @@ export class PermissionAccount extends Account<types.PermissionAccountData> {
permission: types.PermissionAccountData
): types.SwitchboardPermissionKind {
switch (permission.permissions) {
case 0:
case PermitNone.discriminator:
return new PermitNone();
case 1:
case PermitOracleHeartbeat.discriminator:
return new PermitOracleHeartbeat();
case 2:
case PermitOracleQueueUsage.discriminator:
return new PermitOracleQueueUsage();
case 3:
case PermitVrfRequests.discriminator:
return new PermitVrfRequests();
}
throw new Error(
`Failed to find the assigned permissions, expected a value from 0 - 3, received ${permission.permissions}`
`Failed to find the assigned permissions, expected [${PermitNone.discriminator}, ${PermitOracleHeartbeat.discriminator}, ${PermitOracleQueueUsage.discriminator}, or ${PermitVrfRequests.discriminator}], received ${permission.permissions}`
);
}

View File

@ -14,6 +14,7 @@ import {
import { promiseWithTimeout } from '@switchboard-xyz/common';
import * as errors from '../errors';
import * as types from '../generated';
import { vrfCloseAction } from '../generated';
import { SwitchboardProgram } from '../SwitchboardProgram';
import {
TransactionObject,
@ -179,11 +180,9 @@ export class VrfAccount extends Account<types.VrfAccountData> {
params.queueAccount ?? new QueueAccount(this.program, vrf.oracleQueue);
const queue = params.queue ?? (await queueAccount.loadData());
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
queue.authority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queue.authority
);
const requestRandomness = new TransactionObject(
@ -412,11 +411,9 @@ export class VrfAccount extends Account<types.VrfAccountData> {
}) {
const queueAccount = params.queueAccount;
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program,
params.queueAuthority,
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
params.queueAuthority
);
return {
@ -651,6 +648,89 @@ export class VrfAccount extends Account<types.VrfAccountData> {
return result;
}
async closeAccountInstruction(
payer: PublicKey,
params?: VrfCloseParams
): Promise<TransactionObject> {
const vrfLite = await this.loadData();
const queueAccount =
params?.queueAccount ??
new QueueAccount(this.program, vrfLite.oracleQueue);
const queueAuthority =
params?.queueAuthority ?? (await queueAccount.loadData()).authority;
const [permissionAccount, permissionBump] = this.getPermissionAccount(
queueAccount.publicKey,
queueAuthority
);
const [escrowDest, escrowInit] =
await this.program.mint.getOrCreateWrappedUserInstructions(payer, {
fundUpTo: 0,
});
const vrfClose = new TransactionObject(
payer,
[
vrfCloseAction(
this.program,
{
params: {
stateBump: this.program.programState.bump,
permissionBump: permissionBump,
},
},
{
vrf: this.publicKey,
permission: permissionAccount.publicKey,
authority: vrfLite.authority,
oracleQueue: queueAccount.publicKey,
queueAuthority,
programState: this.program.programState.publicKey,
escrow: vrfLite.escrow,
solDest: params?.destination ?? payer,
escrowDest: escrowDest,
tokenProgram: TOKEN_PROGRAM_ID,
}
),
],
params?.authority ? [params.authority] : []
);
if (escrowInit) {
return escrowInit.combine(vrfClose);
}
return vrfClose;
}
async closeAccount(params?: VrfCloseParams): Promise<TransactionSignature> {
const transaction = await this.closeAccountInstruction(
this.program.walletPubkey,
params
);
const txnSignature = await this.program.signAndSend(transaction, {
skipPreflight: true,
});
return txnSignature;
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
}
export interface VrfCloseParams {
destination?: PublicKey;
authority?: Keypair;
queueAccount?: QueueAccount;
queueAuthority?: PublicKey;
}
export interface VrfResult {

View File

@ -349,11 +349,9 @@ export class VrfLiteAccount extends Account<types.VrfLiteAccountData> {
params?.queueAccount ?? new QueueAccount(this.program, vrfLite.queue);
const queueAuthority =
params?.queueAuthority ?? (await queueAccount.loadData()).authority;
const [permissionAccount] = PermissionAccount.fromSeed(
this.program,
queueAuthority,
const [permissionAccount] = this.getPermissionAccount(
queueAccount.publicKey,
this.publicKey
queueAuthority
);
const [escrowDest, escrowInit] =
await this.program.mint.getOrCreateWrappedUserInstructions(payer, {
@ -401,4 +399,20 @@ export class VrfLiteAccount extends Account<types.VrfLiteAccountData> {
});
return txnSignature;
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
public getEscrow(): PublicKey {
return this.program.mint.getAssociatedAddress(this.publicKey);
}
}

View File

@ -15,7 +15,8 @@ import {
} from '@solana/web3.js';
import { promiseWithTimeout } from '@switchboard-xyz/common';
import _ from 'lodash';
import { AccountNotFoundError } from '../errors';
import { VRF_POOL_REQUEST_AMOUNT } from '../const';
import { AccountNotFoundError, InsufficientFundsError } from '../errors';
import * as types from '../generated';
import { VrfPoolRequestEvent } from '../SwitchboardEvents';
import { SwitchboardProgram } from '../SwitchboardProgram';
@ -63,6 +64,7 @@ export type VrfPoolDepositParams = {
tokenWallet?: PublicKey;
tokenAuthority?: Keypair;
amount: number;
disableWrap?: boolean;
};
export type VrfPoolAccountData = types.VrfPoolAccountData & {
@ -257,11 +259,9 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
vrfPool.queue
);
const [permissionAccount] = PermissionAccount.fromSeed(
this.program,
queue.authority,
const [permissionAccount] = this.getPermissionAccount(
queueAccount.publicKey,
params.vrf.publicKey
queue.authority
);
// verify permissions
@ -344,36 +344,24 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
return txnSignature;
}
public async requestInstructions(
payer: PublicKey,
params?: VrfPoolRequestParams
): Promise<TransactionObject> {
const REQUEST_ACCOUNT_SIZE = 7;
const vrfPool = await this.loadData();
const [queueAccount, queue] = await QueueAccount.load(
this.program,
vrfPool.queue
);
const permissionBumpsMap: Map<string, number> = new Map();
/** Returns the sorted, next {@param size} rows in the pool */
public getRemainingAccounts(
vrfPool: VrfPoolAccountData,
queueAuthority: PublicKey,
size = 7
): Array<AccountMeta> {
const vrfRows = [
...vrfPool.pool.slice(vrfPool.idx),
...vrfPool.pool.slice(0, vrfPool.idx),
];
].slice(0, size);
const slice = vrfRows.slice(0, REQUEST_ACCOUNT_SIZE);
const vrfs = slice.map((row): Array<AccountMeta> => {
const accountMetas = vrfRows.map((row): Array<AccountMeta> => {
const escrow = this.program.mint.getAssociatedAddress(row.pubkey);
const [permission, bump] = PermissionAccount.fromSeed(
this.program,
queue.authority,
queueAccount.publicKey,
row.pubkey
const [permission] = this.getPermissionAccount(
vrfPool.queue,
queueAuthority
);
permissionBumpsMap.set(row.pubkey.toBase58(), bump);
return [
{
pubkey: row.pubkey,
@ -393,21 +381,42 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
];
});
const remainingAccounts: Array<AccountMeta> = _.flatten(vrfs).sort((a, b) =>
Buffer.compare(a.pubkey.toBuffer(), b.pubkey.toBuffer())
const remainingAccounts: Array<AccountMeta> = _.flatten(accountMetas).sort(
(a, b) => Buffer.compare(a.pubkey.toBuffer(), b.pubkey.toBuffer())
);
const permissionBumps: Array<number> = [];
for (const remainingAccount of remainingAccounts) {
permissionBumps.push(
permissionBumpsMap.get(remainingAccount.pubkey.toBase58()) ?? 0
);
return remainingAccounts;
}
public async requestInstructions(
payer: PublicKey,
params?: VrfPoolRequestParams,
size = 7
): Promise<TransactionObject> {
const vrfPool = await this.loadData();
const [queueAccount, queue] = await QueueAccount.load(
this.program,
vrfPool.queue
);
const remainingAccounts = this.getRemainingAccounts(
vrfPool,
queue.authority,
size
);
// we dont want to wrap any funds. it will take up space in the txn needed for remainingAccounts
// to increase probability of popping the next row
const vrfPoolBalance = await this.fetchBalance(vrfPool.escrow);
if (vrfPoolBalance < VRF_POOL_REQUEST_AMOUNT) {
throw new InsufficientFundsError(VRF_POOL_REQUEST_AMOUNT, vrfPoolBalance);
}
const requestIxn = types.vrfPoolRequest(
this.program,
{
params: {
permissionBumps: new Uint8Array(permissionBumps),
callback: params?.callback ?? null,
},
},
@ -426,18 +435,13 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
);
requestIxn.keys = requestIxn.keys.concat(remainingAccounts);
const [wrapAccount, wrapTxn] =
await this.program.mint.getOrCreateWrappedUserInstructions(payer, {
fundUpTo: 0.002,
});
const requestTxn = new TransactionObject(
payer,
[requestIxn],
params?.authority ? [params.authority] : []
);
return wrapTxn
? wrapTxn.add(requestIxn, params?.authority ? [params.authority] : [])
: new TransactionObject(
payer,
[requestIxn],
params?.authority ? [params.authority] : []
);
return requestTxn;
}
public async request(
@ -553,18 +557,45 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
this.program.mint.getAssociatedAddress(
params.tokenAuthority?.publicKey ?? payer
);
const userBalance = await this.program.mint.fetchBalance(userTokenAddress);
if (params.disableWrap && !userBalance) {
throw new InsufficientFundsError(params.amount, 0);
}
if (params.disableWrap && params.amount > (userBalance ?? 0)) {
throw new InsufficientFundsError(params.amount, userBalance ?? 0);
}
const transferTxn = new TransactionObject(
payer,
[
createTransferInstruction(
userTokenAddress,
this.program.mint.getAssociatedAddress(this.publicKey),
this.getEscrow(),
params.tokenAuthority?.publicKey ?? payer,
this.program.mint.toTokenAmount(params.amount)
),
],
params.tokenAuthority ? [params.tokenAuthority] : []
);
if (params.amount > (userBalance ?? 0)) {
const [wrapAccount, wrapIxn] =
await this.program.mint.getOrCreateWrappedUserInstructions(
payer,
{ amount: params.amount },
params.tokenAuthority
);
if (wrapIxn) {
if (!wrapAccount.equals(userTokenAddress)) {
throw new Error(
`Incorrect token account, expected ${userTokenAddress}, received ${wrapAccount}`
);
}
return wrapIxn.combine(transferTxn);
}
}
return transferTxn;
}
@ -635,4 +666,68 @@ export class VrfPoolAccount extends Account<VrfPoolAccountData> {
return [event, requestRandomnessSignature];
}
public getPermissionAccount(
queuePubkey: PublicKey,
queueAuthority: PublicKey
): [PermissionAccount, number] {
return PermissionAccount.fromSeed(
this.program,
queueAuthority,
queuePubkey,
this.publicKey
);
}
public getEscrow(): PublicKey {
return this.program.mint.getAssociatedAddress(this.publicKey);
}
public async fetchBalance(escrow?: PublicKey): Promise<number> {
const escrowPubkey =
escrow ?? this.program.mint.getAssociatedAddress(this.publicKey);
const escrowBalance = await this.program.mint.fetchBalance(escrowPubkey);
if (escrowBalance === null) {
throw new AccountNotFoundError('VrfPool Escrow', escrowPubkey);
}
return escrowBalance;
}
public async fundUpToInstruction(
payer: PublicKey,
fundUpTo: number,
disableWrap = false
): Promise<[TransactionObject | undefined, number | undefined]> {
const escrowPubkey = this.getEscrow();
const balance = await this.fetchBalance(escrowPubkey);
if (balance >= fundUpTo) {
return [undefined, undefined];
}
const fundAmount = fundUpTo - balance;
const depositTxn = await this.depositInstructions(payer, {
amount: fundAmount,
disableWrap,
});
return [depositTxn, fundAmount];
}
public async fundUpTo(
payer: PublicKey,
fundUpTo: number,
disableWrap = false
): Promise<[TransactionSignature | undefined, number | undefined]> {
const [fundUpToTxn, fundAmount] = await this.fundUpToInstruction(
payer,
fundUpTo,
disableWrap
);
if (!fundUpToTxn) {
return [undefined, undefined];
}
const txnSignature = await this.program.signAndSend(fundUpToTxn);
return [txnSignature, fundAmount!];
}
}

View File

@ -41,3 +41,5 @@ export const DEVNET_GENESIS_HASH =
export const MAINNET_GENESIS_HASH =
'5eykt4UsFv8P8NJdTREpY1vzqKqZKvdpKuc147dw2N9d';
export const VRF_POOL_REQUEST_AMOUNT = 0.002;

View File

@ -38,8 +38,10 @@ export class NativeMintOnlyError extends Error {
}
}
export class InsufficientFundsError extends Error {
constructor() {
super('Insufficient funds to perform this action');
constructor(required: number, current: number) {
super(
`Insufficient funds to perform this action, required ${required}, current balance ${current}`
);
Object.setPrototypeOf(this, InsufficientFundsError.prototype);
}
}

View File

@ -36,6 +36,7 @@ export interface VrfLiteAccountDataFields {
/** The incremental VRF proof calculation. */
builder: types.VrfBuilderFields;
expiration: BN;
ebuf: Array<number>;
}
export interface VrfLiteAccountDataJSON {
@ -70,6 +71,7 @@ export interface VrfLiteAccountDataJSON {
/** The incremental VRF proof calculation. */
builder: types.VrfBuilderJSON;
expiration: string;
ebuf: Array<number>;
}
export class VrfLiteAccountData {
@ -104,6 +106,7 @@ export class VrfLiteAccountData {
/** The incremental VRF proof calculation. */
readonly builder: types.VrfBuilder;
readonly expiration: BN;
readonly ebuf: Array<number>;
static readonly discriminator = Buffer.from([
98, 127, 126, 124, 166, 81, 97, 100,
@ -126,6 +129,7 @@ export class VrfLiteAccountData {
types.CallbackZC.layout('callback'),
types.VrfBuilder.layout('builder'),
borsh.i64('expiration'),
borsh.array(borsh.u8(), 1024, 'ebuf'),
]);
constructor(fields: VrfLiteAccountDataFields) {
@ -145,6 +149,7 @@ export class VrfLiteAccountData {
this.callback = new types.CallbackZC({ ...fields.callback });
this.builder = new types.VrfBuilder({ ...fields.builder });
this.expiration = fields.expiration;
this.ebuf = fields.ebuf;
}
static async fetch(
@ -205,6 +210,7 @@ export class VrfLiteAccountData {
callback: types.CallbackZC.fromDecoded(dec.callback),
builder: types.VrfBuilder.fromDecoded(dec.builder),
expiration: dec.expiration,
ebuf: dec.ebuf,
});
}
@ -226,6 +232,7 @@ export class VrfLiteAccountData {
callback: this.callback.toJSON(),
builder: this.builder.toJSON(),
expiration: this.expiration.toString(),
ebuf: this.ebuf,
};
}
@ -247,6 +254,7 @@ export class VrfLiteAccountData {
callback: types.CallbackZC.fromJSON(obj.callback),
builder: types.VrfBuilder.fromJSON(obj.builder),
expiration: new BN(obj.expiration),
ebuf: obj.ebuf,
});
}
}

View File

@ -98,7 +98,8 @@ export type CustomError =
| AccountCloseNotReady
| VrfPoolRequestTooSoon
| VrfPoolMiss
| VrfLiteOwnedByPool;
| VrfLiteOwnedByPool
| InsufficientTokenBalance;
export class ArrayOperationError extends Error {
static readonly code = 6000;
@ -1223,6 +1224,17 @@ export class VrfLiteOwnedByPool extends Error {
}
}
export class InsufficientTokenBalance extends Error {
static readonly code = 6099;
readonly code = 6099;
readonly name = 'InsufficientTokenBalance';
readonly msg = 'Escrow has insufficient funds to perform this action.';
constructor(readonly logs?: string[]) {
super('6099: Escrow has insufficient funds to perform this action.');
}
}
export function fromCode(code: number, logs?: string[]): CustomError | null {
switch (code) {
case 6000:
@ -1423,6 +1435,8 @@ export function fromCode(code: number, logs?: string[]): CustomError | null {
return new VrfPoolMiss(logs);
case 6098:
return new VrfLiteOwnedByPool(logs);
case 6099:
return new InsufficientTokenBalance(logs);
}
return null;

View File

@ -58,8 +58,6 @@ export type {
AggregatorSetQueueArgs,
AggregatorSetQueueAccounts,
} from './aggregatorSetQueue';
export { crankInit } from './crankInit';
export type { CrankInitArgs, CrankInitAccounts } from './crankInit';
export { bufferRelayerInit } from './bufferRelayerInit';
export type {
BufferRelayerInitArgs,
@ -75,6 +73,8 @@ export type {
BufferRelayerSaveResultArgs,
BufferRelayerSaveResultAccounts,
} from './bufferRelayerSaveResult';
export { crankInit } from './crankInit';
export type { CrankInitArgs, CrankInitAccounts } from './crankInit';
export { crankPop } from './crankPop';
export type { CrankPopArgs, CrankPopAccounts } from './crankPop';
export { crankPopV2 } from './crankPopV2';
@ -133,6 +133,11 @@ export { vaultTransfer } from './vaultTransfer';
export type { VaultTransferArgs, VaultTransferAccounts } from './vaultTransfer';
export { vrfInit } from './vrfInit';
export type { VrfInitArgs, VrfInitAccounts } from './vrfInit';
export { vrfCloseAction } from './vrfCloseAction';
export type {
VrfCloseActionArgs,
VrfCloseActionAccounts,
} from './vrfCloseAction';
export { vrfLiteCloseAction } from './vrfLiteCloseAction';
export type {
VrfLiteCloseActionArgs,

View File

@ -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 VrfCloseActionArgs {
params: types.VrfCloseParamsFields;
}
export interface VrfCloseActionAccounts {
authority: PublicKey;
vrf: PublicKey;
permission: PublicKey;
oracleQueue: PublicKey;
queueAuthority: PublicKey;
programState: PublicKey;
escrow: PublicKey;
solDest: PublicKey;
escrowDest: PublicKey;
tokenProgram: PublicKey;
}
export const layout = borsh.struct([types.VrfCloseParams.layout('params')]);
export function vrfCloseAction(
program: SwitchboardProgram,
args: VrfCloseActionArgs,
accounts: VrfCloseActionAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.vrf, isSigner: false, isWritable: true },
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
{ pubkey: accounts.oracleQueue, isSigner: false, isWritable: false },
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
{ pubkey: accounts.programState, isSigner: false, isWritable: false },
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
{ pubkey: accounts.solDest, isSigner: false, isWritable: false },
{ pubkey: accounts.escrowDest, isSigner: false, isWritable: true },
{ pubkey: accounts.tokenProgram, isSigner: false, isWritable: false },
];
const identifier = Buffer.from([97, 172, 124, 16, 175, 10, 246, 147]);
const buffer = Buffer.alloc(1000);
const len = layout.encode(
{
params: types.VrfCloseParams.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;
}

View File

@ -13,9 +13,9 @@ export interface VrfLiteCloseActionArgs {
}
export interface VrfLiteCloseActionAccounts {
authority: PublicKey;
vrfLite: PublicKey;
permission: PublicKey;
authority: PublicKey;
queue: PublicKey;
queueAuthority: PublicKey;
programState: PublicKey;
@ -33,9 +33,9 @@ export function vrfLiteCloseAction(
accounts: VrfLiteCloseActionAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.vrfLite, isSigner: false, isWritable: true },
{ pubkey: accounts.permission, isSigner: false, isWritable: true },
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.queue, isSigner: false, isWritable: false },
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
{ pubkey: accounts.programState, isSigner: false, isWritable: false },

View File

@ -13,8 +13,8 @@ export interface VrfLiteInitArgs {
}
export interface VrfLiteInitAccounts {
vrf: PublicKey;
authority: PublicKey;
vrf: PublicKey;
mint: PublicKey;
escrow: PublicKey;
queueAuthority: PublicKey;
@ -36,8 +36,8 @@ export function vrfLiteInit(
accounts: VrfLiteInitAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.vrf, isSigner: true, isWritable: true },
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
{ pubkey: accounts.vrf, isSigner: true, isWritable: true },
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },

View File

@ -15,7 +15,6 @@ export interface VrfLiteRequestRandomnessArgs {
export interface VrfLiteRequestRandomnessAccounts {
authority: PublicKey;
vrfLite: PublicKey;
mint: PublicKey;
queue: PublicKey;
queueAuthority: PublicKey;
dataBuffer: PublicKey;
@ -38,7 +37,6 @@ export function vrfLiteRequestRandomness(
const keys: Array<AccountMeta> = [
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.vrfLite, isSigner: false, isWritable: true },
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
{ pubkey: accounts.queue, isSigner: false, isWritable: true },
{ pubkey: accounts.queueAuthority, isSigner: false, isWritable: false },
{ pubkey: accounts.dataBuffer, isSigner: false, isWritable: false },

View File

@ -13,8 +13,8 @@ export interface VrfPoolAddArgs {
}
export interface VrfPoolAddAccounts {
vrfPool: PublicKey;
authority: PublicKey;
vrfPool: PublicKey;
vrfLite: PublicKey;
queue: PublicKey;
permission: PublicKey;
@ -28,8 +28,8 @@ export function vrfPoolAdd(
accounts: VrfPoolAddAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.vrfLite, isSigner: false, isWritable: true },
{ pubkey: accounts.queue, isSigner: false, isWritable: false },
{ pubkey: accounts.permission, isSigner: false, isWritable: false },

View File

@ -13,8 +13,8 @@ export interface VrfPoolInitArgs {
}
export interface VrfPoolInitAccounts {
vrfPool: PublicKey;
authority: PublicKey;
vrfPool: PublicKey;
queue: PublicKey;
mint: PublicKey;
escrow: PublicKey;
@ -34,8 +34,8 @@ export function vrfPoolInit(
accounts: VrfPoolInitAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.authority, isSigner: false, isWritable: false },
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.queue, isSigner: false, isWritable: false },
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },

View File

@ -13,8 +13,8 @@ export interface VrfPoolRemoveArgs {
}
export interface VrfPoolRemoveAccounts {
vrfPool: PublicKey;
authority: PublicKey;
vrfPool: PublicKey;
queue: PublicKey;
}
@ -28,8 +28,8 @@ export function vrfPoolRemove(
accounts: VrfPoolRemoveAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.queue, isSigner: false, isWritable: false },
];
const identifier = Buffer.from([15, 73, 86, 124, 75, 183, 20, 199]);

View File

@ -13,8 +13,8 @@ export interface VrfPoolRequestArgs {
}
export interface VrfPoolRequestAccounts {
vrfPool: PublicKey;
authority: PublicKey;
vrfPool: PublicKey;
escrow: PublicKey;
mint: PublicKey;
queue: PublicKey;
@ -35,8 +35,8 @@ export function vrfPoolRequest(
accounts: VrfPoolRequestAccounts
) {
const keys: Array<AccountMeta> = [
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.authority, isSigner: true, isWritable: false },
{ pubkey: accounts.vrfPool, isSigner: false, isWritable: true },
{ pubkey: accounts.escrow, isSigner: false, isWritable: true },
{ pubkey: accounts.mint, isSigner: false, isWritable: false },
{ pubkey: accounts.queue, isSigner: false, isWritable: true },

View File

@ -75,9 +75,9 @@ export interface PermitVrfRequestsJSON {
}
export class PermitVrfRequests {
static readonly discriminator = 3;
static readonly discriminator = 4;
static readonly kind = 'PermitVrfRequests';
readonly discriminator = 3;
readonly discriminator = 4;
readonly kind = 'PermitVrfRequests';
toJSON(): PermitVrfRequestsJSON {

View File

@ -0,0 +1,65 @@
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 VrfCloseParamsFields {
stateBump: number;
permissionBump: number;
}
export interface VrfCloseParamsJSON {
stateBump: number;
permissionBump: number;
}
export class VrfCloseParams {
readonly stateBump: number;
readonly permissionBump: number;
constructor(fields: VrfCloseParamsFields) {
this.stateBump = fields.stateBump;
this.permissionBump = fields.permissionBump;
}
static layout(property?: string) {
return borsh.struct(
[borsh.u8('stateBump'), borsh.u8('permissionBump')],
property
);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static fromDecoded(obj: any) {
return new VrfCloseParams({
stateBump: obj.stateBump,
permissionBump: obj.permissionBump,
});
}
static toEncodable(fields: VrfCloseParamsFields) {
return {
stateBump: fields.stateBump,
permissionBump: fields.permissionBump,
};
}
toJSON(): VrfCloseParamsJSON {
return {
stateBump: this.stateBump,
permissionBump: this.permissionBump,
};
}
static fromJSON(obj: VrfCloseParamsJSON): VrfCloseParams {
return new VrfCloseParams({
stateBump: obj.stateBump,
permissionBump: obj.permissionBump,
});
}
toEncodable() {
return VrfCloseParams.toEncodable(this);
}
}

View File

@ -5,31 +5,24 @@ import * as types from '../types'; // eslint-disable-line @typescript-eslint/no-
import * as borsh from '@coral-xyz/borsh';
export interface VrfPoolRequestParamsFields {
permissionBumps: Uint8Array;
callback: types.CallbackFields | null;
}
export interface VrfPoolRequestParamsJSON {
permissionBumps: Array<number>;
callback: types.CallbackJSON | null;
}
export class VrfPoolRequestParams {
readonly permissionBumps: Uint8Array;
readonly callback: types.Callback | null;
constructor(fields: VrfPoolRequestParamsFields) {
this.permissionBumps = fields.permissionBumps;
this.callback =
(fields.callback && new types.Callback({ ...fields.callback })) || null;
}
static layout(property?: string) {
return borsh.struct(
[
borsh.vecU8('permissionBumps'),
borsh.option(types.Callback.layout(), 'callback'),
],
[borsh.option(types.Callback.layout(), 'callback')],
property
);
}
@ -37,11 +30,6 @@ export class VrfPoolRequestParams {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
static fromDecoded(obj: any) {
return new VrfPoolRequestParams({
permissionBumps: new Uint8Array(
obj.permissionBumps.buffer,
obj.permissionBumps.byteOffset,
obj.permissionBumps.length
),
callback:
(obj.callback && types.Callback.fromDecoded(obj.callback)) || null,
});
@ -49,11 +37,6 @@ export class VrfPoolRequestParams {
static toEncodable(fields: VrfPoolRequestParamsFields) {
return {
permissionBumps: Buffer.from(
fields.permissionBumps.buffer,
fields.permissionBumps.byteOffset,
fields.permissionBumps.length
),
callback:
(fields.callback && types.Callback.toEncodable(fields.callback)) ||
null,
@ -62,14 +45,12 @@ export class VrfPoolRequestParams {
toJSON(): VrfPoolRequestParamsJSON {
return {
permissionBumps: Array.from(this.permissionBumps.values()),
callback: (this.callback && this.callback.toJSON()) || null,
};
}
static fromJSON(obj: VrfPoolRequestParamsJSON): VrfPoolRequestParams {
return new VrfPoolRequestParams({
permissionBumps: Uint8Array.from(obj.permissionBumps),
callback: (obj.callback && types.Callback.fromJSON(obj.callback)) || null,
});
}

View File

@ -1,16 +1,28 @@
import * as Lanes from './Lanes';
import * as Shuffle from './Shuffle';
import * as Error from './Error';
import * as AggregatorResolutionMode from './AggregatorResolutionMode';
import * as SwitchboardPermission from './SwitchboardPermission';
import * as Error from './Error';
import * as Lanes from './Lanes';
import * as OracleResponseType from './OracleResponseType';
import * as Shuffle from './Shuffle';
import * as SwitchboardPermission from './SwitchboardPermission';
import * as VrfStatus from './VrfStatus';
export { AccountMetaBorsh } from './AccountMetaBorsh';
export type {
AccountMetaBorshFields,
AccountMetaBorshJSON,
} from './AccountMetaBorsh';
export { AccountMetaZC } from './AccountMetaZC';
export type { AccountMetaZCFields, AccountMetaZCJSON } from './AccountMetaZC';
export { AggregatorAddJobParams } from './AggregatorAddJobParams';
export type {
AggregatorAddJobParamsFields,
AggregatorAddJobParamsJSON,
} from './AggregatorAddJobParams';
export { AggregatorHistoryRow } from './AggregatorHistoryRow';
export type {
AggregatorHistoryRowFields,
AggregatorHistoryRowJSON,
} from './AggregatorHistoryRow';
export { AggregatorInitParams } from './AggregatorInitParams';
export type {
AggregatorInitParamsFields,
@ -31,6 +43,11 @@ export type {
AggregatorRemoveJobParamsFields,
AggregatorRemoveJobParamsJSON,
} from './AggregatorRemoveJobParams';
export { AggregatorRound } from './AggregatorRound';
export type {
AggregatorRoundFields,
AggregatorRoundJSON,
} from './AggregatorRound';
export { AggregatorSaveResultParams } from './AggregatorSaveResultParams';
export type {
AggregatorSaveResultParamsFields,
@ -96,6 +113,8 @@ export type {
AggregatorSetVarianceThresholdParamsFields,
AggregatorSetVarianceThresholdParamsJSON,
} from './AggregatorSetVarianceThresholdParams';
export { BorshDecimal } from './BorshDecimal';
export type { BorshDecimalFields, BorshDecimalJSON } from './BorshDecimal';
export { BufferRelayerInitParams } from './BufferRelayerInitParams';
export type {
BufferRelayerInitParamsFields,
@ -106,11 +125,25 @@ export type {
BufferRelayerOpenRoundParamsFields,
BufferRelayerOpenRoundParamsJSON,
} from './BufferRelayerOpenRoundParams';
export { BufferRelayerRound } from './BufferRelayerRound';
export type {
BufferRelayerRoundFields,
BufferRelayerRoundJSON,
} from './BufferRelayerRound';
export { BufferRelayerSaveResultParams } from './BufferRelayerSaveResultParams';
export type {
BufferRelayerSaveResultParamsFields,
BufferRelayerSaveResultParamsJSON,
} from './BufferRelayerSaveResultParams';
export { Callback } from './Callback';
export type { CallbackFields, CallbackJSON } from './Callback';
export { CallbackZC } from './CallbackZC';
export type { CallbackZCFields, CallbackZCJSON } from './CallbackZC';
export { CompletedPointZC } from './CompletedPointZC';
export type {
CompletedPointZCFields,
CompletedPointZCJSON,
} from './CompletedPointZC';
export { CrankInitParams } from './CrankInitParams';
export type {
CrankInitParamsFields,
@ -131,6 +164,27 @@ export type {
CrankPushParamsFields,
CrankPushParamsJSON,
} from './CrankPushParams';
export { CrankRow } from './CrankRow';
export type { CrankRowFields, CrankRowJSON } from './CrankRow';
export { EcvrfIntermediate } from './EcvrfIntermediate';
export type {
EcvrfIntermediateFields,
EcvrfIntermediateJSON,
} from './EcvrfIntermediate';
export { EcvrfProofZC } from './EcvrfProofZC';
export type { EcvrfProofZCFields, EcvrfProofZCJSON } from './EcvrfProofZC';
export { EdwardsPointZC } from './EdwardsPointZC';
export type {
EdwardsPointZCFields,
EdwardsPointZCJSON,
} from './EdwardsPointZC';
export { FieldElementZC } from './FieldElementZC';
export type {
FieldElementZCFields,
FieldElementZCJSON,
} from './FieldElementZC';
export { Hash } from './Hash';
export type { HashFields, HashJSON } from './Hash';
export { JobInitParams } from './JobInitParams';
export type { JobInitParamsFields, JobInitParamsJSON } from './JobInitParams';
export { JobSetDataParams } from './JobSetDataParams';
@ -168,6 +222,8 @@ export type {
OracleInitParamsFields,
OracleInitParamsJSON,
} from './OracleInitParams';
export { OracleMetrics } from './OracleMetrics';
export type { OracleMetricsFields, OracleMetricsJSON } from './OracleMetrics';
export { OracleQueueInitParams } from './OracleQueueInitParams';
export type {
OracleQueueInitParamsFields,
@ -208,11 +264,41 @@ export type {
ProgramInitParamsFields,
ProgramInitParamsJSON,
} from './ProgramInitParams';
export { ProjectivePointZC } from './ProjectivePointZC';
export type {
ProjectivePointZCFields,
ProjectivePointZCJSON,
} from './ProjectivePointZC';
export { Scalar } from './Scalar';
export type { ScalarFields, ScalarJSON } from './Scalar';
export { SlidingWindowElement } from './SlidingWindowElement';
export type {
SlidingWindowElementFields,
SlidingWindowElementJSON,
} from './SlidingWindowElement';
export { SwitchboardDecimal } from './SwitchboardDecimal';
export type {
SwitchboardDecimalFields,
SwitchboardDecimalJSON,
} from './SwitchboardDecimal';
export {
PermitNone,
PermitOracleHeartbeat,
PermitOracleQueueUsage,
PermitVrfRequests,
} from './SwitchboardPermission';
export { VaultTransferParams } from './VaultTransferParams';
export type {
VaultTransferParamsFields,
VaultTransferParamsJSON,
} from './VaultTransferParams';
export { VrfBuilder } from './VrfBuilder';
export type { VrfBuilderFields, VrfBuilderJSON } from './VrfBuilder';
export { VrfCloseParams } from './VrfCloseParams';
export type {
VrfCloseParamsFields,
VrfCloseParamsJSON,
} from './VrfCloseParams';
export { VrfInitParams } from './VrfInitParams';
export type { VrfInitParamsFields, VrfInitParamsJSON } from './VrfInitParams';
export { VrfLiteCloseParams } from './VrfLiteCloseParams';
@ -235,6 +321,11 @@ export type {
VrfLiteRequestRandomnessParamsFields,
VrfLiteRequestRandomnessParamsJSON,
} from './VrfLiteRequestRandomnessParams';
export { VrfPoolAddParams } from './VrfPoolAddParams';
export type {
VrfPoolAddParamsFields,
VrfPoolAddParamsJSON,
} from './VrfPoolAddParams';
export { VrfPoolInitParams } from './VrfPoolInitParams';
export type {
VrfPoolInitParamsFields,
@ -245,118 +336,42 @@ export type {
VrfPoolRemoveParamsFields,
VrfPoolRemoveParamsJSON,
} from './VrfPoolRemoveParams';
export { VrfPoolAddParams } from './VrfPoolAddParams';
export type {
VrfPoolAddParamsFields,
VrfPoolAddParamsJSON,
} from './VrfPoolAddParams';
export { VrfPoolRequestParams } from './VrfPoolRequestParams';
export type {
VrfPoolRequestParamsFields,
VrfPoolRequestParamsJSON,
} from './VrfPoolRequestParams';
export { VrfProveParams } from './VrfProveParams';
export type {
VrfProveParamsFields,
VrfProveParamsJSON,
} from './VrfProveParams';
export { VrfPoolRow } from './VrfPoolRow';
export type { VrfPoolRowFields, VrfPoolRowJSON } from './VrfPoolRow';
export { VrfProveAndVerifyParams } from './VrfProveAndVerifyParams';
export type {
VrfProveAndVerifyParamsFields,
VrfProveAndVerifyParamsJSON,
} from './VrfProveAndVerifyParams';
export { VrfProveParams } from './VrfProveParams';
export type {
VrfProveParamsFields,
VrfProveParamsJSON,
} from './VrfProveParams';
export { VrfRequestRandomnessParams } from './VrfRequestRandomnessParams';
export type {
VrfRequestRandomnessParamsFields,
VrfRequestRandomnessParamsJSON,
} from './VrfRequestRandomnessParams';
export { VrfRound } from './VrfRound';
export type { VrfRoundFields, VrfRoundJSON } from './VrfRound';
export { VrfSetCallbackParams } from './VrfSetCallbackParams';
export type {
VrfSetCallbackParamsFields,
VrfSetCallbackParamsJSON,
} from './VrfSetCallbackParams';
export { Callback } from './Callback';
export type { CallbackFields, CallbackJSON } from './Callback';
export { EcvrfProofZC } from './EcvrfProofZC';
export type { EcvrfProofZCFields, EcvrfProofZCJSON } from './EcvrfProofZC';
export { Scalar } from './Scalar';
export type { ScalarFields, ScalarJSON } from './Scalar';
export { FieldElementZC } from './FieldElementZC';
export type {
FieldElementZCFields,
FieldElementZCJSON,
} from './FieldElementZC';
export { CompletedPointZC } from './CompletedPointZC';
export type {
CompletedPointZCFields,
CompletedPointZCJSON,
} from './CompletedPointZC';
export { EdwardsPointZC } from './EdwardsPointZC';
export type {
EdwardsPointZCFields,
EdwardsPointZCJSON,
} from './EdwardsPointZC';
export { ProjectivePointZC } from './ProjectivePointZC';
export type {
ProjectivePointZCFields,
ProjectivePointZCJSON,
} from './ProjectivePointZC';
export { EcvrfIntermediate } from './EcvrfIntermediate';
export type {
EcvrfIntermediateFields,
EcvrfIntermediateJSON,
} from './EcvrfIntermediate';
export { Hash } from './Hash';
export type { HashFields, HashJSON } from './Hash';
export { SlidingWindowElement } from './SlidingWindowElement';
export type {
SlidingWindowElementFields,
SlidingWindowElementJSON,
} from './SlidingWindowElement';
export { AggregatorRound } from './AggregatorRound';
export type {
AggregatorRoundFields,
AggregatorRoundJSON,
} from './AggregatorRound';
export { AggregatorHistoryRow } from './AggregatorHistoryRow';
export type {
AggregatorHistoryRowFields,
AggregatorHistoryRowJSON,
} from './AggregatorHistoryRow';
export { SwitchboardDecimal } from './SwitchboardDecimal';
export type {
SwitchboardDecimalFields,
SwitchboardDecimalJSON,
} from './SwitchboardDecimal';
export { CrankRow } from './CrankRow';
export type { CrankRowFields, CrankRowJSON } from './CrankRow';
export { OracleMetrics } from './OracleMetrics';
export type { OracleMetricsFields, OracleMetricsJSON } from './OracleMetrics';
export { VrfBuilder } from './VrfBuilder';
export type { VrfBuilderFields, VrfBuilderJSON } from './VrfBuilder';
export { AccountMetaZC } from './AccountMetaZC';
export type { AccountMetaZCFields, AccountMetaZCJSON } from './AccountMetaZC';
export { AccountMetaBorsh } from './AccountMetaBorsh';
export type {
AccountMetaBorshFields,
AccountMetaBorshJSON,
} from './AccountMetaBorsh';
export { CallbackZC } from './CallbackZC';
export type { CallbackZCFields, CallbackZCJSON } from './CallbackZC';
export { VrfRound } from './VrfRound';
export type { VrfRoundFields, VrfRoundJSON } from './VrfRound';
export { VrfPoolRow } from './VrfPoolRow';
export type { VrfPoolRowFields, VrfPoolRowJSON } from './VrfPoolRow';
export { BufferRelayerRound } from './BufferRelayerRound';
export type {
BufferRelayerRoundFields,
BufferRelayerRoundJSON,
} from './BufferRelayerRound';
export { BorshDecimal } from './BorshDecimal';
export type { BorshDecimalFields, BorshDecimalJSON } from './BorshDecimal';
export { Lanes };
export { Shuffle };
export { Error };
export { AggregatorResolutionMode };
export { SwitchboardPermission };
export { OracleResponseType };
export { VrfStatus };
/**
* The `Lanes` enum represents a subset of the lanes `A,B,C,D` of a
@ -415,8 +430,6 @@ export type ErrorJSON =
| Error.DeserializationErrorJSON
| Error.InvalidDataErrorJSON;
export { AggregatorResolutionMode };
export type AggregatorResolutionModeKind =
| AggregatorResolutionMode.ModeRoundResolution
| AggregatorResolutionMode.ModeSlidingResolution;
@ -424,8 +437,6 @@ export type AggregatorResolutionModeJSON =
| AggregatorResolutionMode.ModeRoundResolutionJSON
| AggregatorResolutionMode.ModeSlidingResolutionJSON;
export { SwitchboardPermission };
export type SwitchboardPermissionKind =
| SwitchboardPermission.PermitNone
| SwitchboardPermission.PermitOracleHeartbeat
@ -437,15 +448,6 @@ export type SwitchboardPermissionJSON =
| SwitchboardPermission.PermitOracleQueueUsageJSON
| SwitchboardPermission.PermitVrfRequestsJSON;
export {
PermitNone,
PermitOracleHeartbeat,
PermitOracleQueueUsage,
PermitVrfRequests,
} from './SwitchboardPermission';
export { OracleResponseType };
export type OracleResponseTypeKind =
| OracleResponseType.TypeSuccess
| OracleResponseType.TypeError
@ -457,8 +459,6 @@ export type OracleResponseTypeJSON =
| OracleResponseType.TypeDisagreementJSON
| OracleResponseType.TypeNoResponseJSON;
export { VrfStatus };
export type VrfStatusKind =
| VrfStatus.StatusNone
| VrfStatus.StatusRequesting

View File

@ -430,7 +430,10 @@ export class NativeMint extends Mint {
}
if (userBalance.lte(wrapAmount)) {
throw new InsufficientFundsError();
throw new InsufficientFundsError(
wrapAmount.toNumber(),
userBalance.toNumber()
);
}
const ephemeralAccount = Keypair.generate();