Repository navigation
The fee's currency is a config convention, not the chain's answer #68
Description
Surfaced while reviewing #67 (the fix for #53), raised independently by all three
reviewers, and deliberately left out of that PR.
What is true today
Every panel that labels a fee reads settings.profile.currency — the ticker
string from the config file. fee_currency() in src/cmd/currency.rs now
documents this honestly, but documenting it is not fixing it.
Why it can be wrong
The SDK's notion of the fee currency is chain_info().chain_id, which is an
i-address, not a ticker. That a readable ticker appears on the panel at all is a
convention of the profile, not something the chain confirmed.
--node is a global override. Point a profile whose currency = "VRSCTEST"
at a different chain and every fee row on every panel confidently names the wrong
coin, on the screen shown immediately before money moves.
Why it was not fixed in #67
native_currency_id() returns a CurrencyId, not a name. Getting a ticker from
the node needs a second currency_definition lookup, a new failure path, and a
name that is itself untrusted — and to stay consistent it would have to happen at
every site that labels a native amount:
src/cmd/currency.rs— mint, preconvert, convert, andlaunch_panelsrc/cmd/send.rssrc/cmd/id.rssrc/cmd/wallet.rssrc/cmd/lifecycle.rssrc/cmd/airgap.rs
That is a repo-wide change. #53 was rated low severity and small effort, and
growing it there would have put an unreviewed cross-cutting change inside a
consistency fix.
Suggested shape
Resolve the chain's own currency name once, where the node is already in hand,
and thread it the way Token { id, shown } already threads a currency the user
named — id and name travelling together so the two cannot silently disagree.
Where the lookup fails, the three-state verdict in src/currency_name.rs already
says how to render an unknown without claiming a nothing.
Worth checking at the same time whether --json should carry the fee currency on
mint, preconvert and convert. It does not today, and #67 left that alone as a
separate contract.
Activity
The token step read its input name from a branch the workflows do not…
chainvue-claude-automation commentedon Sep 1, 2026
Spec gate: needs work
Risk:
high— testEstimated diff: ~800 lines including tests
test
Open questions
Answer these in a comment, then re-apply
claude:ready.Too large for one pull request
Suggested split:
Machine-readable verdict
{ "begruendung": "test", "estimated_diff_lines": 800, "plan": { "ansatz": "", "dateien": [], "tests": [] }, "risk": "high", "risk_begruendung": "test", "rueckfragen": [ "a", "b" ], "split_vorschlag": [ "a", "b" ], "verdict": "needs_spec" }Spec gate · run log
chainvue-claude-automation commentedon Sep 1, 2026
Spec gate: run failed
The spec gate did not produce a verdict. This is a fault in the automation, not in the issue. Run log
Re-apply
claude:readyto try again.chainvue-claude-automation commentedon Sep 1, 2026
Spec gate: needs work
Risk:
high— The fix as scoped by the issue touches src/cmd/send.rs, src/cmd/airgap.rs, src/cmd/id.rs and src/cmd/lifecycle.rs (all listedhighin .github/claude-risk-paths.yml, because they move money, run the air-gap ceremony, or control identities) plus src/cmd/currency.rs, src/cmd/wallet.rs and src/currency_name.rs (medium). Any path set that reaches the high tier makes the whole PR high.Estimated diff: ~750 lines including tests
The issue (src/cmd/currency.rs:2129 fee_currency(), confirmed still returning &settings.profile.currency, and the ~20 call sites found across currency.rs/send.rs/id.rs/wallet.rs/lifecycle.rs/airgap.rs) accurately describes a real, unfixed problem and correctly points at src/currency_name.rs's existing three-state verdict as the pattern tx.rs already follows. But it is written as analysis plus a 'suggested shape,' not a specification: it names an open question on --json scope without answering it, gives no exact row wording or JSON shape to assert on, and leaves the air-gap case (no node in hand) undecided. At roughly twenty call sites across four high-risk files it is also too large for one review as written.
Open questions
highblast radius?sign, which never has a node in hand, what should the fee currency label show — the profile ticker unchanged, an explicit unresolved/offline marker, or something else? The issue's 'resolve it once, where the node is already in hand' implies node-backed commands only but does not say what the offline steps should do instead.--jsononcurrency mint,preconvertandconvertin scope for this issue, or deferred the way Mint, preconvert and convert printed money without saying in what #67 deferred the panel fix — the issue raises it as 'worth checking' rather than deciding it?Answer these in a comment, then re-apply
claude:ready.Too large for one pull request
Suggested split:
How the gate got there
I read src/currency_name.rs (the three-state Known/Absent/Failed verdict and look_up_names, which the issue points to as the pattern to reuse) and src/cmd/currency.rs's fee_currency(), which today just returns &settings.profile.currency. A grep for settings.profile.currency / fee_currency / native_currency_id across src/ confirms the issue's own list: roughly twenty call sites across src/cmd/currency.rs, send.rs, id.rs, wallet.rs, lifecycle.rs and airgap.rs all label an amount or fee row from the config ticker rather than a chain-verified name, while tx.rs already does it the right way (transfer.fee_currency resolved through verdict(names, ...)) — which is the precedent the issue wants copied. .github/claude-risk-paths.yml puts send.rs, airgap.rs, id.rs and lifecycle.rs in the high tier and currency.rs/wallet.rs/currency_name.rs in medium, so touching all six makes this a high-risk PR outright. The issue itself is candid that it deliberately left the shape open ('Suggested shape', not a decision) and flags an explicit open question about whether --json should carry the fee currency on mint/preconvert/convert. It gives no acceptance criterion I can turn into a concrete assertion — no exact panel wording, no exact JSON field name/shape, no decision on what an air-gapped sign step (no node in hand) should print instead of a resolved name, and no decision on whether the ~20 sites land in one PR or several. I could not construct a single 'given command X, expect output Y' from the text as written. The prior automated comment on this issue (test/a/b placeholders) is visibly a broken run, not a real prior verdict, so I disregarded it and re-derived independently.
Machine-readable verdict
{ "analyse": "I read src/currency_name.rs (the three-state Known/Absent/Failed verdict and look_up_names, which the issue points to as the pattern to reuse) and src/cmd/currency.rs's fee_currency(), which today just returns &settings.profile.currency. A grep for settings.profile.currency / fee_currency / native_currency_id across src/ confirms the issue's own list: roughly twenty call sites across src/cmd/currency.rs, send.rs, id.rs, wallet.rs, lifecycle.rs and airgap.rs all label an amount or fee row from the config ticker rather than a chain-verified name, while tx.rs already does it the right way (transfer.fee_currency resolved through verdict(names, ...)) — which is the precedent the issue wants copied. .github/claude-risk-paths.yml puts send.rs, airgap.rs, id.rs and lifecycle.rs in the high tier and currency.rs/wallet.rs/currency_name.rs in medium, so touching all six makes this a high-risk PR outright. The issue itself is candid that it deliberately left the shape open ('Suggested shape', not a decision) and flags an explicit open question about whether --json should carry the fee currency on mint/preconvert/convert. It gives no acceptance criterion I can turn into a concrete assertion — no exact panel wording, no exact JSON field name/shape, no decision on what an air-gapped sign step (no node in hand) should print instead of a resolved name, and no decision on whether the ~20 sites land in one PR or several. I could not construct a single 'given command X, expect output Y' from the text as written. The prior automated comment on this issue (test/a/b placeholders) is visibly a broken run, not a real prior verdict, so I disregarded it and re-derived independently.", "begruendung": "The issue (src/cmd/currency.rs:2129 fee_currency(), confirmed still returning &settings.profile.currency, and the ~20 call sites found across currency.rs/send.rs/id.rs/wallet.rs/lifecycle.rs/airgap.rs) accurately describes a real, unfixed problem and correctly points at src/currency_name.rs's existing three-state verdict as the pattern tx.rs already follows. But it is written as analysis plus a 'suggested shape,' not a specification: it names an open question on --json scope without answering it, gives no exact row wording or JSON shape to assert on, and leaves the air-gap case (no node in hand) undecided. At roughly twenty call sites across four high-risk files it is also too large for one review as written.", "estimated_diff_lines": 750, "plan": { "ansatz": "", "dateien": [], "tests": [] }, "risk": "high", "risk_begruendung": "The fix as scoped by the issue touches src/cmd/send.rs, src/cmd/airgap.rs, src/cmd/id.rs and src/cmd/lifecycle.rs (all listed `high` in .github/claude-risk-paths.yml, because they move money, run the air-gap ceremony, or control identities) plus src/cmd/currency.rs, src/cmd/wallet.rs and src/currency_name.rs (`medium`). Any path set that reaches the high tier makes the whole PR high.", "rueckfragen": [ "Should this land as one pull request touching all six files (currency.rs, send.rs, id.rs, wallet.rs, lifecycle.rs, airgap.rs), or split along the lines the issue itself describes, given close to twenty separate call sites are involved and four of the six files are `high` blast radius?", "For air-gapped `sign`, which never has a node in hand, what should the fee currency label show — the profile ticker unchanged, an explicit unresolved/offline marker, or something else? The issue's 'resolve it once, where the node is already in hand' implies node-backed commands only but does not say what the offline steps should do instead.", "Is adding a fee_currency/fee_currency_name field to `--json` on `currency mint`, `preconvert` and `convert` in scope for this issue, or deferred the way #67 deferred the panel fix — the issue raises it as 'worth checking' rather than deciding it?", "When the lookup comes back Absent or Failed (src/currency_name.rs's three-state verdict), what exact text should each fee/amount row show in place of the config ticker, and should the panel rendering and the --json field say the same thing or different things?", "Is the name looked up once per command invocation and threaded to every row it labels, or does each call site do its own lookup — this decides whether the new logic is one shared helper in src/currency_name.rs or something built per command?" ], "split_vorschlag": [ "Shared native-currency-name resolution helper - add a resolve/verdict helper in src/currency_name.rs that asks the node once for the chain's own currency name and returns the same Known/Absent/Failed verdict look_up_names already uses, with tests mirroring tests/currency_name.rs's scripted-node cases.", "Thread the resolved fee currency through wallet and currency panels - src/cmd/wallet.rs and src/cmd/currency.rs (fee_currency, mint/preconvert/convert/launch_panel) stop reading settings.profile.currency directly and use the resolved verdict, with tests asserting the row text for each of Known/Absent/Failed.", "Thread it through send, id and lifecycle panels - src/cmd/send.rs, src/cmd/id.rs and src/cmd/lifecycle.rs adopt the same helper for their fee/amount rows, with tests.", "Decide and implement the air-gap case - src/cmd/airgap.rs's plan/sign/broadcast split has steps with no node in hand; this sub-issue settles and implements what an offline step should print instead of a resolved name.", "Carry fee_currency in --json for mint, preconvert and convert - the open question the issue raises but does not decide, kept separate exactly as #67 kept it separate from the panel fix." ], "verdict": "needs_spec" }Spec gate · run log