Skip to content

Commit b038b5e

Browse files
authored
[JS] Add Scaled UI Amount Extension Support (#267)
* add idl and generate js client * update scaled ui discriminator number * merge broken version to get feedback * fix type order in idl and add tests * prettier * regenerate client and update tests per comments * update interest bearing mint test comments to adhere to the same convention * lint and format
1 parent 602b1ed commit b038b5e

File tree

13 files changed

+993
-14
lines changed

13 files changed

+993
-14
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ The following clients are available for your programs. You may use the following
6565
## Starting and stopping the local validator
6666

6767
The following script is available to start your local validator.
68+
In order to run the local validator you must also have the spl-elgamal-registry program built.
6869

6970
```sh
71+
pnpm confidential-transfer:elgamal-registry:build # you only need to run this once
7072
pnpm validator:start
7173
```
7274

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export * from './initializeMultisig';
5656
export * from './initializeMultisig2';
5757
export * from './initializeNonTransferableMint';
5858
export * from './initializePermanentDelegate';
59+
export * from './initializeScaledUiAmountMint';
5960
export * from './initializeTokenGroup';
6061
export * from './initializeTokenGroupMember';
6162
export * from './initializeTokenMetadata';
@@ -80,6 +81,7 @@ export * from './updateDefaultAccountState';
8081
export * from './updateGroupMemberPointer';
8182
export * from './updateGroupPointer';
8283
export * from './updateMetadataPointer';
84+
export * from './updateMultiplierScaledUiMint';
8385
export * from './updateRateInterestBearingMint';
8486
export * from './updateTokenGroupMaxSize';
8587
export * from './updateTokenGroupUpdateAuthority';
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/**
2+
* This code was AUTOGENERATED using the codama library.
3+
* Please DO NOT EDIT THIS FILE, instead use visitors
4+
* to add features, then rerun codama to update it.
5+
*
6+
* @see https://github.com/codama-idl/codama
7+
*/
8+
9+
import {
10+
combineCodec,
11+
getAddressDecoder,
12+
getAddressEncoder,
13+
getF64Decoder,
14+
getF64Encoder,
15+
getOptionDecoder,
16+
getOptionEncoder,
17+
getStructDecoder,
18+
getStructEncoder,
19+
getU8Decoder,
20+
getU8Encoder,
21+
transformEncoder,
22+
type Address,
23+
type Codec,
24+
type Decoder,
25+
type Encoder,
26+
type IAccountMeta,
27+
type IInstruction,
28+
type IInstructionWithAccounts,
29+
type IInstructionWithData,
30+
type Option,
31+
type OptionOrNullable,
32+
type WritableAccount,
33+
} from '@solana/kit';
34+
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs';
35+
import { getAccountMetaFactory, type ResolvedAccount } from '../shared';
36+
37+
export const INITIALIZE_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR = 43;
38+
39+
export function getInitializeScaledUiAmountMintDiscriminatorBytes() {
40+
return getU8Encoder().encode(INITIALIZE_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR);
41+
}
42+
43+
export const INITIALIZE_SCALED_UI_AMOUNT_MINT_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR = 0;
44+
45+
export function getInitializeScaledUiAmountMintScaledUiAmountMintDiscriminatorBytes() {
46+
return getU8Encoder().encode(
47+
INITIALIZE_SCALED_UI_AMOUNT_MINT_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR
48+
);
49+
}
50+
51+
export type InitializeScaledUiAmountMintInstruction<
52+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
53+
TAccountMint extends string | IAccountMeta<string> = string,
54+
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
55+
> = IInstruction<TProgram> &
56+
IInstructionWithData<Uint8Array> &
57+
IInstructionWithAccounts<
58+
[
59+
TAccountMint extends string
60+
? WritableAccount<TAccountMint>
61+
: TAccountMint,
62+
...TRemainingAccounts,
63+
]
64+
>;
65+
66+
export type InitializeScaledUiAmountMintInstructionData = {
67+
discriminator: number;
68+
scaledUiAmountMintDiscriminator: number;
69+
/** The authority that can update the multiplier */
70+
authority: Option<Address>;
71+
/** The initial multiplier for the scaled UI extension */
72+
multiplier: number;
73+
};
74+
75+
export type InitializeScaledUiAmountMintInstructionDataArgs = {
76+
/** The authority that can update the multiplier */
77+
authority: OptionOrNullable<Address>;
78+
/** The initial multiplier for the scaled UI extension */
79+
multiplier: number;
80+
};
81+
82+
export function getInitializeScaledUiAmountMintInstructionDataEncoder(): Encoder<InitializeScaledUiAmountMintInstructionDataArgs> {
83+
return transformEncoder(
84+
getStructEncoder([
85+
['discriminator', getU8Encoder()],
86+
['scaledUiAmountMintDiscriminator', getU8Encoder()],
87+
[
88+
'authority',
89+
getOptionEncoder(getAddressEncoder(), {
90+
prefix: null,
91+
noneValue: 'zeroes',
92+
}),
93+
],
94+
['multiplier', getF64Encoder()],
95+
]),
96+
(value) => ({
97+
...value,
98+
discriminator: INITIALIZE_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR,
99+
scaledUiAmountMintDiscriminator:
100+
INITIALIZE_SCALED_UI_AMOUNT_MINT_SCALED_UI_AMOUNT_MINT_DISCRIMINATOR,
101+
})
102+
);
103+
}
104+
105+
export function getInitializeScaledUiAmountMintInstructionDataDecoder(): Decoder<InitializeScaledUiAmountMintInstructionData> {
106+
return getStructDecoder([
107+
['discriminator', getU8Decoder()],
108+
['scaledUiAmountMintDiscriminator', getU8Decoder()],
109+
[
110+
'authority',
111+
getOptionDecoder(getAddressDecoder(), {
112+
prefix: null,
113+
noneValue: 'zeroes',
114+
}),
115+
],
116+
['multiplier', getF64Decoder()],
117+
]);
118+
}
119+
120+
export function getInitializeScaledUiAmountMintInstructionDataCodec(): Codec<
121+
InitializeScaledUiAmountMintInstructionDataArgs,
122+
InitializeScaledUiAmountMintInstructionData
123+
> {
124+
return combineCodec(
125+
getInitializeScaledUiAmountMintInstructionDataEncoder(),
126+
getInitializeScaledUiAmountMintInstructionDataDecoder()
127+
);
128+
}
129+
130+
export type InitializeScaledUiAmountMintInput<
131+
TAccountMint extends string = string,
132+
> = {
133+
/** The mint to initialize. */
134+
mint: Address<TAccountMint>;
135+
authority: InitializeScaledUiAmountMintInstructionDataArgs['authority'];
136+
multiplier: InitializeScaledUiAmountMintInstructionDataArgs['multiplier'];
137+
};
138+
139+
export function getInitializeScaledUiAmountMintInstruction<
140+
TAccountMint extends string,
141+
TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS,
142+
>(
143+
input: InitializeScaledUiAmountMintInput<TAccountMint>,
144+
config?: { programAddress?: TProgramAddress }
145+
): InitializeScaledUiAmountMintInstruction<TProgramAddress, TAccountMint> {
146+
// Program address.
147+
const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS;
148+
149+
// Original accounts.
150+
const originalAccounts = {
151+
mint: { value: input.mint ?? null, isWritable: true },
152+
};
153+
const accounts = originalAccounts as Record<
154+
keyof typeof originalAccounts,
155+
ResolvedAccount
156+
>;
157+
158+
// Original args.
159+
const args = { ...input };
160+
161+
const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
162+
const instruction = {
163+
accounts: [getAccountMeta(accounts.mint)],
164+
programAddress,
165+
data: getInitializeScaledUiAmountMintInstructionDataEncoder().encode(
166+
args as InitializeScaledUiAmountMintInstructionDataArgs
167+
),
168+
} as InitializeScaledUiAmountMintInstruction<TProgramAddress, TAccountMint>;
169+
170+
return instruction;
171+
}
172+
173+
export type ParsedInitializeScaledUiAmountMintInstruction<
174+
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
175+
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
176+
> = {
177+
programAddress: Address<TProgram>;
178+
accounts: {
179+
/** The mint to initialize. */
180+
mint: TAccountMetas[0];
181+
};
182+
data: InitializeScaledUiAmountMintInstructionData;
183+
};
184+
185+
export function parseInitializeScaledUiAmountMintInstruction<
186+
TProgram extends string,
187+
TAccountMetas extends readonly IAccountMeta[],
188+
>(
189+
instruction: IInstruction<TProgram> &
190+
IInstructionWithAccounts<TAccountMetas> &
191+
IInstructionWithData<Uint8Array>
192+
): ParsedInitializeScaledUiAmountMintInstruction<TProgram, TAccountMetas> {
193+
if (instruction.accounts.length < 1) {
194+
// TODO: Coded error.
195+
throw new Error('Not enough accounts');
196+
}
197+
let accountIndex = 0;
198+
const getNextAccount = () => {
199+
const accountMeta = instruction.accounts![accountIndex]!;
200+
accountIndex += 1;
201+
return accountMeta;
202+
};
203+
return {
204+
programAddress: instruction.programAddress,
205+
accounts: {
206+
mint: getNextAccount(),
207+
},
208+
data: getInitializeScaledUiAmountMintInstructionDataDecoder().decode(
209+
instruction.data
210+
),
211+
};
212+
}

0 commit comments

Comments
 (0)