feat(boltz): Boltz submarine & reverse swaps#116
Draft
coreyphillips wants to merge 1 commit into
Draft
Conversation
Integrate Boltz submarine (onchain -> Lightning) and reverse
(Lightning -> onchain) swaps behind the UniFFI surface.
Swap keys and reverse-swap preimages are derived deterministically from
the wallet seed via Boltz's BIP85 scheme (SwapMasterKey/derive_swapkey,
Preimage::from_swap_key). No key material is persisted: boltz.db stores
only a monotonic per-swap derivation index, so a leaked database cannot
move funds and swaps are recoverable from the seed alone (or via Boltz's
rescue API if boltz.db is lost).
- Submarine create/refund and reverse create/claim, with cooperative
key-path then script-path fallback (delegated to boltz-client).
- Managed WebSocket updates stream that auto-claims confirmed reverse
swaps; mnemonic held in memory only for the stream's lifetime.
- Atomic, collision-free swap-index reservation; schema user_version
anchor; input validation on create.
- Idempotent claim/refund (returns the recorded txid without
re-broadcasting).
- SQLite persistence, typed lifecycle status with forward-compatible
Unknown { raw }, and recovery/listing APIs.
- Unit tests for status mapping, DB round-trip, index reservation, and
deterministic derivation; ignored live E2E test against the Boltz API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a
boltzmodule integrating Boltz submarine (onchain → Lightning) and reverse (Lightning → onchain) swaps behind the UniFFI surface, for iOS/Android/Python.The dangerous cryptography (MuSig2 Taproot cooperative signing, swap scripts, claim/refund tx construction) is delegated to the
boltz-clientcrate. This module adds deterministic key management, SQLite persistence, lifecycle tracking, automatic claiming, and the FFI surface.Key design decision: deterministic keys, no stored secrets
Swap keys and reverse-swap preimages are derived from the wallet seed via Boltz's BIP85 scheme (
SwapMasterKey/derive_swapkey,Preimage::from_swap_key) — never random, never persisted.boltz.dbstores only a monotonic per-swap derivation index.Consequences:
boltz.dbis lost.mnemonic(+ optional BIP39 passphrase) now flows through the create/claim/refund/start-updates FFI calls. The background updates stream holds the mnemonic in memory only for its lifetime (dropped on stop) to auto-claim. The passphrase must match the wallet's, or derived keys won't control the funds.What's included
transaction.confirmed(not mempool, to avoid revealing the preimage against an unconfirmed lockup).PRAGMA user_versionmigration anchor; input validation on create.Unknown { raw }; recovery/listing APIs.Testing
cargo build, all 9 boltz unit tests, clippy, and fmt are clean. Tests cover status mapping, DB round-trip/recovery, monotonic index reservation, and deterministic derivation. An ignored live E2E test creates a real reverse swap and cryptographically validates the locally-derived redeem script + invoice against Boltz's response (no broadcast).Known follow-up: the claim/refund broadcast paths are not yet covered by an automated test — they need a regtest Boltz + Electrum stack. Recommended as a follow-up.