Skip to content

CSHLD-1652: Build @bitgo/abstract-utxo to expose new ZEC address helper exports - #9668

Open
abhi-bitgo wants to merge 1 commit into
masterfrom
CSHLD-1652-shielded-zcash-address
Open

CSHLD-1652: Build @bitgo/abstract-utxo to expose new ZEC address helper exports#9668
abhi-bitgo wants to merge 1 commit into
masterfrom
CSHLD-1652-shielded-zcash-address

Conversation

@abhi-bitgo

Copy link
Copy Markdown
Contributor

Summary

Extends Zec.isValidAddress to recognize well-formed ZIP-316 Unified Addresses (Sapling/Orchard) in addition to transparent addresses, and adds standalone helpers for classifying/validating Zcash addresses without needing a coin/SDK instance.

Linear: CSHLD-1652

Changes

  • modules/abstract-utxo/src/impl/zec/address.ts (new): isShieldedZcashAddress, getZcashAddressKind, isValidZcashAddress
  • modules/abstract-utxo/src/impl/zec/zec.ts: Zec.isValidAddress now falls back to shielded-address recognition
  • modules/abstract-utxo/src/impl/zec/index.ts: re-export the new address module
  • modules/abstract-utxo/test/unit/impl/zec/unit/address.ts (new): unit tests covering transparent/shielded/garbage/cross-network cases

Test Plan

  • yarn unit-test --scope abstract-utxo (new address.ts test suite passes)
  • tsc --noEmit and yarn lint clean

@linear-code

linear-code Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

CSHLD-1652

@abhi-bitgo

Copy link
Copy Markdown
Contributor Author

@claude review this pr

@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Claude finished @abhi-bitgo's task —— View job


PR Review: CSHLD-1652 - Build @bitgo/abstract-utxo to expose new ZEC address helper exports

Overview ✅

This PR successfully extends Zcash address validation to support ZIP-316 Unified Addresses (shielded addresses) while maintaining backward compatibility with transparent addresses. The implementation is clean, well-documented, and thoroughly tested.

Code Quality Analysis

✅ Strengths:

  1. Clean Architecture - The new address.ts module provides standalone utility functions that are well-separated from the coin implementation, making them reusable across the codebase.

  2. Robust Error Handling - Proper try-catch blocks with fallback logic in modules/abstract-utxo/src/impl/zec/address.ts:26-35. The functions gracefully handle invalid addresses by catching exceptions and returning appropriate values.

  3. Type Safety - Good use of TypeScript with the ZcashAddressKind type and proper return types throughout.

  4. Comprehensive Testing - The test suite in modules/abstract-utxo/test/unit/impl/zec/unit/address.ts covers:

    • Mainnet unified addresses
    • Testnet unified addresses
    • Transparent addresses
    • Cross-network validation (rejecting mainnet address on testnet)
    • Invalid/garbage input handling
  5. Backward Compatibility - The Zec.isValidAddress implementation in modules/abstract-utxo/src/impl/zec/zec.ts:23-28 properly extends the base class method with fallback logic.

⚠️ Areas for Improvement:

  1. Documentation Clarity - The comment in modules/abstract-utxo/src/impl/zec/address.ts:27-29 about ZcashNetworkName permitting 'zcash'/'zcashTest' could be clearer. Consider adding a brief explanation of why this behavior exists.

  2. Type Casting Safety - The cast network as CoinName in modules/abstract-utxo/src/impl/zec/address.ts:30 is documented but could potentially be error-prone. Consider adding runtime validation or a helper function.

  3. Test Vector Source - While the ZIP-316 test vectors are well-documented as coming from BitGoWASM, consider adding a comment with the specific commit hash or version for traceability.

Security Considerations ✅

  • Input Validation: All functions properly validate input addresses before processing
  • No Direct Buffer Operations: Uses safe WASM library calls instead of manual parsing
  • Network Isolation: Properly validates addresses against the correct network to prevent cross-network confusion

Performance Considerations ✅

  • Efficient Fallback Logic: The transparent address check happens first (faster path), then falls back to shielded validation
  • Exception Handling: Uses exceptions for control flow appropriately, as parsing failures are expected for invalid addresses

API Design ✅

The new exported functions provide a clean, intuitive API:

  • isShieldedZcashAddress() - specific shielded address check
  • getZcashAddressKind() - classification with validation
  • isValidZcashAddress() - general validation (matches existing patterns)

Test Coverage ✅

Excellent test coverage with realistic test vectors and edge cases. The tests verify both positive and negative cases across different networks and address types.

Minor Suggestions:

  1. Consider adding a JSDoc comment to ZcashAddressKind type explaining when each variant is used
  2. The test could benefit from testing more transparent address formats (P2SH, etc.) if supported
  3. Consider adding performance benchmarks if this will be called frequently

Verdict: ✅ APPROVE

This is a well-implemented feature that safely extends Zcash address validation capabilities. The code follows BitGoJS patterns, maintains backward compatibility, and includes comprehensive testing. Ready to merge.


Job Run: View workflow runs

@github-actions

github-actions Bot commented Sep 7, 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

Zec.isValidAddress previously only accepted transparent (base58check)
addresses. Extend it to also recognize well-formed ZIP-316 Unified
Addresses (Sapling/Orchard), and expose standalone helpers
(getZcashAddressKind, isShieldedZcashAddress, isValidZcashAddress) for
callers that need to classify or validate addresses without a coin/SDK
instance.

Ticket: CSHLD-1652
@abhi-bitgo
abhi-bitgo force-pushed the CSHLD-1652-shielded-zcash-address branch from 23443de to a822362 Compare September 7, 2026 04:20
@abhi-bitgo
abhi-bitgo marked this pull request as ready for review September 7, 2026 05:57
@abhi-bitgo
abhi-bitgo requested a review from a team as a code owner September 7, 2026 05:57

@abhishekagrawal080 abhishekagrawal080 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

looks good

*/
export function isShieldedZcashAddress(address: string, network: fixedScriptWallet.ZcashNetworkName): boolean {
try {
fixedScriptWallet.ZcashUnifiedAddress.parse(address, network);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not all unified address are valid with respect to bitgo, only ones with orchard receiver are valid

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.

4 participants