Real estate tokenization on Bitcoin Layer 1, powered by OP_NET.
Fractional property ownership using native BTC — no bridges, no wrapped assets, no custodians.
App · Explorer · Whitepaper · OP_NET
OPWA Protocol enables compliant real estate tokenization on Bitcoin Layer 1. Property owners list assets on-chain; investors acquire fractional ownership using native BTC — no intermediary token, no bridge, no wrapped asset required.
Rental yield is distributed on-chain in USDOP (protocol stablecoin) via a pull-model distributor, proportional to each holder's fraction balance. The complete lifecycle — listing, funding, lock, yield distribution, and refund — is enforced by immutable smart contracts on OP_NET.
The protocol introduces four financial instruments with strictly non-overlapping roles:
| Token | Standard | Role | Supply |
|---|---|---|---|
| OPWACoin (OPWA) | OP-20 | Protocol governance. Fixed supply. | 1B fixed |
| OPWAYield (OPWAY) | OP-20 | Protocol bond. Stake in YieldVault → ~15% APY in USDOP. | Dynamic |
| FractionToken | OP-1155 | Fractional property ownership. Each tokenId = one property. Funded with native BTC. |
Per-property cap |
| USDOP | OP-20 | Yield stablecoin. Minted on yield events. Distributed to stakers and fraction holders. | Mint-on-yield |
Investor ──BTC──▶ FractionToken.invest(tokenId, amount)
│
├─ BTC routed to Treasury P2TR (on-chain verified)
└─ FractionToken(tokenId) minted to investor wallet
Property Owner ──▶ PropertyVaultV2.listProperty(nftId, maxSupply, name)
│
├─ Listing fee collected on-chain
└─ FractionToken.listProperty() called atomically
OPWA Operator ──▶ YieldDistributor.distributeYield(tokenId, usdopAmount)
│
└─ yieldPerShare[tokenId] += amount / totalSupply
Holder ──────────▶ YieldDistributor.claim(tokenId)
│
└─ Receives: (balance × yieldPerShare) − alreadyClaimed
| Contract | Address | Standard |
|---|---|---|
| OPWACoin | opt1sqz822pny75gqn9hp6w5rt26p5kawdqq64vh758d7 |
OP-20 |
| OPWAYield | opt1sqrr0c9la0l38k9przlqsxkxs7ga4dzpxavkus34c |
OP-20 |
| USDOP | opt1sqpmsahd5gaz3zn4lx0m3knqqpmh0ymhxhu79h5qd |
OP-20 |
| YieldVault | opt1sqqu555rqasywflqwdu3t4h8emx8khggteutnlcen |
Custom |
| FractionToken | opt1sqzy4tnjevxmpadj5jk8qlqemn48lhtp2nvz98fuk |
OP-1155 |
| PropertyVaultV2 | opt1sqz8ppz4r2lu3uekqk5u5j6ys7j84qw249q444vk5 |
Custom |
| YieldDistributor | opt1sqre99rget5vudhp4mcte3uu82t42jk45nqq2wnhw |
Custom |
| Treasury P2TR | opt1pv5z0n6gn0n8szljp7dewl52548zyvt48pt406cl607wen22amalqfpft8p |
P2TR |
Canonical source of truth: contracts/deployed-addresses.json
| Parameter | Value | Notes |
|---|---|---|
| Price per fraction | 1,000 sats | Fixed. Native BTC. |
| Funding deadline | 25,920 blocks | ~180 days from listing |
| Lock period | 6,480 blocks | ~45 days from full funding |
| Listing fee (fixed) | 0.001 BTC | Paid by property owner |
| Listing fee (variable) | 0.5% | Of total property value |
| Capital raise fee | 1.5% | Deducted at claimProceeds() |
| Annual management fee | 1.0% | On total property value per year |
| Performance fee | 10% | On yield distributed |
ACTIVE Funding open. Investors call invest(tokenId, amount).
│
▼ 100% funded
FUNDED Lock period active (~45 days).
│
▼ Lock expires
COMPLETED Proceeds released. Rental distribution begins.
│
▼ Deadline without full funding
REFUNDABLE Investors recover BTC via refund(tokenId).
OPWABTC/
├── contracts/
│ ├── op20/
│ │ ├── OPWACoin.ts # Governance token (OP-20)
│ │ ├── OPWAYield.ts # Protocol bond (OP-20)
│ │ └── USDOP.ts # Yield stablecoin (OP-20)
│ ├── op1155/
│ │ └── FractionToken.ts # Fractional property ownership (OP-1155)
│ ├── vault/
│ │ ├── PropertyVaultV2.ts # Property listing and lifecycle
│ │ ├── YieldVault.ts # OPWAY staking vault
│ │ └── YieldDistributor.ts # Rental yield distributor
│ ├── build/ # Compiled WASM artifacts
│ └── deployed-addresses.json # Canonical contract addresses
├── scripts/
│ ├── redeploy-fraction-token.ts # Full redeploy script
│ ├── configure-and-list.ts # Post-deploy configuration
│ ├── list-properties-opwa.ts # Property listing helper
│ └── _verify-properties.ts # On-chain verification
├── docs/
│ ├── whitepaper-v2.md # Protocol whitepaper
│ ├── CONTRACTS.md # Contract interface reference
│ └── security-model.md # Threat model and mitigations
├── audits/ # Security audit reports
├── index.html # Production frontend (single file)
├── AGENTS.md # Rules for AI coding agents
├── SECURITY.md # Vulnerability disclosure policy
└── vercel.json # Deployment config and security headers
| Layer | Technology |
|---|---|
| Contracts | AssemblyScript + @btc-vision/btc-runtime → WASM on OP_NET |
| Token Standards | OP-20 (fungible), OP-1155 (multi-token fractions) |
| Frontend | Vanilla JS/HTML — single file, zero framework dependencies |
| RPC | https://testnet.opnet.org |
| Explorer | opscan.org |
| Deployment | Vercel — push to main triggers auto-deploy |
- Node.js ≥ 18
- An OP_NET testnet wallet with BTC testnet funds
OPNET_MNEMONICenvironment variable (see.env.example)
cd contracts
npm install
npm run build
⚠️ Required patches afternpm install: Two patches must be re-applied to@btc-vision/btc-runtimeafter any fresh install:
runtime/script/Networks.ts—case Testnet: return 'opt'(not'tb')runtime/global.ts— removedeclare function verifySchnorrSignatureThese patches ensure correct bech32 HRP encoding for OP_NET Testnet addresses.
cd contracts
npx asc op1155/index.ts --target fractionToken --measure --uncheckedBehavior never
⚠️ Always use this exact command. Runningasc FractionToken.ts --optimizeproduces a corrupted WASM (~6,880 bytes). The correct output is ~29,177 bytes with theoptHRP string present.
# 1. Deploy FractionToken
OPNET_MNEMONIC='...' npx tsx scripts/redeploy-fraction-token.ts
# 2. Configure and list properties
OPNET_MNEMONIC='...' npx tsx scripts/configure-and-list.ts <FRACTION_TOKEN_ADDR>
# 3. Verify on-chain
OPNET_MNEMONIC='...' npx tsx scripts/_verify-properties.tsnpx serve .
# or simply open index.htmlNo build step required.
- Security audit reports:
/audits - Vulnerability disclosure:
SECURITY.md - Never commit mnemonics or private keys — see
.env.example - All financial state transitions are enforced on-chain — no admin override paths
| 🌐 Application | opwa-protocol.vercel.app |
| 🔍 Explorer | opscan.org |
| 📄 Whitepaper | docs/whitepaper-v2.md |
| 📦 OP_NET | opnet.org |
MIT — see LICENSE

