Skip to content

Fix/ltc and doge check paypro - #4225

Open
MichaelAJay wants to merge 12 commits into
bitpay:masterfrom
MichaelAJay:fix/ltc-and-doge-check-paypro
Open

Fix/ltc and doge check paypro#4225
MichaelAJay wants to merge 12 commits into
bitpay:masterfrom
MichaelAJay:fix/ltc-and-doge-check-paypro

Conversation

@MichaelAJay

Copy link
Copy Markdown
Contributor

Description

Fixes IS-1413.

Verifier.checkPaypro previously verified destination addresses only for BTC and BCH. LTC and DOGE PayPro proposals could therefore substitute a different destination while preserving the invoiced amount and still pass co-signer verification.

This change makes PayPro verification fail closed for all supported multisig/UTXO chains: BTC, BCH, DOGE, and LTC. It compares the complete, order-independent set of transaction outputs against the PayPro instructions, including both destination and amount.

Addresses are parsed and canonicalized with each chain’s own bitcore library. This preserves equivalent address representations while ensuring malformed addresses cannot pass merely because their raw strings match.

Changelog

  • Verify PayPro destinations for DOGE and LTC in addition to BTC and BCH.
  • Compare every transaction output against the complete PayPro instruction set.
  • Match outputs and instructions by normalized destination and atomic amount, independent of ordering.
  • Parse and canonicalize destinations with the corresponding BTC, BCH, DOGE, or LTC address library.
  • Preserve equivalent BTC and LTC Bech32 casing.
  • Preserve equivalent Litecoin legacy 3... and modern M... P2SH representations.
  • Preserve BCH cashaddr/legacy address equivalence.
  • Reject malformed addresses on either the transaction proposal or PayPro instruction side without throwing.
  • Reject unsupported chains and malformed PayPro data instead of accepting by default.
  • Reject mismatched output counts, per-output amounts, and transaction totals.
  • Preserve supported legacy transaction-proposal behavior.
  • Log actionable verification failures with the transaction proposal ID when available.
  • Add unit and caller-boundary regressions covering matching, substituted, equivalent, and malformed PayPro destinations.
  • Update the standalone reproduction to use valid BTC, DOGE, and LTC address fixtures.
  • Move checkTxProposal above its helpers and simplify return statement

Testing Notes

Verified from packages/bitcore-wallet-client, with a local MongoDB instance
already running and reachable at localhost:27017 (Docker container
mongodb, image mongo:7.0, running since 2026-07-13 — not started for this
change, just already part of the local dev environment):

  • npm run compile — passed, no errors.
  • ../../node_modules/.bin/mocha ts_build/test/verifier.test.js --grep 'checkPaypro|checkTxProposal' — 47 passing, 0 failing.
  • npm run lint — passed, no errors.
  • git diff --check — passed, no whitespace errors.
  • npm test (full package suite, including the MongoDB-backed integration tests) — 589 passing, 12 pending, 0 failing, exit code 0. Coverage: Statements 75.29%, Branches 62.03%, Functions 72.58%, Lines 76.99%; all thresholds met, no database-related failures.

The focused coverage includes:

  • Matching and substituted destinations for BTC, BCH, DOGE, and LTC.
  • BTC and LTC Bech32 case equivalence.
  • Litecoin legacy 3... and modern M... P2SH equivalence.
  • Malformed proposal and PayPro destinations for BTC, DOGE, and LTC, including asymmetric cases (malformed on only the proposal side, and only the PayPro side).
  • BCH malformed-address handling and cashaddr/legacy compatibility.
  • Legacy transaction proposals.
  • Reordered, duplicate, missing, and mismatched output/instruction sets.
  • Caller-boundary acceptance and rejection through Verifier.checkTxProposal.

For manual verification:

  1. Create a PayPro proposal for an LTC or DOGE multisig wallet and confirm the matching merchant destination and amount are accepted.
  2. Substitute the destination while retaining the invoiced amount and confirm co-signer verification rejects the proposal with SERVER_COMPROMISED.
  3. For LTC, confirm equivalent supported address representations do not cause a false rejection.

Checklist

  • I have read CONTRIBUTING.md and verified that this PR follows the guidelines and requirements outlined in it.

// `3...`/modern `M...` P2SH, BCH cashaddr/legacy) compare equal while
// unparseable addresses throw and are treated as a verification failure
// instead of matching merely because their raw strings match.
const ADDRESS_LIB_BY_CHAIN: Record<string, { Address: new (address: string) => { toString(): string } }> = {

@leolambo leolambo Aug 25, 2026

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.

this map only has btc, bch, doge, ltc, so every other chain falls through to the unsupported-chain return below and checkPaypro gives false, which becomes SERVER_COMPROMISED. old checkPaypro returned true for eth/xrp/erc20, and getTxProposals throws on the first failing txp, so a single eth or usdc paypro proposal now breaks the whole fetch for the 9 account based coins the ticket listed.

Copilot AI 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.

Pull request overview

This PR hardens Verifier.checkPaypro in bitcore-wallet-client so PayPro verification fails closed for all supported multisig/UTXO chains (BTC, BCH, DOGE, LTC) by validating the full, order-independent output set (destination + atomic amount) against PayPro instructions, using chain-specific address canonicalization.

Changes:

  • Canonicalize and compare PayPro instructions vs proposal outputs for BTC/BCH/DOGE/LTC, including output count and totals, rejecting malformed/unsupported inputs without throwing.
  • Add detailed warning logs on PayPro verification failures (including TXP id when available).
  • Add extensive unit and boundary tests covering matching, substitution attacks, address equivalence forms, malformed inputs, and multi-output ordering/duplication.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
packages/bitcore-wallet-client/src/lib/verifier.ts Expands PayPro verification to DOGE/LTC and to full output-set matching with chain-specific address parsing and stricter validation.
packages/bitcore-wallet-client/test/verifier.test.ts Adds comprehensive PayPro verification and checkTxProposal boundary regression coverage across chains and edge cases.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

3 participants