feat: add API for decoding system instructions
This commit is contained in:
parent
662ce22cdd
commit
6ed2bad9d0
|
@ -475,6 +475,65 @@ declare module '@solana/web3.js' {
|
|||
}
|
||||
|
||||
// === src/system-program.js ===
|
||||
export type CreateAccountParams = {
|
||||
fromPubkey: PublicKey;
|
||||
newAccountPubkey: PublicKey;
|
||||
lamports: number;
|
||||
space: number;
|
||||
programId: PublicKey;
|
||||
};
|
||||
|
||||
export type TransferParams = {
|
||||
fromPubkey: PublicKey;
|
||||
toPubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type AssignParams = {
|
||||
fromPubkey: PublicKey;
|
||||
programId: PublicKey;
|
||||
};
|
||||
|
||||
export type CreateAccountWithSeedParams = {
|
||||
fromPubkey: PublicKey;
|
||||
newAccountPubkey: PublicKey;
|
||||
basePubkey: PublicKey;
|
||||
seed: string;
|
||||
lamports: number;
|
||||
space: number;
|
||||
programId: PublicKey;
|
||||
};
|
||||
|
||||
export type CreateNonceAccountParams = {
|
||||
fromPubkey: PublicKey;
|
||||
noncePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type InitializeNonceParams = {
|
||||
noncePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
};
|
||||
|
||||
export type AdvanceNonceParams = {
|
||||
noncePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
};
|
||||
|
||||
export type WithdrawNonceParams = {
|
||||
noncePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
toPubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type AuthorizeNonceParams = {
|
||||
noncePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
newAuthorizedPubkey: PublicKey;
|
||||
};
|
||||
|
||||
export class SystemProgram {
|
||||
static programId: PublicKey;
|
||||
static nonceSpace: number;
|
||||
|
@ -538,17 +597,30 @@ declare module '@solana/web3.js' {
|
|||
[type in SystemInstructionType]: InstructionType;
|
||||
};
|
||||
|
||||
export class SystemInstruction extends TransactionInstruction {
|
||||
type: SystemInstructionType;
|
||||
fromPublicKey: PublicKey | null;
|
||||
toPublicKey: PublicKey | null;
|
||||
amount: number | null;
|
||||
|
||||
constructor(
|
||||
opts: TransactionInstructionCtorFields,
|
||||
type: SystemInstructionType,
|
||||
);
|
||||
static from(instruction: TransactionInstruction): SystemInstruction;
|
||||
export class SystemInstruction {
|
||||
static decodeInstructionType(
|
||||
instruction: TransactionInstruction,
|
||||
): SystemInstructionType;
|
||||
static decodeCreateAccount(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountParams;
|
||||
static decodeTransfer(instruction: TransactionInstruction): TransferParams;
|
||||
static decodeAssign(instruction: TransactionInstruction): AssignParams;
|
||||
static decodeCreateWithSeed(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountWithSeedParams;
|
||||
static decodeNonceInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeNonceParams;
|
||||
static decodeNonceAdvance(
|
||||
instruction: TransactionInstruction,
|
||||
): AdvanceNonceParams;
|
||||
static decodeNonceWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawNonceParams;
|
||||
static decodeNonceAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeNonceParams;
|
||||
}
|
||||
|
||||
// === src/loader.js ===
|
||||
|
|
|
@ -371,53 +371,79 @@ declare module '@solana/web3.js' {
|
|||
}
|
||||
|
||||
// === src/system-program.js ===
|
||||
declare export type CreateAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
newAccountPubkey: PublicKey,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type TransferParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type AssignParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type CreateAccountWithSeedParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
newAccountPubkey: PublicKey,
|
||||
basePubkey: PublicKey,
|
||||
seed: string,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type CreateNonceAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type InitializeNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type AdvanceNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type WithdrawNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type AuthorizeNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
declare export class SystemProgram {
|
||||
static programId: PublicKey;
|
||||
static nonceSpace: number;
|
||||
|
||||
static createAccount(
|
||||
from: PublicKey,
|
||||
newAccount: PublicKey,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
): Transaction;
|
||||
static transfer(
|
||||
from: PublicKey,
|
||||
to: PublicKey,
|
||||
amount: number,
|
||||
): Transaction;
|
||||
static assign(from: PublicKey, programId: PublicKey): Transaction;
|
||||
static createAccount(params: CreateAccountParams): Transaction;
|
||||
static transfer(params: TransferParams): Transaction;
|
||||
static assign(params: AssignParams): Transaction;
|
||||
static createAccountWithSeed(
|
||||
from: PublicKey,
|
||||
newAccount: PublicKey,
|
||||
base: PublicKey,
|
||||
seed: string,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
): Transaction;
|
||||
static createNonceAccount(
|
||||
from: PublicKey,
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static nonceAdvance(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
): TransactionInstruction;
|
||||
static nonceWithdraw(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static nonceAuthorize(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorized: PublicKey,
|
||||
params: CreateAccountWithSeedParams,
|
||||
): Transaction;
|
||||
static createNonceAccount(params: CreateNonceAccountParams): Transaction;
|
||||
static nonceAdvance(params: AdvanceNonceParams): TransactionInstruction;
|
||||
static nonceWithdraw(params: WithdrawNonceParams): Transaction;
|
||||
static nonceAuthorize(params: AuthorizeNonceParams): Transaction;
|
||||
}
|
||||
|
||||
declare export type SystemInstructionType =
|
||||
|
@ -434,17 +460,27 @@ declare module '@solana/web3.js' {
|
|||
[SystemInstructionType]: InstructionType,
|
||||
};
|
||||
|
||||
declare export class SystemInstruction extends TransactionInstruction {
|
||||
type: SystemInstructionType;
|
||||
fromPublicKey: PublicKey | null;
|
||||
toPublicKey: PublicKey | null;
|
||||
amount: number | null;
|
||||
|
||||
constructor(
|
||||
opts?: TransactionInstructionCtorFields,
|
||||
type: SystemInstructionType,
|
||||
): SystemInstruction;
|
||||
static from(instruction: TransactionInstruction): SystemInstruction;
|
||||
declare export class SystemInstruction {
|
||||
static decodeCreateAccount(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountParams;
|
||||
static decodeTransfer(instruction: TransactionInstruction): TransferParams;
|
||||
static decodeAssign(instruction: TransactionInstruction): AssignParams;
|
||||
static decodeCreateWithSeed(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountWithSeedParams;
|
||||
static decodeNonceInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeNonceParams;
|
||||
static decodeNonceAdvance(
|
||||
instruction: TransactionInstruction,
|
||||
): AdvanceNonceParams;
|
||||
static decodeNonceWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawNonceParams;
|
||||
static decodeNonceAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeNonceParams;
|
||||
}
|
||||
|
||||
// === src/validator-info.js ===
|
||||
|
|
|
@ -191,13 +191,13 @@ export class BudgetProgram {
|
|||
}
|
||||
const trimmedData = data.slice(0, pos);
|
||||
|
||||
const transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
program,
|
||||
amount,
|
||||
trimmedData.length,
|
||||
this.programId,
|
||||
);
|
||||
const transaction = SystemProgram.createAccount({
|
||||
fromPubkey: from,
|
||||
newAccountPubkey: program,
|
||||
lamports: amount,
|
||||
space: trimmedData.length,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
return transaction.add({
|
||||
keys: [
|
||||
|
@ -227,13 +227,13 @@ export class BudgetProgram {
|
|||
}
|
||||
const trimmedData = data.slice(0, pos);
|
||||
|
||||
const transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
program,
|
||||
amount,
|
||||
trimmedData.length,
|
||||
this.programId,
|
||||
);
|
||||
const transaction = SystemProgram.createAccount({
|
||||
fromPubkey: from,
|
||||
newAccountPubkey: program,
|
||||
lamports: amount,
|
||||
space: trimmedData.length,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
return transaction.add({
|
||||
keys: [{pubkey: program, isSigner: false, isWritable: true}],
|
||||
|
@ -260,13 +260,13 @@ export class BudgetProgram {
|
|||
}
|
||||
const trimmedData = data.slice(0, pos);
|
||||
|
||||
const transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
program,
|
||||
amount,
|
||||
trimmedData.length,
|
||||
this.programId,
|
||||
);
|
||||
const transaction = SystemProgram.createAccount({
|
||||
fromPubkey: from,
|
||||
newAccountPubkey: program,
|
||||
lamports: amount,
|
||||
space: trimmedData.length,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
return transaction.add({
|
||||
keys: [{pubkey: program, isSigner: false, isWritable: true}],
|
||||
|
@ -316,13 +316,13 @@ export class BudgetProgram {
|
|||
|
||||
const trimmedData = data.slice(0, pos);
|
||||
|
||||
const transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
program,
|
||||
amount,
|
||||
trimmedData.length,
|
||||
this.programId,
|
||||
);
|
||||
const transaction = SystemProgram.createAccount({
|
||||
fromPubkey: from,
|
||||
newAccountPubkey: program,
|
||||
lamports: amount,
|
||||
space: trimmedData.length,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
return transaction.add({
|
||||
keys: [{pubkey: program, isSigner: false, isWritable: true}],
|
||||
|
|
|
@ -58,13 +58,13 @@ export class Loader {
|
|||
const balanceNeeded = await connection.getMinimumBalanceForRentExemption(
|
||||
data.length,
|
||||
);
|
||||
const transaction = SystemProgram.createAccount(
|
||||
payer.publicKey,
|
||||
program.publicKey,
|
||||
balanceNeeded > 0 ? balanceNeeded : 1,
|
||||
data.length,
|
||||
const transaction = SystemProgram.createAccount({
|
||||
fromPubkey: payer.publicKey,
|
||||
newAccountPubkey: program.publicKey,
|
||||
lamports: balanceNeeded > 0 ? balanceNeeded : 1,
|
||||
space: data.length,
|
||||
programId,
|
||||
);
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, payer, program);
|
||||
}
|
||||
|
||||
|
|
|
@ -463,15 +463,15 @@ export class StakeProgram {
|
|||
static createAccountWithSeed(
|
||||
params: CreateStakeAccountWithSeedParams,
|
||||
): Transaction {
|
||||
let transaction = SystemProgram.createAccountWithSeed(
|
||||
params.fromPubkey,
|
||||
params.stakePubkey,
|
||||
params.basePubkey,
|
||||
params.seed,
|
||||
params.lamports,
|
||||
this.space,
|
||||
this.programId,
|
||||
);
|
||||
let transaction = SystemProgram.createAccountWithSeed({
|
||||
fromPubkey: params.fromPubkey,
|
||||
newAccountPubkey: params.stakePubkey,
|
||||
basePubkey: params.basePubkey,
|
||||
seed: params.seed,
|
||||
lamports: params.lamports,
|
||||
space: this.space,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
|
||||
|
@ -481,13 +481,13 @@ export class StakeProgram {
|
|||
* Generate a Transaction that creates a new Stake account
|
||||
*/
|
||||
static createAccount(params: CreateStakeAccountParams): Transaction {
|
||||
let transaction = SystemProgram.createAccount(
|
||||
params.fromPubkey,
|
||||
params.stakePubkey,
|
||||
params.lamports,
|
||||
this.space,
|
||||
this.programId,
|
||||
);
|
||||
let transaction = SystemProgram.createAccount({
|
||||
fromPubkey: params.fromPubkey,
|
||||
newAccountPubkey: params.stakePubkey,
|
||||
lamports: params.lamports,
|
||||
space: this.space,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
|
||||
|
@ -557,13 +557,13 @@ export class StakeProgram {
|
|||
static split(params: SplitStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, splitStakePubkey, lamports} = params;
|
||||
|
||||
let transaction = SystemProgram.createAccount(
|
||||
stakePubkey,
|
||||
splitStakePubkey,
|
||||
0,
|
||||
this.space,
|
||||
this.programId,
|
||||
);
|
||||
let transaction = SystemProgram.createAccount({
|
||||
fromPubkey: stakePubkey,
|
||||
newAccountPubkey: splitStakePubkey,
|
||||
lamports: 0,
|
||||
space: this.space,
|
||||
programId: this.programId,
|
||||
});
|
||||
transaction.instructions[0].keys[0].isSigner = false;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Split;
|
||||
const data = encodeData(type, {lamports});
|
||||
|
|
|
@ -2,116 +2,351 @@
|
|||
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
|
||||
import {encodeData} from './instruction';
|
||||
import {encodeData, decodeData} from './instruction';
|
||||
import * as Layout from './layout';
|
||||
import {PublicKey} from './publickey';
|
||||
import {SYSVAR_RECENT_BLOCKHASHES_PUBKEY, SYSVAR_RENT_PUBKEY} from './sysvar';
|
||||
import {Transaction, TransactionInstruction} from './transaction';
|
||||
import type {TransactionInstructionCtorFields} from './transaction';
|
||||
|
||||
/**
|
||||
* Create account system transaction params
|
||||
* @typedef {Object} CreateAccountParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} newAccountPubkey
|
||||
* @property {number} lamports
|
||||
* @property {number} space
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type CreateAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
newAccountPubkey: PublicKey,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Transfer system transaction params
|
||||
* @typedef {Object} TransferParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} toPubkey
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type TransferParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Assign system transaction params
|
||||
* @typedef {Object} AssignParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type AssignParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Create account with seed system transaction params
|
||||
* @typedef {Object} CreateAccountWithSeedParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} newAccountPubkey
|
||||
* @property {PublicKey} basePubkey
|
||||
* @property {string} seed
|
||||
* @property {number} lamports
|
||||
* @property {number} space
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type CreateAccountWithSeedParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
newAccountPubkey: PublicKey,
|
||||
basePubkey: PublicKey,
|
||||
seed: string,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Create nonce account system transaction params
|
||||
* @typedef {Object} AssignParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type CreateNonceAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Initialize nonce account system instruction params
|
||||
* @typedef {Object} InitializeNonceParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type InitializeNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Advance nonce account system instruction params
|
||||
* @typedef {Object} AdvanceNonceParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type AdvanceNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Withdraw nonce account system transaction params
|
||||
* @typedef {Object} WithdrawNonceParams
|
||||
* @property {PublicKey} noncePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} toPubkey
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type WithdrawNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Authorize nonce account system transaction params
|
||||
* @typedef {Object} AuthorizeNonceParams
|
||||
* @property {PublicKey} noncePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} newAuthorizedPubkey
|
||||
*/
|
||||
export type AuthorizeNonceParams = {|
|
||||
noncePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* System Instruction class
|
||||
*/
|
||||
export class SystemInstruction extends TransactionInstruction {
|
||||
export class SystemInstruction {
|
||||
/**
|
||||
* Type of SystemInstruction
|
||||
* Decode a system instruction and retrieve the instruction type.
|
||||
*/
|
||||
_type: SystemInstructionType;
|
||||
|
||||
constructor(
|
||||
opts?: TransactionInstructionCtorFields,
|
||||
type: SystemInstructionType,
|
||||
) {
|
||||
if (
|
||||
opts &&
|
||||
opts.programId &&
|
||||
!opts.programId.equals(SystemProgram.programId)
|
||||
) {
|
||||
throw new Error('programId incorrect; not a SystemInstruction');
|
||||
}
|
||||
super(opts);
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
static from(instruction: TransactionInstruction): SystemInstruction {
|
||||
if (!instruction.programId.equals(SystemProgram.programId)) {
|
||||
throw new Error('programId incorrect; not SystemProgram');
|
||||
}
|
||||
static decodeInstructionType(
|
||||
instruction: TransactionInstruction,
|
||||
): SystemInstructionType {
|
||||
this.checkProgramId(instruction.programId);
|
||||
|
||||
const instructionTypeLayout = BufferLayout.u32('instruction');
|
||||
const typeIndex = instructionTypeLayout.decode(instruction.data);
|
||||
|
||||
let type;
|
||||
for (const t of Object.keys(SYSTEM_INSTRUCTION_LAYOUTS)) {
|
||||
if (SYSTEM_INSTRUCTION_LAYOUTS[t].index == typeIndex) {
|
||||
type = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
throw new Error('Instruction type incorrect; not a SystemInstruction');
|
||||
}
|
||||
return new SystemInstruction(
|
||||
{
|
||||
keys: instruction.keys,
|
||||
programId: instruction.programId,
|
||||
data: instruction.data,
|
||||
},
|
||||
type,
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a create account system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeCreateAccount(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {lamports, space, programId} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.Create,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
fromPubkey: instruction.keys[0].pubkey,
|
||||
newAccountPubkey: instruction.keys[1].pubkey,
|
||||
lamports,
|
||||
space,
|
||||
programId: new PublicKey(programId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of SystemInstruction
|
||||
* Decode a transfer system instruction and retrieve the instruction params.
|
||||
*/
|
||||
get type(): SystemInstructionType {
|
||||
return this._type;
|
||||
static decodeTransfer(instruction: TransactionInstruction): TransferParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {lamports} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.Transfer,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
fromPubkey: instruction.keys[0].pubkey,
|
||||
toPubkey: instruction.keys[1].pubkey,
|
||||
lamports,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The `from` public key of the instruction;
|
||||
* returns null if SystemInstructionType does not support this field
|
||||
* Decode an assign system instruction and retrieve the instruction params.
|
||||
*/
|
||||
get fromPublicKey(): PublicKey | null {
|
||||
switch (this.type) {
|
||||
case 'Create':
|
||||
case 'CreateWithSeed':
|
||||
case 'WithdrawNonceAccount':
|
||||
case 'Transfer':
|
||||
return this.keys[0].pubkey;
|
||||
default:
|
||||
return null;
|
||||
static decodeAssign(instruction: TransactionInstruction): AssignParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 1);
|
||||
|
||||
const {programId} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.Assign,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
fromPubkey: instruction.keys[0].pubkey,
|
||||
programId: new PublicKey(programId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a create account with seed system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeCreateWithSeed(
|
||||
instruction: TransactionInstruction,
|
||||
): CreateAccountWithSeedParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {base, seed, lamports, space, programId} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.CreateWithSeed,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
fromPubkey: instruction.keys[0].pubkey,
|
||||
newAccountPubkey: instruction.keys[1].pubkey,
|
||||
basePubkey: new PublicKey(base),
|
||||
seed,
|
||||
lamports,
|
||||
space,
|
||||
programId: new PublicKey(programId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a nonce initialize system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeNonceInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeNonceParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
|
||||
const {authorized} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
noncePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: new PublicKey(authorized),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a nonce advance system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeNonceAdvance(
|
||||
instruction: TransactionInstruction,
|
||||
): AdvanceNonceParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
|
||||
decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.AdvanceNonceAccount,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
noncePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: instruction.keys[2].pubkey,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a nonce withdraw system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeNonceWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawNonceParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 5);
|
||||
|
||||
const {lamports} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.WithdrawNonceAccount,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
noncePubkey: instruction.keys[0].pubkey,
|
||||
toPubkey: instruction.keys[1].pubkey,
|
||||
authorizedPubkey: instruction.keys[4].pubkey,
|
||||
lamports,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a nonce authorize system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeNonceAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeNonceParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {authorized} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.AuthorizeNonceAccount,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
noncePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: instruction.keys[1].pubkey,
|
||||
newAuthorizedPubkey: new PublicKey(authorized),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static checkProgramId(programId: PublicKey) {
|
||||
if (!programId.equals(SystemProgram.programId)) {
|
||||
throw new Error('invalid instruction; programId is not SystemProgram');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `to` public key of the instruction;
|
||||
* returns null if SystemInstructionType does not support this field
|
||||
* @private
|
||||
*/
|
||||
get toPublicKey(): PublicKey | null {
|
||||
switch (this.type) {
|
||||
case 'Create':
|
||||
case 'CreateWithSeed':
|
||||
case 'WithdrawNonceAccount':
|
||||
case 'Transfer':
|
||||
return this.keys[1].pubkey;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `amount` or `lamports` of the instruction;
|
||||
* returns null if SystemInstructionType does not support this field
|
||||
*/
|
||||
get amount(): number | null {
|
||||
const data = SYSTEM_INSTRUCTION_LAYOUTS[this.type].layout.decode(this.data);
|
||||
switch (this.type) {
|
||||
case 'Create':
|
||||
case 'CreateWithSeed':
|
||||
case 'WithdrawNonceAccount':
|
||||
case 'Transfer':
|
||||
return data.lamports;
|
||||
default:
|
||||
return null;
|
||||
static checkKeyLength(keys: Array<any>, expectedLength: number) {
|
||||
if (keys.length !== expectedLength) {
|
||||
throw new Error(
|
||||
`invalid instruction; key length mismatch ${keys.length} != ${expectedLength}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,24 +447,18 @@ export class SystemProgram {
|
|||
/**
|
||||
* Generate a Transaction that creates a new account
|
||||
*/
|
||||
static createAccount(
|
||||
from: PublicKey,
|
||||
newAccount: PublicKey,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
): Transaction {
|
||||
static createAccount(params: CreateAccountParams): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Create;
|
||||
const data = encodeData(type, {
|
||||
lamports,
|
||||
space,
|
||||
programId: programId.toBuffer(),
|
||||
lamports: params.lamports,
|
||||
space: params.space,
|
||||
programId: params.programId.toBuffer(),
|
||||
});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true, isWritable: true},
|
||||
{pubkey: newAccount, isSigner: true, isWritable: true},
|
||||
{pubkey: params.fromPubkey, isSigner: true, isWritable: true},
|
||||
{pubkey: params.newAccountPubkey, isSigner: true, isWritable: true},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -239,18 +468,14 @@ export class SystemProgram {
|
|||
/**
|
||||
* Generate a Transaction that transfers lamports from one account to another
|
||||
*/
|
||||
static transfer(
|
||||
from: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction {
|
||||
static transfer(params: TransferParams): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer;
|
||||
const data = encodeData(type, {lamports});
|
||||
const data = encodeData(type, {lamports: params.lamports});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true, isWritable: true},
|
||||
{pubkey: to, isSigner: false, isWritable: true},
|
||||
{pubkey: params.fromPubkey, isSigner: true, isWritable: true},
|
||||
{pubkey: params.toPubkey, isSigner: false, isWritable: true},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -260,12 +485,12 @@ export class SystemProgram {
|
|||
/**
|
||||
* Generate a Transaction that assigns an account to a program
|
||||
*/
|
||||
static assign(from: PublicKey, programId: PublicKey): Transaction {
|
||||
static assign(params: AssignParams): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Assign;
|
||||
const data = encodeData(type, {programId: programId.toBuffer()});
|
||||
const data = encodeData(type, {programId: params.programId.toBuffer()});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [{pubkey: from, isSigner: true, isWritable: true}],
|
||||
keys: [{pubkey: params.fromPubkey, isSigner: true, isWritable: true}],
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
|
@ -276,27 +501,21 @@ export class SystemProgram {
|
|||
* an address generated with `from`, a seed, and programId
|
||||
*/
|
||||
static createAccountWithSeed(
|
||||
from: PublicKey,
|
||||
newAccount: PublicKey,
|
||||
base: PublicKey,
|
||||
seed: string,
|
||||
lamports: number,
|
||||
space: number,
|
||||
programId: PublicKey,
|
||||
params: CreateAccountWithSeedParams,
|
||||
): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.CreateWithSeed;
|
||||
const data = encodeData(type, {
|
||||
base: base.toBuffer(),
|
||||
seed,
|
||||
lamports,
|
||||
space,
|
||||
programId: programId.toBuffer(),
|
||||
base: params.basePubkey.toBuffer(),
|
||||
seed: params.seed,
|
||||
lamports: params.lamports,
|
||||
space: params.space,
|
||||
programId: params.programId.toBuffer(),
|
||||
});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: from, isSigner: true, isWritable: true},
|
||||
{pubkey: newAccount, isSigner: false, isWritable: true},
|
||||
{pubkey: params.fromPubkey, isSigner: true, isWritable: true},
|
||||
{pubkey: params.newAccountPubkey, isSigner: false, isWritable: true},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -306,28 +525,37 @@ export class SystemProgram {
|
|||
/**
|
||||
* Generate a Transaction that creates a new Nonce account
|
||||
*/
|
||||
static createNonceAccount(
|
||||
from: PublicKey,
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction {
|
||||
let transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
nonceAccount,
|
||||
lamports,
|
||||
this.nonceSpace,
|
||||
this.programId,
|
||||
);
|
||||
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount;
|
||||
const data = encodeData(type, {
|
||||
authorized: authorizedPubkey.toBuffer(),
|
||||
static createNonceAccount(params: CreateNonceAccountParams): Transaction {
|
||||
let transaction = SystemProgram.createAccount({
|
||||
fromPubkey: params.fromPubkey,
|
||||
newAccountPubkey: params.noncePubkey,
|
||||
lamports: params.lamports,
|
||||
space: this.nonceSpace,
|
||||
programId: this.programId,
|
||||
});
|
||||
|
||||
return transaction.add({
|
||||
const initParams = {
|
||||
noncePubkey: params.noncePubkey,
|
||||
authorizedPubkey: params.authorizedPubkey,
|
||||
};
|
||||
|
||||
transaction.add(this.nonceInitialize(initParams));
|
||||
return transaction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an instruction to initialize a Nonce account
|
||||
*/
|
||||
static nonceInitialize(
|
||||
params: InitializeNonceParams,
|
||||
): TransactionInstruction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.InitializeNonceAccount;
|
||||
const data = encodeData(type, {
|
||||
authorized: params.authorizedPubkey.toBuffer(),
|
||||
});
|
||||
const instructionData = {
|
||||
keys: [
|
||||
{pubkey: nonceAccount, isSigner: false, isWritable: true},
|
||||
{pubkey: params.noncePubkey, isSigner: false, isWritable: true},
|
||||
{
|
||||
pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
isSigner: false,
|
||||
|
@ -337,27 +565,25 @@ export class SystemProgram {
|
|||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
};
|
||||
return new TransactionInstruction(instructionData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an instruction to advance the nonce in a Nonce account
|
||||
*/
|
||||
static nonceAdvance(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
): TransactionInstruction {
|
||||
static nonceAdvance(params: AdvanceNonceParams): TransactionInstruction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.AdvanceNonceAccount;
|
||||
const data = encodeData(type);
|
||||
const instructionData = {
|
||||
keys: [
|
||||
{pubkey: nonceAccount, isSigner: false, isWritable: true},
|
||||
{pubkey: params.noncePubkey, isSigner: false, isWritable: true},
|
||||
{
|
||||
pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
{pubkey: params.authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -368,19 +594,14 @@ export class SystemProgram {
|
|||
/**
|
||||
* Generate a Transaction that withdraws lamports from a Nonce account
|
||||
*/
|
||||
static nonceWithdraw(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction {
|
||||
static nonceWithdraw(params: WithdrawNonceParams): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.WithdrawNonceAccount;
|
||||
const data = encodeData(type, {lamports});
|
||||
const data = encodeData(type, {lamports: params.lamports});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: nonceAccount, isSigner: false, isWritable: true},
|
||||
{pubkey: to, isSigner: false, isWritable: true},
|
||||
{pubkey: params.noncePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: params.toPubkey, isSigner: false, isWritable: true},
|
||||
{
|
||||
pubkey: SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
|
||||
isSigner: false,
|
||||
|
@ -391,7 +612,7 @@ export class SystemProgram {
|
|||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
{pubkey: params.authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
@ -402,20 +623,16 @@ export class SystemProgram {
|
|||
* Generate a Transaction that authorizes a new PublicKey as the authority
|
||||
* on a Nonce account.
|
||||
*/
|
||||
static nonceAuthorize(
|
||||
nonceAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorized: PublicKey,
|
||||
): Transaction {
|
||||
static nonceAuthorize(params: AuthorizeNonceParams): Transaction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.AuthorizeNonceAccount;
|
||||
const data = encodeData(type, {
|
||||
newAuthorized: newAuthorized.toBuffer(),
|
||||
authorized: params.newAuthorizedPubkey.toBuffer(),
|
||||
});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: nonceAccount, isSigner: false, isWritable: true},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
{pubkey: params.noncePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: params.authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
|
|
|
@ -109,10 +109,10 @@ test('get program accounts', async () => {
|
|||
result: {Ok: null},
|
||||
},
|
||||
]);
|
||||
let transaction = SystemProgram.assign(
|
||||
account0.publicKey,
|
||||
programId.publicKey,
|
||||
);
|
||||
let transaction = SystemProgram.assign({
|
||||
fromPubkey: account0.publicKey,
|
||||
programId: programId.publicKey,
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, account0);
|
||||
|
||||
mockRpc.push([
|
||||
|
@ -140,7 +140,11 @@ test('get program accounts', async () => {
|
|||
result: {Ok: null},
|
||||
},
|
||||
]);
|
||||
transaction = SystemProgram.assign(account1.publicKey, programId.publicKey);
|
||||
transaction = SystemProgram.assign({
|
||||
fromPubkey: account1.publicKey,
|
||||
programId: programId.publicKey,
|
||||
});
|
||||
|
||||
await sendAndConfirmTransaction(connection, transaction, account1);
|
||||
|
||||
mockGetRecentBlockhash('recent');
|
||||
|
@ -651,14 +655,16 @@ test('get confirmed block', async () => {
|
|||
url,
|
||||
{
|
||||
method: 'getConfirmedBlock',
|
||||
params: [10000],
|
||||
params: [Number.MAX_SAFE_INTEGER],
|
||||
},
|
||||
{
|
||||
error: null,
|
||||
result: null,
|
||||
},
|
||||
]);
|
||||
await expect(connection.getConfirmedBlock(10000)).rejects.toThrow();
|
||||
await expect(
|
||||
connection.getConfirmedBlock(Number.MAX_SAFE_INTEGER),
|
||||
).rejects.toThrow();
|
||||
});
|
||||
|
||||
test('get recent blockhash', async () => {
|
||||
|
@ -962,11 +968,11 @@ test('transaction', async () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const transaction = SystemProgram.transfer(
|
||||
accountFrom.publicKey,
|
||||
accountTo.publicKey,
|
||||
10,
|
||||
);
|
||||
const transaction = SystemProgram.transfer({
|
||||
fromPubkey: accountFrom.publicKey,
|
||||
toPubkey: accountTo.publicKey,
|
||||
lamports: 10,
|
||||
});
|
||||
const signature = await connection.sendTransaction(transaction, accountFrom);
|
||||
|
||||
mockRpc.push([
|
||||
|
@ -1088,12 +1094,16 @@ test('multi-instruction transaction', async () => {
|
|||
|
||||
// 1. Move(accountFrom, accountTo)
|
||||
// 2. Move(accountTo, accountFrom)
|
||||
const transaction = SystemProgram.transfer(
|
||||
accountFrom.publicKey,
|
||||
accountTo.publicKey,
|
||||
100,
|
||||
).add(
|
||||
SystemProgram.transfer(accountTo.publicKey, accountFrom.publicKey, 100),
|
||||
const transaction = SystemProgram.transfer({
|
||||
fromPubkey: accountFrom.publicKey,
|
||||
toPubkey: accountTo.publicKey,
|
||||
lamports: 100,
|
||||
}).add(
|
||||
SystemProgram.transfer({
|
||||
fromPubkey: accountTo.publicKey,
|
||||
toPubkey: accountFrom.publicKey,
|
||||
lamports: 100,
|
||||
}),
|
||||
);
|
||||
const signature = await connection.sendTransaction(
|
||||
transaction,
|
||||
|
@ -1149,11 +1159,11 @@ test('account change notification', async () => {
|
|||
|
||||
await connection.requestAirdrop(owner.publicKey, LAMPORTS_PER_SOL);
|
||||
try {
|
||||
let transaction = SystemProgram.transfer(
|
||||
owner.publicKey,
|
||||
programAccount.publicKey,
|
||||
balanceNeeded,
|
||||
);
|
||||
let transaction = SystemProgram.transfer({
|
||||
fromPubkey: owner.publicKey,
|
||||
toPubkey: programAccount.publicKey,
|
||||
lamports: balanceNeeded,
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, owner);
|
||||
} catch (err) {
|
||||
await connection.removeAccountChangeListener(subscriptionId);
|
||||
|
@ -1213,11 +1223,11 @@ test('program account change notification', async () => {
|
|||
|
||||
await connection.requestAirdrop(owner.publicKey, LAMPORTS_PER_SOL);
|
||||
try {
|
||||
let transaction = SystemProgram.transfer(
|
||||
owner.publicKey,
|
||||
programAccount.publicKey,
|
||||
balanceNeeded,
|
||||
);
|
||||
let transaction = SystemProgram.transfer({
|
||||
fromPubkey: owner.publicKey,
|
||||
toPubkey: programAccount.publicKey,
|
||||
lamports: balanceNeeded,
|
||||
});
|
||||
await sendAndConfirmTransaction(connection, transaction, owner);
|
||||
} catch (err) {
|
||||
await connection.removeProgramAccountChangeListener(subscriptionId);
|
||||
|
|
|
@ -86,12 +86,12 @@ test('create and query nonce account', async () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const transaction = SystemProgram.createNonceAccount(
|
||||
from.publicKey,
|
||||
nonceAccount.publicKey,
|
||||
from.publicKey,
|
||||
minimumAmount,
|
||||
);
|
||||
const transaction = SystemProgram.createNonceAccount({
|
||||
fromPubkey: from.publicKey,
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: from.publicKey,
|
||||
lamports: minimumAmount,
|
||||
});
|
||||
await connection.sendTransaction(transaction, from, nonceAccount);
|
||||
|
||||
const expectedData = Buffer.alloc(68);
|
||||
|
|
|
@ -12,7 +12,6 @@ import {
|
|||
StakeInstruction,
|
||||
StakeProgram,
|
||||
SystemInstruction,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
} from '../src';
|
||||
import {mockRpcEnabled} from './__mocks__/node-fetch';
|
||||
|
@ -34,6 +33,7 @@ test('createAccountWithSeed', () => {
|
|||
const authorizedPubkey = new Account().publicKey;
|
||||
const authorized = new Authorized(authorizedPubkey, authorizedPubkey);
|
||||
const lockup = new Lockup(0, 0, fromPubkey);
|
||||
const lamports = 123;
|
||||
const transaction = StakeProgram.createAccountWithSeed({
|
||||
fromPubkey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
|
@ -41,19 +41,26 @@ test('createAccountWithSeed', () => {
|
|||
seed,
|
||||
authorized,
|
||||
lockup,
|
||||
lamports: 123,
|
||||
lamports,
|
||||
});
|
||||
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
const [systemInstruction, stakeInstruction] = transaction.instructions;
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
|
||||
// TODO decode system instruction
|
||||
|
||||
const params = StakeInstruction.decodeInitialize(stakeInstruction);
|
||||
expect(params.stakePubkey).toEqual(newAccountPubkey);
|
||||
expect(params.authorized).toEqual(authorized);
|
||||
expect(params.lockup).toEqual(lockup);
|
||||
const systemParams = {
|
||||
fromPubkey,
|
||||
newAccountPubkey,
|
||||
basePubkey: fromPubkey,
|
||||
seed,
|
||||
lamports,
|
||||
space: StakeProgram.space,
|
||||
programId: StakeProgram.programId,
|
||||
};
|
||||
expect(systemParams).toEqual(
|
||||
SystemInstruction.decodeCreateWithSeed(systemInstruction),
|
||||
);
|
||||
const initParams = {stakePubkey: newAccountPubkey, authorized, lockup};
|
||||
expect(initParams).toEqual(
|
||||
StakeInstruction.decodeInitialize(stakeInstruction),
|
||||
);
|
||||
});
|
||||
|
||||
test('createAccount', () => {
|
||||
|
@ -62,24 +69,31 @@ test('createAccount', () => {
|
|||
const authorizedPubkey = new Account().publicKey;
|
||||
const authorized = new Authorized(authorizedPubkey, authorizedPubkey);
|
||||
const lockup = new Lockup(0, 0, fromPubkey);
|
||||
const lamports = 123;
|
||||
const transaction = StakeProgram.createAccount({
|
||||
fromPubkey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorized,
|
||||
lockup,
|
||||
lamports: 123,
|
||||
lamports,
|
||||
});
|
||||
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
const [systemInstruction, stakeInstruction] = transaction.instructions;
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
const systemParams = {
|
||||
fromPubkey,
|
||||
newAccountPubkey,
|
||||
lamports,
|
||||
space: StakeProgram.space,
|
||||
programId: StakeProgram.programId,
|
||||
};
|
||||
expect(systemParams).toEqual(
|
||||
SystemInstruction.decodeCreateAccount(systemInstruction),
|
||||
);
|
||||
|
||||
// TODO decode system instruction
|
||||
|
||||
const params = StakeInstruction.decodeInitialize(stakeInstruction);
|
||||
expect(params.stakePubkey).toEqual(newAccountPubkey);
|
||||
expect(params.authorized).toEqual(authorized);
|
||||
expect(params.lockup).toEqual(lockup);
|
||||
const initParams = {stakePubkey: newAccountPubkey, authorized, lockup};
|
||||
expect(initParams).toEqual(
|
||||
StakeInstruction.decodeInitialize(stakeInstruction),
|
||||
);
|
||||
});
|
||||
|
||||
test('delegate', () => {
|
||||
|
@ -127,7 +141,16 @@ test('split', () => {
|
|||
const transaction = StakeProgram.split(params);
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
const [systemInstruction, stakeInstruction] = transaction.instructions;
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
const systemParams = {
|
||||
fromPubkey: stakePubkey,
|
||||
newAccountPubkey: splitStakePubkey,
|
||||
lamports: 0,
|
||||
space: StakeProgram.space,
|
||||
programId: StakeProgram.programId,
|
||||
};
|
||||
expect(systemParams).toEqual(
|
||||
SystemInstruction.decodeCreateAccount(systemInstruction),
|
||||
);
|
||||
expect(params).toEqual(StakeInstruction.decodeSplit(stakeInstruction));
|
||||
});
|
||||
|
||||
|
@ -182,13 +205,10 @@ test('StakeInstructions', () => {
|
|||
);
|
||||
|
||||
expect(createWithSeedTransaction.instructions).toHaveLength(2);
|
||||
const systemInstruction = SystemInstruction.from(
|
||||
const systemInstructionType = SystemInstruction.decodeInstructionType(
|
||||
createWithSeedTransaction.instructions[0],
|
||||
);
|
||||
expect(systemInstruction.fromPublicKey).toEqual(from.publicKey);
|
||||
expect(systemInstruction.toPublicKey).toEqual(newAccountPubkey);
|
||||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
expect(systemInstructionType).toEqual('CreateWithSeed');
|
||||
|
||||
const stakeInstructionType = StakeInstruction.decodeInstructionType(
|
||||
createWithSeedTransaction.instructions[1],
|
||||
|
@ -237,6 +257,35 @@ test('live staking actions', async () => {
|
|||
'recent',
|
||||
);
|
||||
|
||||
{
|
||||
// Create Stake account without seed
|
||||
const newStakeAccount = new Account();
|
||||
let createAndInitialize = StakeProgram.createAccount({
|
||||
fromPubkey: from.publicKey,
|
||||
stakePubkey: newStakeAccount.publicKey,
|
||||
authorized: new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
lockup: new Lockup(0, 0, new PublicKey('0x00')),
|
||||
lamports: minimumAmount + 42,
|
||||
});
|
||||
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
createAndInitialize,
|
||||
from,
|
||||
newStakeAccount,
|
||||
);
|
||||
expect(await connection.getBalance(newStakeAccount.publicKey)).toEqual(
|
||||
minimumAmount + 42,
|
||||
);
|
||||
|
||||
let delegation = StakeProgram.delegate({
|
||||
stakePubkey: newStakeAccount.publicKey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
votePubkey,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, delegation, authorized);
|
||||
}
|
||||
|
||||
// Create Stake account with seed
|
||||
const seed = 'test string';
|
||||
const newAccountPubkey = PublicKey.createWithSeed(
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
SystemInstruction,
|
||||
SystemProgram,
|
||||
Transaction,
|
||||
TransactionInstruction,
|
||||
sendAndConfirmRecentTransaction,
|
||||
LAMPORTS_PER_SOL,
|
||||
} from '../src';
|
||||
|
@ -20,219 +21,129 @@ if (!mockRpcEnabled) {
|
|||
}
|
||||
|
||||
test('createAccount', () => {
|
||||
const from = new Account();
|
||||
const newAccount = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = SystemProgram.createAccount(
|
||||
from.publicKey,
|
||||
newAccount.publicKey,
|
||||
123,
|
||||
BudgetProgram.space,
|
||||
BudgetProgram.programId,
|
||||
const params = {
|
||||
fromPubkey: new Account().publicKey,
|
||||
newAccountPubkey: new Account().publicKey,
|
||||
lamports: 123,
|
||||
space: BudgetProgram.space,
|
||||
programId: BudgetProgram.programId,
|
||||
};
|
||||
const transaction = SystemProgram.createAccount(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [systemInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(
|
||||
SystemInstruction.decodeCreateAccount(systemInstruction),
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(2);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
});
|
||||
|
||||
test('transfer', () => {
|
||||
const from = new Account();
|
||||
const to = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = SystemProgram.transfer(from.publicKey, to.publicKey, 123);
|
||||
|
||||
expect(transaction.keys).toHaveLength(2);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
const params = {
|
||||
fromPubkey: new Account().publicKey,
|
||||
toPubkey: new Account().publicKey,
|
||||
lamports: 123,
|
||||
};
|
||||
const transaction = SystemProgram.transfer(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [systemInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(SystemInstruction.decodeTransfer(systemInstruction));
|
||||
});
|
||||
|
||||
test('assign', () => {
|
||||
const from = new Account();
|
||||
const to = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = SystemProgram.assign(from.publicKey, to.publicKey);
|
||||
|
||||
expect(transaction.keys).toHaveLength(1);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
const params = {
|
||||
fromPubkey: new Account().publicKey,
|
||||
programId: new Account().publicKey,
|
||||
};
|
||||
const transaction = SystemProgram.assign(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [systemInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(SystemInstruction.decodeAssign(systemInstruction));
|
||||
});
|
||||
|
||||
test('createAccountWithSeed', () => {
|
||||
const from = new Account();
|
||||
const newAccount = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = SystemProgram.createAccountWithSeed(
|
||||
from.publicKey,
|
||||
newAccount.publicKey,
|
||||
from.publicKey,
|
||||
'hi there',
|
||||
123,
|
||||
BudgetProgram.space,
|
||||
BudgetProgram.programId,
|
||||
const fromPubkey = new Account().publicKey;
|
||||
const params = {
|
||||
fromPubkey,
|
||||
newAccountPubkey: new Account().publicKey,
|
||||
basePubkey: fromPubkey,
|
||||
seed: 'hi there',
|
||||
lamports: 123,
|
||||
space: BudgetProgram.space,
|
||||
programId: BudgetProgram.programId,
|
||||
};
|
||||
const transaction = SystemProgram.createAccountWithSeed(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [systemInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(
|
||||
SystemInstruction.decodeCreateWithSeed(systemInstruction),
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(2);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
});
|
||||
|
||||
test('createNonceAccount', () => {
|
||||
const from = new Account();
|
||||
const nonceAccount = new Account();
|
||||
|
||||
const transaction = SystemProgram.createNonceAccount(
|
||||
from.publicKey,
|
||||
nonceAccount.publicKey,
|
||||
from.publicKey,
|
||||
123,
|
||||
);
|
||||
const fromPubkey = new Account().publicKey;
|
||||
const params = {
|
||||
fromPubkey,
|
||||
noncePubkey: new Account().publicKey,
|
||||
authorizedPubkey: fromPubkey,
|
||||
lamports: 123,
|
||||
};
|
||||
|
||||
const transaction = SystemProgram.createNonceAccount(params);
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
expect(transaction.instructions[0].programId).toEqual(
|
||||
SystemProgram.programId,
|
||||
const [createInstruction, initInstruction] = transaction.instructions;
|
||||
|
||||
const createParams = {
|
||||
fromPubkey: params.fromPubkey,
|
||||
newAccountPubkey: params.noncePubkey,
|
||||
lamports: params.lamports,
|
||||
space: SystemProgram.nonceSpace,
|
||||
programId: SystemProgram.programId,
|
||||
};
|
||||
expect(createParams).toEqual(
|
||||
SystemInstruction.decodeCreateAccount(createInstruction),
|
||||
);
|
||||
expect(transaction.instructions[1].programId).toEqual(
|
||||
SystemProgram.programId,
|
||||
|
||||
const initParams = {
|
||||
noncePubkey: params.noncePubkey,
|
||||
authorizedPubkey: fromPubkey,
|
||||
};
|
||||
expect(initParams).toEqual(
|
||||
SystemInstruction.decodeNonceInitialize(initInstruction),
|
||||
);
|
||||
// TODO: Validate transaction contents more
|
||||
});
|
||||
|
||||
test('nonceAdvance', () => {
|
||||
const params = {
|
||||
noncePubkey: new Account().publicKey,
|
||||
authorizedPubkey: new Account().publicKey,
|
||||
};
|
||||
const instruction = SystemProgram.nonceAdvance(params);
|
||||
expect(params).toEqual(SystemInstruction.decodeNonceAdvance(instruction));
|
||||
});
|
||||
|
||||
test('nonceWithdraw', () => {
|
||||
const from = new Account();
|
||||
const nonceAccount = new Account();
|
||||
const to = new Account();
|
||||
|
||||
const transaction = SystemProgram.nonceWithdraw(
|
||||
nonceAccount.publicKey,
|
||||
from.publicKey,
|
||||
to.publicKey,
|
||||
123,
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(5);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
const params = {
|
||||
noncePubkey: new Account().publicKey,
|
||||
authorizedPubkey: new Account().publicKey,
|
||||
toPubkey: new Account().publicKey,
|
||||
lamports: 123,
|
||||
};
|
||||
const transaction = SystemProgram.nonceWithdraw(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [instruction] = transaction.instructions;
|
||||
expect(params).toEqual(SystemInstruction.decodeNonceWithdraw(instruction));
|
||||
});
|
||||
|
||||
test('nonceAuthorize', () => {
|
||||
const nonceAccount = new Account();
|
||||
const authorized = new Account();
|
||||
const newAuthorized = new Account();
|
||||
const params = {
|
||||
noncePubkey: new Account().publicKey,
|
||||
authorizedPubkey: new Account().publicKey,
|
||||
newAuthorizedPubkey: new Account().publicKey,
|
||||
};
|
||||
|
||||
const transaction = SystemProgram.nonceAuthorize(
|
||||
nonceAccount.publicKey,
|
||||
authorized.publicKey,
|
||||
newAuthorized.publicKey,
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(2);
|
||||
expect(transaction.programId).toEqual(SystemProgram.programId);
|
||||
// TODO: Validate transaction contents more
|
||||
});
|
||||
|
||||
test('SystemInstruction create', () => {
|
||||
const from = new Account();
|
||||
const to = new Account();
|
||||
const program = new Account();
|
||||
const amount = 42;
|
||||
const space = 100;
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const create = SystemProgram.createAccount(
|
||||
from.publicKey,
|
||||
to.publicKey,
|
||||
amount,
|
||||
space,
|
||||
program.publicKey,
|
||||
);
|
||||
const transaction = new Transaction({recentBlockhash}).add(create);
|
||||
|
||||
const systemInstruction = SystemInstruction.from(transaction.instructions[0]);
|
||||
expect(systemInstruction.fromPublicKey).toEqual(from.publicKey);
|
||||
expect(systemInstruction.toPublicKey).toEqual(to.publicKey);
|
||||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
});
|
||||
|
||||
test('SystemInstruction transfer', () => {
|
||||
const from = new Account();
|
||||
const to = new Account();
|
||||
const amount = 42;
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const transfer = SystemProgram.transfer(from.publicKey, to.publicKey, amount);
|
||||
const transaction = new Transaction({recentBlockhash}).add(transfer);
|
||||
transaction.sign(from);
|
||||
|
||||
const systemInstruction = SystemInstruction.from(transaction.instructions[0]);
|
||||
expect(systemInstruction.fromPublicKey).toEqual(from.publicKey);
|
||||
expect(systemInstruction.toPublicKey).toEqual(to.publicKey);
|
||||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
});
|
||||
|
||||
test('SystemInstruction assign', () => {
|
||||
const from = new Account();
|
||||
const program = new Account();
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const assign = SystemProgram.assign(from.publicKey, program.publicKey);
|
||||
const transaction = new Transaction({recentBlockhash}).add(assign);
|
||||
transaction.sign(from);
|
||||
|
||||
const systemInstruction = SystemInstruction.from(transaction.instructions[0]);
|
||||
expect(systemInstruction.fromPublicKey).toBeNull();
|
||||
expect(systemInstruction.toPublicKey).toBeNull();
|
||||
expect(systemInstruction.amount).toBeNull();
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
});
|
||||
|
||||
test('SystemInstruction createWithSeed', () => {
|
||||
const from = new Account();
|
||||
const to = new Account();
|
||||
const program = new Account();
|
||||
const amount = 42;
|
||||
const space = 100;
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const create = SystemProgram.createAccountWithSeed(
|
||||
from.publicKey,
|
||||
to.publicKey,
|
||||
from.publicKey,
|
||||
'hi there',
|
||||
amount,
|
||||
space,
|
||||
program.publicKey,
|
||||
);
|
||||
const transaction = new Transaction({recentBlockhash}).add(create);
|
||||
|
||||
const systemInstruction = SystemInstruction.from(transaction.instructions[0]);
|
||||
expect(systemInstruction.fromPublicKey).toEqual(from.publicKey);
|
||||
expect(systemInstruction.toPublicKey).toEqual(to.publicKey);
|
||||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
});
|
||||
|
||||
test('SystemInstruction nonceWithdraw', () => {
|
||||
const nonceAccount = new Account();
|
||||
const authorized = new Account();
|
||||
const to = new Account();
|
||||
const amount = 42;
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const nonceWithdraw = SystemProgram.nonceWithdraw(
|
||||
nonceAccount.publicKey,
|
||||
authorized.publicKey,
|
||||
to.publicKey,
|
||||
amount,
|
||||
);
|
||||
const transaction = new Transaction({recentBlockhash}).add(nonceWithdraw);
|
||||
|
||||
const systemInstruction = SystemInstruction.from(transaction.instructions[0]);
|
||||
expect(systemInstruction.fromPublicKey).toEqual(nonceAccount.publicKey);
|
||||
expect(systemInstruction.toPublicKey).toEqual(to.publicKey);
|
||||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
const transaction = SystemProgram.nonceAuthorize(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [instruction] = transaction.instructions;
|
||||
expect(params).toEqual(SystemInstruction.decodeNonceAuthorize(instruction));
|
||||
});
|
||||
|
||||
test('non-SystemInstruction error', () => {
|
||||
|
@ -249,7 +160,9 @@ test('non-SystemInstruction error', () => {
|
|||
data: Buffer.from([2, 0, 0, 0]),
|
||||
};
|
||||
expect(() => {
|
||||
new SystemInstruction(badProgramId, 'Create');
|
||||
SystemInstruction.decodeInstructionType(
|
||||
new TransactionInstruction(badProgramId),
|
||||
);
|
||||
}).toThrow();
|
||||
|
||||
const amount = 123;
|
||||
|
@ -264,12 +177,12 @@ test('non-SystemInstruction error', () => {
|
|||
transaction.sign(from);
|
||||
|
||||
expect(() => {
|
||||
SystemInstruction.from(transaction.instructions[1]);
|
||||
SystemInstruction.decodeInstructionType(transaction.instructions[1]);
|
||||
}).toThrow();
|
||||
|
||||
transaction.instructions[0].data[0] = 11;
|
||||
expect(() => {
|
||||
SystemInstruction.from(transaction.instructions[0]);
|
||||
SystemInstruction.decodeInstructionType(transaction.instructions[0]);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
|
@ -284,20 +197,22 @@ test('live Nonce actions', async () => {
|
|||
const from = new Account();
|
||||
const to = new Account();
|
||||
const authority = new Account();
|
||||
const newAuthority = new Account();
|
||||
await connection.requestAirdrop(from.publicKey, 2 * LAMPORTS_PER_SOL);
|
||||
await connection.requestAirdrop(authority.publicKey, LAMPORTS_PER_SOL);
|
||||
await connection.requestAirdrop(newAuthority.publicKey, LAMPORTS_PER_SOL);
|
||||
|
||||
const minimumAmount = await connection.getMinimumBalanceForRentExemption(
|
||||
SystemProgram.nonceSpace,
|
||||
'recent',
|
||||
);
|
||||
|
||||
let createNonceAccount = SystemProgram.createNonceAccount(
|
||||
from.publicKey,
|
||||
nonceAccount.publicKey,
|
||||
from.publicKey,
|
||||
minimumAmount,
|
||||
);
|
||||
let createNonceAccount = SystemProgram.createNonceAccount({
|
||||
fromPubkey: from.publicKey,
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: from.publicKey,
|
||||
lamports: minimumAmount,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
createNonceAccount,
|
||||
|
@ -311,33 +226,74 @@ test('live Nonce actions', async () => {
|
|||
const nonceQuery2 = await connection.getNonce(nonceAccount.publicKey);
|
||||
expect(nonceQuery1.nonce).toEqual(nonceQuery2.nonce);
|
||||
|
||||
// Wait for blockhash to advance
|
||||
await sleep(500);
|
||||
|
||||
const advanceNonce = new Transaction().add(
|
||||
SystemProgram.nonceAdvance(nonceAccount.publicKey, from.publicKey),
|
||||
SystemProgram.nonceAdvance({
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: from.publicKey,
|
||||
}),
|
||||
);
|
||||
await sendAndConfirmRecentTransaction(connection, advanceNonce, from);
|
||||
|
||||
const nonceQuery3 = await connection.getNonce(nonceAccount.publicKey);
|
||||
expect(nonceQuery1.nonce).not.toEqual(nonceQuery3.nonce);
|
||||
const nonce = nonceQuery3.nonce;
|
||||
|
||||
// Wait for blockhash to advance
|
||||
await sleep(500);
|
||||
|
||||
let transfer = SystemProgram.transfer(
|
||||
from.publicKey,
|
||||
to.publicKey,
|
||||
minimumAmount,
|
||||
const authorizeNonce = new Transaction().add(
|
||||
SystemProgram.nonceAuthorize({
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: from.publicKey,
|
||||
newAuthorizedPubkey: newAuthority.publicKey,
|
||||
}),
|
||||
);
|
||||
await sendAndConfirmRecentTransaction(connection, authorizeNonce, from);
|
||||
|
||||
let transfer = SystemProgram.transfer({
|
||||
fromPubkey: from.publicKey,
|
||||
toPubkey: to.publicKey,
|
||||
lamports: minimumAmount,
|
||||
});
|
||||
transfer.nonceInfo = {
|
||||
nonce,
|
||||
nonceInstruction: SystemProgram.nonceAdvance(
|
||||
nonceAccount.publicKey,
|
||||
from.publicKey,
|
||||
),
|
||||
nonceInstruction: SystemProgram.nonceAdvance({
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: newAuthority.publicKey,
|
||||
}),
|
||||
};
|
||||
|
||||
await sendAndConfirmRecentTransaction(connection, transfer, from);
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
transfer,
|
||||
from,
|
||||
newAuthority,
|
||||
);
|
||||
const toBalance = await connection.getBalance(to.publicKey);
|
||||
expect(toBalance).toEqual(minimumAmount);
|
||||
|
||||
// Wait for blockhash to advance
|
||||
await sleep(500);
|
||||
|
||||
const withdrawAccount = new Account();
|
||||
const withdrawNonce = new Transaction().add(
|
||||
SystemProgram.nonceWithdraw({
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: newAuthority.publicKey,
|
||||
lamports: minimumAmount,
|
||||
toPubkey: withdrawAccount.publicKey,
|
||||
}),
|
||||
);
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
withdrawNonce,
|
||||
newAuthority,
|
||||
);
|
||||
expect(await connection.getBalance(nonceAccount.publicKey)).toEqual(0);
|
||||
const withdrawBalance = await connection.getBalance(
|
||||
withdrawAccount.publicKey,
|
||||
);
|
||||
expect(withdrawBalance).toEqual(minimumAmount);
|
||||
});
|
||||
|
|
|
@ -100,11 +100,11 @@ test('transaction-payer', async () => {
|
|||
},
|
||||
]);
|
||||
|
||||
const transaction = SystemProgram.transfer(
|
||||
accountFrom.publicKey,
|
||||
accountTo.publicKey,
|
||||
10,
|
||||
);
|
||||
const transaction = SystemProgram.transfer({
|
||||
fromPubkey: accountFrom.publicKey,
|
||||
toPubkey: accountTo.publicKey,
|
||||
lamports: 10,
|
||||
});
|
||||
|
||||
const signature = await connection.sendTransaction(
|
||||
transaction,
|
||||
|
|
|
@ -12,11 +12,11 @@ test('signPartial', () => {
|
|||
const account1 = new Account();
|
||||
const account2 = new Account();
|
||||
const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
|
||||
const transfer = SystemProgram.transfer(
|
||||
account1.publicKey,
|
||||
account2.publicKey,
|
||||
123,
|
||||
);
|
||||
const transfer = SystemProgram.transfer({
|
||||
fromPubkey: account1.publicKey,
|
||||
toPubkey: account2.publicKey,
|
||||
lamports: 123,
|
||||
});
|
||||
|
||||
const transaction = new Transaction({recentBlockhash}).add(transfer);
|
||||
transaction.sign(account1, account2);
|
||||
|
@ -33,16 +33,16 @@ test('transfer signatures', () => {
|
|||
const account1 = new Account();
|
||||
const account2 = new Account();
|
||||
const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
|
||||
const transfer1 = SystemProgram.transfer(
|
||||
account1.publicKey,
|
||||
account2.publicKey,
|
||||
123,
|
||||
);
|
||||
const transfer2 = SystemProgram.transfer(
|
||||
account2.publicKey,
|
||||
account1.publicKey,
|
||||
123,
|
||||
);
|
||||
const transfer1 = SystemProgram.transfer({
|
||||
fromPubkey: account1.publicKey,
|
||||
toPubkey: account2.publicKey,
|
||||
lamports: 123,
|
||||
});
|
||||
const transfer2 = SystemProgram.transfer({
|
||||
fromPubkey: account2.publicKey,
|
||||
toPubkey: account1.publicKey,
|
||||
lamports: 123,
|
||||
});
|
||||
|
||||
const orgTransaction = new Transaction({recentBlockhash}).add(
|
||||
transfer1,
|
||||
|
@ -62,16 +62,16 @@ test('dedup signatures', () => {
|
|||
const account1 = new Account();
|
||||
const account2 = new Account();
|
||||
const recentBlockhash = account1.publicKey.toBase58(); // Fake recentBlockhash
|
||||
const transfer1 = SystemProgram.transfer(
|
||||
account1.publicKey,
|
||||
account2.publicKey,
|
||||
123,
|
||||
);
|
||||
const transfer2 = SystemProgram.transfer(
|
||||
account1.publicKey,
|
||||
account2.publicKey,
|
||||
123,
|
||||
);
|
||||
const transfer1 = SystemProgram.transfer({
|
||||
fromPubkey: account1.publicKey,
|
||||
toPubkey: account2.publicKey,
|
||||
lamports: 123,
|
||||
});
|
||||
const transfer2 = SystemProgram.transfer({
|
||||
fromPubkey: account1.publicKey,
|
||||
toPubkey: account2.publicKey,
|
||||
lamports: 123,
|
||||
});
|
||||
|
||||
const orgTransaction = new Transaction({recentBlockhash}).add(
|
||||
transfer1,
|
||||
|
@ -88,14 +88,18 @@ test('use nonce', () => {
|
|||
|
||||
const nonceInfo = {
|
||||
nonce,
|
||||
nonceInstruction: SystemProgram.nonceAdvance(
|
||||
nonceAccount.publicKey,
|
||||
account1.publicKey,
|
||||
),
|
||||
nonceInstruction: SystemProgram.nonceAdvance({
|
||||
noncePubkey: nonceAccount.publicKey,
|
||||
authorizedPubkey: account1.publicKey,
|
||||
}),
|
||||
};
|
||||
|
||||
const transferTransaction = new Transaction({nonceInfo}).add(
|
||||
SystemProgram.transfer(account1.publicKey, account2.publicKey, 123),
|
||||
SystemProgram.transfer({
|
||||
fromPubkey: account1.publicKey,
|
||||
toPubkey: account2.publicKey,
|
||||
lamports: 123,
|
||||
}),
|
||||
);
|
||||
transferTransaction.sign(account1);
|
||||
|
||||
|
@ -137,7 +141,11 @@ test('parse wire format and serialize', () => {
|
|||
const recipient = new PublicKey(
|
||||
'J3dxNj7nDRRqRRXuEMynDG57DkZK4jYRuv3Garmb1i99',
|
||||
); // Arbitrary known public key
|
||||
const transfer = SystemProgram.transfer(sender.publicKey, recipient, 49);
|
||||
const transfer = SystemProgram.transfer({
|
||||
fromPubkey: sender.publicKey,
|
||||
toPubkey: recipient,
|
||||
lamports: 49,
|
||||
});
|
||||
const expectedTransaction = new Transaction({recentBlockhash}).add(transfer);
|
||||
expectedTransaction.sign(sender);
|
||||
|
||||
|
@ -198,7 +206,11 @@ test('serialize unsigned transaction', () => {
|
|||
const recipient = new PublicKey(
|
||||
'J3dxNj7nDRRqRRXuEMynDG57DkZK4jYRuv3Garmb1i99',
|
||||
); // Arbitrary known public key
|
||||
const transfer = SystemProgram.transfer(sender.publicKey, recipient, 49);
|
||||
const transfer = SystemProgram.transfer({
|
||||
fromPubkey: sender.publicKey,
|
||||
toPubkey: recipient,
|
||||
lamports: 49,
|
||||
});
|
||||
const expectedTransaction = new Transaction({recentBlockhash}).add(transfer);
|
||||
|
||||
const wireTransactionArray = [
|
||||
|
|
Loading…
Reference in New Issue