From 8dfde7703188a57f2970e80d025af1a01b25ca88 Mon Sep 17 00:00:00 2001 From: catmcgee Date: Tue, 26 May 2026 15:22:00 -0300 Subject: [PATCH] interface: split ConfigureAccount and ConfigureAccountWithRegistry --- .../configureConfidentialTransferAccount.ts | 22 +- ...ConfidentialTransferAccountWithRegistry.ts | 258 ++++++++++++++++++ .../js/src/generated/instructions/index.ts | 1 + .../js/src/generated/programs/token2022.ts | 16 ++ ...nfigureConfidentialTransferAccount.test.ts | 29 ++ ...dentialTransferAccountWithRegistry.test.ts | 87 ++++++ interface/idl.json | 116 +++++++- 7 files changed, 499 insertions(+), 30 deletions(-) create mode 100644 clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts create mode 100644 clients/js/test/extensions/confidentialTransfer/configureConfidentialTransferAccount.test.ts create mode 100644 clients/js/test/extensions/confidentialTransfer/configureConfidentialTransferAccountWithRegistry.test.ts diff --git a/clients/js/src/generated/instructions/configureConfidentialTransferAccount.ts b/clients/js/src/generated/instructions/configureConfidentialTransferAccount.ts index b41ecc09f..a6da7bfa0 100644 --- a/clients/js/src/generated/instructions/configureConfidentialTransferAccount.ts +++ b/clients/js/src/generated/instructions/configureConfidentialTransferAccount.ts @@ -60,7 +60,6 @@ export type ConfigureConfidentialTransferAccountInstruction< TAccountMint extends string | AccountMeta = string, TAccountInstructionsSysvarOrContextState extends string | AccountMeta = 'Sysvar1nstructions1111111111111111111111111', - TAccountRecord extends string | AccountMeta = string, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -72,7 +71,6 @@ export type ConfigureConfidentialTransferAccountInstruction< TAccountInstructionsSysvarOrContextState extends string ? ReadonlyAccount : TAccountInstructionsSysvarOrContextState, - TAccountRecord extends string ? ReadonlyAccount : TAccountRecord, TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -156,7 +154,6 @@ export type ConfigureConfidentialTransferAccountInput< TAccountToken extends string = string, TAccountMint extends string = string, TAccountInstructionsSysvarOrContextState extends string = string, - TAccountRecord extends string = string, TAccountAuthority extends string = string, > = { /** The SPL Token account. */ @@ -170,8 +167,6 @@ export type ConfigureConfidentialTransferAccountInput< * account. */ instructionsSysvarOrContextState?: Address; - /** (Optional) Record account if the accompanying proof is to be read from a record account. */ - record?: Address; /** The source account's owner/delegate or its multisignature account. */ authority: Address | TransactionSigner; decryptableZeroBalance: ConfigureConfidentialTransferAccountInstructionDataArgs['decryptableZeroBalance']; @@ -184,7 +179,6 @@ export function getConfigureConfidentialTransferAccountInstruction< TAccountToken extends string, TAccountMint extends string, TAccountInstructionsSysvarOrContextState extends string, - TAccountRecord extends string, TAccountAuthority extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( @@ -192,7 +186,6 @@ export function getConfigureConfidentialTransferAccountInstruction< TAccountToken, TAccountMint, TAccountInstructionsSysvarOrContextState, - TAccountRecord, TAccountAuthority >, config?: { programAddress?: TProgramAddress }, @@ -201,7 +194,6 @@ export function getConfigureConfidentialTransferAccountInstruction< TAccountToken, TAccountMint, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -214,7 +206,6 @@ export function getConfigureConfidentialTransferAccountInstruction< token: { value: input.token ?? null, isWritable: true }, mint: { value: input.mint ?? null, isWritable: false }, instructionsSysvarOrContextState: { value: input.instructionsSysvarOrContextState ?? null, isWritable: false }, - record: { value: input.record ?? null, isWritable: false }, authority: { value: input.authority ?? null, isWritable: false }, }; const accounts = originalAccounts as Record; @@ -241,7 +232,6 @@ export function getConfigureConfidentialTransferAccountInstruction< getAccountMeta(accounts.token), getAccountMeta(accounts.mint), getAccountMeta(accounts.instructionsSysvarOrContextState), - getAccountMeta(accounts.record), getAccountMeta(accounts.authority), ...remainingAccounts, ], @@ -254,7 +244,6 @@ export function getConfigureConfidentialTransferAccountInstruction< TAccountToken, TAccountMint, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -278,10 +267,8 @@ export type ParsedConfigureConfidentialTransferAccountInstruction< * account. */ instructionsSysvarOrContextState: TAccountMetas[2]; - /** (Optional) Record account if the accompanying proof is to be read from a record account. */ - record?: TAccountMetas[3] | undefined; /** The source account's owner/delegate or its multisignature account. */ - authority: TAccountMetas[4]; + authority: TAccountMetas[3]; }; data: ConfigureConfidentialTransferAccountInstructionData; }; @@ -294,7 +281,7 @@ export function parseConfigureConfidentialTransferAccountInstruction< InstructionWithAccounts & InstructionWithData, ): ParsedConfigureConfidentialTransferAccountInstruction { - if (instruction.accounts.length < 5) { + if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -304,17 +291,12 @@ export function parseConfigureConfidentialTransferAccountInstruction< accountIndex += 1; return accountMeta; }; - const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; - }; return { programAddress: instruction.programAddress, accounts: { token: getNextAccount(), mint: getNextAccount(), instructionsSysvarOrContextState: getNextAccount(), - record: getNextOptionalAccount(), authority: getNextAccount(), }, data: getConfigureConfidentialTransferAccountInstructionDataDecoder().decode(instruction.data), diff --git a/clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts b/clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts new file mode 100644 index 000000000..b2f34ee9b --- /dev/null +++ b/clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts @@ -0,0 +1,258 @@ +/** + * 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 AccountMeta, + type AccountSignerMeta, + type Address, + type FixedSizeCodec, + type FixedSizeDecoder, + type FixedSizeEncoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, + type WritableSignerAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; + +export const CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_DISCRIMINATOR = 27; + +export function getConfigureConfidentialTransferAccountWithRegistryDiscriminatorBytes() { + return getU8Encoder().encode(CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_DISCRIMINATOR); +} + +export const CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_CONFIDENTIAL_TRANSFER_DISCRIMINATOR = 14; + +export function getConfigureConfidentialTransferAccountWithRegistryConfidentialTransferDiscriminatorBytes() { + return getU8Encoder().encode( + CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_CONFIDENTIAL_TRANSFER_DISCRIMINATOR, + ); +} + +export type ConfigureConfidentialTransferAccountWithRegistryInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountToken extends string | AccountMeta = string, + TAccountMint extends string | AccountMeta = string, + TAccountElgamalRegistry extends string | AccountMeta = string, + TAccountPayer extends string | AccountMeta | undefined = undefined, + TAccountSystemProgram extends string | AccountMeta | undefined = undefined, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountToken extends string ? WritableAccount : TAccountToken, + TAccountMint extends string ? ReadonlyAccount : TAccountMint, + TAccountElgamalRegistry extends string ? ReadonlyAccount : TAccountElgamalRegistry, + ...(TAccountPayer extends undefined + ? [] + : [ + TAccountPayer extends string + ? WritableSignerAccount & AccountSignerMeta + : TAccountPayer, + ]), + ...(TAccountSystemProgram extends undefined + ? [] + : [ + TAccountSystemProgram extends string + ? ReadonlyAccount + : TAccountSystemProgram, + ]), + ...TRemainingAccounts, + ] + >; + +export type ConfigureConfidentialTransferAccountWithRegistryInstructionData = { + discriminator: number; + confidentialTransferDiscriminator: number; +}; + +export type ConfigureConfidentialTransferAccountWithRegistryInstructionDataArgs = {}; + +export function getConfigureConfidentialTransferAccountWithRegistryInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialTransferDiscriminator', getU8Encoder()], + ]), + value => ({ + ...value, + discriminator: CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_DISCRIMINATOR, + confidentialTransferDiscriminator: + CONFIGURE_CONFIDENTIAL_TRANSFER_ACCOUNT_WITH_REGISTRY_CONFIDENTIAL_TRANSFER_DISCRIMINATOR, + }), + ); +} + +export function getConfigureConfidentialTransferAccountWithRegistryInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialTransferDiscriminator', getU8Decoder()], + ]); +} + +export function getConfigureConfidentialTransferAccountWithRegistryInstructionDataCodec(): FixedSizeCodec< + ConfigureConfidentialTransferAccountWithRegistryInstructionDataArgs, + ConfigureConfidentialTransferAccountWithRegistryInstructionData +> { + return combineCodec( + getConfigureConfidentialTransferAccountWithRegistryInstructionDataEncoder(), + getConfigureConfidentialTransferAccountWithRegistryInstructionDataDecoder(), + ); +} + +export type ConfigureConfidentialTransferAccountWithRegistryInput< + TAccountToken extends string = string, + TAccountMint extends string = string, + TAccountElgamalRegistry extends string = string, + TAccountPayer extends string = string, + TAccountSystemProgram extends string = string, +> = { + /** The SPL Token account to configure. */ + token: Address; + /** The corresponding SPL Token mint. */ + mint: Address; + /** The ElGamal registry account that provides the encryption pubkey for the owner. */ + elgamalRegistry: Address; + /** + * (Optional) Payer that funds the rent required to reallocate the token + * account when it does not yet have the `ConfidentialTransferAccount` extension. + */ + payer?: TransactionSigner; + /** (Optional) System program, required when `payer` is provided. */ + systemProgram?: Address; +}; + +export function getConfigureConfidentialTransferAccountWithRegistryInstruction< + TAccountToken extends string, + TAccountMint extends string, + TAccountElgamalRegistry extends string, + TAccountPayer extends string, + TAccountSystemProgram extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: ConfigureConfidentialTransferAccountWithRegistryInput< + TAccountToken, + TAccountMint, + TAccountElgamalRegistry, + TAccountPayer, + TAccountSystemProgram + >, + config?: { programAddress?: TProgramAddress }, +): ConfigureConfidentialTransferAccountWithRegistryInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountElgamalRegistry, + TAccountPayer, + TAccountSystemProgram +> { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + token: { value: input.token ?? null, isWritable: true }, + mint: { value: input.mint ?? null, isWritable: false }, + elgamalRegistry: { value: input.elgamalRegistry ?? null, isWritable: false }, + payer: { value: input.payer ?? null, isWritable: true }, + systemProgram: { value: input.systemProgram ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.token), + getAccountMeta(accounts.mint), + getAccountMeta(accounts.elgamalRegistry), + getAccountMeta(accounts.payer), + getAccountMeta(accounts.systemProgram), + ].filter((x: T | undefined): x is T => x !== undefined), + data: getConfigureConfidentialTransferAccountWithRegistryInstructionDataEncoder().encode({}), + programAddress, + } as ConfigureConfidentialTransferAccountWithRegistryInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountElgamalRegistry, + TAccountPayer, + TAccountSystemProgram + >); +} + +export type ParsedConfigureConfidentialTransferAccountWithRegistryInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token account to configure. */ + token: TAccountMetas[0]; + /** The corresponding SPL Token mint. */ + mint: TAccountMetas[1]; + /** The ElGamal registry account that provides the encryption pubkey for the owner. */ + elgamalRegistry: TAccountMetas[2]; + /** + * (Optional) Payer that funds the rent required to reallocate the token + * account when it does not yet have the `ConfidentialTransferAccount` extension. + */ + payer?: TAccountMetas[3] | undefined; + /** (Optional) System program, required when `payer` is provided. */ + systemProgram?: TAccountMetas[4] | undefined; + }; + data: ConfigureConfidentialTransferAccountWithRegistryInstructionData; +}; + +export function parseConfigureConfidentialTransferAccountWithRegistryInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedConfigureConfidentialTransferAccountWithRegistryInstruction { + if (instruction.accounts.length < 3) { + // TODO: Coded error. + throw new Error('Not enough accounts'); + } + let accountIndex = 0; + const getNextAccount = () => { + const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; + accountIndex += 1; + return accountMeta; + }; + let optionalAccountsRemaining = instruction.accounts.length - 3; + const getNextOptionalAccount = () => { + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); + }; + return { + programAddress: instruction.programAddress, + accounts: { + token: getNextAccount(), + mint: getNextAccount(), + elgamalRegistry: getNextAccount(), + payer: getNextOptionalAccount(), + systemProgram: getNextOptionalAccount(), + }, + data: getConfigureConfidentialTransferAccountWithRegistryInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/index.ts b/clients/js/src/generated/instructions/index.ts index 730b5440a..10fd4a79c 100644 --- a/clients/js/src/generated/instructions/index.ts +++ b/clients/js/src/generated/instructions/index.ts @@ -19,6 +19,7 @@ export * from './confidentialTransfer'; export * from './confidentialTransferWithFee'; export * from './confidentialWithdraw'; export * from './configureConfidentialTransferAccount'; +export * from './configureConfidentialTransferAccountWithRegistry'; export * from './createAssociatedToken'; export * from './createAssociatedTokenIdempotent'; export * from './createNativeMint'; diff --git a/clients/js/src/generated/programs/token2022.ts b/clients/js/src/generated/programs/token2022.ts index 4baebcfe1..7897a5484 100644 --- a/clients/js/src/generated/programs/token2022.ts +++ b/clients/js/src/generated/programs/token2022.ts @@ -29,6 +29,7 @@ import { parseConfidentialTransferWithFeeInstruction, parseConfidentialWithdrawInstruction, parseConfigureConfidentialTransferAccountInstruction, + parseConfigureConfidentialTransferAccountWithRegistryInstruction, parseCreateNativeMintInstruction, parseDisableConfidentialCreditsInstruction, parseDisableCpiGuardInstruction, @@ -120,6 +121,7 @@ import { type ParsedConfidentialTransferWithFeeInstruction, type ParsedConfidentialWithdrawInstruction, type ParsedConfigureConfidentialTransferAccountInstruction, + type ParsedConfigureConfidentialTransferAccountWithRegistryInstruction, type ParsedCreateNativeMintInstruction, type ParsedDisableConfidentialCreditsInstruction, type ParsedDisableCpiGuardInstruction, @@ -259,6 +261,7 @@ export enum Token2022Instruction { InitializeConfidentialTransferMint, UpdateConfidentialTransferMint, ConfigureConfidentialTransferAccount, + ConfigureConfidentialTransferAccountWithRegistry, ApproveConfidentialTransferAccount, EmptyConfidentialTransferAccount, ConfidentialDeposit, @@ -426,6 +429,9 @@ export function identifyToken2022Instruction( if (containsBytes(data, getU8Encoder().encode(27), 0) && containsBytes(data, getU8Encoder().encode(2), 1)) { return Token2022Instruction.ConfigureConfidentialTransferAccount; } + if (containsBytes(data, getU8Encoder().encode(27), 0) && containsBytes(data, getU8Encoder().encode(14), 1)) { + return Token2022Instruction.ConfigureConfidentialTransferAccountWithRegistry; + } if (containsBytes(data, getU8Encoder().encode(27), 0) && containsBytes(data, getU8Encoder().encode(3), 1)) { return Token2022Instruction.ApproveConfidentialTransferAccount; } @@ -653,6 +659,9 @@ export type ParsedToken2022Instruction { + const [token, mint, authority] = await Promise.all([ + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + const instruction = getConfigureConfidentialTransferAccountInstruction({ + token: token.address, + mint: mint.address, + authority, + decryptableZeroBalance: DECRYPTABLE_ZERO_BALANCE, + maximumPendingBalanceCreditCounter: 65_536n, + proofInstructionOffset: 1, + }); + + t.is(instruction.accounts.length, 4); + t.is(instruction.accounts[0].address, token.address); + t.is(instruction.accounts[1].address, mint.address); + t.is(instruction.accounts[2].address, SYSVAR_INSTRUCTIONS_ADDRESS); + t.is(instruction.accounts[3].address, authority.address); +}); diff --git a/clients/js/test/extensions/confidentialTransfer/configureConfidentialTransferAccountWithRegistry.test.ts b/clients/js/test/extensions/confidentialTransfer/configureConfidentialTransferAccountWithRegistry.test.ts new file mode 100644 index 000000000..336b23cea --- /dev/null +++ b/clients/js/test/extensions/confidentialTransfer/configureConfidentialTransferAccountWithRegistry.test.ts @@ -0,0 +1,87 @@ +import { address, generateKeyPairSigner, type AccountMeta } from '@solana/kit'; +import test from 'ava'; +import { + getConfigureConfidentialTransferAccountWithRegistryInstruction, + parseConfigureConfidentialTransferAccountWithRegistryInstruction, +} from '../../../src'; + +const SYSTEM_PROGRAM_ADDRESS = address('11111111111111111111111111111111'); + +test('it encodes the 27/14 discriminator pair', async t => { + const [token, mint, elgamalRegistry] = await Promise.all([ + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + const instruction = getConfigureConfidentialTransferAccountWithRegistryInstruction({ + token: token.address, + mint: mint.address, + elgamalRegistry: elgamalRegistry.address, + }); + + t.is(instruction.data[0], 27); + t.is(instruction.data[1], 14); + t.is(instruction.data.length, 2); +}); + +test('it emits a 3-account layout when payer and systemProgram are omitted', async t => { + const [token, mint, elgamalRegistry] = await Promise.all([ + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + const instruction = getConfigureConfidentialTransferAccountWithRegistryInstruction({ + token: token.address, + mint: mint.address, + elgamalRegistry: elgamalRegistry.address, + }); + const accounts = instruction.accounts as readonly AccountMeta[]; + + t.is(accounts.length, 3); + t.is(accounts[0].address, token.address); + t.is(accounts[1].address, mint.address); + t.is(accounts[2].address, elgamalRegistry.address); +}); + +test('it emits a 5-account layout when payer is provided', async t => { + const [token, mint, elgamalRegistry, payer] = await Promise.all([ + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + const instruction = getConfigureConfidentialTransferAccountWithRegistryInstruction({ + token: token.address, + mint: mint.address, + elgamalRegistry: elgamalRegistry.address, + payer, + systemProgram: SYSTEM_PROGRAM_ADDRESS, + }); + const accounts = instruction.accounts as readonly AccountMeta[]; + + t.is(accounts.length, 5); + t.is(accounts[3].address, payer.address); + t.is(accounts[4].address, SYSTEM_PROGRAM_ADDRESS); +}); + +test('it round-trips through parse', async t => { + const [token, mint, elgamalRegistry] = await Promise.all([ + generateKeyPairSigner(), + generateKeyPairSigner(), + generateKeyPairSigner(), + ]); + + const instruction = getConfigureConfidentialTransferAccountWithRegistryInstruction({ + token: token.address, + mint: mint.address, + elgamalRegistry: elgamalRegistry.address, + }); + const parsed = parseConfigureConfidentialTransferAccountWithRegistryInstruction(instruction); + + t.is(parsed.accounts.token.address, token.address); + t.is(parsed.accounts.mint.address, mint.address); + t.is(parsed.accounts.elgamalRegistry.address, elgamalRegistry.address); +}); diff --git a/interface/idl.json b/interface/idl.json index cf4a2a5c9..4c85edbf8 100644 --- a/interface/idl.json +++ b/interface/idl.json @@ -3228,16 +3228,6 @@ "publicKey": "Sysvar1nstructions1111111111111111111111111" } }, - { - "kind": "instructionAccountNode", - "name": "record", - "isWritable": false, - "isSigner": false, - "isOptional": true, - "docs": [ - "(Optional) Record account if the accompanying proof is to be read from a record account." - ] - }, { "kind": "instructionAccountNode", "name": "authority", @@ -3341,6 +3331,112 @@ } ] }, + { + "kind": "instructionNode", + "name": "configureConfidentialTransferAccountWithRegistry", + "docs": [ + "Configures confidential transfers for a token account using an", + "ElGamal registry account that supplies the encryption pubkey.", + "", + "Unlike `ConfigureAccount`, this instruction does not require a", + "`VerifyPubkeyValidity` proof: the registry already attests to the", + "validity of the ElGamal public key.", + "", + "If the token account does not yet have room for the", + "`ConfidentialTransferAccount` extension, pass `payer` and", + "`systemProgram` so the instruction can fund the required reallocation." + ], + "optionalAccountStrategy": "omitted", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "token", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token account to configure."] + }, + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": ["The corresponding SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "elgamalRegistry", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": ["The ElGamal registry account that provides the encryption pubkey for the owner."] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": true, + "isSigner": true, + "isOptional": true, + "docs": [ + "(Optional) Payer that funds the rent required to reallocate the token", + "account when it does not yet have the `ConfidentialTransferAccount` extension." + ] + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": ["(Optional) System program, required when `payer` is provided."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 27 + } + }, + { + "kind": "instructionArgumentNode", + "name": "confidentialTransferDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 14 + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "confidentialTransferDiscriminator", + "offset": 1 + } + ] + }, { "kind": "instructionNode", "name": "approveConfidentialTransferAccount",