2022-07-13 12:19:51 -07:00
|
|
|
import {expect, use} from 'chai';
|
|
|
|
import chaiAsPromised from 'chai-as-promised';
|
|
|
|
|
|
|
|
import {
|
|
|
|
Keypair,
|
|
|
|
AddressLookupTableProgram,
|
|
|
|
Transaction,
|
|
|
|
AddressLookupTableInstruction,
|
|
|
|
Connection,
|
|
|
|
sendAndConfirmTransaction,
|
2022-08-11 01:57:19 -07:00
|
|
|
} from '../../src';
|
2022-08-11 02:10:11 -07:00
|
|
|
import {sleep} from '../../src/utils/sleep';
|
2022-08-11 01:57:19 -07:00
|
|
|
import {helpers} from '../mocks/rpc-http';
|
|
|
|
import {url} from '../url';
|
2022-07-13 12:19:51 -07:00
|
|
|
|
|
|
|
use(chaiAsPromised);
|
|
|
|
|
|
|
|
describe('AddressLookupTableProgram', () => {
|
|
|
|
it('createAddressLookupTable', () => {
|
|
|
|
const recentSlot = 0;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
const payerPubkey = Keypair.generate().publicKey;
|
|
|
|
const [instruction] = AddressLookupTableProgram.createLookupTable({
|
|
|
|
authority: authorityPubkey,
|
|
|
|
payer: payerPubkey,
|
|
|
|
recentSlot,
|
|
|
|
});
|
|
|
|
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const createLutParams = {
|
|
|
|
authority: authorityPubkey,
|
|
|
|
payer: payerPubkey,
|
|
|
|
recentSlot,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(createLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeCreateLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('extendLookupTableWithPayer', () => {
|
|
|
|
const lutAddress = Keypair.generate().publicKey;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
const payerPubkey = Keypair.generate().publicKey;
|
|
|
|
|
|
|
|
const addressesToAdd = [
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
];
|
|
|
|
|
|
|
|
const instruction = AddressLookupTableProgram.extendLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
payer: payerPubkey,
|
|
|
|
addresses: addressesToAdd,
|
|
|
|
});
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const extendLutParams = {
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
payer: payerPubkey,
|
|
|
|
addresses: addressesToAdd,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(extendLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeExtendLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('extendLookupTableWithoutPayer', () => {
|
|
|
|
const lutAddress = Keypair.generate().publicKey;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
|
|
|
|
const addressesToAdd = [
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
Keypair.generate().publicKey,
|
|
|
|
];
|
|
|
|
|
|
|
|
const instruction = AddressLookupTableProgram.extendLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
addresses: addressesToAdd,
|
|
|
|
});
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const extendLutParams = {
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
payer: undefined,
|
|
|
|
addresses: addressesToAdd,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(extendLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeExtendLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('closeLookupTable', () => {
|
|
|
|
const lutAddress = Keypair.generate().publicKey;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
const recipientPubkey = Keypair.generate().publicKey;
|
|
|
|
|
|
|
|
const instruction = AddressLookupTableProgram.closeLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
recipient: recipientPubkey,
|
|
|
|
});
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const closeLutParams = {
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
recipient: recipientPubkey,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(closeLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeCloseLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('freezeLookupTable', () => {
|
|
|
|
const lutAddress = Keypair.generate().publicKey;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
|
|
|
|
const instruction = AddressLookupTableProgram.freezeLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
});
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const freezeLutParams = {
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(freezeLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeFreezeLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('deactivateLookupTable', () => {
|
|
|
|
const lutAddress = Keypair.generate().publicKey;
|
|
|
|
const authorityPubkey = Keypair.generate().publicKey;
|
|
|
|
|
|
|
|
const instruction = AddressLookupTableProgram.deactivateLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
});
|
|
|
|
|
|
|
|
const transaction = new Transaction().add(instruction);
|
|
|
|
const deactivateLutParams = {
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authorityPubkey,
|
|
|
|
};
|
|
|
|
expect(transaction.instructions).to.have.length(1);
|
|
|
|
expect(deactivateLutParams).to.eql(
|
|
|
|
AddressLookupTableInstruction.decodeDeactivateLookupTable(instruction),
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (process.env.TEST_LIVE) {
|
|
|
|
it('live address lookup table actions', async () => {
|
|
|
|
const connection = new Connection(url, 'confirmed');
|
|
|
|
const authority = Keypair.generate();
|
|
|
|
const payer = Keypair.generate();
|
|
|
|
|
|
|
|
const slot = await connection.getSlot('confirmed');
|
|
|
|
const payerMinBalance =
|
|
|
|
await connection.getMinimumBalanceForRentExemption(44 * 10);
|
|
|
|
|
|
|
|
const [createInstruction, lutAddress] =
|
|
|
|
AddressLookupTableProgram.createLookupTable({
|
|
|
|
authority: authority.publicKey,
|
|
|
|
payer: payer.publicKey,
|
|
|
|
recentSlot: slot,
|
|
|
|
});
|
|
|
|
|
|
|
|
await helpers.airdrop({
|
|
|
|
connection,
|
|
|
|
address: payer.publicKey,
|
|
|
|
amount: payerMinBalance,
|
|
|
|
});
|
|
|
|
|
|
|
|
await helpers.airdrop({
|
|
|
|
connection,
|
|
|
|
address: authority.publicKey,
|
|
|
|
amount: payerMinBalance,
|
|
|
|
});
|
|
|
|
|
|
|
|
// Creating a new lut
|
|
|
|
const createLutTransaction = new Transaction();
|
|
|
|
createLutTransaction.add(createInstruction);
|
|
|
|
createLutTransaction.feePayer = payer.publicKey;
|
|
|
|
|
|
|
|
await sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
createLutTransaction,
|
|
|
|
[authority, payer],
|
|
|
|
{preflightCommitment: 'confirmed'},
|
|
|
|
);
|
|
|
|
|
|
|
|
await sleep(500);
|
|
|
|
|
|
|
|
// Extending a lut without a payer
|
|
|
|
await helpers.airdrop({
|
|
|
|
connection,
|
|
|
|
address: lutAddress,
|
|
|
|
amount: payerMinBalance,
|
|
|
|
});
|
|
|
|
|
|
|
|
const extendWithoutPayerInstruction =
|
|
|
|
AddressLookupTableProgram.extendLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authority.publicKey,
|
|
|
|
addresses: [...Array(10)].map(() => Keypair.generate().publicKey),
|
|
|
|
});
|
|
|
|
const extendLutWithoutPayerTransaction = new Transaction();
|
|
|
|
extendLutWithoutPayerTransaction.add(extendWithoutPayerInstruction);
|
|
|
|
|
|
|
|
await sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
extendLutWithoutPayerTransaction,
|
|
|
|
[authority],
|
|
|
|
{preflightCommitment: 'confirmed'},
|
|
|
|
);
|
|
|
|
|
|
|
|
// Extending an lut with a payer
|
|
|
|
const extendWithPayerInstruction =
|
|
|
|
AddressLookupTableProgram.extendLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authority.publicKey,
|
|
|
|
payer: payer.publicKey,
|
|
|
|
addresses: [...Array(10)].map(() => Keypair.generate().publicKey),
|
|
|
|
});
|
|
|
|
|
|
|
|
const extendLutWithPayerTransaction = new Transaction();
|
|
|
|
extendLutWithPayerTransaction.add(extendWithPayerInstruction);
|
|
|
|
|
|
|
|
await sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
extendLutWithPayerTransaction,
|
|
|
|
[authority, payer],
|
|
|
|
{preflightCommitment: 'confirmed'},
|
|
|
|
);
|
|
|
|
|
|
|
|
//deactivating the lut
|
|
|
|
const deactivateInstruction =
|
|
|
|
AddressLookupTableProgram.deactivateLookupTable({
|
|
|
|
lookupTable: lutAddress,
|
|
|
|
authority: authority.publicKey,
|
|
|
|
});
|
|
|
|
|
|
|
|
const deactivateLutTransaction = new Transaction();
|
|
|
|
deactivateLutTransaction.add(deactivateInstruction);
|
|
|
|
await sendAndConfirmTransaction(
|
|
|
|
connection,
|
|
|
|
deactivateLutTransaction,
|
|
|
|
[authority],
|
|
|
|
{preflightCommitment: 'confirmed'},
|
|
|
|
);
|
|
|
|
|
|
|
|
// After deactivation, LUTs can be closed *only* after a short perioid of time
|
|
|
|
}).timeout(10 * 1000);
|
|
|
|
}
|
|
|
|
});
|