uprev spl-token

uprev spl-token


uprev spl-token
This commit is contained in:
Conner Gallagher 2022-06-29 19:44:33 -06:00
parent 54ba4e85df
commit 4e03241997
55 changed files with 1138 additions and 654 deletions

View File

@ -1,18 +1,18 @@
[provider] [provider]
# cluster = "devnet" cluster = "devnet"
cluster = "localnet" # cluster = "localnet"
wallet = "../payer-keypair.json" wallet = "../payer-keypair.json"
# wallet = "~/.config/solana/id.json" # wallet = "~/.config/solana/id.json"
[programs.localnet] [programs.localnet]
anchor_feed_parser = "7Th37Bvb7u2sS4Xe6YkvCkHSHDAakRUeobRBNXuf2PFD" anchor_feed_parser = "FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
anchor_vrf_parser = "GCam9zJ6soszC4K69Gy84krGdeALxwS2noeBwqLmP6JH" anchor_vrf_parser = "HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
[registry] [registry]
url = "https://anchor.projectserum.com" url = "https://anchor.projectserum.com"
[scripts] [scripts]
test = "yarn run ts-mocha -p ./tsconfig.testing.json -t 1000000 ./programs/*/tests/*.test.ts" test = "yarn run ts-mocha -p ./tsconfig.testing.json -t 1000000 ./programs/anchor-vrf-parser/tests/*.test.ts"
[test.validator] [test.validator]

View File

@ -31,7 +31,7 @@
"@oclif/plugin-version": "^1.0.4", "@oclif/plugin-version": "^1.0.4",
"@oclif/plugin-warn-if-update-available": "^2.0.4", "@oclif/plugin-warn-if-update-available": "^2.0.4",
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/spl-token": "^0.1.8", "@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.43.5", "@solana/web3.js": "^1.43.5",
"@switchboard-xyz/sbv2-utils": "^0.1.25", "@switchboard-xyz/sbv2-utils": "^0.1.25",
"@switchboard-xyz/switchboard-v2": "^0.0.114", "@switchboard-xyz/switchboard-v2": "^0.0.114",

View File

@ -145,9 +145,19 @@ export default class AggregatorCreateCopy extends BaseCommand {
publicKey: new PublicKey(flags.queueKey), publicKey: new PublicKey(flags.queueKey),
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const tokenWallet = ( const tokenWallet = (
await tokenMint.getOrCreateAssociatedAccountInfo(payerKeypair.publicKey) await spl.getOrCreateAssociatedTokenAccount(
this.program.provider.connection,
payerKeypair,
mint.address,
payerKeypair.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
)
).address; ).address;
const createAccountInstructions: ( const createAccountInstructions: (
@ -183,12 +193,12 @@ export default class AggregatorCreateCopy extends BaseCommand {
queueAccount, queueAccount,
aggregatorAccount aggregatorAccount
); );
const leaseEscrow = await spl.Token.getAssociatedTokenAddress( const leaseEscrow = await spl.getAssociatedTokenAddress(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, mint.address,
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
leaseAccount.publicKey, leaseAccount.publicKey,
true true,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
createAccountInstructions.push( createAccountInstructions.push(
@ -260,13 +270,13 @@ export default class AggregatorCreateCopy extends BaseCommand {
createAccountInstructions.push( createAccountInstructions.push(
[ [
spl.Token.createAssociatedTokenAccountInstruction( spl.createAssociatedTokenAccountInstruction(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
leaseEscrow, leaseEscrow,
leaseAccount.publicKey, payerKeypair.publicKey,
payerKeypair.publicKey mint.address,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
), ),
await this.program.methods await this.program.methods
.leaseInit({ .leaseInit({
@ -287,7 +297,7 @@ export default class AggregatorCreateCopy extends BaseCommand {
tokenProgram: spl.TOKEN_PROGRAM_ID, tokenProgram: spl.TOKEN_PROGRAM_ID,
escrow: leaseEscrow, escrow: leaseEscrow,
owner: payerKeypair.publicKey, owner: payerKeypair.publicKey,
mint: tokenMint.publicKey, mint: mint.address,
}) })
// .remainingAccounts( // .remainingAccounts(
// jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => { // jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => {

View File

@ -109,12 +109,18 @@ export default class AggregatorCreate extends BaseCommand {
publicKey: new PublicKey(args.queueKey), publicKey: new PublicKey(args.queueKey),
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const switchTokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const tokenWallet = ( const tokenWallet = await spl.getOrCreateAssociatedTokenAccount(
await switchTokenMint.getOrCreateAssociatedAccountInfo( this.program.provider.connection,
payerKeypair.publicKey payerKeypair,
) mint.address,
).address; payerKeypair.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
);
const createAccountInstructions: ( const createAccountInstructions: (
| TransactionInstruction | TransactionInstruction
@ -178,7 +184,7 @@ export default class AggregatorCreate extends BaseCommand {
}) })
.accounts({ .accounts({
job: jobKeypair.publicKey, job: jobKeypair.publicKey,
authorWallet: tokenWallet, authorWallet: tokenWallet.address,
authority: feedAuthority.publicKey, authority: feedAuthority.publicKey,
programState: programStateAccount.publicKey, programState: programStateAccount.publicKey,
}) })
@ -248,7 +254,7 @@ export default class AggregatorCreate extends BaseCommand {
aggregator: aggregatorKeypair.publicKey, aggregator: aggregatorKeypair.publicKey,
authority: feedAuthority.publicKey, authority: feedAuthority.publicKey,
queue: queueAccount.publicKey, queue: queueAccount.publicKey,
authorWallet: tokenWallet, authorWallet: tokenWallet.address,
programState: programStateAccount.publicKey, programState: programStateAccount.publicKey,
}) })
.instruction(), .instruction(),
@ -286,22 +292,22 @@ export default class AggregatorCreate extends BaseCommand {
queueAccount, queueAccount,
aggregatorAccount aggregatorAccount
); );
const leaseEscrow = await spl.Token.getAssociatedTokenAddress( const leaseEscrow = await spl.getAssociatedTokenAddress(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, mint.address,
spl.TOKEN_PROGRAM_ID,
switchTokenMint.publicKey,
leaseAccount.publicKey, leaseAccount.publicKey,
true true,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
createAccountInstructions.push( createAccountInstructions.push(
[ [
spl.Token.createAssociatedTokenAccountInstruction( spl.createAssociatedTokenAccountInstruction(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID,
switchTokenMint.publicKey,
leaseEscrow, leaseEscrow,
leaseAccount.publicKey, payerKeypair.publicKey,
payerKeypair.publicKey mint.address,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
), ),
await this.program.methods await this.program.methods
.leaseInit({ .leaseInit({
@ -317,12 +323,12 @@ export default class AggregatorCreate extends BaseCommand {
queue: queueAccount.publicKey, queue: queueAccount.publicKey,
aggregator: aggregatorAccount.publicKey, aggregator: aggregatorAccount.publicKey,
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
funder: tokenWallet, funder: tokenWallet.address,
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
tokenProgram: spl.TOKEN_PROGRAM_ID, tokenProgram: spl.TOKEN_PROGRAM_ID,
escrow: leaseEscrow, escrow: leaseEscrow,
owner: payerKeypair.publicKey, owner: payerKeypair.publicKey,
mint: switchTokenMint.publicKey, mint: mint.address,
}) })
// .remainingAccounts( // .remainingAccounts(
// jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => { // jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => {

View File

@ -1,8 +1,8 @@
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { getOrCreateSwitchboardMintTokenAccount } from "@switchboard-xyz/sbv2-utils";
import { import {
AggregatorAccount, AggregatorAccount,
OracleQueueAccount, OracleQueueAccount,
programWallet,
} from "@switchboard-xyz/switchboard-v2"; } from "@switchboard-xyz/switchboard-v2";
import chalk from "chalk"; import chalk from "chalk";
import BaseCommand from "../../BaseCommand"; import BaseCommand from "../../BaseCommand";
@ -44,11 +44,10 @@ export default class AggregatorUpdate extends BaseCommand {
const mint = await oracleQueueAccount.loadMint(); const mint = await oracleQueueAccount.loadMint();
const payoutWallet = ( const payoutWallet = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo( this.program,
programWallet(this.program).publicKey mint
) );
).address;
const aggregatorUpdateTxn = await aggregatorAccount.openRound({ const aggregatorUpdateTxn = await aggregatorAccount.openRound({
oracleQueueAccount, oracleQueueAccount,

View File

@ -1,4 +1,5 @@
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { getOrCreateSwitchboardMintTokenAccount } from "@switchboard-xyz/sbv2-utils";
import { import {
CrankAccount, CrankAccount,
OracleQueueAccount, OracleQueueAccount,
@ -54,12 +55,15 @@ export default class CrankTurn extends BaseCommand {
const progamState = await programStateAccount.loadData(); const progamState = await programStateAccount.loadData();
// get payer payout wallet // get payer payout wallet
const switchboardMint = await programStateAccount.getTokenMint(); const mint = await programStateAccount.getTokenMint();
const payoutWalletAccountInfo = const payoutTokenAddress = await getOrCreateSwitchboardMintTokenAccount(
await switchboardMint.getOrCreateAssociatedAccountInfo(payer.publicKey); this.program,
mint,
payer
);
const txn = await crankAccount.pop({ const txn = await crankAccount.pop({
payoutWallet: payoutWalletAccountInfo.address, payoutWallet: payoutTokenAddress,
queuePubkey: queueAccount.publicKey, queuePubkey: queueAccount.publicKey,
queueAuthority: queue.authority, queueAuthority: queue.authority,
crank: 0, crank: 0,

View File

@ -1,7 +1,10 @@
import { Flags } from "@oclif/core"; import { Flags } from "@oclif/core";
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { prettyPrintLease } from "@switchboard-xyz/sbv2-utils"; import {
getOrCreateSwitchboardMintTokenAccount,
prettyPrintLease,
} from "@switchboard-xyz/sbv2-utils";
import { import {
AggregatorAccount, AggregatorAccount,
LeaseAccount, LeaseAccount,
@ -66,11 +69,15 @@ export default class LeaseCreate extends BaseCommand {
const mint = await oracleQueueAccount.loadMint(); const mint = await oracleQueueAccount.loadMint();
// check funder has enough balance for the request // check funder has enough balance for the request
const funder = ( const funderTokenAddress = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo(payer.publicKey) this.program,
).address; mint,
payer
);
const funderBalanceResponse = const funderBalanceResponse =
await this.program.provider.connection.getTokenAccountBalance(funder); await this.program.provider.connection.getTokenAccountBalance(
funderTokenAddress
);
const funderBalance = new anchor.BN(funderBalanceResponse.value.amount); const funderBalance = new anchor.BN(funderBalanceResponse.value.amount);
if (loadAmount.gt(funderBalance)) { if (loadAmount.gt(funderBalance)) {
throw new Error( throw new Error(
@ -99,7 +106,7 @@ export default class LeaseCreate extends BaseCommand {
oracleQueueAccount, oracleQueueAccount,
funderAuthority: payer, funderAuthority: payer,
withdrawAuthority: payer.publicKey, withdrawAuthority: payer.publicKey,
funder, funder: funderTokenAddress,
loadAmount, loadAmount,
}); });

View File

@ -3,6 +3,7 @@ import * as anchor from "@project-serum/anchor";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { import {
chalkString, chalkString,
getOrCreateSwitchboardMintTokenAccount,
verifyProgramHasPayer, verifyProgramHasPayer,
} from "@switchboard-xyz/sbv2-utils"; } from "@switchboard-xyz/sbv2-utils";
import { import {
@ -81,12 +82,13 @@ export default class LeaseExtend extends BaseCommand {
const initialLeaseBalance = const initialLeaseBalance =
await this.program.provider.connection.getTokenAccountBalance(escrow); await this.program.provider.connection.getTokenAccountBalance(escrow);
const funderTokenAccount = ( const funderTokenAddress = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo(payerKeypair.publicKey) this.program,
).address; mint
);
const initialFunderBalance = const initialFunderBalance =
await this.program.provider.connection.getTokenAccountBalance( await this.program.provider.connection.getTokenAccountBalance(
funderTokenAccount funderTokenAddress
); );
if (!this.silent) { if (!this.silent) {
@ -108,7 +110,7 @@ export default class LeaseExtend extends BaseCommand {
const txn = await leaseAccount.extend({ const txn = await leaseAccount.extend({
loadAmount: amount, loadAmount: amount,
funder: funderTokenAccount, funder: funderTokenAddress,
funderAuthority: payerKeypair, funderAuthority: payerKeypair,
}); });

View File

@ -3,13 +3,13 @@ import * as anchor from "@project-serum/anchor";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { import {
chalkString, chalkString,
getOrCreateSwitchboardMintTokenAccount,
verifyProgramHasPayer, verifyProgramHasPayer,
} from "@switchboard-xyz/sbv2-utils"; } from "@switchboard-xyz/sbv2-utils";
import { import {
AggregatorAccount, AggregatorAccount,
LeaseAccount, LeaseAccount,
OracleQueueAccount, OracleQueueAccount,
programWallet,
} from "@switchboard-xyz/switchboard-v2"; } from "@switchboard-xyz/switchboard-v2";
import chalk from "chalk"; import chalk from "chalk";
import BaseCommand from "../../BaseCommand"; import BaseCommand from "../../BaseCommand";
@ -82,11 +82,11 @@ export default class AggregatorLeaseWithdraw extends BaseCommand {
} catch { } catch {
try { try {
const withdrawKeypair = await loadKeypair(flags.withdrawAddress); const withdrawKeypair = await loadKeypair(flags.withdrawAddress);
withdrawAddress = ( withdrawAddress = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo( this.program,
withdrawKeypair.publicKey mint,
) withdrawKeypair
).address; );
} catch { } catch {
throw new Error( throw new Error(
`failed to parse withdrawAccount flag ${flags.withdrawAddress}` `failed to parse withdrawAccount flag ${flags.withdrawAddress}`
@ -94,11 +94,10 @@ export default class AggregatorLeaseWithdraw extends BaseCommand {
} }
} }
} else { } else {
withdrawAddress = ( withdrawAddress = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo( this.program,
programWallet(this.program).publicKey mint
) );
).address;
} }
const [leaseAccount] = LeaseAccount.fromSeed( const [leaseAccount] = LeaseAccount.fromSeed(

View File

@ -82,7 +82,7 @@ export default class OracleCreate extends BaseCommand {
publicKey: new PublicKey(args.queueKey), publicKey: new PublicKey(args.queueKey),
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed( const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed(
this.program this.program
@ -118,11 +118,11 @@ export default class OracleCreate extends BaseCommand {
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
tokenWalletKeypair.publicKey, tokenWalletKeypair.publicKey,
programStateAccount.publicKey mint.address,
programStateAccount.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await this.program.methods await this.program.methods
.oracleInit({ .oracleInit({

View File

@ -1,7 +1,11 @@
import { Flags } from "@oclif/core"; import { Flags } from "@oclif/core";
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import * as spl from "@solana/spl-token";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { chalkString } from "@switchboard-xyz/sbv2-utils"; import {
chalkString,
getOrCreateSwitchboardMintTokenAccount,
} from "@switchboard-xyz/sbv2-utils";
import { import {
OracleAccount, OracleAccount,
OracleQueueAccount, OracleQueueAccount,
@ -68,14 +72,15 @@ export default class OracleDeposit extends BaseCommand {
).value.amount ).value.amount
); );
const funderTokenAccount = ( const funderTokenAddress = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo(payer.publicKey) this.program,
).address; mint
);
const funderTokenBalance = new anchor.BN( const funderTokenBalance = new anchor.BN(
( (
await this.program.provider.connection.getTokenAccountBalance( await this.program.provider.connection.getTokenAccountBalance(
funderTokenAccount funderTokenAddress
) )
).value.amount ).value.amount
); );
@ -86,12 +91,17 @@ export default class OracleDeposit extends BaseCommand {
); );
} }
const txn = await mint.transfer( const txn = await spl.transfer(
funderTokenAccount, this.program.provider.connection,
payer,
funderTokenAddress,
oracle.tokenAccount, oracle.tokenAccount,
payer, payer,
[],
amount.toNumber() amount.toNumber(),
undefined,
undefined,
spl.TOKEN_PROGRAM_ID
); );
if (this.silent) { if (this.silent) {

View File

@ -1,7 +1,10 @@
import { Flags } from "@oclif/core"; import { Flags } from "@oclif/core";
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import { PublicKey } from "@solana/web3.js"; import { PublicKey } from "@solana/web3.js";
import { chalkString } from "@switchboard-xyz/sbv2-utils"; import {
chalkString,
getOrCreateSwitchboardMintTokenAccount,
} from "@switchboard-xyz/sbv2-utils";
import { import {
OracleAccount, OracleAccount,
OracleQueueAccount, OracleQueueAccount,
@ -119,11 +122,11 @@ export default class OracleWithdraw extends BaseCommand {
} catch { } catch {
try { try {
const withdrawKeypair = await loadKeypair(flags.withdrawAccount); const withdrawKeypair = await loadKeypair(flags.withdrawAccount);
withdrawAccount = ( withdrawAccount = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo( this.program,
withdrawKeypair.publicKey mint,
) withdrawKeypair
).address; );
} catch { } catch {
throw new Error( throw new Error(
`failed to parse withdrawAccount flag ${flags.withdrawAccount}` `failed to parse withdrawAccount flag ${flags.withdrawAccount}`
@ -131,11 +134,10 @@ export default class OracleWithdraw extends BaseCommand {
} }
} }
} else { } else {
withdrawAccount = ( withdrawAccount = await getOrCreateSwitchboardMintTokenAccount(
await mint.getOrCreateAssociatedAccountInfo( this.program,
programWallet(this.program).publicKey mint
) );
).address;
} }
const txn = await oracleAccount.withdraw({ const txn = await oracleAccount.withdraw({

View File

@ -17,7 +17,9 @@ export default class ProgramPrint extends BaseCommand {
async run() { async run() {
const [programState] = ProgramStateAccount.fromSeed(this.program); const [programState] = ProgramStateAccount.fromSeed(this.program);
this.logger.log(await prettyPrintProgramState(programState)); this.logger.log(
await prettyPrintProgramState(programState, undefined, true, true)
);
} }
async catch(error) { async catch(error) {

View File

@ -124,11 +124,12 @@ export default class QueueCreate extends BaseCommand {
const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed( const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed(
this.program this.program
); );
const tokenMint = new spl.Token(
const mint = await spl.getMint(
this.program.provider.connection, this.program.provider.connection,
spl.NATIVE_MINT, spl.NATIVE_MINT,
spl.TOKEN_PROGRAM_ID, undefined,
payerKeypair spl.TOKEN_PROGRAM_ID
); );
const createQueueTxns: ( const createQueueTxns: (
@ -152,11 +153,11 @@ export default class QueueCreate extends BaseCommand {
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
vaultKeypair.publicKey, vaultKeypair.publicKey,
payerKeypair.publicKey mint.address,
payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await this.program.methods await this.program.methods
.programInit({ .programInit({
@ -165,12 +166,12 @@ export default class QueueCreate extends BaseCommand {
.accounts({ .accounts({
state: programStateAccount.publicKey, state: programStateAccount.publicKey,
authority: payerKeypair.publicKey, authority: payerKeypair.publicKey,
tokenMint: tokenMint.publicKey, tokenMint: mint.address,
vault: vaultKeypair.publicKey, vault: vaultKeypair.publicKey,
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
tokenProgram: spl.TOKEN_PROGRAM_ID, tokenProgram: spl.TOKEN_PROGRAM_ID,
daoMint: tokenMint.publicKey, daoMint: mint.address,
}) })
.instruction(), .instruction(),
]); ]);
@ -227,7 +228,7 @@ export default class QueueCreate extends BaseCommand {
buffer: queueBuffer.publicKey, buffer: queueBuffer.publicKey,
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
mint: tokenMint.publicKey, mint: mint.address,
}) })
.instruction() .instruction()
); );
@ -320,11 +321,11 @@ export default class QueueCreate extends BaseCommand {
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
tokenWalletKeypair.publicKey, tokenWalletKeypair.publicKey,
programStateAccount.publicKey mint.address,
programStateAccount.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await this.program.methods await this.program.methods
.oracleInit({ .oracleInit({

View File

@ -1,8 +1,6 @@
/* eslint-disable new-cap */
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
import { import {
AccountInfo,
LAMPORTS_PER_SOL, LAMPORTS_PER_SOL,
NONCE_ACCOUNT_LENGTH, NONCE_ACCOUNT_LENGTH,
PublicKey, PublicKey,
@ -65,7 +63,7 @@ export default class TestCommand extends BaseCommand {
publicKey: oracle.queuePubkey, publicKey: oracle.queuePubkey,
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const [programState, stateBump] = ProgramStateAccount.fromSeed( const [programState, stateBump] = ProgramStateAccount.fromSeed(
oracleAccount.program oracleAccount.program
); );
@ -75,7 +73,7 @@ export default class TestCommand extends BaseCommand {
queueAccount.publicKey, queueAccount.publicKey,
oracleAccount.publicKey oracleAccount.publicKey
); );
const balanceNeeded = await spl.Token.getMinBalanceRentForExemptAccount( const balanceNeeded = await spl.getMinimumBalanceForRentExemptAccount(
oracleAccount.program.provider.connection oracleAccount.program.provider.connection
); );
@ -189,11 +187,11 @@ export default class TestCommand extends BaseCommand {
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
spl.NATIVE_MINT,
newAccount.publicKey, newAccount.publicKey,
oracleAuthority.publicKey mint.address,
oracleAuthority.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await oracleAccount.program.methods await oracleAccount.program.methods
.oracleWithdraw({ .oracleWithdraw({
@ -214,12 +212,12 @@ export default class TestCommand extends BaseCommand {
payer: oracleAuthority.publicKey, payer: oracleAuthority.publicKey,
}) })
.instruction(), .instruction(),
spl.Token.createCloseAccountInstruction( spl.createCloseAccountInstruction(
spl.TOKEN_PROGRAM_ID,
newAccount.publicKey, newAccount.publicKey,
oracleAuthority.publicKey, oracleAuthority.publicKey,
oracleAuthority.publicKey, oracleAuthority.publicKey,
[newAccount] [newAccount],
spl.TOKEN_PROGRAM_ID
) )
); );
@ -243,55 +241,3 @@ export default class TestCommand extends BaseCommand {
super.catch(error, "test command failed"); super.catch(error, "test command failed");
} }
} }
function decodeTokenAccount(
info: AccountInfo<Buffer>,
pubkey: PublicKey
): spl.AccountInfo {
if (info === null) {
throw new Error("FAILED_TO_FIND_ACCOUNT");
}
if (!info.owner.equals(spl.TOKEN_PROGRAM_ID)) {
throw new Error("INVALID_ACCOUNT_OWNER");
}
if (info.data.length !== spl.AccountLayout.span) {
throw new Error(`Invalid account size`);
}
const data = Buffer.from(info.data);
const accountInfo = spl.AccountLayout.decode(data);
accountInfo.address = pubkey;
accountInfo.mint = new PublicKey(accountInfo.mint);
accountInfo.owner = new PublicKey(accountInfo.owner);
accountInfo.amount = spl.u64.fromBuffer(accountInfo.amount);
if (accountInfo.delegateOption === 0) {
accountInfo.delegate = undefined;
accountInfo.delegatedAmount = new spl.u64(0);
} else {
accountInfo.delegate = new PublicKey(accountInfo.delegate);
accountInfo.delegatedAmount = spl.u64.fromBuffer(
accountInfo.delegatedAmount
);
}
accountInfo.isInitialized = accountInfo.state !== 0;
accountInfo.isFrozen = accountInfo.state === 2;
if (accountInfo.isNativeOption === 1) {
accountInfo.rentExemptReserve = spl.u64.fromBuffer(accountInfo.isNative);
accountInfo.isNative = true;
} else {
accountInfo.rentExemptReserve = undefined;
accountInfo.isNative = false;
}
accountInfo.closeAuthority =
accountInfo.closeAuthorityOption === 0
? undefined
: new PublicKey(accountInfo.closeAuthority);
return accountInfo;
}

View File

@ -116,14 +116,15 @@ export default class VrfCreateExample extends BaseCommand {
publicKey: new PublicKey(args.queueKey), publicKey: new PublicKey(args.queueKey),
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const vrfEscrowPubkey = await spl.Token.getAssociatedTokenAddress( const vrfEscrowPubkey = await spl.getAssociatedTokenAddress(
tokenMint.associatedProgramId, mint.address,
tokenMint.programId,
tokenMint.publicKey,
vrfSecret.publicKey, vrfSecret.publicKey,
true true,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed( const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program, this.program,
queue.authority, queue.authority,
@ -134,21 +135,21 @@ export default class VrfCreateExample extends BaseCommand {
// create account txns // create account txns
const createTxn = new Transaction(); const createTxn = new Transaction();
createTxn.add( createTxn.add(
spl.Token.createAssociatedTokenAccountInstruction( spl.createAssociatedTokenAccountInstruction(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
vrfEscrowPubkey, vrfEscrowPubkey,
vrfSecret.publicKey, vrfSecret.publicKey,
payerKeypair.publicKey mint.address,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
), ),
spl.Token.createSetAuthorityInstruction( spl.createSetAuthorityInstruction(
spl.TOKEN_PROGRAM_ID,
vrfEscrowPubkey, vrfEscrowPubkey,
programStateAccount.publicKey,
"AccountOwner",
vrfSecret.publicKey, vrfSecret.publicKey,
[payerKeypair, vrfSecret] spl.AuthorityType.AccountOwner,
programStateAccount.publicKey,
[payerKeypair, vrfSecret],
spl.TOKEN_PROGRAM_ID
), ),
SystemProgram.createAccount({ SystemProgram.createAccount({
fromPubkey: payerKeypair.publicKey, fromPubkey: payerKeypair.publicKey,

View File

@ -132,13 +132,13 @@ export default class VrfCreate extends BaseCommand {
publicKey: new PublicKey(args.queueKey), publicKey: new PublicKey(args.queueKey),
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const vrfEscrowPubkey = await spl.Token.getAssociatedTokenAddress( const vrfEscrowPubkey = await spl.getAssociatedTokenAddress(
tokenMint.associatedProgramId, mint.address,
tokenMint.programId,
tokenMint.publicKey,
vrfSecret.publicKey, vrfSecret.publicKey,
true true,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
const [permissionAccount, permissionBump] = PermissionAccount.fromSeed( const [permissionAccount, permissionBump] = PermissionAccount.fromSeed(
this.program, this.program,
@ -150,21 +150,21 @@ export default class VrfCreate extends BaseCommand {
// create account txns // create account txns
const createTxn = new Transaction(); const createTxn = new Transaction();
createTxn.add( createTxn.add(
spl.Token.createAssociatedTokenAccountInstruction( spl.createAssociatedTokenAccountInstruction(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
vrfEscrowPubkey, vrfEscrowPubkey,
vrfSecret.publicKey, vrfSecret.publicKey,
payerKeypair.publicKey mint.address,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
), ),
spl.Token.createSetAuthorityInstruction( spl.createSetAuthorityInstruction(
spl.TOKEN_PROGRAM_ID,
vrfEscrowPubkey, vrfEscrowPubkey,
programStateAccount.publicKey,
"AccountOwner",
vrfSecret.publicKey, vrfSecret.publicKey,
[payerKeypair, vrfSecret] spl.AuthorityType.AccountOwner,
programStateAccount.publicKey,
[payerKeypair, vrfSecret],
spl.TOKEN_PROGRAM_ID
), ),
SystemProgram.createAccount({ SystemProgram.createAccount({
fromPubkey: payerKeypair.publicKey, fromPubkey: payerKeypair.publicKey,

View File

@ -1,6 +1,7 @@
import { Flags } from "@oclif/core"; import { Flags } from "@oclif/core";
import * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
import { PublicKey, SYSVAR_RECENT_BLOCKHASHES_PUBKEY } from "@solana/web3.js"; import { PublicKey, SYSVAR_RECENT_BLOCKHASHES_PUBKEY } from "@solana/web3.js";
import { getOrCreateSwitchboardMintTokenAccount } from "@switchboard-xyz/sbv2-utils";
import { import {
OracleQueueAccount, OracleQueueAccount,
PermissionAccount, PermissionAccount,
@ -51,7 +52,7 @@ export default class VrfRequest extends BaseCommand {
publicKey: vrf.oracleQueue, publicKey: vrf.oracleQueue,
}); });
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const tokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed( const [programStateAccount, stateBump] = ProgramStateAccount.fromSeed(
this.program this.program
); );
@ -67,11 +68,10 @@ export default class VrfRequest extends BaseCommand {
? await loadKeypair(flags.funderAuthority) ? await loadKeypair(flags.funderAuthority)
: payerKeypair; : payerKeypair;
const funderTokenWallet = ( const funderTokenWallet = await getOrCreateSwitchboardMintTokenAccount(
await tokenMint.getOrCreateAssociatedAccountInfo( this.program,
funderAuthority.publicKey mint
) );
).address;
// const signature = await vrfAccount.requestRandomness({ // const signature = await vrfAccount.requestRandomness({
// authority, // authority,

View File

@ -3,6 +3,5 @@ export * from "./icons";
export * from "./keypair"; export * from "./keypair";
export * from "./misc"; export * from "./misc";
export * from "./sleep"; export * from "./sleep";
export * from "./state";
export * from "./switchboard"; export * from "./switchboard";
export * from "./toCluster"; export * from "./toCluster";

View File

@ -1,36 +0,0 @@
import type * as anchor from "@project-serum/anchor";
import type * as spl from "@solana/spl-token";
import type { PublicKey } from "@solana/web3.js";
import {
ProgramStateAccount,
programWallet,
} from "@switchboard-xyz/switchboard-v2";
export const getOrCreateSwitchboardMintTokenAccount = async (
program: anchor.Program,
switchboardMint?: spl.Token
): Promise<PublicKey> => {
const payer = programWallet(program);
const returnAssociatedAddress = async (
mint: spl.Token
): Promise<PublicKey> => {
const tokenAccount = await mint.getOrCreateAssociatedAccountInfo(
payer.publicKey
);
return tokenAccount.address;
};
let mint = switchboardMint;
if (mint) {
returnAssociatedAddress(mint);
}
const [programState] = ProgramStateAccount.fromSeed(program);
mint = await programState.getTokenMint();
if (mint) {
returnAssociatedAddress(mint);
}
throw new Error(`failed to get associated token account`);
};

View File

@ -9,7 +9,13 @@
"target": "es2019", "target": "es2019",
"esModuleInterop": true, "esModuleInterop": true,
"skipLibCheck": true, "skipLibCheck": true,
"strictPropertyInitialization": false "strictPropertyInitialization": false,
"paths": {
"@solana/spl-token": [
"../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
}
}, },
"files": ["src/index.ts"], "files": ["src/index.ts"],
"include": ["src/**/*"] "include": ["src/**/*"]

View File

@ -3,7 +3,11 @@
"compilerOptions": { "compilerOptions": {
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../libraries/ts"], "@switchboard-xyz/switchboard-v2": ["../libraries/ts"],
"@switchboard-xyz/sbv2-utils": ["../libraries/sbv2-utils"] "@switchboard-xyz/sbv2-utils": ["../libraries/sbv2-utils"],
"@solana/spl-token": [
"../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
} }
}, },
"references": [ "references": [

View File

@ -36,7 +36,7 @@
"@orca-so/sdk": "^1.2.24", "@orca-so/sdk": "^1.2.24",
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@saberhq/token-utils": "^1.12.68", "@saberhq/token-utils": "^1.12.68",
"@solana/spl-token": "^0.1.8", "@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.42.0", "@solana/web3.js": "^1.42.0",
"@switchboard-xyz/switchboard-v2": "^0.0.114", "@switchboard-xyz/switchboard-v2": "^0.0.114",
"big.js": "^6.1.1", "big.js": "^6.1.1",

View File

@ -2,6 +2,7 @@ import * as anchor from "@project-serum/anchor";
import * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
import { import {
PublicKey, PublicKey,
sendAndConfirmTransaction,
SystemProgram, SystemProgram,
Transaction, Transaction,
TransactionInstruction, TransactionInstruction,
@ -85,17 +86,25 @@ export async function createAggregator(
) { ) {
const payerKeypair = programWallet(program); const payerKeypair = programWallet(program);
const queue = await queueAccount.loadData(); const queue = await queueAccount.loadData();
const switchTokenMint = await queueAccount.loadMint(); const mint = await queueAccount.loadMint();
const payerTokenWallet = ( const payerTokenWallet = (
await switchTokenMint.getOrCreateAssociatedAccountInfo( await spl.getOrCreateAssociatedTokenAccount(
payerKeypair.publicKey program.provider.connection,
payerKeypair,
mint.address,
payerKeypair.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
) )
).address; ).address;
// Aggregator params // Aggregator params
const aggregatorKeypair = params.keypair ?? anchor.web3.Keypair.generate(); const aggregatorKeypair = params.keypair ?? anchor.web3.Keypair.generate();
const authority = params.authority ?? payerKeypair.publicKey; const authority = params.authority ?? payerKeypair.publicKey;
const size = program.account.aggregatorAccountData!.size; const size = program.account.aggregatorAccountData.size;
const [programStateAccount, stateBump] = const [programStateAccount, stateBump] =
ProgramStateAccount.fromSeed(program); ProgramStateAccount.fromSeed(program);
const state = await programStateAccount.loadData(); const state = await programStateAccount.loadData();
@ -118,12 +127,12 @@ export async function createAggregator(
queueAccount, queueAccount,
aggregatorAccount aggregatorAccount
); );
const leaseEscrow = await spl.Token.getAssociatedTokenAddress( const leaseEscrow = await spl.getAssociatedTokenAddress(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, mint.address,
spl.TOKEN_PROGRAM_ID,
switchTokenMint.publicKey,
leaseAccount.publicKey, leaseAccount.publicKey,
true true,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
// const jobPubkeys: Array<PublicKey> = []; // const jobPubkeys: Array<PublicKey> = [];
@ -134,7 +143,7 @@ export async function createAggregator(
// [ // [
// payerKeypair.publicKey.toBuffer(), // payerKeypair.publicKey.toBuffer(),
// spl.TOKEN_PROGRAM_ID.toBuffer(), // spl.TOKEN_PROGRAM_ID.toBuffer(),
// switchTokenMint.publicKey.toBuffer(), // mint.address.toBuffer(),
// ], // ],
// spl.ASSOCIATED_TOKEN_PROGRAM_ID // spl.ASSOCIATED_TOKEN_PROGRAM_ID
// ); // );
@ -159,20 +168,21 @@ export async function createAggregator(
programId: program.programId, programId: program.programId,
}), }),
// create aggregator // create aggregator
await program.methods!.aggregatorInit!({ await program.methods
name: (params.name ?? Buffer.from("")).slice(0, 32), .aggregatorInit({
metadata: (params.metadata ?? Buffer.from("")).slice(0, 128), name: (params.name ?? Buffer.from("")).slice(0, 32),
batchSize: params.batchSize, metadata: (params.metadata ?? Buffer.from("")).slice(0, 128),
minOracleResults: params.minRequiredOracleResults, batchSize: params.batchSize,
minJobResults: params.minRequiredJobResults, minOracleResults: params.minRequiredOracleResults,
minUpdateDelaySeconds: params.minUpdateDelaySeconds, minJobResults: params.minRequiredJobResults,
varianceThreshold: SwitchboardDecimal.fromBig( minUpdateDelaySeconds: params.minUpdateDelaySeconds,
new Big(params.varianceThreshold ?? 0) varianceThreshold: SwitchboardDecimal.fromBig(
), new Big(params.varianceThreshold ?? 0)
forceReportPeriod: params.forceReportPeriod ?? new anchor.BN(0), ),
expiration: params.expiration ?? new anchor.BN(0), forceReportPeriod: params.forceReportPeriod ?? new anchor.BN(0),
stateBump, expiration: params.expiration ?? new anchor.BN(0),
}) stateBump,
})
.accounts({ .accounts({
aggregator: aggregatorKeypair.publicKey, aggregator: aggregatorKeypair.publicKey,
authority, authority,
@ -181,7 +191,8 @@ export async function createAggregator(
programState: programStateAccount.publicKey, programState: programStateAccount.publicKey,
}) })
.instruction(), .instruction(),
await program.methods.permissionInit!({}) await program.methods
.permissionInit({})
.accounts({ .accounts({
permission: permissionAccount.publicKey, permission: permissionAccount.publicKey,
authority: params.authority, authority: params.authority,
@ -192,31 +203,33 @@ export async function createAggregator(
}) })
.instruction(), .instruction(),
payerKeypair.publicKey.equals(queue.authority) payerKeypair.publicKey.equals(queue.authority)
? await program.methods.permissionSet!({ ? await program.methods
permission: { permitOracleQueueUsage: null }, .permissionSet({
enable: true, permission: { permitOracleQueueUsage: null },
}) enable: true,
})
.accounts({ .accounts({
permission: permissionAccount.publicKey, permission: permissionAccount.publicKey,
authority: queue.authority, authority: queue.authority,
}) })
.instruction() .instruction()
: undefined, : undefined,
spl.Token.createAssociatedTokenAccountInstruction( spl.createAssociatedTokenAccountInstruction(
spl.ASSOCIATED_TOKEN_PROGRAM_ID, payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID,
switchTokenMint.publicKey,
leaseEscrow, leaseEscrow,
leaseAccount.publicKey, payerKeypair.publicKey,
payerKeypair.publicKey mint.address,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
), ),
await program.methods.leaseInit!({ await program.methods
loadAmount: new anchor.BN(0), .leaseInit({
stateBump, loadAmount: new anchor.BN(0),
leaseBump, stateBump,
withdrawAuthority: payerKeypair.publicKey, leaseBump,
walletBumps: Buffer.from([]), withdrawAuthority: payerKeypair.publicKey,
}) walletBumps: Buffer.from([]),
})
.accounts({ .accounts({
programState: programStateAccount.publicKey, programState: programStateAccount.publicKey,
lease: leaseAccount.publicKey, lease: leaseAccount.publicKey,
@ -228,7 +241,7 @@ export async function createAggregator(
tokenProgram: spl.TOKEN_PROGRAM_ID, tokenProgram: spl.TOKEN_PROGRAM_ID,
escrow: leaseEscrow, escrow: leaseEscrow,
owner: payerKeypair.publicKey, owner: payerKeypair.publicKey,
mint: switchTokenMint.publicKey, mint: mint.address,
}) })
// .remainingAccounts( // .remainingAccounts(
// jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => { // jobPubkeys.concat(jobWallets).map((pubkey: PublicKey) => {
@ -238,9 +251,10 @@ export async function createAggregator(
.instruction(), .instruction(),
...(await Promise.all( ...(await Promise.all(
jobs.map(async ([jobAccount, weight]) => { jobs.map(async ([jobAccount, weight]) => {
return program.methods.aggregatorAddJob!({ return program.methods
weight, .aggregatorAddJob({
}) weight,
})
.accounts({ .accounts({
aggregator: aggregatorKeypair.publicKey, aggregator: aggregatorKeypair.publicKey,
authority: payerKeypair.publicKey, authority: payerKeypair.publicKey,
@ -252,9 +266,11 @@ export async function createAggregator(
].filter(Boolean) as TransactionInstruction[]) ].filter(Boolean) as TransactionInstruction[])
); );
const createSig = await program.provider.sendAndConfirm!( const createSig = await sendAndConfirmTransaction(
program.provider.connection,
new Transaction().add(...createIxns), new Transaction().add(...createIxns),
[payerKeypair, aggregatorKeypair] [payerKeypair, aggregatorKeypair]
); );
return aggregatorAccount; return aggregatorAccount;
} }

View File

@ -17,6 +17,7 @@ import {
} from "@switchboard-xyz/switchboard-v2"; } from "@switchboard-xyz/switchboard-v2";
import type Big from "big.js"; import type Big from "big.js";
import chalk from "chalk"; import chalk from "chalk";
import { getIdlAddress, getProgramDataAddress } from "./anchor.js";
import { anchorBNtoDateTimeString } from "./date.js"; import { anchorBNtoDateTimeString } from "./date.js";
import type { SwitchboardAccountType } from "./switchboard.js"; import type { SwitchboardAccountType } from "./switchboard.js";
@ -100,6 +101,8 @@ export const toVrfStatusString = (status: Record<string, unknown>): string => {
export async function prettyPrintProgramState( export async function prettyPrintProgramState(
programState: ProgramStateAccount, programState: ProgramStateAccount,
accountData?: any, accountData?: any,
printIdlAddress = false,
printDataAddress = false,
SPACING = 24 SPACING = 24
): Promise<string> { ): Promise<string> {
const data = accountData ?? (await programState.loadData()); const data = accountData ?? (await programState.loadData());
@ -110,7 +113,19 @@ export async function prettyPrintProgramState(
); );
outputString += chalkString("authority", data.authority, SPACING) + "\r\n"; outputString += chalkString("authority", data.authority, SPACING) + "\r\n";
outputString += chalkString("tokenMint", data.tokenMint, SPACING) + "\r\n"; outputString += chalkString("tokenMint", data.tokenMint, SPACING) + "\r\n";
outputString += chalkString("tokenVault", data.tokenVault, SPACING); outputString += chalkString("tokenVault", data.tokenVault, SPACING) + "\r\n";
outputString += chalkString("daoMint", data.daoMint, SPACING);
if (printIdlAddress) {
const idlAddress = await getIdlAddress(programState.program.programId);
outputString += "\r\n" + chalkString("idlAddress", idlAddress, SPACING);
}
if (printDataAddress) {
const dataAddress = getProgramDataAddress(programState.program.programId);
outputString +=
"\r\n" + chalkString("programDataAddress", dataAddress, SPACING);
}
return outputString; return outputString;
} }

View File

@ -48,11 +48,11 @@ export async function createQueue(
const [programStateAccount, stateBump] = const [programStateAccount, stateBump] =
ProgramStateAccount.fromSeed(program); ProgramStateAccount.fromSeed(program);
const tokenMint = new spl.Token( const mint = await spl.getMint(
program.provider.connection, program.provider.connection,
spl.NATIVE_MINT, spl.NATIVE_MINT,
spl.TOKEN_PROGRAM_ID, undefined,
payerKeypair spl.TOKEN_PROGRAM_ID
); );
const ixns: (TransactionInstruction | TransactionInstruction[])[] = []; const ixns: (TransactionInstruction | TransactionInstruction[])[] = [];
@ -73,24 +73,25 @@ export async function createQueue(
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
vaultKeypair.publicKey, vaultKeypair.publicKey,
payerKeypair.publicKey mint.address,
payerKeypair.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await program.methods.programInit!({ await program.methods
stateBump, .programInit({
}) stateBump,
})
.accounts({ .accounts({
state: programStateAccount.publicKey, state: programStateAccount.publicKey,
authority: payerKeypair.publicKey, authority: payerKeypair.publicKey,
tokenMint: tokenMint.publicKey, tokenMint: mint.address,
vault: vaultKeypair.publicKey, vault: vaultKeypair.publicKey,
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
tokenProgram: spl.TOKEN_PROGRAM_ID, tokenProgram: spl.TOKEN_PROGRAM_ID,
daoMint: tokenMint.publicKey, daoMint: mint.address,
}) })
.instruction(), .instruction(),
]); ]);
@ -132,32 +133,33 @@ export async function createQueue(
), ),
programId: program.programId, programId: program.programId,
}), }),
await program.methods.oracleQueueInit!({ await program.methods
name: Buffer.from(params.name ?? "").slice(0, 32), .oracleQueueInit({
metadata: Buffer.from("").slice(0, 64), name: Buffer.from(params.name ?? "").slice(0, 32),
reward: params.reward ? new anchor.BN(params.reward) : new anchor.BN(0), metadata: Buffer.from("").slice(0, 64),
minStake: params.minStake reward: params.reward ? new anchor.BN(params.reward) : new anchor.BN(0),
? new anchor.BN(params.minStake) minStake: params.minStake
: new anchor.BN(0), ? new anchor.BN(params.minStake)
// feedProbationPeriod: 0, : new anchor.BN(0),
oracleTimeout: params.oracleTimeout, // feedProbationPeriod: 0,
slashingEnabled: false, oracleTimeout: params.oracleTimeout,
varianceToleranceMultiplier: SwitchboardDecimal.fromBig(new Big(2)), slashingEnabled: false,
authority: authorityKeypair.publicKey, varianceToleranceMultiplier: SwitchboardDecimal.fromBig(new Big(2)),
// consecutiveFeedFailureLimit: new anchor.BN(1000), authority: authorityKeypair.publicKey,
// consecutiveOracleFailureLimit: new anchor.BN(1000), // consecutiveFeedFailureLimit: new anchor.BN(1000),
minimumDelaySeconds: 5, // consecutiveOracleFailureLimit: new anchor.BN(1000),
queueSize: queueSize, minimumDelaySeconds: 5,
unpermissionedFeeds: params.unpermissionedFeeds ?? false, queueSize: queueSize,
unpermissionedVrf: params.unpermissionedVrf ?? false, unpermissionedFeeds: params.unpermissionedFeeds ?? false,
}) unpermissionedVrf: params.unpermissionedVrf ?? false,
})
.accounts({ .accounts({
oracleQueue: queueKeypair.publicKey, oracleQueue: queueKeypair.publicKey,
authority: authorityKeypair.publicKey, authority: authorityKeypair.publicKey,
buffer: queueBuffer.publicKey, buffer: queueBuffer.publicKey,
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
mint: tokenMint.publicKey, mint: mint.address,
}) })
.instruction(), .instruction(),
anchor.web3.SystemProgram.createAccount({ anchor.web3.SystemProgram.createAccount({
@ -170,11 +172,12 @@ export async function createQueue(
), ),
programId: program.programId, programId: program.programId,
}), }),
await program.methods.crankInit!({ await program.methods
name: Buffer.from("Crank").slice(0, 32), .crankInit({
metadata: Buffer.from("").slice(0, 64), name: Buffer.from("Crank").slice(0, 32),
crankSize: params.crankSize, metadata: Buffer.from("").slice(0, 64),
}) crankSize: params.crankSize,
})
.accounts({ .accounts({
crank: crankKeypair.publicKey, crank: crankKeypair.publicKey,
queue: queueKeypair.publicKey, queue: queueKeypair.publicKey,
@ -224,18 +227,19 @@ export async function createQueue(
space: spl.AccountLayout.span, space: spl.AccountLayout.span,
programId: spl.TOKEN_PROGRAM_ID, programId: spl.TOKEN_PROGRAM_ID,
}), }),
spl.Token.createInitAccountInstruction( spl.createInitializeAccountInstruction(
spl.TOKEN_PROGRAM_ID,
tokenMint.publicKey,
tokenWalletKeypair.publicKey, tokenWalletKeypair.publicKey,
programStateAccount.publicKey mint.address,
programStateAccount.publicKey,
spl.TOKEN_PROGRAM_ID
), ),
await program.methods.oracleInit!({ await program.methods
name: Buffer.from(name).slice(0, 32), .oracleInit({
metadata: Buffer.from("").slice(0, 128), name: Buffer.from(name).slice(0, 32),
stateBump, metadata: Buffer.from("").slice(0, 128),
oracleBump, stateBump,
}) oracleBump,
})
.accounts({ .accounts({
oracle: oracleAccount.publicKey, oracle: oracleAccount.publicKey,
oracleAuthority: authorityKeypair.publicKey, oracleAuthority: authorityKeypair.publicKey,
@ -246,7 +250,8 @@ export async function createQueue(
payer: payerKeypair.publicKey, payer: payerKeypair.publicKey,
}) })
.instruction(), .instruction(),
await program.methods.permissionInit!({}) await program.methods
.permissionInit({})
.accounts({ .accounts({
permission: permissionAccount.publicKey, permission: permissionAccount.publicKey,
authority: authorityKeypair.publicKey, authority: authorityKeypair.publicKey,
@ -256,10 +261,11 @@ export async function createQueue(
systemProgram: SystemProgram.programId, systemProgram: SystemProgram.programId,
}) })
.instruction(), .instruction(),
await program.methods.permissionSet!({ await program.methods
permission: { permitOracleHeartbeat: null }, .permissionSet({
enable: true, permission: { permitOracleHeartbeat: null },
}) enable: true,
})
.accounts({ .accounts({
permission: permissionAccount.publicKey, permission: permissionAccount.publicKey,
authority: authorityKeypair.publicKey, authority: authorityKeypair.publicKey,

View File

@ -1,5 +1,5 @@
import type * as anchor from "@project-serum/anchor"; import type * as anchor from "@project-serum/anchor";
import type * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
import type { PublicKey } from "@solana/web3.js"; import type { PublicKey } from "@solana/web3.js";
import { import {
ProgramStateAccount, ProgramStateAccount,
@ -8,15 +8,22 @@ import {
export const getOrCreateSwitchboardMintTokenAccount = async ( export const getOrCreateSwitchboardMintTokenAccount = async (
program: anchor.Program, program: anchor.Program,
switchboardMint?: spl.Token switchboardMint?: spl.Mint,
payer = programWallet(program)
): Promise<PublicKey> => { ): Promise<PublicKey> => {
const payer = programWallet(program);
const returnAssociatedAddress = async ( const returnAssociatedAddress = async (
mint: spl.Token mint: spl.Mint
): Promise<PublicKey> => { ): Promise<PublicKey> => {
const tokenAccount = await mint.getOrCreateAssociatedAccountInfo( const tokenAccount = await spl.getOrCreateAssociatedTokenAccount(
payer.publicKey program.provider.connection,
payer,
mint.address,
payer.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
); );
return tokenAccount.address; return tokenAccount.address;
}; };

View File

@ -11,7 +11,7 @@ import { awaitOpenRound, createAggregator } from "../feed.js";
export interface ISwitchboardTestContext { export interface ISwitchboardTestContext {
program: anchor.Program; program: anchor.Program;
mint: spl.Token; mint: spl.Mint;
payerTokenWallet: PublicKey; payerTokenWallet: PublicKey;
queue: sbv2.OracleQueueAccount; queue: sbv2.OracleQueueAccount;
oracle?: sbv2.OracleAccount; oracle?: sbv2.OracleAccount;
@ -20,7 +20,7 @@ export interface ISwitchboardTestContext {
export class SwitchboardTestContext implements ISwitchboardTestContext { export class SwitchboardTestContext implements ISwitchboardTestContext {
program: anchor.Program; program: anchor.Program;
mint: spl.Token; mint: spl.Mint;
payerTokenWallet: PublicKey; payerTokenWallet: PublicKey;
@ -42,12 +42,14 @@ export class SwitchboardTestContext implements ISwitchboardTestContext {
amount = 1_000_000 amount = 1_000_000
): Promise<PublicKey> { ): Promise<PublicKey> {
const payerKeypair = sbv2.programWallet(program); const payerKeypair = sbv2.programWallet(program);
return spl.Token.createWrappedNativeAccount( return spl.createWrappedNativeAccount(
program.provider.connection, program.provider.connection,
spl.TOKEN_PROGRAM_ID,
payerKeypair.publicKey,
payerKeypair, payerKeypair,
amount payerKeypair.publicKey,
amount,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID
); );
} }
@ -84,7 +86,7 @@ export class SwitchboardTestContext implements ISwitchboardTestContext {
`Failed to load the SBV2 queue for the given cluster, ${error.message}` `Failed to load the SBV2 queue for the given cluster, ${error.message}`
); );
} }
let mint: spl.Token; let mint: spl.Mint;
try { try {
mint = await queue.loadMint(); mint = await queue.loadMint();
} catch (error: any) { } catch (error: any) {
@ -95,7 +97,17 @@ export class SwitchboardTestContext implements ISwitchboardTestContext {
let payerTokenWallet: PublicKey; let payerTokenWallet: PublicKey;
try { try {
payerTokenWallet = ( payerTokenWallet = (
await mint.getOrCreateAssociatedAccountInfo(payerKeypair.publicKey) await spl.getOrCreateAssociatedTokenAccount(
provider.connection,
payerKeypair,
mint.address,
payerKeypair.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
)
).address; ).address;
} catch (error: any) { } catch (error: any) {
throw new Error( throw new Error(

View File

@ -328,11 +328,19 @@ secrets:
programState = await switchboardProgramState.loadData(); programState = await switchboardProgramState.loadData();
} }
const switchboardMint = await switchboardProgramState.getTokenMint(); const mint = await switchboardProgramState.getTokenMint();
const payerSwitchboardWallet = ( const payerSwitchboardWallet = (
await switchboardMint.getOrCreateAssociatedAccountInfo( await spl.getOrCreateAssociatedTokenAccount(
payerKeypair.publicKey connection,
payerKeypair,
mint.address,
payerKeypair.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
) )
).address; ).address;
@ -393,7 +401,7 @@ secrets:
idlAddress, idlAddress,
programState: switchboardProgramState.publicKey, programState: switchboardProgramState.publicKey,
switchboardVault: programState.tokenVault, switchboardVault: programState.tokenVault,
switchboardMint: switchboardMint.publicKey, switchboardMint: mint.address,
tokenWallet: payerSwitchboardWallet, tokenWallet: payerSwitchboardWallet,
queue: queueAccount.publicKey, queue: queueAccount.publicKey,
queueAuthority: queue.authority, queueAuthority: queue.authority,

View File

@ -1,5 +1,6 @@
{ {
"include": ["./src/**/*"], "include": ["./src/**/*"],
"files": ["./src/index.ts"],
"compilerOptions": { "compilerOptions": {
"target": "es2019", "target": "es2019",
"sourceMap": true, "sourceMap": true,
@ -22,7 +23,11 @@
"noImplicitReturns": true, "noImplicitReturns": true,
"strictPropertyInitialization": true, "strictPropertyInitialization": true,
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../ts"] "@switchboard-xyz/switchboard-v2": ["../ts"],
"@solana/spl-token": [
"../../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
} }
}, },
"references": [{ "path": "../ts" }] "references": [{ "path": "../ts" }]

View File

@ -6,6 +6,11 @@
"module": "es2022", "module": "es2022",
"target": "es2019", "target": "es2019",
"outDir": "lib/esm/", "outDir": "lib/esm/",
"rootDir": "./src" "paths": {
"@solana/spl-token": [
"../../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
}
} }
} }

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */ /* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
@ -402,7 +403,7 @@ export class ProgramStateAccount {
let vault = null; let vault = null;
if (params.mint === undefined) { if (params.mint === undefined) {
const decimals = 9; const decimals = 9;
const mint = await spl.createMint( mint = await spl.createMint(
program.provider.connection, program.provider.connection,
payerKeypair, payerKeypair,
payerKeypair.publicKey, payerKeypair.publicKey,
@ -1984,6 +1985,7 @@ export class PermissionAccount {
); );
const psData = await programStateAccount.loadData(); const psData = await programStateAccount.loadData();
// eslint-disable-next-line @typescript-eslint/naming-convention
const [addinState, _] = await PublicKey.findProgramAddress( const [addinState, _] = await PublicKey.findProgramAddress(
[Buffer.from("state")], [Buffer.from("state")],
params.addinProgram.programId params.addinProgram.programId
@ -4107,16 +4109,16 @@ export async function sendAll(
let txs = reqs.map((r: any) => { let txs = reqs.map((r: any) => {
if (r === null || r === undefined) return new Transaction(); if (r === null || r === undefined) return new Transaction();
const tx = r.tx; const tx = r.tx;
let signers = r.signers; let rSigners = r.signers;
if (signers === undefined) { if (rSigners === undefined) {
signers = []; rSigners = [];
} }
tx.feePayer = (provider as anchor.AnchorProvider).wallet.publicKey; tx.feePayer = (provider as anchor.AnchorProvider).wallet.publicKey;
tx.recentBlockhash = blockhash.blockhash; tx.recentBlockhash = blockhash.blockhash;
signers rSigners
.filter((s: any): s is Signer => s !== undefined) .filter((s: any): s is Signer => s !== undefined)
.forEach((kp: any) => { .forEach((kp: any) => {
tx.partialSign(kp); tx.partialSign(kp);
@ -4172,11 +4174,11 @@ export function packInstructions(
currentTransaction.feePayer = feePayer; currentTransaction.feePayer = feePayer;
const encodeLength = (bytes: Array<number>, len: number) => { const encodeLength = (bytes: Array<number>, len: number) => {
let rem_len = len; let remLen = len;
for (;;) { for (;;) {
let elem = rem_len & 0x7f; let elem = remLen & 0x7f;
rem_len >>= 7; remLen >>= 7;
if (rem_len == 0) { if (remLen == 0) {
bytes.push(elem); bytes.push(elem);
break; break;
} else { } else {
@ -4205,7 +4207,7 @@ export function packInstructions(
) { ) {
// If the aggregator transaction fits, it will serialize without error. We can then push it ahead no problem // If the aggregator transaction fits, it will serialize without error. We can then push it ahead no problem
const trimmedInstructions = ixs const trimmedInstructions = ixs
.map(() => currentTransaction.instructions.pop()!) .map(() => currentTransaction.instructions.pop())
.reverse(); .reverse();
// Every serialize adds the instruction signatures as dependencies // Every serialize adds the instruction signatures as dependencies
@ -4277,8 +4279,8 @@ export function signTransactions(
// Get pubkeys of signers needed // Get pubkeys of signers needed
const sigsNeeded = transaction.instructions const sigsNeeded = transaction.instructions
.map((instruction) => { .map((instruction) => {
const signers = instruction.keys.filter((meta) => meta.isSigner); const ixnSigners = instruction.keys.filter((meta) => meta.isSigner);
return signers.map((signer) => signer.pubkey); return ixnSigners.map((signer) => signer.pubkey);
}) })
.flat(); .flat();

View File

@ -13,7 +13,7 @@
"website" "website"
], ],
"scripts": { "scripts": {
"watch": "yarn workspace website start & yarn workspaces run watch", "watch": "yarn workspaces run watch",
"build": "yarn workspaces run build", "build": "yarn workspaces run build",
"build:ts": "yarn workspace @switchboard-xyz/switchboard-v2 build", "build:ts": "yarn workspace @switchboard-xyz/switchboard-v2 build",
"build:cli": "yarn workspace @switchboard-xyz/switchboardv2-cli build", "build:cli": "yarn workspace @switchboard-xyz/switchboardv2-cli build",
@ -35,7 +35,7 @@
"docs:deploy": "yarn workspace website deploy", "docs:deploy": "yarn workspace website deploy",
"gen:idl": "rawrtools gen:anchor SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f -o website/idl -p /idl", "gen:idl": "rawrtools gen:anchor SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f -o website/idl -p /idl",
"gen:idl:devnet": "rawrtools gen:anchor --devnet 2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG -o website/idl -p /idl", "gen:idl:devnet": "rawrtools gen:anchor --devnet 2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG -o website/idl -p /idl",
"nuke": "shx rm -rf {./programs/*,./packages/*,./website,./libraries/*,.}/{node_modules,yarn*.log,build,dist,lib,.anchor,target,Cargo.lock,.docusaurus}" "nuke": "shx rm -rf {./programs/*,./packages/*,./website,./libraries/*,.}/{node_modules,yarn*.log,build,dist,lib,.anchor,Cargo.lock,.docusaurus}"
}, },
"devDependencies": { "devDependencies": {
"@gallynaut/rawrtools": "^0.0.1", "@gallynaut/rawrtools": "^0.0.1",
@ -45,9 +45,9 @@
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"shelljs": "^0.8.5", "shelljs": "^0.8.5",
"shx": "^0.3.4", "shx": "^0.3.4",
"ts-node": "^10.7.0", "ts-node": "^10.8.0",
"typedoc": "^0.22.15", "typedoc": "^0.22.15",
"typescript": "^4.6.3" "typescript": "^4.7.3"
}, },
"engines": { "engines": {
"node": ">=16", "node": ">=16",

View File

@ -28,7 +28,7 @@
"dependencies": { "dependencies": {
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/web3.js": "^1.33.0", "@solana/web3.js": "^1.33.0",
"@switchboard-xyz/switchboard-v2": "^0.0.112", "@switchboard-xyz/switchboard-v2": "^0.0.114",
"big.js": "^6.1.1" "big.js": "^6.1.1"
} }
} }

View File

@ -20,7 +20,7 @@
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/spl-token": "^0.2.0", "@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.37.1", "@solana/web3.js": "^1.37.1",
"@switchboard-xyz/switchboard-v2": "^0.0.112", "@switchboard-xyz/switchboard-v2": "^0.0.114",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",
"readline-sync": "^1.4.10" "readline-sync": "^1.4.10"

View File

@ -71,11 +71,11 @@ async function main() {
// Program State Account and token mint for payout rewards // Program State Account and token mint for payout rewards
const [programStateAccount] = ProgramStateAccount.fromSeed(program); const [programStateAccount] = ProgramStateAccount.fromSeed(program);
console.log(toAccountString("Program State", programStateAccount.publicKey)); console.log(toAccountString("Program State", programStateAccount.publicKey));
const switchTokenMint = await programStateAccount.getTokenMint(); const mint = await programStateAccount.getTokenMint();
const tokenAccount = await spl.createAccount( const tokenAccount = await spl.createAccount(
program.provider.connection, program.provider.connection,
programWallet(program), programWallet(program),
switchTokenMint.address, mint.address,
authority.publicKey, authority.publicKey,
Keypair.generate() Keypair.generate()
); );
@ -225,7 +225,7 @@ async function main() {
nonce: 0, nonce: 0,
crank, crank,
queue, queue,
tokenMint: switchTokenMint.address, tokenMint: mint.address,
}); });
console.log(chalk.green("\u2714 Crank turned")); console.log(chalk.green("\u2714 Crank turned"));
return 0; return 0;

View File

@ -4,7 +4,11 @@
"outDir": "dist", "outDir": "dist",
"rootDir": "src", "rootDir": "src",
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../../libraries/ts"] "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"],
"@solana/spl-token": [
"../../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
} }
}, },
"include": ["src/**/*"], "include": ["src/**/*"],

View File

@ -18,7 +18,7 @@
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/web3.js": "1.33.0", "@solana/web3.js": "1.33.0",
"@switchboard-xyz/sbv2-utils": "^0.1.19", "@switchboard-xyz/sbv2-utils": "^0.1.19",
"@switchboard-xyz/switchboard-v2": "^0.0.112", "@switchboard-xyz/switchboard-v2": "^0.0.114",
"dotenv": "^16.0.0", "dotenv": "^16.0.0",
"node-pagerduty": "^1.3.6" "node-pagerduty": "^1.3.6"
}, },

View File

@ -20,7 +20,11 @@
"strict": false, "strict": false,
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../../libraries/ts"], "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"],
"@switchboard-xyz/sbv2-utils": ["../../libraries/sbv2-utils"] "@switchboard-xyz/sbv2-utils": ["../../libraries/sbv2-utils"],
"@solana/spl-token": [
"../../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
} }
}, },
"include": ["src/**/*"], "include": ["src/**/*"],

View File

@ -2,7 +2,7 @@ import { PublicKey } from "@solana/web3.js"
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten. // Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
export const PROGRAM_ID_CLI = new PublicKey( export const PROGRAM_ID_CLI = new PublicKey(
"7Th37Bvb7u2sS4Xe6YkvCkHSHDAakRUeobRBNXuf2PFD" "FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh"
) )
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value. // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.

View File

@ -14,8 +14,8 @@
"dependencies": { "dependencies": {
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/web3.js": "^1.42.0", "@solana/web3.js": "^1.42.0",
"@switchboard-xyz/sbv2-utils": "^0.1.22", "@switchboard-xyz/sbv2-utils": "^0.1.25",
"@switchboard-xyz/switchboard-v2": "^0.0.112" "@switchboard-xyz/switchboard-v2": "^0.0.114"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",

View File

@ -3,7 +3,7 @@ use anchor_lang::prelude::*;
use std::convert::TryInto; use std::convert::TryInto;
pub use switchboard_v2::AggregatorAccountData; pub use switchboard_v2::AggregatorAccountData;
declare_id!("7Th37Bvb7u2sS4Xe6YkvCkHSHDAakRUeobRBNXuf2PFD"); declare_id!("FnsPs665aBSwJRu2A8wGv6ZT76ipR41kHm4hoA3B1QGh");
#[derive(Accounts)] #[derive(Accounts)]
pub struct ReadResult<'info> { pub struct ReadResult<'info> {

View File

@ -3,14 +3,17 @@
"compilerOptions": { "compilerOptions": {
"types": ["mocha", "chai"], "types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"], "typeRoots": ["./node_modules/@types"],
"lib": ["es2015"], "module": "CommonJS",
"module": "commonjs",
"target": "es6",
"noEmit": true, "noEmit": true,
"esModuleInterop": true, "esModuleInterop": true,
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../../libraries/ts"] "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"]
} }
}, },
"include": [
"tests/**/*",
"client/**/*",
"../../target/types/anchor_feed_parser"
],
"references": [{ "path": "../../libraries/ts" }] "references": [{ "path": "../../libraries/ts" }]
} }

View File

@ -2,7 +2,7 @@ import { PublicKey } from "@solana/web3.js"
// Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten. // Program ID passed with the cli --program-id flag when running the code generator. Do not edit, it will get overwritten.
export const PROGRAM_ID_CLI = new PublicKey( export const PROGRAM_ID_CLI = new PublicKey(
"GCam9zJ6soszC4K69Gy84krGdeALxwS2noeBwqLmP6JH" "HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM"
) )
// This constant will not get overwritten on subsequent code generations and it's safe to modify it's value. // This constant will not get overwritten on subsequent code generations and it's safe to modify it's value.

View File

@ -1,19 +0,0 @@
version: "3.3"
services:
switchboard:
build:
context: ../../../switchboard-oracle-v2
network_mode: host
restart: always
secrets:
- PAYER_SECRETS
environment:
- VERBOSE=1
- LIVE=1
- CLUSTER=localnet
- HEARTBEAT_INTERVAL=15 # Seconds
- ORACLE_KEY=DFJ2DyRCb7BfsMKnVag8qS4YFC6LvtGPCJzRJAYg3h2c
# - RPC_URL=${RPC_URL?err}
secrets:
PAYER_SECRETS:
file: secrets/payer-keypair.json

View File

@ -13,10 +13,10 @@
}, },
"dependencies": { "dependencies": {
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/spl-token": "^0.1.8", "@solana/spl-token": "^0.2.0",
"@solana/web3.js": "^1.42.0", "@solana/web3.js": "^1.42.0",
"@switchboard-xyz/sbv2-utils": "^0.1.22", "@switchboard-xyz/sbv2-utils": "^0.1.25",
"@switchboard-xyz/switchboard-v2": "^0.0.112", "@switchboard-xyz/switchboard-v2": "^0.0.114",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"child_process": "^1.0.2", "child_process": "^1.0.2",
"dotenv": "^16.0.0" "dotenv": "^16.0.0"

View File

@ -4,7 +4,7 @@ pub use actions::*;
pub use anchor_lang::prelude::*; pub use anchor_lang::prelude::*;
use anchor_spl::token::TokenAccount; use anchor_spl::token::TokenAccount;
declare_id!("GCam9zJ6soszC4K69Gy84krGdeALxwS2noeBwqLmP6JH"); declare_id!("HjjRFjCyQH3ne6Gg8Yn3TQafrrYecRrphwLwnh2A26vM");
const MAX_RESULT: u64 = u64::MAX; const MAX_RESULT: u64 = u64::MAX;

View File

@ -1,9 +1,9 @@
import * as anchor from "@project-serum/anchor"; import * as anchor from "@project-serum/anchor";
import type NodeWallet from "@project-serum/anchor/dist/cjs/nodewallet";
import * as spl from "@solana/spl-token"; import * as spl from "@solana/spl-token";
import { import {
AccountInfo, AccountInfo,
Context, Context,
Keypair,
PublicKey, PublicKey,
SystemProgram, SystemProgram,
SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
@ -13,17 +13,18 @@ import {
SwitchboardTestContext, SwitchboardTestContext,
} from "@switchboard-xyz/sbv2-utils"; } from "@switchboard-xyz/sbv2-utils";
import { import {
AnchorWallet,
Callback, Callback,
PermissionAccount, PermissionAccount,
ProgramStateAccount, ProgramStateAccount,
SwitchboardPermission, SwitchboardPermission,
VrfAccount, VrfAccount,
} from "@switchboard-xyz/switchboard-v2"; } from "@switchboard-xyz/switchboard-v2";
import chai from "chai"; import fs from "fs";
import "mocha"; import "mocha";
import type { AnchorVrfParser } from "../../../target/types/anchor_vrf_parser"; import path from "path";
import { IDL } from "../../../target/types/anchor_vrf_parser";
const expect = chai.expect; // const expect = chai.expect;
interface VrfClientState { interface VrfClientState {
bump: number; bump: number;
@ -35,13 +36,38 @@ interface VrfClientState {
vrf: PublicKey; vrf: PublicKey;
} }
describe("anchor-vrf-parser test", async () => { function getProgramId(): PublicKey {
anchor.setProvider(anchor.AnchorProvider.env()); const programKeypairPath = path.join(
__dirname,
"..",
"..",
"..",
"target",
"deploy",
"anchor_vrf_parser-keypair.json"
);
const PROGRAM_ID = Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync(programKeypairPath, "utf8")))
).publicKey;
const vrfClientProgram = anchor.workspace return PROGRAM_ID;
.AnchorVrfParser as anchor.Program<AnchorVrfParser>; }
const provider = vrfClientProgram.provider as anchor.AnchorProvider;
const payer = (provider.wallet as NodeWallet).payer; describe("anchor-vrf-parser test", () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
// const vrfClientProgram = anchor.workspace
// .AnchorVrfParser as Program<AnchorVrfParser>;
const vrfClientProgram = new anchor.Program(
IDL,
getProgramId(),
provider,
new anchor.BorshCoder(IDL)
);
// as anchor.Program<AnchorVrfParser>;
const payer = (provider.wallet as AnchorWallet).payer;
let switchboard: SwitchboardTestContext; let switchboard: SwitchboardTestContext;
@ -133,20 +159,18 @@ describe("anchor-vrf-parser test", async () => {
} }
// Create VRF Client account // Create VRF Client account
await vrfClientProgram.rpc.initState( await vrfClientProgram.methods
{ .initState({
maxResult: new anchor.BN(1), maxResult: new anchor.BN(1),
}, })
{ .accounts({
accounts: { state: vrfClientKey,
state: vrfClientKey, vrf: vrfAccount.publicKey,
vrf: vrfAccount.publicKey, payer: payer.publicKey,
payer: payer.publicKey, authority: payer.publicKey,
authority: payer.publicKey, systemProgram: SystemProgram.programId,
systemProgram: SystemProgram.programId, })
}, .rpc();
}
);
console.log(`Created VrfClient Account: ${vrfClientKey}`); console.log(`Created VrfClient Account: ${vrfClientKey}`);
// Get required switchboard accounts // Get required switchboard accounts
@ -158,17 +182,25 @@ describe("anchor-vrf-parser test", async () => {
queue.publicKey, queue.publicKey,
vrfAccount.publicKey vrfAccount.publicKey
); );
const switchboardMint = await programStateAccount.getTokenMint(); const mint = await programStateAccount.getTokenMint();
const payerTokenAccount = const payerTokenAccount = await spl.getOrCreateAssociatedTokenAccount(
await switchboardMint.getOrCreateAssociatedAccountInfo(payer.publicKey); provider.connection,
payer,
mint.address,
payer.publicKey,
undefined,
undefined,
undefined,
spl.TOKEN_PROGRAM_ID,
spl.ASSOCIATED_TOKEN_PROGRAM_ID
);
// Request randomness // Request randomness
console.log(`Sending RequestRandomness instruction`); console.log(`Sending RequestRandomness instruction`);
const requestTxn = await vrfClientProgram.methods const requestTxn = await vrfClientProgram.methods.requestResult!({
.requestResult({ switchboardStateBump: programStateBump,
switchboardStateBump: programStateBump, permissionBump,
permissionBump, })
})
.accounts({ .accounts({
state: vrfClientKey, state: vrfClientKey,
authority: payer.publicKey, authority: payer.publicKey,

View File

@ -1,26 +1,26 @@
{ {
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
},
"compilerOptions": { "compilerOptions": {
"types": ["mocha", "chai", "node"], "types": ["mocha", "chai"],
"typeRoots": ["./node_modules/@types"], "typeRoots": ["./node_modules/@types"],
"lib": ["es2015"], "module": "CommonJS",
"module": "commonjs",
"target": "es6",
"esModuleInterop": true,
"importsNotUsedAsValues": "remove",
"noEmit": true, "noEmit": true,
"esModuleInterop": true,
"strict": false,
"paths": { "paths": {
"@switchboard-xyz/switchboard-v2": ["../../libraries/ts"], "@switchboard-xyz/switchboard-v2": ["../../libraries/ts"],
"@switchboard-xyz/sbv2-utils": ["../../libraries/sbv2-utils"] "@switchboard-xyz/sbv2-utils": ["../../libraries/sbv2-utils"],
"@solana/spl-token": [
"../../node_modules/@solana/spl-token",
"./node_modules/@solana/spl-token"
]
} }
}, },
// "include": ["client/**/*"], "include": [
"exclude": ["target", "lib"], "tests/**/*",
"client/**/*",
"../../../target/types/anchor_vrf_parser"
],
"references": [ "references": [
{ "path": "../../libraries/ts" }, { "path": "../../libraries/ts" },
{ "path": "../../libraries/sbv2-utils" } { "path": "../../libraries/sbv2-utils" }

View File

@ -16,8 +16,8 @@
"dependencies": { "dependencies": {
"@project-serum/anchor": "^0.24.2", "@project-serum/anchor": "^0.24.2",
"@solana/web3.js": "^1.42.0", "@solana/web3.js": "^1.42.0",
"@switchboard-xyz/sbv2-utils": "^0.1.22", "@switchboard-xyz/sbv2-utils": "^0.1.25",
"@switchboard-xyz/switchboard-v2": "^0.0.112" "@switchboard-xyz/switchboard-v2": "^0.0.114"
}, },
"devDependencies": { "devDependencies": {
"@types/chai": "^4.3.0", "@types/chai": "^4.3.0",

View File

@ -1,120 +1,30 @@
{ {
"ts-node": {
"compilerOptions": {
"module": "commonjs",
"target": "ES2019",
"rootDir": "./",
"strict": false,
"skipLibCheck": true,
"noImplicitReturns": false
}
},
"exclude": ["node_modules"], "exclude": ["node_modules"],
"compilerOptions": { "compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */ "target": "ES2019",
"lib": ["es2019", "dom"],
/* Projects */ "module": "es2022",
// "incremental": true, /* Enable incremental compilation */ "moduleResolution": "node",
// "composite": true /* Enable constraints that allow a TypeScript project to be used with project references. */, "types": ["node", "mocha", "chai", "long"],
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ "resolveJsonModule": true,
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ "allowJs": false,
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ "checkJs": false,
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ "declaration": true,
"declarationMap": true,
/* Language and Environment */ "sourceMap": true,
"target": "ES2019" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, "noEmit": true,
"lib": [ "importHelpers": true,
"es2019", "importsNotUsedAsValues": "error",
"dom" "inlineSources": true,
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */, "esModuleInterop": true,
// "jsx": "react-jsx" /* Specify what JSX code is generated. */, "forceConsistentCasingInFileNames": true,
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ "strict": true,
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ "noImplicitReturns": true,
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ "noFallthroughCasesInSwitch": true,
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ "noUncheckedIndexedAccess": true,
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ "skipLibCheck": true,
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ "paths": {
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ "@solana/spl-token": ["./node_modules/@solana/spl-token"]
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ }
/* Modules */
"module": "ES2020" /* Specify what module code is generated. */,
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node" /* Specify how TypeScript looks up a file from a given module specifier. */,
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
"types": [
"node",
"mocha",
"chai",
"long"
] /* Specify type package names to be included without being referenced in a source file. */,
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
"resolveJsonModule": true /* Enable importing .json files */,
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
"allowJs": false /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */,
"checkJs": false /* Enable error reporting in type-checked JavaScript files. */,
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
/* Emit */
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
"declarationMap": true /* Create sourcemaps for d.ts files. */,
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
"sourceMap": true /* Create source map files for emitted JavaScript files. */,
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
"noEmit": true /* Disable emitting files from a compilation. */,
"importHelpers": true /* Allow importing helper functions from tslib once per project, instead of including them per-file. */,
"importsNotUsedAsValues": "error" /* Specify emit/checking behavior for imports that are only used for types */,
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
"inlineSources": true /* Include source code in the sourcemaps inside the emitted JavaScript. */,
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */,
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */,
/* Type Checking */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
"noImplicitReturns": true /* Enable error reporting for codepaths that do not explicitly return in a function. */,
"noFallthroughCasesInSwitch": true /* Enable error reporting for fallthrough cases in switch statements. */,
"noUncheckedIndexedAccess": true /* Include 'undefined' in index signature results */,
// "noImplicitOverride": true /* Ensure overriding members in derived classes are marked with an override modifier. */,
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
} }
} }

View File

@ -15,101 +15,439 @@ import Link from "@docusaurus/Link";
## Mainnet-Beta ## Mainnet-Beta
Below is a list of public keys used in the Switchboard V2 mainnet deployment. ### Permissionless Queue
The permissionless queue does not require aggregators to have `PERMIT_ORACLE_QUEUE_USAGE` permissions before using a queue's resources.
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Account</th> <th colspan="2">Public Keys</th>
<th>Public Key</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td> <td>
<b>Program ID</b> <b>Oracle Queue</b>
</td> </td>
<td> <td>
<PublicKeyButton publicKey="SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f" /> <PublicKeyButton publicKey="5JYwqvKkqp35w8Nq3ba4z1WYUeJQ1rB36V8XvaGp6zn1" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<b>Permissionless Queue</b> <b>Authority</b>
</td>
<td>
<PublicKeyButton publicKey="31Sof5r1xi7dfcaz4x9Kuwm8J9ueAdDduMcme59sP8gc" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>Oracle Buffer</b>
</td>
<td>
<PublicKeyButton publicKey="FozqXFMS1nQKfPqwVdChr7RJ3y7ccSux39zU682kNYjJ" />
</td>
</tr>
<tr>
<td>
<b>Crank #1</b>
</td> </td>
<td> <td>
<b>Queue</b>
<br />
<PublicKeyButton publicKey="5JYwqvKkqp35w8Nq3ba4z1WYUeJQ1rB36V8XvaGp6zn1" />
<br />
<b>Crank</b>
<br />
<PublicKeyButton publicKey="BKtF8yyQsj3Ft6jb2nkfpEKzARZVdGgdEPs6mFmZNmbA" /> <PublicKeyButton publicKey="BKtF8yyQsj3Ft6jb2nkfpEKzARZVdGgdEPs6mFmZNmbA" />
</td> </td>
</tr> </tr>
<tr>
<td colspan="2">
<div className="centeredText">
<b>Mainnet Permissionless Queue Settings</b>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<table className="table_no_border">
<tr>
<td>
<b>unpermissionedFeedsEnabled</b>
</td>
<td>True</td>
</tr>
<tr>
<td>
<b>unpermissionedVrfEnabled</b>
</td>
<td>True</td>
</tr>
<tr>
<td>
<b>enableBufferRelayers</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>slashingEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>reward</b>
</td>
<td>12500</td>
</tr>
<tr>
<td>
<b>minStake</b>
</td>
<td>0</td>
</tr>
<tr>
<td>
<b>oracleTimeout</b>
</td>
<td>180</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
### Permissioned Queue
The permissioned queue requires aggregators to have `PERMIT_ORACLE_QUEUE_USAGE` permissions before using the queue's resources.
<table>
<thead>
<tr>
<th colspan="2">Public Keys</th>
</tr>
</thead>
<tbody>
<tr> <tr>
<td> <td>
<b>Permissioned Queue</b> <b>Oracle Queue</b>
</td> </td>
<td> <td>
<b>Queue</b>
<br />
<PublicKeyButton publicKey="3HBb2DQqDfuMdzWxNk1Eo9RTMkFYmuEAd32RiLKn9pAn" /> <PublicKeyButton publicKey="3HBb2DQqDfuMdzWxNk1Eo9RTMkFYmuEAd32RiLKn9pAn" />
<br /> </td>
<b>Crank</b> </tr>
<br /> <tr>
<td>
<b>Authority</b>
</td>
<td>
<PublicKeyButton publicKey="31Sof5r1xi7dfcaz4x9Kuwm8J9ueAdDduMcme59sP8gc" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>Oracle Buffer</b>
</td>
<td>
<PublicKeyButton publicKey="FZ3CAm8o5zf18Ua23jhrZJRYCMtGhFxFrTux8N5yrf2T" />
</td>
</tr>
<tr>
<td>
<b>Crank #1</b>
</td>
<td>
<PublicKeyButton publicKey="GdNVLWzcE6h9SPuSbmu69YzxAj8enim9t6mjzuqTXgLd" /> <PublicKeyButton publicKey="GdNVLWzcE6h9SPuSbmu69YzxAj8enim9t6mjzuqTXgLd" />
</td> </td>
</tr> </tr>
<tr>
<td colspan="2">
<div className="centeredText">
<b>Mainnet Permissioned Queue Settings</b>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<table className="table_no_border">
<tr>
<td>
<b>unpermissionedFeedsEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>unpermissionedVrfEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>enableBufferRelayers</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>slashingEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>reward</b>
</td>
<td>12500</td>
</tr>
<tr>
<td>
<b>minStake</b>
</td>
<td>0</td>
</tr>
<tr>
<td>
<b>oracleTimeout</b>
</td>
<td>180</td>
</tr>
</table>
</td>
</tr>
</tbody> </tbody>
</table> </table>
## Devnet ## Devnet
Below is a list of public keys used in the Switchboard V2 devnet deployment. ### Permissionless Queue
The permissionless queue does not require aggregators to have `PERMIT_ORACLE_QUEUE_USAGE` permissions before using a queue's resources.
<table> <table>
<thead> <thead>
<tr> <tr>
<th>Account</th> <th colspan="2">Public Keys</th>
<th>Public Key</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td> <td>
<b>Program ID</b> <b>Oracle Queue</b>
</td> </td>
<td> <td>
<PublicKeyButton publicKey="2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG" /> <PublicKeyButton publicKey="F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
<b>Permissionless Queue</b> <b>Authority</b>
</td>
<td>
<PublicKeyButton publicKey="2KgowxogBrGqRcgXQEmqFvC3PGtCu66qERNJevYW8Ajh" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>Oracle Buffer</b>
</td>
<td>
<PublicKeyButton publicKey="7yJ3sSifpmUFB5BcXy6yMDje15xw2CovJjfXfBKsCfT5" />
</td>
</tr>
<tr>
<td>
<b>Crank #1</b>
</td> </td>
<td> <td>
<b>Queue</b>
<br />
<PublicKeyButton publicKey="F8ce7MsckeZAbAGmxjJNetxYXQa9mKr9nnrC3qKubyYy" />
<br />
<b>Crank</b>
<br />
<PublicKeyButton publicKey="GN9jjCy2THzZxhYqZETmPM3my8vg4R5JyNkgULddUMa5" /> <PublicKeyButton publicKey="GN9jjCy2THzZxhYqZETmPM3my8vg4R5JyNkgULddUMa5" />
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td colspan="2">
<b>Permissioned Queue</b> <div className="centeredText">
<b>Devnet Permissionless Queue Settings</b>
</div>
</td> </td>
<td> </tr>
<b>Queue</b> <tr>
<br /> <td colspan="2">
<PublicKeyButton publicKey="GhYg3R1V6DmJbwuc57qZeoYG6gUuvCotUF1zU3WCj98U" /> <table className="table_no_border">
<br /> <tr>
<b>Crank</b> <td>
<br /> <b>unpermissionedFeedsEnabled</b>
<PublicKeyButton publicKey="GdNVLWzcE6h9SPuSbmu69YzxAj8enim9t6mjzuqTXgLd" /> </td>
<td>True</td>
</tr>
<tr>
<td>
<b>unpermissionedVrfEnabled</b>
</td>
<td>True</td>
</tr>
<tr>
<td>
<b>enableBufferRelayers</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>slashingEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>reward</b>
</td>
<td>12500</td>
</tr>
<tr>
<td>
<b>minStake</b>
</td>
<td>0</td>
</tr>
<tr>
<td>
<b>oracleTimeout</b>
</td>
<td>180</td>
</tr>
</table>
</td>
</tr>
</tbody>
</table>
### Permissioned Queue
The permissioned queue requires aggregators to have `PERMIT_ORACLE_QUEUE_USAGE` permissions before using the queue's resources.
<table>
<thead>
<tr>
<th colspan="2">Public Keys</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<b>Oracle Queue</b>
</td>
<td>
<PublicKeyButton publicKey="GhYg3R1V6DmJbwuc57qZeoYG6gUuvCotUF1zU3WCj98U" />
</td>
</tr>
<tr>
<td>
<b>Authority</b>
</td>
<td>
<PublicKeyButton publicKey="2KgowxogBrGqRcgXQEmqFvC3PGtCu66qERNJevYW8Ajh" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>Oracle Buffer</b>
</td>
<td>
<PublicKeyButton publicKey="DQXUDDcDoQ2FjzjYRi45gjdRqe1EsLwoqNhW2hf488gf" />
</td>
</tr>
<tr>
<td>
<b>Crank #1</b>
</td>
<td>
<PublicKeyButton publicKey="GdNVLWzcE6h9SPuSbmu69YzxAj8enim9t6mjzuqTXgLd" />
</td>
</tr>
<tr>
<td colspan="2">
<div className="centeredText">
<b>Devnet Permissioned Queue Settings</b>
</div>
</td>
</tr>
<tr>
<td colspan="2">
<table className="table_no_border">
<tr>
<td>
<b>unpermissionedFeedsEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>unpermissionedVrfEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>enableBufferRelayers</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>slashingEnabled</b>
</td>
<td>False</td>
</tr>
<tr>
<td>
<b>reward</b>
</td>
<td>12500</td>
</tr>
<tr>
<td>
<b>minStake</b>
</td>
<td>0</td>
</tr>
<tr>
<td>
<b>oracleTimeout</b>
</td>
<td>180</td>
</tr>
</table>
</td> </td>
</tr> </tr>
</tbody> </tbody>

View File

@ -8,6 +8,7 @@ import MarkdownImage from "/src/components/MarkdownImage";
import { Box, Typography, Grid } from "@mui/material"; import { Box, Typography, Grid } from "@mui/material";
import Link from "@docusaurus/Link"; import Link from "@docusaurus/Link";
import ProgramStateAccountData from "/idl/accounts/SbState.md"; import ProgramStateAccountData from "/idl/accounts/SbState.md";
import PublicKeyButton from "/src/components/PublicKeyButton";
# Program # Program
@ -34,3 +35,175 @@ import ProgramStateAccountData from "/idl/accounts/SbState.md";
</Grid> </Grid>
<ProgramStateAccountData /> <ProgramStateAccountData />
## Deployment
Below are the public keys associated with the Switchboard V2 deployment.
### Mainnet-Beta
<table>
<thead>
<tr>
<th colspan="2">Mainnet-Beta</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<b>Program ID</b>
</td>
<td>
<PublicKeyButton publicKey="SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f" />
</td>
</tr>
<tr>
<td>
<b>Upgrade Authority</b>
</td>
<td>
<PublicKeyButton publicKey="31Sof5r1xi7dfcaz4x9Kuwm8J9ueAdDduMcme59sP8gc" />
</td>
</tr>
<tr>
<td>
<b>Program State Account</b>
</td>
<td>
<PublicKeyButton publicKey="CyZuD7RPDcrqCGbNvLCyqk6Py9cEZTKmNKujfPi3ynDd" />
</td>
</tr>
<tr>
<td>
<b>Program Authority</b>
</td>
<td>
<PublicKeyButton publicKey="31Sof5r1xi7dfcaz4x9Kuwm8J9ueAdDduMcme59sP8gc" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>DAO Mint</b>
</td>
<td>
<PublicKeyButton publicKey="11111111111111111111111111111111" />
</td>
</tr>
<tr>
<td>
<b>tokenVault</b>
</td>
<td>
<PublicKeyButton publicKey="J7nSEX8ADf3pVVicd6yKy2Skvg8iLePEmkLUisAAaioD" />
</td>
</tr>
<tr>
<td>
<b>idlAddress</b>
</td>
<td>
<PublicKeyButton publicKey="Fi8vncGpNKbq62gPo56G4toCehWNy77GgqGkTaAF5Lkk" />
</td>
</tr>
<tr>
<td>
<b>programDataAddress</b>
</td>
<td>
<PublicKeyButton publicKey="7nYabs9dUhvxYwdTnrWVBL9MYviKSfrEbdWCUbcnwkpF" />
</td>
</tr>
</tbody>
</table>
### Devnet
<table>
<thead>
<tr>
<th colspan="2">Devnet</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<b>Program ID</b>
</td>
<td>
<PublicKeyButton publicKey="2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG" />
</td>
</tr>
<tr>
<td>
<b>Upgrade Authority</b>
</td>
<td>
<PublicKeyButton publicKey="2KgowxogBrGqRcgXQEmqFvC3PGtCu66qERNJevYW8Ajh" />
</td>
</tr>
<tr>
<td>
<b>Program State Account</b>
</td>
<td>
<PublicKeyButton publicKey="BYM81n8HvTJuqZU1PmTVcwZ9G8uoji7FKM6EaPkwphPt" />
</td>
</tr>
<tr>
<td>
<b>Program Authority</b>
</td>
<td>
<PublicKeyButton publicKey="2KgowxogBrGqRcgXQEmqFvC3PGtCu66qERNJevYW8Ajh" />
</td>
</tr>
<tr>
<td>
<b>Mint</b>
</td>
<td>
<PublicKeyButton publicKey="So11111111111111111111111111111111111111112" />
</td>
</tr>
<tr>
<td>
<b>DAO Mint</b>
</td>
<td>
<PublicKeyButton publicKey="11111111111111111111111111111111" />
</td>
</tr>
<tr>
<td>
<b>tokenVault</b>
</td>
<td>
<PublicKeyButton publicKey="FVLfR6C2ckZhbSwBzZY4CX7YBcddUSge5BNeGQv5eKhy" />
</td>
</tr>
<tr>
<td>
<b>idlAddress</b>
</td>
<td>
<PublicKeyButton publicKey="CKwZcshn4XDvhaWVH9EXnk3iu19t6t5xP2Sy2pD6TRDp" />
</td>
</tr>
<tr>
<td>
<b>programDataAddress</b>
</td>
<td>
<PublicKeyButton publicKey="J4CArpsbrZqu1axqQ4AnrqREs3jwoyA1M5LMiQQmAzB9" />
</td>
</tr>
</tbody>
</table>

View File

@ -34,6 +34,24 @@ td:last-child {
width: 100%; width: 100%;
} }
/* .table_no_border table {
margin-left: 0;
padding-left: 0;
padding-bottom: 0;
margin-bottom: 0;
} */
.table_no_border td,
.table_no_border tr {
border: none;
border-collapse: collapse;
padding: 0.5em 2em;
}
.centeredText {
text-align: center;
}
html[data-theme="dark"] a { html[data-theme="dark"] a {
font-weight: 800; font-weight: 800;
} }

View File

@ -4164,23 +4164,6 @@
"@svgr/plugin-jsx" "^6.2.1" "@svgr/plugin-jsx" "^6.2.1"
"@svgr/plugin-svgo" "^6.2.0" "@svgr/plugin-svgo" "^6.2.0"
"@switchboard-xyz/switchboard-v2@^0.0.112":
version "0.0.112"
resolved "https://registry.npmjs.org/@switchboard-xyz/switchboard-v2/-/switchboard-v2-0.0.112.tgz#368256496666d4e18a64c22d944d6f7a6fcf8aad"
integrity sha512-0Qg4xqzzS0BLMvhXkrEzf2btzY6rtrGa4BEs/LSMIMXg+RgJV4WC++QNcgzuFASfBXw2juWpODOo0STOS4T3Cw==
dependencies:
"@project-serum/anchor" "^0.24.2"
"@solana/spl-governance" "^0.0.34"
assert "^2.0.0"
big.js "^6.1.1"
bs58 "^4.0.1"
chan "^0.6.1"
crypto-js "^4.0.0"
long "^4.0.0"
mocha "^9.1.1"
node-fetch "^3.2.3"
protobufjs "^6.11.3"
"@szmarczak/http-timer@^1.1.2": "@szmarczak/http-timer@^1.1.2":
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421"
@ -16031,9 +16014,9 @@ ts-node@7.0.1:
source-map-support "^0.5.6" source-map-support "^0.5.6"
yn "^2.0.0" yn "^2.0.0"
ts-node@^10.2.1, ts-node@^10.4.0, ts-node@^10.7.0: ts-node@^10.2.1, ts-node@^10.4.0, ts-node@^10.7.0, ts-node@^10.8.0:
version "10.8.1" version "10.8.1"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.8.1.tgz#ea2bd3459011b52699d7e88daa55a45a1af4f066" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.8.1.tgz#ea2bd3459011b52699d7e88daa55a45a1af4f066"
integrity sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g== integrity sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==
dependencies: dependencies:
"@cspotcode/source-map-support" "^0.8.0" "@cspotcode/source-map-support" "^0.8.0"
@ -16215,9 +16198,9 @@ typescript@^4.2.4, typescript@^4.6.3:
resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz" resolved "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz"
integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw== integrity sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==
typescript@^4.3.2, typescript@^4.3.5, typescript@^4.4.3, typescript@^4.7: typescript@^4.3.2, typescript@^4.3.5, typescript@^4.4.3, typescript@^4.7, typescript@^4.7.3:
version "4.7.4" version "4.7.4"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" resolved "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235"
integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==
ua-parser-js@^0.7.30: ua-parser-js@^0.7.30: