Investigate: swap path rejects fee-less small tokens — CU107 'Outputs are required and must be an array' (1-sat single-proof V3)
Maintainers usually reply within 1 day
@Amperstrand is already working on this.
Since Oct 12, 2026.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
Start by tracing the receive path from merchant.Fund to the wallet swap and locating where swap outputs are constructed; the issue does not name files or tests. Compare fee/reserve handling with the mint’s reported input_fee_ppk and determine whether a real wallet can reproduce the failure. Done means identifying the cause and establishing whether this is a user-facing bug or a test-tooling artifact, with an appropriate response for affected payments.
Written by the indexing model from the issue text.
Description
Migrated from Amperstrand/tollgate-module-basic-go#95 as part of the fork retirement — OpenTollGate/tollgate-module-basic-go is the single source of truth; the fork issue carries the original discussion and any lab evidence. Retirement plan: see the tracking issue linked in the migration comment there.]
What happened
During PR validation on the QEMU virtual lab (ai-legion, OpenWrt 24.10.1 VM, testnut mint), a fee-less 1-sat V3 token (single proof, keyset 008e808b89acc141) was submitted through the captive portal. Client-side validation passed ("Valid Cashu token / 1 sat / You will receive 30.00 MiB"), then payment failed with:
Payment failed — #CU107
Payment processing failed: could not swap proofs: Outputs are required and must be an array
The error text is the mint's NUT-03 response — the swap request reached testnut with an empty/missing outputs array.
A fee-buffered token (11 sats minted, mirroring physical-router-test-automation/scripts/mint-token/main.go's feeBuffer = 10) succeeds through the identical path, as do 4-sat tokens (multiple proofs).
Repro (lab)
- Lab: OpenWrt VM 10.99.99.1, backend merchant mode (1 sat/step, 30 MiB steps), testnut.cashu.exchange.
- Mint 1 sat, single proof, V3 (
HttpMinter.mint(1)from PRTAlib/cashu.py). - Submit through the portal (or raw-body POST
text/plainto:2121). - Observe CU107 + mint error above;
logreadshows the swap failure.
Is it fees? — evidence both ways (needs a dig)
For the fee hypothesis: the failure boundary so far is amount/proof-count dependent (1 sat fails, 4/11 sats pass), which smells like a fee reserve being subtracted before outputs are constructed (outputs = amount − fee; fee ≥ amount → empty array). The Gonuts-era mint-token tool explicitly carries feeBuffer = 10 "because of fees".
Against: testnut's /v1/keysets reports input_fee_ppk: 0 for all keysets (including active 008e808b89acc141). If the mint charges nothing, a fee-based explanation requires a locally computed reserve (wallet-side heuristic, not the mint's advertised fee) — or the empty-outputs bug is something else entirely (e.g. single-proof denomination split edge in the swap-output construction).
Questions for whoever digs in
- Where exactly are swap outputs constructed on the receive path (merchant.Fund → wallet swap)? Gonuts vs backend code?
- Is there a fee/reserve computation that ignores
input_fee_ppkor assumes a minimum? - Can a real wallet produce a token that hits this? (If yes → user-facing bug, needs a clean error like "token amount below network fee"; if no → close as test-tooling artifact.)
- Should the backend pre-check
amount ≤ keyset feeand return a proper CU-code instead of surfacing the mint's raw 400?
Environment
- Backend: deployed on lab VM, gonuts-tollgate (version unconfirmed — binary undated; this repro predates any fresh-main deployment)
- Mint: testnut.cashu.exchange (Nutshell-CF/0.0.1),
input_fee_ppk: 0on all keysets - Full session log and portal error snapshot available in PRTA PR #114/#115 validation notes (2026-09-18)
- Dominant language
- Go
- Stars
- 12
- Forks
- 14
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 239
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from OpenTollGate/tollgate-module-basic-go
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
OpenTollGate/tollgate-module-basic-go#833 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
OpenTollGate/tollgate-module-basic-go#813 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
OpenTollGate/tollgate-module-basic-go#804 ·
Maintainers usually reply within 1 day
-
go-battery needs an ndsctl on PATH: TestPurchaseSessionGuardHoldsThroughTheOutcomeUnknownWindow fails on bare hosts (passes with stub)Possibly taken @Amperstrand claimed this 2 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
OpenTollGate/tollgate-module-basic-go#726 · 2 comments ·
Maintainers usually reply within 1 day
-
rebrand-literal-gutter: uhttpd section-vocabulary check trips on a COMMENT (uhttpd.luci in 92-tollgate-admin-setup:178)Possibly taken @Amperstrand claimed this 2 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
OpenTollGate/tollgate-module-basic-go#723 ·
Maintainers usually reply within 1 day
All issues in OpenTollGate/tollgate-module-basic-go
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
Maintainers usually reply within 1 day
-
Add SolentaPossibly taken @sharmao07 claimed this today. Open
Difficulty 1/5 Under an hour Newbie friendliness 85/100
slavakurilyak/awesome-ai-agents#760 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
-
agent-review-finding bug
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
jordansmall/spindrift#5281 ·
Maintainers usually reply within 1 day