feat: Add API to construct confidential transfer instructions - #496
feat: Add API to construct confidential transfer instructions#496matthew-a-klein wants to merge 16 commits into
Conversation
matthew-a-klein
commented
Sep 4, 2026
- 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 SummaryThis 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.
Confidence Score: 3/5The 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
Reviews (1): Last reviewed commit: "fix(confidential transfers): typo" | Re-trigger Greptile |
| func (l ProofLocation[T]) Validate() error { | ||
| if !l.IsInstructionOffset() && l.contextStateAccount.IsZero() { | ||
| return errors.New("zk: proof location is not set") | ||
| } | ||
| return nil |
There was a problem hiding this comment.
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
| 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"` |
There was a problem hiding this comment.
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!