Skip to content

Commit 61bc6d0

Browse files
authored
Define IDL instructions for memo transfers extension (#12)
* Add instructions * Add tests * Add tests
1 parent 84c670b commit 61bc6d0

File tree

7 files changed

+829
-1
lines changed

7 files changed

+829
-1
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
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+
getStructDecoder,
13+
getStructEncoder,
14+
getU8Decoder,
15+
getU8Encoder,
16+
transformEncoder,
17+
type Address,
18+
type Codec,
19+
type Decoder,
20+
type Encoder,
21+
type IAccountMeta,
22+
type IAccountSignerMeta,
23+
type IInstruction,
24+
type IInstructionWithAccounts,
25+
type IInstructionWithData,
26+
type ReadonlyAccount,
27+
type ReadonlySignerAccount,
28+
type TransactionSigner,
29+
type WritableAccount,
30+
} from '@solana/web3.js';
31+
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs';
32+
import { getAccountMetaFactory, type ResolvedAccount } from '../shared';
33+
34+
export const DISABLE_MEMO_TRANSFERS_DISCRIMINATOR = 30;
35+
36+
export function getDisableMemoTransfersDiscriminatorBytes() {
37+
return getU8Encoder().encode(DISABLE_MEMO_TRANSFERS_DISCRIMINATOR);
38+
}
39+
40+
export const DISABLE_MEMO_TRANSFERS_MEMO_TRANSFERS_DISCRIMINATOR = 1;
41+
42+
export function getDisableMemoTransfersMemoTransfersDiscriminatorBytes() {
43+
return getU8Encoder().encode(
44+
DISABLE_MEMO_TRANSFERS_MEMO_TRANSFERS_DISCRIMINATOR
45+
);
46+
}
47+
48+
export type DisableMemoTransfersInstruction<
49+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
50+
TAccountToken extends string | IAccountMeta<string> = string,
51+
TAccountOwner extends string | IAccountMeta<string> = string,
52+
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
53+
> = IInstruction<TProgram> &
54+
IInstructionWithData<Uint8Array> &
55+
IInstructionWithAccounts<
56+
[
57+
TAccountToken extends string
58+
? WritableAccount<TAccountToken>
59+
: TAccountToken,
60+
TAccountOwner extends string
61+
? ReadonlyAccount<TAccountOwner>
62+
: TAccountOwner,
63+
...TRemainingAccounts,
64+
]
65+
>;
66+
67+
export type DisableMemoTransfersInstructionData = {
68+
discriminator: number;
69+
memoTransfersDiscriminator: number;
70+
};
71+
72+
export type DisableMemoTransfersInstructionDataArgs = {};
73+
74+
export function getDisableMemoTransfersInstructionDataEncoder(): Encoder<DisableMemoTransfersInstructionDataArgs> {
75+
return transformEncoder(
76+
getStructEncoder([
77+
['discriminator', getU8Encoder()],
78+
['memoTransfersDiscriminator', getU8Encoder()],
79+
]),
80+
(value) => ({
81+
...value,
82+
discriminator: DISABLE_MEMO_TRANSFERS_DISCRIMINATOR,
83+
memoTransfersDiscriminator:
84+
DISABLE_MEMO_TRANSFERS_MEMO_TRANSFERS_DISCRIMINATOR,
85+
})
86+
);
87+
}
88+
89+
export function getDisableMemoTransfersInstructionDataDecoder(): Decoder<DisableMemoTransfersInstructionData> {
90+
return getStructDecoder([
91+
['discriminator', getU8Decoder()],
92+
['memoTransfersDiscriminator', getU8Decoder()],
93+
]);
94+
}
95+
96+
export function getDisableMemoTransfersInstructionDataCodec(): Codec<
97+
DisableMemoTransfersInstructionDataArgs,
98+
DisableMemoTransfersInstructionData
99+
> {
100+
return combineCodec(
101+
getDisableMemoTransfersInstructionDataEncoder(),
102+
getDisableMemoTransfersInstructionDataDecoder()
103+
);
104+
}
105+
106+
export type DisableMemoTransfersInput<
107+
TAccountToken extends string = string,
108+
TAccountOwner extends string = string,
109+
> = {
110+
/** The token account to update. */
111+
token: Address<TAccountToken>;
112+
/** The account's owner or its multisignature account. */
113+
owner: Address<TAccountOwner> | TransactionSigner<TAccountOwner>;
114+
multiSigners?: Array<TransactionSigner>;
115+
};
116+
117+
export function getDisableMemoTransfersInstruction<
118+
TAccountToken extends string,
119+
TAccountOwner extends string,
120+
>(
121+
input: DisableMemoTransfersInput<TAccountToken, TAccountOwner>
122+
): DisableMemoTransfersInstruction<
123+
typeof TOKEN_2022_PROGRAM_ADDRESS,
124+
TAccountToken,
125+
(typeof input)['owner'] extends TransactionSigner<TAccountOwner>
126+
? ReadonlySignerAccount<TAccountOwner> & IAccountSignerMeta<TAccountOwner>
127+
: TAccountOwner
128+
> {
129+
// Program address.
130+
const programAddress = TOKEN_2022_PROGRAM_ADDRESS;
131+
132+
// Original accounts.
133+
const originalAccounts = {
134+
token: { value: input.token ?? null, isWritable: true },
135+
owner: { value: input.owner ?? null, isWritable: false },
136+
};
137+
const accounts = originalAccounts as Record<
138+
keyof typeof originalAccounts,
139+
ResolvedAccount
140+
>;
141+
142+
// Original args.
143+
const args = { ...input };
144+
145+
// Remaining accounts.
146+
const remainingAccounts: IAccountMeta[] = (args.multiSigners ?? []).map(
147+
(signer) => ({
148+
address: signer.address,
149+
role: AccountRole.READONLY_SIGNER,
150+
signer,
151+
})
152+
);
153+
154+
const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
155+
const instruction = {
156+
accounts: [
157+
getAccountMeta(accounts.token),
158+
getAccountMeta(accounts.owner),
159+
...remainingAccounts,
160+
],
161+
programAddress,
162+
data: getDisableMemoTransfersInstructionDataEncoder().encode({}),
163+
} as DisableMemoTransfersInstruction<
164+
typeof TOKEN_2022_PROGRAM_ADDRESS,
165+
TAccountToken,
166+
(typeof input)['owner'] extends TransactionSigner<TAccountOwner>
167+
? ReadonlySignerAccount<TAccountOwner> & IAccountSignerMeta<TAccountOwner>
168+
: TAccountOwner
169+
>;
170+
171+
return instruction;
172+
}
173+
174+
export type ParsedDisableMemoTransfersInstruction<
175+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
176+
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
177+
> = {
178+
programAddress: Address<TProgram>;
179+
accounts: {
180+
/** The token account to update. */
181+
token: TAccountMetas[0];
182+
/** The account's owner or its multisignature account. */
183+
owner: TAccountMetas[1];
184+
};
185+
data: DisableMemoTransfersInstructionData;
186+
};
187+
188+
export function parseDisableMemoTransfersInstruction<
189+
TProgram extends string,
190+
TAccountMetas extends readonly IAccountMeta[],
191+
>(
192+
instruction: IInstruction<TProgram> &
193+
IInstructionWithAccounts<TAccountMetas> &
194+
IInstructionWithData<Uint8Array>
195+
): ParsedDisableMemoTransfersInstruction<TProgram, TAccountMetas> {
196+
if (instruction.accounts.length < 2) {
197+
// TODO: Coded error.
198+
throw new Error('Not enough accounts');
199+
}
200+
let accountIndex = 0;
201+
const getNextAccount = () => {
202+
const accountMeta = instruction.accounts![accountIndex]!;
203+
accountIndex += 1;
204+
return accountMeta;
205+
};
206+
return {
207+
programAddress: instruction.programAddress,
208+
accounts: {
209+
token: getNextAccount(),
210+
owner: getNextAccount(),
211+
},
212+
data: getDisableMemoTransfersInstructionDataDecoder().decode(
213+
instruction.data
214+
),
215+
};
216+
}

0 commit comments

Comments
 (0)