solana-web3: add TransferWithSeed implementation (#14570)
* fix: add handling for TransferWithSeed system instruction * chore: add failing Assign/AllocateWithSeed test * fix: broken Allocate/AssignWithSeed methods
This commit is contained in:
@ -198,6 +198,23 @@ export type AssignWithSeedParams = {|
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Transfer with seed system transaction params
|
||||
* @typedef {Object} TransferWithSeedParams
|
||||
* @property {PublicKey} accountPubkey
|
||||
* @property {PublicKey} basePubkey
|
||||
* @property {string} seed
|
||||
* @property {PublicKey} programId
|
||||
*/
|
||||
export type TransferWithSeedParams = {|
|
||||
fromPubkey: PublicKey,
|
||||
basePubkey: PublicKey,
|
||||
toPubkey: PublicKey,
|
||||
lamports: number,
|
||||
seed: string,
|
||||
programId: PublicKey,
|
||||
|};
|
||||
|
||||
/**
|
||||
* System Instruction class
|
||||
*/
|
||||
@ -269,6 +286,30 @@ export class SystemInstruction {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a transfer with seed system instruction and retrieve the instruction params.
|
||||
*/
|
||||
static decodeTransferWithSeed(
|
||||
instruction: TransactionInstruction,
|
||||
): TransferWithSeedParams {
|
||||
this.checkProgramId(instruction.programId);
|
||||
this.checkKeyLength(instruction.keys, 3);
|
||||
|
||||
const {lamports, seed, programId} = decodeData(
|
||||
SYSTEM_INSTRUCTION_LAYOUTS.TransferWithSeed,
|
||||
instruction.data,
|
||||
);
|
||||
|
||||
return {
|
||||
fromPubkey: instruction.keys[0].pubkey,
|
||||
basePubkey: instruction.keys[1].pubkey,
|
||||
toPubkey: instruction.keys[2].pubkey,
|
||||
lamports,
|
||||
seed,
|
||||
programId: new PublicKey(programId),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an allocate system instruction and retrieve the instruction params.
|
||||
*/
|
||||
@ -576,6 +617,15 @@ export const SYSTEM_INSTRUCTION_LAYOUTS = Object.freeze({
|
||||
Layout.publicKey('programId'),
|
||||
]),
|
||||
},
|
||||
TransferWithSeed: {
|
||||
index: 11,
|
||||
layout: BufferLayout.struct([
|
||||
BufferLayout.u32('instruction'),
|
||||
BufferLayout.ns64('lamports'),
|
||||
Layout.rustString('seed'),
|
||||
Layout.publicKey('programId'),
|
||||
]),
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
@ -613,15 +663,34 @@ export class SystemProgram {
|
||||
/**
|
||||
* Generate a transaction instruction that transfers lamports from one account to another
|
||||
*/
|
||||
static transfer(params: TransferParams): TransactionInstruction {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer;
|
||||
const data = encodeData(type, {lamports: params.lamports});
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys: [
|
||||
static transfer(
|
||||
params: TransferParams | TransferWithSeedParams,
|
||||
): TransactionInstruction {
|
||||
let data;
|
||||
let keys;
|
||||
if (params.basePubkey) {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.TransferWithSeed;
|
||||
data = encodeData(type, {
|
||||
lamports: params.lamports,
|
||||
seed: params.seed,
|
||||
programId: params.programId.toBuffer(),
|
||||
});
|
||||
keys = [
|
||||
{pubkey: params.fromPubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: params.basePubkey, isSigner: true, isWritable: false},
|
||||
{pubkey: params.toPubkey, isSigner: false, isWritable: true},
|
||||
];
|
||||
} else {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Transfer;
|
||||
data = encodeData(type, {lamports: params.lamports});
|
||||
keys = [
|
||||
{pubkey: params.fromPubkey, isSigner: true, isWritable: true},
|
||||
{pubkey: params.toPubkey, isSigner: false, isWritable: true},
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
@ -634,6 +703,7 @@ export class SystemProgram {
|
||||
params: AssignParams | AssignWithSeedParams,
|
||||
): TransactionInstruction {
|
||||
let data;
|
||||
let keys;
|
||||
if (params.basePubkey) {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.AssignWithSeed;
|
||||
data = encodeData(type, {
|
||||
@ -641,13 +711,18 @@ export class SystemProgram {
|
||||
seed: params.seed,
|
||||
programId: params.programId.toBuffer(),
|
||||
});
|
||||
keys = [
|
||||
{pubkey: params.accountPubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: params.basePubkey, isSigner: true, isWritable: false},
|
||||
];
|
||||
} else {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Assign;
|
||||
data = encodeData(type, {programId: params.programId.toBuffer()});
|
||||
keys = [{pubkey: params.accountPubkey, isSigner: true, isWritable: true}];
|
||||
}
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys: [{pubkey: params.accountPubkey, isSigner: true, isWritable: true}],
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
@ -822,6 +897,7 @@ export class SystemProgram {
|
||||
params: AllocateParams | AllocateWithSeedParams,
|
||||
): TransactionInstruction {
|
||||
let data;
|
||||
let keys;
|
||||
if (params.basePubkey) {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.AllocateWithSeed;
|
||||
data = encodeData(type, {
|
||||
@ -830,15 +906,20 @@ export class SystemProgram {
|
||||
space: params.space,
|
||||
programId: params.programId.toBuffer(),
|
||||
});
|
||||
keys = [
|
||||
{pubkey: params.accountPubkey, isSigner: false, isWritable: true},
|
||||
{pubkey: params.basePubkey, isSigner: true, isWritable: false},
|
||||
];
|
||||
} else {
|
||||
const type = SYSTEM_INSTRUCTION_LAYOUTS.Allocate;
|
||||
data = encodeData(type, {
|
||||
space: params.space,
|
||||
});
|
||||
keys = [{pubkey: params.accountPubkey, isSigner: true, isWritable: true}];
|
||||
}
|
||||
|
||||
return new TransactionInstruction({
|
||||
keys: [{pubkey: params.accountPubkey, isSigner: true, isWritable: true}],
|
||||
keys,
|
||||
programId: this.programId,
|
||||
data,
|
||||
});
|
||||
|
Reference in New Issue
Block a user