Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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