Skip to content

Add the eCash.com (ECX) fork plugin - #457

Open
j0ntz wants to merge 2 commits into
masterfrom
jon/ecash-ecx-fork
Open

Add the eCash.com (ECX) fork plugin#457
j0ntz wants to merge 2 commits into
masterfrom
jon/ecash-ecx-fork

Conversation

@j0ntz

@j0ntz j0ntz commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

CHANGELOG

Does this branch warrant an entry to the CHANGELOG?

  • Yes
  • No

Dependencies

none

Description

Adds ecashcom, a UTXO plugin for eCash (ECX), and the generic transaction-building support its replay protection needs. Recreates #456 with the fork research written down and several defects corrected.

Asana: https://app.asana.com/0/1215088146871429/1217562074592399

What ECX is

ECX is a hard fork of Bitcoin by Layer Two Labs that activates drivechains (BIP300/BIP301). Every Bitcoin address is credited ECX 1:1 at the fork block; Bitcoin itself is untouched. The fork point is Bitcoin block ~963,648, targeted for 2026-08-22 ~15:00 UTC (ecash.com's own banner currently says ~973,728, so the exact height is still moving). It is a different chain from the eCash this repo already ships as ecash/XEC, which is the Bitcoin ABC project. They share a brand name and nothing else, which is the main reason this plugin needs care.

Sources: ecash-com/fast-facts, ecash.com, drivechain.info/dev.txt.

Replay protection, and why the sequence number matters

The fork's opt-in replay protection is a magic locktime: a transaction with nLockTime == 499999999 (LOCKTIME_THRESHOLD - 1) is treated as final by eCash nodes (a change in IsFinalTx), while Bitcoin reads that value as a block height roughly 500 million blocks away and rejects the transaction as non-final. The asymmetry is one directional: it stops an ECX transaction from replaying onto Bitcoin, and the Bitcoin side is protected by splitting order instead.

The protection only holds while at least one input sequence is below 0xffffffff, because a transaction whose inputs are all final has its locktime ignored. So makeTx now does both: it writes the locktime into the PSBT and drops the sequence to 0xfffffffe when RBF is off. With RBF on, the existing 0xfffffffd already satisfies the requirement, and the tests cover both paths plus a control asserting coins without a replay locktime are untouched.

The mechanism is expressed as a generic CoinInfo.replayProtectionLocktime, so any future fork using the same trick just sets the field.

Key derivation

Keys and addresses are byte-for-byte Bitcoin: P2PKH 0x00, P2SH 0x05, bech32 bc, WIF 0x80, xpub/xprv 0x0488B21E/0x0488ADE4. Confirmed independently by the xpub magics in ecash-com/blockbook's ECX coin config.

The plugin therefore uses coin type 0. That is not a shortcut: ECX has no SLIP-44 index of its own, and the forked coins live on Bitcoin's derivation paths, so any other coin type would derive addresses that hold nothing and make the Bitcoin split useless. ECX is registered in Bitcoin's forks list for all four formats.

Naming

The XEC plugin already displays as "eCash". Layer Two Labs disambiguates its own chain as "eCash.com" (the label and alias in their Blockbook coin config, where the alias is literally ecashcom), so this plugin uses that name and that pluginId. Two wallet rows both reading "eCash" is the alternative.

What the fork has not published, left empty rather than guessed

The chain is not live yet. Nothing below is filled in with a plausible-looking value:

  • No explorer. addressExplorer and transactionExplorer are empty strings and blockExplorer is omitted. Every ECX service still runs against the drynet dry-run networks, including in Layer Two Labs' own wallet: ecash-wallet-mobile's NetworkRegistry.swift ships .ecash with explorerTxTemplate: "https://explorer.drynet3.drivechain.dev/tx/{txid}", and they added a remote-config key (remote.svc.explorer.<network>.template) so they can push a real URL after launch. No ecash.com explorer host resolves, and none appears anywhere in the site's JS bundle. An empty string is the "no explorer" signal the app already handles, so the explorer rows stay hidden until a host exists.
  • No Blockbook endpoint, so blockbookServers is empty and a wallet cannot sync. This is structural, not a delay: the fork's own stack is Electrum and Esplora (their wallet uses BDK's ElectrumClient/EsploraClient, and their backends doc states there is no bitcoind-RPC client). Blockbook exists only as ecash-com/blockbook branch ecash-com, whose ecashcom coin config still carries TODO binary URLs and an empty explorer_url. Someone has to deploy one from that config.
  • No maximumFeeRate. It is derived from a USD price, ECX does not trade (ecash.com is still running a /list-ecx page soliciting listings), and a made-up price yields a cap that guards nothing. The field is omitted, so the signing library's own default applies. The sat/byte fee levels are Bitcoin's, carried over because the fork keeps Bitcoin's block size, supply and divisibility.
  • No denomination symbol for ECX. XEC uses e and the fork has not published one, so only the sats unit carries a symbol.
  • The replay scheme could still change. drynet1 and drynet2 used a magic transaction version (0x00BFBF3F) instead of the locktime. The locktime is corroborated by their shipping wallet (case .ecash: return UInt32(499_999_999) // LOCKTIME_THRESHOLD - 1), but reverify against the launch branch and drivechain.info/dev.txt before go-live.
  • The fork height is unsettled and deliberately absent from this plugin. fast-facts says ~963,648, their wallet's constant comments real eCash mainnet: 964_000, and ecash.com's banner currently says ~973,728.

Changes vs PR #456

  • Display names disambiguated from XEC, using Layer Two Labs' own "eCash.com" label.
  • No invented values: Add ECX eCash fork support #456 shipped explorer.ecash.com URLs (a host that does not resolve) and a placeholder USD price for the fee cap. Both are gone, with the reason recorded in code.
  • CHANGELOG entry added.
  • Tests cover the RBF path and a non-ECX control; currency-registry assertions live in test/common/utxobased/info/all.spec.ts and the signing tests in a per-coin file, matching this repo's layout, rather than in Metadata.spec.ts.

Testing

  • npm run lint, npm run types, npm test (1276 passing, 8 pending), and verify-repo.sh all pass.
  • New unit tests: ECX transaction signed with locktime 499999999 and sequence 0xfffffffe; same with RBF on (0xfffffffd); Bitcoin unchanged (locktime 0, sequence 0xffffffff); registry assertions for the XEC/ECX split and plugin-id uniqueness.
  • Linked into edge-react-gui via updot and driven on the iOS simulator: ECX appears as a creatable asset ("ECX / eCash.com"), the wallet creates, and its scene opens. Screenshots are attached below.
  • Opening that wallet crashed the app until a GUI-side fix, see Add eCash.com (ECX) wallet metadata and guard missing currency entries edge-react-gui#6162. The crash is not specific to this plugin (any pluginId with no SPECIAL_CURRENCY_INFO entry hits it) but PR Add ECX eCash fork support #456 would have shipped into it.
  • The chain does not exist yet and has no servers, so balance sync and a real send cannot be exercised until launch.

Chains that fork from Bitcoin can mark their transactions with an
nLockTime value that their own nodes treat as final and the parent chain
rejects as non-final. Coins can now declare that value through
CoinInfo.replayProtectionLocktime, and makeTx writes it into the PSBT
while holding input sequence numbers below 0xffffffff so the locktime is
actually enforced.
@j0ntz

j0ntz commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

📸 Test evidence

ecx create row

ecx create row

ecx wallet created

ecx wallet created

Captured by the agent's in-app test run (build-and-test).

@j0ntz
j0ntz force-pushed the jon/ecash-ecx-fork branch from 48aa9b1 to cccede1 Compare August 18, 2026 00:30
@j0ntz
j0ntz marked this pull request as ready for review August 18, 2026 00:30
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

ECX is the ecash.com hard fork of Bitcoin, which credits every Bitcoin
address 1:1 at the fork block and is unrelated to the Bitcoin ABC eCash
chain this repo already ships as XEC. It reuses Bitcoin's key and address
formats and Bitcoin's coin type, so a Bitcoin wallet can split into it
and find the forked coins, and it marks every transaction with the fork's
replay protection locktime.
@j0ntz
j0ntz force-pushed the jon/ecash-ecx-fork branch from cccede1 to 22d81a8 Compare August 18, 2026 08:02
@samholmes

Copy link
Copy Markdown
Contributor

maybe a better pluginId is ecashbitcoin

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.

2 participants