Skip to content

Atomic swaps: restore offer publishing, UI fixes, generic Ethereum RPC settings, any-asset/any-token swaps - #1269

Open
Maxnflaxl wants to merge 12 commits into
masterfrom
issue/1267
Open

Atomic swaps: restore offer publishing, UI fixes, generic Ethereum RPC settings, any-asset/any-token swaps#1269
Maxnflaxl wants to merge 12 commits into
masterfrom
issue/1267

Conversation

@Maxnflaxl

@Maxnflaxl Maxnflaxl commented Jul 17, 2026

Copy link
Copy Markdown
Member

Warning

DO NOT MERGE UNTIL BeamMW/beam#2075 IS MERGED.

UI side of the atomic-swap repair and extension tracked in #1267. Depends on BeamMW/beam PR issue/2070 — the submodule bump in this branch points at its head; merge that PR first. One commit per issue plus small standalone fix and cleanup commits.

What's in here

#1017 / #1073 — offer publishing restored (submodule bump). Brings the core-side fixes: persisted swap offer publisher address (publishing has thrown ForeignOfferException since 7.3), CLI swap-coin balance validation, the post-funding lock-tx fee-rate check, the fly_client kernel-check fix that unbreaks swap redeems, the generic Ethereum JSON-RPC endpoint, and the core half of any-asset/any-token swaps.

#1129 — first-person labels. Swap amounts are always rendered from the viewer's perspective, but the bare SEND/RECEIVE labels left it ambiguous. The atomic-swap and asset-swap offer tables and the swap create/accept screens (including the token info dialog) now read I SEND / I RECEIVE. Obsolete string ids with no remaining references were dropped; the shared general-send id is untouched.

#1107 — settings section title. "Ethereum node" → "Ethereum" (the section configures the account seed and tokens, not just a node).

BeamMW/beam#1103 — in-progress swap safety note. While coins are locked, the swap details show: "While the swap is in progress, if the other side goes offline your coins will be automatically unlocked in %1 at most." The figure derives from the actual refund-height window (the same computation as the existing in-progress state details), never a hardcoded value, and disappears in terminal states.

#1268 — Ethereum connectivity: Infura or any JSON-RPC endpoint. A provider switcher (same pattern as the Node ↔ Electrum switch): Infura keeps the project-ID flow unchanged; Custom RPC takes any endpoint URL (Alchemy, QuickNode, Chainstack, Ankr, self-hosted). A "Check connection" button reports the detected chain and latest block (eth_chainId/eth_blockNumber) before any swap is attempted; wrong-network endpoints are called out explicitly ("Connected to %1, but Ethereum Mainnet is required"); feedback clears whenever the endpoint fields change, and the check is disabled while edits are unapplied.

#1166 — any Confidential Asset and any ERC-20 token. - Offer creation: the wallet's Confidential Assets and stored custom tokens appear as regular entries in the main currency dropdowns, with their real icons — no separate picker. Assets ride the BEAM side (either direction); balance checks run against the asset, fee checks against BEAM. - Ethereum settings: an add-custom-token flow — enter a contract address, the wallet reads symbol()/decimals() from the contract for confirmation; tokens are stored per wallet and offered as swap currencies. Token amounts convert with the token's real decimals end-to-end. - Accepting: the confirmation screens show the offered token's contract address, symbol and decimals with an explicit warning ("Verify this token contract address carefully. Anyone can create a token with any name."), and the Beam-side asset id/unit name; receiving an asset warns that a small BEAM balance is required for the redeem fee and validates it. - Accepting an asset offer runs its balance/change/fee computations against the offer's asset (BEAM only for the fee), and the redeem-fee BEAM check applies on whichever side receives the asset. - Offer list, rate, currency filter and fit-my-balance are asset- and token-aware with real symbols (contract matching is case-insensitive for EIP-55 addresses), including in-flight swaps on the transactions tab. - Custom-token balance cards on the swaps screen show live balances and the same connection states/settings link as the built-in coin cards.

Settings UX. "Connect more currencies" no longer unfolds every unconnected coin's settings section at once; it navigates with all sections folded (explicit per-coin links still unfold their own section).

Fee-panel fixes. - The recommended fee rate refreshes live: the swap screens re-query the cached rate whenever a swap-coin client reports a new estimate (previously a one-shot read at screen load — opening the screen before the first eth_gasPrice response left "0 / connection error" stuck forever), and an untouched, unfocused fee input adopts the recommendation when it arrives (a field the user is editing is never overwritten). - The fee unit label ("gwei" etc.) is a proper layout child again instead of a zero-sized overlay hack that bled outside the panel on fill-width inputs. - Receiving on the Ethereum side with too little ETH for the redeem-tx gas now says exactly that — "Not enough ETH to pay the redeem transaction fee (%1 needed)" — instead of the generic not-enough-funds message, and ETH-side withdraw fees render in ETH rather than six-digit gwei.

Cleanups. Two refactor commits dedupe what the feature work introduced: one tokenWalletDecimals() for the min(decimals, 9) wire-units rule, shared ERC-20 symbol/amount formatting and token-side helpers in swap_utils, the token-info lookup folded into core Client (GetTokenInfo/OnTokenInfo) instead of a parallel reactor bridge in the UI model, getDefaultFee delegating to getRecommendedFee, and the endpoint-check feedback bound directly to the settings viewmodel.

i18n

All new strings are id-based with English sources; every locale except rs_RS.ts regenerated via lupdate; en_US.ts entries finished.

Testing / QA

The branch builds end-to-end with the bumped submodule (macOS). Core-side behavior is covered by the beam PR's test suites (including CA swaps in both directions against a real node). UI-side manual QA checklist:

  • Offer tables and create/accept screens show I SEND / I RECEIVE (atomic + asset swaps, own + foreign offers).
  • Create Offer: a Confidential Asset and a custom token are pickable in the main currency dropdowns (icons, correct decimals); the recommended Ethereum fee rate fills in by itself once the endpoint responds.
  • Ethereum settings: switcher round-trip; Check connection against a valid endpoint (✓ with chain + block), a garbage URL (✗), and a non-mainnet endpoint on a mainnet build (explicit wrong-network message); settings persist across restart.
  • A live custom-token swap: add token in settings, publish an offer, verify the ERC-20 panel and warning on the accepting wallet, confirm the on-chain amount matches the typed value for a token with fewer than 9 decimals.
  • A CA swap on testnet: pick the asset in the currency dropdown, acceptor sees asset id/unit name and the BEAM-fee note, transactions tab shows the asset unit name while in flight.
  • Swap details during any swap: the auto-unlock note appears while locked and disappears on completion.

Closes #1017, #1073, #1129, #1107, #1268, #1166. Closes BeamMW/beam#1103. Part of #1267.

Maxnflaxl added 12 commits July 16, 2026 23:50
Swap amounts are always rendered from the viewer's perspective (the
offer tables flip sides for foreign offers via
SwapOfferItem::isSendBeam()), but the bare SEND/RECEIVE labels left it
ambiguous whose side is meant. Use explicit first-person labels in the
offer tables and on the swap create/accept screens (atomic and asset
swaps, token info dialog), consistent with the MY OFFERS tab. Obsolete
string ids are dropped.
The section configures the account seed and tokens, not just a node.
… note

Adds a new attention row to the atomic swap transaction details panel
warning that locked coins are automatically unlocked (refunded) if the
counterparty goes offline while the swap is in progress, and for how
long at most. Reuses the exact refund-height condition and time
conversion getStateDetails()/getInProgressNormalStr() already use, and
only shows for the same in-progress states that produce the existing
in-progress note.
Replace the Infura-only Ethereum connectivity with a provider switcher:
Infura (project ID, unchanged) or any Ethereum JSON-RPC endpoint URL
(Alchemy, QuickNode, Chainstack, Ankr, self-hosted). A connection check
reports the detected chain and latest block via eth_chainId /
eth_blockNumber before any swap is attempted.
Brings the core-side atomic swap fixes: persisted swap offer publisher
address (fixes offer publishing broken since 7.3), CLI swap-coin
balance validation, post-funding lock-tx fee-rate check, and the
generic Ethereum JSON-RPC endpoint support the settings UI now exposes.
Note: the referenced submodule commit lives on the beam issue/2070
branch and must be pushed before this branch.
Beam-side asset picker at offer creation (asset id + unit name stamped
into the offer parameters); ethereum settings gain an add-custom-token
flow that reads symbol()/decimals() via the bridge's getTokenInfo and
stores tokens per wallet; the acceptor screens show the offered token's
contract/symbol/decimals and the Beam-side asset id/name and require
explicit confirmation, with a note that receiving an asset requires a
BEAM balance for the redeem fee; offer list, rate, currency filter and
fit-my-balance are asset- and token-aware with real symbols.
…urrencies"

Opening the swap connectivity settings from the Connect-more-currencies
link unfolded the settings of every unconnected coin at once. Navigate
to the section with everything folded instead; explicit per-coin links
still unfold their own section.
… ETH

Receiving on the Ethereum side requires ETH for the redeem tx gas; the
check reported the generic "not enough funds", pointing at the token
amount instead of the missing ETH. Say what is missing and how much.
ETH-side withdraw fees now render in ETH instead of 6-digit gwei.
One tokenWalletDecimals() for the min(decimals, 9) wire-units rule
(was written out in seven places), shared ERC-20 symbol/amount
formatting, one isTokenSide/effectiveSwapDecimals pair instead of
per-viewmodel copies, one fee-rate-clients wiring helper and one
token-lock ETH gas check. Drops the no-op StripUnit detour.
getDefaultFee delegates to getRecommendedFee (bodies were identical
except the BEAM branch), the token-info forwarder slot becomes a
signal-to-signal connection, and the endpoint-check feedback fields
bind directly to the settings viewmodel instead of being push-mirrored
around a broken declarative binding.
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.

atomic swaps not working on desktop wallet 7.3 Add text in transaction details (atomic swap)

1 participant