Skip to content

Commit b1680d0

Browse files
committed
Full basic integration with DCD Contracts
1 parent 56c1ff1 commit b1680d0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+5592
-563
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,9 @@ dist/
3838
**/.DS_Store
3939

4040
# Logs
41-
logs/*
41+
logs/*
42+
43+
/.simplicity-dex.config.toml
44+
/.cache
45+
taker/
46+
simplicity-dex
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Keypair can be generated here: https://start.nostr.net/
2+
nostr_keypair = "keypair..."
3+
relays = [
4+
"wss://relay.damus.io",
5+
"wss://nostr.wine/",
6+
]

.simplicity-dex.example/keypair.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

.simplicity-dex.example/relays.txt

Lines changed: 0 additions & 1 deletion
This file was deleted.

Cargo.toml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,36 @@ version = "0.1.0"
99
edition = "2024"
1010
rust-version = "1.91.0"
1111
authors = ["Blockstream"]
12-
readme = "README.md"
12+
readme = "Readme.md"
1313

1414

1515
[workspace.dependencies]
1616
anyhow = { version = "1.0.100" }
17+
bincode = { version = "2.0.1" }
18+
chrono = { version = "0.4.42" }
1719
clap = { version = "4.5.49", features = ["derive"] }
18-
dirs = {version = "6.0.0"}
20+
config = { version = "0.15.18" }
21+
contracts = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "baa8ab7", package = "contracts" }
22+
contracts-adapter = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "baa8ab7", package = "contracts-adapter" }
23+
dex-nostr-relay = { path = "./crates/dex-nostr-relay" }
24+
dirs = { version = "6.0.0" }
25+
dotenvy = { version = "0.15.7" }
26+
elements = { version = "0.26.1" }
1927
futures-util = { version = "0.3.31" }
20-
global-utils = { path = "crates/global-utils" }
28+
global-utils = { path = "./crates/global-utils" }
29+
hex = { version = "0.4.3" }
30+
humantime = { version = "2.3.0" }
2131
nostr = { version = "0.43.1", features = ["std"] }
2232
nostr-sdk = { version = "0.43.0" }
23-
dex-nostr-relay = { path = "./crates/dex-nostr-relay"}
24-
serde = { version = "1.0.228", features = ["derive"] }
33+
proptest = { version = "1.9.0" }
34+
serde = { version = "1.0.228" }
2535
serde_json = { version = "1.0.145" }
36+
simplicity-lang = { version = "0.6.0" }
37+
simplicityhl = { version = "0.2.0" }
38+
simplicityhl-core = { git = "https://github.com/BlockstreamResearch/simplicity-contracts.git", rev = "baa8ab7", package = "simplicityhl-core", features = ["encoding"] }
39+
sled = { version = "0.34.7" }
2640
thiserror = { version = "2.0.17" }
27-
tokio = { version = "1.48.0", features = ["macros", "test-util", "rt", "rt-multi-thread"] }
41+
tokio = { version = "1.48.0", features = ["macros", "test-util", "rt", "rt-multi-thread", "tracing" ] }
2842
tracing = { version = "0.1.41" }
2943
tracing-appender = { version = "0.2.3" }
3044
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
31-
url = { version = "2.5.7" }

Guide.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Simplicity DEX — Developer Guide
2+
3+
This short guide helps contributors understand, build, test and extend the project. It focuses on practical commands and
4+
the patterns used across crates (not exhaustive; follow Rust and crate docs for deeper dives).
5+
6+
## Project layout
7+
8+
- crates/dex-cli — command line client and UX helpers
9+
- crates/dex-nostr-relay — relay logic, event parsing and storage
10+
- crates/global-utils — other helpers
11+
12+
## Prerequisites
13+
14+
- Install Rust
15+
- Create your nostr keypair (Can be generated here: https://start.nostr.net/)
16+
17+
## Quick start
18+
19+
1. Build:
20+
- cargo build -r
21+
2. Run CLI (local dev):
22+
- `cargo build -r`
23+
- `mkdir -p ./demo`
24+
- `mv ./target/release/simplicity-dex ./demo/simplicity-dex`
25+
- `cp ./.simplicity-dex.example/.simplicity-dex.config.toml ./demo/.simplicity-dex.config.toml`
26+
- `echo SEED_HEX=ffff0123456789abcdef0123456789abcdef0123456789abcdef0123456789ab > ./demo/.env`
27+
3. Insert your valid nostr keypair into `.simplicity-dex.config.toml`
28+
29+
## Commands example execution
30+
31+
Overall trading for dcd contracts can be split in two sides: taker and maker.
32+
33+
Maker and Taker responsible for taking such steps:
34+
35+
1) Maker initializes contract in Liquid;
36+
2) Maker funds contract with collateral and settlement tokens. (by now for test **collateral** = LBTC-Testnet, **settlement** = minted token from scratch)
37+
3) Taker funds contract with collateral tokens and takes contract parameters from already discovered maker event_id.
38+
4) Maker now can make:
39+
* Early collateral termination
40+
* Early settlement termination
41+
5) Taker now can make:
42+
* Early termination
43+
6) After `settlement-height` both maker and taker can use settlement exit to receive their tokens (collateral or settlement) depending on the settlement token price, which is signed with oracle.
44+
45+
1. Create your own contract with your values. For example can be taken
46+
47+
* `taker-funding-start-time` 1764328373 (timestamp can be taken from https://www.epochconverter.com/)
48+
* `taker-funding-end-time` 1764358373 (Block time when taker funding period ends)
49+
* `contract-expiry-time` 1764359373 (Block time when contract expires)
50+
* `early-termination-end-time` 1764359373 (Block time when early termination is no longer allowed)
51+
* `settlement-height` 2169368 (Block height at which oracle price is attested)
52+
* `principal-collateral-amount` 2000 (Base collateral amount)
53+
* `incentive-basis-points` 1000 (Incentive in basis points (1 bp = 0.01%))
54+
* `filler-per-principal-collateral` 100 (Filler token ratio)
55+
* `strike-price` 25 (Oracle strike price for settlement)
56+
* `settlement-asset-entropy` `0ffa97b7ee6fcaac30b0c04803726f13c5176af59596874a3a770cbfd2a8d183` (Asset entropy (hex) for settlement)
57+
* `oracle-pubkey` `757f7c05d2d8f92ab37b880710491222a0d22b66be83ae68ff75cc6cb15dd2eb` (`./simplicity-dex helpers address --account-index 5`)
58+
59+
Actual command in cli:
60+
```bash
61+
./simplicity-dex maker init
62+
--utxo-1 <FIRST_LBTC_UTXO>
63+
--utxo-2 <SECOND_LBTC_UTXO>
64+
--utxo-3 <THIRD_LBTC_UTXO>
65+
--taker-funding-start-time <TAKER_FUNDING_START_TIME>
66+
--taker-funding-end-time <TAKER_FUNDING_END_TIME>
67+
--contract-expiry-time <CONTRACT_EXPIRY_TIME>
68+
--early-termination-end-time <EARLY_TERMINATION_END_TIME>
69+
--settlement-height <SETTLEMENT_HEIGHT>
70+
--principal-collateral-amount <PRINCIPAL_COLLATERAL_AMOUNT>
71+
--incentive-basis-points <INCENTIVE_BASIS_POINTS>
72+
--filler-per-principal-collateral <FILLER_PER_PRINCIPAL_COLLATERAL>
73+
--strike-price <STRIKE_PRICE>
74+
--settlement-asset-entropy <SETTLEMENT_ASSET_ENTROPY>
75+
--oracle-pubkey <ORACLE_PUBLIC_KEY>
76+
```
77+
78+
2. Maker fund cli command:
79+
```bash
80+
./simplicity-dex maker fund
81+
--filler-utxo <FILLER_TOKEN_UTXO>
82+
--grant-coll-utxo <GRANTOR_COLLATERAL_TOKEN_UTXO>
83+
--grant-settl-utxo <GRANTOR_SETTLEMENT_TOKEN_UTXO>
84+
--settl-asset-utxo <SETTLEMENT_ASSET_UTXO>
85+
--fee-utxo <FEE_UTXO>
86+
--taproot-pubkey-gen <DCD_TAPROOT_PUBKEY_GEN>
87+
```
88+
89+
3. Taker has to fund
90+
91+
```bash
92+
./simplicity-dex taker fund
93+
--filler-utxo <FILLER_TOKEN_UTXO>
94+
--collateral-utxo <COLLATERAL_TOKEN_UTXO>
95+
--collateral-amount-deposit <COLLATERAL_AMOUNT_TO_DEPOSIT>
96+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
97+
```
98+
99+
4. Taker can wait for specific `settlement-height` and gracefully exit contract:
100+
```bash
101+
./simplicity-dex taker settlement
102+
--filler-utxo <FILLER_TOKEN_UTXO>
103+
--asset-utxo <ASSET_UTXO>
104+
--fee-utxo <FEE_UTXO>
105+
--filler-to-burn <FILLER_AMOUNT_TO_BURN>
106+
--price-now <PRICE_AT_CURRENT_BLOCK_HEIGHT>
107+
--oracle-sign <ORACLE_SIGNATURE>
108+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
109+
```
110+
111+
5. Maker can wait for specific `settlement-height` and gracefully exit contract:
112+
```bash
113+
./simplicity-dex maker settlement
114+
--grant-collateral-utxo <GRANTOR_COLLATERAL_TOKEN_UTXO>
115+
--grant-settlement-utxo <GRANTOR_SETTLEMENT_TOKEN_UTXO>
116+
--asset-utxo <ASSET_UTXO>
117+
--fee-utxo <FEE_UTXO>
118+
--grantor-amount-burn <GRANTOR_AMOUNT_TO_BURN>
119+
--price-now <PRICE_AT_CURRENT_BLOCK_HEIGHT>
120+
--oracle-sign <ORACLE_SIGNATURE>
121+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
122+
```
123+
124+
* Maker or Taker depending on the can use Merge(2/3/4) command to merge collateral tokens.
125+
This is made exactly for combining outs into one to eliminate execution of contract with usage of little fragments
126+
```bash
127+
./simplicity-dex helpers merge-tokens4
128+
--token-utxo-1 <TOKEN_UTXO_1>
129+
--token-utxo-2 <TOKEN_UTXO_2>
130+
--token-utxo-3 <TOKEN_UTXO_3>
131+
--token-utxo-4 <TOKEN_UTXO_4>
132+
--fee-utxo <FEE_UTXO>
133+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
134+
```
135+
136+
* For early collateral termination Maker can use command:
137+
```bash
138+
./simplicity-dex maker termination-collateral
139+
--grantor-collateral-utxo <GRANTOR_COLLATERAL_TOKEN_UTXO>
140+
--collateral-utxo <COLLATERAL_TOKEN_UTXO>
141+
--fee-utxo <FEE_UTXO>
142+
--grantor-collateral-burn <GRANTOR_COLLATERAL_AMOUNT_TO_BURN>
143+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
144+
```
145+
146+
* For early settlement termination Maker can use command:
147+
```bash
148+
./simplicity-dex maker termination-settlement
149+
--settlement-asset-utxo <SETTLEMENT_ASSET_UTXO>
150+
--grantor-settlement-utxo <GRANTOR_SETTLEMENT_TOKEN_UTXO>
151+
--fee-utxo <FEE_UTXO>
152+
--grantor-settlement-amount-burn <GRANTOR_SETTLEMENT_AMOUNT_TO_BURN>
153+
--maker-order-event-id <MAKER_ORDER_EVENT_ID>
154+
```
155+
156+
* For early termination Taker can use command:
157+
```bash
158+
./simplicity-dex taker termination-early
159+
--filler-utxo <FILLER_TOKEN_UTXO>
160+
--collateral-utxo <COLLATERAL_TOKEN_UTXO>
161+
--fee-utxo <FEE_UTXO>
162+
--filler-to-return <FILLER_TOKEN_AMOUNT_TO_RETURN>
163+
--maker-order-event-id <MAKER_ORDER_EVENT_ID
164+
```

Makefile

Lines changed: 0 additions & 27 deletions
This file was deleted.

README.md

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
# Simplicity DEX
22

3-
A distributed exchange built on the NOSTR protocol, leveraging Simplicity smart contracts and the PACT (PACT for Auditable Contract Transactions) messaging protocol.
3+
A distributed exchange built on the NOSTR protocol, leveraging Simplicity smart contracts and the PACT (PACT for
4+
Auditable Contract Transactions) messaging protocol.
45

56
## Overview
67

7-
Simplicity DEX is a decentralized exchange that combines the power of Simplicity smart contracts with the distributed messaging capabilities of NOSTR. By utilizing the PACT protocol, we enable secure, auditable, and transparent trading of digital assets without relying on centralized intermediaries.
8+
Simplicity DEX is a decentralized exchange that combines the power of Simplicity smart contracts with the distributed
9+
messaging capabilities of NOSTR. By utilizing the PACT protocol, we enable secure, auditable, and transparent trading of
10+
digital assets without relying on centralized intermediaries.
811

912
## Key Features
1013

@@ -16,34 +19,53 @@ Simplicity DEX is a decentralized exchange that combines the power of Simplicity
1619

1720
## DEX Messaging Protocol
1821

19-
The core of our DEX is the **PACT (PACT for Auditable Contract Transactions)** protocol, which defines the format of trading offers. This protocol is fully adapted to be compatible with the NOSTR event structure.
22+
The core of our DEX is the **PACT (PACT for Auditable Contract Transactions)** protocol, which defines the format of
23+
trading offers. This protocol is fully adapted to be compatible with the NOSTR event structure.
2024

2125
### Offer Structure
2226

23-
A PACT offer is implemented as a standard NOSTR event with kind `30078` (non-standard, ephemeral event kind for DEX offers). The event structure maps to PACT requirements as follows:
27+
A PACT offer is implemented as a standard NOSTR event with kind `30078` (non-standard, ephemeral event kind for DEX
28+
offers). The event structure maps to PACT requirements as follows:
2429

25-
| NOSTR Field | PACT Field | Data Type | Required | Description |
26-
|-------------|------------|-----------|----------|-------------|
27-
| `id` | Event ID | string (64-char hex) | Yes | SHA-256 hash of canonical serialized event data (excluding `sig`). Serves as unique, content-addressed identifier |
28-
| `pubkey` | Maker Key | string (64-char hex) | Yes | 32-byte x-only Schnorr public key of market maker. Must be registered in on-chain Maker Identity Registry |
29-
| `created_at` | Timestamp | integer | Yes | Unix timestamp (seconds) when offer was created |
30-
| `description` | Description | string | No | Human-readable description of instrument and complex terms |
31-
| `kind` | Event Type | integer | Yes | Event type identifier. Value `1` reserved for standard offers. Enables future protocol extensions |
32-
| `tags` | Metadata | array of arrays | Yes | Structured machine-readable metadata for filtering and discovery |
33-
| `content` | Contract Code | string | Yes | Stringified JSON containing full Simplicity contract code |
34-
| `sig` | Signature | string (128-char hex) | Yes | 64-byte Schnorr signature proving authenticity and integrity |
30+
| NOSTR Field | PACT Field | Data Type | Required | Description |
31+
|---------------|---------------|-----------------------|----------|-------------------------------------------------------------------------------------------------------------------|
32+
| `id` | Event ID | string (64-char hex) | Yes | SHA-256 hash of canonical serialized event data (excluding `sig`). Serves as unique, content-addressed identifier |
33+
| `pubkey` | Maker Key | string (64-char hex) | Yes | 32-byte x-only Schnorr public key of market maker. Must be registered in on-chain Maker Identity Registry |
34+
| `created_at` | Timestamp | integer | Yes | Unix timestamp (seconds) when offer was created |
35+
| `description` | Description | string | No | Human-readable description of instrument and complex terms |
36+
| `kind` | Event Type | integer | Yes | Event type identifier. Value `1` reserved for standard offers. Enables future protocol extensions |
37+
| `tags` | Metadata | array of arrays | Yes | Structured machine-readable metadata for filtering and discovery |
38+
| `content` | Contract Code | string | Yes | Stringified JSON containing full Simplicity contract code |
39+
| `sig` | Signature | string (128-char hex) | Yes | 64-byte Schnorr signature proving authenticity and integrity |
3540

3641
### Tag Examples
3742

3843
The `tags` field contains structured metadata as key-value pairs:
3944

4045
```json
4146
[
42-
["asset_to_sell", "<liquid_asset_id>"],
43-
["asset_to_buy", "<liquid_asset_id>"],
44-
["price", "1000000", "sats_per_contract"],
45-
["expiry", "1735689600"],
46-
["compiler", "simplicity-v1.2.3", "deterministic_build_hash"]
47+
[
48+
"asset_to_sell",
49+
"<liquid_asset_id>"
50+
],
51+
[
52+
"asset_to_buy",
53+
"<liquid_asset_id>"
54+
],
55+
[
56+
"price",
57+
"1000000",
58+
"sats_per_contract"
59+
],
60+
[
61+
"expiry",
62+
"1735689600"
63+
],
64+
[
65+
"compiler",
66+
"simplicity-v1.2.3",
67+
"deterministic_build_hash"
68+
]
4769
]
4870
```
4971

@@ -99,4 +121,5 @@ This project is licensed under the MIT License - see the LICENSE file for detail
99121

100122
## Disclaimer
101123

102-
This software is experimental and should be used with caution. Always verify contract code and understand the risks before trading.
124+
This software is experimental and should be used with caution. Always verify contract code and understand the risks
125+
before trading.

0 commit comments

Comments
 (0)