Skip to content

Commit 84c670b

Browse files
authored
Define reallocate IDL instruction (#11)
* Add instruction * Add extensionType * Add test * Update test * Fix test
1 parent f733892 commit 84c670b

File tree

7 files changed

+687
-1
lines changed

7 files changed

+687
-1
lines changed

clients/js/src/generated/instructions/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export * from './initializeMultisig2';
4343
export * from './initializeTransferFeeConfig';
4444
export * from './mintTo';
4545
export * from './mintToChecked';
46+
export * from './reallocate';
4647
export * from './recoverNestedAssociatedToken';
4748
export * from './revoke';
4849
export * from './setAuthority';
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
/**
2+
* This code was AUTOGENERATED using the kinobi library.
3+
* Please DO NOT EDIT THIS FILE, instead use visitors
4+
* to add features, then rerun kinobi to update it.
5+
*
6+
* @see https://github.com/kinobi-so/kinobi
7+
*/
8+
9+
import {
10+
AccountRole,
11+
combineCodec,
12+
getArrayDecoder,
13+
getArrayEncoder,
14+
getStructDecoder,
15+
getStructEncoder,
16+
getU8Decoder,
17+
getU8Encoder,
18+
transformEncoder,
19+
type Address,
20+
type Codec,
21+
type Decoder,
22+
type Encoder,
23+
type IAccountMeta,
24+
type IAccountSignerMeta,
25+
type IInstruction,
26+
type IInstructionWithAccounts,
27+
type IInstructionWithData,
28+
type ReadonlyAccount,
29+
type ReadonlySignerAccount,
30+
type TransactionSigner,
31+
type WritableAccount,
32+
type WritableSignerAccount,
33+
} from '@solana/web3.js';
34+
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs';
35+
import { getAccountMetaFactory, type ResolvedAccount } from '../shared';
36+
import {
37+
getExtensionTypeDecoder,
38+
getExtensionTypeEncoder,
39+
type ExtensionType,
40+
type ExtensionTypeArgs,
41+
} from '../types';
42+
43+
export const REALLOCATE_DISCRIMINATOR = 29;
44+
45+
export function getReallocateDiscriminatorBytes() {
46+
return getU8Encoder().encode(REALLOCATE_DISCRIMINATOR);
47+
}
48+
49+
export type ReallocateInstruction<
50+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
51+
TAccountToken extends string | IAccountMeta<string> = string,
52+
TAccountPayer extends string | IAccountMeta<string> = string,
53+
TAccountSystemProgram extends
54+
| string
55+
| IAccountMeta<string> = '11111111111111111111111111111111',
56+
TAccountOwner extends string | IAccountMeta<string> = string,
57+
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
58+
> = IInstruction<TProgram> &
59+
IInstructionWithData<Uint8Array> &
60+
IInstructionWithAccounts<
61+
[
62+
TAccountToken extends string
63+
? WritableAccount<TAccountToken>
64+
: TAccountToken,
65+
TAccountPayer extends string
66+
? WritableSignerAccount<TAccountPayer> &
67+
IAccountSignerMeta<TAccountPayer>
68+
: TAccountPayer,
69+
TAccountSystemProgram extends string
70+
? ReadonlyAccount<TAccountSystemProgram>
71+
: TAccountSystemProgram,
72+
TAccountOwner extends string
73+
? ReadonlyAccount<TAccountOwner>
74+
: TAccountOwner,
75+
...TRemainingAccounts,
76+
]
77+
>;
78+
79+
export type ReallocateInstructionData = {
80+
discriminator: number;
81+
/** New extension types to include in the reallocated account. */
82+
newExtensionTypes: Array<ExtensionType>;
83+
};
84+
85+
export type ReallocateInstructionDataArgs = {
86+
/** New extension types to include in the reallocated account. */
87+
newExtensionTypes: Array<ExtensionTypeArgs>;
88+
};
89+
90+
export function getReallocateInstructionDataEncoder(): Encoder<ReallocateInstructionDataArgs> {
91+
return transformEncoder(
92+
getStructEncoder([
93+
['discriminator', getU8Encoder()],
94+
[
95+
'newExtensionTypes',
96+
getArrayEncoder(getExtensionTypeEncoder(), { size: 'remainder' }),
97+
],
98+
]),
99+
(value) => ({ ...value, discriminator: REALLOCATE_DISCRIMINATOR })
100+
);
101+
}
102+
103+
export function getReallocateInstructionDataDecoder(): Decoder<ReallocateInstructionData> {
104+
return getStructDecoder([
105+
['discriminator', getU8Decoder()],
106+
[
107+
'newExtensionTypes',
108+
getArrayDecoder(getExtensionTypeDecoder(), { size: 'remainder' }),
109+
],
110+
]);
111+
}
112+
113+
export function getReallocateInstructionDataCodec(): Codec<
114+
ReallocateInstructionDataArgs,
115+
ReallocateInstructionData
116+
> {
117+
return combineCodec(
118+
getReallocateInstructionDataEncoder(),
119+
getReallocateInstructionDataDecoder()
120+
);
121+
}
122+
123+
export type ReallocateInput<
124+
TAccountToken extends string = string,
125+
TAccountPayer extends string = string,
126+
TAccountSystemProgram extends string = string,
127+
TAccountOwner extends string = string,
128+
> = {
129+
/** The token account to reallocate. */
130+
token: Address<TAccountToken>;
131+
/** The payer account to fund reallocation. */
132+
payer: TransactionSigner<TAccountPayer>;
133+
/** System program for reallocation funding. */
134+
systemProgram?: Address<TAccountSystemProgram>;
135+
/** The account's owner or its multisignature account. */
136+
owner: Address<TAccountOwner> | TransactionSigner<TAccountOwner>;
137+
newExtensionTypes: ReallocateInstructionDataArgs['newExtensionTypes'];
138+
multiSigners?: Array<TransactionSigner>;
139+
};
140+
141+
export function getReallocateInstruction<
142+
TAccountToken extends string,
143+
TAccountPayer extends string,
144+
TAccountSystemProgram extends string,
145+
TAccountOwner extends string,
146+
>(
147+
input: ReallocateInput<
148+
TAccountToken,
149+
TAccountPayer,
150+
TAccountSystemProgram,
151+
TAccountOwner
152+
>
153+
): ReallocateInstruction<
154+
typeof TOKEN_2022_PROGRAM_ADDRESS,
155+
TAccountToken,
156+
TAccountPayer,
157+
TAccountSystemProgram,
158+
(typeof input)['owner'] extends TransactionSigner<TAccountOwner>
159+
? ReadonlySignerAccount<TAccountOwner> & IAccountSignerMeta<TAccountOwner>
160+
: TAccountOwner
161+
> {
162+
// Program address.
163+
const programAddress = TOKEN_2022_PROGRAM_ADDRESS;
164+
165+
// Original accounts.
166+
const originalAccounts = {
167+
token: { value: input.token ?? null, isWritable: true },
168+
payer: { value: input.payer ?? null, isWritable: true },
169+
systemProgram: { value: input.systemProgram ?? null, isWritable: false },
170+
owner: { value: input.owner ?? null, isWritable: false },
171+
};
172+
const accounts = originalAccounts as Record<
173+
keyof typeof originalAccounts,
174+
ResolvedAccount
175+
>;
176+
177+
// Original args.
178+
const args = { ...input };
179+
180+
// Resolve default values.
181+
if (!accounts.systemProgram.value) {
182+
accounts.systemProgram.value =
183+
'11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
184+
}
185+
186+
// Remaining accounts.
187+
const remainingAccounts: IAccountMeta[] = (args.multiSigners ?? []).map(
188+
(signer) => ({
189+
address: signer.address,
190+
role: AccountRole.READONLY_SIGNER,
191+
signer,
192+
})
193+
);
194+
195+
const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
196+
const instruction = {
197+
accounts: [
198+
getAccountMeta(accounts.token),
199+
getAccountMeta(accounts.payer),
200+
getAccountMeta(accounts.systemProgram),
201+
getAccountMeta(accounts.owner),
202+
...remainingAccounts,
203+
],
204+
programAddress,
205+
data: getReallocateInstructionDataEncoder().encode(
206+
args as ReallocateInstructionDataArgs
207+
),
208+
} as ReallocateInstruction<
209+
typeof TOKEN_2022_PROGRAM_ADDRESS,
210+
TAccountToken,
211+
TAccountPayer,
212+
TAccountSystemProgram,
213+
(typeof input)['owner'] extends TransactionSigner<TAccountOwner>
214+
? ReadonlySignerAccount<TAccountOwner> & IAccountSignerMeta<TAccountOwner>
215+
: TAccountOwner
216+
>;
217+
218+
return instruction;
219+
}
220+
221+
export type ParsedReallocateInstruction<
222+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
223+
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
224+
> = {
225+
programAddress: Address<TProgram>;
226+
accounts: {
227+
/** The token account to reallocate. */
228+
token: TAccountMetas[0];
229+
/** The payer account to fund reallocation. */
230+
payer: TAccountMetas[1];
231+
/** System program for reallocation funding. */
232+
systemProgram: TAccountMetas[2];
233+
/** The account's owner or its multisignature account. */
234+
owner: TAccountMetas[3];
235+
};
236+
data: ReallocateInstructionData;
237+
};
238+
239+
export function parseReallocateInstruction<
240+
TProgram extends string,
241+
TAccountMetas extends readonly IAccountMeta[],
242+
>(
243+
instruction: IInstruction<TProgram> &
244+
IInstructionWithAccounts<TAccountMetas> &
245+
IInstructionWithData<Uint8Array>
246+
): ParsedReallocateInstruction<TProgram, TAccountMetas> {
247+
if (instruction.accounts.length < 4) {
248+
// TODO: Coded error.
249+
throw new Error('Not enough accounts');
250+
}
251+
let accountIndex = 0;
252+
const getNextAccount = () => {
253+
const accountMeta = instruction.accounts![accountIndex]!;
254+
accountIndex += 1;
255+
return accountMeta;
256+
};
257+
return {
258+
programAddress: instruction.programAddress,
259+
accounts: {
260+
token: getNextAccount(),
261+
payer: getNextAccount(),
262+
systemProgram: getNextAccount(),
263+
owner: getNextAccount(),
264+
},
265+
data: getReallocateInstructionDataDecoder().decode(instruction.data),
266+
};
267+
}

clients/js/src/generated/programs/token2022.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import {
4848
type ParsedInitializeTransferFeeConfigInstruction,
4949
type ParsedMintToCheckedInstruction,
5050
type ParsedMintToInstruction,
51+
type ParsedReallocateInstruction,
5152
type ParsedRevokeInstruction,
5253
type ParsedSetAuthorityInstruction,
5354
type ParsedSetTransferFeeInstruction,
@@ -139,6 +140,7 @@ export enum Token2022Instruction {
139140
ConfidentialTransferWithFee,
140141
InitializeDefaultAccountState,
141142
UpdateDefaultAccountState,
143+
Reallocate,
142144
}
143145

144146
export function identifyToken2022Instruction(
@@ -355,6 +357,9 @@ export function identifyToken2022Instruction(
355357
) {
356358
return Token2022Instruction.UpdateDefaultAccountState;
357359
}
360+
if (containsBytes(data, getU8Encoder().encode(29), 0)) {
361+
return Token2022Instruction.Reallocate;
362+
}
358363
throw new Error(
359364
'The provided instruction could not be identified as a token-2022 instruction.'
360365
);
@@ -506,4 +511,7 @@ export type ParsedToken2022Instruction<
506511
} & ParsedInitializeDefaultAccountStateInstruction<TProgram>)
507512
| ({
508513
instructionType: Token2022Instruction.UpdateDefaultAccountState;
509-
} & ParsedUpdateDefaultAccountStateInstruction<TProgram>);
514+
} & ParsedUpdateDefaultAccountStateInstruction<TProgram>)
515+
| ({
516+
instructionType: Token2022Instruction.Reallocate;
517+
} & ParsedReallocateInstruction<TProgram>);
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* This code was AUTOGENERATED using the kinobi library.
3+
* Please DO NOT EDIT THIS FILE, instead use visitors
4+
* to add features, then rerun kinobi to update it.
5+
*
6+
* @see https://github.com/kinobi-so/kinobi
7+
*/
8+
9+
import {
10+
combineCodec,
11+
getEnumDecoder,
12+
getEnumEncoder,
13+
getU16Decoder,
14+
getU16Encoder,
15+
type Codec,
16+
type Decoder,
17+
type Encoder,
18+
} from '@solana/web3.js';
19+
20+
/**
21+
* Extensions that can be applied to mints or accounts. Mint extensions must
22+
* only be applied to mint accounts, and account extensions must only be
23+
* applied to token holding accounts.
24+
*/
25+
26+
export enum ExtensionType {
27+
Uninitialized,
28+
TransferFeeConfig,
29+
TransferFeeAmount,
30+
MintCloseAuthority,
31+
ConfidentialTransferMint,
32+
ConfidentialTransferAccount,
33+
DefaultAccountState,
34+
ImmutableOwner,
35+
MemoTransfer,
36+
NonTransferable,
37+
InterestBearingConfig,
38+
CpiGuard,
39+
PermanentDelegate,
40+
NonTransferableAccount,
41+
TransferHook,
42+
TransferHookAccount,
43+
ConfidentialTransferFee,
44+
ConfidentialTransferFeeAmount,
45+
MetadataPointer,
46+
TokenMetadata,
47+
GroupPointer,
48+
TokenGroup,
49+
GroupMemberPointer,
50+
TokenGroupMember,
51+
}
52+
53+
export type ExtensionTypeArgs = ExtensionType;
54+
55+
export function getExtensionTypeEncoder(): Encoder<ExtensionTypeArgs> {
56+
return getEnumEncoder(ExtensionType, { size: getU16Encoder() });
57+
}
58+
59+
export function getExtensionTypeDecoder(): Decoder<ExtensionType> {
60+
return getEnumDecoder(ExtensionType, { size: getU16Decoder() });
61+
}
62+
63+
export function getExtensionTypeCodec(): Codec<
64+
ExtensionTypeArgs,
65+
ExtensionType
66+
> {
67+
return combineCodec(getExtensionTypeEncoder(), getExtensionTypeDecoder());
68+
}

clients/js/src/generated/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export * from './authorityType';
1111
export * from './decryptableBalance';
1212
export * from './encryptedBalance';
1313
export * from './extension';
14+
export * from './extensionType';
1415
export * from './transferFee';

0 commit comments

Comments
 (0)