chore: migrate to typescript
This commit is contained in:
committed by
Justin Starry
parent
3eb9f7b3eb
commit
f912c63b22
756
web3.js/src/stake-program.ts
Normal file
756
web3.js/src/stake-program.ts
Normal file
@@ -0,0 +1,756 @@
|
||||
import * as BufferLayout from 'buffer-layout';
|
||||
|
||||
import {encodeData, decodeData, InstructionType} from './instruction';
|
||||
import * as Layout from './layout';
|
||||
import {PublicKey} from './publickey';
|
||||
import {SystemProgram} from './system-program';
|
||||
import {
|
||||
SYSVAR_CLOCK_PUBKEY,
|
||||
SYSVAR_RENT_PUBKEY,
|
||||
SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||
} from './sysvar';
|
||||
import {Transaction, TransactionInstruction} from './transaction';
|
||||
|
||||
/**
|
||||
* Address of the stake config account which configures the rate
|
||||
* of stake warmup and cooldown as well as the slashing penalty.
|
||||
*/
|
||||
export const STAKE_CONFIG_ID = new PublicKey(
|
||||
'StakeConfig11111111111111111111111111111111',
|
||||
);
|
||||
|
||||
/**
|
||||
* Stake account authority info
|
||||
*/
|
||||
export class Authorized {
|
||||
/** stake authority */
|
||||
staker: PublicKey;
|
||||
/** withdraw authority */
|
||||
withdrawer: PublicKey;
|
||||
|
||||
/**
|
||||
* Create a new Authorized object
|
||||
* @param staker the stake authority
|
||||
* @param withdrawer the withdraw authority
|
||||
*/
|
||||
constructor(staker: PublicKey, withdrawer: PublicKey) {
|
||||
this.staker = staker;
|
||||
this.withdrawer = withdrawer;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stake account lockup info
|
||||
*/
|
||||
export class Lockup {
|
||||
/** Unix timestamp of lockup expiration */
|
||||
unixTimestamp: number;
|
||||
/** Epoch of lockup expiration */
|
||||
epoch: number;
|
||||
/** Lockup custodian authority */
|
||||
custodian: PublicKey;
|
||||
|
||||
/**
|
||||
* Create a new Lockup object
|
||||
*/
|
||||
constructor(unixTimestamp: number, epoch: number, custodian: PublicKey) {
|
||||
this.unixTimestamp = unixTimestamp;
|
||||
this.epoch = epoch;
|
||||
this.custodian = custodian;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create stake account transaction params
|
||||
*/
|
||||
export type CreateStakeAccountParams = {
|
||||
/** Address of the account which will fund creation */
|
||||
fromPubkey: PublicKey;
|
||||
/** Address of the new stake account */
|
||||
stakePubkey: PublicKey;
|
||||
/** Authorities of the new stake account */
|
||||
authorized: Authorized;
|
||||
/** Lockup of the new stake account */
|
||||
lockup: Lockup;
|
||||
/** Funding amount */
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create stake account with seed transaction params
|
||||
*/
|
||||
export type CreateStakeAccountWithSeedParams = {
|
||||
fromPubkey: PublicKey;
|
||||
stakePubkey: PublicKey;
|
||||
basePubkey: PublicKey;
|
||||
seed: string;
|
||||
authorized: Authorized;
|
||||
lockup: Lockup;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize stake instruction params
|
||||
*/
|
||||
export type InitializeStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorized: Authorized;
|
||||
lockup: Lockup;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delegate stake instruction params
|
||||
*/
|
||||
export type DelegateStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
votePubkey: PublicKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authorize stake instruction params
|
||||
*/
|
||||
export type AuthorizeStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
newAuthorizedPubkey: PublicKey;
|
||||
stakeAuthorizationType: StakeAuthorizationType;
|
||||
custodianPubkey?: PublicKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Authorize stake instruction params using a derived key
|
||||
*/
|
||||
export type AuthorizeWithSeedStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorityBase: PublicKey;
|
||||
authoritySeed: string;
|
||||
authorityOwner: PublicKey;
|
||||
newAuthorizedPubkey: PublicKey;
|
||||
stakeAuthorizationType: StakeAuthorizationType;
|
||||
custodianPubkey?: PublicKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Split stake instruction params
|
||||
*/
|
||||
export type SplitStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
splitStakePubkey: PublicKey;
|
||||
lamports: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Withdraw stake instruction params
|
||||
*/
|
||||
export type WithdrawStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
toPubkey: PublicKey;
|
||||
lamports: number;
|
||||
custodianPubkey?: PublicKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Deactivate stake instruction params
|
||||
*/
|
||||
export type DeactivateStakeParams = {
|
||||
stakePubkey: PublicKey;
|
||||
authorizedPubkey: PublicKey;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stake Instruction class
|
||||
*/
|
||||
export class StakeInstruction {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
let type: StakeInstructionType | undefined;
|
||||
for (const [ixType, layout] of Object.entries(STAKE_INSTRUCTION_LAYOUTS)) {
|
||||
if (layout.index == typeIndex) {
|
||||
type = ixType as StakeInstructionType;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!type) {
|
||||
throw new Error('Instruction type incorrect; not a StakeInstruction');
|
||||
}
|
||||
|
||||
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),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a delegate stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
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,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an authorize stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeAuthorize(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
const {newAuthorized, stakeAuthorizationType} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.Authorize,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
const o: AuthorizeStakeParams = {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
authorizedPubkey: instruction.keys[2].pubkey,
|
||||
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
||||
stakeAuthorizationType: {
|
||||
index: stakeAuthorizationType,
|
||||
},
|
||||
};
|
||||
if (instruction.keys.length > 3) {
|
||||
o.custodianPubkey = instruction.keys[3].pubkey;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an authorize-with-seed stake instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeAuthorizeWithSeed(
|
||||
instruction: TransactionInstruction,
|
||||
): AuthorizeWithSeedStakeParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 2);
|
||||
|
||||
const {
|
||||
newAuthorized,
|
||||
stakeAuthorizationType,
|
||||
authoritySeed,
|
||||
authorityOwner,
|
||||
} = decodeData(
|
||||
STAKE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
const o: AuthorizeWithSeedStakeParams = {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
authorityBase: instruction.keys[1].pubkey,
|
||||
authoritySeed: authoritySeed,
|
||||
authorityOwner: new PublicKey(authorityOwner),
|
||||
newAuthorizedPubkey: new PublicKey(newAuthorized),
|
||||
stakeAuthorizationType: {
|
||||
index: stakeAuthorizationType,
|
||||
},
|
||||
};
|
||||
if (instruction.keys.length > 3) {
|
||||
o.custodianPubkey = instruction.keys[3].pubkey;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
);
|
||||
|
||||
const o: WithdrawStakeParams = {
|
||||
stakePubkey: instruction.keys[0].pubkey,
|
||||
toPubkey: instruction.keys[1].pubkey,
|
||||
authorizedPubkey: instruction.keys[4].pubkey,
|
||||
lamports,
|
||||
};
|
||||
if (instruction.keys.length > 5) {
|
||||
o.custodianPubkey = instruction.keys[5].pubkey;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static checkProgramId(programId: PublicKey) {
|
||||
if (!programId.equals(StakeProgram.programId)) {
|
||||
throw new Error('invalid instruction; programId is not StakeProgram');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
static checkKeyLength(keys: Array<any>, expectedLength: number) {
|
||||
if (keys.length < expectedLength) {
|
||||
throw new Error(
|
||||
`invalid instruction; found ${keys.length} keys, expected at least ${expectedLength}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An enumeration of valid StakeInstructionType's
|
||||
*/
|
||||
export type StakeInstructionType =
|
||||
| 'AuthorizeWithSeed'
|
||||
| 'Authorize'
|
||||
| 'Deactivate'
|
||||
| 'Delegate'
|
||||
| 'Initialize'
|
||||
| 'Split'
|
||||
| 'Withdraw';
|
||||
|
||||
/**
|
||||
* An enumeration of valid stake InstructionType's
|
||||
*/
|
||||
export const STAKE_INSTRUCTION_LAYOUTS: {
|
||||
[type in StakeInstructionType]: InstructionType;
|
||||
} = Object.freeze({
|
||||
Initialize: {
|
||||
index: 0,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
Layout.authorized(),
|
||||
Layout.lockup(),
|
||||
]),
|
||||
},
|
||||
Authorize: {
|
||||
index: 1,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
Layout.publicKey('newAuthorized'),
|
||||
BufferLayout.u32('stakeAuthorizationType'),
|
||||
]),
|
||||
},
|
||||
Delegate: {
|
||||
index: 2,
|
||||
layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
|
||||
},
|
||||
Split: {
|
||||
index: 3,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
BufferLayout.ns64('lamports'),
|
||||
]),
|
||||
},
|
||||
Withdraw: {
|
||||
index: 4,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
BufferLayout.ns64('lamports'),
|
||||
]),
|
||||
},
|
||||
Deactivate: {
|
||||
index: 5,
|
||||
layout: BufferLayout.struct([BufferLayout.u32('instruction')]),
|
||||
},
|
||||
AuthorizeWithSeed: {
|
||||
index: 8,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
Layout.publicKey('newAuthorized'),
|
||||
BufferLayout.u32('stakeAuthorizationType'),
|
||||
Layout.rustString('authoritySeed'),
|
||||
Layout.publicKey('authorityOwner'),
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef {Object} StakeAuthorizationType
|
||||
* @property (index} The Stake Authorization index (from solana-stake-program)
|
||||
*/
|
||||
export type StakeAuthorizationType = {
|
||||
index: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* An enumeration of valid StakeAuthorizationLayout's
|
||||
*/
|
||||
export const StakeAuthorizationLayout = Object.freeze({
|
||||
Staker: {
|
||||
index: 0,
|
||||
},
|
||||
Withdrawer: {
|
||||
index: 1,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Factory class for transactions to interact with the Stake program
|
||||
*/
|
||||
export class StakeProgram {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor() {}
|
||||
|
||||
/**
|
||||
* Public key that identifies the Stake program
|
||||
*/
|
||||
static get programId(): PublicKey {
|
||||
return new PublicKey('Stake11111111111111111111111111111111111111');
|
||||
}
|
||||
|
||||
/**
|
||||
* Max space of a Stake account
|
||||
*
|
||||
* This is generated from the solana-stake-program StakeState struct as
|
||||
* `std::mem::size_of::<StakeState>()`:
|
||||
* https://docs.rs/solana-stake-program/1.4.4/solana_stake_program/stake_state/enum.StakeState.html
|
||||
*/
|
||||
static get space(): number {
|
||||
return 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an Initialize instruction to add to a Stake Create transaction
|
||||
*/
|
||||
static initialize(params: InitializeStakeParams): TransactionInstruction {
|
||||
const {stakePubkey, authorized, lockup} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Initialize;
|
||||
const data = encodeData(type, {
|
||||
authorized: {
|
||||
staker: authorized.staker.toBuffer(),
|
||||
withdrawer: authorized.withdrawer.toBuffer(),
|
||||
},
|
||||
lockup: {
|
||||
unixTimestamp: lockup.unixTimestamp,
|
||||
epoch: lockup.epoch,
|
||||
custodian: lockup.custodian.toBuffer(),
|
||||
},
|
||||
});
|
||||
const instructionData = {
|
||||
keys: [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
};
|
||||
return new TransactionInstruction(instructionData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that creates a new Stake account at
|
||||
* an address generated with `from`, a seed, and the Stake programId
|
||||
*/
|
||||
static createAccountWithSeed(
|
||||
params: CreateStakeAccountWithSeedParams,
|
||||
): Transaction {
|
||||
const transaction = new Transaction();
|
||||
transaction.add(
|
||||
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}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that creates a new Stake account
|
||||
*/
|
||||
static createAccount(params: CreateStakeAccountParams): Transaction {
|
||||
const transaction = new Transaction();
|
||||
transaction.add(
|
||||
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}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that delegates Stake tokens to a validator
|
||||
* Vote PublicKey. This transaction can also be used to redelegate Stake
|
||||
* to a new validator Vote PublicKey.
|
||||
*/
|
||||
static delegate(params: DelegateStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, votePubkey} = params;
|
||||
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Delegate;
|
||||
const data = encodeData(type);
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: votePubkey, isSigner: false, isWritable: false},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
||||
{
|
||||
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{pubkey: STAKE_CONFIG_ID, isSigner: false, isWritable: false},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that authorizes a new PublicKey as Staker
|
||||
* or Withdrawer on the Stake account.
|
||||
*/
|
||||
static authorize(params: AuthorizeStakeParams): Transaction {
|
||||
const {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
newAuthorizedPubkey,
|
||||
stakeAuthorizationType,
|
||||
custodianPubkey,
|
||||
} = params;
|
||||
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Authorize;
|
||||
const data = encodeData(type, {
|
||||
newAuthorized: newAuthorizedPubkey.toBuffer(),
|
||||
stakeAuthorizationType: stakeAuthorizationType.index,
|
||||
});
|
||||
|
||||
const keys = [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: true},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
];
|
||||
if (custodianPubkey) {
|
||||
keys.push({pubkey: custodianPubkey, isSigner: false, isWritable: false});
|
||||
}
|
||||
return new Transaction().add({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that authorizes a new PublicKey as Staker
|
||||
* or Withdrawer on the Stake account.
|
||||
*/
|
||||
static authorizeWithSeed(params: AuthorizeWithSeedStakeParams): Transaction {
|
||||
const {
|
||||
stakePubkey,
|
||||
authorityBase,
|
||||
authoritySeed,
|
||||
authorityOwner,
|
||||
newAuthorizedPubkey,
|
||||
stakeAuthorizationType,
|
||||
custodianPubkey,
|
||||
} = params;
|
||||
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.AuthorizeWithSeed;
|
||||
const data = encodeData(type, {
|
||||
newAuthorized: newAuthorizedPubkey.toBuffer(),
|
||||
stakeAuthorizationType: stakeAuthorizationType.index,
|
||||
authoritySeed: authoritySeed,
|
||||
authorityOwner: authorityOwner.toBuffer(),
|
||||
});
|
||||
|
||||
const keys = [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: authorityBase, isSigner: true, isWritable: false},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
||||
];
|
||||
if (custodianPubkey) {
|
||||
keys.push({pubkey: custodianPubkey, isSigner: false, isWritable: false});
|
||||
}
|
||||
return new Transaction().add({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that splits Stake tokens into another stake account
|
||||
*/
|
||||
static split(params: SplitStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey, splitStakePubkey, lamports} = params;
|
||||
|
||||
const transaction = new Transaction();
|
||||
transaction.add(
|
||||
SystemProgram.createAccount({
|
||||
fromPubkey: authorizedPubkey,
|
||||
newAccountPubkey: splitStakePubkey,
|
||||
lamports: 0,
|
||||
space: this.space,
|
||||
programId: this.programId,
|
||||
}),
|
||||
);
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Split;
|
||||
const data = encodeData(type, {lamports});
|
||||
|
||||
return transaction.add({
|
||||
keys: [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: splitStakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that withdraws deactivated Stake tokens.
|
||||
*/
|
||||
static withdraw(params: WithdrawStakeParams): Transaction {
|
||||
const {
|
||||
stakePubkey,
|
||||
authorizedPubkey,
|
||||
toPubkey,
|
||||
lamports,
|
||||
custodianPubkey,
|
||||
} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Withdraw;
|
||||
const data = encodeData(type, {lamports});
|
||||
|
||||
const keys = [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: toPubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
||||
{
|
||||
pubkey: SYSVAR_STAKE_HISTORY_PUBKEY,
|
||||
isSigner: false,
|
||||
isWritable: false,
|
||||
},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
];
|
||||
if (custodianPubkey) {
|
||||
keys.push({pubkey: custodianPubkey, isSigner: false, isWritable: false});
|
||||
}
|
||||
return new Transaction().add({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a Transaction that deactivates Stake tokens.
|
||||
*/
|
||||
static deactivate(params: DeactivateStakeParams): Transaction {
|
||||
const {stakePubkey, authorizedPubkey} = params;
|
||||
const type = STAKE_INSTRUCTION_LAYOUTS.Deactivate;
|
||||
const data = encodeData(type);
|
||||
|
||||
return new Transaction().add({
|
||||
keys: [
|
||||
{pubkey: stakePubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: SYSVAR_CLOCK_PUBKEY, isSigner: false, isWritable: false},
|
||||
{pubkey: authorizedPubkey, isSigner: true, isWritable: false},
|
||||
],
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user