From 0f4e774d5b9dc041ec1823cfa9f51741a458e57d Mon Sep 17 00:00:00 2001 From: Loris Leiva Date: Tue, 2 Jun 2026 10:03:00 +0100 Subject: [PATCH] Sync Token 2022 IDL with the program interface This PR brings the hand-written Token 2022 IDL (`interface/idl.json`) back in sync with the actual program interface, including all extensions. It fixes incorrect instruction data layouts and account lists, adds missing instructions, and aligns the IDL with the original Token program IDL where they share instructions. ## Confidential Transfer - Add the missing `transferAmountAuditorCiphertextLo`/`Hi` fields to `confidentialTransfer` and `confidentialTransferWithFee`. - Add the missing `configureConfidentialTransferAccountWithRegistry` instruction. - Remove the extraneous `record` account from `configureConfidentialTransferAccount` and `emptyConfidentialTransferAccount`. - Omit absent optional proof accounts on `confidentialWithdraw`, `confidentialTransfer` and `confidentialTransferWithFee` instead of padding them with the program ID. ## Confidential Transfer Fee - Make `withdrawWithheldAuthorityElGamalPubkey` a required public key on `initializeConfidentialTransferFee`. - Remove the extraneous `record` account from `withdrawWithheldTokensFromMintForConfidentialTransferFee` and `withdrawWithheldTokensFromAccountsForConfidentialTransferFee`. ## Confidential Mint Burn - Add the entire extension, previously missing: `initializeConfidentialMintBurn`, `rotateSupplyElgamalPubkey`, `updateConfidentialMintBurnDecryptableSupply`, `confidentialMint`, `confidentialBurn` and `applyConfidentialPendingBurn`. - Fill in the empty `ConfidentialMintBurn` extension account state. ## Permissioned Burn - Add the missing `permissionedConfidentialBurn` instruction. ## Extension types - Fix the order of the `extensionType` enum to match the program. - Add the missing `confidentialMintBurn` and `permissionedBurn` variants. ## Alignment with the Token program IDL - Add the `batch` instruction, modelled identically to the Token IDL. - Add the optional `rent` account to `syncNative`. - Rename `withdrawExcessLamports` accounts to `source`/`destination`. ## Misc - Remove the `origin: "shank"` field and set the version to `3.0.1` to match the interface crate. ## Client The JS client was regenerated from the updated IDL. A few manual changes were also made: a new `ConfidentialMintBurn` case in `getInitializeInstructionsForExtensions`, an end-to-end test for `initializeConfidentialMintBurn`, and updates to existing tests affected by the IDL changes. --- .../applyConfidentialPendingBurn.ts | 196 ++ .../js/src/generated/instructions/batch.ts | 127 ++ .../instructions/confidentialBurn.ts | 407 +++++ .../instructions/confidentialMint.ts | 407 +++++ .../instructions/confidentialTransfer.ts | 70 +- .../confidentialTransferWithFee.ts | 92 +- .../instructions/confidentialWithdraw.ts | 40 +- .../configureConfidentialTransferAccount.ts | 22 +- ...ConfidentialTransferAccountWithRegistry.ts | 252 +++ .../emptyConfidentialTransferAccount.ts | 22 +- .../js/src/generated/instructions/index.ts | 9 + .../initializeConfidentialMintBurn.ts | 180 ++ .../initializeConfidentialTransferFee.ts | 14 +- .../permissionedConfidentialBurn.ts | 432 +++++ .../instructions/rotateSupplyElgamalPubkey.ts | 268 +++ .../src/generated/instructions/syncNative.ts | 48 +- ...teConfidentialMintBurnDecryptableSupply.ts | 213 +++ .../instructions/withdrawExcessLamports.ts | 62 +- ...sFromAccountsForConfidentialTransferFee.ts | 36 +- ...okensFromMintForConfidentialTransferFee.ts | 36 +- .../js/src/generated/programs/token2022.ts | 136 +- clients/js/src/generated/types/extension.ts | 50 +- .../js/src/generated/types/extensionType.ts | 8 +- .../getInitializeInstructionsForExtensions.ts | 9 + .../initializeConfidentialMintBurn.test.ts | 78 + .../initializeConfidentialTransferFee.test.ts | 2 +- clients/js/test/getMintSize.test.ts | 11 +- clients/js/test/withdrawExcess.test.ts | 4 +- interface/idl.json | 1586 +++++++++++++++-- 29 files changed, 4477 insertions(+), 340 deletions(-) create mode 100644 clients/js/src/generated/instructions/applyConfidentialPendingBurn.ts create mode 100644 clients/js/src/generated/instructions/batch.ts create mode 100644 clients/js/src/generated/instructions/confidentialBurn.ts create mode 100644 clients/js/src/generated/instructions/confidentialMint.ts create mode 100644 clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts create mode 100644 clients/js/src/generated/instructions/initializeConfidentialMintBurn.ts create mode 100644 clients/js/src/generated/instructions/permissionedConfidentialBurn.ts create mode 100644 clients/js/src/generated/instructions/rotateSupplyElgamalPubkey.ts create mode 100644 clients/js/src/generated/instructions/updateConfidentialMintBurnDecryptableSupply.ts create mode 100644 clients/js/test/extensions/confidentialMintBurn/initializeConfidentialMintBurn.test.ts diff --git a/clients/js/src/generated/instructions/applyConfidentialPendingBurn.ts b/clients/js/src/generated/instructions/applyConfidentialPendingBurn.ts new file mode 100644 index 000000000..a085fb944 --- /dev/null +++ b/clients/js/src/generated/instructions/applyConfidentialPendingBurn.ts @@ -0,0 +1,196 @@ +/** + * 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 { + AccountRole, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; + +export const APPLY_CONFIDENTIAL_PENDING_BURN_DISCRIMINATOR = 42; + +export function getApplyConfidentialPendingBurnDiscriminatorBytes() { + return getU8Encoder().encode(APPLY_CONFIDENTIAL_PENDING_BURN_DISCRIMINATOR); +} + +export const APPLY_CONFIDENTIAL_PENDING_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 5; + +export function getApplyConfidentialPendingBurnConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(APPLY_CONFIDENTIAL_PENDING_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type ApplyConfidentialPendingBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMint extends string | AccountMeta = string, + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountMint extends string ? WritableAccount : TAccountMint, + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type ApplyConfidentialPendingBurnInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; +}; + +export type ApplyConfidentialPendingBurnInstructionDataArgs = {}; + +export function getApplyConfidentialPendingBurnInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ]), + value => ({ + ...value, + discriminator: APPLY_CONFIDENTIAL_PENDING_BURN_DISCRIMINATOR, + confidentialMintBurnDiscriminator: APPLY_CONFIDENTIAL_PENDING_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getApplyConfidentialPendingBurnInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ]); +} + +export function getApplyConfidentialPendingBurnInstructionDataCodec(): FixedSizeCodec< + ApplyConfidentialPendingBurnInstructionDataArgs, + ApplyConfidentialPendingBurnInstructionData +> { + return combineCodec( + getApplyConfidentialPendingBurnInstructionDataEncoder(), + getApplyConfidentialPendingBurnInstructionDataDecoder(), + ); +} + +export type ApplyConfidentialPendingBurnInput< + TAccountMint extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token mint. */ + mint: Address; + /** The mint authority or its multisignature account. */ + authority: Address | TransactionSigner; + multiSigners?: Array; +}; + +export function getApplyConfidentialPendingBurnInstruction< + TAccountMint extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: ApplyConfidentialPendingBurnInput, + config?: { programAddress?: TProgramAddress }, +): ApplyConfidentialPendingBurnInstruction< + TProgramAddress, + TAccountMint, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + mint: { value: input.mint ?? null, isWritable: true }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + return Object.freeze({ + accounts: [getAccountMeta(accounts.mint), getAccountMeta(accounts.authority), ...remainingAccounts], + data: getApplyConfidentialPendingBurnInstructionDataEncoder().encode({}), + programAddress, + } as ApplyConfidentialPendingBurnInstruction< + TProgramAddress, + TAccountMint, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedApplyConfidentialPendingBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token mint. */ + mint: TAccountMetas[0]; + /** The mint authority or its multisignature account. */ + authority: TAccountMetas[1]; + }; + data: ApplyConfidentialPendingBurnInstructionData; +}; + +export function parseApplyConfidentialPendingBurnInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedApplyConfidentialPendingBurnInstruction { + if (instruction.accounts.length < 2) { + // 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; + }; + return { + programAddress: instruction.programAddress, + accounts: { mint: getNextAccount(), authority: getNextAccount() }, + data: getApplyConfidentialPendingBurnInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/batch.ts b/clients/js/src/generated/instructions/batch.ts new file mode 100644 index 000000000..ae4d776f4 --- /dev/null +++ b/clients/js/src/generated/instructions/batch.ts @@ -0,0 +1,127 @@ +/** + * 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 { + addDecoderSizePrefix, + addEncoderSizePrefix, + combineCodec, + getArrayDecoder, + getArrayEncoder, + getBytesDecoder, + getBytesEncoder, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, + type AccountMeta, + type Address, + type Codec, + type Decoder, + type Encoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyUint8Array, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; + +export const BATCH_DISCRIMINATOR = 255; + +export function getBatchDiscriminatorBytes() { + return getU8Encoder().encode(BATCH_DISCRIMINATOR); +} + +export type BatchInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & InstructionWithData & InstructionWithAccounts; + +export type BatchInstructionData = { + discriminator: number; + /** Instruction data for batch instructions. */ + data: Array<{ numberOfAccounts: number; instructionData: ReadonlyUint8Array }>; +}; + +export type BatchInstructionDataArgs = { + /** Instruction data for batch instructions. */ + data: Array<{ numberOfAccounts: number; instructionData: ReadonlyUint8Array }>; +}; + +export function getBatchInstructionDataEncoder(): Encoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + [ + 'data', + getArrayEncoder( + getStructEncoder([ + ['numberOfAccounts', getU8Encoder()], + ['instructionData', addEncoderSizePrefix(getBytesEncoder(), getU8Encoder())], + ]), + { size: 'remainder' }, + ), + ], + ]), + value => ({ ...value, discriminator: BATCH_DISCRIMINATOR }), + ); +} + +export function getBatchInstructionDataDecoder(): Decoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + [ + 'data', + getArrayDecoder( + getStructDecoder([ + ['numberOfAccounts', getU8Decoder()], + ['instructionData', addDecoderSizePrefix(getBytesDecoder(), getU8Decoder())], + ]), + { size: 'remainder' }, + ), + ], + ]); +} + +export function getBatchInstructionDataCodec(): Codec { + return combineCodec(getBatchInstructionDataEncoder(), getBatchInstructionDataDecoder()); +} + +export type BatchInput = { + data: BatchInstructionDataArgs['data']; +}; + +export function getBatchInstruction( + input: BatchInput, + config?: { programAddress?: TProgramAddress }, +): BatchInstruction { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original args. + const args = { ...input }; + + return Object.freeze({ + data: getBatchInstructionDataEncoder().encode(args as BatchInstructionDataArgs), + programAddress, + } as BatchInstruction); +} + +export type ParsedBatchInstruction = { + programAddress: Address; + data: BatchInstructionData; +}; + +export function parseBatchInstruction( + instruction: Instruction & InstructionWithData, +): ParsedBatchInstruction { + return { + programAddress: instruction.programAddress, + data: getBatchInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/confidentialBurn.ts b/clients/js/src/generated/instructions/confidentialBurn.ts new file mode 100644 index 000000000..0b5986bab --- /dev/null +++ b/clients/js/src/generated/instructions/confidentialBurn.ts @@ -0,0 +1,407 @@ +/** + * 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 { + AccountRole, + combineCodec, + getI8Decoder, + getI8Encoder, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; +import { + getDecryptableBalanceDecoder, + getDecryptableBalanceEncoder, + getEncryptedBalanceDecoder, + getEncryptedBalanceEncoder, + type DecryptableBalance, + type DecryptableBalanceArgs, + type EncryptedBalance, + type EncryptedBalanceArgs, +} from '../types'; + +export const CONFIDENTIAL_BURN_DISCRIMINATOR = 42; + +export function getConfidentialBurnDiscriminatorBytes() { + return getU8Encoder().encode(CONFIDENTIAL_BURN_DISCRIMINATOR); +} + +export const CONFIDENTIAL_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 4; + +export function getConfidentialBurnConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(CONFIDENTIAL_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type ConfidentialBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountToken extends string | AccountMeta = string, + TAccountMint extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountToken extends string ? WritableAccount : TAccountToken, + TAccountMint extends string ? WritableAccount : TAccountMint, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountCiphertextValidityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type ConfidentialBurnInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; + /** The new decryptable balance of the burner if the burn succeeds. */ + newDecryptableAvailableBalance: DecryptableBalance; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextLo: EncryptedBalance; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextHi: EncryptedBalance; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the `ConfidentialBurn` instruction in the transaction. If the + * offset is `0`, then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the `ConfidentialBurn` instruction in the transaction. + * If the offset is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * `ConfidentialBurn` instruction in the transaction. If the offset is + * `0`, then use a context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export type ConfidentialBurnInstructionDataArgs = { + /** The new decryptable balance of the burner if the burn succeeds. */ + newDecryptableAvailableBalance: DecryptableBalanceArgs; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextLo: EncryptedBalanceArgs; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextHi: EncryptedBalanceArgs; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the `ConfidentialBurn` instruction in the transaction. If the + * offset is `0`, then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the `ConfidentialBurn` instruction in the transaction. + * If the offset is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * `ConfidentialBurn` instruction in the transaction. If the offset is + * `0`, then use a context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export function getConfidentialBurnInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ['newDecryptableAvailableBalance', getDecryptableBalanceEncoder()], + ['burnAmountAuditorCiphertextLo', getEncryptedBalanceEncoder()], + ['burnAmountAuditorCiphertextHi', getEncryptedBalanceEncoder()], + ['equalityProofInstructionOffset', getI8Encoder()], + ['ciphertextValidityProofInstructionOffset', getI8Encoder()], + ['rangeProofInstructionOffset', getI8Encoder()], + ]), + value => ({ + ...value, + discriminator: CONFIDENTIAL_BURN_DISCRIMINATOR, + confidentialMintBurnDiscriminator: CONFIDENTIAL_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getConfidentialBurnInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ['newDecryptableAvailableBalance', getDecryptableBalanceDecoder()], + ['burnAmountAuditorCiphertextLo', getEncryptedBalanceDecoder()], + ['burnAmountAuditorCiphertextHi', getEncryptedBalanceDecoder()], + ['equalityProofInstructionOffset', getI8Decoder()], + ['ciphertextValidityProofInstructionOffset', getI8Decoder()], + ['rangeProofInstructionOffset', getI8Decoder()], + ]); +} + +export function getConfidentialBurnInstructionDataCodec(): FixedSizeCodec< + ConfidentialBurnInstructionDataArgs, + ConfidentialBurnInstructionData +> { + return combineCodec(getConfidentialBurnInstructionDataEncoder(), getConfidentialBurnInstructionDataDecoder()); +} + +export type ConfidentialBurnInput< + TAccountToken extends string = string, + TAccountMint extends string = string, + TAccountInstructionsSysvar extends string = string, + TAccountEqualityRecord extends string = string, + TAccountCiphertextValidityRecord extends string = string, + TAccountRangeRecord extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token account. */ + token: Address; + /** The SPL Token mint. */ + mint: Address; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: Address; + /** The account owner or its multisignature account. */ + authority: Address | TransactionSigner; + newDecryptableAvailableBalance: ConfidentialBurnInstructionDataArgs['newDecryptableAvailableBalance']; + burnAmountAuditorCiphertextLo: ConfidentialBurnInstructionDataArgs['burnAmountAuditorCiphertextLo']; + burnAmountAuditorCiphertextHi: ConfidentialBurnInstructionDataArgs['burnAmountAuditorCiphertextHi']; + equalityProofInstructionOffset: ConfidentialBurnInstructionDataArgs['equalityProofInstructionOffset']; + ciphertextValidityProofInstructionOffset: ConfidentialBurnInstructionDataArgs['ciphertextValidityProofInstructionOffset']; + rangeProofInstructionOffset: ConfidentialBurnInstructionDataArgs['rangeProofInstructionOffset']; + multiSigners?: Array; +}; + +export function getConfidentialBurnInstruction< + TAccountToken extends string, + TAccountMint extends string, + TAccountInstructionsSysvar extends string, + TAccountEqualityRecord extends string, + TAccountCiphertextValidityRecord extends string, + TAccountRangeRecord extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: ConfidentialBurnInput< + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + TAccountAuthority + >, + config?: { programAddress?: TProgramAddress }, +): ConfidentialBurnInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // 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: true }, + instructionsSysvar: { value: input.instructionsSysvar ?? null, isWritable: false }, + equalityRecord: { value: input.equalityRecord ?? null, isWritable: false }, + ciphertextValidityRecord: { value: input.ciphertextValidityRecord ?? null, isWritable: false }, + rangeRecord: { value: input.rangeRecord ?? null, isWritable: false }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.token), + getAccountMeta(accounts.mint), + getAccountMeta(accounts.instructionsSysvar), + getAccountMeta(accounts.equalityRecord), + getAccountMeta(accounts.ciphertextValidityRecord), + getAccountMeta(accounts.rangeRecord), + getAccountMeta(accounts.authority), + ...remainingAccounts, + ].filter((x: T | undefined): x is T => x !== undefined), + data: getConfidentialBurnInstructionDataEncoder().encode(args as ConfidentialBurnInstructionDataArgs), + programAddress, + } as ConfidentialBurnInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedConfidentialBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token account. */ + token: TAccountMetas[0]; + /** The SPL Token mint. */ + mint: TAccountMetas[1]; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: TAccountMetas[2] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: TAccountMetas[3] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: TAccountMetas[4] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: TAccountMetas[5] | undefined; + /** The account owner or its multisignature account. */ + authority: TAccountMetas[6]; + }; + data: ConfidentialBurnInstructionData; +}; + +export function parseConfidentialBurnInstruction( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedConfidentialBurnInstruction { + 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(), + instructionsSysvar: getNextOptionalAccount(), + equalityRecord: getNextOptionalAccount(), + ciphertextValidityRecord: getNextOptionalAccount(), + rangeRecord: getNextOptionalAccount(), + authority: getNextAccount(), + }, + data: getConfidentialBurnInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/confidentialMint.ts b/clients/js/src/generated/instructions/confidentialMint.ts new file mode 100644 index 000000000..227594374 --- /dev/null +++ b/clients/js/src/generated/instructions/confidentialMint.ts @@ -0,0 +1,407 @@ +/** + * 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 { + AccountRole, + combineCodec, + getI8Decoder, + getI8Encoder, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; +import { + getDecryptableBalanceDecoder, + getDecryptableBalanceEncoder, + getEncryptedBalanceDecoder, + getEncryptedBalanceEncoder, + type DecryptableBalance, + type DecryptableBalanceArgs, + type EncryptedBalance, + type EncryptedBalanceArgs, +} from '../types'; + +export const CONFIDENTIAL_MINT_DISCRIMINATOR = 42; + +export function getConfidentialMintDiscriminatorBytes() { + return getU8Encoder().encode(CONFIDENTIAL_MINT_DISCRIMINATOR); +} + +export const CONFIDENTIAL_MINT_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 3; + +export function getConfidentialMintConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(CONFIDENTIAL_MINT_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type ConfidentialMintInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountToken extends string | AccountMeta = string, + TAccountMint extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountToken extends string ? WritableAccount : TAccountToken, + TAccountMint extends string ? WritableAccount : TAccountMint, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountCiphertextValidityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type ConfidentialMintInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; + /** The new decryptable supply if the mint succeeds. */ + newDecryptableSupply: DecryptableBalance; + /** The mint amount encrypted under the auditor ElGamal public key. */ + mintAmountAuditorCiphertextLo: EncryptedBalance; + /** The mint amount encrypted under the auditor ElGamal public key. */ + mintAmountAuditorCiphertextHi: EncryptedBalance; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the `ConfidentialMint` instruction in the transaction. If the + * offset is `0`, then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the `ConfidentialMint` instruction in the transaction. + * If the offset is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * `ConfidentialMint` instruction in the transaction. If the offset is + * `0`, then use a context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export type ConfidentialMintInstructionDataArgs = { + /** The new decryptable supply if the mint succeeds. */ + newDecryptableSupply: DecryptableBalanceArgs; + /** The mint amount encrypted under the auditor ElGamal public key. */ + mintAmountAuditorCiphertextLo: EncryptedBalanceArgs; + /** The mint amount encrypted under the auditor ElGamal public key. */ + mintAmountAuditorCiphertextHi: EncryptedBalanceArgs; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the `ConfidentialMint` instruction in the transaction. If the + * offset is `0`, then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the `ConfidentialMint` instruction in the transaction. + * If the offset is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * `ConfidentialMint` instruction in the transaction. If the offset is + * `0`, then use a context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export function getConfidentialMintInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ['newDecryptableSupply', getDecryptableBalanceEncoder()], + ['mintAmountAuditorCiphertextLo', getEncryptedBalanceEncoder()], + ['mintAmountAuditorCiphertextHi', getEncryptedBalanceEncoder()], + ['equalityProofInstructionOffset', getI8Encoder()], + ['ciphertextValidityProofInstructionOffset', getI8Encoder()], + ['rangeProofInstructionOffset', getI8Encoder()], + ]), + value => ({ + ...value, + discriminator: CONFIDENTIAL_MINT_DISCRIMINATOR, + confidentialMintBurnDiscriminator: CONFIDENTIAL_MINT_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getConfidentialMintInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ['newDecryptableSupply', getDecryptableBalanceDecoder()], + ['mintAmountAuditorCiphertextLo', getEncryptedBalanceDecoder()], + ['mintAmountAuditorCiphertextHi', getEncryptedBalanceDecoder()], + ['equalityProofInstructionOffset', getI8Decoder()], + ['ciphertextValidityProofInstructionOffset', getI8Decoder()], + ['rangeProofInstructionOffset', getI8Decoder()], + ]); +} + +export function getConfidentialMintInstructionDataCodec(): FixedSizeCodec< + ConfidentialMintInstructionDataArgs, + ConfidentialMintInstructionData +> { + return combineCodec(getConfidentialMintInstructionDataEncoder(), getConfidentialMintInstructionDataDecoder()); +} + +export type ConfidentialMintInput< + TAccountToken extends string = string, + TAccountMint extends string = string, + TAccountInstructionsSysvar extends string = string, + TAccountEqualityRecord extends string = string, + TAccountCiphertextValidityRecord extends string = string, + TAccountRangeRecord extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token account. */ + token: Address; + /** The SPL Token mint. */ + mint: Address; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: Address; + /** The account owner or its multisignature account. */ + authority: Address | TransactionSigner; + newDecryptableSupply: ConfidentialMintInstructionDataArgs['newDecryptableSupply']; + mintAmountAuditorCiphertextLo: ConfidentialMintInstructionDataArgs['mintAmountAuditorCiphertextLo']; + mintAmountAuditorCiphertextHi: ConfidentialMintInstructionDataArgs['mintAmountAuditorCiphertextHi']; + equalityProofInstructionOffset: ConfidentialMintInstructionDataArgs['equalityProofInstructionOffset']; + ciphertextValidityProofInstructionOffset: ConfidentialMintInstructionDataArgs['ciphertextValidityProofInstructionOffset']; + rangeProofInstructionOffset: ConfidentialMintInstructionDataArgs['rangeProofInstructionOffset']; + multiSigners?: Array; +}; + +export function getConfidentialMintInstruction< + TAccountToken extends string, + TAccountMint extends string, + TAccountInstructionsSysvar extends string, + TAccountEqualityRecord extends string, + TAccountCiphertextValidityRecord extends string, + TAccountRangeRecord extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: ConfidentialMintInput< + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + TAccountAuthority + >, + config?: { programAddress?: TProgramAddress }, +): ConfidentialMintInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // 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: true }, + instructionsSysvar: { value: input.instructionsSysvar ?? null, isWritable: false }, + equalityRecord: { value: input.equalityRecord ?? null, isWritable: false }, + ciphertextValidityRecord: { value: input.ciphertextValidityRecord ?? null, isWritable: false }, + rangeRecord: { value: input.rangeRecord ?? null, isWritable: false }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.token), + getAccountMeta(accounts.mint), + getAccountMeta(accounts.instructionsSysvar), + getAccountMeta(accounts.equalityRecord), + getAccountMeta(accounts.ciphertextValidityRecord), + getAccountMeta(accounts.rangeRecord), + getAccountMeta(accounts.authority), + ...remainingAccounts, + ].filter((x: T | undefined): x is T => x !== undefined), + data: getConfidentialMintInstructionDataEncoder().encode(args as ConfidentialMintInstructionDataArgs), + programAddress, + } as ConfidentialMintInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedConfidentialMintInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token account. */ + token: TAccountMetas[0]; + /** The SPL Token mint. */ + mint: TAccountMetas[1]; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: TAccountMetas[2] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: TAccountMetas[3] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: TAccountMetas[4] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: TAccountMetas[5] | undefined; + /** The account owner or its multisignature account. */ + authority: TAccountMetas[6]; + }; + data: ConfidentialMintInstructionData; +}; + +export function parseConfidentialMintInstruction( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedConfidentialMintInstruction { + 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(), + instructionsSysvar: getNextOptionalAccount(), + equalityRecord: getNextOptionalAccount(), + ciphertextValidityRecord: getNextOptionalAccount(), + rangeRecord: getNextOptionalAccount(), + authority: getNextAccount(), + }, + data: getConfidentialMintInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/confidentialTransfer.ts b/clients/js/src/generated/instructions/confidentialTransfer.ts index 3e015861a..6610957fc 100644 --- a/clients/js/src/generated/instructions/confidentialTransfer.ts +++ b/clients/js/src/generated/instructions/confidentialTransfer.ts @@ -36,8 +36,12 @@ import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; import { getDecryptableBalanceDecoder, getDecryptableBalanceEncoder, + getEncryptedBalanceDecoder, + getEncryptedBalanceEncoder, type DecryptableBalance, type DecryptableBalanceArgs, + type EncryptedBalance, + type EncryptedBalanceArgs, } from '../types'; export const CONFIDENTIAL_TRANSFER_DISCRIMINATOR = 27; @@ -57,10 +61,10 @@ export type ConfidentialTransferInstruction< TAccountSourceToken extends string | AccountMeta = string, TAccountMint extends string | AccountMeta = string, TAccountDestinationToken extends string | AccountMeta = string, - TAccountInstructionsSysvar extends string | AccountMeta = string, - TAccountEqualityRecord extends string | AccountMeta = string, - TAccountCiphertextValidityRecord extends string | AccountMeta = string, - TAccountRangeRecord extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -72,14 +76,30 @@ export type ConfidentialTransferInstruction< TAccountDestinationToken extends string ? WritableAccount : TAccountDestinationToken, - TAccountInstructionsSysvar extends string - ? ReadonlyAccount - : TAccountInstructionsSysvar, - TAccountEqualityRecord extends string ? ReadonlyAccount : TAccountEqualityRecord, - TAccountCiphertextValidityRecord extends string - ? ReadonlyAccount - : TAccountCiphertextValidityRecord, - TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountCiphertextValidityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -90,6 +110,10 @@ export type ConfidentialTransferInstructionData = { confidentialTransferDiscriminator: number; /** The new source decryptable balance if the transfer succeeds. */ newSourceDecryptableAvailableBalance: DecryptableBalance; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextLo: EncryptedBalance; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextHi: EncryptedBalance; /** * Relative location of the * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction @@ -115,6 +139,10 @@ export type ConfidentialTransferInstructionData = { export type ConfidentialTransferInstructionDataArgs = { /** The new source decryptable balance if the transfer succeeds. */ newSourceDecryptableAvailableBalance: DecryptableBalanceArgs; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextLo: EncryptedBalanceArgs; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextHi: EncryptedBalanceArgs; /** * Relative location of the * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction @@ -143,6 +171,8 @@ export function getConfidentialTransferInstructionDataEncoder(): FixedSizeEncode ['discriminator', getU8Encoder()], ['confidentialTransferDiscriminator', getU8Encoder()], ['newSourceDecryptableAvailableBalance', getDecryptableBalanceEncoder()], + ['transferAmountAuditorCiphertextLo', getEncryptedBalanceEncoder()], + ['transferAmountAuditorCiphertextHi', getEncryptedBalanceEncoder()], ['equalityProofInstructionOffset', getI8Encoder()], ['ciphertextValidityProofInstructionOffset', getI8Encoder()], ['rangeProofInstructionOffset', getI8Encoder()], @@ -160,6 +190,8 @@ export function getConfidentialTransferInstructionDataDecoder(): FixedSizeDecode ['discriminator', getU8Decoder()], ['confidentialTransferDiscriminator', getU8Decoder()], ['newSourceDecryptableAvailableBalance', getDecryptableBalanceDecoder()], + ['transferAmountAuditorCiphertextLo', getEncryptedBalanceDecoder()], + ['transferAmountAuditorCiphertextHi', getEncryptedBalanceDecoder()], ['equalityProofInstructionOffset', getI8Decoder()], ['ciphertextValidityProofInstructionOffset', getI8Decoder()], ['rangeProofInstructionOffset', getI8Decoder()], @@ -207,6 +239,8 @@ export type ConfidentialTransferInput< /** The source account's owner/delegate or its multisignature account. */ authority: Address | TransactionSigner; newSourceDecryptableAvailableBalance: ConfidentialTransferInstructionDataArgs['newSourceDecryptableAvailableBalance']; + transferAmountAuditorCiphertextLo: ConfidentialTransferInstructionDataArgs['transferAmountAuditorCiphertextLo']; + transferAmountAuditorCiphertextHi: ConfidentialTransferInstructionDataArgs['transferAmountAuditorCiphertextHi']; equalityProofInstructionOffset: ConfidentialTransferInstructionDataArgs['equalityProofInstructionOffset']; ciphertextValidityProofInstructionOffset: ConfidentialTransferInstructionDataArgs['ciphertextValidityProofInstructionOffset']; rangeProofInstructionOffset: ConfidentialTransferInstructionDataArgs['rangeProofInstructionOffset']; @@ -274,7 +308,7 @@ export function getConfidentialTransferInstruction< signer, })); - const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); return Object.freeze({ accounts: [ getAccountMeta(accounts.sourceToken), @@ -286,7 +320,7 @@ export function getConfidentialTransferInstruction< getAccountMeta(accounts.rangeRecord), getAccountMeta(accounts.authority), ...remainingAccounts, - ], + ].filter((x: T | undefined): x is T => x !== undefined), data: getConfidentialTransferInstructionDataEncoder().encode(args as ConfidentialTransferInstructionDataArgs), programAddress, } as ConfidentialTransferInstruction< @@ -342,7 +376,7 @@ export function parseConfidentialTransferInstruction< InstructionWithAccounts & InstructionWithData, ): ParsedConfidentialTransferInstruction { - if (instruction.accounts.length < 8) { + if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -352,9 +386,11 @@ export function parseConfidentialTransferInstruction< accountIndex += 1; return accountMeta; }; + let optionalAccountsRemaining = instruction.accounts.length - 4; const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); }; return { programAddress: instruction.programAddress, diff --git a/clients/js/src/generated/instructions/confidentialTransferWithFee.ts b/clients/js/src/generated/instructions/confidentialTransferWithFee.ts index 0c8947bfd..70d3f08ba 100644 --- a/clients/js/src/generated/instructions/confidentialTransferWithFee.ts +++ b/clients/js/src/generated/instructions/confidentialTransferWithFee.ts @@ -36,8 +36,12 @@ import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; import { getDecryptableBalanceDecoder, getDecryptableBalanceEncoder, + getEncryptedBalanceDecoder, + getEncryptedBalanceEncoder, type DecryptableBalance, type DecryptableBalanceArgs, + type EncryptedBalance, + type EncryptedBalanceArgs, } from '../types'; export const CONFIDENTIAL_TRANSFER_WITH_FEE_DISCRIMINATOR = 27; @@ -57,12 +61,12 @@ export type ConfidentialTransferWithFeeInstruction< TAccountSourceToken extends string | AccountMeta = string, TAccountMint extends string | AccountMeta = string, TAccountDestinationToken extends string | AccountMeta = string, - TAccountInstructionsSysvar extends string | AccountMeta = string, - TAccountEqualityRecord extends string | AccountMeta = string, - TAccountTransferAmountCiphertextValidityRecord extends string | AccountMeta = string, - TAccountFeeSigmaRecord extends string | AccountMeta = string, - TAccountFeeCiphertextValidityRecord extends string | AccountMeta = string, - TAccountRangeRecord extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountTransferAmountCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountFeeSigmaRecord extends string | AccountMeta | undefined = undefined, + TAccountFeeCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -74,18 +78,44 @@ export type ConfidentialTransferWithFeeInstruction< TAccountDestinationToken extends string ? WritableAccount : TAccountDestinationToken, - TAccountInstructionsSysvar extends string - ? ReadonlyAccount - : TAccountInstructionsSysvar, - TAccountEqualityRecord extends string ? ReadonlyAccount : TAccountEqualityRecord, - TAccountTransferAmountCiphertextValidityRecord extends string - ? ReadonlyAccount - : TAccountTransferAmountCiphertextValidityRecord, - TAccountFeeSigmaRecord extends string ? ReadonlyAccount : TAccountFeeSigmaRecord, - TAccountFeeCiphertextValidityRecord extends string - ? ReadonlyAccount - : TAccountFeeCiphertextValidityRecord, - TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountTransferAmountCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountTransferAmountCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountTransferAmountCiphertextValidityRecord, + ]), + ...(TAccountFeeSigmaRecord extends undefined + ? [] + : [ + TAccountFeeSigmaRecord extends string + ? ReadonlyAccount + : TAccountFeeSigmaRecord, + ]), + ...(TAccountFeeCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountFeeCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountFeeCiphertextValidityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -96,6 +126,10 @@ export type ConfidentialTransferWithFeeInstructionData = { confidentialTransferDiscriminator: number; /** The new source decryptable balance if the transfer succeeds. */ newSourceDecryptableAvailableBalance: DecryptableBalance; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextLo: EncryptedBalance; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextHi: EncryptedBalance; /** * Relative location of the * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction @@ -138,6 +172,10 @@ export type ConfidentialTransferWithFeeInstructionData = { export type ConfidentialTransferWithFeeInstructionDataArgs = { /** The new source decryptable balance if the transfer succeeds. */ newSourceDecryptableAvailableBalance: DecryptableBalanceArgs; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextLo: EncryptedBalanceArgs; + /** The transfer amount encrypted under the auditor ElGamal public key. */ + transferAmountAuditorCiphertextHi: EncryptedBalanceArgs; /** * Relative location of the * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction @@ -183,6 +221,8 @@ export function getConfidentialTransferWithFeeInstructionDataEncoder(): FixedSiz ['discriminator', getU8Encoder()], ['confidentialTransferDiscriminator', getU8Encoder()], ['newSourceDecryptableAvailableBalance', getDecryptableBalanceEncoder()], + ['transferAmountAuditorCiphertextLo', getEncryptedBalanceEncoder()], + ['transferAmountAuditorCiphertextHi', getEncryptedBalanceEncoder()], ['equalityProofInstructionOffset', getI8Encoder()], ['transferAmountCiphertextValidityProofInstructionOffset', getI8Encoder()], ['feeSigmaProofInstructionOffset', getI8Encoder()], @@ -202,6 +242,8 @@ export function getConfidentialTransferWithFeeInstructionDataDecoder(): FixedSiz ['discriminator', getU8Decoder()], ['confidentialTransferDiscriminator', getU8Decoder()], ['newSourceDecryptableAvailableBalance', getDecryptableBalanceDecoder()], + ['transferAmountAuditorCiphertextLo', getEncryptedBalanceDecoder()], + ['transferAmountAuditorCiphertextHi', getEncryptedBalanceDecoder()], ['equalityProofInstructionOffset', getI8Decoder()], ['transferAmountCiphertextValidityProofInstructionOffset', getI8Decoder()], ['feeSigmaProofInstructionOffset', getI8Decoder()], @@ -260,6 +302,8 @@ export type ConfidentialTransferWithFeeInput< /** The source account's owner/delegate or its multisignature account. */ authority: Address | TransactionSigner; newSourceDecryptableAvailableBalance: ConfidentialTransferWithFeeInstructionDataArgs['newSourceDecryptableAvailableBalance']; + transferAmountAuditorCiphertextLo: ConfidentialTransferWithFeeInstructionDataArgs['transferAmountAuditorCiphertextLo']; + transferAmountAuditorCiphertextHi: ConfidentialTransferWithFeeInstructionDataArgs['transferAmountAuditorCiphertextHi']; equalityProofInstructionOffset: ConfidentialTransferWithFeeInstructionDataArgs['equalityProofInstructionOffset']; transferAmountCiphertextValidityProofInstructionOffset: ConfidentialTransferWithFeeInstructionDataArgs['transferAmountCiphertextValidityProofInstructionOffset']; feeSigmaProofInstructionOffset: ConfidentialTransferWithFeeInstructionDataArgs['feeSigmaProofInstructionOffset']; @@ -340,7 +384,7 @@ export function getConfidentialTransferWithFeeInstruction< signer, })); - const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); return Object.freeze({ accounts: [ getAccountMeta(accounts.sourceToken), @@ -354,7 +398,7 @@ export function getConfidentialTransferWithFeeInstruction< getAccountMeta(accounts.rangeRecord), getAccountMeta(accounts.authority), ...remainingAccounts, - ], + ].filter((x: T | undefined): x is T => x !== undefined), data: getConfidentialTransferWithFeeInstructionDataEncoder().encode( args as ConfidentialTransferWithFeeInstructionDataArgs, ), @@ -421,7 +465,7 @@ export function parseConfidentialTransferWithFeeInstruction< InstructionWithAccounts & InstructionWithData, ): ParsedConfidentialTransferWithFeeInstruction { - if (instruction.accounts.length < 10) { + if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -431,9 +475,11 @@ export function parseConfidentialTransferWithFeeInstruction< accountIndex += 1; return accountMeta; }; + let optionalAccountsRemaining = instruction.accounts.length - 4; const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); }; return { programAddress: instruction.programAddress, diff --git a/clients/js/src/generated/instructions/confidentialWithdraw.ts b/clients/js/src/generated/instructions/confidentialWithdraw.ts index da3f7861f..fa31520c5 100644 --- a/clients/js/src/generated/instructions/confidentialWithdraw.ts +++ b/clients/js/src/generated/instructions/confidentialWithdraw.ts @@ -58,9 +58,9 @@ export type ConfidentialWithdrawInstruction< TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, TAccountToken extends string | AccountMeta = string, TAccountMint extends string | AccountMeta = string, - TAccountInstructionsSysvar extends string | AccountMeta = string, - TAccountEqualityRecord extends string | AccountMeta = string, - TAccountRangeRecord extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -69,11 +69,23 @@ export type ConfidentialWithdrawInstruction< [ TAccountToken extends string ? WritableAccount : TAccountToken, TAccountMint extends string ? ReadonlyAccount : TAccountMint, - TAccountInstructionsSysvar extends string - ? ReadonlyAccount - : TAccountInstructionsSysvar, - TAccountEqualityRecord extends string ? ReadonlyAccount : TAccountEqualityRecord, - TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -251,7 +263,7 @@ export function getConfidentialWithdrawInstruction< signer, })); - const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); return Object.freeze({ accounts: [ getAccountMeta(accounts.token), @@ -261,7 +273,7 @@ export function getConfidentialWithdrawInstruction< getAccountMeta(accounts.rangeRecord), getAccountMeta(accounts.authority), ...remainingAccounts, - ], + ].filter((x: T | undefined): x is T => x !== undefined), data: getConfidentialWithdrawInstructionDataEncoder().encode(args as ConfidentialWithdrawInstructionDataArgs), programAddress, } as ConfidentialWithdrawInstruction< @@ -311,7 +323,7 @@ export function parseConfidentialWithdrawInstruction< InstructionWithAccounts & InstructionWithData, ): ParsedConfidentialWithdrawInstruction { - if (instruction.accounts.length < 6) { + if (instruction.accounts.length < 3) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -321,9 +333,11 @@ export function parseConfidentialWithdrawInstruction< accountIndex += 1; return accountMeta; }; + let optionalAccountsRemaining = instruction.accounts.length - 3; const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); }; return { programAddress: instruction.programAddress, 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..bb685147f --- /dev/null +++ b/clients/js/src/generated/instructions/configureConfidentialTransferAccountWithRegistry.ts @@ -0,0 +1,252 @@ +/** + * 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. */ + token: Address; + /** The corresponding SPL Token mint. */ + mint: Address; + /** The ElGamal registry account. */ + elgamalRegistry: Address; + /** (Optional) The payer account to fund reallocation. */ + payer?: TransactionSigner; + /** (Optional) System program for reallocation funding. */ + 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. */ + token: TAccountMetas[0]; + /** The corresponding SPL Token mint. */ + mint: TAccountMetas[1]; + /** The ElGamal registry account. */ + elgamalRegistry: TAccountMetas[2]; + /** (Optional) The payer account to fund reallocation. */ + payer?: TAccountMetas[3] | undefined; + /** (Optional) System program for reallocation funding. */ + 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/emptyConfidentialTransferAccount.ts b/clients/js/src/generated/instructions/emptyConfidentialTransferAccount.ts index f25e33d41..7206f6fd1 100644 --- a/clients/js/src/generated/instructions/emptyConfidentialTransferAccount.ts +++ b/clients/js/src/generated/instructions/emptyConfidentialTransferAccount.ts @@ -51,7 +51,6 @@ export type EmptyConfidentialTransferAccountInstruction< TAccountToken extends string | AccountMeta = string, TAccountInstructionsSysvarOrContextState extends string | AccountMeta = 'Sysvar1nstructions1111111111111111111111111', - TAccountRecord extends string | AccountMeta = string, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -62,7 +61,6 @@ export type EmptyConfidentialTransferAccountInstruction< TAccountInstructionsSysvarOrContextState extends string ? ReadonlyAccount : TAccountInstructionsSysvarOrContextState, - TAccountRecord extends string ? ReadonlyAccount : TAccountRecord, TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -124,7 +122,6 @@ export function getEmptyConfidentialTransferAccountInstructionDataCodec(): Fixed export type EmptyConfidentialTransferAccountInput< TAccountToken extends string = string, TAccountInstructionsSysvarOrContextState extends string = string, - TAccountRecord extends string = string, TAccountAuthority extends string = string, > = { /** The SPL Token account. */ @@ -136,8 +133,6 @@ export type EmptyConfidentialTransferAccountInput< * 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; proofInstructionOffset: EmptyConfidentialTransferAccountInstructionDataArgs['proofInstructionOffset']; @@ -147,14 +142,12 @@ export type EmptyConfidentialTransferAccountInput< export function getEmptyConfidentialTransferAccountInstruction< TAccountToken extends string, TAccountInstructionsSysvarOrContextState extends string, - TAccountRecord extends string, TAccountAuthority extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( input: EmptyConfidentialTransferAccountInput< TAccountToken, TAccountInstructionsSysvarOrContextState, - TAccountRecord, TAccountAuthority >, config?: { programAddress?: TProgramAddress }, @@ -162,7 +155,6 @@ export function getEmptyConfidentialTransferAccountInstruction< TProgramAddress, TAccountToken, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -174,7 +166,6 @@ export function getEmptyConfidentialTransferAccountInstruction< const originalAccounts = { token: { value: input.token ?? null, isWritable: true }, 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; @@ -200,7 +191,6 @@ export function getEmptyConfidentialTransferAccountInstruction< accounts: [ getAccountMeta(accounts.token), getAccountMeta(accounts.instructionsSysvarOrContextState), - getAccountMeta(accounts.record), getAccountMeta(accounts.authority), ...remainingAccounts, ], @@ -212,7 +202,6 @@ export function getEmptyConfidentialTransferAccountInstruction< TProgramAddress, TAccountToken, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -234,10 +223,8 @@ export type ParsedEmptyConfidentialTransferAccountInstruction< * account. */ instructionsSysvarOrContextState: TAccountMetas[1]; - /** (Optional) Record account if the accompanying proof is to be read from a record account. */ - record?: TAccountMetas[2] | undefined; /** The source account's owner/delegate or its multisignature account. */ - authority: TAccountMetas[3]; + authority: TAccountMetas[2]; }; data: EmptyConfidentialTransferAccountInstructionData; }; @@ -250,7 +237,7 @@ export function parseEmptyConfidentialTransferAccountInstruction< InstructionWithAccounts & InstructionWithData, ): ParsedEmptyConfidentialTransferAccountInstruction { - if (instruction.accounts.length < 4) { + if (instruction.accounts.length < 3) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -260,16 +247,11 @@ export function parseEmptyConfidentialTransferAccountInstruction< 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(), instructionsSysvarOrContextState: getNextAccount(), - record: getNextOptionalAccount(), authority: getNextAccount(), }, data: getEmptyConfidentialTransferAccountInstructionDataDecoder().decode(instruction.data), diff --git a/clients/js/src/generated/instructions/index.ts b/clients/js/src/generated/instructions/index.ts index 730b5440a..80729e2c7 100644 --- a/clients/js/src/generated/instructions/index.ts +++ b/clients/js/src/generated/instructions/index.ts @@ -8,17 +8,22 @@ export * from './amountToUiAmount'; export * from './applyConfidentialPendingBalance'; +export * from './applyConfidentialPendingBurn'; export * from './approve'; export * from './approveChecked'; export * from './approveConfidentialTransferAccount'; +export * from './batch'; export * from './burn'; export * from './burnChecked'; export * from './closeAccount'; +export * from './confidentialBurn'; export * from './confidentialDeposit'; +export * from './confidentialMint'; export * from './confidentialTransfer'; export * from './confidentialTransferWithFee'; export * from './confidentialWithdraw'; export * from './configureConfidentialTransferAccount'; +export * from './configureConfidentialTransferAccountWithRegistry'; export * from './createAssociatedToken'; export * from './createAssociatedTokenIdempotent'; export * from './createNativeMint'; @@ -41,6 +46,7 @@ export * from './harvestWithheldTokensToMintForConfidentialTransferFee'; export * from './initializeAccount'; export * from './initializeAccount2'; export * from './initializeAccount3'; +export * from './initializeConfidentialMintBurn'; export * from './initializeConfidentialTransferFee'; export * from './initializeConfidentialTransferMint'; export * from './initializeDefaultAccountState'; @@ -69,11 +75,13 @@ export * from './mintToChecked'; export * from './pause'; export * from './permissionedBurn'; export * from './permissionedBurnChecked'; +export * from './permissionedConfidentialBurn'; export * from './reallocate'; export * from './recoverNestedAssociatedToken'; export * from './removeTokenMetadataKey'; export * from './resume'; export * from './revoke'; +export * from './rotateSupplyElgamalPubkey'; export * from './setAuthority'; export * from './setTransferFee'; export * from './syncNative'; @@ -83,6 +91,7 @@ export * from './transferChecked'; export * from './transferCheckedWithFee'; export * from './uiAmountToAmount'; export * from './unwrapLamports'; +export * from './updateConfidentialMintBurnDecryptableSupply'; export * from './updateConfidentialTransferMint'; export * from './updateDefaultAccountState'; export * from './updateGroupMemberPointer'; diff --git a/clients/js/src/generated/instructions/initializeConfidentialMintBurn.ts b/clients/js/src/generated/instructions/initializeConfidentialMintBurn.ts new file mode 100644 index 000000000..cd0fc56d8 --- /dev/null +++ b/clients/js/src/generated/instructions/initializeConfidentialMintBurn.ts @@ -0,0 +1,180 @@ +/** + * 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, + getStructDecoder, + getStructEncoder, + getU8Decoder, + getU8Encoder, + transformEncoder, + type AccountMeta, + type Address, + type FixedSizeCodec, + type FixedSizeDecoder, + type FixedSizeEncoder, + type Instruction, + type InstructionWithAccounts, + type InstructionWithData, + type ReadonlyUint8Array, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; +import { + getDecryptableBalanceDecoder, + getDecryptableBalanceEncoder, + type DecryptableBalance, + type DecryptableBalanceArgs, +} from '../types'; + +export const INITIALIZE_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 42; + +export function getInitializeConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(INITIALIZE_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export const INITIALIZE_CONFIDENTIAL_MINT_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 0; + +export function getInitializeConfidentialMintBurnConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(INITIALIZE_CONFIDENTIAL_MINT_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type InitializeConfidentialMintBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMint extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [TAccountMint extends string ? WritableAccount : TAccountMint, ...TRemainingAccounts] + >; + +export type InitializeConfidentialMintBurnInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; + /** The ElGamal pubkey used to encrypt the confidential supply. */ + supplyElgamalPubkey: Address; + /** The initial 0 supply encrypted with the supply aes key. */ + decryptableSupply: DecryptableBalance; +}; + +export type InitializeConfidentialMintBurnInstructionDataArgs = { + /** The ElGamal pubkey used to encrypt the confidential supply. */ + supplyElgamalPubkey: Address; + /** The initial 0 supply encrypted with the supply aes key. */ + decryptableSupply: DecryptableBalanceArgs; +}; + +export function getInitializeConfidentialMintBurnInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ['supplyElgamalPubkey', getAddressEncoder()], + ['decryptableSupply', getDecryptableBalanceEncoder()], + ]), + value => ({ + ...value, + discriminator: INITIALIZE_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + confidentialMintBurnDiscriminator: INITIALIZE_CONFIDENTIAL_MINT_BURN_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getInitializeConfidentialMintBurnInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ['supplyElgamalPubkey', getAddressDecoder()], + ['decryptableSupply', getDecryptableBalanceDecoder()], + ]); +} + +export function getInitializeConfidentialMintBurnInstructionDataCodec(): FixedSizeCodec< + InitializeConfidentialMintBurnInstructionDataArgs, + InitializeConfidentialMintBurnInstructionData +> { + return combineCodec( + getInitializeConfidentialMintBurnInstructionDataEncoder(), + getInitializeConfidentialMintBurnInstructionDataDecoder(), + ); +} + +export type InitializeConfidentialMintBurnInput = { + /** The SPL Token mint. */ + mint: Address; + supplyElgamalPubkey: InitializeConfidentialMintBurnInstructionDataArgs['supplyElgamalPubkey']; + decryptableSupply: InitializeConfidentialMintBurnInstructionDataArgs['decryptableSupply']; +}; + +export function getInitializeConfidentialMintBurnInstruction< + TAccountMint extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: InitializeConfidentialMintBurnInput, + config?: { programAddress?: TProgramAddress }, +): InitializeConfidentialMintBurnInstruction { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { mint: { value: input.mint ?? null, isWritable: true } }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + return Object.freeze({ + accounts: [getAccountMeta(accounts.mint)], + data: getInitializeConfidentialMintBurnInstructionDataEncoder().encode( + args as InitializeConfidentialMintBurnInstructionDataArgs, + ), + programAddress, + } as InitializeConfidentialMintBurnInstruction); +} + +export type ParsedInitializeConfidentialMintBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token mint. */ + mint: TAccountMetas[0]; + }; + data: InitializeConfidentialMintBurnInstructionData; +}; + +export function parseInitializeConfidentialMintBurnInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedInitializeConfidentialMintBurnInstruction { + if (instruction.accounts.length < 1) { + // 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; + }; + return { + programAddress: instruction.programAddress, + accounts: { mint: getNextAccount() }, + data: getInitializeConfidentialMintBurnInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/initializeConfidentialTransferFee.ts b/clients/js/src/generated/instructions/initializeConfidentialTransferFee.ts index 967f3aafa..87166ae2a 100644 --- a/clients/js/src/generated/instructions/initializeConfidentialTransferFee.ts +++ b/clients/js/src/generated/instructions/initializeConfidentialTransferFee.ts @@ -61,14 +61,14 @@ export type InitializeConfidentialTransferFeeInstructionData = { /** Optional authority to set the withdraw withheld authority ElGamal key */ authority: Option
; /** Withheld fees from accounts must be encrypted with this ElGamal key */ - withdrawWithheldAuthorityElGamalPubkey: Option
; + withdrawWithheldAuthorityElGamalPubkey: Address; }; export type InitializeConfidentialTransferFeeInstructionDataArgs = { /** Optional authority to set the withdraw withheld authority ElGamal key */ authority: OptionOrNullable
; /** Withheld fees from accounts must be encrypted with this ElGamal key */ - withdrawWithheldAuthorityElGamalPubkey: OptionOrNullable
; + withdrawWithheldAuthorityElGamalPubkey: Address; }; export function getInitializeConfidentialTransferFeeInstructionDataEncoder(): FixedSizeEncoder { @@ -77,10 +77,7 @@ export function getInitializeConfidentialTransferFeeInstructionDataEncoder(): Fi ['discriminator', getU8Encoder()], ['confidentialTransferFeeDiscriminator', getU8Encoder()], ['authority', getOptionEncoder(getAddressEncoder(), { prefix: null, noneValue: 'zeroes' })], - [ - 'withdrawWithheldAuthorityElGamalPubkey', - getOptionEncoder(getAddressEncoder(), { prefix: null, noneValue: 'zeroes' }), - ], + ['withdrawWithheldAuthorityElGamalPubkey', getAddressEncoder()], ]), value => ({ ...value, @@ -96,10 +93,7 @@ export function getInitializeConfidentialTransferFeeInstructionDataDecoder(): Fi ['discriminator', getU8Decoder()], ['confidentialTransferFeeDiscriminator', getU8Decoder()], ['authority', getOptionDecoder(getAddressDecoder(), { prefix: null, noneValue: 'zeroes' })], - [ - 'withdrawWithheldAuthorityElGamalPubkey', - getOptionDecoder(getAddressDecoder(), { prefix: null, noneValue: 'zeroes' }), - ], + ['withdrawWithheldAuthorityElGamalPubkey', getAddressDecoder()], ]); } diff --git a/clients/js/src/generated/instructions/permissionedConfidentialBurn.ts b/clients/js/src/generated/instructions/permissionedConfidentialBurn.ts new file mode 100644 index 000000000..a7b1a2f37 --- /dev/null +++ b/clients/js/src/generated/instructions/permissionedConfidentialBurn.ts @@ -0,0 +1,432 @@ +/** + * 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 { + AccountRole, + combineCodec, + getI8Decoder, + getI8Encoder, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; +import { + getDecryptableBalanceDecoder, + getDecryptableBalanceEncoder, + getEncryptedBalanceDecoder, + getEncryptedBalanceEncoder, + type DecryptableBalance, + type DecryptableBalanceArgs, + type EncryptedBalance, + type EncryptedBalanceArgs, +} from '../types'; + +export const PERMISSIONED_CONFIDENTIAL_BURN_DISCRIMINATOR = 46; + +export function getPermissionedConfidentialBurnDiscriminatorBytes() { + return getU8Encoder().encode(PERMISSIONED_CONFIDENTIAL_BURN_DISCRIMINATOR); +} + +export const PERMISSIONED_CONFIDENTIAL_BURN_PERMISSIONED_BURN_DISCRIMINATOR = 3; + +export function getPermissionedConfidentialBurnPermissionedBurnDiscriminatorBytes() { + return getU8Encoder().encode(PERMISSIONED_CONFIDENTIAL_BURN_PERMISSIONED_BURN_DISCRIMINATOR); +} + +export type PermissionedConfidentialBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountToken extends string | AccountMeta = string, + TAccountMint extends string | AccountMeta = string, + TAccountInstructionsSysvar extends string | AccountMeta | undefined = undefined, + TAccountEqualityRecord extends string | AccountMeta | undefined = undefined, + TAccountCiphertextValidityRecord extends string | AccountMeta | undefined = undefined, + TAccountRangeRecord extends string | AccountMeta | undefined = undefined, + TAccountPermissionedBurnAuthority extends string | AccountMeta = string, + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountToken extends string ? WritableAccount : TAccountToken, + TAccountMint extends string ? WritableAccount : TAccountMint, + ...(TAccountInstructionsSysvar extends undefined + ? [] + : [ + TAccountInstructionsSysvar extends string + ? ReadonlyAccount + : TAccountInstructionsSysvar, + ]), + ...(TAccountEqualityRecord extends undefined + ? [] + : [ + TAccountEqualityRecord extends string + ? ReadonlyAccount + : TAccountEqualityRecord, + ]), + ...(TAccountCiphertextValidityRecord extends undefined + ? [] + : [ + TAccountCiphertextValidityRecord extends string + ? ReadonlyAccount + : TAccountCiphertextValidityRecord, + ]), + ...(TAccountRangeRecord extends undefined + ? [] + : [TAccountRangeRecord extends string ? ReadonlyAccount : TAccountRangeRecord]), + TAccountPermissionedBurnAuthority extends string + ? ReadonlySignerAccount & + AccountSignerMeta + : TAccountPermissionedBurnAuthority, + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type PermissionedConfidentialBurnInstructionData = { + discriminator: number; + permissionedBurnDiscriminator: number; + /** The new decryptable balance of the burner if the burn succeeds. */ + newDecryptableAvailableBalance: DecryptableBalance; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextLo: EncryptedBalance; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextHi: EncryptedBalance; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the burn instruction in the transaction. If the offset is `0`, + * then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the burn instruction in the transaction. If the offset + * is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * burn instruction in the transaction. If the offset is `0`, then use a + * context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export type PermissionedConfidentialBurnInstructionDataArgs = { + /** The new decryptable balance of the burner if the burn succeeds. */ + newDecryptableAvailableBalance: DecryptableBalanceArgs; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextLo: EncryptedBalanceArgs; + /** The burn amount encrypted under the auditor ElGamal public key. */ + burnAmountAuditorCiphertextHi: EncryptedBalanceArgs; + /** + * Relative location of the + * `ProofInstruction::VerifyCiphertextCommitmentEquality` instruction + * to the burn instruction in the transaction. If the offset is `0`, + * then use a context state account for the proof. + */ + equalityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity` + * instruction to the burn instruction in the transaction. If the offset + * is `0`, then use a context state account for the proof. + */ + ciphertextValidityProofInstructionOffset: number; + /** + * Relative location of the + * `ProofInstruction::VerifyBatchedRangeProofU128` instruction to the + * burn instruction in the transaction. If the offset is `0`, then use a + * context state account for the proof. + */ + rangeProofInstructionOffset: number; +}; + +export function getPermissionedConfidentialBurnInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['permissionedBurnDiscriminator', getU8Encoder()], + ['newDecryptableAvailableBalance', getDecryptableBalanceEncoder()], + ['burnAmountAuditorCiphertextLo', getEncryptedBalanceEncoder()], + ['burnAmountAuditorCiphertextHi', getEncryptedBalanceEncoder()], + ['equalityProofInstructionOffset', getI8Encoder()], + ['ciphertextValidityProofInstructionOffset', getI8Encoder()], + ['rangeProofInstructionOffset', getI8Encoder()], + ]), + value => ({ + ...value, + discriminator: PERMISSIONED_CONFIDENTIAL_BURN_DISCRIMINATOR, + permissionedBurnDiscriminator: PERMISSIONED_CONFIDENTIAL_BURN_PERMISSIONED_BURN_DISCRIMINATOR, + }), + ); +} + +export function getPermissionedConfidentialBurnInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['permissionedBurnDiscriminator', getU8Decoder()], + ['newDecryptableAvailableBalance', getDecryptableBalanceDecoder()], + ['burnAmountAuditorCiphertextLo', getEncryptedBalanceDecoder()], + ['burnAmountAuditorCiphertextHi', getEncryptedBalanceDecoder()], + ['equalityProofInstructionOffset', getI8Decoder()], + ['ciphertextValidityProofInstructionOffset', getI8Decoder()], + ['rangeProofInstructionOffset', getI8Decoder()], + ]); +} + +export function getPermissionedConfidentialBurnInstructionDataCodec(): FixedSizeCodec< + PermissionedConfidentialBurnInstructionDataArgs, + PermissionedConfidentialBurnInstructionData +> { + return combineCodec( + getPermissionedConfidentialBurnInstructionDataEncoder(), + getPermissionedConfidentialBurnInstructionDataDecoder(), + ); +} + +export type PermissionedConfidentialBurnInput< + TAccountToken extends string = string, + TAccountMint extends string = string, + TAccountInstructionsSysvar extends string = string, + TAccountEqualityRecord extends string = string, + TAccountCiphertextValidityRecord extends string = string, + TAccountRangeRecord extends string = string, + TAccountPermissionedBurnAuthority extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token account. */ + token: Address; + /** The SPL Token mint. */ + mint: Address; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: Address; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: Address; + /** Authority configured on the mint that must sign any permissioned burn instruction. */ + permissionedBurnAuthority: TransactionSigner; + /** The account's owner/delegate or its multisignature account. */ + authority: Address | TransactionSigner; + newDecryptableAvailableBalance: PermissionedConfidentialBurnInstructionDataArgs['newDecryptableAvailableBalance']; + burnAmountAuditorCiphertextLo: PermissionedConfidentialBurnInstructionDataArgs['burnAmountAuditorCiphertextLo']; + burnAmountAuditorCiphertextHi: PermissionedConfidentialBurnInstructionDataArgs['burnAmountAuditorCiphertextHi']; + equalityProofInstructionOffset: PermissionedConfidentialBurnInstructionDataArgs['equalityProofInstructionOffset']; + ciphertextValidityProofInstructionOffset: PermissionedConfidentialBurnInstructionDataArgs['ciphertextValidityProofInstructionOffset']; + rangeProofInstructionOffset: PermissionedConfidentialBurnInstructionDataArgs['rangeProofInstructionOffset']; + multiSigners?: Array; +}; + +export function getPermissionedConfidentialBurnInstruction< + TAccountToken extends string, + TAccountMint extends string, + TAccountInstructionsSysvar extends string, + TAccountEqualityRecord extends string, + TAccountCiphertextValidityRecord extends string, + TAccountRangeRecord extends string, + TAccountPermissionedBurnAuthority extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: PermissionedConfidentialBurnInput< + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + TAccountPermissionedBurnAuthority, + TAccountAuthority + >, + config?: { programAddress?: TProgramAddress }, +): PermissionedConfidentialBurnInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + TAccountPermissionedBurnAuthority, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // 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: true }, + instructionsSysvar: { value: input.instructionsSysvar ?? null, isWritable: false }, + equalityRecord: { value: input.equalityRecord ?? null, isWritable: false }, + ciphertextValidityRecord: { value: input.ciphertextValidityRecord ?? null, isWritable: false }, + rangeRecord: { value: input.rangeRecord ?? null, isWritable: false }, + permissionedBurnAuthority: { value: input.permissionedBurnAuthority ?? null, isWritable: false }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.token), + getAccountMeta(accounts.mint), + getAccountMeta(accounts.instructionsSysvar), + getAccountMeta(accounts.equalityRecord), + getAccountMeta(accounts.ciphertextValidityRecord), + getAccountMeta(accounts.rangeRecord), + getAccountMeta(accounts.permissionedBurnAuthority), + getAccountMeta(accounts.authority), + ...remainingAccounts, + ].filter((x: T | undefined): x is T => x !== undefined), + data: getPermissionedConfidentialBurnInstructionDataEncoder().encode( + args as PermissionedConfidentialBurnInstructionDataArgs, + ), + programAddress, + } as PermissionedConfidentialBurnInstruction< + TProgramAddress, + TAccountToken, + TAccountMint, + TAccountInstructionsSysvar, + TAccountEqualityRecord, + TAccountCiphertextValidityRecord, + TAccountRangeRecord, + TAccountPermissionedBurnAuthority, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedPermissionedConfidentialBurnInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token account. */ + token: TAccountMetas[0]; + /** The SPL Token mint. */ + mint: TAccountMetas[1]; + /** + * (Optional) Instructions sysvar if at least one of the + * `zk_elgamal_proof` instructions are included in the same + * transaction. + */ + instructionsSysvar?: TAccountMetas[2] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyCiphertextCommitmentEquality` proof. + */ + equalityRecord?: TAccountMetas[3] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedGroupedCiphertext3HandlesValidity` proof. + */ + ciphertextValidityRecord?: TAccountMetas[4] | undefined; + /** + * (Optional) The context state account containing the pre-verified + * `VerifyBatchedRangeProofU128` proof. + */ + rangeRecord?: TAccountMetas[5] | undefined; + /** Authority configured on the mint that must sign any permissioned burn instruction. */ + permissionedBurnAuthority: TAccountMetas[6]; + /** The account's owner/delegate or its multisignature account. */ + authority: TAccountMetas[7]; + }; + data: PermissionedConfidentialBurnInstructionData; +}; + +export function parsePermissionedConfidentialBurnInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedPermissionedConfidentialBurnInstruction { + if (instruction.accounts.length < 4) { + // 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 - 4; + const getNextOptionalAccount = () => { + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); + }; + return { + programAddress: instruction.programAddress, + accounts: { + token: getNextAccount(), + mint: getNextAccount(), + instructionsSysvar: getNextOptionalAccount(), + equalityRecord: getNextOptionalAccount(), + ciphertextValidityRecord: getNextOptionalAccount(), + rangeRecord: getNextOptionalAccount(), + permissionedBurnAuthority: getNextAccount(), + authority: getNextAccount(), + }, + data: getPermissionedConfidentialBurnInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/rotateSupplyElgamalPubkey.ts b/clients/js/src/generated/instructions/rotateSupplyElgamalPubkey.ts new file mode 100644 index 000000000..7b947de60 --- /dev/null +++ b/clients/js/src/generated/instructions/rotateSupplyElgamalPubkey.ts @@ -0,0 +1,268 @@ +/** + * 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 { + AccountRole, + combineCodec, + getAddressDecoder, + getAddressEncoder, + getI8Decoder, + getI8Encoder, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; + +export const ROTATE_SUPPLY_ELGAMAL_PUBKEY_DISCRIMINATOR = 42; + +export function getRotateSupplyElgamalPubkeyDiscriminatorBytes() { + return getU8Encoder().encode(ROTATE_SUPPLY_ELGAMAL_PUBKEY_DISCRIMINATOR); +} + +export const ROTATE_SUPPLY_ELGAMAL_PUBKEY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 1; + +export function getRotateSupplyElgamalPubkeyConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(ROTATE_SUPPLY_ELGAMAL_PUBKEY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type RotateSupplyElgamalPubkeyInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMint extends string | AccountMeta = string, + TAccountInstructionsSysvarOrContextState extends string | AccountMeta = + 'Sysvar1nstructions1111111111111111111111111', + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountMint extends string ? WritableAccount : TAccountMint, + TAccountInstructionsSysvarOrContextState extends string + ? ReadonlyAccount + : TAccountInstructionsSysvarOrContextState, + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type RotateSupplyElgamalPubkeyInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; + /** The new ElGamal pubkey for supply encryption. */ + newSupplyElgamalPubkey: Address; + /** + * The location of the + * `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction + * relative to the `RotateSupplyElGamalPubkey` instruction in the + * transaction. If the offset is `0`, then use a context state account + * for the proof. + */ + proofInstructionOffset: number; +}; + +export type RotateSupplyElgamalPubkeyInstructionDataArgs = { + /** The new ElGamal pubkey for supply encryption. */ + newSupplyElgamalPubkey: Address; + /** + * The location of the + * `ProofInstruction::VerifyCiphertextCiphertextEquality` instruction + * relative to the `RotateSupplyElGamalPubkey` instruction in the + * transaction. If the offset is `0`, then use a context state account + * for the proof. + */ + proofInstructionOffset: number; +}; + +export function getRotateSupplyElgamalPubkeyInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ['newSupplyElgamalPubkey', getAddressEncoder()], + ['proofInstructionOffset', getI8Encoder()], + ]), + value => ({ + ...value, + discriminator: ROTATE_SUPPLY_ELGAMAL_PUBKEY_DISCRIMINATOR, + confidentialMintBurnDiscriminator: ROTATE_SUPPLY_ELGAMAL_PUBKEY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getRotateSupplyElgamalPubkeyInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ['newSupplyElgamalPubkey', getAddressDecoder()], + ['proofInstructionOffset', getI8Decoder()], + ]); +} + +export function getRotateSupplyElgamalPubkeyInstructionDataCodec(): FixedSizeCodec< + RotateSupplyElgamalPubkeyInstructionDataArgs, + RotateSupplyElgamalPubkeyInstructionData +> { + return combineCodec( + getRotateSupplyElgamalPubkeyInstructionDataEncoder(), + getRotateSupplyElgamalPubkeyInstructionDataDecoder(), + ); +} + +export type RotateSupplyElgamalPubkeyInput< + TAccountMint extends string = string, + TAccountInstructionsSysvarOrContextState extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token mint. */ + mint: Address; + /** + * Instructions sysvar if `CiphertextCiphertextEquality` is included in + * the same transaction or context state account if + * `CiphertextCiphertextEquality` is pre-verified into a context state + * account. + */ + instructionsSysvarOrContextState?: Address; + /** The confidential mint authority or its multisignature account. */ + authority: Address | TransactionSigner; + newSupplyElgamalPubkey: RotateSupplyElgamalPubkeyInstructionDataArgs['newSupplyElgamalPubkey']; + proofInstructionOffset: RotateSupplyElgamalPubkeyInstructionDataArgs['proofInstructionOffset']; + multiSigners?: Array; +}; + +export function getRotateSupplyElgamalPubkeyInstruction< + TAccountMint extends string, + TAccountInstructionsSysvarOrContextState extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: RotateSupplyElgamalPubkeyInput, + config?: { programAddress?: TProgramAddress }, +): RotateSupplyElgamalPubkeyInstruction< + TProgramAddress, + TAccountMint, + TAccountInstructionsSysvarOrContextState, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + mint: { value: input.mint ?? null, isWritable: true }, + instructionsSysvarOrContextState: { value: input.instructionsSysvarOrContextState ?? null, isWritable: false }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Resolve default values. + if (!accounts.instructionsSysvarOrContextState.value) { + accounts.instructionsSysvarOrContextState.value = + 'Sysvar1nstructions1111111111111111111111111' as Address<'Sysvar1nstructions1111111111111111111111111'>; + } + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + return Object.freeze({ + accounts: [ + getAccountMeta(accounts.mint), + getAccountMeta(accounts.instructionsSysvarOrContextState), + getAccountMeta(accounts.authority), + ...remainingAccounts, + ], + data: getRotateSupplyElgamalPubkeyInstructionDataEncoder().encode( + args as RotateSupplyElgamalPubkeyInstructionDataArgs, + ), + programAddress, + } as RotateSupplyElgamalPubkeyInstruction< + TProgramAddress, + TAccountMint, + TAccountInstructionsSysvarOrContextState, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedRotateSupplyElgamalPubkeyInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token mint. */ + mint: TAccountMetas[0]; + /** + * Instructions sysvar if `CiphertextCiphertextEquality` is included in + * the same transaction or context state account if + * `CiphertextCiphertextEquality` is pre-verified into a context state + * account. + */ + instructionsSysvarOrContextState: TAccountMetas[1]; + /** The confidential mint authority or its multisignature account. */ + authority: TAccountMetas[2]; + }; + data: RotateSupplyElgamalPubkeyInstructionData; +}; + +export function parseRotateSupplyElgamalPubkeyInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedRotateSupplyElgamalPubkeyInstruction { + 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; + }; + return { + programAddress: instruction.programAddress, + accounts: { + mint: getNextAccount(), + instructionsSysvarOrContextState: getNextAccount(), + authority: getNextAccount(), + }, + data: getRotateSupplyElgamalPubkeyInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/syncNative.ts b/clients/js/src/generated/instructions/syncNative.ts index 2a81134d9..3bbe41230 100644 --- a/clients/js/src/generated/instructions/syncNative.ts +++ b/clients/js/src/generated/instructions/syncNative.ts @@ -21,6 +21,7 @@ import { type Instruction, type InstructionWithAccounts, type InstructionWithData, + type ReadonlyAccount, type ReadonlyUint8Array, type WritableAccount, } from '@solana/kit'; @@ -36,11 +37,18 @@ export function getSyncNativeDiscriminatorBytes() { export type SyncNativeInstruction< TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, TAccountAccount extends string | AccountMeta = string, + TAccountRent extends string | AccountMeta | undefined = undefined, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & InstructionWithData & InstructionWithAccounts< - [TAccountAccount extends string ? WritableAccount : TAccountAccount, ...TRemainingAccounts] + [ + TAccountAccount extends string ? WritableAccount : TAccountAccount, + ...(TAccountRent extends undefined + ? [] + : [TAccountRent extends string ? ReadonlyAccount : TAccountRent]), + ...TRemainingAccounts, + ] >; export type SyncNativeInstructionData = { discriminator: number }; @@ -65,31 +73,45 @@ export function getSyncNativeInstructionDataCodec(): FixedSizeCodec< return combineCodec(getSyncNativeInstructionDataEncoder(), getSyncNativeInstructionDataDecoder()); } -export type SyncNativeInput = { +export type SyncNativeInput = { /** The native token account to sync with its underlying lamports. */ account: Address; + /** Rent sysvar. */ + rent?: Address; }; export function getSyncNativeInstruction< TAccountAccount extends string, + TAccountRent extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( - input: SyncNativeInput, + input: SyncNativeInput, config?: { programAddress?: TProgramAddress }, -): SyncNativeInstruction { +): SyncNativeInstruction { // Program address. const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; // Original accounts. - const originalAccounts = { account: { value: input.account ?? null, isWritable: true } }; + const originalAccounts = { + account: { value: input.account ?? null, isWritable: true }, + rent: { value: input.rent ?? null, isWritable: false }, + }; const accounts = originalAccounts as Record; - const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + // Resolve default values. + if (!accounts.rent.value) { + accounts.rent.value = + 'SysvarRent111111111111111111111111111111111' as Address<'SysvarRent111111111111111111111111111111111'>; + } + + const getAccountMeta = getAccountMetaFactory(programAddress, 'omitted'); return Object.freeze({ - accounts: [getAccountMeta(accounts.account)], + accounts: [getAccountMeta(accounts.account), getAccountMeta(accounts.rent)].filter( + (x: T | undefined): x is T => x !== undefined, + ), data: getSyncNativeInstructionDataEncoder().encode({}), programAddress, - } as SyncNativeInstruction); + } as SyncNativeInstruction); } export type ParsedSyncNativeInstruction< @@ -100,6 +122,8 @@ export type ParsedSyncNativeInstruction< accounts: { /** The native token account to sync with its underlying lamports. */ account: TAccountMetas[0]; + /** Rent sysvar. */ + rent?: TAccountMetas[1] | undefined; }; data: SyncNativeInstructionData; }; @@ -119,9 +143,15 @@ export function parseSyncNativeInstruction { + if (optionalAccountsRemaining === 0) return undefined; + optionalAccountsRemaining -= 1; + return getNextAccount(); + }; return { programAddress: instruction.programAddress, - accounts: { account: getNextAccount() }, + accounts: { account: getNextAccount(), rent: getNextOptionalAccount() }, data: getSyncNativeInstructionDataDecoder().decode(instruction.data), }; } diff --git a/clients/js/src/generated/instructions/updateConfidentialMintBurnDecryptableSupply.ts b/clients/js/src/generated/instructions/updateConfidentialMintBurnDecryptableSupply.ts new file mode 100644 index 000000000..89b0b4f74 --- /dev/null +++ b/clients/js/src/generated/instructions/updateConfidentialMintBurnDecryptableSupply.ts @@ -0,0 +1,213 @@ +/** + * 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 { + AccountRole, + 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 ReadonlySignerAccount, + type ReadonlyUint8Array, + type TransactionSigner, + type WritableAccount, +} from '@solana/kit'; +import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs'; +import { getAccountMetaFactory, type ResolvedAccount } from '../shared'; +import { + getDecryptableBalanceDecoder, + getDecryptableBalanceEncoder, + type DecryptableBalance, + type DecryptableBalanceArgs, +} from '../types'; + +export const UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_DISCRIMINATOR = 42; + +export function getUpdateConfidentialMintBurnDecryptableSupplyDiscriminatorBytes() { + return getU8Encoder().encode(UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_DISCRIMINATOR); +} + +export const UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR = 2; + +export function getUpdateConfidentialMintBurnDecryptableSupplyConfidentialMintBurnDiscriminatorBytes() { + return getU8Encoder().encode(UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR); +} + +export type UpdateConfidentialMintBurnDecryptableSupplyInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMint extends string | AccountMeta = string, + TAccountAuthority extends string | AccountMeta = string, + TRemainingAccounts extends readonly AccountMeta[] = [], +> = Instruction & + InstructionWithData & + InstructionWithAccounts< + [ + TAccountMint extends string ? WritableAccount : TAccountMint, + TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, + ...TRemainingAccounts, + ] + >; + +export type UpdateConfidentialMintBurnDecryptableSupplyInstructionData = { + discriminator: number; + confidentialMintBurnDiscriminator: number; + /** The new decryptable supply. */ + newDecryptableSupply: DecryptableBalance; +}; + +export type UpdateConfidentialMintBurnDecryptableSupplyInstructionDataArgs = { + /** The new decryptable supply. */ + newDecryptableSupply: DecryptableBalanceArgs; +}; + +export function getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataEncoder(): FixedSizeEncoder { + return transformEncoder( + getStructEncoder([ + ['discriminator', getU8Encoder()], + ['confidentialMintBurnDiscriminator', getU8Encoder()], + ['newDecryptableSupply', getDecryptableBalanceEncoder()], + ]), + value => ({ + ...value, + discriminator: UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_DISCRIMINATOR, + confidentialMintBurnDiscriminator: + UPDATE_CONFIDENTIAL_MINT_BURN_DECRYPTABLE_SUPPLY_CONFIDENTIAL_MINT_BURN_DISCRIMINATOR, + }), + ); +} + +export function getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataDecoder(): FixedSizeDecoder { + return getStructDecoder([ + ['discriminator', getU8Decoder()], + ['confidentialMintBurnDiscriminator', getU8Decoder()], + ['newDecryptableSupply', getDecryptableBalanceDecoder()], + ]); +} + +export function getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataCodec(): FixedSizeCodec< + UpdateConfidentialMintBurnDecryptableSupplyInstructionDataArgs, + UpdateConfidentialMintBurnDecryptableSupplyInstructionData +> { + return combineCodec( + getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataEncoder(), + getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataDecoder(), + ); +} + +export type UpdateConfidentialMintBurnDecryptableSupplyInput< + TAccountMint extends string = string, + TAccountAuthority extends string = string, +> = { + /** The SPL Token mint. */ + mint: Address; + /** The confidential mint authority or its multisignature account. */ + authority: Address | TransactionSigner; + newDecryptableSupply: UpdateConfidentialMintBurnDecryptableSupplyInstructionDataArgs['newDecryptableSupply']; + multiSigners?: Array; +}; + +export function getUpdateConfidentialMintBurnDecryptableSupplyInstruction< + TAccountMint extends string, + TAccountAuthority extends string, + TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, +>( + input: UpdateConfidentialMintBurnDecryptableSupplyInput, + config?: { programAddress?: TProgramAddress }, +): UpdateConfidentialMintBurnDecryptableSupplyInstruction< + TProgramAddress, + TAccountMint, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority +> { + // Program address. + const programAddress = config?.programAddress ?? TOKEN_2022_PROGRAM_ADDRESS; + + // Original accounts. + const originalAccounts = { + mint: { value: input.mint ?? null, isWritable: true }, + authority: { value: input.authority ?? null, isWritable: false }, + }; + const accounts = originalAccounts as Record; + + // Original args. + const args = { ...input }; + + // Remaining accounts. + const remainingAccounts: AccountMeta[] = (args.multiSigners ?? []).map(signer => ({ + address: signer.address, + role: AccountRole.READONLY_SIGNER, + signer, + })); + + const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); + return Object.freeze({ + accounts: [getAccountMeta(accounts.mint), getAccountMeta(accounts.authority), ...remainingAccounts], + data: getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataEncoder().encode( + args as UpdateConfidentialMintBurnDecryptableSupplyInstructionDataArgs, + ), + programAddress, + } as UpdateConfidentialMintBurnDecryptableSupplyInstruction< + TProgramAddress, + TAccountMint, + (typeof input)['authority'] extends TransactionSigner + ? ReadonlySignerAccount & AccountSignerMeta + : TAccountAuthority + >); +} + +export type ParsedUpdateConfidentialMintBurnDecryptableSupplyInstruction< + TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, + TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], +> = { + programAddress: Address; + accounts: { + /** The SPL Token mint. */ + mint: TAccountMetas[0]; + /** The confidential mint authority or its multisignature account. */ + authority: TAccountMetas[1]; + }; + data: UpdateConfidentialMintBurnDecryptableSupplyInstructionData; +}; + +export function parseUpdateConfidentialMintBurnDecryptableSupplyInstruction< + TProgram extends string, + TAccountMetas extends readonly AccountMeta[], +>( + instruction: Instruction & + InstructionWithAccounts & + InstructionWithData, +): ParsedUpdateConfidentialMintBurnDecryptableSupplyInstruction { + if (instruction.accounts.length < 2) { + // 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; + }; + return { + programAddress: instruction.programAddress, + accounts: { mint: getNextAccount(), authority: getNextAccount() }, + data: getUpdateConfidentialMintBurnDecryptableSupplyInstructionDataDecoder().decode(instruction.data), + }; +} diff --git a/clients/js/src/generated/instructions/withdrawExcessLamports.ts b/clients/js/src/generated/instructions/withdrawExcessLamports.ts index 5df9b582c..1cefaa286 100644 --- a/clients/js/src/generated/instructions/withdrawExcessLamports.ts +++ b/clients/js/src/generated/instructions/withdrawExcessLamports.ts @@ -40,18 +40,16 @@ export function getWithdrawExcessLamportsDiscriminatorBytes() { export type WithdrawExcessLamportsInstruction< TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS, - TAccountSourceAccount extends string | AccountMeta = string, - TAccountDestinationAccount extends string | AccountMeta = string, + TAccountSource extends string | AccountMeta = string, + TAccountDestination extends string | AccountMeta = string, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & InstructionWithData & InstructionWithAccounts< [ - TAccountSourceAccount extends string ? WritableAccount : TAccountSourceAccount, - TAccountDestinationAccount extends string - ? WritableAccount - : TAccountDestinationAccount, + TAccountSource extends string ? WritableAccount : TAccountSource, + TAccountDestination extends string ? WritableAccount : TAccountDestination, TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -83,31 +81,31 @@ export function getWithdrawExcessLamportsInstructionDataCodec(): FixedSizeCodec< } export type WithdrawExcessLamportsInput< - TAccountSourceAccount extends string = string, - TAccountDestinationAccount extends string = string, + TAccountSource extends string = string, + TAccountDestination extends string = string, TAccountAuthority extends string = string, > = { - /** Account holding excess lamports. */ - sourceAccount: Address; - /** Destination account for withdrawn lamports. */ - destinationAccount: Address; - /** The source account's owner/delegate or its multisignature account. */ + /** The source account. */ + source: Address; + /** The destination account. */ + destination: Address; + /** The source account owner or its multisignature account. */ authority: Address | TransactionSigner; multiSigners?: Array; }; export function getWithdrawExcessLamportsInstruction< - TAccountSourceAccount extends string, - TAccountDestinationAccount extends string, + TAccountSource extends string, + TAccountDestination extends string, TAccountAuthority extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( - input: WithdrawExcessLamportsInput, + input: WithdrawExcessLamportsInput, config?: { programAddress?: TProgramAddress }, ): WithdrawExcessLamportsInstruction< TProgramAddress, - TAccountSourceAccount, - TAccountDestinationAccount, + TAccountSource, + TAccountDestination, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -117,8 +115,8 @@ export function getWithdrawExcessLamportsInstruction< // Original accounts. const originalAccounts = { - sourceAccount: { value: input.sourceAccount ?? null, isWritable: true }, - destinationAccount: { value: input.destinationAccount ?? null, isWritable: true }, + source: { value: input.source ?? null, isWritable: true }, + destination: { value: input.destination ?? null, isWritable: true }, authority: { value: input.authority ?? null, isWritable: false }, }; const accounts = originalAccounts as Record; @@ -136,8 +134,8 @@ export function getWithdrawExcessLamportsInstruction< const getAccountMeta = getAccountMetaFactory(programAddress, 'programId'); return Object.freeze({ accounts: [ - getAccountMeta(accounts.sourceAccount), - getAccountMeta(accounts.destinationAccount), + getAccountMeta(accounts.source), + getAccountMeta(accounts.destination), getAccountMeta(accounts.authority), ...remainingAccounts, ], @@ -145,8 +143,8 @@ export function getWithdrawExcessLamportsInstruction< programAddress, } as WithdrawExcessLamportsInstruction< TProgramAddress, - TAccountSourceAccount, - TAccountDestinationAccount, + TAccountSource, + TAccountDestination, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -159,11 +157,11 @@ export type ParsedWithdrawExcessLamportsInstruction< > = { programAddress: Address; accounts: { - /** Account holding excess lamports. */ - sourceAccount: TAccountMetas[0]; - /** Destination account for withdrawn lamports. */ - destinationAccount: TAccountMetas[1]; - /** The source account's owner/delegate or its multisignature account. */ + /** The source account. */ + source: TAccountMetas[0]; + /** The destination account. */ + destination: TAccountMetas[1]; + /** The source account owner or its multisignature account. */ authority: TAccountMetas[2]; }; data: WithdrawExcessLamportsInstructionData; @@ -189,11 +187,7 @@ export function parseWithdrawExcessLamportsInstruction< }; return { programAddress: instruction.programAddress, - accounts: { - sourceAccount: getNextAccount(), - destinationAccount: getNextAccount(), - authority: getNextAccount(), - }, + accounts: { source: getNextAccount(), destination: getNextAccount(), authority: getNextAccount() }, data: getWithdrawExcessLamportsInstructionDataDecoder().decode(instruction.data), }; } diff --git a/clients/js/src/generated/instructions/withdrawWithheldTokensFromAccountsForConfidentialTransferFee.ts b/clients/js/src/generated/instructions/withdrawWithheldTokensFromAccountsForConfidentialTransferFee.ts index 74c667a0d..ab2e5357b 100644 --- a/clients/js/src/generated/instructions/withdrawWithheldTokensFromAccountsForConfidentialTransferFee.ts +++ b/clients/js/src/generated/instructions/withdrawWithheldTokensFromAccountsForConfidentialTransferFee.ts @@ -59,7 +59,6 @@ export type WithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstruct TAccountMint extends string | AccountMeta = string, TAccountDestination extends string | AccountMeta = string, TAccountInstructionsSysvarOrContextState extends string | AccountMeta = string, - TAccountRecord extends string | AccountMeta = string, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -71,7 +70,6 @@ export type WithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstruct TAccountInstructionsSysvarOrContextState extends string ? ReadonlyAccount : TAccountInstructionsSysvarOrContextState, - TAccountRecord extends string ? ReadonlyAccount : TAccountRecord, TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -139,17 +137,19 @@ export type WithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInput< TAccountMint extends string = string, TAccountDestination extends string = string, TAccountInstructionsSysvarOrContextState extends string = string, - TAccountRecord extends string = string, TAccountAuthority extends string = string, > = { /** The token mint. */ mint: Address; /** The fee receiver account. */ destination: Address; - /** Instructions sysvar or context state account */ + /** + * Instructions sysvar if `VerifyCiphertextCiphertextEquality` is + * included in the same transaction or context state account if + * `VerifyCiphertextCiphertextEquality` is pre-verified into a context + * state account. + */ instructionsSysvarOrContextState: Address; - /** Optional record account */ - record?: Address; /** The mint's withdraw_withheld_authority */ authority: Address | TransactionSigner; numTokenAccounts: WithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstructionDataArgs['numTokenAccounts']; @@ -162,7 +162,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI TAccountMint extends string, TAccountDestination extends string, TAccountInstructionsSysvarOrContextState extends string, - TAccountRecord extends string, TAccountAuthority extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( @@ -170,7 +169,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, TAccountAuthority >, config?: { programAddress?: TProgramAddress }, @@ -179,7 +177,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -192,7 +189,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI mint: { value: input.mint ?? null, isWritable: false }, destination: { value: input.destination ?? null, isWritable: true }, 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; @@ -213,7 +209,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI getAccountMeta(accounts.mint), getAccountMeta(accounts.destination), getAccountMeta(accounts.instructionsSysvarOrContextState), - getAccountMeta(accounts.record), getAccountMeta(accounts.authority), ...remainingAccounts, ], @@ -226,7 +221,6 @@ export function getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeI TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -243,12 +237,15 @@ export type ParsedWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeIn mint: TAccountMetas[0]; /** The fee receiver account. */ destination: TAccountMetas[1]; - /** Instructions sysvar or context state account */ + /** + * Instructions sysvar if `VerifyCiphertextCiphertextEquality` is + * included in the same transaction or context state account if + * `VerifyCiphertextCiphertextEquality` is pre-verified into a context + * state account. + */ instructionsSysvarOrContextState: TAccountMetas[2]; - /** Optional record account */ - record?: TAccountMetas[3] | undefined; /** The mint's withdraw_withheld_authority */ - authority: TAccountMetas[4]; + authority: TAccountMetas[3]; }; data: WithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstructionData; }; @@ -261,7 +258,7 @@ export function parseWithdrawWithheldTokensFromAccountsForConfidentialTransferFe InstructionWithAccounts & InstructionWithData, ): ParsedWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstruction { - if (instruction.accounts.length < 5) { + if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -271,17 +268,12 @@ export function parseWithdrawWithheldTokensFromAccountsForConfidentialTransferFe accountIndex += 1; return accountMeta; }; - const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; - }; return { programAddress: instruction.programAddress, accounts: { mint: getNextAccount(), destination: getNextAccount(), instructionsSysvarOrContextState: getNextAccount(), - record: getNextOptionalAccount(), authority: getNextAccount(), }, data: getWithdrawWithheldTokensFromAccountsForConfidentialTransferFeeInstructionDataDecoder().decode( diff --git a/clients/js/src/generated/instructions/withdrawWithheldTokensFromMintForConfidentialTransferFee.ts b/clients/js/src/generated/instructions/withdrawWithheldTokensFromMintForConfidentialTransferFee.ts index 069b841ba..7ab0206a6 100644 --- a/clients/js/src/generated/instructions/withdrawWithheldTokensFromMintForConfidentialTransferFee.ts +++ b/clients/js/src/generated/instructions/withdrawWithheldTokensFromMintForConfidentialTransferFee.ts @@ -59,7 +59,6 @@ export type WithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction< TAccountMint extends string | AccountMeta = string, TAccountDestination extends string | AccountMeta = string, TAccountInstructionsSysvarOrContextState extends string | AccountMeta = string, - TAccountRecord extends string | AccountMeta = string, TAccountAuthority extends string | AccountMeta = string, TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & @@ -71,7 +70,6 @@ export type WithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction< TAccountInstructionsSysvarOrContextState extends string ? ReadonlyAccount : TAccountInstructionsSysvarOrContextState, - TAccountRecord extends string ? ReadonlyAccount : TAccountRecord, TAccountAuthority extends string ? ReadonlyAccount : TAccountAuthority, ...TRemainingAccounts, ] @@ -133,17 +131,19 @@ export type WithdrawWithheldTokensFromMintForConfidentialTransferFeeInput< TAccountMint extends string = string, TAccountDestination extends string = string, TAccountInstructionsSysvarOrContextState extends string = string, - TAccountRecord extends string = string, TAccountAuthority extends string = string, > = { /** The token mint. */ mint: Address; /** The fee receiver account. */ destination: Address; - /** Instructions sysvar or context state account */ + /** + * Instructions sysvar if `VerifyCiphertextCiphertextEquality` is + * included in the same transaction or context state account if + * `VerifyCiphertextCiphertextEquality` is pre-verified into a context + * state account. + */ instructionsSysvarOrContextState: Address; - /** Optional record account if proof is read from record */ - record?: Address; /** The mint's withdraw_withheld_authority */ authority: Address | TransactionSigner; proofInstructionOffset: WithdrawWithheldTokensFromMintForConfidentialTransferFeeInstructionDataArgs['proofInstructionOffset']; @@ -155,7 +155,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr TAccountMint extends string, TAccountDestination extends string, TAccountInstructionsSysvarOrContextState extends string, - TAccountRecord extends string, TAccountAuthority extends string, TProgramAddress extends Address = typeof TOKEN_2022_PROGRAM_ADDRESS, >( @@ -163,7 +162,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, TAccountAuthority >, config?: { programAddress?: TProgramAddress }, @@ -172,7 +170,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -185,7 +182,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr mint: { value: input.mint ?? null, isWritable: true }, destination: { value: input.destination ?? null, isWritable: true }, 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; @@ -206,7 +202,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr getAccountMeta(accounts.mint), getAccountMeta(accounts.destination), getAccountMeta(accounts.instructionsSysvarOrContextState), - getAccountMeta(accounts.record), getAccountMeta(accounts.authority), ...remainingAccounts, ], @@ -219,7 +214,6 @@ export function getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstr TAccountMint, TAccountDestination, TAccountInstructionsSysvarOrContextState, - TAccountRecord, (typeof input)['authority'] extends TransactionSigner ? ReadonlySignerAccount & AccountSignerMeta : TAccountAuthority @@ -236,12 +230,15 @@ export type ParsedWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstru mint: TAccountMetas[0]; /** The fee receiver account. */ destination: TAccountMetas[1]; - /** Instructions sysvar or context state account */ + /** + * Instructions sysvar if `VerifyCiphertextCiphertextEquality` is + * included in the same transaction or context state account if + * `VerifyCiphertextCiphertextEquality` is pre-verified into a context + * state account. + */ instructionsSysvarOrContextState: TAccountMetas[2]; - /** Optional record account if proof is read from record */ - record?: TAccountMetas[3] | undefined; /** The mint's withdraw_withheld_authority */ - authority: TAccountMetas[4]; + authority: TAccountMetas[3]; }; data: WithdrawWithheldTokensFromMintForConfidentialTransferFeeInstructionData; }; @@ -254,7 +251,7 @@ export function parseWithdrawWithheldTokensFromMintForConfidentialTransferFeeIns InstructionWithAccounts & InstructionWithData, ): ParsedWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstruction { - if (instruction.accounts.length < 5) { + if (instruction.accounts.length < 4) { // TODO: Coded error. throw new Error('Not enough accounts'); } @@ -264,17 +261,12 @@ export function parseWithdrawWithheldTokensFromMintForConfidentialTransferFeeIns accountIndex += 1; return accountMeta; }; - const getNextOptionalAccount = () => { - const accountMeta = getNextAccount(); - return accountMeta.address === TOKEN_2022_PROGRAM_ADDRESS ? undefined : accountMeta; - }; return { programAddress: instruction.programAddress, accounts: { mint: getNextAccount(), destination: getNextAccount(), instructionsSysvarOrContextState: getNextAccount(), - record: getNextOptionalAccount(), authority: getNextAccount(), }, data: getWithdrawWithheldTokensFromMintForConfidentialTransferFeeInstructionDataDecoder().decode( diff --git a/clients/js/src/generated/programs/token2022.ts b/clients/js/src/generated/programs/token2022.ts index 4baebcfe1..31947ce1f 100644 --- a/clients/js/src/generated/programs/token2022.ts +++ b/clients/js/src/generated/programs/token2022.ts @@ -18,17 +18,22 @@ import { import { parseAmountToUiAmountInstruction, parseApplyConfidentialPendingBalanceInstruction, + parseApplyConfidentialPendingBurnInstruction, parseApproveCheckedInstruction, parseApproveConfidentialTransferAccountInstruction, parseApproveInstruction, + parseBatchInstruction, parseBurnCheckedInstruction, parseBurnInstruction, parseCloseAccountInstruction, + parseConfidentialBurnInstruction, parseConfidentialDepositInstruction, + parseConfidentialMintInstruction, parseConfidentialTransferInstruction, parseConfidentialTransferWithFeeInstruction, parseConfidentialWithdrawInstruction, parseConfigureConfidentialTransferAccountInstruction, + parseConfigureConfidentialTransferAccountWithRegistryInstruction, parseCreateNativeMintInstruction, parseDisableConfidentialCreditsInstruction, parseDisableCpiGuardInstruction, @@ -49,6 +54,7 @@ import { parseInitializeAccount2Instruction, parseInitializeAccount3Instruction, parseInitializeAccountInstruction, + parseInitializeConfidentialMintBurnInstruction, parseInitializeConfidentialTransferFeeInstruction, parseInitializeConfidentialTransferMintInstruction, parseInitializeDefaultAccountStateInstruction, @@ -77,10 +83,12 @@ import { parsePauseInstruction, parsePermissionedBurnCheckedInstruction, parsePermissionedBurnInstruction, + parsePermissionedConfidentialBurnInstruction, parseReallocateInstruction, parseRemoveTokenMetadataKeyInstruction, parseResumeInstruction, parseRevokeInstruction, + parseRotateSupplyElgamalPubkeyInstruction, parseSetAuthorityInstruction, parseSetTransferFeeInstruction, parseSyncNativeInstruction, @@ -90,6 +98,7 @@ import { parseTransferInstruction, parseUiAmountToAmountInstruction, parseUnwrapLamportsInstruction, + parseUpdateConfidentialMintBurnDecryptableSupplyInstruction, parseUpdateConfidentialTransferMintInstruction, parseUpdateDefaultAccountStateInstruction, parseUpdateGroupMemberPointerInstruction, @@ -109,17 +118,22 @@ import { parseWithdrawWithheldTokensFromMintInstruction, type ParsedAmountToUiAmountInstruction, type ParsedApplyConfidentialPendingBalanceInstruction, + type ParsedApplyConfidentialPendingBurnInstruction, type ParsedApproveCheckedInstruction, type ParsedApproveConfidentialTransferAccountInstruction, type ParsedApproveInstruction, + type ParsedBatchInstruction, type ParsedBurnCheckedInstruction, type ParsedBurnInstruction, type ParsedCloseAccountInstruction, + type ParsedConfidentialBurnInstruction, type ParsedConfidentialDepositInstruction, + type ParsedConfidentialMintInstruction, type ParsedConfidentialTransferInstruction, type ParsedConfidentialTransferWithFeeInstruction, type ParsedConfidentialWithdrawInstruction, type ParsedConfigureConfidentialTransferAccountInstruction, + type ParsedConfigureConfidentialTransferAccountWithRegistryInstruction, type ParsedCreateNativeMintInstruction, type ParsedDisableConfidentialCreditsInstruction, type ParsedDisableCpiGuardInstruction, @@ -140,6 +154,7 @@ import { type ParsedInitializeAccount2Instruction, type ParsedInitializeAccount3Instruction, type ParsedInitializeAccountInstruction, + type ParsedInitializeConfidentialMintBurnInstruction, type ParsedInitializeConfidentialTransferFeeInstruction, type ParsedInitializeConfidentialTransferMintInstruction, type ParsedInitializeDefaultAccountStateInstruction, @@ -168,10 +183,12 @@ import { type ParsedPauseInstruction, type ParsedPermissionedBurnCheckedInstruction, type ParsedPermissionedBurnInstruction, + type ParsedPermissionedConfidentialBurnInstruction, type ParsedReallocateInstruction, type ParsedRemoveTokenMetadataKeyInstruction, type ParsedResumeInstruction, type ParsedRevokeInstruction, + type ParsedRotateSupplyElgamalPubkeyInstruction, type ParsedSetAuthorityInstruction, type ParsedSetTransferFeeInstruction, type ParsedSyncNativeInstruction, @@ -181,6 +198,7 @@ import { type ParsedTransferInstruction, type ParsedUiAmountToAmountInstruction, type ParsedUnwrapLamportsInstruction, + type ParsedUpdateConfidentialMintBurnDecryptableSupplyInstruction, type ParsedUpdateConfidentialTransferMintInstruction, type ParsedUpdateDefaultAccountStateInstruction, type ParsedUpdateGroupMemberPointerInstruction, @@ -270,6 +288,7 @@ export enum Token2022Instruction { EnableNonConfidentialCredits, DisableNonConfidentialCredits, ConfidentialTransferWithFee, + ConfigureConfidentialTransferAccountWithRegistry, InitializeDefaultAccountState, UpdateDefaultAccountState, Reallocate, @@ -297,6 +316,12 @@ export enum Token2022Instruction { UpdateGroupPointer, InitializeGroupMemberPointer, UpdateGroupMemberPointer, + InitializeConfidentialMintBurn, + RotateSupplyElgamalPubkey, + UpdateConfidentialMintBurnDecryptableSupply, + ConfidentialMint, + ConfidentialBurn, + ApplyConfidentialPendingBurn, InitializeScaledUiAmountMint, UpdateMultiplierScaledUiMint, InitializePausableConfig, @@ -315,6 +340,8 @@ export enum Token2022Instruction { InitializePermissionedBurn, PermissionedBurn, PermissionedBurnChecked, + PermissionedConfidentialBurn, + Batch, } export function identifyToken2022Instruction( @@ -459,6 +486,9 @@ export function identifyToken2022Instruction( if (containsBytes(data, getU8Encoder().encode(27), 0) && containsBytes(data, getU8Encoder().encode(13), 1)) { return Token2022Instruction.ConfidentialTransferWithFee; } + if (containsBytes(data, getU8Encoder().encode(27), 0) && containsBytes(data, getU8Encoder().encode(14), 1)) { + return Token2022Instruction.ConfigureConfidentialTransferAccountWithRegistry; + } if (containsBytes(data, getU8Encoder().encode(28), 0) && containsBytes(data, getU8Encoder().encode(0), 1)) { return Token2022Instruction.InitializeDefaultAccountState; } @@ -540,6 +570,24 @@ export function identifyToken2022Instruction( if (containsBytes(data, getU8Encoder().encode(41), 0) && containsBytes(data, getU8Encoder().encode(1), 1)) { return Token2022Instruction.UpdateGroupMemberPointer; } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(0), 1)) { + return Token2022Instruction.InitializeConfidentialMintBurn; + } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(1), 1)) { + return Token2022Instruction.RotateSupplyElgamalPubkey; + } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(2), 1)) { + return Token2022Instruction.UpdateConfidentialMintBurnDecryptableSupply; + } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(3), 1)) { + return Token2022Instruction.ConfidentialMint; + } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(4), 1)) { + return Token2022Instruction.ConfidentialBurn; + } + if (containsBytes(data, getU8Encoder().encode(42), 0) && containsBytes(data, getU8Encoder().encode(5), 1)) { + return Token2022Instruction.ApplyConfidentialPendingBurn; + } if (containsBytes(data, getU8Encoder().encode(43), 0) && containsBytes(data, getU8Encoder().encode(0), 1)) { return Token2022Instruction.InitializeScaledUiAmountMint; } @@ -594,6 +642,12 @@ export function identifyToken2022Instruction( if (containsBytes(data, getU8Encoder().encode(46), 0) && containsBytes(data, getU8Encoder().encode(2), 1)) { return Token2022Instruction.PermissionedBurnChecked; } + if (containsBytes(data, getU8Encoder().encode(46), 0) && containsBytes(data, getU8Encoder().encode(3), 1)) { + return Token2022Instruction.PermissionedConfidentialBurn; + } + if (containsBytes(data, getU8Encoder().encode(255), 0)) { + return Token2022Instruction.Batch; + } throw new Error('The provided instruction could not be identified as a token-2022 instruction.'); } @@ -680,6 +734,9 @@ export type ParsedToken2022Instruction) + | ({ + instructionType: Token2022Instruction.InitializeConfidentialMintBurn; + } & ParsedInitializeConfidentialMintBurnInstruction) + | ({ + instructionType: Token2022Instruction.RotateSupplyElgamalPubkey; + } & ParsedRotateSupplyElgamalPubkeyInstruction) + | ({ + instructionType: Token2022Instruction.UpdateConfidentialMintBurnDecryptableSupply; + } & ParsedUpdateConfidentialMintBurnDecryptableSupplyInstruction) + | ({ instructionType: Token2022Instruction.ConfidentialMint } & ParsedConfidentialMintInstruction) + | ({ instructionType: Token2022Instruction.ConfidentialBurn } & ParsedConfidentialBurnInstruction) + | ({ + instructionType: Token2022Instruction.ApplyConfidentialPendingBurn; + } & ParsedApplyConfidentialPendingBurnInstruction) | ({ instructionType: Token2022Instruction.InitializeScaledUiAmountMint; } & ParsedInitializeScaledUiAmountMintInstruction) @@ -782,7 +853,11 @@ export type ParsedToken2022Instruction { getU16Encoder(), ), ], - ['ConfidentialMintBurn', addEncoderSizePrefix(getStructEncoder([]), getU16Encoder())], + [ + 'ConfidentialMintBurn', + addEncoderSizePrefix( + getStructEncoder([ + ['confidentialSupply', getEncryptedBalanceEncoder()], + ['decryptableSupply', getDecryptableBalanceEncoder()], + ['supplyElgamalPubkey', getAddressEncoder()], + ['pendingBurn', getEncryptedBalanceEncoder()], + ]), + getU16Encoder(), + ), + ], [ 'ScaledUiAmountConfig', addEncoderSizePrefix( @@ -950,7 +981,18 @@ export function getExtensionDecoder(): Decoder { getU16Decoder(), ), ], - ['ConfidentialMintBurn', addDecoderSizePrefix(getStructDecoder([]), getU16Decoder())], + [ + 'ConfidentialMintBurn', + addDecoderSizePrefix( + getStructDecoder([ + ['confidentialSupply', getEncryptedBalanceDecoder()], + ['decryptableSupply', getDecryptableBalanceDecoder()], + ['supplyElgamalPubkey', getAddressDecoder()], + ['pendingBurn', getEncryptedBalanceDecoder()], + ]), + getU16Decoder(), + ), + ], [ 'ScaledUiAmountConfig', addDecoderSizePrefix( diff --git a/clients/js/src/generated/types/extensionType.ts b/clients/js/src/generated/types/extensionType.ts index ef490d422..a5ef0632c 100644 --- a/clients/js/src/generated/types/extensionType.ts +++ b/clients/js/src/generated/types/extensionType.ts @@ -41,15 +41,17 @@ export enum ExtensionType { TransferHookAccount, ConfidentialTransferFee, ConfidentialTransferFeeAmount, - ScaledUiAmountConfig, - PausableConfig, - PausableAccount, MetadataPointer, TokenMetadata, GroupPointer, TokenGroup, GroupMemberPointer, TokenGroupMember, + ConfidentialMintBurn, + ScaledUiAmountConfig, + PausableConfig, + PausableAccount, + PermissionedBurn, } export type ExtensionTypeArgs = ExtensionType; diff --git a/clients/js/src/getInitializeInstructionsForExtensions.ts b/clients/js/src/getInitializeInstructionsForExtensions.ts index ff8d6806e..65e32e4bf 100644 --- a/clients/js/src/getInitializeInstructionsForExtensions.ts +++ b/clients/js/src/getInitializeInstructionsForExtensions.ts @@ -5,6 +5,7 @@ import { getEnableMemoTransfersInstruction, getEnableCpiGuardInstruction, getDisableCpiGuardInstruction, + getInitializeConfidentialMintBurnInstruction, getInitializeConfidentialTransferMintInstruction, getInitializeDefaultAccountStateInstruction, getInitializeGroupMemberPointerInstruction, @@ -42,6 +43,14 @@ export function getPreInitializeInstructionsForMintExtensions( ...extension, }), ]; + case 'ConfidentialMintBurn': + return [ + getInitializeConfidentialMintBurnInstruction({ + mint, + supplyElgamalPubkey: extension.supplyElgamalPubkey, + decryptableSupply: extension.decryptableSupply, + }), + ]; case 'DefaultAccountState': return [ getInitializeDefaultAccountStateInstruction({ diff --git a/clients/js/test/extensions/confidentialMintBurn/initializeConfidentialMintBurn.test.ts b/clients/js/test/extensions/confidentialMintBurn/initializeConfidentialMintBurn.test.ts new file mode 100644 index 000000000..edee0bb51 --- /dev/null +++ b/clients/js/test/extensions/confidentialMintBurn/initializeConfidentialMintBurn.test.ts @@ -0,0 +1,78 @@ +import { Account, address, generateKeyPairSigner, some } from '@solana/kit'; +import test from 'ava'; +import { + Mint, + extension, + fetchMint, + getInitializeConfidentialMintBurnInstruction, + getInitializeConfidentialTransferMintInstruction, +} from '../../../src'; +import { + createDefaultSolanaClient, + generateKeyPairSignerWithSol, + getCreateMintInstructions, + sendAndConfirmInstructions, +} from '../../_setup'; + +test('it initializes a mint with confidential mint burn', async t => { + // Given an authority and a mint account. + const client = createDefaultSolanaClient(); + const [authority, mint] = await Promise.all([generateKeyPairSignerWithSol(client), generateKeyPairSigner()]); + + // And a confidential transfer extension, which is required by the + // confidential mint burn extension. + const confidentialTransferAuthority = address('6sPR6MzvjMMP5LSZzEtTe4ZBVX9rhBmtM1dmfFtkNTbW'); + const auditorElgamalPubkey = address('BTNEPmmWuj7Sg4Fo5i1FC5eiV2Aj4jiv9boarvE5XeaX'); + const confidentialTransferMintExtension = extension('ConfidentialTransferMint', { + authority: some(confidentialTransferAuthority), + autoApproveNewAccounts: true, + auditorElgamalPubkey: some(auditorElgamalPubkey), + }); + + // And a confidential mint burn extension. + const supplyElgamalPubkey = address('BTNEPmmWuj7Sg4Fo5i1FC5eiV2Aj4jiv9boarvE5XeaX'); + const decryptableSupply = new Uint8Array(36).fill(0); + const confidentialMintBurnExtension = extension('ConfidentialMintBurn', { + // The confidential supply and pending burn are zero-initialized. + confidentialSupply: new Uint8Array(64).fill(0), + decryptableSupply, + supplyElgamalPubkey, + pendingBurn: new Uint8Array(64).fill(0), + }); + + // When we create and initialize a mint account with these extensions. + const [createMintInstruction, initMintInstruction] = await getCreateMintInstructions({ + authority: authority.address, + client, + extensions: [confidentialTransferMintExtension, confidentialMintBurnExtension], + mint, + payer: authority, + }); + + await sendAndConfirmInstructions(client, authority, [ + createMintInstruction, + getInitializeConfidentialTransferMintInstruction({ + mint: mint.address, + authority: some(confidentialTransferAuthority), + autoApproveNewAccounts: true, + auditorElgamalPubkey: some(auditorElgamalPubkey), + }), + getInitializeConfidentialMintBurnInstruction({ + mint: mint.address, + supplyElgamalPubkey, + decryptableSupply, + }), + initMintInstruction, + ]); + + // Then we expect the mint account to exist and have both extensions. + const mintAccount = await fetchMint(client.rpc, mint.address); + t.like(mintAccount, >{ + address: mint.address, + data: { + mintAuthority: some(authority.address), + isInitialized: true, + extensions: some([confidentialTransferMintExtension, confidentialMintBurnExtension]), + }, + }); +}); diff --git a/clients/js/test/extensions/confidentialTransferFee/initializeConfidentialTransferFee.test.ts b/clients/js/test/extensions/confidentialTransferFee/initializeConfidentialTransferFee.test.ts index d392b8ff7..cacf375be 100644 --- a/clients/js/test/extensions/confidentialTransferFee/initializeConfidentialTransferFee.test.ts +++ b/clients/js/test/extensions/confidentialTransferFee/initializeConfidentialTransferFee.test.ts @@ -87,7 +87,7 @@ test('it initializes a mint with confidential transfer fee', async t => { getInitializeConfidentialTransferFeeInstruction({ mint: mint.address, authority: some(confidentialTransferAuthority), - withdrawWithheldAuthorityElGamalPubkey: some(elgamalPubkey), + withdrawWithheldAuthorityElGamalPubkey: elgamalPubkey, }), initMintInstruction, ]); diff --git a/clients/js/test/getMintSize.test.ts b/clients/js/test/getMintSize.test.ts index d734a0037..9654e77c1 100644 --- a/clients/js/test/getMintSize.test.ts +++ b/clients/js/test/getMintSize.test.ts @@ -30,7 +30,14 @@ test('it returns the size including all provided extensions', t => { test('it returns the correct size for the confidential mint burn extension', t => { t.is( - getMintSize([extension('ConfidentialMintBurn', {})]), - 166 /* extended mint base size */ + 4 /* ConfidentialMintBurn extension size */, + getMintSize([ + extension('ConfidentialMintBurn', { + confidentialSupply: new Uint8Array(64), + decryptableSupply: new Uint8Array(36), + supplyElgamalPubkey: address('6YG6ggAzLnqu1oV56HELbmvfyveD3JKmCmEWGU9W6RK2'), + pendingBurn: new Uint8Array(64), + }), + ]), + 166 /* extended mint base size */ + 4 /* TLV header */ + 196 /* ConfidentialMintBurn extension size */, ); }); diff --git a/clients/js/test/withdrawExcess.test.ts b/clients/js/test/withdrawExcess.test.ts index e4844547d..48ea73741 100644 --- a/clients/js/test/withdrawExcess.test.ts +++ b/clients/js/test/withdrawExcess.test.ts @@ -78,8 +78,8 @@ test('it withdraws excess lamports from an associated token account', async t => // And we initiate withdrawal of excess lamports from the ATA to the destination const withdrawInstruction = await getWithdrawExcessLamportsInstruction({ - sourceAccount: ata, - destinationAccount: destination.address, + source: ata, + destination: destination.address, authority: owner, }); await sendAndConfirmInstructions(client, payer, [withdrawInstruction]); diff --git a/interface/idl.json b/interface/idl.json index cf4a2a5c9..8eb32eea6 100644 --- a/interface/idl.json +++ b/interface/idl.json @@ -6,8 +6,7 @@ "kind": "programNode", "name": "token-2022", "publicKey": "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb", - "version": "3.0.2", - "origin": "shank", + "version": "3.0.1", "docs": [], "accounts": [ { @@ -1790,7 +1789,7 @@ "`system_instruction::transfer` to move lamports to a wrapped token", "account, and needs to have its token `amount` field updated." ], - "optionalAccountStrategy": "programId", + "optionalAccountStrategy": "omitted", "accounts": [ { "kind": "instructionAccountNode", @@ -1799,6 +1798,18 @@ "isSigner": false, "isOptional": false, "docs": ["The native token account to sync with its underlying lamports."] + }, + { + "kind": "instructionAccountNode", + "name": "rent", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": ["Rent sysvar."], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "SysvarRent111111111111111111111111111111111" + } } ], "arguments": [ @@ -3228,16 +3239,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", @@ -3476,16 +3477,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", @@ -3703,7 +3694,7 @@ "Fails if the source or destination accounts are frozen.", "Fails if the associated mint is extended as `NonTransferable`." ], - "optionalAccountStrategy": "programId", + "optionalAccountStrategy": "omitted", "accounts": [ { "kind": "instructionAccountNode", @@ -3891,7 +3882,7 @@ "", "Fails if the associated mint is extended as `NonTransferable`." ], - "optionalAccountStrategy": "programId", + "optionalAccountStrategy": "omitted", "accounts": [ { "kind": "instructionAccountNode", @@ -4002,6 +3993,24 @@ "name": "decryptableBalance" } }, + { + "kind": "instructionArgumentNode", + "name": "transferAmountAuditorCiphertextLo", + "docs": ["The transfer amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "transferAmountAuditorCiphertextHi", + "docs": ["The transfer amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, { "kind": "instructionArgumentNode", "name": "equalityProofInstructionOffset", @@ -4547,7 +4556,7 @@ "`TransferWithFee`. Namely, the instruction fails if the", "associated mint is extended as `NonTransferable`." ], - "optionalAccountStrategy": "programId", + "optionalAccountStrategy": "omitted", "accounts": [ { "kind": "instructionAccountNode", @@ -4677,6 +4686,24 @@ "name": "decryptableBalance" } }, + { + "kind": "instructionArgumentNode", + "name": "transferAmountAuditorCiphertextLo", + "docs": ["The transfer amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "transferAmountAuditorCiphertextHi", + "docs": ["The transfer amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, { "kind": "instructionArgumentNode", "name": "equalityProofInstructionOffset", @@ -4780,6 +4807,115 @@ } ] }, + { + "kind": "instructionNode", + "name": "configureConfidentialTransferAccountWithRegistry", + "docs": [ + "Configures confidential transfers for a token account.", + "", + "This instruction is identical to the `ConfigureAccount` instruction", + "except that an `ElGamalRegistry` account is expected in place of the", + "`VerifyPubkeyValidity` proof.", + "", + "An `ElGamalRegistry` account is valid if it shares the same owner with", + "the token account. If a valid `ElGamalRegistry` account is provided,", + "then the program skips the verification of the ElGamal pubkey validity", + "proof as well as the token owner signature.", + "", + "If the token account is not large enough to include the new", + "confidential transfer extension, then optionally reallocate the account", + "to increase the data size. To reallocate, a payer account to fund the", + "reallocation and the system account should be included in the", + "instruction." + ], + "optionalAccountStrategy": "omitted", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "token", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token account."] + }, + { + "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."] + }, + { + "kind": "instructionAccountNode", + "name": "payer", + "isWritable": true, + "isSigner": true, + "isOptional": true, + "docs": ["(Optional) The payer account to fund reallocation."] + }, + { + "kind": "instructionAccountNode", + "name": "systemProgram", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": ["(Optional) System program for reallocation funding."] + } + ], + "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": "initializeDefaultAccountState", @@ -5997,10 +6133,7 @@ "name": "withdrawWithheldAuthorityElGamalPubkey", "docs": ["Withheld fees from accounts must be encrypted with this ElGamal key"], "type": { - "kind": "zeroableOptionTypeNode", - "item": { - "kind": "publicKeyTypeNode" - } + "kind": "publicKeyTypeNode" } } ], @@ -6054,15 +6187,12 @@ "isWritable": false, "isSigner": false, "isOptional": false, - "docs": ["Instructions sysvar or context state account"] - }, - { - "kind": "instructionAccountNode", - "name": "record", - "isWritable": false, - "isSigner": false, - "isOptional": true, - "docs": ["Optional record account if proof is read from record"] + "docs": [ + "Instructions sysvar if `VerifyCiphertextCiphertextEquality` is", + "included in the same transaction or context state account if", + "`VerifyCiphertextCiphertextEquality` is pre-verified into a context", + "state account." + ] }, { "kind": "instructionAccountNode", @@ -6183,15 +6313,12 @@ "isWritable": false, "isSigner": false, "isOptional": false, - "docs": ["Instructions sysvar or context state account"] - }, - { - "kind": "instructionAccountNode", - "name": "record", - "isWritable": false, - "isSigner": false, - "isOptional": true, - "docs": ["Optional record account"] + "docs": [ + "Instructions sysvar if `VerifyCiphertextCiphertextEquality` is", + "included in the same transaction or context state account if", + "`VerifyCiphertextCiphertextEquality` is pre-verified into a context", + "state account." + ] }, { "kind": "instructionAccountNode", @@ -6540,19 +6667,19 @@ "accounts": [ { "kind": "instructionAccountNode", - "name": "sourceAccount", + "name": "source", "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["Account holding excess lamports."] + "docs": ["The source account."] }, { "kind": "instructionAccountNode", - "name": "destinationAccount", + "name": "destination", "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["Destination account for withdrawn lamports."] + "docs": ["The destination account."] }, { "kind": "instructionAccountNode", @@ -6560,10 +6687,7 @@ "isWritable": false, "isSigner": "either", "isOptional": false, - "docs": ["The source account's owner/delegate or its multisignature account."], - "defaultValue": { - "kind": "identityValueNode" - } + "docs": ["The source account owner or its multisignature account."] } ], "arguments": [ @@ -7160,15 +7284,17 @@ }, { "kind": "instructionNode", - "name": "initializeScaledUiAmountMint", + "name": "initializeConfidentialMintBurn", "docs": [ - "Initialize a new mint with the `ScaledUiAmount` extension.", + "Initializes confidential mints and burns for a mint.", "", - "Fails if the mint has already been initialized, so must be called before `InitializeMint`.", + "The `ConfidentialMintBurnInstruction::InitializeMint` instruction", + "requires no signers and MUST be included within the same Transaction as", + "`TokenInstruction::InitializeMint`. Otherwise another party can", + "initialize the configuration.", "", - "The mint must have exactly enough space allocated for the base mint (82 bytes),", - "plus 83 bytes of padding, 1 byte reserved for the account type,", - "then space required for this extension, plus any others." + "The instruction fails if the `TokenInstruction::InitializeMint`", + "instruction has already executed for the mint." ], "optionalAccountStrategy": "programId", "accounts": [ @@ -7178,7 +7304,7 @@ "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["The mint to initialize."] + "docs": ["The SPL Token mint."] } ], "arguments": [ @@ -7194,12 +7320,12 @@ }, "defaultValue": { "kind": "numberValueNode", - "number": 43 + "number": 42 } }, { "kind": "instructionArgumentNode", - "name": "scaledUiAmountMintDiscriminator", + "name": "confidentialMintBurnDiscriminator", "defaultValueStrategy": "omitted", "docs": [], "type": { @@ -7214,23 +7340,19 @@ }, { "kind": "instructionArgumentNode", - "name": "authority", - "docs": ["The authority that can update the multiplier"], + "name": "supplyElgamalPubkey", + "docs": ["The ElGamal pubkey used to encrypt the confidential supply."], "type": { - "kind": "zeroableOptionTypeNode", - "item": { - "kind": "publicKeyTypeNode" - } + "kind": "publicKeyTypeNode" } }, { "kind": "instructionArgumentNode", - "name": "multiplier", - "docs": ["The initial multiplier for the scaled UI extension"], + "name": "decryptableSupply", + "docs": ["The initial 0 supply encrypted with the supply aes key."], "type": { - "kind": "numberTypeNode", - "format": "f64", - "endian": "le" + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" } } ], @@ -7242,18 +7364,19 @@ }, { "kind": "fieldDiscriminatorNode", - "name": "scaledUiAmountMintDiscriminator", + "name": "confidentialMintBurnDiscriminator", "offset": 1 } ] }, { "kind": "instructionNode", - "name": "updateMultiplierScaledUiMint", + "name": "rotateSupplyElgamalPubkey", "docs": [ - "Update the multiplier. Only supported for mints that include the", - "`ScaledUiAmountConfig` extension.", - "You can set a specific timestamp for the multiplier to take effect." + "Rotates the ElGamal pubkey used to encrypt confidential supply.", + "", + "The pending burn amount must be zero in order for this instruction to be", + "processed successfully." ], "optionalAccountStrategy": "programId", "accounts": [ @@ -7263,15 +7386,32 @@ "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["The mint."] + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "instructionsSysvarOrContextState", + "isWritable": false, + "isSigner": false, + "isOptional": false, + "docs": [ + "Instructions sysvar if `CiphertextCiphertextEquality` is included in", + "the same transaction or context state account if", + "`CiphertextCiphertextEquality` is pre-verified into a context state", + "account." + ], + "defaultValue": { + "kind": "publicKeyValueNode", + "publicKey": "Sysvar1nstructions1111111111111111111111111" + } }, { "kind": "instructionAccountNode", "name": "authority", - "isWritable": true, + "isWritable": false, "isSigner": "either", "isOptional": false, - "docs": ["The multiplier authority."] + "docs": ["The confidential mint authority or its multisignature account."] } ], "arguments": [ @@ -7287,12 +7427,12 @@ }, "defaultValue": { "kind": "numberValueNode", - "number": 43 + "number": 42 } }, { "kind": "instructionArgumentNode", - "name": "scaledUiAmountMintDiscriminator", + "name": "confidentialMintBurnDiscriminator", "defaultValueStrategy": "omitted", "docs": [], "type": { @@ -7307,21 +7447,25 @@ }, { "kind": "instructionArgumentNode", - "name": "multiplier", - "docs": ["The new multiplier for the scaled UI extension"], + "name": "newSupplyElgamalPubkey", + "docs": ["The new ElGamal pubkey for supply encryption."], "type": { - "kind": "numberTypeNode", - "format": "f64", - "endian": "le" + "kind": "publicKeyTypeNode" } }, { "kind": "instructionArgumentNode", - "name": "effectiveTimestamp", - "docs": ["The timestamp at which the new multiplier will take effect"], + "name": "proofInstructionOffset", + "docs": [ + "The location of the", + "`ProofInstruction::VerifyCiphertextCiphertextEquality` instruction", + "relative to the `RotateSupplyElGamalPubkey` instruction in the", + "transaction. If the offset is `0`, then use a context state account", + "for the proof." + ], "type": { "kind": "numberTypeNode", - "format": "i64", + "format": "i8", "endian": "le" } } @@ -7346,19 +7490,15 @@ }, { "kind": "fieldDiscriminatorNode", - "name": "scaledUiAmountMintDiscriminator", + "name": "confidentialMintBurnDiscriminator", "offset": 1 } ] }, { "kind": "instructionNode", - "name": "initializePausableConfig", - "docs": [ - "Initialize a new mint with the `Pausable` extension.", - "", - "Fails if the mint has already been initialized, so must be called before `InitializeMint`." - ], + "name": "updateConfidentialMintBurnDecryptableSupply", + "docs": ["Updates the decryptable supply of the mint."], "optionalAccountStrategy": "programId", "accounts": [ { @@ -7367,8 +7507,812 @@ "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["The mint."] - } + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": false, + "isSigner": "either", + "isOptional": false, + "docs": ["The confidential mint authority or its multisignature account."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 42 + } + }, + { + "kind": "instructionArgumentNode", + "name": "confidentialMintBurnDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 2 + } + }, + { + "kind": "instructionArgumentNode", + "name": "newDecryptableSupply", + "docs": ["The new decryptable supply."], + "type": { + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "confidentialMintBurnDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "confidentialMint", + "docs": [ + "Mints tokens to a confidential balance.", + "", + "Fails if the destination account is frozen.", + "", + "In order for this instruction to be successfully processed, it must be", + "accompanied by the following list of `zk_elgamal_proof` program", + "instructions:", + "- `VerifyCiphertextCommitmentEquality`", + "- `VerifyBatchedGroupedCiphertext3HandlesValidity`", + "- `VerifyBatchedRangeProofU128`", + "These instructions can be accompanied in the same transaction or can be", + "pre-verified into a context state account, in which case, only their", + "context state account addresses need to be provided." + ], + "optionalAccountStrategy": "omitted", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "token", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token account."] + }, + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "instructionsSysvar", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) Instructions sysvar if at least one of the", + "`zk_elgamal_proof` instructions are included in the same", + "transaction." + ] + }, + { + "kind": "instructionAccountNode", + "name": "equalityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyCiphertextCommitmentEquality` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "ciphertextValidityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedGroupedCiphertext3HandlesValidity` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "rangeRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedRangeProofU128` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": false, + "isSigner": "either", + "isOptional": false, + "docs": ["The account owner or its multisignature account."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 42 + } + }, + { + "kind": "instructionArgumentNode", + "name": "confidentialMintBurnDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 3 + } + }, + { + "kind": "instructionArgumentNode", + "name": "newDecryptableSupply", + "docs": ["The new decryptable supply if the mint succeeds."], + "type": { + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "mintAmountAuditorCiphertextLo", + "docs": ["The mint amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "mintAmountAuditorCiphertextHi", + "docs": ["The mint amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "equalityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyCiphertextCommitmentEquality` instruction", + "to the `ConfidentialMint` instruction in the transaction. If the", + "offset is `0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "ciphertextValidityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity`", + "instruction to the `ConfidentialMint` instruction in the transaction.", + "If the offset is `0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "rangeProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedRangeProofU128` instruction to the", + "`ConfidentialMint` instruction in the transaction. If the offset is", + "`0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "confidentialMintBurnDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "confidentialBurn", + "docs": [ + "Burns tokens from a confidential balance.", + "", + "Fails if the source account is frozen.", + "", + "In order for this instruction to be successfully processed, it must be", + "accompanied by the following list of `zk_elgamal_proof` program", + "instructions:", + "- `VerifyCiphertextCommitmentEquality`", + "- `VerifyBatchedGroupedCiphertext3HandlesValidity`", + "- `VerifyBatchedRangeProofU128`", + "These instructions can be accompanied in the same transaction or can be", + "pre-verified into a context state account, in which case, only their", + "context state account addresses need to be provided." + ], + "optionalAccountStrategy": "omitted", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "token", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token account."] + }, + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "instructionsSysvar", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) Instructions sysvar if at least one of the", + "`zk_elgamal_proof` instructions are included in the same", + "transaction." + ] + }, + { + "kind": "instructionAccountNode", + "name": "equalityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyCiphertextCommitmentEquality` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "ciphertextValidityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedGroupedCiphertext3HandlesValidity` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "rangeRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedRangeProofU128` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": false, + "isSigner": "either", + "isOptional": false, + "docs": ["The account owner or its multisignature account."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 42 + } + }, + { + "kind": "instructionArgumentNode", + "name": "confidentialMintBurnDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 4 + } + }, + { + "kind": "instructionArgumentNode", + "name": "newDecryptableAvailableBalance", + "docs": ["The new decryptable balance of the burner if the burn succeeds."], + "type": { + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "burnAmountAuditorCiphertextLo", + "docs": ["The burn amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "burnAmountAuditorCiphertextHi", + "docs": ["The burn amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "equalityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyCiphertextCommitmentEquality` instruction", + "to the `ConfidentialBurn` instruction in the transaction. If the", + "offset is `0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "ciphertextValidityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity`", + "instruction to the `ConfidentialBurn` instruction in the transaction.", + "If the offset is `0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "rangeProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedRangeProofU128` instruction to the", + "`ConfidentialBurn` instruction in the transaction. If the offset is", + "`0`, then use a context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", + "endian": "le" + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "confidentialMintBurnDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "applyConfidentialPendingBurn", + "docs": ["Applies the pending burn amount to the confidential supply."], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": false, + "isSigner": "either", + "isOptional": false, + "docs": ["The mint authority or its multisignature account."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 42 + } + }, + { + "kind": "instructionArgumentNode", + "name": "confidentialMintBurnDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 5 + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "confidentialMintBurnDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "initializeScaledUiAmountMint", + "docs": [ + "Initialize a new mint with the `ScaledUiAmount` extension.", + "", + "Fails if the mint has already been initialized, so must be called before `InitializeMint`.", + "", + "The mint must have exactly enough space allocated for the base mint (82 bytes),", + "plus 83 bytes of padding, 1 byte reserved for the account type,", + "then space required for this extension, plus any others." + ], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The mint to initialize."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 43 + } + }, + { + "kind": "instructionArgumentNode", + "name": "scaledUiAmountMintDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 0 + } + }, + { + "kind": "instructionArgumentNode", + "name": "authority", + "docs": ["The authority that can update the multiplier"], + "type": { + "kind": "zeroableOptionTypeNode", + "item": { + "kind": "publicKeyTypeNode" + } + } + }, + { + "kind": "instructionArgumentNode", + "name": "multiplier", + "docs": ["The initial multiplier for the scaled UI extension"], + "type": { + "kind": "numberTypeNode", + "format": "f64", + "endian": "le" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "scaledUiAmountMintDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "updateMultiplierScaledUiMint", + "docs": [ + "Update the multiplier. Only supported for mints that include the", + "`ScaledUiAmountConfig` extension.", + "You can set a specific timestamp for the multiplier to take effect." + ], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The mint."] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": true, + "isSigner": "either", + "isOptional": false, + "docs": ["The multiplier authority."] + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 43 + } + }, + { + "kind": "instructionArgumentNode", + "name": "scaledUiAmountMintDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 1 + } + }, + { + "kind": "instructionArgumentNode", + "name": "multiplier", + "docs": ["The new multiplier for the scaled UI extension"], + "type": { + "kind": "numberTypeNode", + "format": "f64", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "effectiveTimestamp", + "docs": ["The timestamp at which the new multiplier will take effect"], + "type": { + "kind": "numberTypeNode", + "format": "i64", + "endian": "le" + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "scaledUiAmountMintDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "initializePausableConfig", + "docs": [ + "Initialize a new mint with the `Pausable` extension.", + "", + "Fails if the mint has already been initialized, so must be called before `InitializeMint`." + ], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The mint."] + } ], "arguments": [ { @@ -8508,7 +9452,118 @@ }, "defaultValue": { "kind": "numberValueNode", - "number": 1 + "number": 1 + } + }, + { + "kind": "instructionArgumentNode", + "name": "amount", + "docs": ["The amount of tokens to burn."], + "type": { + "kind": "numberTypeNode", + "format": "u64", + "endian": "le" + } + } + ], + "remainingAccounts": [ + { + "kind": "instructionRemainingAccountsNode", + "isOptional": true, + "isSigner": true, + "docs": [], + "value": { + "kind": "argumentValueNode", + "name": "multiSigners" + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + }, + { + "kind": "fieldDiscriminatorNode", + "name": "permissionedBurnDiscriminator", + "offset": 1 + } + ] + }, + { + "kind": "instructionNode", + "name": "permissionedBurnChecked", + "docs": [ + "Burn tokens with expected decimals when the mint has the permissioned burn extension enabled." + ], + "optionalAccountStrategy": "programId", + "accounts": [ + { + "kind": "instructionAccountNode", + "name": "account", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The source account to burn from."] + }, + { + "kind": "instructionAccountNode", + "name": "mint", + "isWritable": true, + "isSigner": false, + "isOptional": false, + "docs": ["The token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "permissionedBurnAuthority", + "isWritable": false, + "isSigner": true, + "isOptional": false, + "docs": ["Authority configured on the mint that must sign any permissioned burn instruction."] + }, + { + "kind": "instructionAccountNode", + "name": "authority", + "isWritable": false, + "isSigner": "either", + "isOptional": false, + "docs": ["The account's owner/delegate or its multisignature account."], + "defaultValue": { + "kind": "identityValueNode" + } + } + ], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 46 + } + }, + { + "kind": "instructionArgumentNode", + "name": "permissionedBurnDiscriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 2 } }, { @@ -8520,6 +9575,16 @@ "format": "u64", "endian": "le" } + }, + { + "kind": "instructionArgumentNode", + "name": "decimals", + "docs": ["Expected number of base 10 digits to the right of the decimal place."], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } } ], "remainingAccounts": [ @@ -8549,19 +9614,32 @@ }, { "kind": "instructionNode", - "name": "permissionedBurnChecked", + "name": "permissionedConfidentialBurn", "docs": [ - "Burn tokens with expected decimals when the mint has the permissioned burn extension enabled." + "Burn tokens from a confidential balance when the mint has the", + "permissioned burn extension enabled.", + "", + "Fails if the source account is frozen.", + "", + "In order for this instruction to be successfully processed, it must be", + "accompanied by the following list of `zk_elgamal_proof` program", + "instructions:", + "- `VerifyCiphertextCommitmentEquality`", + "- `VerifyBatchedGroupedCiphertext3HandlesValidity`", + "- `VerifyBatchedRangeProofU128`", + "These instructions can be accompanied in the same transaction or can be", + "pre-verified into a context state account, in which case, only their", + "context state account addresses need to be provided." ], - "optionalAccountStrategy": "programId", + "optionalAccountStrategy": "omitted", "accounts": [ { "kind": "instructionAccountNode", - "name": "account", + "name": "token", "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["The source account to burn from."] + "docs": ["The SPL Token account."] }, { "kind": "instructionAccountNode", @@ -8569,7 +9647,52 @@ "isWritable": true, "isSigner": false, "isOptional": false, - "docs": ["The token mint."] + "docs": ["The SPL Token mint."] + }, + { + "kind": "instructionAccountNode", + "name": "instructionsSysvar", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) Instructions sysvar if at least one of the", + "`zk_elgamal_proof` instructions are included in the same", + "transaction." + ] + }, + { + "kind": "instructionAccountNode", + "name": "equalityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyCiphertextCommitmentEquality` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "ciphertextValidityRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedGroupedCiphertext3HandlesValidity` proof." + ] + }, + { + "kind": "instructionAccountNode", + "name": "rangeRecord", + "isWritable": false, + "isSigner": false, + "isOptional": true, + "docs": [ + "(Optional) The context state account containing the pre-verified", + "`VerifyBatchedRangeProofU128` proof." + ] }, { "kind": "instructionAccountNode", @@ -8585,10 +9708,7 @@ "isWritable": false, "isSigner": "either", "isOptional": false, - "docs": ["The account's owner/delegate or its multisignature account."], - "defaultValue": { - "kind": "identityValueNode" - } + "docs": ["The account's owner/delegate or its multisignature account."] } ], "arguments": [ @@ -8619,26 +9739,78 @@ }, "defaultValue": { "kind": "numberValueNode", - "number": 2 + "number": 3 } }, { "kind": "instructionArgumentNode", - "name": "amount", - "docs": ["The amount of tokens to burn."], + "name": "newDecryptableAvailableBalance", + "docs": ["The new decryptable balance of the burner if the burn succeeds."], + "type": { + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "burnAmountAuditorCiphertextLo", + "docs": ["The burn amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "burnAmountAuditorCiphertextHi", + "docs": ["The burn amount encrypted under the auditor ElGamal public key."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "instructionArgumentNode", + "name": "equalityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyCiphertextCommitmentEquality` instruction", + "to the burn instruction in the transaction. If the offset is `0`,", + "then use a context state account for the proof." + ], "type": { "kind": "numberTypeNode", - "format": "u64", + "format": "i8", "endian": "le" } }, { "kind": "instructionArgumentNode", - "name": "decimals", - "docs": ["Expected number of base 10 digits to the right of the decimal place."], + "name": "ciphertextValidityProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedGroupedCiphertext3HandlesValidity`", + "instruction to the burn instruction in the transaction. If the offset", + "is `0`, then use a context state account for the proof." + ], "type": { "kind": "numberTypeNode", - "format": "u8", + "format": "i8", + "endian": "le" + } + }, + { + "kind": "instructionArgumentNode", + "name": "rangeProofInstructionOffset", + "docs": [ + "Relative location of the", + "`ProofInstruction::VerifyBatchedRangeProofU128` instruction to the", + "burn instruction in the transaction. If the offset is `0`, then use a", + "context state account for the proof." + ], + "type": { + "kind": "numberTypeNode", + "format": "i8", "endian": "le" } } @@ -8667,6 +9839,100 @@ "offset": 1 } ] + }, + { + "kind": "instructionNode", + "name": "batch", + "docs": [ + "Executes a batch of instructions. The instructions to be executed are", + "specified in sequence on the instruction data. Each instruction", + "provides:", + "- `u8`: number of accounts", + "- `u8`: instruction data length (includes the discriminator)", + "- `u8`: instruction discriminator", + "- `[u8]`: instruction data", + "", + "Accounts follow a similar pattern, where accounts for each instruction", + "are specified in sequence. Therefore, the number of accounts expected by", + "this instruction is variable, i.e., it depends on the instructions", + "provided.", + "", + "Both the number of accounts and instruction data length are used to", + "identify the slice of accounts and instruction data for each", + "instruction.", + "", + "Note that it is not sound to have a `batch` instruction that contains", + "other `batch` instructions; an error will be raised when this is", + "detected." + ], + "optionalAccountStrategy": "programId", + "accounts": [], + "arguments": [ + { + "kind": "instructionArgumentNode", + "name": "discriminator", + "defaultValueStrategy": "omitted", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "defaultValue": { + "kind": "numberValueNode", + "number": 255 + } + }, + { + "kind": "instructionArgumentNode", + "name": "data", + "docs": ["Instruction data for batch instructions."], + "type": { + "kind": "arrayTypeNode", + "item": { + "kind": "structTypeNode", + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "numberOfAccounts", + "docs": [], + "type": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + } + }, + { + "kind": "structFieldTypeNode", + "name": "instructionData", + "docs": [], + "type": { + "kind": "sizePrefixTypeNode", + "prefix": { + "kind": "numberTypeNode", + "format": "u8", + "endian": "le" + }, + "type": { + "kind": "bytesTypeNode" + } + } + } + ] + }, + "count": { + "kind": "remainderCountNode" + } + } + } + ], + "discriminators": [ + { + "kind": "fieldDiscriminatorNode", + "name": "discriminator", + "offset": 0 + } + ] } ], "definedTypes": [ @@ -9963,7 +11229,43 @@ "kind": "sizePrefixTypeNode", "type": { "kind": "structTypeNode", - "fields": [] + "fields": [ + { + "kind": "structFieldTypeNode", + "name": "confidentialSupply", + "docs": ["The confidential supply of the mint (encrypted by `supply_elgamal_pubkey`)."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + }, + { + "kind": "structFieldTypeNode", + "name": "decryptableSupply", + "docs": ["The decryptable confidential supply of the mint."], + "type": { + "kind": "definedTypeLinkNode", + "name": "decryptableBalance" + } + }, + { + "kind": "structFieldTypeNode", + "name": "supplyElgamalPubkey", + "docs": ["The ElGamal pubkey used to encrypt the confidential supply."], + "type": { + "kind": "publicKeyTypeNode" + } + }, + { + "kind": "structFieldTypeNode", + "name": "pendingBurn", + "docs": ["The amount of burnt tokens that have not yet been applied to the confidential supply (encrypted by `supply_elgamal_pubkey`)."], + "type": { + "kind": "definedTypeLinkNode", + "name": "encryptedBalance" + } + } + ] }, "prefix": { "kind": "numberTypeNode", @@ -10230,21 +11532,6 @@ "name": "confidentialTransferFeeAmount", "docs": ["Includes confidential withheld transfer fees"] }, - { - "kind": "enumEmptyVariantTypeNode", - "name": "scaledUiAmountConfig", - "docs": ["Tokens have a scaled UI amount"] - }, - { - "kind": "enumEmptyVariantTypeNode", - "name": "pausableConfig", - "docs": ["Mint contains pausable configuration"] - }, - { - "kind": "enumEmptyVariantTypeNode", - "name": "pausableAccount", - "docs": ["Account contains pausable configuration"] - }, { "kind": "enumEmptyVariantTypeNode", "name": "metadataPointer", @@ -10283,6 +11570,31 @@ "kind": "enumEmptyVariantTypeNode", "name": "tokenGroupMember", "docs": ["Mint contains token group member configurations"] + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "confidentialMintBurn", + "docs": ["Mint allowing the minting and burning of confidential tokens"] + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "scaledUiAmountConfig", + "docs": ["Tokens whose UI amount is scaled by a given amount"] + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "pausableConfig", + "docs": ["Mint contains pausable configuration"] + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "pausableAccount", + "docs": ["Account contains pausable configuration"] + }, + { + "kind": "enumEmptyVariantTypeNode", + "name": "permissionedBurn", + "docs": ["Mint requires a permissioned burn authority to sign for any burn"] } ], "size": {