Draft: Add initial eCash (XEC) chain support to THORNode via shared UTXO client

Summary

This draft merge request introduces an initial eCash (XEC) integration into THORNode following the existing shared UTXO client architecture.

This change does not introduce a dedicated ECashClient wrapper. Instead, it wires XEC into the same shared utxo.NewClient(...) model already used by BTC, BCH, LTC, DOGE, and ZEC, with chain-specific handling gated by ChainID.

The key protocol-specific difference addressed in this patch is that Bitcoin ABC exposes several RPC transaction/output values in XEC units rather than BTC/BCH-style 1e8 whole-coin units. Because of that, this patch introduces explicit XEC ↔️ sats conversion helpers and avoids blindly reusing BTC/BCH assumptions.

It also hardens XEC address handling by requiring explicit ecash: CashAddr prefixes and disabling unverified MockNet prefix handling until canonical values are confirmed.

Scope of this draft

This MR covers:

  • registration of XECChain and XECAsset
  • Bifrost chain loading through the shared UTXO client
  • XEC config wiring and default chain config
  • XEC-specific UTXO helpers in bifrost/pkg/chainclients/utxo/ecash.go
  • explicit XEC RPC amount conversion (1 XEC = 100 sats)
  • stricter CashAddr validation / detection using ecash:
  • fail-closed handling for unverified XEC MockNet address parameters

This MR does not yet implement:

  • Avalanche finality integration (isfinaltransaction, finalized_blockhash)
  • full XEC-specific unit test coverage
  • verified MockNet/test/reg prefix support beyond fail-closed behavior

Why this follows the repo’s architecture

THORNode’s current pattern for UTXO chains is a shared client model, not one client per chain wrapper. This MR follows that pattern.

Instead of introducing a separate XEC client abstraction, it extends the existing UTXO flow by:

  • adding common.XECChain
  • wiring XEC through utxo.NewClient(...)
  • adding chain-specific helpers where required
  • reusing BCH-like transaction/script handling where appropriate
  • isolating XEC-specific unit conversions and address rules

Files touched

Chain / asset identity

  • common/chain.go
  • common/asset.go

Bifrost loading

  • bifrost/pkg/chainclients/loadchains.go

Config

  • config/config.go
  • config/default.yaml

UTXO helpers and amount conversion

  • bifrost/pkg/chainclients/utxo/ecash.go
  • related UTXO code paths that consume RPC float values and convert them into internal integer accounting

Address / pubkey hardening

  • common/address.go
  • common/pubkey.go

Key protocol-specific considerations

1. RPC amount semantics

Bitcoin ABC RPCs expose relevant values such as vout.value, listunspent.amount, and gettxout.value in XEC units. This differs from the BTC/BCH-style assumption often represented through btcutil.NewAmount(...).

For XEC, this draft uses:

  • sats = round(xec * 100)
  • xec = sats / 100

This keeps THORNode internal accounting in integer base units while respecting Bitcoin ABC’s RPC semantics.

2. Address safety

Because XEC and BCH share BCH-like CashAddr mechanics, this patch explicitly requires ecash: prefixes for XEC validation and detection to avoid accidental BCH/XEC ambiguity.

It also disables MockNet XEC address parsing/derivation until the canonical prefix is verified, preferring fail-closed behavior over guessing.

3. Conservative config posture

This draft avoids optimistic assumptions in chain policy areas that still need verification. In particular, XEC mempool ancestor defaults are set conservatively rather than assuming “no limit”.

Current limitations / TODOs

  • verify canonical XEC MockNet/test/reg CashAddr prefixes
  • add XEC unit tests for:
    • address validation
    • pubkey derivation
    • XEC ↔️ sats conversions
    • vout/listunspent parsing paths
  • evaluate Avalanche finality integration using:
    • isfinaltransaction
    • getblockchaininfo.finalized_blockhash

Why this is a Draft MR

This is intentionally opened as a Draft because the architectural direction is correct, the initial wiring is in place, and the safety hardening is meaningful, but there are still protocol-specific validation tasks left before proposing this upstream.

Suggested review focus

Feedback is especially welcome on:

  1. whether the shared UTXO integration path is the right upstreamable direction for XEC
  2. whether the XEC RPC amount conversion handling is placed in the right load-bearing paths
  3. whether the current fail-closed address strategy is the right interim posture
  4. how Avalanche finality should best integrate into Bifrost scanning/confirmation logic in a later phase

For chain-integration study and precedent, this work was informed by reviewing the Monero chain support MR pattern (!4696) as a reference for how a new chain gets integrated into THORNode at the protocol level.

Merge request reports

Loading