Skip to content

Solana CT: SDK Phase 1a — confidential transfer instruction builders - #9620

Open
bhavidhingra wants to merge 2 commits into
masterfrom
bhavi/chalo-1090-solana-ct-sdk-phase1
Open

Solana CT: SDK Phase 1a — confidential transfer instruction builders#9620
bhavidhingra wants to merge 2 commits into
masterfrom
bhavi/chalo-1090-solana-ct-sdk-phase1

Conversation

@bhavidhingra

Copy link
Copy Markdown
Contributor

Description

Adds Token-2022 confidential transfer (CT) transaction construction in `sdk-coin-sol` for Phase 1a (deposits + transfers + conversions, without TransferFee).

This PR replaces the earlier PR #9384 which was scoped to ConfidentialMint + proof-account tx group (Phase 2 / v0 obsolete). The new PR is Phase 1a-only, with all instruction layouts verified against the canonical Rust source (`solana-program/token-2022`).

New instruction builders

Instruction Size Layout
ConfigureAccount 47B `[27][2] + decryptable_zero_balance(36) + counter(u64) + proof_offset(i8)`
ApplyPendingBalance 46B `[27][8] + expected_counter(u64) + new_decryptable(36)`
Deposit 11B `[27][5] + amount(u64) + decimals(u8)`
Withdraw 49B `[27][6] + amount(u64) + decimals(u8) + new_decryptable(36) + eq_offset(i8) + range_offset(i8)`
Transfer 169B `[27][7] + new_decryptable(36) + auditor_ct_lo(64) + auditor_ct_hi(64) + eq_offset(i8) + validity_offset(i8) + range_offset(i8)`
VerifyPubkeyValidity 1+proof `[4] + proof_data`
VerifyEquality 1+proof `[3] + proof_data` or `[3] + offset(u32)`
VerifyValidity3Handles 1+proof `[12] + proof_data` or `[12] + offset(u32)`
VerifyRangeU128 1+proof `[7] + proof_data` or `[7] + offset(i32)`

Key design decisions

  • Instruction builders are v0/v1-agnostic — they produce instruction data + account metas only. The caller (Wallet Platform) assembles v1 transactions in the correct order.
  • ConfigureAccount 47B layout is correct — verified against canonical `solana-program/token-2022` Rust source. The old `solana-program-library` fork had `encryption_pubkey` (32B) embedded in instruction data, but the current on-chain version extracts the ElGamal pubkey from the `VerifyPubkeyValidity` proof via the instructions sysvar.
  • Phase 1b (TransferFee) deferred to a separate PR — 1a covers 3-proof CT Transfer only (equality + validity + range U128).
  • CreateATA already exists in `sdk-coin-sol` — reused, no new code needed.
  • ConfidentialMint + proof-account tx group dropped (Phase 2 / v0 obsolete with v1-only decision).

Issue Number

CHALO-1090

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

18 new unit tests covering:

  • All instruction data layouts (byte-level verification of discriminators, field offsets, and sizes)
  • Account metas (writable/signer flags, correct addresses)
  • Context state vs inline proof modes (offset == 0 → context state, offset != 0 → sysvar)
  • Multi-instruction v1 tx assembly (ApplyPendingBalance + 3 proofs + Transfer)
  • Validation (empty builder rejects, missing params reject)

All 680 existing sdk-coin-sol unit tests continue to pass.

```bash
cd modules/sdk-coin-sol
yarn mocha --grep "Confidential Transfer Builder" --timeout 30000 # 18 passing
yarn mocha --timeout 60000 # 680 passing
```

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
  • The ticket was included in the commit message as a reference
  • I have added tests that prove my feature works
  • New and existing unit tests pass locally with my changes

@bhavidhingra
bhavidhingra requested review from a team as code owners September 1, 2026 12:17
@linear-code

linear-code Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

CHALO-1090

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

⚠️ Unit tests are failing on Node 26.x (Current release line, non-blocking). This is not an LTS version yet, so it does not block merge, but it signals an incompatibility to fix before Node 26.x becomes LTS.

View run

@bhavidhingra
bhavidhingra force-pushed the bhavi/chalo-1090-solana-ct-sdk-phase1 branch 3 times, most recently from d74028c to 46370e0 Compare September 2, 2026 11:06
bhavidhingra added a commit that referenced this pull request Sep 2, 2026
…lidation

Fixes from PR #9620 review:

1. Use s8() for signed proof instruction offsets (was u8 — negative
   offsets would wrap without guarantee)
2. Single-pass parser preserving instruction order (was concatenating
   CT + custom arrays, breaking round-trip fidelity)
3. VerifyPubkeyValidity context state mode support (was always requiring
   proofData, throwing for context state callers)
4. Assert context state addresses provided when offset == 0 (was silently
   omitting accounts, causing on-chain failures)
5. Validate numeric strings before BigInt() (was throwing raw SyntaxError)
6. Fix ZK proof program ID to canonical on-chain constant
   ZkE1Gama1Proof111... (was using devnet sandbox deployment). Add
   .zkProofProgramId() builder setter for custom deployments.
7. Remove Omit<X['params'], never> no-op type
8. from() routing: detect CT transactions by programId + discriminators
   and route to ConfidentialTransferBuilder (was always routing to
   CustomInstructionBuilder)

35 CT unit tests, 701 total — all passing.

CHALO-1090
…builders (Phase 1a)

Add SDK instruction builders for Solana Token-2022 confidential transfers:

- ConfigureAccount (47B): one-time ATA setup for CT extension
- ApplyPendingBalance (46B): credits pending → available (idempotent)
- Deposit (11B): public → confidential conversion
- Withdraw (49B): confidential → public conversion (eq + range proofs)
- Transfer (169B): confidential → confidential (eq + validity + range proofs)
- VerifyPubkeyValidity, VerifyEquality, VerifyValidity, VerifyRange proof builders

All instruction layouts verified against canonical Rust source
(solana-program/token-2022). Builders are v0/v1-agnostic — produce
instruction data + account metas only; caller assembles v1 transactions.

Review fixes applied:
- s8() for signed proof instruction offsets (was u8)
- Single-pass parser preserving instruction order
- VerifyPubkeyValidity context state mode support
- Assert context state addresses when offset == 0
- Validate numeric strings before BigInt()
- Canonical ZK proof program ID (ZkE1Gama1Proof111...) + .zkProofProgramId() setter
- from() routing: detect CT txs by programId + discriminators
- Remove Omit<X['params'], never> no-op type

New ConfidentialTransferBuilder class with fluent setters for all CT
instruction types. Factory wiring via getConfidentialTransferBuilder().
Parser round-trip preserves CT instruction metadata.

35 unit tests covering all instruction layouts, account metas, context
state vs inline proof modes, signed offsets, validation, and from() routing.
701 total tests passing.

CHALO-1090
@bhavidhingra
bhavidhingra force-pushed the bhavi/chalo-1090-solana-ct-sdk-phase1 branch from 3a04636 to 3242781 Compare September 2, 2026 12:49
… value

Replace CustomTx piggyback + runtime discriminator sniffing with a
first-class TransactionType.ConfidentialTransfer enum value, matching
the pattern used by ERC-7984 confidential token types.

CT detection now happens once at the classification layer
(getTransactionType / deriveTransactionType) instead of being scattered
across builder factory sniffing. The CustomTx path is restored to handle
only actual custom transactions.

CHALO-1090
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