fix tests
This commit is contained in:
parent
aa08dbef43
commit
271918602f
|
@ -64,5 +64,5 @@ jobs:
|
|||
run: |
|
||||
solana-keygen new --no-bip39-passphrase --outfile ~/.config/solana/id.json --silent
|
||||
mkdir -p .anchor/test-ledger
|
||||
solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone 2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG --clone J4CArpsbrZqu1axqQ4AnrqREs3jwoyA1M5LMiQQmAzB9 --clone CKwZcshn4XDvhaWVH9EXnk3iu19t6t5xP2Sy2pD6TRDp & sleep 15
|
||||
solana-test-validator -q -r --ledger .anchor/test-ledger --mint $(solana-keygen pubkey ~/.config/solana/id.json) --bind-address 0.0.0.0 --url https://api.devnet.solana.com --rpc-port 8899 --clone 2TfB33aLaneQb5TNVwyDz3jSZXS6jdW2ARw1Dgf84XCG --clone J4CArpsbrZqu1axqQ4AnrqREs3jwoyA1M5LMiQQmAzB9 --clone CKwZcshn4XDvhaWVH9EXnk3iu19t6t5xP2Sy2pD6TRDp --clone BYM81n8HvTJuqZU1PmTVcwZ9G8uoji7FKM6EaPkwphPt --clone FVLfR6C2ckZhbSwBzZY4CX7YBcddUSge5BNeGQv5eKhy & sleep 15
|
||||
npm run test:localnet
|
||||
|
|
|
@ -5,6 +5,7 @@ import * as errors from '../errors';
|
|||
import Big from 'big.js';
|
||||
import { SwitchboardProgram } from '../program';
|
||||
import {
|
||||
AccountMeta,
|
||||
Keypair,
|
||||
PublicKey,
|
||||
SystemProgram,
|
||||
|
@ -20,6 +21,7 @@ import { LeaseAccount } from './leaseAccount';
|
|||
import { PermissionAccount } from './permissionAccount';
|
||||
import * as spl from '@solana/spl-token';
|
||||
import { TransactionObject } from '../transaction';
|
||||
import { TOKEN_PROGRAM_ID } from '@solana/spl-token';
|
||||
|
||||
export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
||||
static accountName = 'AggregatorAccountData';
|
||||
|
@ -716,62 +718,20 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
return txnSignature;
|
||||
}
|
||||
|
||||
public openRoundInstruction(
|
||||
public async openRoundInstruction(
|
||||
payer: PublicKey,
|
||||
params: {
|
||||
queueAccount: QueueAccount;
|
||||
queueAuthority: PublicKey;
|
||||
queueDataBuffer: PublicKey;
|
||||
mint: PublicKey;
|
||||
payoutWallet: PublicKey;
|
||||
lease: [LeaseAccount, number];
|
||||
leaseEscrow: PublicKey;
|
||||
permission: [PermissionAccount, number];
|
||||
}
|
||||
): TransactionInstruction {
|
||||
const [leaseAccount, leaseBump] = params.lease;
|
||||
const [permissionAccount, permissionBump] = params.permission;
|
||||
|
||||
return types.aggregatorOpenRound(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
stateBump: this.program.programState.bump,
|
||||
leaseBump: leaseBump,
|
||||
permissionBump: permissionBump,
|
||||
jitter: 0, // what is this for?
|
||||
},
|
||||
},
|
||||
{
|
||||
aggregator: this.publicKey,
|
||||
lease: leaseAccount.publicKey,
|
||||
oracleQueue: params.queueAccount.publicKey,
|
||||
queueAuthority: params.queueAuthority,
|
||||
permission: permissionAccount.publicKey,
|
||||
escrow: params.leaseEscrow,
|
||||
programState: this.program.programState.publicKey,
|
||||
payoutWallet: params.payoutWallet,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
dataBuffer: params.queueDataBuffer,
|
||||
mint: params.mint,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public async openRound(
|
||||
params: Partial<{
|
||||
aggregator: types.AggregatorAccountData;
|
||||
queueAccount: QueueAccount;
|
||||
queueAuthority: PublicKey;
|
||||
queueDataBuffer: PublicKey;
|
||||
mint: PublicKey;
|
||||
payoutWallet: PublicKey;
|
||||
lease: [LeaseAccount, number];
|
||||
leaseEscrow: PublicKey;
|
||||
permission: [PermissionAccount, number];
|
||||
aggregator?: types.AggregatorAccountData;
|
||||
queueAccount?: QueueAccount;
|
||||
queue?: types.OracleQueueAccountData;
|
||||
queueAuthority?: PublicKey;
|
||||
queueDataBuffer?: PublicKey;
|
||||
payoutWallet?: PublicKey;
|
||||
lease?: [LeaseAccount, number];
|
||||
leaseEscrow?: PublicKey;
|
||||
permission?: [PermissionAccount, number];
|
||||
}>
|
||||
): Promise<TransactionSignature> {
|
||||
const payer = this.program.walletPubkey;
|
||||
): Promise<TransactionObject> {
|
||||
const aggregator = params.aggregator ?? (await this.loadData());
|
||||
const queueAccount =
|
||||
params.queueAccount ??
|
||||
|
@ -779,12 +739,16 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
|
||||
let queueAuthority = params.queueAuthority;
|
||||
let queueDataBuffer = params.queueDataBuffer;
|
||||
let mint = params.mint;
|
||||
if (!queueAuthority || !queueDataBuffer || !mint) {
|
||||
const queue = await queueAccount.loadData();
|
||||
|
||||
let queue = params.queue;
|
||||
if (params.queue) {
|
||||
queueAuthority = params.queue.authority;
|
||||
queueDataBuffer = params.queue.dataBuffer;
|
||||
}
|
||||
if (!queueAuthority || !queueDataBuffer) {
|
||||
queue = await queueAccount.loadData();
|
||||
queueAuthority = queue.authority;
|
||||
queueDataBuffer = queue.dataBuffer;
|
||||
mint = mint ?? queue.mint ?? spl.NATIVE_MINT;
|
||||
}
|
||||
|
||||
const [leaseAccount, leaseBump] =
|
||||
|
@ -794,18 +758,23 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
queueAccount.publicKey,
|
||||
this.publicKey
|
||||
);
|
||||
let lease: types.LeaseAccountData;
|
||||
try {
|
||||
await leaseAccount.loadData();
|
||||
lease = await leaseAccount.loadData();
|
||||
} catch (_) {
|
||||
throw new Error(
|
||||
'A requested lease pda account has not been initialized.'
|
||||
);
|
||||
}
|
||||
const leaseEscrow = spl.getAssociatedTokenAddressSync(
|
||||
mint,
|
||||
leaseAccount.publicKey,
|
||||
true
|
||||
);
|
||||
|
||||
const leaseEscrow =
|
||||
params.leaseEscrow ??
|
||||
lease.escrow ??
|
||||
spl.getAssociatedTokenAddressSync(
|
||||
this.program.mint.address,
|
||||
leaseAccount.publicKey,
|
||||
true
|
||||
);
|
||||
|
||||
const [permissionAccount, permissionBump] =
|
||||
params.permission ??
|
||||
|
@ -815,44 +784,76 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
queueAccount.publicKey,
|
||||
this.publicKey
|
||||
);
|
||||
let permission: types.PermissionAccountData;
|
||||
try {
|
||||
await permissionAccount.loadData();
|
||||
permission = await permissionAccount.loadData();
|
||||
} catch (_) {
|
||||
throw new Error(
|
||||
'A requested aggregator permission pda account has not been initialized.'
|
||||
);
|
||||
}
|
||||
|
||||
const preInstructions: Array<TransactionInstruction> = [];
|
||||
const ixns: Array<TransactionInstruction> = [];
|
||||
|
||||
const payoutWallet = spl.getAssociatedTokenAddressSync(mint, payer, true);
|
||||
try {
|
||||
await spl.getAccount(this.program.connection, payoutWallet);
|
||||
} catch (error) {
|
||||
// TODO: Catch error and make sure it matches account doesnt exist
|
||||
preInstructions.push(
|
||||
spl.createAssociatedTokenAccountInstruction(
|
||||
payer,
|
||||
payoutWallet,
|
||||
payer,
|
||||
mint
|
||||
)
|
||||
);
|
||||
const payoutWallet =
|
||||
params.payoutWallet ?? this.program.mint.getAssociatedAddress(payer);
|
||||
const payoutWalletAccountInfo =
|
||||
await this.program.connection.getAccountInfo(payoutWallet);
|
||||
if (payoutWalletAccountInfo === null) {
|
||||
const [createTokenAccountTxn] =
|
||||
this.program.mint.createAssocatedUserInstruction(payer);
|
||||
ixns.push(...createTokenAccountTxn.ixns);
|
||||
}
|
||||
|
||||
return await this.program.signAndSendTransaction([
|
||||
...preInstructions,
|
||||
this.openRoundInstruction(this.program.walletPubkey, {
|
||||
queueAccount,
|
||||
queueAuthority,
|
||||
queueDataBuffer,
|
||||
mint,
|
||||
lease: [leaseAccount, leaseBump],
|
||||
permission: [permissionAccount, permissionBump],
|
||||
payoutWallet: payoutWallet,
|
||||
leaseEscrow: leaseEscrow,
|
||||
}),
|
||||
]);
|
||||
ixns.push(
|
||||
types.aggregatorOpenRound(
|
||||
this.program,
|
||||
{
|
||||
params: {
|
||||
stateBump: this.program.programState.bump,
|
||||
leaseBump,
|
||||
permissionBump,
|
||||
jitter: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
aggregator: this.publicKey,
|
||||
lease: leaseAccount.publicKey,
|
||||
oracleQueue: queueAccount.publicKey,
|
||||
queueAuthority: queueAuthority,
|
||||
permission: permissionAccount.publicKey,
|
||||
escrow: leaseEscrow,
|
||||
programState: this.program.programState.publicKey,
|
||||
payoutWallet: payoutWallet,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
dataBuffer: queueDataBuffer,
|
||||
mint: this.program.mint.address,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
return new TransactionObject(payer, ixns, []);
|
||||
}
|
||||
|
||||
public async openRound(
|
||||
params: Partial<{
|
||||
aggregator?: types.AggregatorAccountData;
|
||||
queueAccount?: QueueAccount;
|
||||
queue?: types.OracleQueueAccountData;
|
||||
queueAuthority?: PublicKey;
|
||||
queueDataBuffer?: PublicKey;
|
||||
payoutWallet?: PublicKey;
|
||||
lease?: [LeaseAccount, number];
|
||||
leaseEscrow?: PublicKey;
|
||||
permission?: [PermissionAccount, number];
|
||||
}>
|
||||
): Promise<TransactionSignature> {
|
||||
const openRoundTxn = await this.openRoundInstruction(
|
||||
this.program.walletPubkey,
|
||||
params
|
||||
);
|
||||
const txnSignature = await this.program.signAndSend(openRoundTxn);
|
||||
return txnSignature;
|
||||
}
|
||||
|
||||
public saveResultInstruction(
|
||||
|
@ -877,6 +878,7 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
} & Partial<{
|
||||
error?: boolean;
|
||||
historyBuffer?: PublicKey;
|
||||
oracles: Array<types.OracleAccountData>;
|
||||
}>
|
||||
): TransactionInstruction {
|
||||
const [leaseAccount, leaseBump] = params.lease;
|
||||
|
@ -944,11 +946,26 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
payoutWallet: PublicKey;
|
||||
lease: [LeaseAccount, number];
|
||||
leaseEscrow: PublicKey;
|
||||
oracles: Array<types.OracleAccountData>;
|
||||
}>
|
||||
): Promise<TransactionSignature> {
|
||||
const payer = this.program.walletPubkey;
|
||||
const aggregator = params.aggregator ?? (await this.loadData());
|
||||
|
||||
const remainingAccounts: Array<PublicKey> = [];
|
||||
for (let i = 0; i < aggregator.oracleRequestBatchSize; ++i) {
|
||||
remainingAccounts.push(aggregator.currentRound.oraclePubkeysData[i]);
|
||||
}
|
||||
for (const oracle of params?.oracles ?? []) {
|
||||
remainingAccounts.push(oracle.tokenAccount);
|
||||
}
|
||||
remainingAccounts.push(
|
||||
anchor.utils.publicKey.findProgramAddressSync(
|
||||
[Buffer.from('SlidingResultAccountData'), this.publicKey.toBytes()],
|
||||
this.program.programId
|
||||
)[0]
|
||||
);
|
||||
|
||||
const oracleIdx =
|
||||
params.oracleIdx ??
|
||||
aggregator.currentRound.oraclePubkeysData
|
||||
|
@ -959,6 +976,18 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
throw new Error('Failed to find oracle in current round');
|
||||
}
|
||||
|
||||
const ixns: Array<TransactionInstruction> = [];
|
||||
|
||||
const payoutWallet =
|
||||
params.payoutWallet ?? this.program.mint.getAssociatedAddress(payer);
|
||||
const payoutWalletAccountInfo =
|
||||
await this.program.connection.getAccountInfo(payoutWallet);
|
||||
if (payoutWalletAccountInfo === null) {
|
||||
const [createTokenAccountTxn] =
|
||||
this.program.mint.createAssocatedUserInstruction(payer);
|
||||
ixns.push(...createTokenAccountTxn.ixns);
|
||||
}
|
||||
|
||||
const queueAccount =
|
||||
params.queueAccount ??
|
||||
new QueueAccount(this.program, aggregator.queuePubkey);
|
||||
|
@ -1023,49 +1052,41 @@ export class AggregatorAccount extends Account<types.AggregatorAccountData> {
|
|||
);
|
||||
}
|
||||
|
||||
const preInstructions: Array<TransactionInstruction> = [];
|
||||
|
||||
const payoutWallet = spl.getAssociatedTokenAddressSync(mint, payer, true);
|
||||
try {
|
||||
await spl.getAccount(this.program.connection, payoutWallet);
|
||||
} catch (error) {
|
||||
// TODO: Catch error and make sure it matches account doesnt exist
|
||||
preInstructions.push(
|
||||
spl.createAssociatedTokenAccountInstruction(
|
||||
payer,
|
||||
payoutWallet,
|
||||
payer,
|
||||
mint
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
const historyBuffer = params.historyBuffer ?? aggregator.historyBuffer;
|
||||
|
||||
// TODO: Add SlidingWindow account to remainingAccounts
|
||||
const saveResultIxn = this.saveResultInstruction({
|
||||
queueAccount,
|
||||
queueAuthority,
|
||||
feedPermission: [feedPermissionAccount, feedPermissionBump],
|
||||
jobs: params.jobs,
|
||||
historyBuffer: historyBuffer.equals(PublicKey.default)
|
||||
? undefined
|
||||
: historyBuffer,
|
||||
oracleAccount: params.oracleAccount,
|
||||
oracleIdx,
|
||||
oraclePermission: [oraclePermissionAccount, oraclePermissionBump],
|
||||
value: params.value,
|
||||
minResponse: params.minResponse,
|
||||
maxResponse: params.maxResponse,
|
||||
error: params.error ?? false,
|
||||
mint,
|
||||
payoutWallet: payoutWallet,
|
||||
lease: [leaseAccount, leaseBump],
|
||||
leaseEscrow: leaseEscrow,
|
||||
});
|
||||
saveResultIxn.keys.push(
|
||||
...remainingAccounts.map((pubkey): AccountMeta => {
|
||||
return { isSigner: false, isWritable: true, pubkey };
|
||||
})
|
||||
);
|
||||
ixns.push(saveResultIxn);
|
||||
|
||||
return await this.program.signAndSendTransaction([
|
||||
...preInstructions,
|
||||
this.saveResultInstruction({
|
||||
queueAccount,
|
||||
queueAuthority,
|
||||
feedPermission: [feedPermissionAccount, feedPermissionBump],
|
||||
jobs: params.jobs,
|
||||
historyBuffer: historyBuffer.equals(PublicKey.default)
|
||||
? undefined
|
||||
: historyBuffer,
|
||||
oracleAccount: params.oracleAccount,
|
||||
oracleIdx,
|
||||
oraclePermission: [oraclePermissionAccount, oraclePermissionBump],
|
||||
value: params.value,
|
||||
minResponse: params.minResponse,
|
||||
maxResponse: params.maxResponse,
|
||||
error: params.error ?? false,
|
||||
mint,
|
||||
payoutWallet: payoutWallet,
|
||||
lease: [leaseAccount, leaseBump],
|
||||
leaseEscrow: leaseEscrow,
|
||||
}),
|
||||
]);
|
||||
const saveResultTxn = new TransactionObject(
|
||||
this.program.walletPubkey,
|
||||
ixns,
|
||||
[]
|
||||
);
|
||||
const txnSignature = await this.program.signAndSend(saveResultTxn);
|
||||
return txnSignature;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -90,7 +90,6 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
payer: PublicKey,
|
||||
params: {
|
||||
loadAmount?: number;
|
||||
mint: PublicKey;
|
||||
funder?: PublicKey;
|
||||
funderAuthority?: Keypair;
|
||||
queuePubkey: PublicKey;
|
||||
|
@ -111,11 +110,11 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
const funder = params.funder
|
||||
? params.funder
|
||||
: program.mint.getAssociatedAddress(funderAuthority);
|
||||
const funderBalance = await program.mint.getBalance(funderAuthority);
|
||||
const funderBalance = (await program.mint.getBalance(funderAuthority)) ?? 0;
|
||||
if (loadAmount && funderBalance < loadAmount) {
|
||||
const wrapIxns = await program.mint.unwrapInstruction(
|
||||
const wrapIxns = await program.mint.wrapInstruction(
|
||||
payer,
|
||||
params.loadAmount,
|
||||
{ amount: loadAmount },
|
||||
params.funderAuthority
|
||||
);
|
||||
ixns.push(...wrapIxns.ixns);
|
||||
|
@ -132,14 +131,14 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
[
|
||||
leaseAccount.publicKey.toBuffer(),
|
||||
spl.TOKEN_PROGRAM_ID.toBuffer(),
|
||||
params.mint.toBuffer(),
|
||||
program.mint.address.toBuffer(),
|
||||
],
|
||||
spl.ASSOCIATED_TOKEN_PROGRAM_ID
|
||||
);
|
||||
|
||||
const { walletBumps } = LeaseAccount.getWallets(
|
||||
params.jobAuthorities,
|
||||
params.mint
|
||||
program.mint.address
|
||||
);
|
||||
|
||||
ixns.push(
|
||||
|
@ -147,7 +146,7 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
payer,
|
||||
escrow,
|
||||
leaseAccount.publicKey,
|
||||
params.mint
|
||||
program.mint.address
|
||||
),
|
||||
types.leaseInit(
|
||||
program,
|
||||
|
@ -171,7 +170,7 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
owner: funderAuthority,
|
||||
escrow: escrow,
|
||||
programState: program.programState.publicKey,
|
||||
mint: params.mint,
|
||||
mint: program.mint.address,
|
||||
}
|
||||
)
|
||||
);
|
||||
|
@ -348,7 +347,8 @@ export class LeaseAccount extends Account<types.LeaseAccountData> {
|
|||
const funder = params.funder
|
||||
? params.funder
|
||||
: this.program.mint.getAssociatedAddress(funderAuthority);
|
||||
const funderBalance = await this.program.mint.getBalance(funderAuthority);
|
||||
const funderBalance =
|
||||
(await this.program.mint.getBalance(funderAuthority)) ?? 0;
|
||||
if (funderBalance < params.loadAmount) {
|
||||
const wrapIxns = await this.program.mint.unwrapInstruction(
|
||||
payer,
|
||||
|
|
|
@ -253,7 +253,8 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
);
|
||||
}
|
||||
|
||||
return await this.program.signAndSendTransaction(
|
||||
const heartbeatTxn = new TransactionObject(
|
||||
this.program.walletPubkey,
|
||||
[
|
||||
this.heartbeatInstruction(this.program.walletPubkey, {
|
||||
tokenWallet: tokenWallet,
|
||||
|
@ -266,6 +267,9 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
],
|
||||
params.authority ? [params.authority] : []
|
||||
);
|
||||
|
||||
const txnSignature = await this.program.signAndSend(heartbeatTxn);
|
||||
return txnSignature;
|
||||
}
|
||||
|
||||
withdrawInstruction(
|
||||
|
@ -343,7 +347,8 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
permissionBump = permission[1];
|
||||
}
|
||||
|
||||
return await this.program.signAndSendTransaction(
|
||||
const withdrawTxn = new TransactionObject(
|
||||
this.program.walletPubkey,
|
||||
[
|
||||
this.withdrawInstruction(this.program.walletPubkey, {
|
||||
amount: params.amount,
|
||||
|
@ -355,5 +360,8 @@ export class OracleAccount extends Account<types.OracleAccountData> {
|
|||
],
|
||||
params.authority ? [params.authority] : []
|
||||
);
|
||||
|
||||
const txnSignature = await this.program.signAndSend(withdrawTxn);
|
||||
return txnSignature;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import * as anchor from '@project-serum/anchor';
|
||||
import { SwitchboardProgram } from '../';
|
||||
import { SwitchboardProgram } from '../program';
|
||||
import * as types from '../generated';
|
||||
import { Account } from './account';
|
||||
import * as spl from '@solana/spl-token';
|
||||
|
@ -10,6 +10,7 @@ import {
|
|||
SystemProgram,
|
||||
TransactionSignature,
|
||||
} from '@solana/web3.js';
|
||||
import { TransactionObject } from '../transaction';
|
||||
|
||||
/**
|
||||
* Account type representing Switchboard global program state.
|
||||
|
@ -68,21 +69,28 @@ export class ProgramStateAccount extends Account<types.SbState> {
|
|||
];
|
||||
}
|
||||
})();
|
||||
const instruction = types.programInit(
|
||||
program,
|
||||
{ params: { stateBump: bump } },
|
||||
{
|
||||
state: account.publicKey,
|
||||
authority: program.wallet.publicKey,
|
||||
payer: program.wallet.publicKey,
|
||||
tokenMint: mint,
|
||||
vault: vault,
|
||||
systemProgram: SystemProgram.programId,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
daoMint: params.daoMint ?? mint,
|
||||
}
|
||||
|
||||
const programInit = new TransactionObject(
|
||||
program.walletPubkey,
|
||||
[
|
||||
types.programInit(
|
||||
program,
|
||||
{ params: { stateBump: bump } },
|
||||
{
|
||||
state: account.publicKey,
|
||||
authority: program.wallet.publicKey,
|
||||
payer: program.wallet.publicKey,
|
||||
tokenMint: mint,
|
||||
vault: vault,
|
||||
systemProgram: SystemProgram.programId,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
daoMint: params.daoMint ?? mint,
|
||||
}
|
||||
),
|
||||
],
|
||||
[]
|
||||
);
|
||||
await program.signAndSendTransaction([instruction]);
|
||||
await program.signAndSend(programInit);
|
||||
} catch {} // eslint-disable-line no-empty
|
||||
}
|
||||
return [account, bump];
|
||||
|
@ -143,18 +151,26 @@ export class ProgramStateAccount extends Account<types.SbState> {
|
|||
): Promise<TransactionSignature> {
|
||||
const [account, bump] = ProgramStateAccount.fromSeed(program);
|
||||
const vault = (await account.loadData()).tokenVault;
|
||||
const instruction = types.vaultTransfer(
|
||||
program,
|
||||
{ params: { stateBump: bump, amount: params.amount } },
|
||||
{
|
||||
state: account.publicKey,
|
||||
to,
|
||||
vault,
|
||||
authority: authority.publicKey,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
}
|
||||
|
||||
const vaultTransfer = new TransactionObject(
|
||||
program.walletPubkey,
|
||||
[
|
||||
types.vaultTransfer(
|
||||
program,
|
||||
{ params: { stateBump: bump, amount: params.amount } },
|
||||
{
|
||||
state: account.publicKey,
|
||||
to,
|
||||
vault,
|
||||
authority: authority.publicKey,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
}
|
||||
),
|
||||
],
|
||||
[]
|
||||
);
|
||||
return program.signAndSendTransaction([instruction]);
|
||||
const txnSignature = await program.signAndSend(vaultTransfer);
|
||||
return txnSignature;
|
||||
}
|
||||
/**
|
||||
* @return account size of the global {@linkcode ProgramStateAccount}.
|
||||
|
|
|
@ -405,7 +405,20 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
): Promise<[TransactionObject[], AggregatorAccount]> {
|
||||
const queue = await this.loadData();
|
||||
|
||||
const pre: TransactionObject[] = [];
|
||||
const txns: TransactionObject[] = [];
|
||||
const post: TransactionObject[] = [];
|
||||
|
||||
// getOrCreate token account for
|
||||
const userTokenAddress = this.program.mint.getAssociatedAddress(payer);
|
||||
const userTokenAccountInfo = await this.program.connection.getAccountInfo(
|
||||
userTokenAddress
|
||||
);
|
||||
if (userTokenAccountInfo === null) {
|
||||
const [createTokenAccount] =
|
||||
this.program.mint.createAssocatedUserInstruction(payer);
|
||||
pre.push(createTokenAccount);
|
||||
}
|
||||
|
||||
// create / load jobs
|
||||
const jobs: { job: JobAccount; weight: number }[] = [];
|
||||
|
@ -424,7 +437,7 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
jobKeypair: job.jobKeypair,
|
||||
}
|
||||
);
|
||||
txns.push(...jobInit);
|
||||
pre.push(...jobInit);
|
||||
jobs.push({ job: jobAccount, weight: job.weight ?? 1 });
|
||||
} else if ('pubkey' in job) {
|
||||
const jobAccount = new JobAccount(this.program, job.pubkey);
|
||||
|
@ -435,16 +448,6 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
}
|
||||
}
|
||||
}
|
||||
// getOrCreate token account for
|
||||
const userTokenAddress = this.program.mint.getAssociatedAddress(payer);
|
||||
const userTokenAccountInfo = await this.program.connection.getAccountInfo(
|
||||
userTokenAddress
|
||||
);
|
||||
if (userTokenAccountInfo === null) {
|
||||
const [createTokenAccount] =
|
||||
this.program.mint.createAssocatedUserInstruction(payer);
|
||||
txns.push(createTokenAccount);
|
||||
}
|
||||
|
||||
const [aggregatorInit, aggregatorAccount] =
|
||||
await AggregatorAccount.createInstruction(this.program, payer, {
|
||||
|
@ -465,14 +468,14 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
loadAmount: params.loadAmount,
|
||||
funder: params.funder,
|
||||
funderAuthority: params.funderAuthority,
|
||||
mint: this.program.mint.address,
|
||||
aggregatorPubkey: aggregatorAccount.publicKey,
|
||||
queuePubkey: this.publicKey,
|
||||
jobAuthorities: [],
|
||||
}
|
||||
);
|
||||
txns.push(leaseInit);
|
||||
// // create permission account
|
||||
|
||||
// create permission account
|
||||
const [permissionInit, permissionAccount] =
|
||||
PermissionAccount.createInstruction(this.program, payer, {
|
||||
granter: this.publicKey,
|
||||
|
@ -498,10 +501,14 @@ export class QueueAccount extends Account<types.OracleQueueAccountData> {
|
|||
weight: weight,
|
||||
authority: params.authority,
|
||||
});
|
||||
txns.push(addJobTxn);
|
||||
post.push(addJobTxn);
|
||||
}
|
||||
|
||||
const packed = TransactionObject.pack(txns);
|
||||
const packed = TransactionObject.pack([
|
||||
...TransactionObject.pack(pre),
|
||||
...TransactionObject.pack(txns),
|
||||
...TransactionObject.pack(post),
|
||||
]);
|
||||
|
||||
return [packed, aggregatorAccount];
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { PublicKey, SystemProgram } from '@solana/web3.js';
|
|||
import * as errors from '../errors';
|
||||
import * as types from '../generated';
|
||||
import { SwitchboardProgram } from '../program';
|
||||
import { TransactionObject } from '../transaction';
|
||||
import { Account, OnAccountChangeCallback } from './account';
|
||||
import { QueueAccount } from './queueAccount';
|
||||
|
||||
|
@ -48,15 +49,13 @@ export class VrfAccount extends Account<types.VrfAccountData> {
|
|||
program: SwitchboardProgram,
|
||||
params: VrfInitParams
|
||||
): Promise<[string, VrfAccount]> {
|
||||
return this.createInstructions(program, {
|
||||
...params,
|
||||
payerKeypair: program.wallet.payer,
|
||||
}).then(async ([instructions, account]) => {
|
||||
const txSignature = await program.signAndSendTransaction(instructions, [
|
||||
params.vrfKeypair,
|
||||
]);
|
||||
return [txSignature, account];
|
||||
});
|
||||
const [createTxn, vrfAccount] = await VrfAccount.createInstructions(
|
||||
program,
|
||||
program.walletPubkey,
|
||||
params
|
||||
);
|
||||
const txnSignature = await program.signAndSend(createTxn);
|
||||
return [txnSignature, vrfAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,9 +66,9 @@ export class VrfAccount extends Account<types.VrfAccountData> {
|
|||
*/
|
||||
public static async createInstructions(
|
||||
program: SwitchboardProgram,
|
||||
params: VrfInitParams & { payerKeypair: anchor.web3.Keypair },
|
||||
payer: PublicKey = program.walletPubkey
|
||||
): Promise<[anchor.web3.TransactionInstruction[], VrfAccount]> {
|
||||
payer: PublicKey,
|
||||
params: VrfInitParams
|
||||
): Promise<[TransactionObject, VrfAccount]> {
|
||||
const vrfAccount = new VrfAccount(program, params.vrfKeypair.publicKey);
|
||||
const size = program.account.vrfAccountData.size;
|
||||
const switchTokenMint = await params.queue.loadMint();
|
||||
|
@ -78,50 +77,50 @@ export class VrfAccount extends Account<types.VrfAccountData> {
|
|||
params.vrfKeypair.publicKey,
|
||||
true
|
||||
);
|
||||
return [
|
||||
[
|
||||
spl.createAssociatedTokenAccountInstruction(
|
||||
program.wallet.payer.publicKey,
|
||||
escrow,
|
||||
params.vrfKeypair.publicKey,
|
||||
switchTokenMint.address
|
||||
const ixns = [
|
||||
spl.createAssociatedTokenAccountInstruction(
|
||||
program.wallet.payer.publicKey,
|
||||
escrow,
|
||||
params.vrfKeypair.publicKey,
|
||||
switchTokenMint.address
|
||||
),
|
||||
spl.createSetAuthorityInstruction(
|
||||
escrow,
|
||||
params.vrfKeypair.publicKey,
|
||||
spl.AuthorityType.AccountOwner,
|
||||
program.programState.publicKey,
|
||||
[program.wallet.payer, params.vrfKeypair]
|
||||
),
|
||||
SystemProgram.createAccount({
|
||||
fromPubkey: program.wallet.payer.publicKey,
|
||||
newAccountPubkey: params.vrfKeypair.publicKey,
|
||||
space: size,
|
||||
lamports: await program.connection.getMinimumBalanceForRentExemption(
|
||||
size
|
||||
),
|
||||
spl.createSetAuthorityInstruction(
|
||||
escrow,
|
||||
params.vrfKeypair.publicKey,
|
||||
spl.AuthorityType.AccountOwner,
|
||||
program.programState.publicKey,
|
||||
[program.wallet.payer, params.vrfKeypair]
|
||||
),
|
||||
SystemProgram.createAccount({
|
||||
fromPubkey: program.wallet.payer.publicKey,
|
||||
newAccountPubkey: params.vrfKeypair.publicKey,
|
||||
space: size,
|
||||
lamports: await program.connection.getMinimumBalanceForRentExemption(
|
||||
size
|
||||
),
|
||||
programId: program.programId,
|
||||
}),
|
||||
types.vrfInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
stateBump: program.programState.bump,
|
||||
callback: params.callback,
|
||||
},
|
||||
programId: program.programId,
|
||||
}),
|
||||
types.vrfInit(
|
||||
program,
|
||||
{
|
||||
params: {
|
||||
stateBump: program.programState.bump,
|
||||
callback: params.callback,
|
||||
},
|
||||
{
|
||||
vrf: params.vrfKeypair.publicKey,
|
||||
authority: params.authority ?? params.vrfKeypair.publicKey,
|
||||
escrow,
|
||||
oracleQueue: params.queue.publicKey,
|
||||
programState: program.programState.publicKey,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
}
|
||||
),
|
||||
],
|
||||
vrfAccount,
|
||||
},
|
||||
{
|
||||
vrf: params.vrfKeypair.publicKey,
|
||||
authority: params.authority ?? params.vrfKeypair.publicKey,
|
||||
escrow,
|
||||
oracleQueue: params.queue.publicKey,
|
||||
programState: program.programState.publicKey,
|
||||
tokenProgram: spl.TOKEN_PROGRAM_ID,
|
||||
}
|
||||
),
|
||||
];
|
||||
|
||||
const txn = new TransactionObject(payer, ixns, [params.vrfKeypair]);
|
||||
return [txn, vrfAccount];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -55,14 +55,23 @@ export class Mint {
|
|||
return swbDecimal.toBig().toNumber();
|
||||
}
|
||||
|
||||
public async getAccount(user: PublicKey): Promise<spl.Account> {
|
||||
public async getAccount(user: PublicKey): Promise<spl.Account | null> {
|
||||
const userTokenAddress = Mint.getAssociatedAddress(user);
|
||||
const account = await spl.getAccount(this.connection, userTokenAddress);
|
||||
const userTokenAccountInfo = await this.provider.connection.getAccountInfo(
|
||||
userTokenAddress
|
||||
);
|
||||
if (userTokenAccountInfo === null) {
|
||||
return null;
|
||||
}
|
||||
const account = spl.unpackAccount(userTokenAddress, userTokenAccountInfo);
|
||||
return account;
|
||||
}
|
||||
|
||||
public async getBalance(user: PublicKey): Promise<number> {
|
||||
public async getBalance(user: PublicKey): Promise<number | null> {
|
||||
const userAccount = await this.getAccount(user);
|
||||
if (userAccount === null) {
|
||||
return null;
|
||||
}
|
||||
return this.fromTokenAmount(userAccount.amount);
|
||||
}
|
||||
|
||||
|
@ -147,7 +156,7 @@ export class Mint {
|
|||
Mint.native,
|
||||
owner
|
||||
);
|
||||
return [account, new TransactionObject(payer, [ixn], user ? [user] : [])];
|
||||
return [account, new TransactionObject(payer, [ixn], [])];
|
||||
}
|
||||
|
||||
public createUserInstruction(
|
||||
|
@ -179,6 +188,8 @@ export class Mint {
|
|||
throw new NativeMintOnlyError();
|
||||
}
|
||||
|
||||
const ixns: TransactionInstruction[] = [];
|
||||
|
||||
const owner = user ? user.publicKey : payer;
|
||||
|
||||
const ownerBalance = new Big(await this.connection.getBalance(owner));
|
||||
|
@ -189,6 +200,16 @@ export class Mint {
|
|||
userAccountInfo === null
|
||||
? null
|
||||
: spl.unpackAccount(userAddress, userAccountInfo);
|
||||
// if (userAccount === null) {
|
||||
// ixns.push(
|
||||
// spl.createAssociatedTokenAccountInstruction(
|
||||
// payer,
|
||||
// userAddress,
|
||||
// owner,
|
||||
// Mint.native
|
||||
// )
|
||||
// );
|
||||
// }
|
||||
|
||||
const balance = userAccount
|
||||
? new Big(this.fromTokenAmount(userAccount.amount))
|
||||
|
@ -219,7 +240,7 @@ export class Mint {
|
|||
|
||||
const wrapAmountLamports = this.toTokenAmount(wrapAmount.toNumber());
|
||||
|
||||
const ixns = [
|
||||
ixns.push(
|
||||
spl.createAssociatedTokenAccountInstruction(
|
||||
payer,
|
||||
ephemeralWallet,
|
||||
|
@ -242,8 +263,8 @@ export class Mint {
|
|||
ephemeralWallet,
|
||||
owner,
|
||||
ephemeralAccount.publicKey
|
||||
),
|
||||
];
|
||||
)
|
||||
);
|
||||
|
||||
return new TransactionObject(
|
||||
payer,
|
||||
|
@ -286,7 +307,7 @@ export class Mint {
|
|||
const signers: Keypair[] = user ? [user] : [];
|
||||
|
||||
const userAddress = this.getAssociatedAddress(owner);
|
||||
const userBalance = await this.getBalance(owner);
|
||||
const userBalance = (await this.getBalance(owner)) ?? 0;
|
||||
|
||||
if (amount) {
|
||||
if (amount >= userBalance) {
|
||||
|
|
|
@ -376,27 +376,6 @@ export class SwitchboardProgram {
|
|||
|
||||
return txnSignature;
|
||||
}
|
||||
|
||||
public async signAndSendTransaction(
|
||||
instructions: TransactionInstruction[],
|
||||
signers?: Signer[]
|
||||
): Promise<TransactionSignature> {
|
||||
if (isBrowser) throw new errors.SwitchboardProgramIsBrowserError();
|
||||
if (this.isReadOnly) throw new errors.SwitchboardProgramReadOnlyError();
|
||||
|
||||
const txnSignature = await this.provider.sendAndConfirm(
|
||||
await this.provider.wallet.signTransaction(
|
||||
new Transaction({
|
||||
feePayer: this.provider.wallet.publicKey,
|
||||
...(await this.connection.getLatestBlockhash()),
|
||||
}).add(...instructions)
|
||||
),
|
||||
signers,
|
||||
{ skipPreflight: false, maxRetries: 10 }
|
||||
);
|
||||
|
||||
return txnSignature;
|
||||
}
|
||||
}
|
||||
|
||||
export class AnchorWallet implements anchor.Wallet {
|
||||
|
|
|
@ -50,6 +50,8 @@ describe('Aggregator Tests', () => {
|
|||
|
||||
queueAccount = oracleQueue;
|
||||
|
||||
await ctx.program.mint.getOrCreateAssociatedUser(ctx.program.walletPubkey);
|
||||
|
||||
// add a single oracle for open round calls
|
||||
await queueAccount.createOracle({
|
||||
name: 'oracle-1',
|
||||
|
@ -222,9 +224,8 @@ describe('Aggregator Tests', () => {
|
|||
);
|
||||
}
|
||||
|
||||
const finalUserTokenBalance = await ctx.program.mint.getBalance(
|
||||
ctx.payer.publicKey
|
||||
);
|
||||
const finalUserTokenBalance =
|
||||
(await ctx.program.mint.getBalance(ctx.payer.publicKey)) ?? 0;
|
||||
if (initialUserTokenBalance !== finalUserTokenBalance) {
|
||||
throw new Error(
|
||||
`User token balance has incorrect funds, expected ${initialUserTokenBalance} wSOL, received ${finalUserTokenBalance}`
|
||||
|
|
|
@ -27,10 +27,8 @@ describe('Mint Tests', () => {
|
|||
await ctx.program.mint.createAssocatedUser(ctx.payer.publicKey, user);
|
||||
userTokenAddress = tokenAddress;
|
||||
|
||||
const userTokenAccount = await ctx.program.mint.getAccount(user.publicKey);
|
||||
const userTokenBalance = ctx.program.mint.fromTokenAmount(
|
||||
userTokenAccount.amount
|
||||
);
|
||||
const userTokenBalance =
|
||||
(await ctx.program.mint.getBalance(user.publicKey)) ?? 0;
|
||||
|
||||
if (userTokenBalance !== 0) {
|
||||
throw new Error(
|
||||
|
@ -50,10 +48,8 @@ describe('Mint Tests', () => {
|
|||
user
|
||||
);
|
||||
|
||||
const userTokenAccount = await ctx.program.mint.getAccount(user.publicKey);
|
||||
const userTokenBalance = ctx.program.mint.fromTokenAmount(
|
||||
userTokenAccount.amount
|
||||
);
|
||||
const userTokenBalance =
|
||||
(await ctx.program.mint.getBalance(user.publicKey)) ?? 0;
|
||||
if (userTokenBalance !== 0.25) {
|
||||
throw new Error(
|
||||
`Incorrect user token balance, expected 0.25, received ${userTokenBalance}`
|
||||
|
@ -66,12 +62,8 @@ describe('Mint Tests', () => {
|
|||
throw new Error(`User token address does not exist`);
|
||||
}
|
||||
|
||||
const initialUserTokenAccount = await ctx.program.mint.getAccount(
|
||||
user.publicKey
|
||||
);
|
||||
const initialUserTokenBalance = ctx.program.mint.fromTokenAmount(
|
||||
initialUserTokenAccount.amount
|
||||
);
|
||||
const initialUserTokenBalance =
|
||||
(await ctx.program.mint.getBalance(user.publicKey)) ?? 0;
|
||||
const expectedFinalBalance = initialUserTokenBalance - 0.1;
|
||||
if (expectedFinalBalance < 0) {
|
||||
throw new Error(`Final user token address would be negative`);
|
||||
|
|
|
@ -74,6 +74,8 @@ export async function setupTest(): Promise<TestContext> {
|
|||
console.error(e);
|
||||
}
|
||||
|
||||
await program.mint.getOrCreateAssociatedUser(program.walletPubkey);
|
||||
|
||||
return {
|
||||
cluster,
|
||||
program,
|
||||
|
|
|
@ -1426,7 +1426,7 @@ export class AggregatorAccount {
|
|||
mint: params.tokenMint,
|
||||
})
|
||||
.remainingAccounts(
|
||||
remainingAccounts.map((pubkey: PublicKey) => {
|
||||
remainingAccounts.map((pubkey: PublicKey): AccountMeta => {
|
||||
return { isSigner: false, isWritable: true, pubkey };
|
||||
})
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue