-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Define IDL instructions for token group extension (#28)
* Add initializeTokenGroup instruction * Add test * Fetch Token22 program from mainnet This is because the Token22 program baked in the `solana-test-validator` is not up-to-date enough to support the token group interface. * Fix token group extension layout For some reason, the example account was using u32 numbers for size and maxSize whereas the token group interface clearly uses u64 numbers. * Add updateTokenGroupMaxSize * Add failing test * Add updateTokenGroupUpdateAuthority * Add initializeTokenGroupMember * Add token group post instruction to helpers * Add tests for updateTokenGroupUpdateAuthority * Add failing test * Fix token member extension test
- Loading branch information
1 parent
b1f2c8a
commit 271880c
Showing
19 changed files
with
1,727 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
243 changes: 243 additions & 0 deletions
243
clients/js/src/generated/instructions/initializeTokenGroup.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,243 @@ | ||
/** | ||
* 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, | ||
getAddressDecoder, | ||
getAddressEncoder, | ||
getBytesDecoder, | ||
getBytesEncoder, | ||
getOptionDecoder, | ||
getOptionEncoder, | ||
getStructDecoder, | ||
getStructEncoder, | ||
getU64Decoder, | ||
getU64Encoder, | ||
transformEncoder, | ||
type Address, | ||
type Codec, | ||
type Decoder, | ||
type Encoder, | ||
type IAccountMeta, | ||
type IAccountSignerMeta, | ||
type IInstruction, | ||
type IInstructionWithAccounts, | ||
type IInstructionWithData, | ||
type Option, | ||
type OptionOrNullable, | ||
type ReadonlyAccount, | ||
type ReadonlySignerAccount, | ||
type ReadonlyUint8Array, | ||
type TransactionSigner, | ||
type WritableAccount, | ||
} from '@solana/web3.js'; | ||
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; | ||
import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; | ||
|
||
export const INITIALIZE_TOKEN_GROUP_DISCRIMINATOR = new Uint8Array([ | ||
121, 113, 108, 39, 54, 51, 0, 4, | ||
]); | ||
|
||
export function getInitializeTokenGroupDiscriminatorBytes() { | ||
return getBytesEncoder().encode(INITIALIZE_TOKEN_GROUP_DISCRIMINATOR); | ||
} | ||
|
||
export type InitializeTokenGroupInstruction< | ||
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, | ||
TAccountGroup extends string | IAccountMeta<string> = string, | ||
TAccountMint extends string | IAccountMeta<string> = string, | ||
TAccountMintAuthority extends string | IAccountMeta<string> = string, | ||
TRemainingAccounts extends readonly IAccountMeta<string>[] = [], | ||
> = IInstruction<TProgram> & | ||
IInstructionWithData<Uint8Array> & | ||
IInstructionWithAccounts< | ||
[ | ||
TAccountGroup extends string | ||
? WritableAccount<TAccountGroup> | ||
: TAccountGroup, | ||
TAccountMint extends string | ||
? ReadonlyAccount<TAccountMint> | ||
: TAccountMint, | ||
TAccountMintAuthority extends string | ||
? ReadonlySignerAccount<TAccountMintAuthority> & | ||
IAccountSignerMeta<TAccountMintAuthority> | ||
: TAccountMintAuthority, | ||
...TRemainingAccounts, | ||
] | ||
>; | ||
|
||
export type InitializeTokenGroupInstructionData = { | ||
discriminator: ReadonlyUint8Array; | ||
/** Update authority for the group */ | ||
updateAuthority: Option<Address>; | ||
/** The maximum number of group members */ | ||
maxSize: bigint; | ||
}; | ||
|
||
export type InitializeTokenGroupInstructionDataArgs = { | ||
/** Update authority for the group */ | ||
updateAuthority: OptionOrNullable<Address>; | ||
/** The maximum number of group members */ | ||
maxSize: number | bigint; | ||
}; | ||
|
||
export function getInitializeTokenGroupInstructionDataEncoder(): Encoder<InitializeTokenGroupInstructionDataArgs> { | ||
return transformEncoder( | ||
getStructEncoder([ | ||
['discriminator', getBytesEncoder()], | ||
[ | ||
'updateAuthority', | ||
getOptionEncoder(getAddressEncoder(), { | ||
prefix: null, | ||
noneValue: 'zeroes', | ||
}), | ||
], | ||
['maxSize', getU64Encoder()], | ||
]), | ||
(value) => ({ | ||
...value, | ||
discriminator: INITIALIZE_TOKEN_GROUP_DISCRIMINATOR, | ||
}) | ||
); | ||
} | ||
|
||
export function getInitializeTokenGroupInstructionDataDecoder(): Decoder<InitializeTokenGroupInstructionData> { | ||
return getStructDecoder([ | ||
['discriminator', getBytesDecoder()], | ||
[ | ||
'updateAuthority', | ||
getOptionDecoder(getAddressDecoder(), { | ||
prefix: null, | ||
noneValue: 'zeroes', | ||
}), | ||
], | ||
['maxSize', getU64Decoder()], | ||
]); | ||
} | ||
|
||
export function getInitializeTokenGroupInstructionDataCodec(): Codec< | ||
InitializeTokenGroupInstructionDataArgs, | ||
InitializeTokenGroupInstructionData | ||
> { | ||
return combineCodec( | ||
getInitializeTokenGroupInstructionDataEncoder(), | ||
getInitializeTokenGroupInstructionDataDecoder() | ||
); | ||
} | ||
|
||
export type InitializeTokenGroupInput< | ||
TAccountGroup extends string = string, | ||
TAccountMint extends string = string, | ||
TAccountMintAuthority extends string = string, | ||
> = { | ||
group: Address<TAccountGroup>; | ||
mint: Address<TAccountMint>; | ||
mintAuthority: TransactionSigner<TAccountMintAuthority>; | ||
updateAuthority: InitializeTokenGroupInstructionDataArgs['updateAuthority']; | ||
maxSize: InitializeTokenGroupInstructionDataArgs['maxSize']; | ||
}; | ||
|
||
export function getInitializeTokenGroupInstruction< | ||
TAccountGroup extends string, | ||
TAccountMint extends string, | ||
TAccountMintAuthority extends string, | ||
TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, | ||
>( | ||
input: InitializeTokenGroupInput< | ||
TAccountGroup, | ||
TAccountMint, | ||
TAccountMintAuthority | ||
>, | ||
config?: { programAddress?: TProgramAddress } | ||
): InitializeTokenGroupInstruction< | ||
TProgramAddress, | ||
TAccountGroup, | ||
TAccountMint, | ||
TAccountMintAuthority | ||
> { | ||
// Program address. | ||
const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; | ||
|
||
// Original accounts. | ||
const originalAccounts = { | ||
group: { value: input.group ?? null, isWritable: true }, | ||
mint: { value: input.mint ?? null, isWritable: false }, | ||
mintAuthority: { value: input.mintAuthority ?? null, isWritable: false }, | ||
}; | ||
const accounts = originalAccounts as Record< | ||
keyof typeof originalAccounts, | ||
ResolvedAccount | ||
>; | ||
|
||
// Original args. | ||
const args = { ...input }; | ||
|
||
const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); | ||
const instruction = { | ||
accounts: [ | ||
getAccountMeta(accounts.group), | ||
getAccountMeta(accounts.mint), | ||
getAccountMeta(accounts.mintAuthority), | ||
], | ||
programAddress, | ||
data: getInitializeTokenGroupInstructionDataEncoder().encode( | ||
args as InitializeTokenGroupInstructionDataArgs | ||
), | ||
} as InitializeTokenGroupInstruction< | ||
TProgramAddress, | ||
TAccountGroup, | ||
TAccountMint, | ||
TAccountMintAuthority | ||
>; | ||
|
||
return instruction; | ||
} | ||
|
||
export type ParsedInitializeTokenGroupInstruction< | ||
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, | ||
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[], | ||
> = { | ||
programAddress: Address<TProgram>; | ||
accounts: { | ||
group: TAccountMetas[0]; | ||
mint: TAccountMetas[1]; | ||
mintAuthority: TAccountMetas[2]; | ||
}; | ||
data: InitializeTokenGroupInstructionData; | ||
}; | ||
|
||
export function parseInitializeTokenGroupInstruction< | ||
TProgram extends string, | ||
TAccountMetas extends readonly IAccountMeta[], | ||
>( | ||
instruction: IInstruction<TProgram> & | ||
IInstructionWithAccounts<TAccountMetas> & | ||
IInstructionWithData<Uint8Array> | ||
): ParsedInitializeTokenGroupInstruction<TProgram, TAccountMetas> { | ||
if (instruction.accounts.length < 3) { | ||
// 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: { | ||
group: getNextAccount(), | ||
mint: getNextAccount(), | ||
mintAuthority: getNextAccount(), | ||
}, | ||
data: getInitializeTokenGroupInstructionDataDecoder().decode( | ||
instruction.data | ||
), | ||
}; | ||
} |
Oops, something went wrong.