Author: Rob — The story of how a whiteboard idea became a working trustless swap protocol.
It started with a piece of paper and a pen — Paul Sztorc's handwriting, to be specific. He shared a document called uniswap-sidechain.pdf and a question that seemed simple: if Bitcoin can support sidechains through BIP-300, how do we get value between chains without trusting anyone?
The original sketch laid out the full picture. At the top sat L1 Signet — a patched Bitcoin node running in test mode. Below it, a stack of L2 sidechains: Thunder for fast payments, zSide for privacy experiments, and a new idea that didn't have a name yet — what would become CoinShift.
But the sketch went further. It explored a concept Paul called the "orphanchain" — an L3 layer that would hold a copy of an existing blockchain like Monero. The idea was wild: what if you could mirror an entire altcoin's block history as a sidechain-of-a-sidechain, and use it to prove that altcoin transactions happened?
Paul framed the core idea precisely: CoinShift would be an "Alt-Txn-Prover" (ATP). It would shadow external blockchains — Monero, Litecoin, Bitcoin Cash — so that if 5 XMR was sent from address A to B, CoinShift would know. And knowing means being able to move L2 signet coins from address C to D in response.
The key insight about altcoins never leaving their own L1 was crucial. The altcoins don't get deposited into CoinShift. What moves is evidence that an altcoin transaction happened. That evidence is the ATP.
But this "shadow chain" approach raised a problem Bitcoin developers rarely worry about: orphan blocks matter. On a normal L1, orphan blocks are irrelevant and discarded — the longest chain wins, and stale blocks are forgotten. But when you're shadowing an external chain, the rules change. An orphan block on the source chain might contain a transaction that triggers a conditional payment — something like "pay if 1000 blocks are built on this fork."
Paul scribbled it on the sketch: all orphans must be kept, because any of them could trigger a payment. Every fork, every stale block, every abandoned branch. It was a fascinating constraint, but it also made the architecture enormously complex.
The first approach was SPV-based. Paul started researching how to validate block headers from different chains. BTC and LTC were easy — their pow.cpp is straightforward. But BCH had convoluted difficulty adjustment rules from many protocol changes. BSV was unclear. And Monero was the hardest — different header structures, different hashing, different everything.
Paul spent two weeks trying to get even the LTC SPV version to work. He was honest about it: he wouldn't trust his own work. The idea of bundling off-the-shelf wallets — Electrum for BTC, Electron-Cash for BCH, ElectrumSV for BSV, Feather for XMR — and using them as header validators came up. Each chain would get an advance_header_chain() function that passes new headers to the appropriate wallet for PoW validation.
But eventually a simpler path emerged: just download the full node for each chain and ask it for the blocks. Yes, it uses more disk space. Yes, it's "unnecessary" in some ways. But the disastrous consequences of a bug in custom SPV validation made full nodes the safer choice. As Paul put it: for crypto, it's safer to just let the chain's own node do the work, and we copy it.
The withdrawal problem is what made everything click. BIP-300 requires miners to vote over roughly 3 to 6 months before a withdrawal is approved. That's a security feature, but it means getting your BTC back from a sidechain is painfully slow.
CoinShift's answer: don't withdraw. Swap instead.
If Alice has L2 coins and wants BTC, she doesn't need the withdrawal process. She finds Bob, who has BTC and wants L2 coins. They trade directly, peer-to-peer, with the sidechain enforcing the swap trustlessly. Minutes to hours instead of months.
Paul laid out the roadmap in concrete steps. First: revive the QT/C++ based testchain. Fork it, name it CoinShift. Then have it download a Litecoin full node, sync the LTC blockchain, and make CoinShift aware of how many confirmations an LTC transaction has.
The target chain list was ambitious:
I agreed that BTC and LTC were the right starting point. LTC even comes with DOGE merged mining support as a bonus. The work started with a C++ drivechain fork, adding bitcoin-cli support for the main JSON-RPCs.
But the real implementation moved to Rust. The codebase became coinshift-rs, eventually finding its permanent home under the Layer Two Labs GitHub organization. I spent weeks on integration tests, finding hidden corner cases, building robust 3-participant test scenarios. Paul even tried getting the GitHub Actions CI/CD working — yolo'ing a build just to see if it would upload to the releases server, manually pulling builds out of GA when GitHub's services went down for a whole weekend.
The core design emerged from hard constraints: no intermediaries, real L1 verification, and atomic safety. The protocol has four phases:
When Alice creates a swap offer, her L2 coins are locked on-chain by the sidechain consensus. Only a valid claim transaction can unlock them.
CoinShift connects to the parent chain via standard Bitcoin Core RPC, watching for transactions matching the swap parameters — right address, right amount, right chain.
Once the L1 payment is detected, the system waits for the required confirmations (6 for BTC, 3 for BCH/LTC). Only then does the swap become claimable.
Bob submits a claim transaction on the sidechain. The locked outputs are released to him. Minutes to hours, not months.
Looking at CoinShift today, you can trace a direct line from that original sketch. The layers are still there — just refined:
The BIP-300/301 patched Bitcoin Core node. Exactly what the original sketch showed as "L1 Signet" at the top of the page.
The bridge layer that validates deposits, withdrawals, and BMM commitments between L1 and all sidechains.
The sidechain runtime with wallet, mempool, miner, and P2P networking. Merge-mined with Bitcoin via BMM.
The core innovation: a state machine that manages the full lifecycle of trustless cross-chain swaps.
Any Bitcoin Core-compatible chain can be a swap target. Currently: BTC (6 conf), BCH (3 conf), LTC (3 conf), plus Signet and Regtest for testing.
The L3 orphanchain from the original sketch? It's still an interesting idea. But CoinShift proved that you can build something immediately useful — a protocol that solves a real problem (slow withdrawals) — without needing to solve every problem at once.
CoinShift today is a Rust application that runs as a BIP-300 sidechain. It occupies slots S15 and S255, with builds uploaded automatically via GitHub Actions to the releases server. It includes:
The full documentation, protocol specifications, and download links are available at coinshift.bip300.xyz.
The roadmap includes EVM support — specifically ETH and ERC-20 tokens. USDT on Ethereum is enormously popular, and supporting any ERC-20 token standard opens the door to a much wider swap market. Paul even considered TRON support given USDT's popularity there, though we decided ETH was the more reliable foundation.
XMR remains the hardest target from the original list. Its block headers are different enough from the BTC/LTC family that SPV validation would require significant custom work. But the full-node approach we settled on means it's a matter of engineering effort, not fundamental impossibility.
The journey from Paul's sketch to a working swap engine taught us something about building on Bitcoin: start with the simplest thing that solves a real problem.
The orphanchain was intellectually fascinating. The ATP concept — proving altcoin transactions inside a sidechain — opened up enormous possibilities. But what people actually needed was a way to get BTC for their sidechain coins without waiting half a year.
CoinShift does that. And because it's built on BIP-300's infrastructure, it inherits Bitcoin's proof-of-work security through Blind Merged Mining.
The sketch is still pinned to the wall. Maybe one day we'll build the orphanchain too.