Skip to content

WritzProtocol/writz

Repository files navigation

Writz Protocol

Bitcoin was built to be yours. Your loans should be too.

CI Tests Network License: MIT

Live App · Docs · Relayer API

Writz is the first trustless Bitcoin lending protocol on Stellar. Lock real BTC directly from your Bitcoin wallet, borrow USDC on Stellar, and keep every position private — always.

No bridge. No custodian. No wrapped tokens. No public balance sheet.


What Makes Writz Different

Writz Every other lending protocol
Custodian Bitcoin Script is the custodian A company holds your BTC
Privacy Private by default · ZK proofs Your position is a public billboard
BTC Native on-chain BTC Wrapped token (WBTC, tBTC…)
Emergency exit CLTV timelock → reclaim alone Depends on protocol availability

This Is Not a Whitepaper

As of June 2026, four contracts are live on Soroban testnet, 268 tests pass, and real Bitcoin transactions have been verified on-chain.

What Status
Bitcoin SPV verification on Soroban ✅ Live on testnet
ZK-private positions (Groth16 BN254) ✅ Verified on-chain
P2WSH locking + co-signed BTC release ✅ Broadcast on Bitcoin Signet
Poseidon Merkle commitment tree ✅ Root updated on-chain
Full deposit → borrow → repay ZK flow ✅ 6 sequential testnet transactions
268 tests across all modules ✅ All passing

Live Testnet Contracts

Contract Address WASM Tests
bitcoin-spv CAE5L7BO2GNF7MIZWXB2BTUMLYNIMQZUSWN2BWLZQS7HRHLOUSL6VLWJ 5.2 KB 28
zk-verifier CDV45GLXG4AOU6BDZSY5YHHVNGQIAYAPD3PUGXIIIYLIO6V2XGO6SMFV 11.8 KB 18
commitment-tree CDFAP3J4WLFZC2N5U66X5EO62POBBIBXOKCCMCM3IRLJNXT73C4IBKA7 26.6 KB 50
private-lend CCLH2GJYG3QSHZJI7V7VK3DNMNK3I3QJCECBSFGX3AC6CK4I7EF7ZJ2G 50

Full deployment log, init transactions, and verified calls: contracts/deployments/testnet.md


System Architecture

System Architecture

The protocol operates across two blockchains. Bitcoin is the custody layer — BTC never leaves the Bitcoin network. Stellar is the execution layer — loan logic, privacy, and USDC flows all run on Soroban.

Four layers, each with a clear boundary:

  1. Bitcoin Network — user's BTC wallet locks funds into a P2WSH script. The script enforces two spending conditions; no third party can move the funds.
  2. Backend Services — a stateless SPV Relayer watches Bitcoin blocks and assembles proof bundles for Soroban. A ZK Prover runs in the browser (no server-side proving).
  3. Soroban Contracts — four contracts verify Bitcoin transactions cryptographically, verify ZK proofs, manage the Poseidon Merkle tree, and issue/repay USDC loans.
  4. Browser — all secrets stay on the user's device. ZK proofs are generated locally. The Stellar wallet signs Soroban transactions.

How It Works

1 — Deposit & Borrow

Deposit Flow

  1. User connects their Bitcoin wallet (Xverse) and a Stellar wallet (Freighter) to the Writz UI.
  2. The frontend derives a unique P2WSH address for this deposit (user public key + protocol public key + timelock).
  3. User sends BTC to that address on Bitcoin. The script is now live on-chain.
  4. After 6 confirmations, the SPV Relayer assembles a proof bundle: raw transaction, block headers, and Merkle inclusion path.
  5. The bitcoin-spv Soroban contract verifies the bundle cryptographically — no oracle, no trust.
  6. The browser generates a Groth16 ZK proof (deposit circuit): proves BTC was locked and a valid commitment exists, without revealing the amount.
  7. The commitment-tree contract verifies the ZK proof on-chain and inserts the commitment into the Poseidon Merkle tree.
  8. The user can now borrow up to 66% of BTC value in USDC from the private-lend pool.

2 — Borrow & Repay

Borrow / Repay Flow

Borrowing requires a ZK proof that the position's collateral ratio is above the minimum threshold. The proof reveals nothing about the actual amounts — only that the invariant holds. Repayment rotates the nullifier so the position cannot be double-spent.

3 — BTC Release

BTC Release

When the loan is fully repaid, the protocol co-signs a PSBT (Partially Signed Bitcoin Transaction) using its signing key. The user countersigns with their Bitcoin wallet and broadcasts. BTC arrives back in their wallet. The protocol never held custody at any point.


ZK Privacy Layer

Every position is private from the moment of deposit. The Soroban contracts verify loan validity without ever learning the amounts involved.

What Is Hidden

Hidden Visible
Collateral amount (BTC) Total protocol TVL (aggregate)
Loan amount (USDC) Total USDC outstanding (aggregate)
Health ratio That a liquidation occurred (not who/how much)
User identity Merkle tree root

Three Groth16 Circuits

ZK Circuits

  • deposit.circom — Proves BTC was locked and a valid commitment exists. Public output: the commitment hash and the SPV verification result.
  • borrow_repay.circom — Proves the position is sufficiently collateralized for the requested borrow amount, and correctly computes repayment with interest.
  • liquidation.circom — Proves a position's health ratio fell below the liquidation threshold (120%). Anyone can trigger liquidation by providing this proof.

Circuits use Groth16 over BN254. Verification runs on Soroban via Protocol 26 host functions (bn254.g1_msm, bn254.pairing_check).

Position Lifecycle

Commitment State Machine


Smart Contract Architecture

Contract Interactions

Contract Purpose Depends on
bitcoin-spv SHA256d, PoW validation, Merkle inclusion, block header chain
zk-verifier Stores Groth16 verification keys; verifies deposit/borrow_repay/liquidation proofs
commitment-tree Poseidon Merkle tree; core deposit/borrow/repay/liquidate logic bitcoin-spv + zk-verifier
private-lend USDC lending pool; supply, withdraw, interest rate model, orchestration commitment-tree

Interest rate model — kinked curve: base rate + linear slope up to 75% utilization, then a steep slope to discourage over-borrowing. Protocol captures the spread between borrow and supply rates.


Bitcoin Script Design

Bitcoin P2WSH Script

The BTC locking mechanism lives entirely on Bitcoin. The P2WSH redeem script encodes two spending paths:

OP_IF
  <protocol_pubkey> OP_CHECKSIGVERIFY
  <user_pubkey>     OP_CHECKSIG
OP_ELSE
  <locktime>        OP_CHECKLOCKTIMEVERIFY OP_DROP
  <user_pubkey>     OP_CHECKSIG
OP_ENDIF

Path A — Cooperative release (normal case): Both the protocol and user sign. Triggered when the loan is repaid. The Soroban contract issues the co-signature only after verifying repayment on-chain.

Path B — Emergency recovery (timelock): After a predefined locktime (loan maturity + 30 days), the user can spend without any protocol involvement. If Writz disappears, the user's funds are never locked forever.

See bitcoin-script/ for the full P2WSH builder, address derivation, and PSBT signing toolkit.


Products

Product Description Status
PrivateLend Deposit BTC as collateral → borrow USDC privately Phase 1 — testnet ✅
Dark Swap Convert BTC to USDC directly · no exchange · no visible order Phase 3 — planned
BTC Savings BTC collateral + USDC auto-routed to highest-yield Stellar pools Phase 3 — planned
ZK Proof of Reserve Prove BTC holdings without revealing wallets or amounts · B2B SaaS Phase 3 — planned

The Bitcoin SPV SDK is also open infrastructure. Any Stellar protocol that needs to verify a Bitcoin transaction on-chain can use bitcoin-spv with one call. Writz charges a per-verification fee.


Repository Structure

writz/
├── contracts/               # Soroban smart contracts (Rust)
│   ├── contracts/
│   │   ├── bitcoin-spv/     # SHA256d · PoW · Merkle inclusion · block headers
│   │   ├── zk-verifier/     # Groth16 BN254 · verification key store
│   │   ├── commitment-tree/ # Poseidon Merkle tree · ZK lending logic
│   │   └── private-lend/    # USDC pool · interest model · orchestration
│   └── deployments/
│       └── testnet.md       # Live addresses · tx hashes · verified calls
│
├── circuits/                # ZK circuits (Circom 2.2.3 + snarkjs)
│   ├── src/
│   │   ├── deposit.circom
│   │   ├── borrow_repay.circom
│   │   ├── liquidation.circom
│   │   └── merkle.circom
│   └── keys/                # Verification keys (committed to repo)
│
├── relayer/                 # SPV Relayer service (TypeScript · Express · Bun)
│   └── src/
│       ├── routes/proof.ts  # GET /spv-proof/:txid
│       └── bitcoin/         # Esplora client · header fetching · proof assembly
│
├── bitcoin-script/          # Bitcoin locking script toolkit (TypeScript)
│   └── src/
│       ├── script.ts        # P2WSH builder
│       ├── address.ts       # Address derivation (testnet / mainnet)
│       ├── spend.ts         # Path A/B PSBT signing
│       └── keys.ts          # Key management
│
├── frontend/                # Next.js web app (React 19 · TypeScript · Tailwind)
│   └── src/
│       ├── components/      # DepositFlow · PositionDashboard · LenderPanel
│       ├── lib/flows/       # deposit · borrow · repay · recover · lend
│       ├── lib/position/    # Commitment derivation · note encryption
│       └── lib/prover/      # In-browser ZK proof generation (snarkjs)
│
├── packages/
│   └── commitment-tree/     # Generated TypeScript bindings for commitment-tree
│
├── scripts/
│   ├── deploy/              # Deployment scripts · e2e_zkflow.js · set_vkeys.js
│   └── diagrams/            # Graphviz architecture diagrams (Python)
│
└── docs/                    # Full documentation (Mintlify)

Tech Stack

Layer Technology Notes
Smart contracts Soroban · Rust Protocol 26 · soroban-sdk = "26"
ZK proofs Circom 2.2.3 · snarkjs · Groth16 BN254 curve · in-browser proving
ZK on-chain Protocol 26 host functions bn254.g1_msm · bn254.pairing_check
Bitcoin scripting P2WSH (Phase 1) → Taproot (Phase 3) bitcoinjs-lib · ecpair
Bitcoin wallets Xverse · sats-connect PSBT standard
Frontend Next.js 16 · React 19 · TypeScript App Router · Tailwind CSS 4
Stellar wallets Stellar Wallets Kit · Privy Freighter · Lobstr · email login
Relayer runtime Bun · Express.js Alpine Docker · Esplora-backed
Merkle hashing Poseidon (poseidon-lite) Same in circuits + contracts + JS
CI GitHub Actions 4 parallel jobs · all tests must pass

Quick Start

Prerequisites

# Rust with Soroban WASM target
rustup target add wasm32v1-none
cargo install stellar-cli --locked --version 27  # or later

# Node.js / Bun (for relayer, bitcoin-script, circuits, frontend)
node --version  # >= 20
bun --version   # >= 1.1

# For ZK circuit compilation only
npm install -g circom snarkjs

Run All Tests

# 1. Soroban contracts — 146 tests
cd contracts && cargo test

# 2. Relayer service — 35 tests
cd ../relayer && npm install && npm test

# 3. Bitcoin script toolkit — 48 tests
cd ../bitcoin-script && npm install && npm test

# 4. ZK circuits — 45 tests
cd ../circuits && npm install && npm test

All 268 tests pass. If anything fails, open an issue.

Full ZK End-to-End on Soroban Testnet

Runs the complete deposit → borrow → repay cycle against the live testnet contracts (6 transactions):

WRITZ_DEV_SECRET=<your-testnet-key> node scripts/deploy/e2e_zkflow.js

Get a free testnet key and fund it with Stellar Friendbot.

Frontend Dev Server

cd frontend
cp .env.example .env.local
# Fill in NEXT_PUBLIC_* contract addresses from contracts/deployments/testnet.md
# Set NEXT_PUBLIC_RELAYER_URL=https://writz-relayer-production.up.railway.app
bun install && bun dev
# → http://localhost:3000

The testnet app is also live at writz-protocol.vercel.app.

Generate Architecture Diagrams

pip install graphviz
python3 scripts/diagrams/render-all.py
# → docs/diagrams/output/*.png + *.svg

Test Coverage

Module Language Tests How to run
bitcoin-spv contract Rust 28 cd contracts && cargo test -p bitcoin-spv
zk-verifier contract Rust 18 cd contracts && cargo test -p zk-verifier
commitment-tree contract Rust 50 cd contracts && cargo test -p commitment-tree
private-lend contract Rust 50 cd contracts && cargo test -p private-lend
Relayer service TypeScript 35 cd relayer && npm test
Bitcoin script toolkit TypeScript 48 cd bitcoin-script && npm test
ZK circuits Circom / JS 45 cd circuits && npm test
Total 268

Roadmap

Roadmap

Phase 1 — Foundation (current, Jul–Sep 2026)

  • 4 contracts live on Soroban testnet
  • Full ZK E2E cycle verified on-chain
  • P2WSH locking and release tested on Bitcoin Signet
  • SCF Build Award submitted (~$92K, Open Track)
  • Trusted setup ceremony planned (5+ independent participants)
  • Mintlify docs live at docs.writz.io

Phase 2 — Launch (Q4 2026)

  • Audit Bank: Veridise (ZK circuits) + OtterSec (Soroban contracts)
  • Mainnet launch gated: $50K TVL cap, whitelist-only first 30 days
  • Frontend: full deposit / borrow / repay / repay UI with in-browser ZK proving
  • DeFiLlama listing on day 1

Phase 3 — Scale (2027)

  • Dark Swap: private BTC → USDC conversions
  • BTC Savings: auto-routed USDC yield (Blend, Phoenix DEX)
  • ZK Proof of Reserve: enterprise B2B attestation product
  • WRTZ governance token: fair IDO at $5M TVL, real-yield buyback mechanics
  • SPV SDK published as open Stellar ecosystem infrastructure

Business Model

Revenue Stream Mechanism
Lending spread Borrow rate minus supply rate on PrivateLend
Swap fees Basis points on each Dark Swap conversion
SPV API fees Per-verification or subscription for third-party Stellar protocol integrations
Proof of Reserve SaaS Monthly subscription for enterprise B2B customers
Insurance fund % of all protocol fees auto-routed to an on-chain reserve

Security

Risk Model

Risk Mitigation
Bitcoin reorg Require 6 confirmations before deposit is recognized
P2WSH script bug Formal review; emergency timelock protects users regardless
Protocol key compromise MPC / HSM co-signing key; key rotation roadmap
SPV contract exploit External audit; stateless approach minimizes attack surface
Oracle manipulation Median of multiple price feeds (Pyth + DIA)
ZK proof soundness Battle-tested Groth16; production ceremony required before mainnet
Mass liquidation (BTC crash) Conservative 150% collateral ratio; open liquidation keeps keepers competitive

Audit Roadmap

Auditor Scope Timing
Veridise ZK circuits (Circom + proving keys) After SCF Tranche #1
OtterSec / Zellic Soroban contracts After SCF Tranche #2
Internal Bitcoin P2WSH scripting Ongoing

Mainnet launch is gated on zero critical/high findings from both audits.

To report a security issue: open a private GitHub Security Advisory.


Documentation

Full documentation lives in docs/ and is published at writz.mintlify.app:

Start here:

Products:

How it works (technical):

Developers:

Security:

Roadmap:

  • Vision — Where Writz is going by 2028.
  • Phases — Phase-by-phase execution plan.

Contributing

  1. Fork the repo and create a branch from main.
  2. Run the full test suite before opening a PR — all 268 tests must pass.
  3. For new features, add tests. For bug fixes, add a regression test.
  4. Open a PR with a clear description of what changed and why.

See docs/developers/contribution-guide.md for detailed guidelines.


Get Involved

You are Start here
BTC holder who wants to borrow USDC privately PrivateLend →
Developer who wants to build on the protocol Quick Start →
Stellar protocol that needs Bitcoin verification SPV SDK →
Institution exploring ZK Proof of Reserve ZK PoR →

License

MIT

About

Trustless Bitcoin DeFi on Stellar — ZK-private BTC collateral lending

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors