feat: add API for decoding stake instructions
This commit is contained in:
parent
01e65d2070
commit
aba7e14f3a
|
@ -369,52 +369,74 @@ declare module '@solana/web3.js' {
|
|||
constructor(unixTimestamp: number, epoch: number, custodian: PublicKey);
|
||||
}
|
||||
|
||||
export type CreateStakeAccountParams = {
|
||||
fromPubkey: PublicKey;
|
||||
stakePubkey: PublicKey;
|
||||
authorized: Authorized;
|
||||
lockup: Lockup;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type CreateStakeAccountWithSeedParams = {
|
||||
fromPubkey: PublicKey;
|
||||
stakePubkey: PublicKey;
|
||||
basePubkey: PublicKey;
|
||||
seed: string;
|
||||
authorized: Authorized;
|
||||
lockup: Lockup;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type InitializeStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorized: Authorized;
|
||||
lockup: Lockup;
|
||||
};
|
||||
|
||||
export type DelegateStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
votePubkey: PublicKey;
|
||||
};
|
||||
|
||||
export type AuthorizeStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
newAuthorizedPubkey: PublicKey;
|
||||
stakeAuthorizationType: StakeAuthorizationType;
|
||||
};
|
||||
|
||||
export type SplitStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
splitStakePubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type WithdrawStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
toPubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
export type DeactivateStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
};
|
||||
|
||||
export class StakeProgram {
|
||||
static programId: PublicKey;
|
||||
static space: number;
|
||||
|
||||
static createAccount(
|
||||
from: PublicKey,
|
||||
stakeAccount: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static createAccount(params: CreateStakeAccountParams): Transaction;
|
||||
static createAccountWithSeed(
|
||||
from: PublicKey,
|
||||
stakeAccount: PublicKey,
|
||||
seed: string,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static delegate(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
votePubkey: PublicKey,
|
||||
): Transaction;
|
||||
static authorize(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorized: PublicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationType,
|
||||
): Transaction;
|
||||
static split(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
splitStakePubkey: PublicKey,
|
||||
): Transaction;
|
||||
static withdraw(
|
||||
stakeAccount: PublicKey,
|
||||
withdrawerPubkey: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static deactivate(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
params: CreateStakeAccountWithSeedParams,
|
||||
): Transaction;
|
||||
static delegate(params: DelegateStakeParams): Transaction;
|
||||
static authorize(params: AuthorizeStakeParams): Transaction;
|
||||
static split(params: SplitStakeParams): Transaction;
|
||||
static withdraw(params: WithdrawStakeParams): Transaction;
|
||||
static deactivate(params: DeactivateStakeParams): Transaction;
|
||||
}
|
||||
|
||||
export type StakeInstructionType =
|
||||
|
@ -429,16 +451,26 @@ declare module '@solana/web3.js' {
|
|||
[type in StakeInstructionType]: InstructionType;
|
||||
};
|
||||
|
||||
export class StakeInstruction extends TransactionInstruction {
|
||||
type: StakeInstructionType;
|
||||
stakePublicKey: PublicKey | null;
|
||||
authorizedPublicKey: PublicKey | null;
|
||||
|
||||
constructor(
|
||||
opts: TransactionInstructionCtorFields,
|
||||
type: StakeInstructionType,
|
||||
);
|
||||
static from(instruction: TransactionInstruction): StakeInstruction;
|
||||
export class StakeInstruction {
|
||||
static decodeInstructionType(
|
||||
instruction: TransactionInstruction,
|
||||
): StakeInstructionType;
|
||||
static decodeInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeStakeParams;
|
||||
static decodeDelegate(
|
||||
instruction: TransactionInstruction,
|
||||
): DelegateStakeParams;
|
||||
static decodeAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeStakeParams;
|
||||
static decodeSplit(instruction: TransactionInstruction): SplitStakeParams;
|
||||
static decodeWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawStakeParams;
|
||||
static decodeDeactivate(
|
||||
instruction: TransactionInstruction,
|
||||
): DeactivateStakeParams;
|
||||
}
|
||||
|
||||
// === src/system-program.js ===
|
||||
|
|
|
@ -266,52 +266,74 @@ declare module '@solana/web3.js' {
|
|||
): Lockup;
|
||||
}
|
||||
|
||||
declare export type CreateStakeAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type CreateStakeAccountWithSeedParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
basePubkey: PublicKey,
|
||||
seed: string,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type InitializeStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
|};
|
||||
|
||||
declare export type DelegateStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
votePubkey: PublicKey,
|
||||
|};
|
||||
|
||||
declare export type AuthorizeStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorizedPubkey: PublicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationType,
|
||||
|};
|
||||
|
||||
declare export type SplitStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
splitStakePubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type WithdrawStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
declare export type DeactivateStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
declare export class StakeProgram {
|
||||
static programId: PublicKey;
|
||||
static space: number;
|
||||
|
||||
static createAccount(
|
||||
from: PublicKey,
|
||||
stakeAccount: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static createAccount(params: CreateStakeAccountParams): Transaction;
|
||||
static createAccountWithSeed(
|
||||
from: PublicKey,
|
||||
stakeAccount: PublicKey,
|
||||
seed: string,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static delegate(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
votePubkey: PublicKey,
|
||||
): Transaction;
|
||||
static authorize(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorized: PublicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationType,
|
||||
): Transaction;
|
||||
static split(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
splitStakePubkey: PublicKey,
|
||||
): Transaction;
|
||||
static withdraw(
|
||||
stakeAccount: PublicKey,
|
||||
withdrawerPubkey: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction;
|
||||
static deactivate(
|
||||
stakeAccount: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
params: CreateStakeAccountWithSeedParams,
|
||||
): Transaction;
|
||||
static delegate(params: DelegateStakeParams): Transaction;
|
||||
static authorize(params: AuthorizeStakeParams): Transaction;
|
||||
static split(params: SplitStakeParams): Transaction;
|
||||
static withdraw(params: WithdrawStakeParams): Transaction;
|
||||
static deactivate(params: DeactivateStakeParams): Transaction;
|
||||
}
|
||||
|
||||
declare export type StakeInstructionType =
|
||||
|
@ -326,16 +348,26 @@ declare module '@solana/web3.js' {
|
|||
[StakeInstructionType]: InstructionType,
|
||||
};
|
||||
|
||||
declare export class StakeInstruction extends TransactionInstruction {
|
||||
type: StakeInstructionType;
|
||||
stakePublicKey: PublicKey | null;
|
||||
authorizedPublicKey: PublicKey | null;
|
||||
|
||||
constructor(
|
||||
opts?: TransactionInstructionCtorFields,
|
||||
type: StakeInstructionType,
|
||||
): StakeInstruction;
|
||||
static from(instruction: TransactionInstruction): StakeInstruction;
|
||||
declare export class StakeInstruction {
|
||||
static decodeInstructionType(
|
||||
instruction: TransactionInstruction,
|
||||
): StakeInstructionType;
|
||||
static decodeInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeStakeParams;
|
||||
static decodeDelegate(
|
||||
instruction: TransactionInstruction,
|
||||
): DelegateStakeParams;
|
||||
static decodeAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeStakeParams;
|
||||
static decodeSplit(instruction: TransactionInstruction): SplitStakeParams;
|
||||
static decodeWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawStakeParams;
|
||||
static decodeDeactivate(
|
||||
instruction: TransactionInstruction,
|
||||
): DeactivateStakeParams;
|
||||
}
|
||||
|
||||
// === src/system-program.js ===
|
||||
|
|
|
@ -25,3 +25,23 @@ export function encodeData(type: InstructionType, fields: Object): Buffer {
|
|||
type.layout.encode(layoutFields, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode instruction data buffer using an InstructionType
|
||||
*/
|
||||
export function decodeData(type: InstructionType, buffer: Buffer): Object {
|
||||
let data;
|
||||
try {
|
||||
data = type.layout.decode(buffer);
|
||||
} catch (err) {
|
||||
throw new Error('invalid instruction; ' + err);
|
||||
}
|
||||
|
||||
if (data.instruction !== type.index) {
|
||||
throw new Error(
|
||||
`invalid instruction; instruction index mismatch ${data.instruction} != ${type.index}`,
|
||||
);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
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 {SystemProgram} from './system-program';
|
||||
|
@ -12,7 +12,6 @@ import {
|
|||
SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||
} from './sysvar';
|
||||
import {Transaction, TransactionInstruction} from './transaction';
|
||||
import type {TransactionInstructionCtorFields} from './transaction';
|
||||
|
||||
export const STAKE_CONFIG_ID = new PublicKey(
|
||||
'StakeConfig11111111111111111111111111111111',
|
||||
|
@ -46,31 +45,137 @@ export class Lockup {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stake account transaction params
|
||||
* @typedef {Object} CreateStakeAccountParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {Authorized} authorized
|
||||
* @property {Lockup} lockup
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type CreateStakeAccountParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Create stake account with seed transaction params
|
||||
* @typedef {Object} CreateStakeAccountWithSeedParams
|
||||
* @property {PublicKey} fromPubkey
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} basePubkey
|
||||
* @property {string} seed
|
||||
* @property {Authorized} authorized
|
||||
* @property {Lockup} lockup
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type CreateStakeAccountWithSeedParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
basePubkey: PublicKey,
|
||||
seed: string,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Initialize stake instruction params
|
||||
* @typedef {Object} InitializeStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {Authorized} authorized
|
||||
* @property {Lockup} lockup
|
||||
*/
|
||||
export type InitializeStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Delegate stake instruction params
|
||||
* @typedef {Object} DelegateStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} votePubkey
|
||||
*/
|
||||
export type DelegateStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
votePubkey: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Authorize stake instruction params
|
||||
* @typedef {Object} AuthorizeStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} newAuthorizedPubkey
|
||||
* @property {StakeAuthorizationType} stakeAuthorizationType
|
||||
*/
|
||||
export type AuthorizeStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorizedPubkey: PublicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationType,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Split stake instruction params
|
||||
* @typedef {Object} SplitStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} splitStakePubkey
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type SplitStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
splitStakePubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Withdraw stake instruction params
|
||||
* @typedef {Object} WithdrawStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
* @property {PublicKey} toPubkey
|
||||
* @property {number} lamports
|
||||
*/
|
||||
export type WithdrawStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Deactivate stake instruction params
|
||||
* @typedef {Object} DeactivateStakeParams
|
||||
* @property {PublicKey} stakePubkey
|
||||
* @property {PublicKey} authorizedPubkey
|
||||
*/
|
||||
export type DeactivateStakeParams = {|
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Stake Instruction class
|
||||
*/
|
||||
export class StakeInstruction extends TransactionInstruction {
|
||||
_type: StakeInstructionType;
|
||||
|
||||
constructor(
|
||||
opts?: TransactionInstructionCtorFields,
|
||||
type: StakeInstructionType,
|
||||
) {
|
||||
if (
|
||||
opts &&
|
||||
opts.programId &&
|
||||
!opts.programId.equals(StakeProgram.programId)
|
||||
) {
|
||||
throw new Error('programId incorrect; not a StakeInstruction');
|
||||
}
|
||||
super(opts);
|
||||
this._type = type;
|
||||
}
|
||||
|
||||
static from(instruction: TransactionInstruction): StakeInstruction {
|
||||
if (!instruction.programId.equals(StakeProgram.programId)) {
|
||||
throw new Error('programId incorrect; not StakeProgram');
|
||||
}
|
||||
export class StakeInstruction {
|
||||
/**
|
||||
* Decode a stake instruction and retrieve the instruction type.
|
||||
*/
|
||||
static decodeInstructionType(
|
||||
instruction: TransactionInstruction,
|
||||
): StakeInstructionType {
|
||||
this.checkProgramId(instruction.programId);
|
||||
|
||||
const instructionTypeLayout = BufferLayout.u32('instruction');
|
||||
const typeIndex = instructionTypeLayout.decode(instruction.data);
|
||||
|
@ -81,63 +186,155 @@ export class StakeInstruction extends TransactionInstruction {
|
|||
type = t;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
throw new Error('Instruction type incorrect; not a StakeInstruction');
|
||||
}
|
||||
return new StakeInstruction(
|
||||
{
|
||||
keys: instruction.keys,
|
||||
programId: instruction.programId,
|
||||
data: instruction.data,
|
||||
},
|
||||
type,
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a initialize stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeInitialize(
|
||||
instruction: TransactionInstruction,
|
||||
): InitializeStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {authorized, lockup} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.Initialize,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
authorized: new Authorized(
|
||||
new PublicKey(authorized.staker),
|
||||
new PublicKey(authorized.withdrawer),
|
||||
),
|
||||
lockup: new Lockup(
|
||||
lockup.unixTimestamp,
|
||||
lockup.epoch,
|
||||
new PublicKey(lockup.custodian),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Type of StakeInstruction
|
||||
* Decode a delegate stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
get type(): StakeInstructionType {
|
||||
return this._type;
|
||||
static decodeDelegate(
|
||||
instruction: TransactionInstruction,
|
||||
): DelegateStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 6);
|
||||
decodeData(STAKE_INSTRUCTION_LAYOUTS.Delegate, instruction.data);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
votePubkey: instruction.keys[1].pubkey,
|
||||
authorizedPubkey: instruction.keys[5].pubkey,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The `stake account` public key of the instruction;
|
||||
* returns null if StakeInstructionType does not support this field
|
||||
* Decode an authorize stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
get stakePublicKey(): PublicKey | null {
|
||||
switch (this.type) {
|
||||
case 'Initialize':
|
||||
case 'Delegate':
|
||||
case 'Authorize':
|
||||
case 'Split':
|
||||
case 'Withdraw':
|
||||
case 'Deactivate':
|
||||
return this.keys[0].pubkey;
|
||||
default:
|
||||
return null;
|
||||
static decodeAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
const {newAuthorized, stakeAuthorizationType} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.Authorize,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: instruction.keys[2].pubkey,
|
||||
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
||||
stakeAuthorizationType: {
|
||||
index: stakeAuthorizationType,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a split stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeSplit(instruction: TransactionInstruction): SplitStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
const {lamports} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.Split,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
splitStakePubkey: instruction.keys[1].pubkey,
|
||||
authorizedPubkey: instruction.keys[2].pubkey,
|
||||
lamports,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a withdraw stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeWithdraw(
|
||||
instruction: TransactionInstruction,
|
||||
): WithdrawStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 5);
|
||||
const {lamports} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.Withdraw,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
toPubkey: instruction.keys[1].pubkey,
|
||||
authorizedPubkey: instruction.keys[4].pubkey,
|
||||
lamports,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a deactivate stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeDeactivate(
|
||||
instruction: TransactionInstruction,
|
||||
): DeactivateStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
decodeData(STAKE_INSTRUCTION_LAYOUTS.Deactivate, instruction.data);
|
||||
|
||||
return {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: instruction.keys[2].pubkey,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
static checkProgramId(programId: PublicKey) {
|
||||
if (!programId.equals(StakeProgram.programId)) {
|
||||
throw new Error('invalid instruction; programId is not StakeProgram');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The `authorized account` public key of the instruction;
|
||||
*
|
||||
* returns null if StakeInstructionType does not support this field
|
||||
* @private
|
||||
*/
|
||||
get authorizedPublicKey(): PublicKey | null {
|
||||
switch (this.type) {
|
||||
case 'Delegate':
|
||||
return this.keys[5].pubkey;
|
||||
case 'Authorize':
|
||||
return this.keys[2].pubkey;
|
||||
case 'Split':
|
||||
return this.keys[2].pubkey;
|
||||
case 'Withdraw':
|
||||
return this.keys[4].pubkey;
|
||||
case 'Deactivate':
|
||||
return this.keys[2].pubkey;
|
||||
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}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -234,11 +431,8 @@ export class StakeProgram {
|
|||
/**
|
||||
* Generate an Initialize instruction to add to a Stake Create transaction
|
||||
*/
|
||||
static initialize(
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
): TransactionInstruction {
|
||||
static initialize(params: InitializeStakeParams): TransactionInstruction {
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Initialize;
|
||||
const data = encodeData(type, {
|
||||
authorized: {
|
||||
|
@ -267,46 +461,36 @@ export class StakeProgram {
|
|||
* an address generated with `from`, a seed, and the Stake programId
|
||||
*/
|
||||
static createAccountWithSeed(
|
||||
from: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
base: PublicKey,
|
||||
seed: string,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
params: CreateStakeAccountWithSeedParams,
|
||||
): Transaction {
|
||||
let transaction = SystemProgram.createAccountWithSeed(
|
||||
from,
|
||||
stakePubkey,
|
||||
base,
|
||||
seed,
|
||||
lamports,
|
||||
params.fromPubkey,
|
||||
params.stakePubkey,
|
||||
params.basePubkey,
|
||||
params.seed,
|
||||
params.lamports,
|
||||
this.space,
|
||||
this.programId,
|
||||
);
|
||||
|
||||
return transaction.add(this.initialize(stakePubkey, authorized, lockup));
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that creates a new Stake account
|
||||
*/
|
||||
static createAccount(
|
||||
from: PublicKey,
|
||||
stakePubkey: PublicKey,
|
||||
authorized: Authorized,
|
||||
lockup: Lockup,
|
||||
lamports: number,
|
||||
): Transaction {
|
||||
static createAccount(params: CreateStakeAccountParams): Transaction {
|
||||
let transaction = SystemProgram.createAccount(
|
||||
from,
|
||||
stakePubkey,
|
||||
lamports,
|
||||
params.fromPubkey,
|
||||
params.stakePubkey,
|
||||
params.lamports,
|
||||
this.space,
|
||||
this.programId,
|
||||
);
|
||||
|
||||
return transaction.add(this.initialize(stakePubkey, authorized, lockup));
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
return transaction.add(this.initialize({stakePubkey, authorized, lockup}));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -314,11 +498,9 @@ export class StakeProgram {
|
|||
* Vote PublicKey. This transaction can also be used to redelegate Stake
|
||||
* to a new validator Vote PublicKey.
|
||||
*/
|
||||
static delegate(
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
votePubkey: PublicKey,
|
||||
): Transaction {
|
||||
static delegate(params: DelegateStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, votePubkey} = params;
|
||||
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Delegate;
|
||||
const data = encodeData(type);
|
||||
|
||||
|
@ -344,15 +526,17 @@ export class StakeProgram {
|
|||
* Generate a Transaction that authorizes a new PublicKey as Staker
|
||||
* or Withdrawer on the Stake account.
|
||||
*/
|
||||
static authorize(
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
newAuthorized: PublicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationType,
|
||||
): Transaction {
|
||||
static authorize(params: AuthorizeStakeParams): Transaction {
|
||||
const {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
newAuthorizedPubkey,
|
||||
stakeAuthorizationType,
|
||||
} = params;
|
||||
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Authorize;
|
||||
const data = encodeData(type, {
|
||||
newAuthorized: newAuthorized.toBuffer(),
|
||||
newAuthorized: newAuthorizedPubkey.toBuffer(),
|
||||
stakeAuthorizationType: stakeAuthorizationType.index,
|
||||
});
|
||||
|
||||
|
@ -370,12 +554,9 @@ export class StakeProgram {
|
|||
/**
|
||||
* Generate a Transaction that splits Stake tokens into another stake account
|
||||
*/
|
||||
static split(
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
lamports: number,
|
||||
splitStakePubkey: PublicKey,
|
||||
): Transaction {
|
||||
static split(params: SplitStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, splitStakePubkey, lamports} = params;
|
||||
|
||||
let transaction = SystemProgram.createAccount(
|
||||
stakePubkey,
|
||||
splitStakePubkey,
|
||||
|
@ -401,19 +582,15 @@ export class StakeProgram {
|
|||
/**
|
||||
* Generate a Transaction that withdraws deactivated Stake tokens.
|
||||
*/
|
||||
static withdraw(
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
to: PublicKey,
|
||||
lamports: number,
|
||||
): Transaction {
|
||||
static withdraw(params: WithdrawStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, toPubkey, lamports} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Withdraw;
|
||||
const data = encodeData(type, {lamports});
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: to, isSigner: false, isWritable: true},
|
||||
{pubkey: toPubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
||||
{
|
||||
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||
|
@ -430,10 +607,8 @@ export class StakeProgram {
|
|||
/**
|
||||
* Generate a Transaction that deactivates Stake tokens.
|
||||
*/
|
||||
static deactivate(
|
||||
stakePubkey: PublicKey,
|
||||
authorizedPubkey: PublicKey,
|
||||
): Transaction {
|
||||
static deactivate(params: DeactivateStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Deactivate;
|
||||
const data = encodeData(type);
|
||||
|
||||
|
|
|
@ -24,164 +24,137 @@ if (!mockRpcEnabled) {
|
|||
}
|
||||
|
||||
test('createAccountWithSeed', () => {
|
||||
const from = new Account();
|
||||
const fromPubkey = new Account().publicKey;
|
||||
const seed = 'test string';
|
||||
const newAccountPubkey = PublicKey.createWithSeed(
|
||||
from.publicKey,
|
||||
fromPubkey,
|
||||
seed,
|
||||
StakeProgram.programId,
|
||||
);
|
||||
const authorized = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.createAccountWithSeed(
|
||||
from.publicKey,
|
||||
newAccountPubkey,
|
||||
from.publicKey,
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const authorized = new Authorized(authorizedPubkey, authorizedPubkey);
|
||||
const lockup = new Lockup(0, 0, fromPubkey);
|
||||
const transaction = StakeProgram.createAccountWithSeed({
|
||||
fromPubkey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
basePubkey: fromPubkey,
|
||||
seed,
|
||||
new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
new Lockup(0, 0, from.publicKey),
|
||||
123,
|
||||
);
|
||||
authorized,
|
||||
lockup,
|
||||
lamports: 123,
|
||||
});
|
||||
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
expect(transaction.instructions[0].programId).toEqual(
|
||||
SystemProgram.programId,
|
||||
);
|
||||
expect(transaction.instructions[1].programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[1]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(newAccountPubkey);
|
||||
// TODO: Validate transaction contents more
|
||||
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);
|
||||
});
|
||||
|
||||
test('createAccount', () => {
|
||||
const from = new Account();
|
||||
const newAccount = new Account();
|
||||
const authorized = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.createAccount(
|
||||
from.publicKey,
|
||||
newAccount.publicKey,
|
||||
new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
new Lockup(0, 0, from.publicKey),
|
||||
123,
|
||||
);
|
||||
const fromPubkey = new Account().publicKey;
|
||||
const newAccountPubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const authorized = new Authorized(authorizedPubkey, authorizedPubkey);
|
||||
const lockup = new Lockup(0, 0, fromPubkey);
|
||||
const transaction = StakeProgram.createAccount({
|
||||
fromPubkey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorized,
|
||||
lockup,
|
||||
lamports: 123,
|
||||
});
|
||||
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
expect(transaction.instructions[0].programId).toEqual(
|
||||
SystemProgram.programId,
|
||||
);
|
||||
expect(transaction.instructions[1].programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[1]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(newAccount.publicKey);
|
||||
const [systemInstruction, stakeInstruction] = transaction.instructions;
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
|
||||
expect(() => {
|
||||
StakeInstruction.from(transaction.instructions[0]);
|
||||
}).toThrow();
|
||||
// TODO: Validate transaction contents more
|
||||
// TODO decode system instruction
|
||||
|
||||
const params = StakeInstruction.decodeInitialize(stakeInstruction);
|
||||
expect(params.stakePubkey).toEqual(newAccountPubkey);
|
||||
expect(params.authorized).toEqual(authorized);
|
||||
expect(params.lockup).toEqual(lockup);
|
||||
});
|
||||
|
||||
test('delegate', () => {
|
||||
const stake = new Account();
|
||||
const authorized = new Account();
|
||||
const vote = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.delegate(
|
||||
stake.publicKey,
|
||||
authorized.publicKey,
|
||||
vote.publicKey,
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(6);
|
||||
expect(transaction.programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[0]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(stake.publicKey);
|
||||
expect(stakeInstruction.authorizedPublicKey).toEqual(authorized.publicKey);
|
||||
// TODO: Validate transaction contents more
|
||||
const stakePubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const votePubkey = new Account().publicKey;
|
||||
const params = {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
votePubkey,
|
||||
};
|
||||
const transaction = StakeProgram.delegate(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [stakeInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(StakeInstruction.decodeDelegate(stakeInstruction));
|
||||
});
|
||||
|
||||
test('authorize', () => {
|
||||
const stake = new Account();
|
||||
const authorized = new Account();
|
||||
const newAuthorized = new Account();
|
||||
const type = StakeAuthorizationLayout.Staker;
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.authorize(
|
||||
stake.publicKey,
|
||||
authorized.publicKey,
|
||||
newAuthorized.publicKey,
|
||||
type,
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(3);
|
||||
expect(transaction.programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[0]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(stake.publicKey);
|
||||
expect(stakeInstruction.authorizedPublicKey).toEqual(authorized.publicKey);
|
||||
// TODO: Validate transaction contents more
|
||||
const stakePubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const newAuthorizedPubkey = new Account().publicKey;
|
||||
const stakeAuthorizationType = StakeAuthorizationLayout.Staker;
|
||||
const params = {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
newAuthorizedPubkey,
|
||||
stakeAuthorizationType,
|
||||
};
|
||||
const transaction = StakeProgram.authorize(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [stakeInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(StakeInstruction.decodeAuthorize(stakeInstruction));
|
||||
});
|
||||
|
||||
test('split', () => {
|
||||
const stake = new Account();
|
||||
const authorized = new Account();
|
||||
const newStake = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.split(
|
||||
stake.publicKey,
|
||||
authorized.publicKey,
|
||||
123,
|
||||
newStake.publicKey,
|
||||
);
|
||||
|
||||
const stakePubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const splitStakePubkey = new Account().publicKey;
|
||||
const params = {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
splitStakePubkey,
|
||||
lamports: 123,
|
||||
};
|
||||
const transaction = StakeProgram.split(params);
|
||||
expect(transaction.instructions).toHaveLength(2);
|
||||
expect(transaction.instructions[0].programId).toEqual(
|
||||
SystemProgram.programId,
|
||||
);
|
||||
expect(transaction.instructions[1].programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[1]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(stake.publicKey);
|
||||
expect(stakeInstruction.authorizedPublicKey).toEqual(authorized.publicKey);
|
||||
// TODO: Validate transaction contents more
|
||||
const [systemInstruction, stakeInstruction] = transaction.instructions;
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
expect(params).toEqual(StakeInstruction.decodeSplit(stakeInstruction));
|
||||
});
|
||||
|
||||
test('withdraw', () => {
|
||||
const stake = new Account();
|
||||
const withdrawer = new Account();
|
||||
const to = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.withdraw(
|
||||
stake.publicKey,
|
||||
withdrawer.publicKey,
|
||||
to.publicKey,
|
||||
123,
|
||||
);
|
||||
|
||||
expect(transaction.keys).toHaveLength(5);
|
||||
expect(transaction.programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[0]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(stake.publicKey);
|
||||
expect(stakeInstruction.authorizedPublicKey).toEqual(withdrawer.publicKey);
|
||||
// TODO: Validate transaction contents more
|
||||
const stakePubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const toPubkey = new Account().publicKey;
|
||||
const params = {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
toPubkey,
|
||||
lamports: 123,
|
||||
};
|
||||
const transaction = StakeProgram.withdraw(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [stakeInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(StakeInstruction.decodeWithdraw(stakeInstruction));
|
||||
});
|
||||
|
||||
test('deactivate', () => {
|
||||
const stake = new Account();
|
||||
const authorized = new Account();
|
||||
let transaction;
|
||||
|
||||
transaction = StakeProgram.deactivate(stake.publicKey, authorized.publicKey);
|
||||
|
||||
expect(transaction.keys).toHaveLength(3);
|
||||
expect(transaction.programId).toEqual(StakeProgram.programId);
|
||||
const stakeInstruction = StakeInstruction.from(transaction.instructions[0]);
|
||||
expect(stakeInstruction.stakePublicKey).toEqual(stake.publicKey);
|
||||
expect(stakeInstruction.authorizedPublicKey).toEqual(authorized.publicKey);
|
||||
// TODO: Validate transaction contents more
|
||||
const stakePubkey = new Account().publicKey;
|
||||
const authorizedPubkey = new Account().publicKey;
|
||||
const params = {stakePubkey, authorizedPubkey};
|
||||
const transaction = StakeProgram.deactivate(params);
|
||||
expect(transaction.instructions).toHaveLength(1);
|
||||
const [stakeInstruction] = transaction.instructions;
|
||||
expect(params).toEqual(StakeInstruction.decodeDeactivate(stakeInstruction));
|
||||
});
|
||||
|
||||
test('StakeInstructions', () => {
|
||||
|
@ -195,19 +168,20 @@ test('StakeInstructions', () => {
|
|||
const authorized = new Account();
|
||||
const amount = 123;
|
||||
const recentBlockhash = 'EETubP5AKHgjPAhzPAFcb8BAY1hMH639CWCFTqi3hq1k'; // Arbitrary known recentBlockhash
|
||||
const createWithSeed = StakeProgram.createAccountWithSeed(
|
||||
from.publicKey,
|
||||
newAccountPubkey,
|
||||
from.publicKey,
|
||||
const createWithSeed = StakeProgram.createAccountWithSeed({
|
||||
fromPubkey: from.publicKey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
basePubkey: from.publicKey,
|
||||
seed,
|
||||
new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
new Lockup(0, 0, from.publicKey),
|
||||
amount,
|
||||
);
|
||||
authorized: new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
lockup: new Lockup(0, 0, from.publicKey),
|
||||
lamports: amount,
|
||||
});
|
||||
const createWithSeedTransaction = new Transaction({recentBlockhash}).add(
|
||||
createWithSeed,
|
||||
);
|
||||
|
||||
expect(createWithSeedTransaction.instructions).toHaveLength(2);
|
||||
const systemInstruction = SystemInstruction.from(
|
||||
createWithSeedTransaction.instructions[0],
|
||||
);
|
||||
|
@ -216,29 +190,30 @@ test('StakeInstructions', () => {
|
|||
expect(systemInstruction.amount).toEqual(amount);
|
||||
expect(systemInstruction.programId).toEqual(SystemProgram.programId);
|
||||
|
||||
const stakeInstruction = StakeInstruction.from(
|
||||
const stakeInstructionType = StakeInstruction.decodeInstructionType(
|
||||
createWithSeedTransaction.instructions[1],
|
||||
);
|
||||
expect(stakeInstruction.type).toEqual('Initialize');
|
||||
expect(stakeInstructionType).toEqual('Initialize');
|
||||
|
||||
expect(() => {
|
||||
StakeInstruction.from(createWithSeedTransaction.instructions[0]);
|
||||
StakeInstruction.decodeInstructionType(
|
||||
createWithSeedTransaction.instructions[0],
|
||||
);
|
||||
}).toThrow();
|
||||
|
||||
const stake = new Account();
|
||||
const vote = new Account();
|
||||
const delegate = StakeProgram.delegate(
|
||||
stake.publicKey,
|
||||
authorized.publicKey,
|
||||
vote.publicKey,
|
||||
);
|
||||
const delegate = StakeProgram.delegate({
|
||||
stakePubkey: stake.publicKey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
votePubkey: vote.publicKey,
|
||||
});
|
||||
|
||||
const delegateTransaction = new Transaction({recentBlockhash}).add(delegate);
|
||||
|
||||
const anotherStakeInstruction = StakeInstruction.from(
|
||||
const anotherStakeInstructionType = StakeInstruction.decodeInstructionType(
|
||||
delegateTransaction.instructions[0],
|
||||
);
|
||||
expect(anotherStakeInstruction.type).toEqual('Delegate');
|
||||
expect(anotherStakeInstructionType).toEqual('Delegate');
|
||||
});
|
||||
|
||||
test('live staking actions', async () => {
|
||||
|
@ -270,15 +245,15 @@ test('live staking actions', async () => {
|
|||
StakeProgram.programId,
|
||||
);
|
||||
|
||||
let createAndInitializeWithSeed = StakeProgram.createAccountWithSeed(
|
||||
from.publicKey,
|
||||
newAccountPubkey,
|
||||
from.publicKey,
|
||||
let createAndInitializeWithSeed = StakeProgram.createAccountWithSeed({
|
||||
fromPubkey: from.publicKey,
|
||||
stakePubkey: newAccountPubkey,
|
||||
basePubkey: from.publicKey,
|
||||
seed,
|
||||
new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
new Lockup(0, 0, new PublicKey('0x00')),
|
||||
3 * minimumAmount + 42,
|
||||
);
|
||||
authorized: new Authorized(authorized.publicKey, authorized.publicKey),
|
||||
lockup: new Lockup(0, 0, new PublicKey('0x00')),
|
||||
lamports: 3 * minimumAmount + 42,
|
||||
});
|
||||
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
|
@ -288,33 +263,33 @@ test('live staking actions', async () => {
|
|||
let originalStakeBalance = await connection.getBalance(newAccountPubkey);
|
||||
expect(originalStakeBalance).toEqual(3 * minimumAmount + 42);
|
||||
|
||||
let delegation = StakeProgram.delegate(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
let delegation = StakeProgram.delegate({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
votePubkey,
|
||||
);
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, delegation, authorized);
|
||||
|
||||
// Test that withdraw fails before deactivation
|
||||
const recipient = new Account();
|
||||
let withdraw = StakeProgram.withdraw(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
recipient.publicKey,
|
||||
1000,
|
||||
);
|
||||
let withdraw = StakeProgram.withdraw({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
toPubkey: recipient.publicKey,
|
||||
lamports: 1000,
|
||||
});
|
||||
await expect(
|
||||
sendAndConfirmRecentTransaction(connection, withdraw, authorized),
|
||||
).rejects.toThrow();
|
||||
|
||||
// Split stake
|
||||
const newStake = new Account();
|
||||
let split = StakeProgram.split(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
minimumAmount + 20,
|
||||
newStake.publicKey,
|
||||
);
|
||||
let split = StakeProgram.split({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
splitStakePubkey: newStake.publicKey,
|
||||
lamports: minimumAmount + 20,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
split,
|
||||
|
@ -326,26 +301,26 @@ test('live staking actions', async () => {
|
|||
const newAuthorized = new Account();
|
||||
await connection.requestAirdrop(newAuthorized.publicKey, LAMPORTS_PER_SOL);
|
||||
|
||||
let authorize = StakeProgram.authorize(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
newAuthorized.publicKey,
|
||||
StakeAuthorizationLayout.Withdrawer,
|
||||
);
|
||||
let authorize = StakeProgram.authorize({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
newAuthorizedPubkey: newAuthorized.publicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationLayout.Withdrawer,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, authorize, authorized);
|
||||
authorize = StakeProgram.authorize(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
newAuthorized.publicKey,
|
||||
StakeAuthorizationLayout.Staker,
|
||||
);
|
||||
authorize = StakeProgram.authorize({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
newAuthorizedPubkey: newAuthorized.publicKey,
|
||||
stakeAuthorizationType: StakeAuthorizationLayout.Staker,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, authorize, authorized);
|
||||
|
||||
// Test old authorized can't deactivate
|
||||
let deactivateNotAuthorized = StakeProgram.deactivate(
|
||||
newAccountPubkey,
|
||||
authorized.publicKey,
|
||||
);
|
||||
let deactivateNotAuthorized = StakeProgram.deactivate({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: authorized.publicKey,
|
||||
});
|
||||
await expect(
|
||||
sendAndConfirmRecentTransaction(
|
||||
connection,
|
||||
|
@ -355,19 +330,19 @@ test('live staking actions', async () => {
|
|||
).rejects.toThrow();
|
||||
|
||||
// Deactivate stake
|
||||
let deactivate = StakeProgram.deactivate(
|
||||
newAccountPubkey,
|
||||
newAuthorized.publicKey,
|
||||
);
|
||||
let deactivate = StakeProgram.deactivate({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: newAuthorized.publicKey,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, deactivate, newAuthorized);
|
||||
|
||||
// Test that withdraw succeeds after deactivation
|
||||
withdraw = StakeProgram.withdraw(
|
||||
newAccountPubkey,
|
||||
newAuthorized.publicKey,
|
||||
recipient.publicKey,
|
||||
minimumAmount + 20,
|
||||
);
|
||||
withdraw = StakeProgram.withdraw({
|
||||
stakePubkey: newAccountPubkey,
|
||||
authorizedPubkey: newAuthorized.publicKey,
|
||||
toPubkey: recipient.publicKey,
|
||||
lamports: minimumAmount + 20,
|
||||
});
|
||||
await sendAndConfirmRecentTransaction(connection, withdraw, newAuthorized);
|
||||
const balance = await connection.getBalance(newAccountPubkey);
|
||||
expect(balance).toEqual(minimumAmount + 2);
|
||||
|
|
|
@ -112,11 +112,11 @@ test('use nonce', () => {
|
|||
const stakeAccount = new Account();
|
||||
const voteAccount = new Account();
|
||||
const stakeTransaction = new Transaction({nonceInfo}).add(
|
||||
StakeProgram.delegate(
|
||||
stakeAccount.publicKey,
|
||||
account1.publicKey,
|
||||
voteAccount.publicKey,
|
||||
),
|
||||
StakeProgram.delegate({
|
||||
stakePubkey: stakeAccount.publicKey,
|
||||
authorizedPubkey: account1.publicKey,
|
||||
votePubkey: voteAccount.publicKey,
|
||||
}),
|
||||
);
|
||||
stakeTransaction.sign(account1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue