Skip to content

Commit

Permalink
Define IDL instructions for confidential transfer extension (#7)
Browse files Browse the repository at this point in the history
* Add initializeConfidentialTransferMint

* Wrap transfer fee tests in same folder

* Rename init transfer fee config test

* Add test for initializeConfidentialTransferMint

* Add updateConfidentialTransferMint

* Add test for updateConfidentialTransferMint

* Add configureConfidentialAccount

* Add approveConfidentialAccount

* Add emptyConfidentialAccount

* Add confidentialDeposit

* Add confidentialWithdraw

* Add confidentialTransfer

* Add confidentialTransferWithFee

* Add applyConfidentialPendingBalance

* Add enableConfidentialCredits

* Add disableConfidentialCredits

* Add enableNonConfidentialCredits

* Add disableNonConfidentialCredits
  • Loading branch information
lorisleiva authored Oct 7, 2024
1 parent 7b06c3b commit dd5f3a4
Show file tree
Hide file tree
Showing 21 changed files with 6,217 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
/**
* This code was AUTOGENERATED using the kinobi library.
* Please DO NOT EDIT THIS FILE, instead use visitors
* to add features, then rerun kinobi to update it.
*
* @see https://github.com/kinobi-so/kinobi
*/

import {
AccountRole,
combineCodec,
getStructDecoder,
getStructEncoder,
getU64Decoder,
getU64Encoder,
getU8Decoder,
getU8Encoder,
transformEncoder,
type Address,
type Codec,
type Decoder,
type Encoder,
type IAccountMeta,
type IAccountSignerMeta,
type IInstruction,
type IInstructionWithAccounts,
type IInstructionWithData,
type ReadonlyAccount,
type ReadonlySignerAccount,
type TransactionSigner,
type WritableAccount,
} from '@solana/web3.js';
import { TOKEN_2022_PROGRAM_ADDRESS } from '../programs';
import { getAccountMetaFactory, type ResolvedAccount } from '../shared';
import {
getDecryptableBalanceDecoder,
getDecryptableBalanceEncoder,
type DecryptableBalance,
type DecryptableBalanceArgs,
} from '../types';

export const APPLY_CONFIDENTIAL_PENDING_BALANCE_DISCRIMINATOR = 27;

export function getApplyConfidentialPendingBalanceDiscriminatorBytes() {
return getU8Encoder().encode(
APPLY_CONFIDENTIAL_PENDING_BALANCE_DISCRIMINATOR
);
}

export const APPLY_CONFIDENTIAL_PENDING_BALANCE_CONFIDENTIAL_TRANSFER_DISCRIMINATOR = 8;

export function getApplyConfidentialPendingBalanceConfidentialTransferDiscriminatorBytes() {
return getU8Encoder().encode(
APPLY_CONFIDENTIAL_PENDING_BALANCE_CONFIDENTIAL_TRANSFER_DISCRIMINATOR
);
}

export type ApplyConfidentialPendingBalanceInstruction<
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountToken extends string | IAccountMeta<string> = string,
TAccountAuthority extends string | IAccountMeta<string> = string,
TRemainingAccounts extends readonly IAccountMeta<string>[] = [],
> = IInstruction<TProgram> &
IInstructionWithData<Uint8Array> &
IInstructionWithAccounts<
[
TAccountToken extends string
? WritableAccount<TAccountToken>
: TAccountToken,
TAccountAuthority extends string
? ReadonlyAccount<TAccountAuthority>
: TAccountAuthority,
...TRemainingAccounts,
]
>;

export type ApplyConfidentialPendingBalanceInstructionData = {
discriminator: number;
confidentialTransferDiscriminator: number;
/**
* The expected number of pending balance credits since the last successful
* `ApplyPendingBalance` instruction
*/
expectedPendingBalanceCreditCounter: bigint;
/**
* The new decryptable balance if the pending balance is applied
* successfully
*/
newDecryptableAvailableBalance: DecryptableBalance;
};

export type ApplyConfidentialPendingBalanceInstructionDataArgs = {
/**
* The expected number of pending balance credits since the last successful
* `ApplyPendingBalance` instruction
*/
expectedPendingBalanceCreditCounter: number | bigint;
/**
* The new decryptable balance if the pending balance is applied
* successfully
*/
newDecryptableAvailableBalance: DecryptableBalanceArgs;
};

export function getApplyConfidentialPendingBalanceInstructionDataEncoder(): Encoder<ApplyConfidentialPendingBalanceInstructionDataArgs> {
return transformEncoder(
getStructEncoder([
['discriminator', getU8Encoder()],
['confidentialTransferDiscriminator', getU8Encoder()],
['expectedPendingBalanceCreditCounter', getU64Encoder()],
['newDecryptableAvailableBalance', getDecryptableBalanceEncoder()],
]),
(value) => ({
...value,
discriminator: APPLY_CONFIDENTIAL_PENDING_BALANCE_DISCRIMINATOR,
confidentialTransferDiscriminator:
APPLY_CONFIDENTIAL_PENDING_BALANCE_CONFIDENTIAL_TRANSFER_DISCRIMINATOR,
})
);
}

export function getApplyConfidentialPendingBalanceInstructionDataDecoder(): Decoder<ApplyConfidentialPendingBalanceInstructionData> {
return getStructDecoder([
['discriminator', getU8Decoder()],
['confidentialTransferDiscriminator', getU8Decoder()],
['expectedPendingBalanceCreditCounter', getU64Decoder()],
['newDecryptableAvailableBalance', getDecryptableBalanceDecoder()],
]);
}

export function getApplyConfidentialPendingBalanceInstructionDataCodec(): Codec<
ApplyConfidentialPendingBalanceInstructionDataArgs,
ApplyConfidentialPendingBalanceInstructionData
> {
return combineCodec(
getApplyConfidentialPendingBalanceInstructionDataEncoder(),
getApplyConfidentialPendingBalanceInstructionDataDecoder()
);
}

export type ApplyConfidentialPendingBalanceInput<
TAccountToken extends string = string,
TAccountAuthority extends string = string,
> = {
/** The SPL Token account. */
token: Address<TAccountToken>;
/** The source account's owner/delegate or its multisignature account. */
authority: Address<TAccountAuthority> | TransactionSigner<TAccountAuthority>;
expectedPendingBalanceCreditCounter: ApplyConfidentialPendingBalanceInstructionDataArgs['expectedPendingBalanceCreditCounter'];
newDecryptableAvailableBalance: ApplyConfidentialPendingBalanceInstructionDataArgs['newDecryptableAvailableBalance'];
multiSigners?: Array<TransactionSigner>;
};

export function getApplyConfidentialPendingBalanceInstruction<
TAccountToken extends string,
TAccountAuthority extends string,
>(
input: ApplyConfidentialPendingBalanceInput<TAccountToken, TAccountAuthority>
): ApplyConfidentialPendingBalanceInstruction<
typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountToken,
(typeof input)['authority'] extends TransactionSigner<TAccountAuthority>
? ReadonlySignerAccount<TAccountAuthority> &
IAccountSignerMeta<TAccountAuthority>
: TAccountAuthority
> {
// Program address.
const programAddress = TOKEN_2022_PROGRAM_ADDRESS;

// Original accounts.
const originalAccounts = {
token: { value: input.token ?? null, isWritable: true },
authority: { value: input.authority ?? null, isWritable: false },
};
const accounts = originalAccounts as Record<
keyof typeof originalAccounts,
ResolvedAccount
>;

// Original args.
const args = { ...input };

// Remaining accounts.
const remainingAccounts: IAccountMeta[] = (args.multiSigners ?? []).map(
(signer) => ({
address: signer.address,
role: AccountRole.READONLY_SIGNER,
signer,
})
);

const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
const instruction = {
accounts: [
getAccountMeta(accounts.token),
getAccountMeta(accounts.authority),
...remainingAccounts,
],
programAddress,
data: getApplyConfidentialPendingBalanceInstructionDataEncoder().encode(
args as ApplyConfidentialPendingBalanceInstructionDataArgs
),
} as ApplyConfidentialPendingBalanceInstruction<
typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountToken,
(typeof input)['authority'] extends TransactionSigner<TAccountAuthority>
? ReadonlySignerAccount<TAccountAuthority> &
IAccountSignerMeta<TAccountAuthority>
: TAccountAuthority
>;

return instruction;
}

export type ParsedApplyConfidentialPendingBalanceInstruction<
TProgram extends string = typeof TOKEN_2022_PROGRAM_ADDRESS,
TAccountMetas extends readonly IAccountMeta[] = readonly IAccountMeta[],
> = {
programAddress: Address<TProgram>;
accounts: {
/** The SPL Token account. */
token: TAccountMetas[0];
/** The source account's owner/delegate or its multisignature account. */
authority: TAccountMetas[1];
};
data: ApplyConfidentialPendingBalanceInstructionData;
};

export function parseApplyConfidentialPendingBalanceInstruction<
TProgram extends string,
TAccountMetas extends readonly IAccountMeta[],
>(
instruction: IInstruction<TProgram> &
IInstructionWithAccounts<TAccountMetas> &
IInstructionWithData<Uint8Array>
): ParsedApplyConfidentialPendingBalanceInstruction<TProgram, TAccountMetas> {
if (instruction.accounts.length < 2) {
// TODO: Coded error.
throw new Error('Not enough accounts');
}
let accountIndex = 0;
const getNextAccount = () => {
const accountMeta = instruction.accounts![accountIndex]!;
accountIndex += 1;
return accountMeta;
};
return {
programAddress: instruction.programAddress,
accounts: {
token: getNextAccount(),
authority: getNextAccount(),
},
data: getApplyConfidentialPendingBalanceInstructionDataDecoder().decode(
instruction.data
),
};
}
Loading

0 comments on commit dd5f3a4

Please sign in to comment.