Add transparent refund address for shielded Zcash Maya swaps - #459
Open
j0ntz wants to merge 2 commits into
Open
Conversation
j0ntz
force-pushed
the
jon/zec-shielded-refund-address
branch
2 times, most recently
from
June 16, 2026 01:08
d550dc3 to
67bbce0
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 67bbce0. Configure here.
j0ntz
force-pushed
the
jon/zec-shielded-refund-address
branch
from
June 16, 2026 01:17
67bbce0 to
dfd5a7a
Compare
Contributor
Author
peachbits
requested changes
Jul 28, 2026
j0ntz
force-pushed
the
jon/zec-shielded-refund-address
branch
from
July 28, 2026 22:27
dfd5a7a to
4a473d9
Compare
j0ntz
force-pushed
the
jon/zec-shielded-refund-address
branch
from
July 28, 2026 22:39
4a473d9 to
b55835f
Compare
peachbits
requested changes
Jul 29, 2026
Maya cannot refund a shielded Zcash source and rejects the refund with "can't refund ZEC from shielded source without a refund address". Add the wallet's transparent (t-address) refund address to the Maya swap memo as DESTADDR/REFUNDADDR so Maya can process refunds. The refund is injected into the memo client-side rather than passed to the quote endpoint. Appending it to the quote request overflows Zcash's 80-char transparent-memo limit and the quote endpoint rejects the swap. The ZEC swap carries its memo in the shielded note, which is not bound by that limit, so the refund is added after the quote is fetched. Non-Zcash sources are unchanged and continue to default to the sending address.
j0ntz
force-pushed
the
jon/zec-shielded-refund-address
branch
from
July 29, 2026 23:08
b55835f to
73c3394
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.






CHANGELOG
Does this branch warrant an entry to the CHANGELOG?
Dependencies
none
Description
Asana: https://app.asana.com/0/1215088146871429/1214541361005860
Problem. When Edge sends a shielded-Zcash swap to Maya, the swap memo carries no refund address. Maya cannot refund a shielded source and rejects the refund:
For every chain except Zcash, Maya defaults the refund to the sending address, which is correct. A shielded ZEC source has no transparent sending address to refund to, so the integrator must supply a transparent (t-address) refund address in the swap memo.
Fix. In the shared Thorchain/Maya common code, when the source wallet is Zcash, fetch the wallet's transparent address (
getAddress(fromWallet, 'transparentAddress'), the same helper already used for the ZEC receive side) and append it to the swap memo's destination field asDESTADDR/REFUNDADDRper the Maya memo spec, via the new documented helperappendMayaRefundAddress(which replaces the destination address in the memo withDESTADDR/REFUNDADDR). Since this is the Zcash-only path, the code throwsSwapCurrencyErrorif the transparent refund address is missing.The refund address is deliberately NOT passed to the
quote/swapendpoint. Given arefund_address, Maya builds that sameDESTADDR/REFUNDADDRmemo and then rejects the quote because the result overflows the source chain's memo limit (e.g. ZEC to DASH is 86/80). The shielded ZEC send instead carries the memo in the encrypted note (512 bytes), which is not bound by the 80-char transparent-memo limit that the quote endpoint pre-validates against, so the refund is injected client-side after the quote is fetched without it. Non-Zcash sources are untouched and keep defaulting to the sending address (their quote requests and memos are unchanged).The change lives entirely in the dependency; no gui-side wiring is required.
Verification.
tsc --noEmit, eslint, and the mocha suite all pass (viaverify-repo.sh, which also runs the webpack build).test/thorchain.test.tspinappendMayaRefundAddress's output to the exact memo shape (=:d:DEST/REFUND:0/1/1:ej:75) and cover the destination-not-present edge case.mayanode.mayachain.info) confirms why the endpoint cannot build the memo: BTC to ETH withrefund_addressreturnsgenerated memo too long for source chain: ...(96/80); the same request without it returns a valid 53-char memo.HALTZECTRADING=1,trading is halted, can't process swap) at the protocol level, and a swap during the halt fails at the quote before the refund injection runs, so it would not exercise this code anyway. Re-run the in-app smoke once Maya resumes ZEC trading.Note
Medium Risk
Changes Maya Zcash swap memo construction and refund routing for a subset of swaps; wrong address formatting could misroute refunds, but scope is limited to ZEC source via the existing ZIP-321 path.
Overview
Shielded Zcash → Maya swaps now embed a transparent (t-address) refund in the swap memo as
DESTADDR/REFUNDADDR, so Maya can refund when trading is halted or the swap fails—shielded sources cannot default to the sender like other chains.Quotes still call
quote/swapwithoutrefund_address, because Maya would build the same long memo and reject quotes that exceed the 80-character transparent memo limit; the shielded ZIP-321 path carries the memo in the encrypted note (512 bytes), soappendMayaRefundAddresspatches the memo after quoting. Missing transparent refund address fails the swap withSwapCurrencyError.Unit tests lock the memo shape; CHANGELOG notes the Maya behavior.
Reviewed by Cursor Bugbot for commit 80f0430. Bugbot is set up for automated code reviews on this repo. Configure here.