Ferry: Multi-chain HTLC Web Service

Project Name: Ferry: Multi-chain HTLC Web Service

Description: Ferry v0.1.0 is a browser app for trustless atomic swaps between Zenon and other chains. It has no backend, needs no full node, and never holds a key for either chain. The whole deployable is a folder of static files.

Cross-chain swaps have worked since 2017, but nobody used them, because every implementation made each side run a synced node and copy hex strings by hand. Ferry removes both problems:

  • Funding an HTLC is just a payment to an ordinary address. Any wallet can pay it, including a hardware wallet, a phone, or an exchange withdrawal.
  • Spending out of a contract uses a throwaway key that can only move coins already inside that one contract.
  • The Zenon leg is signed by the Syrius browser extension. Ferry builds the htlc call and the extension signs it, so the Zenon key never reaches the page.

The result is that a swap only needs a browser tab and the wallets you already have.

Why it matters for Zenon: it gives ZNN and every ZTS a trustless route to and from BTC and SOL without a bridge, a custodian, or an exchange listing. Syrius’s P2P swaps already use NoM’s embedded HTLC contract between two Zenon users. Ferry takes that contract across chains, from a browser, with no CLI.

URL: https://github.com/sol-znn/ferry-web

Team:

  • sol: design, implementation, testing, documentation.
  • 0x3639: security audit, remediation.
  • edgepillar: security audit, remediation.

Phases

Phase 1 is delivered, live on mainnet, and under audit.
Phase 2 is partially delivered.
Phase 3 is left open for the community to shape and will be filed separately.

Phase 1: BTC ⇄ Zenon atomic swaps (delivered, live on mainnet)

High-level overview of main tasks:

  • Swap engine in Go compiled to WebAssembly: contract construction, a strict template parser, local script-engine verification, leg-ordering rules, and Esplora and Zenon clients
  • Zenon leg through the Syrius extension: htlc.Create / Unlock / Reclaim built as bytes and signed by the wallet, with znn-cli commands as a fallback
  • Strict verification: refuses an HTLC with the wrong hash, payee, token or amount, one about to expire, or one on the wrong side of the Bitcoin locktime. A check Ferry can’t perform is never reported as passed
  • Preimage recovery with no CLI or explorer, read from the HTLC contract’s own chain even if the counterparty goes silent
  • Auto Mode: funds, builds and redeems once armed, but never signs, skips a check, or refunds on its own
  • Live sessions over Nostr: values move between the two browsers, encrypted and signed, and every value goes through the same checks as a hand-pasted one. There is no preimage field
  • Offer board on public Nostr relays: signed posts, optional wallet-ownership proofs, presence dots, and sealed takes
  • Recovery that doesn’t depend on the site: a refund pre-signed as soon as funding is seen, an offline Recover page, and export/import
  • Security remediation: a source-level review of be879e1b (11 Sep 2026) reported 7 findings (4 high, 2 medium, 1 low). All 7 are fixed with regression tests

Completion of Phase 1 will be measured by:

  • :white_check_mark: A full swap of 10,000 sat for 1 ZNN, settled by clicking through the real page in two browser profiles on Bitcoin and Zenon mainnets, with the Zenon leg published through the Syrius extension and read back from the chain independently
  • :white_check_mark: All 7 review findings fixed with regression tests, and CI green (go test plus a smoke test of the shipped ferry.wasm)
  • :hourglass_not_done: Security audit by @0x3639 and @edgepillar completed, and any findings addressed

Phase 2: BTC / SOL / ZTS to any (partially delivered)

High-level overview of main tasks:

  • Generalized swap model (swapoffer2:) with a separate leg module per chain, covering BTC⇄ZTS, ZTS⇄ZTS, SOL⇄ZTS, and SOL⇄BTC
  • Solana HTLC program (ferry-htlc) with two branches that both pay fixed addresses. redeem and refund can be called by anyone :white_check_mark:
  • Phantom wallet support alongside Syrius and UniSat :white_check_mark:
  • A board gate requiring a proven address on every chain the offer settles on :white_check_mark:
  • Deploy the Solana program on a public cluster
  • Merge v2 into the main Ferry deployment, carrying over the Phase 1 remediations
  • Update the in-app user guide for the multi-chain flows
  • Security remediation

Completion of Phase 2 will be measured by:

  • :white_check_mark: BTC⇄ZTS deployed and live on mainnet
  • :white_check_mark: The refund drill passing on all three test chains: a Bitcoin refund, htlc.Reclaim, and a Solana refund
  • :hourglass_not_done: ZTS⇄ZTS, SOL⇄ZTS and SOL⇄BTC each settled end to end through the UI on public test networks, and covered by the smoke suite
  • :hourglass_not_done: The Solana program deployed on a public cluster, and v2 live as the main Ferry deployment
  • :hourglass_not_done: Security audit by @0x3639 and @edgepillar completed, and any findings addressed

Phase 3: Open for suggestions (not requested in this proposal)

Candidates:

  • Chains: EVM (one Solidity HTLC for ETH, BNB, Base and Arbitrum), Litecoin, Dogecoin and Bitcoin Cash (same script template), Zcash (transparent addresses), Lightning hold invoices, and Monero. Monero has no HTLC, so it needs an adaptor-signature protocol instead and is a research item rather than an integration.
  • Features: passphrase encryption for swap records, RBF / CPFP fee bumping, an adversarial review of sessions, a watchtower, and indexer integration

Phase 3 will be filed as its own proposal once its scope and cost are agreed in this thread.


Funding

Total Requested Funding = 15,000 ZNN and 150,000 QSR (Phases 1–2)

Project Duration

  • Phase 1: 2 weeks (delivered)
  • Phase 2: 2 weeks (ZTS⇄ZTS and the Solana pairs deployed on devnet)

How did you calculate your budget?

  • Scope. Phase 1 is two products in one: the swap engine and the coordination layer (sessions, board, Auto Mode and wallet protocol), plus documentation, test harnesses, and the security remediation. Phase 2 adds a third chain, a Solana program, and ZTS⇄ZTS swaps.
  • Comparable proposals. Maximum-size requests of 5,000 ZNN / 50,000 QSR have funded the combined SDK and CLI updates (about 200 h) and the Zenon professional documentation. The Bridge Frontend asked for 15,000 ZNN / 150,000 QSR, the same total as here.

Project and Payment Milestones:

Phase 1
Funding Request: 67% (10,000 ZNN and 100,000 QSR)
Duration: 2 weeks, delivered

Split:

  • sol: 8,000 ZNN, 80,000 QSR
  • Auditors: 2,000 ZNN, 20,000 QSR

Phase 2
Funding Request: 33% (5,000 ZNN and 50,000 QSR)
Duration: 2 weeks
Status: ZTS⇄ZTS, SOL⇄ZTS and SOL⇄BTC deployed on devnet

Split:

  • sol: 4,000 ZNN, 40,000 QSR
  • Auditors: 1,000 ZNN, 10,000 QSR

Other Information

Risks, Assumptions, Known Issues, Dependencies:

  • Known gaps:
    • BTC⇄ZTS is live on mainnet. The rest of Phase 2 (ZTS⇄ZTS, SOL⇄ZTS, SOL⇄BTC) has only been tested on devnet, and the Solana program isn’t on a public cluster yet.
    • Swap records are unencrypted in localStorage.
    • There is no RBF or fee bumping (the offline Recover page is the manual fallback).
    • The first visit downloads about 3 MB gzipped.
  • Dependencies:
    • Public Zenon nodes serving wss:// on port 35998, which works today
    • The Syrius browser extension for one-click Zenon legs (znn-cli is the fallback)
    • Public Nostr relays for sessions and the board (optional; hand-pasting still works)
    • A deployed Solana program for SOL legs

Have you previously submitted a proposal (either in Accelerator-Z or Incubator)?

On-chain filing

Project name Funds
Ferry: BTC Swaps (1/3) 5,000 ZNN / 50,000 QSR
Ferry: BTC Swaps (2/3) 5,000 ZNN / 50,000 QSR
Ferry: Multi-chain Swaps (3/3) 5,000 ZNN / 50,000 QSR

Technical documentation (in the repository):

  • docs/SECURITY.md: the browser threat model
  • docs/ARCHITECTURE.md
  • docs/EXTENSION-WALLET.md: the Syrius boundary and the live runs
  • docs/BOARD.md
  • docs/TESTING.md
  • audits/: the review report and remediation log