Skip to content

Commit

Permalink
Merged main
Browse files Browse the repository at this point in the history
  • Loading branch information
0xCipherCoder committed Nov 13, 2024
2 parents ffbb870 + 45ca918 commit 4384269
Show file tree
Hide file tree
Showing 6 changed files with 263 additions and 0 deletions.
1 change: 1 addition & 0 deletions clients/js/src/generated/instructions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export * from './initializeMint2';
export * from './initializeMintCloseAuthority';
export * from './initializeMultisig';
export * from './initializeMultisig2';
export * from './initializeNonTransferableMint';
export * from './initializeTokenGroup';
export * from './initializeTokenGroupMember';
export * from './initializeTokenMetadata';
Expand Down
155 changes: 155 additions & 0 deletions clients/js/src/generated/instructions/initializeNonTransferableMint.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/**
* This code was AUTOGENERATED using the codama library.
* Please DO NOT EDIT THIS FILE, instead use visitors
* to add features, then rerun codama to update it.
*
* @see https://github.com/codama-idl/codama
*/

import {
combineCodec,
getStructDecoder,
getStructEncoder,
getU8Decoder,
getU8Encoder,
transformEncoder,
type Address,
type Codec,
type Decoder,
type Encoder,
type IAccountMeta,
type IInstruction,
type IInstructionWithAccounts,
type IInstructionWithData,
type WritableAccount,
} from '@solana/web3.js';
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs';
import { getAccountMetaFactory, type ResolvedAccount } from '../shared';

export const INITIALIZE_NON_TRANSFERABLE_MINT_DISCRIMINATOR = 32;

export function getInitializeNonTransferableMintDiscriminatorBytes() {
return getU8Encoder().encode(INITIALIZE_NON_TRANSFERABLE_MINT_DISCRIMINATOR);
}

export type InitializeNonTransferableMintInstruction<
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountMint extends string | IAccountMeta<string> = string,
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
> = IInstruction<TProgram> &
IInstructionWithData<Uint8Array> &
IInstructionWithAccounts<
[
TAccountMint extends string
? WritableAccount<TAccountMint>
: TAccountMint,
...TRemainingAccounts,
]
>;

export type InitializeNonTransferableMintInstructionData = {
discriminator: number;
};

export type InitializeNonTransferableMintInstructionDataArgs = {};

export function getInitializeNonTransferableMintInstructionDataEncoder(): Encoder<InitializeNonTransferableMintInstructionDataArgs> {
return transformEncoder(
getStructEncoder([['discriminator', getU8Encoder()]]),
(value) => ({
...value,
discriminator: INITIALIZE_NON_TRANSFERABLE_MINT_DISCRIMINATOR,
})
);
}

export function getInitializeNonTransferableMintInstructionDataDecoder(): Decoder<InitializeNonTransferableMintInstructionData> {
return getStructDecoder([['discriminator', getU8Decoder()]]);
}

export function getInitializeNonTransferableMintInstructionDataCodec(): Codec<
InitializeNonTransferableMintInstructionDataArgs,
InitializeNonTransferableMintInstructionData
> {
return combineCodec(
getInitializeNonTransferableMintInstructionDataEncoder(),
getInitializeNonTransferableMintInstructionDataDecoder()
);
}

export type InitializeNonTransferableMintInput<
TAccountMint extends string = string,
> = {
/** The mint account to initialize. */
mint: Address<TAccountMint>;
};

export function getInitializeNonTransferableMintInstruction<
TAccountMint extends string,
TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS,
>(
input: InitializeNonTransferableMintInput<TAccountMint>,
config?: { programAddress?: TProgramAddress }
): InitializeNonTransferableMintInstruction<TProgramAddress, TAccountMint> {
// Program address.
const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS;

// Original accounts.
const originalAccounts = {
mint: { value: input.mint ?? null, isWritable: true },
};
const accounts = originalAccounts as Record<
keyof typeof originalAccounts,
ResolvedAccount
>;

const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
const instruction = {
accounts: [getAccountMeta(accounts.mint)],
programAddress,
data: getInitializeNonTransferableMintInstructionDataEncoder().encode({}),
} as InitializeNonTransferableMintInstruction<TProgramAddress, TAccountMint>;

return instruction;
}

export type ParsedInitializeNonTransferableMintInstruction<
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
> = {
programAddress: Address<TProgram>;
accounts: {
/** The mint account to initialize. */
mint: TAccountMetas[0];
};
data: InitializeNonTransferableMintInstructionData;
};

export function parseInitializeNonTransferableMintInstruction<
TProgram extends string,
TAccountMetas extends readonly IAccountMeta[],
>(
instruction: IInstruction<TProgram> &
IInstructionWithAccounts<TAccountMetas> &
IInstructionWithData<Uint8Array>
): ParsedInitializeNonTransferableMintInstruction<TProgram, TAccountMetas> {
if (instruction.accounts.length < 1) {
// TODO: Coded error.
throw new Error('Not enough accounts');
}
let accountIndex = 0;
const getNextAccount = () => {
const accountMeta = instruction.accounts![accountIndex]!;
accountIndex += 1;
return accountMeta;
};
return {
programAddress: instruction.programAddress,
accounts: {
mint: getNextAccount(),
},
data: getInitializeNonTransferableMintInstructionDataDecoder().decode(
instruction.data
),
};
}
8 changes: 8 additions & 0 deletions clients/js/src/generated/programs/token2022.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import {
type ParsedInitializeMintInstruction,
type ParsedInitializeMultisig2Instruction,
type ParsedInitializeMultisigInstruction,
type ParsedInitializeNonTransferableMintInstruction,
type ParsedInitializeTokenGroupInstruction,
type ParsedInitializeTokenGroupMemberInstruction,
type ParsedInitializeTokenMetadataInstruction,
Expand Down Expand Up @@ -164,6 +165,7 @@ export enum Token2022Instruction {
Reallocate,
EnableMemoTransfers,
DisableMemoTransfers,
InitializeNonTransferableMint,
EnableCpiGuard,
DisableCpiGuard,
InitializeTransferHook,
Expand Down Expand Up @@ -414,6 +416,9 @@ export function identifyToken2022Instruction(
) {
return Token2022Instruction.DisableMemoTransfers;
}
if (containsBytes(data, getU8Encoder().encode(32), 0)) {
return Token2022Instruction.InitializeNonTransferableMint;
}
if (
containsBytes(data, getU8Encoder().encode(34), 0) &&
containsBytes(data, getU8Encoder().encode(0), 1)
Expand Down Expand Up @@ -708,6 +713,9 @@ export type ParsedToken2022Instruction<
| ({
instructionType: Token2022Instruction.DisableMemoTransfers;
} & ParsedDisableMemoTransfersInstruction<TProgram>)
| ({
instructionType: Token2022Instruction.InitializeNonTransferableMint;
} & ParsedInitializeNonTransferableMintInstruction<TProgram>)
| ({
instructionType: Token2022Instruction.EnableCpiGuard;
} & ParsedEnableCpiGuardInstruction<TProgram>)
Expand Down
3 changes: 3 additions & 0 deletions clients/js/src/getInitializeInstructionsForExtensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
getInitializeTokenGroupInstruction,
getInitializeTokenMetadataInstruction,
getInitializeTransferFeeConfigInstruction,
getInitializeNonTransferableMintInstruction,
getInitializeTransferHookInstruction,
} from './generated';

Expand Down Expand Up @@ -83,6 +84,8 @@ export function getPreInitializeInstructionsForMintExtensions(
memberAddress: extension.memberAddress,
}),
];
case 'NonTransferable':
return getInitializeNonTransferableMintInstruction({ mint });
case 'TransferHook':
return [
getInitializeTransferHookInstruction({
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Account, generateKeyPairSigner, some } from '@solana/web3.js';
import test from 'ava';
import {
Mint,
extension,
fetchMint,
getInitializeNonTransferableMintInstruction,
} from '../../../src';
import {
createDefaultSolanaClient,
generateKeyPairSignerWithSol,
getCreateMintInstructions,
sendAndConfirmInstructions,
} from '../../_setup';

test('it initializes a non-transferable mint', async (t) => {
// Given an authority and a mint account.
const client = createDefaultSolanaClient();
const [authority, mint] = await Promise.all([
generateKeyPairSignerWithSol(client),
generateKeyPairSigner(),
]);

// When we create and initialize a mint account as non-transferable
const [createMintInstruction, initMintInstruction] =
await getCreateMintInstructions({
authority: authority.address,
client,
extensions: [extension('NonTransferable', {})],
mint,
payer: authority,
});

await sendAndConfirmInstructions(client, authority, [
createMintInstruction,
getInitializeNonTransferableMintInstruction({
mint: mint.address,
}),
initMintInstruction,
]);

// Then we expect the mint to be initialized with the non-transferable extension
const mintAccount = await fetchMint(client.rpc, mint.address);
t.like(mintAccount, <Account<Mint>>{
address: mint.address,
data: {
mintAuthority: some(authority.address),
isInitialized: true,
extensions: some([extension('NonTransferable', {})]),
},
});
});
44 changes: 44 additions & 0 deletions program/idl.json
Original file line number Diff line number Diff line change
Expand Up @@ -5345,6 +5345,50 @@
}
]
},
{
"kind": "instructionNode",
"name": "initializeNonTransferableMint",
"docs": [
"Initialize the non transferable extension for the given mint account",
"",
"Fails if the account has already been initialized, so must be called before `InitializeMint`."
],
"optionalAccountStrategy": "programId",
"accounts": [
{
"kind": "instructionAccountNode",
"name": "mint",
"isWritable": true,
"isSigner": false,
"isOptional": false,
"docs": ["The mint account to initialize."]
}
],
"arguments": [
{
"kind": "instructionArgumentNode",
"name": "discriminator",
"defaultValueStrategy": "omitted",
"docs": [],
"type": {
"kind": "numberTypeNode",
"format": "u8",
"endian": "le"
},
"defaultValue": {
"kind": "numberValueNode",
"number": 32
}
}
],
"discriminators": [
{
"kind": "fieldDiscriminatorNode",
"name": "discriminator",
"offset": 0
}
]
},
{
"kind": "instructionNode",
"name": "enableCpiGuard",
Expand Down

0 comments on commit 4384269

Please sign in to comment.