Skip to content

feat: Add API to construct confidential transfer instructions - #496

Draft
matthew-a-klein wants to merge 16 commits into
solana-foundation:mainfrom
reilabs:confidential-instructions
Draft

feat: Add API to construct confidential transfer instructions#496
matthew-a-klein wants to merge 16 commits into
solana-foundation:mainfrom
reilabs:confidential-instructions

Conversation

@matthew-a-klein

Copy link
Copy Markdown
Contributor
  • As above: Add builders to construct instructions for all 15 token-2022 confidential transfer extension instructions.
  • Add functionality for encoding/decoding instructions and data.
  • Add unit tests for builders
  • Add parity tests ensuring that encoding/decoding works the same as rust sdk
  • Add CI job ensuring that parity test vectors are reproducible by CI. (Also checks zk-elgamal-proof client test vectors, see feat: client API for ZK El Gamal Program #492 )

@greptile-apps

greptile-apps Bot commented Sep 4, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds typed construction and decoding for all 15 Token-2022 confidential-transfer instructions, including proof-location composition, Rust parity vectors, and a reproducibility workflow.

  • Adds fixed-layout codecs and account builders for confidential-transfer operations.
  • Introduces sibling-instruction and context-state proof-location handling.
  • Adds Go/Rust parity tests and deterministic CI regeneration.
  • Also introduces a typed-nil panic path and removes an existing exported low-level API.

Confidence Score: 3/5

The PR is not yet safe to merge because proof construction can panic on a validly typed nil input and the change breaks an existing exported construction API.

A typed nil proof pointer passes the new location validation and reaches unsafe byte conversion, while the typed-wrapper migration removes public symbols that downstream users may already compile against.

Files Needing Attention: programs/zk-elgamal-proof/zkprogram/proof_location.go, programs/token-2022/ConfidentialTransferExtension.go

Important Files Changed

Filename Overview
programs/token-2022/ConfidentialTransferExtension.go Replaces opaque confidential-transfer data with typed variants, but removes the existing exported low-level construction API.
programs/zk-elgamal-proof/zkprogram/proof_location.go Introduces generic proof locations, but validation accepts nonzero-offset locations containing typed nil proof pointers.
programs/token-2022/confidential_transfer_common.go Centralizes signer and proof-instruction assembly; unchecked typed nil proof data can reach proof encoding.
programs/token-2022/ConfidentialTransferTransfer.go Adds typed transfer data and proof composition with account layouts checked against Rust parity vectors.
programs/token-2022/ConfidentialTransferTransferWithFee.go Adds fee-bearing transfer construction and fixed-layout encoding for its five proofs.
programs/token-2022/confidential_transfer_rust_parity_test.go Compares instruction data and complete account metadata against reproducible Rust-generated vectors.
.github/workflows/parity-vectors.yml Adds CI verification that committed Go parity vectors remain reproducible from locked Rust dependencies.

Reviews (1): Last reviewed commit: "fix(confidential transfers): typo" | Re-trigger Greptile

Comment on lines +41 to +45
func (l ProofLocation[T]) Validate() error {
if !l.IsInstructionOffset() && l.contextStateAccount.IsZero() {
return errors.New("zk: proof location is not set")
}
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Typed nil proof panics

A nonzero-offset location containing a typed nil proof pointer passes this validation because only the offset and context account are checked. The confidential-transfer builders then pass it through the ProofData interface, where it bypasses the ordinary nil check and reaches the unsafe byte conversion in podBytes. For example, using ProofLocationOffset(1, (*proofdata.ZeroCiphertextProofData)(nil)) therefore panics instead of returning an error. Validate that instruction-offset locations contain non-nil proof data.

Knowledge Base Used: Zero-knowledge ElGamal proof program APIs

Comment on lines 33 to 37
type ConfidentialTransferExtension struct {
SubInstruction uint8
// Raw data for the sub-instruction (after the sub-instruction byte).
RawData []byte
ag_binary.BaseVariant

Accounts ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`
Signers ag_solanago.AccountMetaSlice `bin:"-" borsh_skip:"true"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Public construction API removed

This change removes the exported SubInstruction and RawData fields as well as NewConfidentialTransferInstruction, without providing a compatible exported replacement. If downstream consumers use this existing public API, they will no longer compile after upgrading. The equivalent low-level helper is now package-private, so retain or deprecate the old API rather than removing it in this feature change.

Knowledge Base Used:

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@matthew-a-klein
matthew-a-klein marked this pull request as draft September 4, 2026 09:51
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