Skip to content

fix(sdk-coin-sol): correct ConfigureAccount wire and fee reallocation - #10119

Open
bhavidhingra wants to merge 1 commit into
masterfrom
bhavi/chalo-2030-ct-configure-account-abi
Open

bhavidhingra wants to merge 1 commit into
masterfrom
bhavi/chalo-2030-ct-configure-account-abi

Conversation

@bhavidhingra

Copy link
Copy Markdown
Contributor

Description

Fixes the Token-2022 confidential-transfer wire so SDK-built account enablement actually works on-chain. Two defects live in the encoder (modules/sdk-coin-sol), both of which make every ConfigureAccount fail:

  1. ConfigureAccount wrote the deprecated 79-byte payload. Token-2022 no longer carries the ElGamal pubkey in the instruction data — the key is recovered from the accompanying VerifyPubkeyValidity proof context. New layout: [27][2] + decryptable_zero_balance(36) + maximum_pending_balance_credit_counter(u64) + proof_instruction_offset(i8) = 47 bytes. The elgamalPubkey param is removed from ConfigureConfidentialTransferAccount (the caller still needs the key to generate the proof, but it is not instruction data).

  2. Reallocate reserved only ConfidentialTransferAccount. For a mint carrying TransferFeeConfig, ConfigureAccount also initializes ConfidentialTransferFeeAmount, so the account must be 68 bytes larger (64 payload + TLV header). Reallocate now appends extension type 17 when the mint is fee-bearing.

The pinned @solana/spl-token (0.4.13) enum predates the confidential-fee members, so type 17 is declared locally with the Token-2022 enum order cited.

API change (unreleased CT lane only): elgamalPubkey removed from configureAccount; new optional mintHasTransferFeeConfig on createAta / ReallocateConfidentialTransferAccount. Consumers (wallet-platform #63702) must pass the flag for fee-bearing mints and stop passing elgamalPubkey.

Issue Number

CHALO-2030

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change for the unreleased confidential-transfer SDK API (param removed/added as described above)

How Has This Been Tested?

  • Unit: ConfigureAccount wire-bytes test asserts the exact 47-byte layout and offsets; new createAta reallocate tests assert the extension list [5] versus [5, 17]. Both were written failing first (79 ≠ 47, 3 ≠ 5 bytes) against the previous encoders.
  • mocha in modules/sdk-coin-sol: 895 passing / 0 failing (Node 24).
  • Devnet (acceptance gate): CreateATA → Reallocate → ConfigureAccount → VerifyPubkeyValidity confirmed by the real Token-2022 program on devnet:
    • plain CT mint — 469B account, extensions ImmutableOwner, ConfidentialTransferAccount(295B)
    • TransferFeeConfig CT mint — 549B account, extensions ImmutableOwner, TransferFeeAmount(8B), ConfidentialTransferAccount(295B), ConfidentialTransferFeeAmount(64B)
    • control run with the fee extension omitted — ConfigureAccount fails with invalid account data, confirming the shortfall the fix prevents

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My code compiles correctly for both Node and Browser environments
  • I have commented my code, particularly in hard-to-understand areas
  • My commits follow Conventional Commits and I have properly described any BREAKING CHANGES
  • The ticket or github issue was included in the commit message as a reference
  • I have made corresponding changes to the documentation and on any new/updated functions and/or methods
  • I have added tests that prove my fix is effective and that my feature works
  • New and existing unit tests pass locally with my changes

Token-2022 ConfigureAccount carries no ElGamal pubkey: the key is taken from
the VerifyPubkeyValidity proof context. Drop the inline 32-byte key so the
instruction data is [27][2] + decryptable_zero_balance(36) +
maximum_pending_balance_credit_counter(u64) + proof_instruction_offset(i8),
instead of the deprecated 79-byte form.

Reallocate now also reserves ConfidentialTransferFeeAmount (extension 17)
when the mint carries TransferFeeConfig: ConfigureAccount initializes that
extension for such mints, so the account needs its 68 bytes of space.

Verified on devnet: CreateATA + Reallocate + ConfigureAccount +
VerifyPubkeyValidity confirms for a plain CT mint (469B account, extension 5)
and a TransferFeeConfig CT mint (549B, extensions 2/5/17). The same sequence
without the fee extension fails ConfigureAccount with invalid account data.

CHALO-2030
@bhavidhingra
bhavidhingra requested a review from a team as a code owner November 3, 2026 12:39

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@linear-code

linear-code Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

CHALO-2030

@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

⚠️ Compatibility checks are failing on Node.js 27-nightly (experimental, non-blocking). This does not block merge, but it signals an incompatibility to fix before this release becomes supported.

View run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant