diff --git a/README.md b/README.md index 7e060d5..0b01808 100644 --- a/README.md +++ b/README.md @@ -2,16 +2,159 @@ This repository is the codebase for the Magic Protocol contracts and web application. +Magic Protocol is a trustless Bitcoin-to-Stacks bridge that enables users to swap BTC for xBTC (wrapped Bitcoin on Stacks) and vice versa without requiring trust in a centralized party. + Check out the [Magic docs](https://docs.magic.fun) for more information about how Magic works. +## Table of Contents + +- [Overview](#overview) +- [Architecture](#architecture) +- [Project Structure](#project-structure) +- [Contracts](#contracts) +- [Development Setup](#development-setup) +- [Testing](#testing) +- [Environment Variables](#environment-variables) +- [Contributing](#contributing) +- [License](#license) + +## Overview + +Magic Protocol enables trustless atomic swaps between Bitcoin (BTC) and wrapped Bitcoin on Stacks (xBTC). The protocol uses Hash Time-Locked Contracts (HTLCs) to ensure that swaps are either completed fully or refunded, eliminating counterparty risk. + +### Key Features + +- **Trustless Swaps**: No centralized party holds your funds +- **Atomic Transactions**: Swaps complete fully or are automatically refunded +- **Supplier System**: Liquidity providers can earn fees by facilitating swaps +- **Inbound & Outbound**: Support for both BTC→xBTC and xBTC→BTC swaps + +## Architecture + +The protocol consists of three main components: + +1. **Bridge Contract** (`bridge.clar`): Core protocol logic handling supplier registration, escrow management, and swap finalization +2. **Supplier Wrapper** (`supplier-wrapper.clar`): Helper contract for suppliers to manage their liquidity +3. **Clarity Bitcoin Library** (`clarity-bitcoin.clar`): Bitcoin transaction parsing and validation + +### Swap Flow + +**Inbound Swap (BTC → xBTC):** +1. User creates an HTLC on Bitcoin with the supplier's public key +2. User calls `escrow-swap` with the BTC transaction proof +3. Supplier reveals the preimage to claim BTC and releases xBTC to the user + +**Outbound Swap (xBTC → BTC):** +1. User initiates outbound swap by locking xBTC in the contract +2. Supplier sends BTC to the user's Bitcoin address +3. Supplier finalizes the swap with the BTC transaction proof + +## Project Structure + +``` +magic-protocol/ +├── contracts/ # Clarity smart contracts +│ ├── bridge.clar # Main protocol contract +│ ├── supplier-wrapper.clar +│ ├── clarity-bitcoin.clar +│ └── test/ # Test contracts +├── common/ # Shared TypeScript utilities and Clarigen bindings +├── components/ # React UI components +├── docs/ # Contract documentation +├── pages/ # Next.js pages +├── public/ # Static assets +├── scripts/ # Utility scripts +├── settings/ # Configuration files +└── test/ # Test files +``` + ## Contracts -The main contract for Magic is [./contracts/bridge.clar](`bridge.clar`), where all protocol-specific logic is handled. You can find tests for this contract under the `test` directory. +The main contract for Magic is [`./contracts/bridge.clar`](./contracts/bridge.clar), where all protocol-specific logic is handled. You can find tests for this contract under the `test` directory. + +### Contract Documentation + +- [`bridge`](./docs/bridge.md) - Core protocol contract +- [`supplier-wrapper`](./docs/supplier-wrapper.md) - Supplier helper contract +- [`clarity-bitcoin`](./docs/clarity-bitcoin.md) - Bitcoin transaction utilities + +## Development Setup + +### Prerequisites + +- [Node.js](https://nodejs.org/) (v16 or higher) +- [Yarn](https://yarnpkg.com/) package manager +- [Clarinet](https://github.com/hirosystems/clarinet) (for Clarity development) + +### Installation + +1. Clone the repository: + ```bash + git clone https://github.com/magicstx/magic-protocol.git + cd magic-protocol + ``` + +2. Install dependencies: + ```bash + yarn + ``` + +3. Copy the environment configuration: + ```bash + cp .env.example .env.local + ``` + +4. Start the development server: + ```bash + yarn dev + ``` + +The app will be available at [localhost:4444](http://localhost:4444). + +## Testing + +Run the test suite with: + +```bash +yarn test +``` + +For Clarity contract tests using Clarinet: + +```bash +clarinet test +``` + +## Environment Variables + +Create a `.env.local` file based on `.env.example`: + +| Variable | Description | +| --- | --- | +| `NEXT_PUBLIC_NETWORK` | Network to use (`testnet` or `mainnet`) | +| `NEXT_PUBLIC_ELECTRUM_HOST` | Electrum server host | +| `NEXT_PUBLIC_ELECTRUM_PORT` | Electrum server port | + +The example configuration works for public testnet configurations. + +## Contributing + +Contributions are welcome! Please follow these steps: + +1. Fork the repository +2. Create a feature branch (`git checkout -b feature/amazing-feature`) +3. Make your changes +4. Run tests to ensure everything works +5. Commit your changes (`git commit -m 'Add amazing feature'`) +6. Push to your branch (`git push origin feature/amazing-feature`) +7. Open a Pull Request -## Development setup +### Code Style -First, install dependencies by running `yarn`. +- Follow existing code conventions +- Add tests for new functionality +- Update documentation as needed -Copy the `.env.example` file to `.env.local`. The example configuration will work for public testnet configurations. +## License -Finally, run the app with `yarn dev`. The app will be available at [localhost:4444](http://localhost:4444). +This project is licensed under the GPL-2.0 License - see the [LICENSE](LICENSE) file for details. diff --git a/docs/README.md b/docs/README.md index c7d3dbc..934493f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,9 +1,38 @@ -# Contracts - -- [`ft-trait`](.mdinet/SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.ft-trait.clar) -- [`restricted-token-trait`](.mdinet/SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.restricted-token-trait.clar) -- [`Wrapped-Bitcoin`](.mdinet/SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.Wrapped-Bitcoin.clar) -- [`test-utils`](contracts/test/test-utils.md) -- [`clarity-bitcoin`](contracts/test/clarity-bitcoin.md) -- [`bridge`](contracts/bridge.md) -- [`supplier-wrapper`](contracts/supplier-wrapper.md) +# Contract Documentation + +This directory contains auto-generated documentation for Magic Protocol smart contracts. + +## Core Contracts + +- [`bridge`](./bridge.md) - Main protocol contract handling supplier registration, escrow management, and swap finalization +- [`supplier-wrapper`](./supplier-wrapper.md) - Helper contract for suppliers to manage their liquidity + +## Supporting Contracts + +- [`clarity-bitcoin`](./clarity-bitcoin.md) - Bitcoin transaction parsing and validation utilities +- [`test-utils`](./test-utils.md) - Testing utilities + +## External Dependencies + +These contracts are external dependencies used by the protocol: + +- [`ft-trait`](./../.clarinet/SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.ft-trait.clar) - SIP-010 fungible token trait +- [`restricted-token-trait`](./../.clarinet/SP3DX3H4FEYZJZ586MFBS25ZW3HZDMEW92260R2PR.restricted-token-trait.clar) - Restricted token trait +- [`Wrapped-Bitcoin`](./Wrapped-Bitcoin.md) - xBTC token contract (wrapped Bitcoin on Stacks) + +## Contract Architecture + +``` + ┌─────────────────────┐ + │ bridge.clar │ + │ (Core Protocol) │ + └──────────┬──────────┘ + │ + ┌───────────────────┼───────────────────┐ + │ │ │ + ▼ ▼ ▼ +┌──────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ supplier-wrapper │ │ clarity-bitcoin │ │ Wrapped-Bitcoin│ +│ (Supplier Mgmt) │ │ (BTC Parsing) │ │ (xBTC) │ +└──────────────────┘ └─────────────────┘ └─────────────────┘ +``` diff --git a/docs/bridge.md b/docs/bridge.md index d2cbedc..c018d39 100644 --- a/docs/bridge.md +++ b/docs/bridge.md @@ -762,7 +762,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| controller | principal | | +| controller | principal | The STX address of the supplier controller | ### get-supplier-id-by-public-key @@ -787,7 +787,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| public-key | (buff 33) | | +| public-key | (buff 33) | The 33-byte compressed public key of the supplier | ### get-supplier @@ -812,7 +812,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-funds @@ -837,7 +837,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-escrow @@ -862,7 +862,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-inbound-swap @@ -887,7 +887,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| txid | (buff 32) | | +| txid | (buff 32) | The 32-byte Bitcoin transaction ID | ### get-preimage @@ -912,7 +912,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| txid | (buff 32) | | +| txid | (buff 32) | The 32-byte Bitcoin transaction ID | ### get-outbound-swap @@ -937,7 +937,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-completed-outbound-swap-txid @@ -962,7 +962,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-completed-outbound-swap-by-txid @@ -987,7 +987,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| txid | (buff 32) | | +| txid | (buff 32) | The 32-byte Bitcoin transaction ID | ### get-swapper-id @@ -1012,7 +1012,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| swapper | principal | | +| swapper | principal | The STX address of the swapper | ### get-swapper-principal @@ -1037,7 +1037,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-next-supplier-id @@ -1126,7 +1126,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| id | uint | | +| id | uint | The unique identifier of the supplier | ### get-inbound-meta @@ -1151,7 +1151,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| txid | (buff 32) | | +| txid | (buff 32) | The 32-byte Bitcoin transaction ID | ### get-full-inbound @@ -1183,7 +1183,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| txid | (buff 32) | | +| txid | (buff 32) | The 32-byte Bitcoin transaction ID | ### get-user-inbound-volume @@ -1211,7 +1211,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| user | principal | | +| user | principal | The STX address of the user | ### get-total-inbound-volume @@ -1258,7 +1258,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| user | principal | | +| user | principal | The STX address of the user | ### get-total-outbound-volume @@ -1302,7 +1302,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| user | principal | | +| user | principal | The STX address of the user | ### get-total-volume @@ -1354,9 +1354,9 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| amount | uint | | -| sender | principal | | -| recipient | principal | | +| amount | uint | The amount in satoshis (sats) | +| sender | principal | The sending principal address | +| recipient | principal | The receiving principal address | ### concat-buffs @@ -1387,7 +1387,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| buffs | (list 6 (buff 32)) | | +| buffs | (list 6 (buff 32)) | List of buffers to concatenate | ### concat-buffs-fold @@ -1421,8 +1421,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| b | (buff 32) | | -| result | (buff 192) | | +| b | (buff 32) | Buffer to append | +| result | (buff 192) | Accumulated result buffer | ### get-swap-amount @@ -1455,9 +1455,9 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| amount | uint | | -| fee-rate | int | | -| base-fee | int | | +| amount | uint | The amount in satoshis (sats) | +| fee-rate | int | Fee rate in basis points (1/100 of a percent) | +| base-fee | int | Fixed base fee in satoshis | ### get-amount-with-fee-rate @@ -1488,8 +1488,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| amount | uint | | -| fee-rate | int | | +| amount | uint | The amount in satoshis (sats) | +| fee-rate | int | Fee rate in basis points (1/100 of a percent) | ### update-user-inbound-volume @@ -1522,8 +1522,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| user | principal | | -| amount | uint | | +| user | principal | The STX address of the user | +| amount | uint | The amount in satoshis (sats) | ### update-user-outbound-volume @@ -1556,8 +1556,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| user | principal | | -| amount | uint | | +| user | principal | The STX address of the user | +| amount | uint | The amount in satoshis (sats) | ### validate-expiration @@ -1585,8 +1585,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| expiration | uint | | -| mined-height | uint | | +| expiration | uint | Block height when the swap expires | +| mined-height | uint | Block height when the transaction was mined | ### validate-fee @@ -1622,7 +1622,7 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| fee-opt | (optional int) | | +| fee-opt | (optional int) | Optional fee rate in basis points | ### validate-btc-addr @@ -1654,8 +1654,8 @@ to receive the xBTC escrowed. | Name | Type | Description | | --- | --- | --- | -| version | (buff 1) | | -| hash | (buff 20) | | +| version | (buff 1) | Bitcoin address version byte (P2PKH or P2SH) | +| hash | (buff 20) | 20-byte hash (e.g., pubkey hash or script hash) | ### validate-outbound-revocable @@ -1692,7 +1692,7 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| swap-id | uint | | +| swap-id | uint | The unique identifier of the swap | ### generate-htlc-script @@ -1739,11 +1739,11 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| sender | (buff 33) | | -| recipient | (buff 33) | | -| expiration | (buff 4) | | -| hash | (buff 32) | | -| swapper | (buff 4) | | +| sender | (buff 33) | 33-byte compressed public key of the sender | +| recipient | (buff 33) | 33-byte compressed public key of the recipient | +| expiration | (buff 4) | 4-byte little-endian expiration value | +| hash | (buff 32) | 32-byte hash (SHA256 of preimage) | +| swapper | (buff 4) | 4-byte swapper ID | ### generate-script-hash @@ -1768,7 +1768,7 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| script | (buff 120) | | +| script | (buff 120) | Bitcoin redeem script | ### generate-htlc-script-hash @@ -1799,11 +1799,11 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| sender | (buff 33) | | -| recipient | (buff 33) | | -| expiration | (buff 4) | | -| hash | (buff 32) | | -| swapper | (buff 4) | | +| sender | (buff 33) | 33-byte compressed public key of the sender | +| recipient | (buff 33) | 33-byte compressed public key of the recipient | +| expiration | (buff 4) | 4-byte little-endian expiration value | +| hash | (buff 32) | 32-byte hash (SHA256 of preimage) | +| swapper | (buff 4) | 4-byte swapper ID | ### generate-p2pkh-output @@ -1828,7 +1828,7 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| hash | (buff 20) | | +| hash | (buff 20) | 20-byte hash (e.g., pubkey hash or script hash) | ### generate-p2sh-output @@ -1853,7 +1853,7 @@ to be revoked, it must be expired and not finalized | Name | Type | Description | | --- | --- | --- | -| hash | (buff 20) | | +| hash | (buff 20) | 20-byte hash (e.g., pubkey hash or script hash) | ### generate-output @@ -1884,8 +1884,8 @@ so it should only ever be these two. | Name | Type | Description | | --- | --- | --- | -| version | (buff 1) | | -| hash | (buff 20) | | +| version | (buff 1) | Bitcoin address version byte (P2PKH or P2SH) | +| hash | (buff 20) | 20-byte hash (e.g., pubkey hash or script hash) | ### bytes-len @@ -1910,7 +1910,7 @@ so it should only ever be these two. | Name | Type | Description | | --- | --- | --- | -| bytes | (buff 4) | | +| bytes | (buff 4) | Buffer to measure length of | ### read-uint32 @@ -1943,8 +1943,8 @@ little-endian | Name | Type | Description | | --- | --- | --- | -| num | (buff 4) | | -| length | uint | | +| num | (buff 4) | 4-byte little-endian number | +| length | uint | Number of bytes to read | ### buff-to-u8 @@ -1968,4 +1968,4 @@ little-endian | Name | Type | Description | | --- | --- | --- | -| byte | (buff 1) | | +| byte | (buff 1) | Single byte to convert |