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:
Tyera Eulberg
2021-01-14 09:59:31 -07:00
committed by GitHub
parent b37dbed479
commit 1eb7681a85
4 changed files with 291 additions and 11 deletions

View File

@ -3,6 +3,7 @@
import {
Account,
Connection,
PublicKey,
StakeProgram,
SystemInstruction,
SystemProgram,
@ -52,6 +53,23 @@ test('transfer', () => {
expect(params).toEqual(SystemInstruction.decodeTransfer(systemInstruction));
});
test('transferWithSeed', () => {
const params = {
fromPubkey: new Account().publicKey,
basePubkey: new Account().publicKey,
toPubkey: new Account().publicKey,
lamports: 123,
seed: '你好',
programId: new Account().publicKey,
};
const transaction = new Transaction().add(SystemProgram.transfer(params));
expect(transaction.instructions).toHaveLength(1);
const [systemInstruction] = transaction.instructions;
expect(params).toEqual(
SystemInstruction.decodeTransferWithSeed(systemInstruction),
);
});
test('allocate', () => {
const params = {
accountPubkey: new Account().publicKey,
@ -402,3 +420,154 @@ test('live Nonce actions', async () => {
);
expect(withdrawBalance).toEqual(minimumAmount);
});
test('live withSeed actions', async () => {
if (mockRpcEnabled) {
console.log('non-live test skipped');
return;
}
const connection = new Connection(url, 'singleGossip');
const baseAccount = await newAccountWithLamports(
connection,
2 * LAMPORTS_PER_SOL,
);
const basePubkey = baseAccount.publicKey;
const seed = 'hi there';
const programId = new Account().publicKey;
const createAccountWithSeedAddress = await PublicKey.createWithSeed(
basePubkey,
seed,
programId,
);
const space = 0;
const minimumAmount = await connection.getMinimumBalanceForRentExemption(
space,
);
const createAccountWithSeedParams = {
fromPubkey: basePubkey,
newAccountPubkey: createAccountWithSeedAddress,
basePubkey,
seed,
lamports: minimumAmount,
space,
programId,
};
const createAccountWithSeedTransaction = new Transaction().add(
SystemProgram.createAccountWithSeed(createAccountWithSeedParams),
);
await sendAndConfirmTransaction(
connection,
createAccountWithSeedTransaction,
[baseAccount],
{commitment: 'singleGossip', preflightCommitment: 'singleGossip'},
);
const createAccountWithSeedBalance = await connection.getBalance(
createAccountWithSeedAddress,
);
expect(createAccountWithSeedBalance).toEqual(minimumAmount);
// Transfer to a derived address
const programId2 = new Account().publicKey;
const transferWithSeedAddress = await PublicKey.createWithSeed(
basePubkey,
seed,
programId2,
);
await sendAndConfirmTransaction(
connection,
new Transaction().add(
SystemProgram.transfer({
fromPubkey: baseAccount.publicKey,
toPubkey: transferWithSeedAddress,
lamports: 3 * minimumAmount,
}),
),
[baseAccount],
{commitment: 'singleGossip', preflightCommitment: 'singleGossip'},
);
let transferWithSeedAddressBalance = await connection.getBalance(
transferWithSeedAddress,
);
expect(transferWithSeedAddressBalance).toEqual(3 * minimumAmount);
// Test TransferWithSeed
const programId3 = new Account();
const toPubkey = await PublicKey.createWithSeed(
basePubkey,
seed,
programId3.publicKey,
);
const transferWithSeedParams = {
fromPubkey: transferWithSeedAddress,
basePubkey,
toPubkey,
lamports: 2 * minimumAmount,
seed,
programId: programId2,
};
const transferWithSeedTransaction = new Transaction().add(
SystemProgram.transfer(transferWithSeedParams),
);
await sendAndConfirmTransaction(
connection,
transferWithSeedTransaction,
[baseAccount],
{commitment: 'singleGossip', preflightCommitment: 'singleGossip'},
);
const toBalance = await connection.getBalance(toPubkey);
expect(toBalance).toEqual(2 * minimumAmount);
transferWithSeedAddressBalance = await connection.getBalance(
createAccountWithSeedAddress,
);
expect(transferWithSeedAddressBalance).toEqual(minimumAmount);
// Test AllocateWithSeed
const allocateWithSeedParams = {
accountPubkey: toPubkey,
basePubkey,
seed,
space: 10,
programId: programId3.publicKey,
};
const allocateWithSeedTransaction = new Transaction().add(
SystemProgram.allocate(allocateWithSeedParams),
);
await sendAndConfirmTransaction(
connection,
allocateWithSeedTransaction,
[baseAccount],
{commitment: 'singleGossip', preflightCommitment: 'singleGossip'},
);
let account = await connection.getAccountInfo(toPubkey);
if (account === null) {
expect(account).not.toBeNull();
return;
}
expect(account.data).toHaveLength(10);
// Test AssignWithSeed
const assignWithSeedParams = {
accountPubkey: toPubkey,
basePubkey,
seed,
programId: programId3.publicKey,
};
const assignWithSeedTransaction = new Transaction().add(
SystemProgram.assign(assignWithSeedParams),
);
await sendAndConfirmTransaction(
connection,
assignWithSeedTransaction,
[baseAccount],
{commitment: 'singleGossip', preflightCommitment: 'singleGossip'},
);
account = await connection.getAccountInfo(toPubkey);
if (account === null) {
expect(account).not.toBeNull();
return;
}
expect(account.owner).toEqual(programId3.publicKey);
});