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": {