Skip to content

Commit

Permalink
Add getInitializeInstructionsForMintExtensions helper (#10)
Browse files Browse the repository at this point in the history
  • Loading branch information
lorisleiva authored Oct 8, 2024
1 parent 91ffbcb commit f733892
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 111 deletions.
44 changes: 44 additions & 0 deletions clients/js/src/getInitializeInstructionsForMintExtensions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Address, IInstruction } from '@solana/web3.js';
import {
ExtensionArgs,
getInitializeConfidentialTransferMintInstruction,
getInitializeDefaultAccountStateInstruction,
getInitializeTransferFeeConfigInstruction,
} from './generated';

export function getInitializeInstructionsForMintExtensions(
mint: Address,
extensions: ExtensionArgs[]
): IInstruction[] {
return extensions.flatMap((extension) => {
switch (extension.__kind) {
case 'ConfidentialTransferMint':
return [
getInitializeConfidentialTransferMintInstruction({
mint,
...extension,
}),
];
case 'DefaultAccountState':
return [
getInitializeDefaultAccountStateInstruction({
mint,
state: extension.state,
}),
];
case 'TransferFeeConfig':
return [
getInitializeTransferFeeConfigInstruction({
mint,
transferFeeConfigAuthority: extension.transferFeeConfigAuthority,
withdrawWithheldAuthority: extension.withdrawWithheldAuthority,
transferFeeBasisPoints:
extension.newerTransferFee.transferFeeBasisPoints,
maximumFee: extension.newerTransferFee.maximumFee,
}),
];
default:
return [];
}
});
}
1 change: 1 addition & 0 deletions clients/js/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './generated';

export * from './getInitializeInstructionsForMintExtensions';
export * from './getTokenSize';
export * from './getMintSize';
15 changes: 13 additions & 2 deletions clients/js/test/_setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
ExtensionArgs,
TOKEN_2022_PROGRAM_ADDRESS,
getInitializeAccountInstruction,
getInitializeInstructionsForMintExtensions,
getInitializeMintInstruction,
getMintSize,
getMintToInstruction,
Expand Down Expand Up @@ -163,8 +164,18 @@ export const createMint = async (
input: Omit<Parameters<typeof getCreateMintInstructions>[0], 'mint'>
): Promise<Address> => {
const mint = await generateKeyPairSigner();
const instructions = await getCreateMintInstructions({ ...input, mint });
await sendAndConfirmInstructions(input.client, input.payer, instructions);
const [createAccount, initMint] = await getCreateMintInstructions({
...input,
mint,
});
await sendAndConfirmInstructions(input.client, input.payer, [
createAccount,
...getInitializeInstructionsForMintExtensions(
mint.address,
input.extensions ?? []
),
initMint,
]);
return mint.address;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,64 +10,53 @@ import {
Mint,
extension,
fetchMint,
getInitializeConfidentialTransferMintInstruction,
getUpdateConfidentialTransferMintInstruction,
} from '../../../src';
import {
createDefaultSolanaClient,
createMint,
generateKeyPairSignerWithSol,
getCreateMintInstructions,
sendAndConfirmInstructions,
} from '../../_setup';

test('it updates a mint account with confidential transfer', async (t) => {
// Given some signer accounts.
const client = createDefaultSolanaClient();
const [authority, confidentialTransferAuthority, mint] = await Promise.all([
const [authority, confidentialTransferAuthority] = await Promise.all([
generateKeyPairSignerWithSol(client),
generateKeyPairSigner(),
generateKeyPairSigner(),
]);

// And a mint account initialized with a confidential transfer extension.
const confidentialTransferExtension = extension('ConfidentialTransferMint', {
authority: some(confidentialTransferAuthority.address),
autoApproveNewAccounts: true,
auditorElgamalPubkey: some(
address('BTNEPmmWuj7Sg4Fo5i1FC5eiV2Aj4jiv9boarvE5XeaX')
),
const mint = await createMint({
authority: authority.address,
client,
extensions: [
extension('ConfidentialTransferMint', {
authority: some(confidentialTransferAuthority.address),
autoApproveNewAccounts: true,
auditorElgamalPubkey: some(
address('BTNEPmmWuj7Sg4Fo5i1FC5eiV2Aj4jiv9boarvE5XeaX')
),
}),
],
payer: authority,
});
const [createMintInstruction, initMintInstruction] =
await getCreateMintInstructions({
authority: authority.address,
client,
extensions: [confidentialTransferExtension],
mint,
payer: authority,
});
await sendAndConfirmInstructions(client, authority, [
createMintInstruction,
getInitializeConfidentialTransferMintInstruction({
mint: mint.address,
...confidentialTransferExtension,
}),
initMintInstruction,
]);

// When we update the mint account with new confidential transfer configs.
await sendAndConfirmInstructions(client, authority, [
getUpdateConfidentialTransferMintInstruction({
mint: mint.address,
mint,
authority: confidentialTransferAuthority,
autoApproveNewAccounts: false,
auditorElgamalPubkey: none(),
}),
]);

// Then we expect the mint account to have the following updated data.
const mintAccount = await fetchMint(client.rpc, mint.address);
const mintAccount = await fetchMint(client.rpc, mint);
t.like(mintAccount, <Account<Mint>>{
address: mint.address,
address: mint,
data: {
mintAuthority: some(authority.address),
extensions: some([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '../../../src';
import {
createDefaultSolanaClient,
createMint,
createToken,
generateKeyPairSignerWithSol,
getCreateMintInstructions,
Expand Down Expand Up @@ -64,38 +65,26 @@ test('it initializes a mint account with a default account state extension', asy
test('it initializes a token account with the default state defined on the mint account', async (t) => {
// Given some signer accounts.
const client = createDefaultSolanaClient();
const [authority, freezeAuthority, mint] = await Promise.all([
const [authority, freezeAuthority] = await Promise.all([
generateKeyPairSignerWithSol(client),
generateKeyPairSigner(),
generateKeyPairSigner(),
]);

// And a mint account initialized with a default account state extension.
const defaultAccountStateExtension = extension('DefaultAccountState', {
state: AccountState.Frozen,
const mint = await createMint({
authority: authority.address,
client,
extensions: [
extension('DefaultAccountState', { state: AccountState.Frozen }),
],
freezeAuthority: freezeAuthority.address,
payer: authority,
});
const [createMintInstruction, initMintInstruction] =
await getCreateMintInstructions({
authority: authority.address,
client,
extensions: [defaultAccountStateExtension],
freezeAuthority: freezeAuthority.address,
mint,
payer: authority,
});
await sendAndConfirmInstructions(client, authority, [
createMintInstruction,
getInitializeDefaultAccountStateInstruction({
mint: mint.address,
state: defaultAccountStateExtension.state,
}),
initMintInstruction,
]);

// When we create a new token account for the mint.
const token = await createToken({
client,
mint: mint.address,
mint,
owner: address('HHS1XymmkBpYAkg3XTbZLxgHa5n11PAWUCWdiVtRmzzS'),
payer: authority,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,60 +5,47 @@ import {
Mint,
extension,
fetchMint,
getInitializeDefaultAccountStateInstruction,
getUpdateDefaultAccountStateInstruction,
} from '../../../src';
import {
createDefaultSolanaClient,
createMint,
generateKeyPairSignerWithSol,
getCreateMintInstructions,
sendAndConfirmInstructions,
} from '../../_setup';

test('it updates the default state account on a mint account', async (t) => {
// Given some signer accounts.
const client = createDefaultSolanaClient();
const [authority, freezeAuthority, mint] = await Promise.all([
const [authority, freezeAuthority] = await Promise.all([
generateKeyPairSignerWithSol(client),
generateKeyPairSigner(),
generateKeyPairSigner(),
]);

// And a mint account initialized with a default account state extension.
const defaultAccountStateExtension = extension('DefaultAccountState', {
state: AccountState.Frozen,
const mint = await createMint({
authority: authority.address,
client,
extensions: [
extension('DefaultAccountState', { state: AccountState.Frozen }),
],
freezeAuthority: freezeAuthority.address,
payer: authority,
});
const [createMintInstruction, initMintInstruction] =
await getCreateMintInstructions({
authority: authority.address,
client,
extensions: [defaultAccountStateExtension],
freezeAuthority: freezeAuthority.address,
mint,
payer: authority,
});
await sendAndConfirmInstructions(client, authority, [
createMintInstruction,
getInitializeDefaultAccountStateInstruction({
mint: mint.address,
state: defaultAccountStateExtension.state,
}),
initMintInstruction,
]);

// When we update the default account state on the mint account.
await sendAndConfirmInstructions(client, authority, [
getUpdateDefaultAccountStateInstruction({
mint: mint.address,
mint,
freezeAuthority,
state: AccountState.Initialized,
}),
]);

// Then we expect the mint account to have the following updated data.
const mintAccount = await fetchMint(client.rpc, mint.address);
const mintAccount = await fetchMint(client.rpc, mint);
t.like(mintAccount, <Account<Mint>>{
address: mint.address,
address: mint,
data: {
extensions: some([
extension('DefaultAccountState', { state: AccountState.Initialized }),
Expand Down
Loading

0 comments on commit f733892

Please sign in to comment.