# 👋-Hello!

![](/files/-MFpFeeAJndbKCtckRsS)

**OpenDEX is a cross-chain DEX network, featuring a user-friendly web app for spontaneous asset swaps and a layer 3 high-speed trading network for liquidity providers & day traders built on the** [**Lightning**](https://lightning.network/) **and** [**Connext**](https://connext.network/) **networks.** OpenDEX consists of software, community, member projects, and the BOLD protocol standard with the goal to unify currently incompatible protocols and fragmented liquidity.

## Get Started

[🔁 **Swap privately & securely** via the easy-to-use web app 🖥️](https://boltz.exchange/)

[🌊 **Provide liquidity & earn** by running a node 👨‍💻](/develop/docs/liquidity-providers)

## OpenDEX Features

* No central authority. No middleman.
* No account. No KYC. No personal data.
* No protocol token.
* [Tor](https://www.torproject.org/) by default preserves privacy.
* [BOLD](/develop/bold/00-introduction) as open protocol. Support for multiple implementations.
* Direct, peer-to-peer trading.
* Complete control of funds at all times.
* Order book locally aggregates orders from peers in the network.
* Orders are matched locally with peer orders.
* Instant order settlement via atomic swaps on the [Lightning](https://lightning.network/) and [Connext](https://connext.network/) networks.

## Support & Community

**OpenDEX operates non-profit and is not a company**, nor any other sort of legal entity. It is an open community of individuals & member projects, working together to maintain the OpenDEX software and BOLD protocol specifications. OpenDEX was started to create a unified & long-term viable alternative to trading on trusted and KYCed centralized exchanges. Find the slides of the first public announcement at #hcpp19 in Prague [here](https://github.com/opendexnetwork/opendex/raw/master/slides/20191005_hcpp19.pdf) and the video recording [here](https://www.youtube.com/watch?v=euSr9A6tI90).

* Join our [weekly community call or watch the recordings](/develop/community/videos).
* Get support on our [Discord](https://discord.gg/aS5RMchDrU) and join our [Telegram](https://t.me/opendexnetwork) community.
* Contribute on [GitHub](https://github.com/opendexnetwork).


# 🎥-Weekly Call & Videos

This section contains video recordings of OpenDEX community calls, explainers, guides & more!

## Community Calls

* Jitsi link to join the call: <https://meet.jit.si/opendex-community>
* Time and day of the call: 18:00 UTC, every Wednesday
* Discussions are recorded and uploaded here

### Community Call #21 (2021-06-02) 👉 [Video](https://youtu.be/zKR8LECPM5k) 👈

One more rather casual call where we discussed [Bitcoin metrics cooling off](https://mailchi.mp/bytetree/the-bitcoin-network-slumps), Marathon (a North American Bitcoin Mining corp) first [starting to censor Bitcoin transactions](https://www.coindesk.com/marathon-miners-censor-bitcoin-transactions-ofac-compliant) to be "compliant with U.S. regulatory standards", then [coming around announcing not to do it anymore just a couple of weeks later](https://marathondh.com/ceo-fred-thiel-comments-on-migration-to-standard-bitcoin-core-0-211-node-and-support-for-taproot/), Jack Maller's [Bitcoin car](https://bitcoinmagazine.com/culture/bitcoin-car-will-be-in-indianapolis-500), a lenghty discussion about [Ethereum's price outperforming Bitcoin](https://finance.yahoo.com/news/jp-morgan-explains-why-ethereum-134546824.html), store of Value vs. moving fast/innovation, [Taproot looking very much to activate this signalling period](https://taproot.watch/), [continued funding for utreexo](https://dci.mit.edu/utreexo) and more ethereum vs. bitcoin ;) Looking forward to finally have something to demo in two weeks 🔥

### Community Call #20 (2021-05-19) 👉 [Video](https://youtu.be/B_alfOZysQ8) 👈

In this casual edition of our call [we looked at Bitcoin's energy consumption and Tesla's REC business](https://twitter.com/Elisabeth_Steyn/status/]1392799067986554880?s=09), Tesla's 2021 Q1 report [showing main profit generated by REC's and the one-time Bitcoin sale](https://tesla-cdn.thron.com/static/R3GJMT_TSLA_Q1_2021_Update_5KJWZA.pdf?xseo=\&response-content-disposition=inline%3Bfilename%3D%22TSLA-Q1-2021-Update.pdf%22), [China banning Bitcoin (for the 17th time)](https://cointelegraph.com/news/chinese-trade-associations-sound-crypto-investment-warning), it's been an incredible week and there was probably never such a [coordinated attack against a single asset](https://www.zerohedge.com/crypto/human-history-no-single-asset-has-come-under-such-coordinated-assault-global-institutions) with even [the pope feeling qualified to have an opinion on Bitcoin's "fossil fuel" energy consumption](https://twitter.com/Pontifex/status/1394993742226939905), Taproot close to activation (check [taproot.watch](https://taproot.watch)), a minor [Bitcoin Core CVE](https://github.com/btcsuite/btcd/pull/1719), the upcoming [LND 0.13 release](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.0-beta.rc2), discussed [PoW vs. PoS](https://platform.spacemesh.io/docs/protocol/mining/overview/) and RGB's [mycitadel wallet](https://github.com/mycitadel).

### Community Call #19 (2021-03-24) 👉 [Video](https://youtu.be/EGmR676jMt8) 👈

In this call [we laughed](https://pbs.twimg.com/media/ExO8ELWXEAUoa81?format=jpg\&name=small) once more at the [ECB's claim not to be responsible for increasing econimic inequality](https://twitter.com/ecb/status/1374647699480453121) (read about the Cantillon effect [here](https://www.austriancenter.com/cantillon-effect-populism/)), [Tesla now **accepting** Bitcoin](https://twitter.com/elonmusk/status/1374617643446063105) and that by running their own merchant software and Bitcoin nodes, [Breez launching a built-in podcast platform](https://medium.com/breez-technology/podcasts-on-breez-streaming-sats-for-streaming-ideas-d9361ae8a627), how [Taproot may handle Quantum Computers](https://bitcoinops.org/en/newsletters/2021/03/24/) and our main topic: [UniSwap V3](https://uniswap.org/blog/uniswap-v3/).

Tl;dr: UniSwap V3 is great and fixes a couple of inefficiencies of V2, but OpenDEX still keeps most of its advantages over UniSwap with the major one being: it's truly cross-chain. Native BTC, native ETH, no wrapping.

### Community Call #18 (2021-03-17) 👉 [Video](https://youtu.be/oB3BeDNtN7g) 👈

In this exciting community call we covered the [troll title changes at Tesla (Master of Coin!) 😹](https://www.sec.gov/Archives/edgar/data/0001318605/000156459021012981/tsla-8k_20210315.htm), the new taproot activation alternative [speedy trial](https://bitcoinmagazine.com/technical/discussing-taproot-activation-through-speedy-trial) that could bring us taproot in 2021 🤯, the VERY different and entirely [developer driven upgrade approach on ethereum](https://www.coindesk.com/ethereum-proof-of-stake-sooner-than-you-think), that in some (admittedly rare) circumstances [lightning funding transactions are still prone to transaction malleability and thus loss of funds](https://bitcoinops.org/en/newsletters/2021/03/17/) and spend the rest of the call wrapping our head around RGB 🌈, shout-out to Maxim from the RGB Team patiently explaining and answering questions and stay tuned about how we will work together to make a lightning-based DEX Standard a reality!

Check out these links to learn more about RGB or even get your hands dirty and try it out:

* Project Page: <https://rgb-org.github.io>
* FAQs: <https://www.rgbfaq.com>
* Telegram: <https://t.me/rgbtelegram>
* GitHub: <https://github.com/LNP-BP>
* Docker Containers (CLI ftw!): <https://github.com/LNP-BP/docker>
* MyCitadel RGB-enabled iOS Wallet: <https://www.mycitadel.io>

### Community Call #17 (2021-03-03) 👉 [NO Video, sorry!](/develop/community/videos) 👈

In this community call we covered [the continued institutional flow into Bitcoin](https://mailchi.mp/bytetree/bitcoin-institutional-flows-are-a-game-changer), [the new major geth 1.10 release](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.0) which dramatically speeds up accessing ethereum state (out of experience we can't recommend to upgrade just yet though), [another improvement proposal for a BIP70 successor](https://bitcoinops.org/en/newsletters/2021/03/03/), [I2P (an alternative to Tor) support in Bitcoin Core](https://github.com/bitcoin/bitcoin/pull/20685) ([here](https://geti2p.net/en/comparison/tor) you can learn more about the differences between I2P and Tor), the [RGB MyCitadel iOS App 🌈](https://github.com/mycitadel/mycitadel-node) (get a basic overview of RGB [here](https://www.rgbfaq.com/faq), but as promised we'll cover RGB in greater detail in next week's call and finally saw the [new update feature of the OpenDEX Desktop App](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.10) and went through how arbitrage incentivizes liquidity providers to offer liquidity on the OpenDEX network, how it works in practice and why leveraging arbitrage with CEXes to incentivize liquidity provision on OpenDEX is only really possible because of instant finality of trades. Apologies for the missing recording, we'll have a backup recording next week ✌️

### Community Call #16 (2021-02-24) 👉 [Video](https://youtu.be/zpwiZlbRRbs) 👈

In this community call we covered the last piece of the puzzle missing for taproot activation on bitcoin: [LOT=true vs. LOT=false](https://bitcoinmagazine.com/articles/lottrue-or-lotfalse-this-is-the-last-hurdle-before-taproot-activation), [the new lnd 0.12.1 release](https://github.com/lightningnetwork/lnd/releases/tag/v0.12.1-beta) which fixes a nasty crash, a demo of the new setup flow in our latest [OpenDEX Desktop App Testnet release](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.7) and saw a pretty cool demo of an upcoming feature for Boltz, which not only makes it compatibly with virtually all mobile ethereum wallets, but also doesn't require you to hold ETH to do swaps with an ERC20 asset like USDT! You can already try it out at [testnet.boltz.exchange](https://testnet.boltz.exchange/) - dope! 🌿

### Community Call #15 (2021-02-17) 👉 [NO Video, sorry!](/develop/community/videos) 👈

In this community call we covered another exciting week of happenings: [Microstrategy raising even moar money to buy Bitcoin](https://www.microstrategy.com/en/investor-relations/press/microstrategy-announces-proposed-private-offering-of-600m-of-convertible-senior-notes), [a new proposal how to offer escrow services on lightning and hold fees](https://bitcoinops.org/en/newsletters/2021/02/17/) based on a post-taproot feature called [PTLCs](https://bitcoinops.org/en/topics/ptlc/) (a more private & efficient replacment for HTLCs), our [👉 website re-write 👈 (check it out!)](https://opendex.network/), [all-new OpenDEX Destkop Release for Windows 🎉](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.1), also some of you asked me to link this pretty stats page [coin.dance](https://coin.dance/). Apologies for the missing recording, our bad ✌️

### Community Call #14 (2021-02-10) 👉 [Video](https://youtu.be/A9bQPYvWb1o) 👈

In this community call we covered another exciting week of happenings: [Tesla's $1.5 Billion investment in Bitcoin](https://www.sec.gov/ix?doc=/Archives/edgar/data/1318605/000156459021004599/tsla-10k_20201231.htm), [Bytetree's BOLD investment strategy](https://mailchi.mp/bytetree/bitcoin-gold-bold), [Taproot activation settled on BIP8](https://bitcoinops.org/en/newsletters/2021/02/10/), [geth's upcoming breaking change on the rpc layer](https://twitter.com/peter_szilagyi/status/1359503621826764805), [shady shady 1inch.exchange](https://twitter.com/brockjelmore/status/1354488170000355328), [xmr.to closure](https://xmr.to/blog/job-done) and [dexfairy.com](https://dexfairy.com/).

### Community Call #13 (2021-02-03) 👉 [Video](https://youtu.be/Xha5l6t19Nk) 👈

In this community call we announced our move from "Exchange Union" to ["OpenDEX"](https://opendex.network), which unifies everything under one name and should avoid confusion down the road. This also comes with a change in product focus, how we are funded, team members and more. The gist is: we are shifting focus towards UX & end-user facing trading products while keeping our core atomic-swap-DNA (the user is always in control of funds) & OpenDEX will become even more open going forward. If you are interested in day-to-day updates and what we are working on, please join our [Discord server](https://discord.gg/aS5RMchDrU) and *watch* our [GitHub repositories](https://github.com/opendexnetwork). We also touched on [Microstrategy sharing the "Bitcoin for Corporations"](https://www.microstrategy.com/en/resources/events/world-2021/bitcoin-summit) playbook, [Elon on Clubhouse](https://twitter.com/MMCrypto/status/1356131319424704513?s=09) & Bisq's new ["Cash by Mail"](https://bisq.wiki/Cash_by_mail) feature.

### Community Call #12 (2021-01-27) 👉 [Video](https://youtu.be/tL5FRf-QvH8) 👈

In this community call, we talked extensively about `r/wallstreetbets` amazing coup against wallstreet causing hedge funds getting liquidated for their overleveraged short positions on [GameStop's stock](https://finance.yahoo.com/quote/GME), that the response of "trading restrictions" of AmeriTrade & others has to lead to decentralized trading networks like OpenDEX to take off, Bitcoin as treasury for non-profits and the new releases of lnd & connext. Finally, we saw a demo of a feature-complete Trading view in XUD UI.

### Community Call #11 (2021-01-13) 👉 [Video](https://youtu.be/CpeFQqFKksg) 👈

In this community call, we laughed hard at ECB's Christina Lagarde's call for a global Bitcoin regulation because of the ["funny business" conducted](https://www.reuters.com/article/us-crypto-currency-ecb/ecbs-lagarde-calls-for-regulating-bitcoins-funny-business-idUSKBN29I1B1), how we can learn from [Wasabi's fallback mechanisms preventing being impacted by the recent attack on Tor Consensus](https://blog.wasabiwallet.io/wasabi-wallet-tor-consensus/) and touched on an open PR [removing all remaining JSON encoding from the OpenDEX protocol](https://github.com/ExchangeUnion/xud/pull/2061#pullrequestreview-567439995) moving everything cleanly to protobuf. Last but not least we saw a pretty neat sneak peak of the upcoming trading feature in XUD UI.

### Community Call #10 (2020-12-23) 👉 [Video](https://youtu.be/CFwnbgoMMBM) 👈

In this Christmas Edition of our community call, we clarified that the recent [customer data dump](https://www.ledger.com/message-ledgers-ceo-data-leak) probably should be the end of Ledger, the recent [SEC charge](https://www.sec.gov/news/press-release/2020-338) probably the end of Ripple and, more importantly, saw an end-to-end demo of a deposit with XUD UI & went through a pretty interesting OpenDEX Q\&A session, touching on the different stakeholders involved, why no token and more.

### Community Call #9 (2020-12-16) 👉 [Video](https://youtu.be/QTx7U6fPe_k) 👈

In this community call, we talked about the last edition of the amazing [Bitcoin Optech Newsletter](https://bitcoinops.org/en/newsletters/2020/12/16/), about the upcoming [0.12.0 LND release](https://github.com/lightningnetwork/lnd/releases/tag/v0.12.0-beta.rc1) and development updates from Boltz & Exchange Union with special focus on the new [1.2.0 XUD UI release](https://github.com/ExchangeUnion/xud-ui/releases/tag/v1.2.0) 🌈

### Community Call #8 (2020-12-09) 👉 [Video](https://youtu.be/oBoDNGI8f3w) 👈

In this community call, we touched on the events of the week and then went on discussing the upcoming release of the next connext protocol version called "vector" (<https://github.com/connext/vector>), which Exchange Union expects to move to as soon as it's available (2020ish). We also have seen a demo of the upcoming 1.2.0 XUD UI release (and heard a range of excuses why it's taking so long, but also some decent commitment to deliver until next week).

### Community Call #7 (2020-12-02) 👉 [Video](https://youtu.be/_KbbTmMA8WM) & [Slides](https://github.com/BoltzExchange/slides/blob/master/boltzopendex.pdf) 👈

In this community call, we touched on the recent happenings eth2 launch and [Breez'es great overview of lightning use cases](https://medium.com/breez-technology/waypoints-on-the-road-to-lightnings-mass-adoption-88e4148a2c3c) and learned in-depth about the recently launched BTC/USDT swaps on [boltz.exchange](https://boltz.exchange) 🔥

### Community Call #6 (2020-11-25) 👉 [Video](https://youtu.be/xi0sXZgG9NE) & [Slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20201125_OpenDEX_Community_Call.pdf) 👈

In in this special edition of our community call, we dived into "Running a bitcoin node" and looked at three projects helping to make this quest easier with a Raspberry Pi: [RaspiBlitz](https://raspiblitz.org/), [MyNode](https://mynodebtc.com/) & [Umbrel](https://getumbrel.com/). We had a closer look at Umbrel and discussed how it achieves great UX. We learned that Exchange Union is working on an integration with RaspiBlitz already and that we can expect to access OpenDEX seamlessly via above projects in the future.

### Community Call #5 (2020-11-18) 👉 [Video](https://youtu.be/tt_TYVft4dQ) 👈

In this community call we discussed [lnmarkets](https://lnmarkets.com), the proactive [miner initiative for activation of taproot on bitcoin](https://taprootactivation.com) and saw and saw a first demo of multi-channel trades via xud.

### Community Call #4 (2020-11-11) 👉 [Video](https://youtu.be/iNw5d1rZUqY) 👈

In this community call we discussed Lightning Pool, the Infura downtime and Ethereum chain split and saw a pretty cool demo of the upcoming ⚡-BTC/USDT swaps on [boltz.exchange](https://boltz.exchange) 🔥

### Community Call #3 (2020-11-04) 👉 [Video](https://youtu.be/IBrVkzyCwb4) 👈

In this community call we discussed using multiple channels to settle one trade (will be demoed next week) and and saw an alpha demo of the upcoming 1.1.0 release of XUD Explorer featuring full setup on Windows. This version takes Windows users from 0 to "deposit funds" in a couple of Minutes, seamlessly installing docker as part of the installation flow.

### Community Call #2 (2020-10-28) 👉 [Video](https://youtu.be/rC7zlCSuVEc) 👈

In our second community call we saw a demo of the first iteration of XUD Explorer, a Desktop App UI for OpenDEX and discussion of various topics, such as hot wallets - the risk exposure one faces when using payment channel networks like the Lightning Network.

### Community Call #1 (2020-10-21) 👉 [Video](https://youtu.be/mGumdYAjDkY) & [Slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20201021_OpenDEX_Community_Call.pdf) 👈

In our first community call we covered the **Why?, How?, What?** along with some live mainnet trading and a Q\&A session.

## Misc

### First public announcement (2019-10-05) 👉 [Video](https://www.youtube.com/watch?v=euSr9A6tI90) & [slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20191005_hcpp19.pdf) 👈

The first public announcement of OpenDEX at [#hcpp19](https://opt-out.hcpp.cz/) in Prague.


# 📝-Intro

The OpenDEX Daemon ([`opendexd`](https://github.com/opendexnetwork/opendexd)) is "the node" and core of the OpenDEX network. The graphic below shows the different participants in OpenDEX and how they are connected.

![](/files/-MTuFblfGy6pvwGRY5dP)

## How to Run a Node

👉 as [**Liquidity Provider**](/develop/docs/liquidity-providers), earning via automated arbitrage between external exchanges and OpenDEX

👉 as [**Swap Provider**](/develop/docs/swap-providers), sourcing liquidity on OpenDEX **(WIP)**

👉 as [**Day Trader**](/develop/docs/day-traders), trading instantaneously while preserving full control & privacy

👉 as [**Developer**](/develop/docs/developers), contributing or building on top of `opendexd`

## Special Docs

* [Dockerless Guide](/develop/docs/dockerless)
* [Close Shop Guide](/develop/docs/close-shop)
* [CLI Documentation](/develop/docs/cli)
* [Config Documentation](/develop/docs/config)

## Support & Community

* [Contribute](/develop/docs/contribute)!
* Support and development-related questions are welcome on our [Discord](https://discord.gg/aS5RMchDrU)!

## Help us to improve!

Please help us to improve by opening issues (or even better PRs) for [opendexd](https://github.com/opendexnetwork/opendexd), [opendex-docker](https://github.com/opendexnetwork/opendex-docker), [opendex-ui](https://github.com/opendexnetwork/opendex-ui) & [opendex-desktop](https://github.com/opendexnetwork/opendex-desktop).


# 🌊-Liquidity Providers

This guide is written for anyone looking to run a opendex liquidity provider setup entirely via the command line and create a revenue stream via automated arbitrage.

## Prerequisites

### Two Modes

1. **Default: Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider. This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Optional: Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more time and resources, but keeps the setup trustless.

### Three Networks

1. **Simnet**. `Status: down` until further notice
2. **Testnet**. `Status: up | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 200GB for full | Initial Sync Time: 15 mins for light, 24h for full`

   bitcoin testnet 3, litecoin testnet 4, ethereum rinkeby. Faucets: [t-BTC](https://coinfaucet.eu/en/btc-testnet/), [t-LTC](https://testnet.help/en/ltcfaucet/testnet), [t-ETH 1](https://faucet.rinkeby.io/) or [2](https://testnet.help/en/ethfaucet/rinkeby). If you need help or some testnet coins, hit us up on [Discord](https://discord.gg/aS5RMchDrU)!
3. **Mainnet**. `Status: down | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 1TB for full | Initial Sync Time: 30 mins for light, 72h for full`

   Down until all breaking changes are merged and some weeks on testnet didn't reveal major issues.

### Hardware

Since liquidity providers should be online 24/7 and we are ushering in a post-cloud era, we recommend setting up a power-efficient linux box connected to your router. No special configurations, like port forwardings, are necessary. Running your opendexd setup in the cloud is obviously possible, just not something we encourage to do.

[**🧑‍🏭 Standard Hardware Guide**](/develop/docs/liquidity-providers/standard-hardware): This guide walks you through setting up an arm64-based Raspberry Pi3/4. Costs: **65€-290€**

[**💪 Pro Hardware Guide**](/develop/docs/liquidity-providers/pro-hardware): This guide walks you through setting up a powerful amd64-based Mini PC. Costs: **180€-465€**

🎚️ **Custom**: If you are using a different device or a cloud VPS:

* Check the hardware requirements for the different networks and modes above
* The full setup requires a SSD for geth being able to sync. For the light setup, a regular HDD/SD card is fine.
* If you are using a VPS for testnet or mainnet, you can switch to 2 cores & 4 GB RAM after initial sync, given you use default settings.
* We currently support `amd64` (also called `x86`/`x64`) and `arm64` (also called `aarch64`/`armv8`), which should cover most devices and services.

### Software

Docker & Docker Compose.

Version >= 18.09 on Linux or Windows 10 [using WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). If you do not have docker & docker-compose installed yet and you are using Ubuntu 20.04 LTS, install these via `sudo apt install docker.io`. If you are using any version besides Ubuntu 20.04, follow the official [docker install instructions](https://docs.docker.com/get-docker/). Also make sure that the current user can run docker commands. Test with `docker run hello-world`. If this fails, [follow these instructions](https://docs.docker.com/engine/install/linux-postinstall/). This guide was written using Ubuntu 20.04 LTS.

## The Setup

From here we assume that your device is running with docker set up. Check the guides in the hardware section above if your device is not ready yet.

### Let's Roll (!WIP - NOT FULLY WORKING YET!)

Start the environment with

```bash
curl https://raw.githubusercontent.com/opendexnetwork/opendex-docker/master/opendexd.sh -o ~/opendexd.sh
bash ~/opendexd.sh
```

The setup will ask you to choose the network:

```
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
🚀 Launching mainnet environment
🌍 Checking for updates ...
```

Sync light clients (default):

```
Syncing light clients:
┌─────────┬─────────────────────────────────────────────────────┐
│ SERVICE │ STATUS                                              │
├─────────┼─────────────────────────────────────────────────────┤
│ lndbtc  │ Syncing 34.24% (610000/1781443)                     │
├─────────┼─────────────────────────────────────────────────────┤
│ lndltc  │ Syncing 12.17% (191000/1568645)                     │
└─────────┴─────────────────────────────────────────────────────┘
```

And then guide you through some basics:

```
Do you want to create a new opendexd environment or restore an existing one?
1) Create New
2) Restore Existing
Please choose: 1
```

When creating a new opendexd SEED, the setup asks you to set a password to encrypt your environment's private keys and to write down your mnemonic phrase. This serves as backup for your opendexd node key and wallets (your on-chain assets). This is your last resort in case something happens to your device. **Keep it somewhere safe!**

```
You are creating an opendexd node key and underlying wallets. All will be secured by a single password provided below.

Enter a password: 
Re-enter password: 

----------------------BEGIN OPENDEX SEED---------------------
 1. you         2. won't       3. find        4. money      
 5. in          6. this        7. seed        8. but    
 9. good       10. thinking   11. if         12. you      
13. are        14. interested 15. in         16. getting     
17. rewarded   18. for        19. testing    20. opendex  
21. security   22. hit        23. us         24. up   
-----------------------END OPENDEX SEED----------------------

The following wallets were initialized: BTC, LTC, ERC20(ETH)
```

Then you'll be asked to enter the path to your backup drive, e.g. a previously mounted USB drive:

```
Please enter a path to a destination where to store a backup of your environment. It includes everything, but NOT your on-chain wallet balance which is secured by your opendexd SEED. The path should be an external drive, like a USB or network drive, which is permanently available on your device since backups are written constantly.

Enter path to backup location: /media/USB/
Checking... OK.
```

The entered backup drive location is persisted as `backup-dir = "/media/USB/"` in `mainnet.conf` and can be changed any time. Alternatively, you can consider running your environment on two hard drives in [RAID 1](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1) to protect against data loss.

Then the setup might restart clients and ask you to enter your password once more before the CTL

Use the `status` command to check on the your setup's health and sync progress. The default light setup should show `Ready` after some seconds:

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for lndbtc, lndltc                     │
└───────────┴────────────────────────────────────────────────┘
```

If you configured the full setup via config file or cli parameters, the sync will start fast and get slower towards the end. You might see 0.00% progress for several minutes at first.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 0.00% (0/436000)                       │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 0.00% (0/324000)                       │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 0.00% (55/9140561)                     │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

After a while you should see all three full-nodes syncing nicely.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 43.06% (262348/609123)                 │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 35.94% (631593/1757002)                │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 10.16% (929072/9140623)                │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

Bitcoind/Litecoind should finish syncing within 12h, geth in about 72h on powerful hardware. A Pi4 needs about twice that long.

The CLI takes `opendex-cli` commands without the need to prepend `opendex-cli`, e.g. simply type `getinfo` to get basic information about your opendex node. Run `help` to get an always up-to-date list of commands. Append `-j` to any command to get JSON instead of the formatted output, e.g. using `listpeers` to see other opendexd nodes on the network:

```
mainnet > listpeers -j
{
  "peersList": [
    {
      "address": "rgz5icb5jdxzmu7r7tbis64q23ioytzd4tqikuyb5kz75w75rbe6veyd.onion:8885",
      "nodePubKey": "02529a91d073dda641565ef7affccf035905f3d8c88191bdea83a35f37ccce5d64",
      "lndPubKeysMap": [
        [
          "BTC",
          "035cb9afb06a83e65fbab15c900d78580673cf56ce38c5814fb71f1eb57fcba7ee"
        ],
        [
          "LTC",
          "036cf16cd7de6193efb2855e784409c3633f893662dd6edcf7a545a99659232373"
        ]
      ],
      "inbound": false,
      "pairsList": [
        "LTC/BTC",
        "ETH/BTC",
      ],
      "opendexdVersion": "1.2.7",
      "secondsConnected": 100,
      "connextAddress": "0xe802431257a1d9366BD5747F0F52bAd25A6C3092"
    }
  ]
}
```

### Your First Trade

Start by depositing some funds into your opendex node:

```bash
deposit btc #Send BTC to this address
deposit ltc #Send LTC to this address
deposit eth #Send ETH to this address
```

The deposit command for BTC & LTC is powered by [Boltz](https://boltz.exchange). Boltz will automatically open a balanced lightning channel to you, if you don't have a channel yet. This can take several minutes to complete and we'd kindly ask you to wait patiently for your funds to appear in the `getbalance` overview. If you want to follow what is happening under the hood, you can do so by typing `logs boltz`. For ETH, currently one still needs to trigger a manual channel creation in a second step after funds were deposited:

```
openchannel ETH 13.37
```

Check existing orders for all activated pairs with the command `orderbook`. It might take several seconds to see orders after opendexd was started due to the decentralized nature of the order exchange. Use `orderbook btc/usdt` to show the order book for BTC/USDT only:

```
mainnet > orderbook btc/usdt

Trading pair: BTC/USDT
┌───────────────────────────────────────┬───────────────────────────────────────┐
│ Buy                                   │ Sell                                  │
├───────────────────┬───────────────────┼───────────────────┬───────────────────┤
│ Quantity          │ Price             │ Price             │ Quantity          │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.28918298        │ 7171.56           │ 7172.253          │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 1                 │ 7171.1937         │ 7172.9757         │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7171.083          │ 7316.0663         │ 1                 │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7170.899          │ 7316.44           │ 0.22393946        │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
```

Use `getbalance` to check your balance *before* the swap.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.10944853    │ 2.5                        │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5000          │ 5000                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

Issue a regular limit order with e.g. `sell 0.1 btc/usdt 7171` to sell 0.1 btc for a price of 7171 USDT per BTC. If your order was matched, settlement shouldn't take longer than a couple of seconds.

```
mainnet > sell 0.1 btc/usdt 7171
swapped 0.1 BTC with peer order ca24fe00-1c1e-11ea-8b1b-3b2ec0335696
```

Use `getbalance` to check your balance *after* the swap. You are now owning 0.1 BTC less and 717 USDT more.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.00944842    │ 2.39999989                 │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5717          │ 5717                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

### Connect Arby

In this final step we are connecting your opendex setup to your CEX (Centralized EXchage) account via a liquidity provider bot called ["arby"](https://github.com/opendexnetwork/market-maker-bot). Arby enables "transfer" of orders from the CEX into OpenDEX and creates an arbitrage revenue stream for you as liquidity provider. Arby issues orders on the OpenDEX network based on the CEX price, adding a `margin` as premium. When orders are filled on OpenDEX, arby takes care of executing a counter trade on the CEX to lock in profits. At the time of writing, arby supports connecting to [Binance](https://www.binance.com) and [Kraken](https://www.kraken.com/), but more exchanges will be added over time; check arby's [FAQ](https://github.com/opendexnetwork/market-maker-bot#faq) for an up-to-date list. We'll use Binance as example in the following. You will need funds for at least one supported asset on Binance (e.g. BTC) for arby to start issuing orders. To activate arby, `exit` from `opendexd ctl` and run `cp ~/.opendexd-docker/mainnet/sample-mainnet.conf ~/.opendexd-docker/mainnet/mainnet.conf` to create a config file for your environment. Then edit the following options in `mainnet.conf`:

```bash
opendexd@ubuntu:~$ nano ~/.opendex-docker/mainnet/mainnet.conf
# this option needs to be set to false to allow arby to execute Binance orders on your behalf, crucially needed for arby to function
test-mode="false"
# the trading pair to activate arby for; currently arby can only handle one pair at a time
base-asset = "BTC"
quote-asset = "USDT"
#cex-base-asset = "" # optional - only needs to be specified if centralized exchange base asset is different from base-asset, e.g. USD instead of USDT
#cex-quote-asset = "" # optional - only needs to be specified if centralized exchange quote asset is different from quote-asset, e.g. USD instead of USDT
# log into your Binance account to obtain your api key and secret
cex = "binance"
cex-api-key = "your api key"
cex-api-secret = "your api secret"
# this is the percentage you'd like to add on top of your orders, 3% in this example
margin = "0.03"
# enable arby
disabled = false
# CTRL+S, CTRL+X.
```

Re-enter opendex-ctl (`bash ~/opendexd.sh`) and accept the prompt to add arby. After a minute you should see arby's automatically issued orders based on your Binance and OpenDEX balance via `listorders`. Completed OpenDEX trades are listed in `tradehistory`. You can follow actions taken by arby with `logs arby`.

Check the official [README](https://github.com/opendexnetwork/market-maker-bot/blob/main/README.md) to learn more about how arby works.

## Report Issues

Please give us feedback and report bugs by running `report` from within `opendex ctl` or join our dedicated "-help" channel on [Discord](https://discord.gg/aS5RMchDrU)!

## Tips 'n Tricks

* No need to open/forward ports
* An overview of all available commands within `opendex ctl` can be printed by typing `help` in `opendex ctl`. It allows to use client's cli (e.g. `lncli`), check client status, logs and many more.
* The opendex-docker setup uses the fixed home directory `~/.opendex-docker` where blockchain & wallet data is stored in by default. Customize the wallet & chain data directory by creating a global opendex-docker config file with `cp ~/.opendex-docker/sample-opendex-docker.conf ~/.opendex-docker/opendex-docker.conf`, then edit `dir`.
* All config options can temporary be set via cli parameters; run `bash opendex.sh --help` to get an overview of all available parameters. To e.g. use another directory for your mainnet environment, you can run `bash opendex.sh --mainnet-dir /path/to/temp/mainnet/dir`.
* To permanently change options on a network level, create a network-specific config file with the latest options, e.g. for mainnet with `cp ~/.opendex-docker/mainnet/sample-mainnet.conf ~/.opendex-docker/mainnet/mainnet.conf`, then edit `mainnet.conf`.
* If you only have a small SSD available (<300GB) for a full setup, you can place your entire setup on a HDD, except for a small part of geth's data, which needs to be located on a fast SSD:

  ```bash
  [geth]
  # SSD (internal)
  dir = "/home/<user>/.opendex-docker/mainnet/geth"
  # HDD (external)
  ancient-chaindata-dir = "/media/HDD/opendex/03-Mainnet/data/geth"
  ```
* Sample config full setup:

  ```bash
  # edit these lines to sync full nodes for bitcoin, litecoin & ethereum
  [bitcoind]
  mode = "native"
  [litecoind]
  mode = "native"
  [geth]
  mode = "native"
  ```
* You may use external full-nodes (including infura). &#x20;

  ```bash
  # connect to an external bitcoin core node in your local network (Use `10.0.2.1` on linux or `host.docker.internal` on mac if the full node is running on the same machine)
  [bitcoind]
  mode = "external"
  rpc-host = "192.168.1.42"
  rpc-port = "8332"
  rpc-user = "opendex"
  rpc-password = "opendex"
  zmqpubrawblock = "192.168.1.42:28332"
  zmqpubrawtx = "192.168.1.42:28333"
  ```
* Sample config of your external bitcoind/litecoind to work with the defaults in the `<network>.conf` file:

  ```bash
  -rpcuser=opendex
  -rpcpassword=opendex
  -rpcport=18332
  -rpcallowip=0.0.0.0/0
  -rpcbind=0.0.0.0
  -zmqpubrawblock=tcp://0.0.0.0:38332
  -zmqpubrawtx=tcp://0.0.0.0:38333
  ```
* Permanently set the alias `opendex` to launch `opendex ctl` from anywhere:

  Add the line `alias opendex="bash ~/opendex.sh"` to the end of `~/.bashrc` or `~/.bash_aliases` on Linux and `bash_profile` on Mac, then `source` the file.
* You can `exit` from `opendex ctl` any time and re-enter with `bash ~/opendex.sh`; the environment will stay up.
* A reboot of your host machine does **not** restart your `opendex-docker` environment by default. You will need to run `bash ~/opendex.sh` and `unlock` your environment with your password.
* Permanently stop the environment by typing `down` in `opendex ctl`. A restart can be achieved with `down` first and then running `bash ~/opendex.sh` again.
* `opendex-docker` only uses offical opendexd releases for mainnet. Testnet is running the latest `opendexd` master and is updated frequently.
* If you are syncing the full setup, and `geth` shows sync status **99.99%** for longer than 72h, you are probably running geth on a drive that is too slow for geth to catch up with the chain. In this case, `down` the environment and run a performance test of the disk as desribed [here](/develop/docs/liquidity-providers/standard-hardware#pi-full-setup). If results are below the 100 MB/s mark, you can either switch to a faster SSD, use the default light setup connecting to an open geth node or use infura.
* Docker *might* not play nicely with a VPN you are running on the host machine. If you see `Failed to launch environment`, try disconnecting the VPN.
* If you decide to remove `opendex-docker` from your machine, run the following commands when the environment is `down`:

  ```bash
  # Use with caution: this step removes all `opendex` blockchain and wallet data from your system. If you have channels open without backup or lost your seed mnemonic, you are at risk of loosing funds.
  sudo rm -rf ~/.opendex-docker
  rm -rf ~/opendex.sh
  rm -rf /custom/mainnet/dir
  ```

### References

* [bitcoind config options](https://github.com/bitcoin/bitcoin/blob/master/share/examples/bitcoin.conf)
* [litecoind config options](https://litecoin.info/index.php/Litecoin.conf#litecoin.conf_Configuration_File)
* [geth config options](https://github.com/ethereum/go-ethereum/blob/master/README.md#configuration)
* [lnd config options](https://github.com/lightningnetwork/lnd/blob/master/sample-lnd.conf)
* [connext config options](https://docs.connext.network)
* [opendexd config options](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf)


# 🧑‍🏭 Standard Hardware Guide

This guide is written for liquidity providers to turn a Raspberry Pi into an always-on OpenDEX node.

![](/files/-MT_sqhAsoPmFZ9PThUh)

Two options are available:

1. **Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider or optionally [Infura](https://infura.io/). This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes. **Supported by all Pi3/4 models.**
2. **Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more resources and an SSD, but keeps the setup trustless. **Supported only by the Pi4 with 4GB RAM or more.**

If you are not sure, we recommend to start with the light setup. If you opt for the Pi4 4/8GB, you can switch to the full setup at any time.

## Light Reference Shopping List (Spain): \~65 €

* [Pi3 B+](https://www.tiendatec.es/raspberry-pi/placas-base/752-raspberry-pi-3-modelo-b-plus-713179640259.html): 39,95 €
* [Pi3 B+ Power Supply](https://www.tiendatec.es/raspberry-pi/raspberry-pi-alimentacion/974-fuente-alimentacion-5v-3a-micro-usb-con-interruptor-raspberry-pi-3-8472496015080.html): 6,65 €
* [32GB MicroSD card](https://www.amazon.es/dp/B06XYHN68L/): 15 €
  * A performant microSD card is important; not the right place to save some bucks.
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

## Full Reference Shopping List (Spain): \~290 €

* [Pi4 (8GB)](https://www.tiendatec.es/raspberry-pi/placas-base/1231-raspberry-pi-4-modelo-b-8gb-765756931199.html): 82,95 €
* [Pi4 Power Supply](https://www.tiendatec.es/raspberry-pi/raspberry-pi-alimentacion/1093-alimentador-oficial-raspberry-pi-4-usb-c-5v-3a-15w-negro-644824914886.html): 8,95 €
* [Pi4 Cooling Case](https://www.tiendatec.es/raspberry-pi/cajas/1110-caja-cofre-alta-disipacion-con-dos-ventiladores-para-raspberry-pi-4-8472496015950.html): 14,95 €
  * Needed! The Pi4 is a hottie.
* [32GB MicroSD card](https://www.amazon.es/dp/B06XYHN68L/): 15 €
  * A performant microSD card is important; not the right place to save some bucks.
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.
* [1TB external SSD](https://www.amazon.es/gp/product/B074M774TW/): 165 €
  * **For full setup only, not needed for light setup!**
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).

## Pi Basic Setup

1. [Download Ubuntu 20.04 for the Pi](https://ubuntu.com/download/raspberry-pi) onto your computer, choosing **64-bit**. Any other 64-bit (also called `arm64`, `aarch64`, `armv8`) linux os for the Pi is fine too. Systems like [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/), which, at the time of writing, are still based on the 32-bit (`armv7`) architecture , are **not** supported. This guide was written using `Ubuntu 20.04`.
2. Insert the microSD card into your computer and follow the [flash instructions](https://ubuntu.com/download/iot/installation-media).
3. *Optional:* If you don't have a screen, usb keyboard and even an ethernet cable available, you can pre-configure Wifi for a headless setup.

   ```bash
   # on your linux computer, cd to the mounted microSD card partition "writable" and copy the wifi sample file. If you can't see any partition called "writable", then you are probably running something other than linux and need to figure out how to mount an ext4 filesystem.
   sudo cp ./usr/share/doc/netplan/examples/wireless.yaml ./etc/netplan/
   # open the file to edit
   sudo nano ./etc/netplan/wireless.yaml
   # strip down the file to the bare minmum for the Pi to get an IP automatically assigned by your router
   network:
   version: 2
   wifis:
    wlan0:
      dhcp4: yes
      dhcp6: no
      access-points:
        "<YOUR WIFI SSID>":
          password: "<YOUR WIFI PASSWORD>"
   # if you can't access your router to read out your Pi's IP, you can also configure a static IP now
      addresses: [192.168.1.42/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [192.168.1.1, 8.8.8.8]
   # CTRL+S, CTRL+X.
   ```
4. Insert the microSD card into your Pi, connect it to your router via ethernet cable and to a power supply. Connecting a screen via HDMI and a USB keyboard makes life easier, but checking the assigned IP in your router and SSHing in from your computer works too.
5. Follow the inital setup instructions. Default user + password is `ubuntu`. You will be asked to change the password on first login.
6. Update ubuntu via `sudo apt update && sudo apt upgrade`
7. If you are using Ubuntu 20.04, install docker & docker-compose by running `sudo apt install docker.io`. Otherwise if you are using any version besides Ubuntu 20.04, follow the [official instructions](https://docs.docker.com/install/linux/docker-ce/ubuntu/) (select `arm64` in step 4 of "Set up the repository") to install docker.
8. Add new user `opendex`:

   ```bash
   ubuntu@ubuntu:~$ sudo adduser opendex
   Adding user `opendex' ...
   Adding new group `opendex' (1001) ...
   Adding new user `opendex' (1001) with group `opendex' ...
   Creating home directory `/home/opendex' ...
   Copying files from `/etc/skel' ...
   New password: 
   Retype new password: 
   passwd: password updated successfully
   Changing the user information for opendexd
   Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
   Is the information correct? [Y/n] ubuntu@ubuntu:~$ Y
   ```
9. Add the `opendex` user to the sudo group (advanced users can skip this and use another user to run sudo commands), the docker group and test if docker is working:

   ```bash
   ubuntu@ubuntu:~$ sudo usermod -aG sudo opendex
   ubuntu@ubuntu:~$ sudo usermod -aG docker opendex
   # switch to user opendexd
   ubuntu@ubuntu:~$ sudo su - opendex
   opendex@ubuntu:~$ docker run hello-world
   Hello from Docker!
   This message shows that your installation appears to be working correctly.
   ```
10. Looking good! Optionally, add an alias to enter your opendexd environment by simply typing "opendex":

    ```bash
    opendex@ubuntu:~$ sudo nano ~/.bash_aliases
    # add the line
    alias opendex='bash ~/opendex.sh'
    # CTRL+S, CTRL+X. Then run
    opendex@ubuntu:~$ source ~/.bashrc
    ```
11. Connect the USB stick to your Pi and set it up. It is very important to do this for a mainnet setup (given you do not want to lose money)!

    ```bash
    # check the USB stick's path with
    opendex@ubuntu:~$ ls -la /dev/ | grep sd
    crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
    brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
    brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
    crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
    # set it to automount via fstab
    opendex@ubuntu:~$ sudo nano /etc/fstab
    # add the line
    /dev/sda1 /media/USB ext4 defaults 0 2
    # CTRL+S, CTRL+X. Then mount it
    opendex@ubuntu:~$ sudo mkdir /media/USB
    opendex@ubuntu:~$ sudo mount -a
    # check if mounting worked
    opendex@ubuntu:~$ df -h
    # make sure opendexd can use it
    opendex@ubuntu:~$ sudo chown opendex:opendex /media/USB
    ```

    From here the light and full setup require different settings. Continue choosing one.

## Pi Light Setup

If you are using a Pi model with 2GB of RAM or more, you can continue [here](/develop/docs/liquidity-providers#the-setup). If you are using a Pi model with <2GB of RAM, we will have to catch a temporary RAM spike when creating the opendex environment by creating a swap file (overflow RAM) of 2GB on the internal sd card:

```bash
# create the swap file
opendex@ubuntu:~$ sudo fallocate -l 2G /home/opendex/swapfile
# mark it as swap file
opendex@ubuntu:~$ sudo chmod 600 /home/opendex/swapfile && sudo mkswap /home/opendex/swapfile
# enable it
opendex@ubuntu:~$ sudo swapon /home/opendex/swapfile
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/home/opendex/swapfile none swap sw 0 0
# # CTRL+S, CTRL+X. Let's verify it's working & reboot
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/home/opendex/swapfile file  2G   0B   -2
opendex@ubuntu:~$ sudo reboot
# after reboot, let's check if the swapfile is still active
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/home/opendex/swapfile file  2G   0B   -2
```

Light setup - **DONE!** Continue [here](/develop/docs/liquidity-providers#the-setup).

## Pi Full Setup

Connect the SSD to your Pi4 and set it up:

```bash
# let's check the SSD's path
opendex@ubuntu:~$ ls -la /dev/ | grep sd
crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
brw-rw----  1 root disk      8,  16 Jan 28 10:45 sdb
brw-rw----  1 root disk      8,  17 Jan 28 10:45 sdb1 #this is your SSD
crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/dev/sdb1 /media/SSD ext4 defaults 0 2
# CTRL+S, CTRL+X. Then mount it
opendex@ubuntu:~$ sudo mkdir /media/SSD
opendex@ubuntu:~$ mount -a
# check if mounting worked
opendex@ubuntu:~$ df -h
# make sure opendexd can use it without sudo privileges
opendex@ubuntu:~$ sudo chown opendexd:opendexd /media/SSD
```

Let's do a quick performance test of the SSD. If you are close to these values, you are good to go, whereas <100 MB/s would be too slow:

```bash
opendex@ubuntu:~$ sudo dd if=/dev/zero  of=/media/SSD/deleteme.dat bs=32M count=64 oflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 12.8709 s, 167 MB/s
opendex@ubuntu:~$ sudo dd if=/media/SSD/deleteme.dat of=/dev/null bs=32M count=64 iflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 15.5791 s, 138 MB/s
opendex@ubuntu:~$ sudo rm /media/SSD/deleteme.dat
```

Important: geth needs loads of RAM when syncing, so we need to create a swap file (overflow RAM) of 8GB on the external SSD:

```bash
# create a swap file on the SSD, we recommend a size of 8GB
opendex@ubuntu:~$ sudo fallocate -l 8G /media/SSD/swapfile
# mark it as swap file
opendex@ubuntu:~$ sudo chmod 600 /media/SSD/swapfile && sudo mkswap /media/SSD/swapfile
# enable it
opendex@ubuntu:~$ sudo swapon /media/SSD/swapfile
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/media/SSD/swapfile none swap sw 0 0
# # CTRL+S, CTRL+X. Let's verify it's working & reboot
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/media/SSD/swapfile file  8G   0B   -2
opendex@ubuntu:~$ sudo reboot
# after reboot, let's check if the swapfile is still active
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/media/SSD/swapfile file  8G   0B   -2
```

Full setup - **DONE!** Continue [here](/develop/docs/liquidity-providers#the-setup).


# Pro Hardware Guide

This guide is written for professional liquidity providers to turn a powerful Mini PC into an always-on OpenDEX node.

![](/files/-MT_sqiJs_8xySAarC-M)

Two options are available:

1. **Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider or optionally [Infura](https://infura.io/). This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more resources and an SSD, but keeps the setup trustless.

## Light Reference Shopping List (Europe): \~180 €

* [GIGABYTE GB-BLCE-4105 BRIX](https://www.computeruniverse.net/en/gigabyte-gb-blce-4105-brix): 138 €
* [4 GB RAM](https://www.computeruniverse.net/en/crucial-4gb-ddr4-so-dimm-ct4g4sfs824a-2400mhz-ram): 15 €
* [120GB M.2 SSD](https://www.computeruniverse.net/en/wd-green-ssd-m2-2280-120gb): 20 €
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

## Full Reference Shopping List (Europe): \~465 €

* [GIGABYTE GB-BLCE-4105 BRIX](https://www.computeruniverse.net/en/gigabyte-gb-blce-4105-brix): 138 €
  * Alternative: [ODROID H2+](https://www.hardkernel.com/shop/odroid-h2plus/) - same platform, features NVME, needs separate case, power supply and wifi dongle, out of stock at times
* [32 GB RAM](https://www.computeruniverse.net/en/kingston-hyperx-impact-32gb-ddr4-so-dimm-ram-2): 127 €
  * Alternative: [List of compatible RAM](https://wiki.odroid.com/odroid-h2/hardware/ram)
* [2TB SSD](https://www.computeruniverse.net/en/sandisk-ssd-plus-25-2tb): 193 €
  * Alternative: [1 TB M.2 SSD NVME](https://www.computeruniverse.net/en/gigabyte-ssd-nvme-m2-2280-1tb) - for Odroid H2+
  * Alternative: [240GB M.2 SSD](https://www.computeruniverse.net/en/wd-green-ssd-m2-2280-240gb) + [2TB HDD](https://www.computeruniverse.net/en/seagate-firecuda-compute-st2000lx001-sshd-2tb)
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

## Setup

1. [Download Ubuntu Server 20.04 LTS](https://ubuntu.com/download/server) onto your computer. Any other linux distribution supporting docker is also fine. This guide was written using `Ubuntu Server 20.04`.
2. Insert a USB Stick into your computer and [create the a bootable USB Stick](https://ubuntu.com/tutorials/tutorial-create-a-usb-stick-on-ubuntu) with the ubuntu image you just downloaded.
3. Open your Mini PC, plug in RAM & drives, close it, connect it to your router via ethernet cable and to a power supply. Connect a screen via HDMI, a USB keyboard, the created bootable USB Stick, fire the Mini PC up and follow the the inital setup instructions.
4. Update ubuntu via `sudo apt update && sudo apt upgrade`
5. If you are using Ubuntu 20.04, install docker & docker-compose by running `sudo apt install docker.io`. Otherwise if you are using any version besides Ubuntu 20.04, follow the [official instructions](https://docs.docker.com/install/linux/docker-ce/ubuntu/) to install docker.
6. Add new user `opendex`:

   ```bash
   ubuntu@ubuntu:~$ sudo adduser opendex
   Adding user `opendex' ...
   Adding new group `opendex' (1001) ...
   Adding new user `opendex' (1001) with group `opendex' ...
   Creating home directory `/home/opendex' ...
   Copying files from `/etc/skel' ...
   New password: 
   Retype new password: 
   passwd: password updated successfully
   Changing the user information for opendexd
   Enter the new value, or press ENTER for the default
    Full Name []: 
    Room Number []: 
    Work Phone []: 
    Home Phone []: 
    Other []: 
   Is the information correct? [Y/n] ubuntu@ubuntu:~$ Y
   ```
7. Add the `opendex` user to the sudo group (advanced users can skip this and use another user to run sudo commands), the docker group and test if docker is working:

   ```bash
   ubuntu@ubuntu:~$ sudo usermod -aG sudo opendex
   ubuntu@ubuntu:~$ sudo usermod -aG docker opendex
   # switch to user opendex
   ubuntu@ubuntu:~$ sudo su - opendex
   opendex@ubuntu:~$ docker run hello-world
   Hello from Docker!
   This message shows that your installation appears to be working correctly.
   ```
8. Looking good! Optionally, add an alias to enter your opendexd environment by simply typing "opendex":

   ```bash
   opendex@ubuntu:~$ sudo nano ~/.bash_aliases
   # add the line
   alias opendex='bash ~/opendex.sh'
   # CTRL+S, CTRL+X. Then run
   opendex@ubuntu:~$ source ~/.bashrc
   ```
9. Connect the USB stick to your machine and set it up. It is very important to do this for a mainnet setup (given you do not want to lose money)!

   ```bash
   # check the USB stick's path with
   opendex@ubuntu:~$ ls -la /dev/ | grep sd
   crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
   brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
   brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
   crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
   # set it to automount via fstab
   opendex@ubuntu:~$ sudo nano /etc/fstab
   # add the line
   /dev/sda1 /media/USB ext4 defaults 0 2
   # CTRL+S, CTRL+X. Then mount it
   opendex@ubuntu:~$ sudo mkdir /media/USB
   opendex@ubuntu:~$ sudo mount -a
   # check if mounting worked
   opendex@ubuntu:~$ df -h
   # make sure opendexd can use it
   opendex@ubuntu:~$ sudo chown opendex:opendex /media/USB
   ```

   **DONE!** Continue [here](/develop/docs/liquidity-providers#the-setup).


# 🔁-Swap Providers

This guide is written for system administrators of projects looking to **source liquidity** on the OpenDEX network and is still an **early-stage WIP**.

## Prerequisites

### Two Modes

1. **Default: Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider. This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Optional: Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more time and resources, but keeps the setup trustless.

### Three Networks

1. **Simnet**. `Status: down` until further notice
2. **Testnet**. `Status: up | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 200GB for full | Initial Sync Time: 15 mins for light, 24h for full`

   bitcoin testnet 3, litecoin testnet 4, ethereum rinkeby. Faucets: [t-BTC](https://coinfaucet.eu/en/btc-testnet/), [t-LTC](https://testnet.help/en/ltcfaucet/testnet), [t-ETH 1](https://faucet.rinkeby.io/) or [2](https://testnet.help/en/ethfaucet/rinkeby). If you need help or some testnet coins, hit us up on [Discord](https://discord.gg/aS5RMchDrU)!
3. **Mainnet**. `Status: down | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 1TB for full | Initial Sync Time: 30 mins for light, 72h for full`

   Down until all breaking changes are merged and some weeks on testnet didn't reveal major issues.

### Software

Docker & Docker Compose.

Version >= 18.09 on Linux or Windows 10 [using WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). If you do not have docker & docker-compose installed yet and you are using Ubuntu 20.04 LTS, install these via `sudo apt install docker.io`. If you are using any version besides Ubuntu 20.04, follow the official [docker install instructions](https://docs.docker.com/get-docker/). Also make sure that the current user can run docker commands. Test with `docker run hello-world`. If this fails, [follow these instructions](https://docs.docker.com/engine/install/linux-postinstall/). This guide was written using Ubuntu 20.04 LTS.

## The Setup

From here we assume that your device is running with docker set up. Check the guides in the hardware section above if your device is not ready yet.

### Let's Roll

Start the environment with

```bash
curl https://raw.githubusercontent.com/opendexnetwork/opendex-docker/master/opendexd.sh -o ~/opendexd.sh
bash ~/opendexd.sh
```

The setup will ask you to choose the network:

```
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
🚀 Launching mainnet environment
🌍 Checking for updates ...
```

Sync light clients (default):

```
Syncing light clients:
┌─────────┬─────────────────────────────────────────────────────┐
│ SERVICE │ STATUS                                              │
├─────────┼─────────────────────────────────────────────────────┤
│ lndbtc  │ Syncing 34.24% (610000/1781443)                     │
├─────────┼─────────────────────────────────────────────────────┤
│ lndltc  │ Syncing 12.17% (191000/1568645)                     │
└─────────┴─────────────────────────────────────────────────────┘
```

And then guide you through some basics:

```
Do you want to create a new opendexd environment or restore an existing one?
1) Create New
2) Restore Existing
Please choose: 1
```

When creating a new opendexd SEED, the setup asks you to set a password to encrypt your environment's private keys and to write down your mnemonic phrase. This serves as backup for your opendexd node key and wallets (your on-chain assets). This is your last resort in case something happens to your device. **Keep it somewhere safe!**

```
You are creating an opendexd node key and underlying wallets. All will be secured by a single password provided below.

Enter a password: 
Re-enter password: 

----------------------BEGIN OPENDEX SEED---------------------
 1. you         2. won't       3. find        4. money      
 5. in          6. this        7. seed        8. but    
 9. good       10. thinking   11. if         12. you      
13. are        14. interested 15. in         16. getting     
17. rewarded   18. for        19. testing    20. opendex  
21. security   22. hit        23. us         24. up   
-----------------------END OPENDEX SEED----------------------

The following wallets were initialized: BTC, LTC, ERC20(ETH)
```

Then you'll be asked to enter the path to your backup drive, e.g. a previously mounted USB drive:

```
Please enter a path to a destination where to store a backup of your environment. It includes everything, but NOT your on-chain wallet balance which is secured by your opendexd SEED. The path should be an external drive, like a USB or network drive, which is permanently available on your device since backups are written constantly.

Enter path to backup location: /media/USB/
Checking... OK.
```

The entered backup drive location is persisted as `backup-dir = "/media/USB/"` in `mainnet.conf` and can be changed any time. Alternatively, you can consider running your environment on two hard drives in [RAID 1](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1) to protect against data loss.

Then the setup might restart clients and ask you to enter your password once more before the CTL

Use the `status` command to check on the your setup's health and sync progress. The default light setup should show `Ready` after some seconds:

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for lndbtc, lndltc                     │
└───────────┴────────────────────────────────────────────────┘
```

If you configured the full setup via config file or cli parameters, the sync will start fast and get slower towards the end. You might see 0.00% progress for several minutes at first.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 0.00% (0/436000)                       │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 0.00% (0/324000)                       │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 0.00% (55/9140561)                     │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

After a while you should see all three full-nodes syncing nicely.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 43.06% (262348/609123)                 │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 35.94% (631593/1757002)                │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 10.16% (929072/9140623)                │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

Bitcoind/Litecoind should finish syncing within 12h, geth in about 72h on powerful hardware. A Pi4 needs about twice that long.

The CLI takes `opendex-cli` commands without the need to prepend `opendex-cli`, e.g. simply type `getinfo` to get basic information about your opendex node. Run `help` to get an always up-to-date list of commands. Append `-j` to any command to get JSON instead of the formatted output, e.g. using `listpeers` to see other opendexd nodes on the network:

```
mainnet > listpeers -j
{
  "peersList": [
    {
      "address": "rgz5icb5jdxzmu7r7tbis64q23ioytzd4tqikuyb5kz75w75rbe6veyd.onion:8885",
      "nodePubKey": "02529a91d073dda641565ef7affccf035905f3d8c88191bdea83a35f37ccce5d64",
      "lndPubKeysMap": [
        [
          "BTC",
          "035cb9afb06a83e65fbab15c900d78580673cf56ce38c5814fb71f1eb57fcba7ee"
        ],
        [
          "LTC",
          "036cf16cd7de6193efb2855e784409c3633f893662dd6edcf7a545a99659232373"
        ]
      ],
      "inbound": false,
      "pairsList": [
        "LTC/BTC",
        "ETH/BTC",
      ],
      "opendexdVersion": "1.2.7",
      "secondsConnected": 100,
      "connextAddress": "0xe802431257a1d9366BD5747F0F52bAd25A6C3092"
    }
  ]
}
```

### Your First Trade

Start by depositing some funds into your opendex node:

```bash
deposit btc #Send BTC to this address
deposit ltc #Send LTC to this address
deposit eth #Send ETH to this address
```

The deposit command for BTC & LTC is powered by [Boltz](https://boltz.exchange). Boltz will automatically open a balanced lightning channel to you, if you don't have a channel yet. This can take several minutes to complete and we'd kindly ask you to wait patiently for your funds to appear in the `getbalance` overview. If you want to follow what is happening under the hood, you can do so by typing `logs boltz`. For ETH, currently one still needs to trigger a manual channel creation in a second step after funds were deposited:

```
openchannel ETH 13.37
```

Check existing orders for all activated pairs with the command `orderbook`. It might take several seconds to see orders after opendexd was started due to the decentralized nature of the order exchange. Use `orderbook btc/usdt` to show the order book for BTC/USDT only:

```
mainnet > orderbook btc/usdt

Trading pair: BTC/USDT
┌───────────────────────────────────────┬───────────────────────────────────────┐
│ Buy                                   │ Sell                                  │
├───────────────────┬───────────────────┼───────────────────┬───────────────────┤
│ Quantity          │ Price             │ Price             │ Quantity          │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.28918298        │ 7171.56           │ 7172.253          │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 1                 │ 7171.1937         │ 7172.9757         │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7171.083          │ 7316.0663         │ 1                 │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7170.899          │ 7316.44           │ 0.22393946        │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
```

Use `getbalance` to check your balance *before* the swap.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.10944853    │ 2.5                        │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5000          │ 5000                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

Issue a regular limit order with e.g. `sell 0.1 btc/usdt 7171` to sell 0.1 btc for a price of 7171 USDT per BTC. If your order was matched, settlement shouldn't take longer than a couple of seconds.

```
mainnet > sell 0.1 btc/usdt 7171
swapped 0.1 BTC with peer order ca24fe00-1c1e-11ea-8b1b-3b2ec0335696
```

Use `getbalance` to check your balance *after* the swap. You are now owning 0.1 BTC less and 717 USDT more.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.00944842    │ 2.39999989                 │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5717          │ 5717                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

### Connect Swap Provider Bot

WIP

## Report Issues

Please give us feedback and report bugs by running `report` from within `opendex ctl` or our "help" channel on [Discord](https://discord.gg/aS5RMchDrU)!

### References

* [bitcoind config options](https://github.com/bitcoin/bitcoin/blob/master/share/examples/bitcoin.conf)
* [litecoind config options](https://litecoin.info/index.php/Litecoin.conf#litecoin.conf_Configuration_File)
* [geth config options](https://github.com/ethereum/go-ethereum/blob/master/README.md#configuration)
* [lnd config options](https://github.com/lightningnetwork/lnd/blob/master/sample-lnd.conf)
* [connext config options](https://docs.connext.network/en/latest/quickstart/clientInstantiation.html#client-options)
* [opendexd config options](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf)


# 📈-Day Traders

The [OpenDEX Desktop App](https://github.com/opendexnetwork/opendex-desktop/releases) is the recommended way for high-frequency trading on the OpenDEX Network with a nice user interface. If preferred, trading entirely via the command line is possible though following [this guide](/develop/docs/liquidity-providers).


# 👨‍💻-Developers

This guide is intended to help developers who want to contribute to `opendexd`. Developers who want to build services on top of `opendexd`, should check out the node's [API Documentation](https://api.opendex.network/).

## Contribution Guidelines

Be sure to read the [Contribution Guidelines](/develop/docs/contribute) before starting to work or opening a Pull Request.

## Recommended Development Environments

The following development environments are known to be compatible with `opendexd` and are recommended for developers that are unsure what tools to use.

### Visual Studio Code

[Visual Studio Code](https://code.visualstudio.com/) is a cross-platform code editor that's compatible with most popular programming languages and extensible via a large collection of plug-ins.

#### Visual Studio Code Plugins

Consider using the following plugins for working with `opendexd`.

* [TSLint](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin)
* [vscode-proto3](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3)
* [Bracket Pair Colorizer](https://marketplace.visualstudio.com/items?itemName=coenraads.bracket-pair-colorizer) (definitely optional)

#### Visual Studio Code Environment Config

Adding the two files from [this gist](https://gist.github.com/sangaman/117af412eefc28c4f763c0152ddd3b99) into a `.vscode` folder within the folder where you've cloned `opendexd` will automatically provide debug configurations and general settings that are helpful when developing `opendexd`.

## `opendexd` Setup

### Auto-restart `opendexd` on file change

Auto restart on every file change under `dist` folder with `nodemon`:

```
nodemon --watch dist -e js bin/opendexd
```

With some sample args disabling lndbtc/lndltc:

```
nodemon --watch dist -e js bin/opendexd --lndbtc.disable=true --lndltc.disable=true
```

### Connect `opendexd` to testnet

We recommend to connect the `opendexd` instance you are developing on to testnet. Combined with above restarting mechanism, this lets you instantly see how your changes behave in a real-world trading environment.

1. Start testnet with default settings as described [here](/develop/docs/liquidity-providers).
2. Once the environment is up and running, exit from the cli session by typing `exit` or open a second terminal.
3. Stop the opendexd container with `docker stop testnet_opendexd_1`.
4. Copy the testnet lndbtc & lndltc folders into some path that you can easily access. E.g. into your home directory:

   ```
   sudo cp -R ~/.opendex-docker/testnet/data/lndbtc ~/
   sudo cp -R ~/.opendex-docker/testnet/data/lndltc ~/
   ```
5. Ensure that you own the copied folders:

   ```
   sudo chown -R <youruser> ~/lndbtc
   sudo chown -R <youruser> ~/lndltc
   ```
6. Create/change `opendex.conf` in `~/.opendexd` to contain the following:

   ```bash
   [lnd.BTC]
   cltvdelta = 40
   disable = false
   host = "localhost"
   nomacaroons = false
   port = 20009
   certpath = "/home/<youruser>/lndbtc/tls.cert"
   macaroonpath = "/home/<youruser>/lndbtc/data/chain/bitcoin/testnet/admin.macaroon"
   [lnd.LTC]
   cltvdelta = 576
   disable = false
   host = "localhost"
   nomacaroons = false
   port = 21009
   certpath = "/home/<youruser>/lndltc/tls.cert"
   macaroonpath = "/home/<youruser>/lndltc/data/chain/litecoin/testnet/admin.macaroon"
   [connext]
   disable = false
   host = "localhost"
   port = 18000
   ```
7. Now you can start your local `opendexd` instance and it should connect to the running testnet docker environment. You can check that everything works with `~/opendexd/bin$ ./opendex-cli -p 18886 getinfo`.

## References

* [Official TypeScript Documentation](https://www.typescriptlang.org/docs/home.html)
* [Official Node.js Documentation](https://nodejs.org/en/docs/)
* [LND Developer Guide](https://dev.lightning.community/)
* [Official gRPC Documentation](https://grpc.io/docs/)


# 🤝-Code Contribution

Yay! Thanks for helping us build OpenDEX! Any contributions are welcome no matter how big or small. From typos and bug fixes to entire modules...

## Contribution Guidelines

If you are new to contributing to open sources projects on GitHub, check out [this how-to](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github/).

### Feature Branches & Pull Requests

We use [feature branches](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) for devlopment. Each branch and pull request should focus on a particular feature or issue. Ensure that new branches are created from the latest code in `main`. A branch must be in a working and stable state before it can be merged into `main`.

Pull requests will be reviewed and changes may be requested. If changes are required, make new commits directly to the feature branch. If there have been conflicting commits to `main` since a feature branch was created, rebase the branch onto main using `git rebase`.

For pull requests of small scope, you may squash multiple commits into a single commit or a maintainer will squash them before merging. For more complex pull requests that touch many parts of the code or which contain commits from multiple contributors, please collapse commits by author and affected files or components of the project. This can be performed through an interactive rebase with `git rebase -i`. Use `git commit --amend` when fixing minor typos or bugs with the most recent commit. These practices help maintain a clean and coherent commit history while preserving contribution authorship.

### Linting & Testing

New test cases are appreciated for any pull requests that changes or adds new functionality. Although the current test suites are in early stages, thorough testing and code coverage is an important long term goal.

All code is linted with [tslint](https://github.com/palantir/tslint) using a slightly modified [tslint adaptation](https://github.com/progre/tslint-config-airbnb) of [Airbnb's javascript style guide](https://github.com/airbnb/javascript). Ensure that your contributions pass all linting rules by running `npm run lint` or using a code editor with a tslint plugin. Per-line or per-file exceptions to linting rules are allowable in certain cases.

### Commenting & Documentation

Make your code legible by using descriptive variable, function, and class names. For blocks of codes whose function is not readily apparent, add comments explaining what they do. If a pull request changes the interface to `opendexd` or introduces new functionality, update the README to describe these changes.

`opendexd` uses [TypeDoc](http://typedoc.org/guides/doccomments/) and any comments documenting specific classes, methods, properties should follow this convention.

Commit messages should be concise and descriptive. For larger or more complex commits, add details of what has changed in the commit description.

If you see something missing or want to develop another cool feature or bug fix which doesn't have an issue yet, open one and we'll take it from there. We don't recommend working on things without a GitHub issue.


# ✋-Dockerless Setup

This page contains instructions how to natively install `opendexd` and its minimal dependencies `lnd` (BTC) & `connext` (ETH & ERC20) on linux. It is mainly geared towards developers and administrators which prefer a native installation over docker.

## Requirements

Make sure to have the following installed:

* [Node.js](https://nodejs.org/en/download/), current active LTS (we recommend [installing via nvm](https://nodejs.org/en/download/package-manager/#nvm))
* [Go](https://golang.org/), v1.14 or higher
* a user called `opendexd`

## opendexd

### Option 1: Installing latest release via npm

This is the easiest and fastest way to install `opendexd` on a `amd64` machine:

```bash
sudo npm install opendexd -g --unsafe-perm
```

### Option 2: Cloning from GitHub

Testers and developers are encouraged to clone the repository from GitHub and install from source:

```bash
git clone https://github.com/opendexnetwork/opendexd
cd opendexd
npm install
npm run compile
npm run compile:seedutil
```

If you are on an architecture that is *not* `amd64`, you'll have to remove `grpc-tools` and potentially others from the `devDependencies` section of [`package.json`](https://github.com/opendexnetwork/opendexd/blob/main/package.json).

### Daemonize `opendexd`

If you want to daemonize `opendexd`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```
[Unit]
Description=opendexd

[Service]
User=opendexd
Group=opendexd
Type=simple
Environment=NODE_ENV=production
ExecStart=/home/opendexd/opendexd/bin/opendexd --mainnet
KillMode=process
KillSignal=SIGINT
```

## LND (BTC)

Follow the [lnd installation guide](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md#installing-lnd).

### Daemonize `lnd`

If you want to daemonize `lnd`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```
[Unit]
Description=LND

[Service]
User=opendexd
Group=opendexd
Type=simple
ExecStart=/home/opendexd/lnd/bin/lnd --bitcoin.mainnet
KillMode=process
KillSignal=SIGINT
```

## Connext

Follow the [docs](https://github.com/connext/vector#quick-start), you want the **`node`: vector node + database** stack.

### Daemonize `connext`

If you want to daemonize `connext`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```
[Unit]
Description=Connext

[Service]
User=opendexd
Group=opendexd
Type=simple
Environment="NODE_ENV=production"
Environment="CONNEXT_NODE_URL=https://connext.boltz.exchange"
Environment="CONNEXT_ETH_PROVIDER_URL=http://eth.kilrau.com:41007"
Environment="LEGACY_MODE=true"
WorkingDirectory=/home/opendexd/connext/
ExecStart=node /home/opendexd/connext/build/src/index.js
KillMode=process
KillSignal=SIGINT
```

## Tor

You can install tor via `sudo apt install tor` on most linux distros nowadays, just make sure [the version is fairly recent](https://github.com/torproject/tor/releases). If not, consult the [tor installation guides](https://2019.www.torproject.org/docs/installguide.html.en). Run `systemctl status tor` or `ps aux | grep tor` to verify the tor process is running.

## Putting it all together

Create the following `opendexd.conf` in `/home/opendexd/.opendexd`:

```
mainnet = true

[p2p]
tor = true
torport = 9050

[connext]
disable = false
host = "localhost"
port = 8000
webhookhost = "localhost"
webhookport = 8887

[lnd.BTC]
disable = false
host = "localhost"
certpath = "/home/opendexd/.lnd/tls.cert"
macaroonpath = "/home/opendexd/.lnd/admin.macaroon"

[lnd.LTC]
disable = true
```

For convenience, consider adding `alias opendex-cli='/home/opendexd/opendexd/bin/opendex-cli -p 8886'` to the opendexd user's `.bashrc` and source it. Then restart `opendexd` once (e.g. with `systemctl restart opendexd`) and try running `opendex-cli getinfo`, which should return with an overview of opendexd's, as well as lnd's and connext status.

Ping us in the help channel of our [Discord server](https://discord.gg/aS5RMchDrU) for support.

## Tips 'n Tricks

* When installing on a Raspberry Pi you might see `Unexpected error during initialization`. [Here](https://github.com/ExchangeUnion/xud/issues/1199#issuecomment-527819108) is the solution.
* If you see an `install error` when installing via `npm install`, try `npm install --production` & `npm install typescript`.


# 🛑-How-to Close Shop

This guide is written for anyone looking to "close shop", to withdraw all funds from an opendex environment.

## Close Shop

Enter your environment via:

```bash
bash ~/opendex.sh
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
```

Stop arby to prevent it from issuing orders:

```bash
stop arby
```

Close all BTC & LTC channels:

```bash
lndbtc-lncli closeallchannels
lndltc-lncli closeallchannels
```

Check your ETH/ERC20 channel balances with `getbalance` and close channels using the full channel balance in the following command:

```bash
closechannel ETH --amount 0.5234
closechannel USDT --amount 124.12
```

`getbalance` should now show all **channel** balances as `0`. Once your ETH/ERC20 channel balances are available as `Wallet Balance (Not Tradable)`, you can import your seed/private key into a wallet like metamask. To do this, run the following command and follow the instructions:

```bash
getethmnemonic
```

Once your BTC and LTC channel balances are available as `Wallet Balance (Not Tradable)`, run:

```bash
lndbtc-lncli sendcoins --sweepall --addr <YOUR_EXTERNAL_BTC_ADDRESS>
lndltc-lncli sendcoins --sweepall --addr <YOUR_EXTERNAL_LTC_ADDRESS>
```

One more check that all balances are indeed `0` with `getbalance` and you can safely `down` and delete your environment.


# 💻-CLI Docs

`opendex-cli` is the command line interface that handles much of the basic interaction with a running `opendexd` instance. If `opendexd` is installed globally, it can be launched from any directory. In the recommended [opendex-docker](/develop/docs/liquidity-providers) setup, it can be used from within the `opendexd ctl` shell.

To get a list of up-to-date commands, run:

```
opendex-cli --help
```

Calling any one of the listed commands with the `--help` flag will output additional instructions for that particular command.

Examples for commands:

```bash
# Manually connect to another opendexd instance (has to be running the same network: simnet/testnet/mainnet)
$ opendex-cli connect 025fbfe0e92bf0e5e64500ed542d51f4f9d59111a2d3fa142e90567ec417c4a617@1.opendex.network:8885

# Places a new limit order BUYING 10 LTC for a price of 0.0079 BTC per LTC
$ opendex-cli buy 10 LTC/BTC 0.0079

# Places a new limit order SELLING 5 LTC for the best market price
$ opendex-cli sell 5 LTC/BTC market
```

By default, the CLI output is formatted and abbreviated. Append `-j` to any of the CLI calls to receive the full output in JSON format.


# 🎚️-Config Docs

An *optional* configuration file uses [TOML](https://github.com/toml-lang/toml) and by default should be saved at `~/.opendexd/opendex.conf` on Linux or `AppData\Local\OpenDEX\opendex.conf` on Windows. Run `opendexd` at least once for this folder to be created. The `opendexd` repository contains an up-to-date [`sample-opendex.conf`](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf) which serves as template for creating `opendex.conf`. It is possible to overwrite the default data directory by launching `opendexd` with `opendexd --opendexdir=/path/to/custom/opendexdir`.

## Precedence

The precedence order in which configuration option values are applied is as follows (high to low):

1. Option given on the command line
2. Option read from the config file
3. Option default value (as seen in the output of `opendexd --help`)


# 📜-Intro

These **BOLD (for Basis of Layer-3 DEX)** documents describe a protocol for p2p trading of cryptocurrencies with the following design goals:

* decentralized order exchange
* native cross-chain capability
* instantaneous off-chain settlement

Nodes running implementations of the protocol comprise the OpenDEX network. Click "Next" below to start reading the BOLD protocol specifications.


# 1️⃣-Message Format

## Overview

All messages sent between nodes have headers. The initial handshake messages are sent unencrypted, and all other messages are encrypted and authenticated using the keys that are generated during the initial handshake.

All messages payloads are serialized using **Protocol Buffers**.

Protocol buffers are a language-neutral, platform-neutral, extensible mechanism for serializing structured data. You can find [documentation on the Google Developers site](https://developers.google.com/protocol-buffers/).

To develop with protocol buffers you will need to install the protocol buffer compiler (to compile `.proto` files) and the protocol buffer runtime for your chosen programming language.

Protocol buffers currently support development in Java, Python, Go, Rust, C, C++, Objective-C, C#, Dart, Ruby, Perl, Haskell, Javascript, [and more](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md#programming-languages).

### The unencrypted message

| Size (bytes) | Name     | Data Type | Description                                             |
| ------------ | -------- | --------- | ------------------------------------------------------- |
| 4            | magic    | uint32    | Magic value to specify the message's network            |
| 4            | length   | uint32    | Payload length                                          |
| 4            | type     | uint32    | Message type                                            |
| 4            | checksum | uint32    | First 4 bytes of sha256 hash of JSON-serialized message |
| length       | payload  | bytes     | The actual data                                         |

#### Magic values

| Network | Magic value  |
| ------- | ------------ |
| mainnet | `0xd9b4bef9` |
| testnet | `0x0709110b` |
| simnet  | `0x12141c16` |
| regnet  | `0xdab5bffa` |

### The encrypted message

| Size (bytes) | Name       | Data Type | Description           |
| ------------ | ---------- | --------- | --------------------- |
| 4            | length     | uint32    | Length of the payload |
| length       | ciphertext | bytes     | The encrypted data    |

#### Ciphertext pre-encryption format

| Size (bytes) | Name    | Data Type | Description     |
| ------------ | ------- | --------- | --------------- |
| 4            | length  | uint32    | Payload length  |
| 4            | type    | uint32    | Message type    |
| length       | payload | bytes     | The actual data |


# 2️⃣-Peer Protocol

## Overview

The current protocol requires a direct connection between two nodes for performing updates, trades, and swaps. This section describes how the connection is set up.

Each node maintains a persistent **secp256k1** private key with a corresponding public key, node key for short, which uniquely identifies the node in the network. We recommend only allowing manual resets of the private key, for example by deleting a file or database entry.

An initial handshake is required to establish a secure TCP-based session between two nodes. The default listening TCP port is **8885**.

## Handshake Protocol

The communication session is established by creating a TCP connection and agreeing on ephemeral key material for further encrypted communication, in addition to utilizing the persistent key for authentication. The process of establishing this session is the “handshake” and is carried out between the “initiator” (the peer that opened the TCP connection) and the “recipient” (the peer that accepted it).

The handshake consists of *each side* sending the `SessionInit` message, and waiting to receive the `SessionAck` message back. The first `SessionInit` message is expected to be sent by the initiator.

The initiator must know the recipient's identity (node key) in advance. The recipient learns the initiator's identity by receiving the `SessionInit` message.

By the end of the handshake, two distinct shared keys are created, one for each side of the communication, to be used to encrypt all messages during the session's lifetime.

## Handshake Messages

These messages are used in the initial handshake:

### SessionInit Message (0x00)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string sign = 2`
secp256k1 signature over sha256 hash of a JSON-serialized msg containing fields 3-7

`string peer_pub_key = 3`
The target node secp256k1 public key (in hex)

`string ephemeral_pub_key = 4`
An ephemeral secp256k1 public key (in hex), generated by the sender, for ECDH key exchange

`NodeState node_state = 5`
General info regarding the sender's current node state

`string version = 6`
OpenDEX client version

`string node_pub_key = 7`
The sender's secp256k1 public key (in hex)
```

Once received by the destination node, the message is authenticated as follows:

* `peer_pub_key` should match the destination node's public key&#x20;
* `node_pub_key` should match the sender node expected public key (relevant for the initiator node only since he already knows the recipient node's identity)
* `sign` should be a valid secp256k1 signature over the sha256 hash of a JSON-serialized msg containing fields 3-7

If the fields of the `SessionInit` message are valid, the receiver replies with a `SessionAck` message. If a `SessionAck` message is not received within a reasonable time frame (10 seconds is recommended), the sender may disconnect.

### SessionAck Message (0x01)

```
`string id = 1`
The message's globally unique identifier, generated by the sender

`string req_id = 2`
The id of the received SessionInit message

`string ephemeral_pub_key = 3`
An ephemeral secp256k1 public key (in hex), generated by the sender, for ECDH key exchange
```

Once the receiver of the `SessionInit` message (Bob) has generated his ECDH keys, he can calculate the shared key by using the `ephemeral_pub_key` from the `SessionInit` message. Once the `SessionAck` message is received by the sender of the `SessionInit` message (Alice), she can compute the shared key as well. All future communication from Alice to Bob must be encrypted with aes-256-cbc symmetric encryption using the shared key.

## Coordination Messages

These messages are used to maintain the P2P overlay after a session has been established via the initial handshake.

### Ping Message (0x04)

```
`string id = 1`
The message's globally unique identifier, generated by the sender
```

In order to allow long-lived TCP connections, both ends keep the TCP connection alive at the application level using `Ping` and `Pong` messages.

It is recommended to send a `Ping` message every 30 seconds.

The sender of a `Ping` message may disconnect if a `Pong` message is not received within 10 seconds.

### Pong Message (0x05)

```
`string id = 1` 
The message's globally unique identifier, generated by the sender

`string req_id = 2`
The id of the received Ping message
```

The `Pong` message is sent in response to the `Ping` message. It serves to keep the connection alive by explicitly notifying the other end that the receiver is still active.

### Disconnecting Message (0x03)

```
`string id = 1`
The message's unique identifier, generated by the sender 

`uint32 reason = 2`
The reason for the imminent disconnection 

`string payload = 3`
Optional payload to specify the disconnection reason
```

The `Disconnecting` message is used to inform a connected peer that a disconnection is imminent and that the peer should disconnect immediately. A well-behaved host that sends a `Disconnecting` message allows the peer at least 2 seconds to disconnect before disconnecting itself.

`reason` is an optional parameter for specifying one of the following reasons for the disconnection:

| Reason | Meaning                                     |
| ------ | ------------------------------------------- |
| `0x01` | Response stalling                           |
| `0x02` | Incompatible client protocol version        |
| `0x03` | Unexpected identity                         |
| `0x04` | Forbidden identity update                   |
| `0x05` | Connected to self                           |
| `0x06` | Not accepting new connections               |
| `0x07` | Banned                                      |
| `0x08` | Already connected                           |
| `0x09` | Shutdown                                    |
| `0x0a` | Malformed version                           |
| `0x0b` | Authentication failure: invalid target node |
| `0x0c` | Authentication failure: invalid signature   |
| `0x0d` | Wire protocol error                         |

### GetNodes Message (0x0a)

```
`string id = 1`
Message's globally unique identifier, generated by the sender
```

The `GetNodes` message is used to query a peer for its list of known, reachable OpenDEX nodes.

### Nodes Message (0x0b)

```
`string id = 1`
Message's globally unique identifier, generated by the sender 

`string req_id = 2`
Link to the id field from the received GetNodes message

`repeated Node nodes = 2`
The list of known nodes
```

The `Nodes` message is used to respond to the `GetNodes` message.

### NodeStateUpdate Message (0x02)

```
`string id = 1`
Message's globally unique identifier, generated by the sender 

`NodeState node_state = 2`
The updated node state.
```

The `NodeStateUpdate` message is used to tell a peer about a change in the node state. An example of an update is the removal or addition of a supported trading pair.

## Custom types

### NodeState type

```
`repeated Address addresses = 1`
The sender's listening TCP addresses

`repeated string pairs = 2`
The sender's list of trading pair symbols, constructed with the base currency first, followed by a  '/' separator and the quote currency (e.g., [“LTC/BTC”, “DAI/BTC”])

`string connext_identifier = 3`
The sender's Connext identifier (e.g. `indra123abc`)

`map<string, string> lnd_pub_keys = 4`
The sender's list of LND public keys

`map<string, string> token_identifiers = 5`
Mapping between currency symbols and chain identifiers or ETH-ERC20 token contract addresses (e.g., { BTC: 'bitcoin-mainnet', LTC: 'litecoin-mainnet', ETH:,'0x0000000000000000000000000000000000000000' })

`map<string, LndUris> lnd_uris = 6`
Mapping between currency symbols to LND listening URIs (should be reachable from the internet e.g., { BTC: ['2w526cyown43ovsvsojdowheqmukbykrexzyccp6v6j4pm5ve3hjzrid.onion:9735'], LTC: '['lndltc.kilrau.com:9735', 'qiyibtczmuhutusmygvc2injxl7v4yfcodwj3pft63edycud5gr3giad.onion:10735']' })
```

### Address type

```
`string host = 1`

`uint32 port = 2`
```

### LndUris type

```
`repeated string lnd_uri = 1`
```

### Node type

```
`string node_pub_key = 1`
The node's public key upon which its identity should be verified

`repeated Address addresses = 2`
The node's listening TCP addresses
```


# 3️⃣-Trade Protocol

## Overview

OpenDEX does not rely on a central order book or matching engine. Instead, each node on the network maintains its own local order book and matching engine.

Order matching systems of major exchanges differentiate between two participants: the taker and the maker. A taker "fills" the order of a maker.

Similarly, we distinguish between these two types of participants in a trade on OpenDEX:

* The **Maker**: submits an order which cannot be matched immediately by an existing order in the order book. The order is added to the order book and propagated to all connected peers.&#x20;
* The **Taker**: issues an order which can immediately be matched with an existing (maker) order in the order book.

## Order Type

```
`string id = 1`
The order's globally unique identifier, generated by the sender 

`string pair_id = 1`
A trading pair symbol, constructed with the base currency first, followed by a '/' separator and the quote currency (e.g., “LTC/BTC”)

`double price = 3`
The price for the order expressed in units of the quote currency

`uint64 quantity = 4`
The number of satoshis (or equivalent) for the order

`bool is_buy = 5`
Whether the order is a buy (true) or a sell (false)

`string replace_order_id = 6`
The id of an order that this order is replacing, the specified order should be removed
```

## Trade Protocol

### Order Message (0x06)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`Order order = 2`
The order
```

The `Order` message is used to tell a peer about a new maker order. It should only be sent to peers after the order (or part of the order) could not be matched in the local order book.

### OrderInvalidation Message (0x07)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string order_id = 2`
The order’s unique identifier

`string pair_id = 3`
The trading pair symbol associated with the order

`uint64 quantity = 4`
The number of satoshis (or equivalent) to invalidate from the order sum
```

The `OrderInvalidation` message is used to tell a peer about the full or partial invalidation of a previously sent order. It allows the peer to remove the order from his local order book. Order invalidation is a common event which occurs due to order cancellation or filling (by another node). Failing to send updates about the order will result in peers having a stale order in their local order books. These peers might fill the order and instantiate swap procedures which are doomed to fail. In this case, the maker node’s reputation may be penalized.

### The GetOrders Message (0x08)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`repeated string pair_ids = 2`
The requested orders trading pair symbols, constructed with the base currency first, followed by a  '/' separator and the quote currency (e.g., [“LTC/BTC”, “DAI/BTC”])
```

The `GetOrders` message is used to query a peer for a list of all open orders for the specified trading pairs. It is mainly used to initialize the local order book with a snapshot of the peer's existing open orders after establishing a connection to the peer. New orders are expected to get pushed by the peer via the `Order` message, instead of being queried for.

### The Orders Message (0x09)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string req_id = 2`
The id from the received `GetOrders` message

`repeated Order orders = 3`
The list of orders
```

The `Orders` message is used to respond to the `GetOrders` message.


# 4️⃣-Swap Protocol

## Overview

Once an order match is found in the taker’s order book, the swap protocol should be initiated. The current swap protocol assumes that the taker and maker are connected via a payment channel network (e.g. [Lightning](http://lightning.network/) or [Connext](https://connext.network/)) with sufficient balance available for the swap. The following is the swap protocol's "happy" flow:

1. Taker finds a match, e.g. buying 1 BTC for 10k DAI
2. Taker creates the private `r_preimage` and the public `r_hash` for the atomic swap
3. Taker sends the `SwapRequest` message to the maker, which includes `r_hash`
4. Maker confirms full or partial quantity in the `SwapAccepted` message
5. Taker starts the swap by dispatching the first-leg HTLCs on the DAI payment channel to the maker end, using `r_hash`
6. Maker listens for an incoming HTLC on the DAI payment channel. Once it arrives he verifies price and quantity and then dispatches the second-leg HTLCs on the BTC payment channel to the taker end.
7. Taker listens for an incoming HTLC on the BTC payment channel. Once it arrives he releases `r_preimage`. This allows **both** the taker and the maker payments to finalize.
8. Both nodes locally mark the swap as completed once the respective HTLC is resolved and the payment is finalized.

Possible misbehaviors and their outcome:

| Misbehavior                                                                         | Outcome                                              | Effect on payment channels                                  |
| ----------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
| Maker doesn't respond to the `SwapRequest` message                                  | Taker should timeout the swap and penalize the maker | None                                                        |
| Taker doesn't start the swap after receiving the `SwapAccepted` message             | Maker should timeout the swap and penalize the taker | None                                                        |
| Maker receives the first-leg HTLC with insufficient amount or incorrect CLTV delta  | Maker should send the taker a `SwapError` message    | Taker funds are locked until HTLC expiration                |
| Maker doesn't continue the swap after receiving the first-leg HTLC                  | Taker should timeout the swap and penalize the maker | Taker funds are locked until HTLC expiration                |
| Taker receives the second-leg HTLC with insufficient amount or incorrect CLTV delta | Taker should sends the maker a `SwapError` message   | Both Taker and Maker funds are locked until HTLC expiration |
| Taker doesn't release `r_preimage` after receiving the second-leg HTLC              | Maker should timeout the swap and penalize the taker | Both Taker and Maker funds are locked until HTLC expiration |

## Swap Protocol

### SwapRequest Message (0x0c)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 proposed_quantity = 2`
The proposed quantity

`string pair_id = 3`
The trading pair for the swap

`string order_id = 4`
The unique identifier of the maker order

`string r_hash = 5`
The taker preimage hash (in hex)

`uint32 taker_cltv_delta = 6`
The CLTV delta from the current height that should be used to set the timelock for the final hop when sending to the taker
```

The `SwapRequest` message is sent by the taker to the maker to start the swap negotiation.

### SwapAccepted Message (0x0d)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 req_id = 2`
The id from the received SwapRequest message

`string r_hash = 3`
The taker’s preimage hash (in hex) from the received SwapRequest message

`string quantity = 4`
The accepted quantity (which may be less than the proposed quantity)

`uint32 maker_cltv_delta = 5`
The CLTV delta from the current height that should be used to set the timelock for the final hop when sending to the maker
```

The `SwapAccepted` message is sent by the maker to the taker to accept the swap request.

### SwapFailed Message (0x0f)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 req_id = 2`
An optional id from the received SwapRequest message. Otherwise, this field is empty

`string r_hash = 3`
The taker’s preimage hash (in hex)

`string error_message = 4`
Additional information regarding the failure reason

`uint32 failure_reason = 5`
The failure reason
```

The `SwapFailed` message can be sent by either side of the swap protocol, at any time, to announce the swap termination.

`failure_reason` is an optional parameter for specifying the failure reason:

| Failure Reason | Meaning                       | Description                                                                                              |
| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------- |
| `0x00`         | Order Not Found               | Could not find the order specified by a swap request                                                     |
| `0x01`         | Order On Hold                 | The order specified by a swap request is on hold for a different ongoing swap                            |
| `0x02`         | Invalid Swap Request          | The swap request contained invalid data                                                                  |
| `0x03`         | Swap Client Not Setup         | We are not connected to both swap clients, or we are missing public key identifiers for the peer's nodes |
| `0x04`         | No Route Found                | Could not find a route to complete the swap                                                              |
| `0x05`         | Unexpected Client Error       | A swap client call failed for an unexpected reason                                                       |
| `0x06`         | Invalid Swap Message Received | Received a swap message with invalid data                                                                |
| `0x07`         | Send Payment Failure          | The call to send payment failed                                                                          |
| `0x08`         | Invalid Resolve Request       | The swap resolver request was invalid                                                                    |
| `0x09`         | Payment Hash Reuse            | The swap request attempts to reuse a payment hash                                                        |
| `0x0a`         | Swap Timed Out                | The swap timed out while we were waiting for it to complete execution                                    |
| `0x0b`         | Deal Timed Out                | The deal timed out while we were waiting for the peer to respond to our swap request                     |
| `0x0c`         | Unknown Error                 | The swap failed due to an unrecognized error                                                             |


# 👋-Hello!

## ⚠️ NOT ACTIVELY MAINTAINED ⚠️

![](/files/X8Q64buSCLJKcuYorZ21)

**OpenDEX is a cross-chain DEX network, featuring a user-friendly web app for spontaneous asset swaps and a layer 3 high-speed trading network for liquidity providers & day traders built on the** [**Lightning**](https://lightning.network/) **and** [**Connext**](https://connext.network/) **networks.** OpenDEX consists of software, community, member projects, and the BOLD protocol standard with the goal to unify currently incompatible protocols and fragmented liquidity.

## Get Started

[🔁 **Swap privately & securely** via the easy-to-use web app 🖥️](https://opendex.app)

[🌊 **Provide liquidity & earn** by running a node 👨‍💻](/docs/liquidity-providers)

## OpenDEX Features

* No central authority. No middleman.
* No account. No KYC. No personal data.
* No protocol token.
* [Tor](https://www.torproject.org/) by default preserves privacy.
* [BOLD](/bold/00-introduction) as open protocol. Support for multiple implementations.
* Direct, peer-to-peer trading.
* Complete control of funds at all times.
* Order book locally aggregates orders from peers in the network.
* Orders are matched locally with peer orders.
* Instant order settlement via atomic swaps on the [Lightning](https://lightning.network/) and [Connext](https://connext.network/) networks.

## Support & Community

**OpenDEX operates non-profit and is not a company**, nor any other sort of legal entity. It is an open community of individuals & member projects, working together to maintain the OpenDEX software and BOLD protocol specifications. OpenDEX was started to create a unified & long-term viable alternative to trading on trusted and KYCed centralized exchanges. Find the slides of the first public announcement at #hcpp19 in Prague [here](https://github.com/opendexnetwork/opendex/raw/master/slides/20191005_hcpp19.pdf) and the video recording [here](https://www.youtube.com/watch?v=euSr9A6tI90).

* Join our [weekly community call or watch the recordings](/community/videos).
* Get support on our [Discord](https://discord.gg/aS5RMchDrU) and join our [Telegram](https://t.me/opendexnetwork) community.
* Contribute on [GitHub](https://github.com/opendexnetwork).


# 🎥-Weekly Call & Videos

This section contains video recordings of OpenDEX community calls, explainers, guides & more!

## Community Calls

* Jitsi link to join the call: <https://meet.jit.si/opendex-community>
* Time and day of the call: 18:00 UTC, every Wednesday
* Discussions are recorded and uploaded here

### Community Call #21 (2021-06-02) 👉 [Video](https://youtu.be/zKR8LECPM5k) 👈

One more rather casual call where we discussed [Bitcoin metrics cooling off](https://mailchi.mp/bytetree/the-bitcoin-network-slumps), Marathon (a North American Bitcoin Mining corp) first [starting to censor Bitcoin transactions](https://www.coindesk.com/marathon-miners-censor-bitcoin-transactions-ofac-compliant) to be "compliant with U.S. regulatory standards", then [coming around announcing not to do it anymore just a couple of weeks later](https://marathondh.com/ceo-fred-thiel-comments-on-migration-to-standard-bitcoin-core-0-211-node-and-support-for-taproot/), Jack Maller's [Bitcoin car](https://bitcoinmagazine.com/culture/bitcoin-car-will-be-in-indianapolis-500), a lenghty discussion about [Ethereum's price outperforming Bitcoin](https://finance.yahoo.com/news/jp-morgan-explains-why-ethereum-134546824.html), store of Value vs. moving fast/innovation, [Taproot looking very much to activate this signalling period](https://taproot.watch/), [continued funding for utreexo](https://dci.mit.edu/utreexo) and more ethereum vs. bitcoin ;) Looking forward to finally have something to demo in two weeks 🔥

### Community Call #20 (2021-05-19) 👉 [Video](https://youtu.be/B_alfOZysQ8) 👈

In this casual edition of our call [we looked at Bitcoin's energy consumption and Tesla's REC business](https://twitter.com/Elisabeth_Steyn/status/]1392799067986554880?s=09), Tesla's 2021 Q1 report [showing main profit generated by REC's and the one-time Bitcoin sale](https://tesla-cdn.thron.com/static/R3GJMT_TSLA_Q1_2021_Update_5KJWZA.pdf?xseo=\&response-content-disposition=inline%3Bfilename%3D%22TSLA-Q1-2021-Update.pdf%22), [China banning Bitcoin (for the 17th time)](https://cointelegraph.com/news/chinese-trade-associations-sound-crypto-investment-warning), it's been an incredible week and there was probably never such a [coordinated attack against a single asset](https://www.zerohedge.com/crypto/human-history-no-single-asset-has-come-under-such-coordinated-assault-global-institutions) with even [the pope feeling qualified to have an opinion on Bitcoin's "fossil fuel" energy consumption](https://twitter.com/Pontifex/status/1394993742226939905), Taproot close to activation (check [taproot.watch](https://taproot.watch)), a minor [Bitcoin Core CVE](https://github.com/btcsuite/btcd/pull/1719), the upcoming [LND 0.13 release](https://github.com/lightningnetwork/lnd/releases/tag/v0.13.0-beta.rc2), discussed [PoW vs. PoS](https://platform.spacemesh.io/docs/protocol/mining/overview/) and RGB's [mycitadel wallet](https://github.com/mycitadel).

### Community Call #19 (2021-03-24) 👉 [Video](https://youtu.be/EGmR676jMt8) 👈

In this call [we laughed](https://pbs.twimg.com/media/ExO8ELWXEAUoa81?format=jpg\&name=small) once more at the [ECB's claim not to be responsible for increasing econimic inequality](https://twitter.com/ecb/status/1374647699480453121) (read about the Cantillon effect [here](https://www.austriancenter.com/cantillon-effect-populism/)), [Tesla now **accepting** Bitcoin](https://twitter.com/elonmusk/status/1374617643446063105) and that by running their own merchant software and Bitcoin nodes, [Breez launching a built-in podcast platform](https://medium.com/breez-technology/podcasts-on-breez-streaming-sats-for-streaming-ideas-d9361ae8a627), how [Taproot may handle Quantum Computers](https://bitcoinops.org/en/newsletters/2021/03/24/) and our main topic: [UniSwap V3](https://uniswap.org/blog/uniswap-v3/).

Tl;dr: UniSwap V3 is great and fixes a couple of inefficiencies of V2, but OpenDEX still keeps most of its advantages over UniSwap with the major one being: it's truly cross-chain. Native BTC, native ETH, no wrapping.

### Community Call #18 (2021-03-17) 👉 [Video](https://youtu.be/oB3BeDNtN7g) 👈

In this exciting community call we covered the [troll title changes at Tesla (Master of Coin!) 😹](https://www.sec.gov/Archives/edgar/data/0001318605/000156459021012981/tsla-8k_20210315.htm), the new taproot activation alternative [speedy trial](https://bitcoinmagazine.com/technical/discussing-taproot-activation-through-speedy-trial) that could bring us taproot in 2021 🤯, the VERY different and entirely [developer driven upgrade approach on ethereum](https://www.coindesk.com/ethereum-proof-of-stake-sooner-than-you-think), that in some (admittedly rare) circumstances [lightning funding transactions are still prone to transaction malleability and thus loss of funds](https://bitcoinops.org/en/newsletters/2021/03/17/) and spend the rest of the call wrapping our head around RGB 🌈, shout-out to Maxim from the RGB Team patiently explaining and answering questions and stay tuned about how we will work together to make a lightning-based DEX Standard a reality!

Check out these links to learn more about RGB or even get your hands dirty and try it out:

* Project Page: <https://rgb-org.github.io>
* FAQs: <https://www.rgbfaq.com>
* Telegram: <https://t.me/rgbtelegram>
* GitHub: <https://github.com/LNP-BP>
* Docker Containers (CLI ftw!): <https://github.com/LNP-BP/docker>
* MyCitadel RGB-enabled iOS Wallet: <https://www.mycitadel.io>

### Community Call #17 (2021-03-03) 👉 [NO Video, sorry!](/community/videos) 👈

In this community call we covered [the continued institutional flow into Bitcoin](https://mailchi.mp/bytetree/bitcoin-institutional-flows-are-a-game-changer), [the new major geth 1.10 release](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.0) which dramatically speeds up accessing ethereum state (out of experience we can't recommend to upgrade just yet though), [another improvement proposal for a BIP70 successor](https://bitcoinops.org/en/newsletters/2021/03/03/), [I2P (an alternative to Tor) support in Bitcoin Core](https://github.com/bitcoin/bitcoin/pull/20685) ([here](https://geti2p.net/en/comparison/tor) you can learn more about the differences between I2P and Tor), the [RGB MyCitadel iOS App 🌈](https://github.com/mycitadel/mycitadel-node) (get a basic overview of RGB [here](https://www.rgbfaq.com/faq), but as promised we'll cover RGB in greater detail in next week's call and finally saw the [new update feature of the OpenDEX Desktop App](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.10) and went through how arbitrage incentivizes liquidity providers to offer liquidity on the OpenDEX network, how it works in practice and why leveraging arbitrage with CEXes to incentivize liquidity provision on OpenDEX is only really possible because of instant finality of trades. Apologies for the missing recording, we'll have a backup recording next week ✌️

### Community Call #16 (2021-02-24) 👉 [Video](https://youtu.be/zpwiZlbRRbs) 👈

In this community call we covered the last piece of the puzzle missing for taproot activation on bitcoin: [LOT=true vs. LOT=false](https://bitcoinmagazine.com/articles/lottrue-or-lotfalse-this-is-the-last-hurdle-before-taproot-activation), [the new lnd 0.12.1 release](https://github.com/lightningnetwork/lnd/releases/tag/v0.12.1-beta) which fixes a nasty crash, a demo of the new setup flow in our latest [OpenDEX Desktop App Testnet release](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.7) and saw a pretty cool demo of an upcoming feature for Boltz, which not only makes it compatibly with virtually all mobile ethereum wallets, but also doesn't require you to hold ETH to do swaps with an ERC20 asset like USDT! You can already try it out at [testnet.boltz.exchange](https://testnet.boltz.exchange/) - dope! 🌿

### Community Call #15 (2021-02-17) 👉 [NO Video, sorry!](/community/videos) 👈

In this community call we covered another exciting week of happenings: [Microstrategy raising even moar money to buy Bitcoin](https://www.microstrategy.com/en/investor-relations/press/microstrategy-announces-proposed-private-offering-of-600m-of-convertible-senior-notes), [a new proposal how to offer escrow services on lightning and hold fees](https://bitcoinops.org/en/newsletters/2021/02/17/) based on a post-taproot feature called [PTLCs](https://bitcoinops.org/en/topics/ptlc/) (a more private & efficient replacment for HTLCs), our [👉 website re-write 👈 (check it out!)](https://opendex.network/), [all-new OpenDEX Destkop Release for Windows 🎉](https://github.com/opendexnetwork/opendex-desktop/releases/tag/v1.0.0-testnet.1), also some of you asked me to link this pretty stats page [coin.dance](https://coin.dance/). Apologies for the missing recording, our bad ✌️

### Community Call #14 (2021-02-10) 👉 [Video](https://youtu.be/A9bQPYvWb1o) 👈

In this community call we covered another exciting week of happenings: [Tesla's $1.5 Billion investment in Bitcoin](https://www.sec.gov/ix?doc=/Archives/edgar/data/1318605/000156459021004599/tsla-10k_20201231.htm), [Bytetree's BOLD investment strategy](https://mailchi.mp/bytetree/bitcoin-gold-bold), [Taproot activation settled on BIP8](https://bitcoinops.org/en/newsletters/2021/02/10/), [geth's upcoming breaking change on the rpc layer](https://twitter.com/peter_szilagyi/status/1359503621826764805), [shady shady 1inch.exchange](https://twitter.com/brockjelmore/status/1354488170000355328), [xmr.to closure](https://xmr.to/blog/job-done) and [dexfairy.com](https://dexfairy.com/).

### Community Call #13 (2021-02-03) 👉 [Video](https://youtu.be/Xha5l6t19Nk) 👈

In this community call we announced our move from "Exchange Union" to ["OpenDEX"](https://opendex.network), which unifies everything under one name and should avoid confusion down the road. This also comes with a change in product focus, how we are funded, team members and more. The gist is: we are shifting focus towards UX & end-user facing trading products while keeping our core atomic-swap-DNA (the user is always in control of funds) & OpenDEX will become even more open going forward. If you are interested in day-to-day updates and what we are working on, please join our [Discord server](https://discord.gg/aS5RMchDrU) and *watch* our [GitHub repositories](https://github.com/opendexnetwork). We also touched on [Microstrategy sharing the "Bitcoin for Corporations"](https://www.microstrategy.com/en/resources/events/world-2021/bitcoin-summit) playbook, [Elon on Clubhouse](https://twitter.com/MMCrypto/status/1356131319424704513?s=09) & Bisq's new ["Cash by Mail"](https://bisq.wiki/Cash_by_mail) feature.

### Community Call #12 (2021-01-27) 👉 [Video](https://youtu.be/tL5FRf-QvH8) 👈

In this community call, we talked extensively about `r/wallstreetbets` amazing coup against wallstreet causing hedge funds getting liquidated for their overleveraged short positions on [GameStop's stock](https://finance.yahoo.com/quote/GME), that the response of "trading restrictions" of AmeriTrade & others has to lead to decentralized trading networks like OpenDEX to take off, Bitcoin as treasury for non-profits and the new releases of lnd & connext. Finally, we saw a demo of a feature-complete Trading view in XUD UI.

### Community Call #11 (2021-01-13) 👉 [Video](https://youtu.be/CpeFQqFKksg) 👈

In this community call, we laughed hard at ECB's Christina Lagarde's call for a global Bitcoin regulation because of the ["funny business" conducted](https://www.reuters.com/article/us-crypto-currency-ecb/ecbs-lagarde-calls-for-regulating-bitcoins-funny-business-idUSKBN29I1B1), how we can learn from [Wasabi's fallback mechanisms preventing being impacted by the recent attack on Tor Consensus](https://blog.wasabiwallet.io/wasabi-wallet-tor-consensus/) and touched on an open PR [removing all remaining JSON encoding from the OpenDEX protocol](https://github.com/ExchangeUnion/xud/pull/2061#pullrequestreview-567439995) moving everything cleanly to protobuf. Last but not least we saw a pretty neat sneak peak of the upcoming trading feature in XUD UI.

### Community Call #10 (2020-12-23) 👉 [Video](https://youtu.be/CFwnbgoMMBM) 👈

In this Christmas Edition of our community call, we clarified that the recent [customer data dump](https://www.ledger.com/message-ledgers-ceo-data-leak) probably should be the end of Ledger, the recent [SEC charge](https://www.sec.gov/news/press-release/2020-338) probably the end of Ripple and, more importantly, saw an end-to-end demo of a deposit with XUD UI & went through a pretty interesting OpenDEX Q\&A session, touching on the different stakeholders involved, why no token and more.

### Community Call #9 (2020-12-16) 👉 [Video](https://youtu.be/QTx7U6fPe_k) 👈

In this community call, we talked about the last edition of the amazing [Bitcoin Optech Newsletter](https://bitcoinops.org/en/newsletters/2020/12/16/), about the upcoming [0.12.0 LND release](https://github.com/lightningnetwork/lnd/releases/tag/v0.12.0-beta.rc1) and development updates from Boltz & Exchange Union with special focus on the new [1.2.0 XUD UI release](https://github.com/ExchangeUnion/xud-ui/releases/tag/v1.2.0) 🌈

### Community Call #8 (2020-12-09) 👉 [Video](https://youtu.be/oBoDNGI8f3w) 👈

In this community call, we touched on the events of the week and then went on discussing the upcoming release of the next connext protocol version called "vector" (<https://github.com/connext/vector>), which Exchange Union expects to move to as soon as it's available (2020ish). We also have seen a demo of the upcoming 1.2.0 XUD UI release (and heard a range of excuses why it's taking so long, but also some decent commitment to deliver until next week).

### Community Call #7 (2020-12-02) 👉 [Video](https://youtu.be/_KbbTmMA8WM) & [Slides](https://github.com/BoltzExchange/slides/blob/master/boltzopendex.pdf) 👈

In this community call, we touched on the recent happenings eth2 launch and [Breez'es great overview of lightning use cases](https://medium.com/breez-technology/waypoints-on-the-road-to-lightnings-mass-adoption-88e4148a2c3c) and learned in-depth about the recently launched BTC/USDT swaps on [boltz.exchange](https://boltz.exchange) 🔥

### Community Call #6 (2020-11-25) 👉 [Video](https://youtu.be/xi0sXZgG9NE) & [Slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20201125_OpenDEX_Community_Call.pdf) 👈

In in this special edition of our community call, we dived into "Running a bitcoin node" and looked at three projects helping to make this quest easier with a Raspberry Pi: [RaspiBlitz](https://raspiblitz.org/), [MyNode](https://mynodebtc.com/) & [Umbrel](https://getumbrel.com/). We had a closer look at Umbrel and discussed how it achieves great UX. We learned that Exchange Union is working on an integration with RaspiBlitz already and that we can expect to access OpenDEX seamlessly via above projects in the future.

### Community Call #5 (2020-11-18) 👉 [Video](https://youtu.be/tt_TYVft4dQ) 👈

In this community call we discussed [lnmarkets](https://lnmarkets.com), the proactive [miner initiative for activation of taproot on bitcoin](https://taprootactivation.com) and saw and saw a first demo of multi-channel trades via xud.

### Community Call #4 (2020-11-11) 👉 [Video](https://youtu.be/iNw5d1rZUqY) 👈

In this community call we discussed Lightning Pool, the Infura downtime and Ethereum chain split and saw a pretty cool demo of the upcoming ⚡-BTC/USDT swaps on [boltz.exchange](https://boltz.exchange) 🔥

### Community Call #3 (2020-11-04) 👉 [Video](https://youtu.be/IBrVkzyCwb4) 👈

In this community call we discussed using multiple channels to settle one trade (will be demoed next week) and and saw an alpha demo of the upcoming 1.1.0 release of XUD Explorer featuring full setup on Windows. This version takes Windows users from 0 to "deposit funds" in a couple of Minutes, seamlessly installing docker as part of the installation flow.

### Community Call #2 (2020-10-28) 👉 [Video](https://youtu.be/rC7zlCSuVEc) 👈

In our second community call we saw a demo of the first iteration of XUD Explorer, a Desktop App UI for OpenDEX and discussion of various topics, such as hot wallets - the risk exposure one faces when using payment channel networks like the Lightning Network.

### Community Call #1 (2020-10-21) 👉 [Video](https://youtu.be/mGumdYAjDkY) & [Slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20201021_OpenDEX_Community_Call.pdf) 👈

In our first community call we covered the **Why?, How?, What?** along with some live mainnet trading and a Q\&A session.

## Misc

### First public announcement (2019-10-05) 👉 [Video](https://www.youtube.com/watch?v=euSr9A6tI90) & [slides](https://raw.githubusercontent.com/opendexnetwork/opendex/master/slides/20191005_hcpp19.pdf) 👈

The first public announcement of OpenDEX at [#hcpp19](https://opt-out.hcpp.cz/) in Prague.


# 📝-Intro

The OpenDEX Daemon ([`opendexd`](https://github.com/opendexnetwork/opendexd)) is "the node" and core of the OpenDEX network. The graphic below shows the different participants in OpenDEX and how they are connected.

![](/files/nU0E66uArvowDvoZ2TLa)

### How to Run a Node

👉 as [**Liquidity Provider**](/docs/liquidity-providers), earning via automated arbitrage between external exchanges and OpenDEX

👉 as [**Swap Provider**](/docs/swap-providers), sourcing liquidity on OpenDEX **(WIP)**

👉 as [**Day Trader**](/docs/day-traders), trading instantaneously while preserving full control & privacy

👉 as [**Developer**](/docs/developers), contributing or building on top of `opendexd`

### Special Docs

* [Dockerless Guide](/docs/dockerless)
* [Close Shop Guide](/docs/close-shop)
* [CLI Documentation](/docs/cli)
* [Config Documentation](/docs/config)

### Support & Community

* [Contribute](/docs/contribute)!
* Support and development-related questions are welcome on our [Discord](https://discord.gg/aS5RMchDrU)!

### Help us to improve!

Please help us to improve by opening issues (or even better PRs) for [opendexd](https://github.com/opendexnetwork/opendexd), [opendex-docker](https://github.com/opendexnetwork/opendex-docker), [opendex-ui](https://github.com/opendexnetwork/opendex-ui) & [opendex-desktop](https://github.com/opendexnetwork/opendex-desktop).


# 🌊-Liquidity Providers

This guide is written for anyone looking to run a opendex liquidity provider setup entirely via the command line and create a revenue stream via automated arbitrage.

## Prerequisites

### Two Modes

1. **Default: Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider. This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Optional: Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more time and resources, but keeps the setup trustless.

### Three Networks

1. **Simnet**. `Status: down` until further notice
2. **Testnet**. `Status: up | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 200GB for full | Initial Sync Time: 15 mins for light, 24h for full`

   bitcoin testnet 3, litecoin testnet 4, ethereum rinkeby. Faucets: [t-BTC](https://coinfaucet.eu/en/btc-testnet/), [t-LTC](https://testnet.help/en/ltcfaucet/testnet), [t-ETH 1](https://faucet.rinkeby.io/) or [2](https://testnet.help/en/ethfaucet/rinkeby). If you need help or some testnet coins, hit us up on [Discord](https://discord.gg/aS5RMchDrU)!
3. **Mainnet**. `Status: down | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 1TB for full | Initial Sync Time: 30 mins for light, 72h for full`

   Down until all breaking changes are merged and some weeks on testnet didn't reveal major issues.

### Hardware

Since liquidity providers should be online 24/7 and we are ushering in a post-cloud era, we recommend setting up a power-efficient linux box connected to your router. No special configurations, like port forwardings, are necessary. Running your opendexd setup in the cloud is obviously possible, just not something we encourage to do.

[**🧑‍🏭 Standard Hardware Guide**](/docs/liquidity-providers/standard-hardware): This guide walks you through setting up an arm64-based Raspberry Pi3/4. Costs: **65€-290€**

[**💪 Pro Hardware Guide**](/docs/liquidity-providers/pro-hardware): This guide walks you through setting up a powerful amd64-based Mini PC. Costs: **180€-465€**

🎚️ **Custom**: If you are using a different device or a cloud VPS:

* Check the hardware requirements for the different networks and modes above
* The full setup requires a SSD for geth being able to sync. For the light setup, a regular HDD/SD card is fine.
* If you are using a VPS for testnet or mainnet, you can switch to 2 cores & 4 GB RAM after initial sync, given you use default settings.
* We currently support `amd64` (also called `x86`/`x64`) and `arm64` (also called `aarch64`/`armv8`), which should cover most devices and services.

### Software

Docker & Docker Compose.

Version >= 18.09 on Linux or Windows 10 [using WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). If you do not have docker & docker-compose installed yet and you are using Ubuntu 20.04 LTS, install these via `sudo apt install docker.io`. If you are using any version besides Ubuntu 20.04, follow the official [docker install instructions](https://docs.docker.com/get-docker/). Also make sure that the current user can run docker commands. Test with `docker run hello-world`. If this fails, [follow these instructions](https://docs.docker.com/engine/install/linux-postinstall/). This guide was written using Ubuntu 20.04 LTS.

## The Setup

From here we assume that your device is running with docker set up. Check the guides in the hardware section above if your device is not ready yet.

### Let's Roll (!WIP - NOT FULLY WORKING YET!)

Start the environment with

```bash
curl https://raw.githubusercontent.com/opendexnetwork/opendex-docker/master/opendexd.sh -o ~/opendexd.sh
bash ~/opendexd.sh
```

The setup will ask you to choose the network:

```
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
🚀 Launching mainnet environment
🌍 Checking for updates ...
```

Sync light clients (default):

```
Syncing light clients:
┌─────────┬─────────────────────────────────────────────────────┐
│ SERVICE │ STATUS                                              │
├─────────┼─────────────────────────────────────────────────────┤
│ lndbtc  │ Syncing 34.24% (610000/1781443)                     │
├─────────┼─────────────────────────────────────────────────────┤
│ lndltc  │ Syncing 12.17% (191000/1568645)                     │
└─────────┴─────────────────────────────────────────────────────┘
```

And then guide you through some basics:

```
Do you want to create a new opendexd environment or restore an existing one?
1) Create New
2) Restore Existing
Please choose: 1
```

When creating a new opendexd SEED, the setup asks you to set a password to encrypt your environment's private keys and to write down your mnemonic phrase. This serves as backup for your opendexd node key and wallets (your on-chain assets). This is your last resort in case something happens to your device. **Keep it somewhere safe!**

```
You are creating an opendexd node key and underlying wallets. All will be secured by a single password provided below.
  
Enter a password: 
Re-enter password: 

----------------------BEGIN OPENDEX SEED---------------------
 1. you         2. won't       3. find        4. money      
 5. in          6. this        7. seed        8. but    
 9. good       10. thinking   11. if         12. you      
13. are        14. interested 15. in         16. getting     
17. rewarded   18. for        19. testing    20. opendex  
21. security   22. hit        23. us         24. up   
-----------------------END OPENDEX SEED----------------------

The following wallets were initialized: BTC, LTC, ERC20(ETH)
```

Then you'll be asked to enter the path to your backup drive, e.g. a previously mounted USB drive:

```
Please enter a path to a destination where to store a backup of your environment. It includes everything, but NOT your on-chain wallet balance which is secured by your opendexd SEED. The path should be an external drive, like a USB or network drive, which is permanently available on your device since backups are written constantly.

Enter path to backup location: /media/USB/
Checking... OK.
```

The entered backup drive location is persisted as `backup-dir = "/media/USB/"` in `mainnet.conf` and can be changed any time. Alternatively, you can consider running your environment on two hard drives in [RAID 1](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1) to protect against data loss.

Then the setup might restart clients and ask you to enter your password once more before the CTL

Use the `status` command to check on the your setup's health and sync progress. The default light setup should show `Ready` after some seconds:

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for lndbtc, lndltc                     │
└───────────┴────────────────────────────────────────────────┘
```

If you configured the full setup via config file or cli parameters, the sync will start fast and get slower towards the end. You might see 0.00% progress for several minutes at first.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 0.00% (0/436000)                       │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 0.00% (0/324000)                       │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 0.00% (55/9140561)                     │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

After a while you should see all three full-nodes syncing nicely.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 43.06% (262348/609123)                 │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 35.94% (631593/1757002)                │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 10.16% (929072/9140623)                │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

Bitcoind/Litecoind should finish syncing within 12h, geth in about 72h on powerful hardware. A Pi4 needs about twice that long.

The CLI takes `opendex-cli` commands without the need to prepend `opendex-cli`, e.g. simply type `getinfo` to get basic information about your opendex node. Run `help` to get an always up-to-date list of commands. Append `-j` to any command to get JSON instead of the formatted output, e.g. using `listpeers` to see other opendexd nodes on the network:

```
mainnet > listpeers -j
{
  "peersList": [
    {
      "address": "rgz5icb5jdxzmu7r7tbis64q23ioytzd4tqikuyb5kz75w75rbe6veyd.onion:8885",
      "nodePubKey": "02529a91d073dda641565ef7affccf035905f3d8c88191bdea83a35f37ccce5d64",
      "lndPubKeysMap": [
        [
          "BTC",
          "035cb9afb06a83e65fbab15c900d78580673cf56ce38c5814fb71f1eb57fcba7ee"
        ],
        [
          "LTC",
          "036cf16cd7de6193efb2855e784409c3633f893662dd6edcf7a545a99659232373"
        ]
      ],
      "inbound": false,
      "pairsList": [
        "LTC/BTC",
        "ETH/BTC",
      ],
      "opendexdVersion": "1.2.7",
      "secondsConnected": 100,
      "connextAddress": "0xe802431257a1d9366BD5747F0F52bAd25A6C3092"
    }
  ]
}
```

### Your First Trade

Start by depositing some funds into your opendex node:

```bash
deposit btc #Send BTC to this address
deposit ltc #Send LTC to this address
deposit eth #Send ETH to this address
```

The deposit command for BTC & LTC is powered by [Boltz](https://boltz.exchange). Boltz will automatically open a balanced lightning channel to you, if you don't have a channel yet. This can take several minutes to complete and we'd kindly ask you to wait patiently for your funds to appear in the `getbalance` overview. If you want to follow what is happening under the hood, you can do so by typing `logs boltz`. For ETH, currently one still needs to trigger a manual channel creation in a second step after funds were deposited:

```
openchannel ETH 13.37
```

Check existing orders for all activated pairs with the command `orderbook`. It might take several seconds to see orders after opendexd was started due to the decentralized nature of the order exchange. Use `orderbook btc/usdt` to show the order book for BTC/USDT only:

```
mainnet > orderbook btc/usdt

Trading pair: BTC/USDT
┌───────────────────────────────────────┬───────────────────────────────────────┐
│ Buy                                   │ Sell                                  │
├───────────────────┬───────────────────┼───────────────────┬───────────────────┤
│ Quantity          │ Price             │ Price             │ Quantity          │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.28918298        │ 7171.56           │ 7172.253          │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 1                 │ 7171.1937         │ 7172.9757         │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7171.083          │ 7316.0663         │ 1                 │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7170.899          │ 7316.44           │ 0.22393946        │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
```

Use `getbalance` to check your balance *before* the swap.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.10944853    │ 2.5                        │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5000          │ 5000                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

Issue a regular limit order with e.g. `sell 0.1 btc/usdt 7171` to sell 0.1 btc for a price of 7171 USDT per BTC. If your order was matched, settlement shouldn't take longer than a couple of seconds.

```
mainnet > sell 0.1 btc/usdt 7171
swapped 0.1 BTC with peer order ca24fe00-1c1e-11ea-8b1b-3b2ec0335696
```

Use `getbalance` to check your balance *after* the swap. You are now owning 0.1 BTC less and 717 USDT more.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.00944842    │ 2.39999989                 │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5717          │ 5717                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

### Connect Arby

In this final step we are connecting your opendex setup to your CEX (Centralized EXchage) account via a liquidity provider bot called ["arby"](https://github.com/opendexnetwork/market-maker-bot). Arby enables "transfer" of orders from the CEX into OpenDEX and creates an arbitrage revenue stream for you as liquidity provider. Arby issues orders on the OpenDEX network based on the CEX price, adding a `margin` as premium. When orders are filled on OpenDEX, arby takes care of executing a counter trade on the CEX to lock in profits. At the time of writing, arby supports connecting to [Binance](https://www.binance.com) and [Kraken](https://www.kraken.com/), but more exchanges will be added over time; check arby's [FAQ](https://github.com/opendexnetwork/market-maker-bot#faq) for an up-to-date list. We'll use Binance as example in the following. You will need funds for at least one supported asset on Binance (e.g. BTC) for arby to start issuing orders. To activate arby, `exit` from `opendexd ctl` and run `cp ~/.opendexd-docker/mainnet/sample-mainnet.conf ~/.opendexd-docker/mainnet/mainnet.conf` to create a config file for your environment. Then edit the following options in `mainnet.conf`:

```bash
opendexd@ubuntu:~$ nano ~/.opendex-docker/mainnet/mainnet.conf
# this option needs to be set to false to allow arby to execute Binance orders on your behalf, crucially needed for arby to function
test-mode="false"
# the trading pair to activate arby for; currently arby can only handle one pair at a time
base-asset = "BTC"
quote-asset = "USDT"
#cex-base-asset = "" # optional - only needs to be specified if centralized exchange base asset is different from base-asset, e.g. USD instead of USDT
#cex-quote-asset = "" # optional - only needs to be specified if centralized exchange quote asset is different from quote-asset, e.g. USD instead of USDT
# log into your Binance account to obtain your api key and secret
cex = "binance"
cex-api-key = "your api key"
cex-api-secret = "your api secret"
# this is the percentage you'd like to add on top of your orders, 3% in this example
margin = "0.03"
# enable arby
disabled = false
# CTRL+S, CTRL+X.
```

Re-enter opendex-ctl (`bash ~/opendexd.sh`) and accept the prompt to add arby. After a minute you should see arby's automatically issued orders based on your Binance and OpenDEX balance via `listorders`. Completed OpenDEX trades are listed in `tradehistory`. You can follow actions taken by arby with `logs arby`.

Check the official [README](https://github.com/opendexnetwork/market-maker-bot/blob/main/README.md) to learn more about how arby works.

## Report Issues

Please give us feedback and report bugs by running `report` from within `opendex ctl` or join our dedicated "-help" channel on [Discord](https://discord.gg/aS5RMchDrU)!

## Tips 'n Tricks

* No need to open/forward ports
* An overview of all available commands within `opendex ctl` can be printed by typing `help` in `opendex ctl`. It allows to use client's cli (e.g. `lncli`), check client status, logs and many more.
* The opendex-docker setup uses the fixed home directory `~/.opendex-docker` where blockchain & wallet data is stored in by default. Customize the wallet & chain data directory by creating a global opendex-docker config file with `cp ~/.opendex-docker/sample-opendex-docker.conf ~/.opendex-docker/opendex-docker.conf`, then edit `dir`.
* All config options can temporary be set via cli parameters; run `bash opendex.sh --help` to get an overview of all available parameters. To e.g. use another directory for your mainnet environment, you can run `bash opendex.sh --mainnet-dir /path/to/temp/mainnet/dir`.
* To permanently change options on a network level, create a network-specific config file with the latest options, e.g. for mainnet with `cp ~/.opendex-docker/mainnet/sample-mainnet.conf ~/.opendex-docker/mainnet/mainnet.conf`, then edit `mainnet.conf`.
* If you only have a small SSD available (<300GB) for a full setup, you can place your entire setup on a HDD, except for a small part of geth's data, which needs to be located on a fast SSD:

```bash
[geth]
# SSD (internal)
dir = "/home/<user>/.opendex-docker/mainnet/geth"
# HDD (external)
ancient-chaindata-dir = "/media/HDD/opendex/03-Mainnet/data/geth"
```

* Sample config full setup:

```bash
# edit these lines to sync full nodes for bitcoin, litecoin & ethereum
[bitcoind]
mode = "native"
[litecoind]
mode = "native"
[geth]
mode = "native"
```

* You may use external full-nodes (including infura).

```bash
# connect to an external bitcoin core node in your local network (Use `10.0.2.1` on linux or `host.docker.internal` on mac if the full node is running on the same machine)
[bitcoind]
mode = "external"
rpc-host = "192.168.1.42"
rpc-port = "8332"
rpc-user = "opendex"
rpc-password = "opendex"
zmqpubrawblock = "192.168.1.42:28332"
zmqpubrawtx = "192.168.1.42:28333"
```

* Sample config of your external bitcoind/litecoind to work with the defaults in the `<network>.conf` file:

```bash
-rpcuser=opendex
-rpcpassword=opendex
-rpcport=18332
-rpcallowip=0.0.0.0/0
-rpcbind=0.0.0.0
-zmqpubrawblock=tcp://0.0.0.0:38332
-zmqpubrawtx=tcp://0.0.0.0:38333
```

* Permanently set the alias `opendex` to launch `opendex ctl` from anywhere: Add the line `alias opendex="bash ~/opendex.sh"` to the end of `~/.bashrc` or `~/.bash_aliases` on Linux and `bash_profile` on Mac, then `source` the file.
* You can `exit` from `opendex ctl` any time and re-enter with `bash ~/opendex.sh`; the environment will stay up.
* A reboot of your host machine does **not** restart your `opendex-docker` environment by default. You will need to run `bash ~/opendex.sh` and `unlock` your environment with your password.
* Permanently stop the environment by typing `down` in `opendex ctl`. A restart can be achieved with `down` first and then running `bash ~/opendex.sh` again.
* `opendex-docker` only uses offical opendexd releases for mainnet. Testnet is running the latest `opendexd` master and is updated frequently.
* If you are syncing the full setup, and `geth` shows sync status **99.99%** for longer than 72h, you are probably running geth on a drive that is too slow for geth to catch up with the chain. In this case, `down` the environment and run a performance test of the disk as desribed [here](/docs/liquidity-providers/standard-hardware#pi-full-setup). If results are below the 100 MB/s mark, you can either switch to a faster SSD, use the default light setup connecting to an open geth node or use infura.
* Docker *might* not play nicely with a VPN you are running on the host machine. If you see `Failed to launch environment`, try disconnecting the VPN.
* If you decide to remove `opendex-docker` from your machine, run the following commands when the environment is `down`:

```bash
# Use with caution: this step removes all `opendex` blockchain and wallet data from your system. If you have channels open without backup or lost your seed mnemonic, you are at risk of loosing funds.
sudo rm -rf ~/.opendex-docker
rm -rf ~/opendex.sh
rm -rf /custom/mainnet/dir
```

### References

* [bitcoind config options](https://github.com/bitcoin/bitcoin/blob/master/share/examples/bitcoin.conf)
* [litecoind config options](https://litecoin.info/index.php/Litecoin.conf#litecoin.conf_Configuration_File)
* [geth config options](https://github.com/ethereum/go-ethereum/blob/master/README.md#configuration)
* [lnd config options](https://github.com/lightningnetwork/lnd/blob/master/sample-lnd.conf)
* [connext config options](https://docs.connext.network)
* [opendexd config options](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf)


# 🧑‍🏭 Standard Hardware Guide

This guide is written for liquidity providers to turn a Raspberry Pi into an always-on OpenDEX node.

![](/files/N2ObnHVmWdgmBJh0aBOq)

Two options are available:

1. **Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider or optionally [Infura](https://infura.io/). This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes. **Supported by all Pi3/4 models.**
2. **Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more resources and an SSD, but keeps the setup trustless. **Supported only by the Pi4 with 4GB RAM or more.**

If you are not sure, we recommend to start with the light setup. If you opt for the Pi4 4/8GB, you can switch to the full setup at any time.

### Light Reference Shopping List (Spain): \~65 €

* [Pi3 B+](https://www.tiendatec.es/raspberry-pi/placas-base/752-raspberry-pi-3-modelo-b-plus-713179640259.html): 39,95 €
* [Pi3 B+ Power Supply](https://www.tiendatec.es/raspberry-pi/raspberry-pi-alimentacion/974-fuente-alimentacion-5v-3a-micro-usb-con-interruptor-raspberry-pi-3-8472496015080.html): 6,65 €
* [32GB MicroSD card](https://www.amazon.es/dp/B06XYHN68L/): 15 €
  * A performant microSD card is important; not the right place to save some bucks.
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

### Full Reference Shopping List (Spain): \~290 €

* [Pi4 (8GB)](https://www.tiendatec.es/raspberry-pi/placas-base/1231-raspberry-pi-4-modelo-b-8gb-765756931199.html): 82,95 €
* [Pi4 Power Supply](https://www.tiendatec.es/raspberry-pi/raspberry-pi-alimentacion/1093-alimentador-oficial-raspberry-pi-4-usb-c-5v-3a-15w-negro-644824914886.html): 8,95 €
* [Pi4 Cooling Case](https://www.tiendatec.es/raspberry-pi/cajas/1110-caja-cofre-alta-disipacion-con-dos-ventiladores-para-raspberry-pi-4-8472496015950.html): 14,95 €
  * Needed! The Pi4 is a hottie.
* [32GB MicroSD card](https://www.amazon.es/dp/B06XYHN68L/): 15 €
  * A performant microSD card is important; not the right place to save some bucks.
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.
* [1TB external SSD](https://www.amazon.es/gp/product/B074M774TW/): 165 €
  * **For full setup only, not needed for light setup!**
  * For more options, check [this storage benchmark list](https://jamesachambers.com/raspberry-pi-storage-benchmarks/).

### Pi Basic Setup

1. [Download Ubuntu 20.04 for the Pi](https://ubuntu.com/download/raspberry-pi) onto your computer, choosing **64-bit**. Any other 64-bit (also called `arm64`, `aarch64`, `armv8`) linux os for the Pi is fine too. Systems like [Raspberry Pi OS](https://www.raspberrypi.org/downloads/raspberry-pi-os/), which, at the time of writing, are still based on the 32-bit (`armv7`) architecture , are **not** supported. This guide was written using `Ubuntu 20.04`.
2. Insert the microSD card into your computer and follow the [flash instructions](https://ubuntu.com/download/iot/installation-media).
3. *Optional:* If you don't have a screen, usb keyboard and even an ethernet cable available, you can pre-configure Wifi for a headless setup.

```bash
# on your linux computer, cd to the mounted microSD card partition "writable" and copy the wifi sample file. If you can't see any partition called "writable", then you are probably running something other than linux and need to figure out how to mount an ext4 filesystem.
sudo cp ./usr/share/doc/netplan/examples/wireless.yaml ./etc/netplan/
# open the file to edit
sudo nano ./etc/netplan/wireless.yaml
# strip down the file to the bare minmum for the Pi to get an IP automatically assigned by your router
network:
  version: 2
  wifis:
    wlan0:
      dhcp4: yes
      dhcp6: no
      access-points:
        "<YOUR WIFI SSID>":
          password: "<YOUR WIFI PASSWORD>"
# if you can't access your router to read out your Pi's IP, you can also configure a static IP now
      addresses: [192.168.1.42/24]
      gateway4: 192.168.1.1
      nameservers:
        addresses: [192.168.1.1, 8.8.8.8]
# CTRL+S, CTRL+X.
```

1. Insert the microSD card into your Pi, connect it to your router via ethernet cable and to a power supply. Connecting a screen via HDMI and a USB keyboard makes life easier, but checking the assigned IP in your router and SSHing in from your computer works too.
2. Follow the inital setup instructions. Default user + password is `ubuntu`. You will be asked to change the password on first login.
3. Update ubuntu via `sudo apt update && sudo apt upgrade`
4. If you are using Ubuntu 20.04, install docker & docker-compose by running `sudo apt install docker.io`. Otherwise if you are using any version besides Ubuntu 20.04, follow the [official instructions](https://docs.docker.com/install/linux/docker-ce/ubuntu/) (select `arm64` in step 4 of "Set up the repository") to install docker.
5. Add new user `opendex`:

```bash
ubuntu@ubuntu:~$ sudo adduser opendex
Adding user `opendex' ...
Adding new group `opendex' (1001) ...
Adding new user `opendex' (1001) with group `opendex' ...
Creating home directory `/home/opendex' ...
Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for opendexd
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] ubuntu@ubuntu:~$ Y
```

1. Add the `opendex` user to the sudo group (advanced users can skip this and use another user to run sudo commands), the docker group and test if docker is working:

```bash
ubuntu@ubuntu:~$ sudo usermod -aG sudo opendex
ubuntu@ubuntu:~$ sudo usermod -aG docker opendex
# switch to user opendexd
ubuntu@ubuntu:~$ sudo su - opendex
opendex@ubuntu:~$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
```

1. Looking good! Optionally, add an alias to enter your opendexd environment by simply typing "opendex":

```bash
opendex@ubuntu:~$ sudo nano ~/.bash_aliases
# add the line
alias opendex='bash ~/opendex.sh'
# CTRL+S, CTRL+X. Then run
opendex@ubuntu:~$ source ~/.bashrc
```

1. Connect the USB stick to your Pi and set it up. It is very important to do this for a mainnet setup (given you do not want to lose money)!

```bash
# check the USB stick's path with
opendex@ubuntu:~$ ls -la /dev/ | grep sd
crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/dev/sda1 /media/USB ext4 defaults 0 2
# CTRL+S, CTRL+X. Then mount it
opendex@ubuntu:~$ sudo mkdir /media/USB
opendex@ubuntu:~$ sudo mount -a
# check if mounting worked
opendex@ubuntu:~$ df -h
# make sure opendexd can use it
opendex@ubuntu:~$ sudo chown opendex:opendex /media/USB
```

From here the light and full setup require different settings. Continue choosing one.

### Pi Light Setup

If you are using a Pi model with 2GB of RAM or more, you can continue [here](/docs/liquidity-providers#the-setup). If you are using a Pi model with <2GB of RAM, we will have to catch a temporary RAM spike when creating the opendex environment by creating a swap file (overflow RAM) of 2GB on the internal sd card:

```bash
# create the swap file
opendex@ubuntu:~$ sudo fallocate -l 2G /home/opendex/swapfile
# mark it as swap file
opendex@ubuntu:~$ sudo chmod 600 /home/opendex/swapfile && sudo mkswap /home/opendex/swapfile
# enable it
opendex@ubuntu:~$ sudo swapon /home/opendex/swapfile
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/home/opendex/swapfile none swap sw 0 0
# # CTRL+S, CTRL+X. Let's verify it's working & reboot
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/home/opendex/swapfile file  2G   0B   -2
opendex@ubuntu:~$ sudo reboot
# after reboot, let's check if the swapfile is still active
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/home/opendex/swapfile file  2G   0B   -2
```

Light setup - **DONE!** Continue [here](/docs/liquidity-providers#the-setup).

### Pi Full Setup

Connect the SSD to your Pi4 and set it up:

```bash
# let's check the SSD's path
opendex@ubuntu:~$ ls -la /dev/ | grep sd
crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
brw-rw----  1 root disk      8,  16 Jan 28 10:45 sdb
brw-rw----  1 root disk      8,  17 Jan 28 10:45 sdb1 #this is your SSD
crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/dev/sdb1 /media/SSD ext4 defaults 0 2
# CTRL+S, CTRL+X. Then mount it
opendex@ubuntu:~$ sudo mkdir /media/SSD
opendex@ubuntu:~$ mount -a
# check if mounting worked
opendex@ubuntu:~$ df -h
# make sure opendexd can use it without sudo privileges
opendex@ubuntu:~$ sudo chown opendexd:opendexd /media/SSD
```

Let's do a quick performance test of the SSD. If you are close to these values, you are good to go, whereas <100 MB/s would be too slow:

```bash
opendex@ubuntu:~$ sudo dd if=/dev/zero  of=/media/SSD/deleteme.dat bs=32M count=64 oflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 12.8709 s, 167 MB/s
opendex@ubuntu:~$ sudo dd if=/media/SSD/deleteme.dat of=/dev/null bs=32M count=64 iflag=direct
64+0 records in
64+0 records out
2147483648 bytes (2.1 GB, 2.0 GiB) copied, 15.5791 s, 138 MB/s
opendex@ubuntu:~$ sudo rm /media/SSD/deleteme.dat
```

Important: geth needs loads of RAM when syncing, so we need to create a swap file (overflow RAM) of 8GB on the external SSD:

```bash
# create a swap file on the SSD, we recommend a size of 8GB
opendex@ubuntu:~$ sudo fallocate -l 8G /media/SSD/swapfile
# mark it as swap file
opendex@ubuntu:~$ sudo chmod 600 /media/SSD/swapfile && sudo mkswap /media/SSD/swapfile
# enable it
opendex@ubuntu:~$ sudo swapon /media/SSD/swapfile
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/media/SSD/swapfile none swap sw 0 0
# # CTRL+S, CTRL+X. Let's verify it's working & reboot
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/media/SSD/swapfile file  8G   0B   -2
opendex@ubuntu:~$ sudo reboot
# after reboot, let's check if the swapfile is still active
opendex@ubuntu:~$ sudo swapon --show
NAME               TYPE SIZE USED PRIO
/media/SSD/swapfile file  8G   0B   -2
```

Full setup - **DONE!** Continue [here](/docs/liquidity-providers#the-setup).


# Pro Hardware Guide

This guide is written for professional liquidity providers to turn a powerful Mini PC into an always-on OpenDEX node.

![](/files/icBxTeBpn0DTTLDrzxdJ)

Two options are available:

1. **Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider or optionally [Infura](https://infura.io/). This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more resources and an SSD, but keeps the setup trustless.

### Light Reference Shopping List (Europe): \~180 €

* [GIGABYTE GB-BLCE-4105 BRIX](https://www.computeruniverse.net/en/gigabyte-gb-blce-4105-brix): 138 €
* [4 GB RAM](https://www.computeruniverse.net/en/crucial-4gb-ddr4-so-dimm-ct4g4sfs824a-2400mhz-ram): 15 €
* [120GB M.2 SSD](https://www.computeruniverse.net/en/wd-green-ssd-m2-2280-120gb): 20 €
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

### Full Reference Shopping List (Europe): \~465 €

* [GIGABYTE GB-BLCE-4105 BRIX](https://www.computeruniverse.net/en/gigabyte-gb-blce-4105-brix): 138 €
  * Alternative: [ODROID H2+](https://www.hardkernel.com/shop/odroid-h2plus/) - same platform, features NVME, needs separate case, power supply and wifi dongle, out of stock at times
* [32 GB RAM](https://www.computeruniverse.net/en/kingston-hyperx-impact-32gb-ddr4-so-dimm-ram-2): 127 €
  * Alternative: [List of compatible RAM](https://wiki.odroid.com/odroid-h2/hardware/ram)
* [2TB SSD](https://www.computeruniverse.net/en/sandisk-ssd-plus-25-2tb): 193 €
  * Alternative: [1 TB M.2 SSD NVME](https://www.computeruniverse.net/en/gigabyte-ssd-nvme-m2-2280-1tb) - for Odroid H2+
  * Alternative: [240GB M.2 SSD](https://www.computeruniverse.net/en/wd-green-ssd-m2-2280-240gb) + [2TB HDD](https://www.computeruniverse.net/en/seagate-firecuda-compute-st2000lx001-sshd-2tb)
* [USB stick for backups](https://www.amazon.es/dp/B00TPG6P22/): 3,99 €
  * Any >1GB USB stick will do.
  * A NAS/Samba share works too.

### Setup

1. [Download Ubuntu Server 20.04 LTS](https://ubuntu.com/download/server) onto your computer. Any other linux distribution supporting docker is also fine. This guide was written using `Ubuntu Server 20.04`.
2. Insert a USB Stick into your computer and [create the a bootable USB Stick](https://ubuntu.com/tutorials/tutorial-create-a-usb-stick-on-ubuntu) with the ubuntu image you just downloaded.
3. Open your Mini PC, plug in RAM & drives, close it, connect it to your router via ethernet cable and to a power supply. Connect a screen via HDMI, a USB keyboard, the created bootable USB Stick, fire the Mini PC up and follow the the inital setup instructions.
4. Update ubuntu via `sudo apt update && sudo apt upgrade`
5. If you are using Ubuntu 20.04, install docker & docker-compose by running `sudo apt install docker.io`. Otherwise if you are using any version besides Ubuntu 20.04, follow the [official instructions](https://docs.docker.com/install/linux/docker-ce/ubuntu/) to install docker.
6. Add new user `opendex`:

```bash
ubuntu@ubuntu:~$ sudo adduser opendex
Adding user `opendex' ...
Adding new group `opendex' (1001) ...
Adding new user `opendex' (1001) with group `opendex' ...
Creating home directory `/home/opendex' ...
Copying files from `/etc/skel' ...
New password: 
Retype new password: 
passwd: password updated successfully
Changing the user information for opendexd
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] ubuntu@ubuntu:~$ Y
```

1. Add the `opendex` user to the sudo group (advanced users can skip this and use another user to run sudo commands), the docker group and test if docker is working:

```bash
ubuntu@ubuntu:~$ sudo usermod -aG sudo opendex
ubuntu@ubuntu:~$ sudo usermod -aG docker opendex
# switch to user opendex
ubuntu@ubuntu:~$ sudo su - opendex
opendex@ubuntu:~$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
```

1. Looking good! Optionally, add an alias to enter your opendexd environment by simply typing "opendex":

```bash
opendex@ubuntu:~$ sudo nano ~/.bash_aliases
# add the line
alias opendex='bash ~/opendex.sh'
# CTRL+S, CTRL+X. Then run
opendex@ubuntu:~$ source ~/.bashrc
```

1. Connect the USB stick to your machine and set it up. It is very important to do this for a mainnet setup (given you do not want to lose money)!

```bash
# check the USB stick's path with
opendex@ubuntu:~$ ls -la /dev/ | grep sd
crw-------  1 root root      2,  61 Dec  3 16:27 ptysd
brw-rw----  1 root disk      8,   0 Dec  3 16:27 sda
brw-rw----  1 root disk      8,   1 Dec  3 16:27 sda1 #this is your USB Stick
crw-------  1 root root      3,  61 Dec  3 16:27 ttysd
# set it to automount via fstab
opendex@ubuntu:~$ sudo nano /etc/fstab
# add the line
/dev/sda1 /media/USB ext4 defaults 0 2
# CTRL+S, CTRL+X. Then mount it
opendex@ubuntu:~$ sudo mkdir /media/USB
opendex@ubuntu:~$ sudo mount -a
# check if mounting worked
opendex@ubuntu:~$ df -h
# make sure opendexd can use it
opendex@ubuntu:~$ sudo chown opendex:opendex /media/USB
```

**DONE!** Continue [here](/docs/liquidity-providers#the-setup).


# 🔁-Swap Providers

This guide is written for system administrators of projects looking to **source liquidity** on the OpenDEX network and is still an **early-stage WIP**.

## Prerequisites

### Two Modes

1. **Default: Light setup** using [Neutrino](https://github.com/lightninglabs/neutrino) and a random open eth provider. This keeps the setup light-weight & cheap, but creates a certain dependency on other people's full nodes.
2. **Optional: Full setup** using [bitcoind](https://github.com/bitcoin/bitcoin/), [litecoind](https://github.com/litecoin-project/litecoin) and [geth](https://github.com/ethereum/go-ethereum). Requires more time and resources, but keeps the setup trustless.

### Three Networks

1. **Simnet**. `Status: down` until further notice
2. **Testnet**. `Status: up | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 200GB for full | Initial Sync Time: 15 mins for light, 24h for full`

   bitcoin testnet 3, litecoin testnet 4, ethereum rinkeby. Faucets: [t-BTC](https://coinfaucet.eu/en/btc-testnet/), [t-LTC](https://testnet.help/en/ltcfaucet/testnet), [t-ETH 1](https://faucet.rinkeby.io/) or [2](https://testnet.help/en/ethfaucet/rinkeby). If you need help or some testnet coins, hit us up on [Discord](https://discord.gg/aS5RMchDrU)!
3. **Mainnet**. `Status: down | Required CPUs: 2 for light, 4 for full | RAM: 2GB for light, 16GB for full | Disk: 1GB for light, 1TB for full | Initial Sync Time: 30 mins for light, 72h for full`

   Down until all breaking changes are merged and some weeks on testnet didn't reveal major issues.

### Software

Docker & Docker Compose.

Version >= 18.09 on Linux or Windows 10 [using WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install-win10). If you do not have docker & docker-compose installed yet and you are using Ubuntu 20.04 LTS, install these via `sudo apt install docker.io`. If you are using any version besides Ubuntu 20.04, follow the official [docker install instructions](https://docs.docker.com/get-docker/). Also make sure that the current user can run docker commands. Test with `docker run hello-world`. If this fails, [follow these instructions](https://docs.docker.com/engine/install/linux-postinstall/). This guide was written using Ubuntu 20.04 LTS.

## The Setup

From here we assume that your device is running with docker set up. Check the guides in the hardware section above if your device is not ready yet.

### Let's Roll

Start the environment with

```bash
curl https://raw.githubusercontent.com/opendexnetwork/opendex-docker/master/opendexd.sh -o ~/opendexd.sh
bash ~/opendexd.sh
```

The setup will ask you to choose the network:

```
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
🚀 Launching mainnet environment
🌍 Checking for updates ...
```

Sync light clients (default):

```
Syncing light clients:
┌─────────┬─────────────────────────────────────────────────────┐
│ SERVICE │ STATUS                                              │
├─────────┼─────────────────────────────────────────────────────┤
│ lndbtc  │ Syncing 34.24% (610000/1781443)                     │
├─────────┼─────────────────────────────────────────────────────┤
│ lndltc  │ Syncing 12.17% (191000/1568645)                     │
└─────────┴─────────────────────────────────────────────────────┘
```

And then guide you through some basics:

```
Do you want to create a new opendexd environment or restore an existing one?
1) Create New
2) Restore Existing
Please choose: 1
```

When creating a new opendexd SEED, the setup asks you to set a password to encrypt your environment's private keys and to write down your mnemonic phrase. This serves as backup for your opendexd node key and wallets (your on-chain assets). This is your last resort in case something happens to your device. **Keep it somewhere safe!**

```
You are creating an opendexd node key and underlying wallets. All will be secured by a single password provided below.
  
Enter a password: 
Re-enter password: 

----------------------BEGIN OPENDEX SEED---------------------
 1. you         2. won't       3. find        4. money      
 5. in          6. this        7. seed        8. but    
 9. good       10. thinking   11. if         12. you      
13. are        14. interested 15. in         16. getting     
17. rewarded   18. for        19. testing    20. opendex  
21. security   22. hit        23. us         24. up   
-----------------------END OPENDEX SEED----------------------

The following wallets were initialized: BTC, LTC, ERC20(ETH)
```

Then you'll be asked to enter the path to your backup drive, e.g. a previously mounted USB drive:

```
Please enter a path to a destination where to store a backup of your environment. It includes everything, but NOT your on-chain wallet balance which is secured by your opendexd SEED. The path should be an external drive, like a USB or network drive, which is permanently available on your device since backups are written constantly.

Enter path to backup location: /media/USB/
Checking... OK.
```

The entered backup drive location is persisted as `backup-dir = "/media/USB/"` in `mainnet.conf` and can be changed any time. Alternatively, you can consider running your environment on two hard drives in [RAID 1](https://en.wikipedia.org/wiki/Standard_RAID_levels#RAID_1) to protect against data loss.

Then the setup might restart clients and ask you to enter your password once more before the CTL

Use the `status` command to check on the your setup's health and sync progress. The default light setup should show `Ready` after some seconds:

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Ready (light mode)                             │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Syncing                                        │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for lndbtc, lndltc                     │
└───────────┴────────────────────────────────────────────────┘
```

If you configured the full setup via config file or cli parameters, the sync will start fast and get slower towards the end. You might see 0.00% progress for several minutes at first.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 0.00% (0/436000)                       │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 0.00% (0/324000)                       │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 0.00% (55/9140561)                     │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

After a while you should see all three full-nodes syncing nicely.

```
mainnet > status
┌───────────┬────────────────────────────────────────────────┐
│ SERVICE   │ STATUS                                         │
├───────────┼────────────────────────────────────────────────┤
│ bitcoind  │ Syncing 43.06% (262348/609123)                 │
├───────────┼────────────────────────────────────────────────┤
│ litecoind │ Syncing 35.94% (631593/1757002)                │
├───────────┼────────────────────────────────────────────────┤
│ geth      │ Syncing 10.16% (929072/9140623)                │
├───────────┼────────────────────────────────────────────────┤
│ lndbtc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ lndltc    │ Waiting for sync                               │
├───────────┼────────────────────────────────────────────────┤
│ connext   │ Ready                                          │
├───────────┼────────────────────────────────────────────────┤
│ opendexd  │ Waiting for sync                               │
└───────────┴────────────────────────────────────────────────┘
```

Bitcoind/Litecoind should finish syncing within 12h, geth in about 72h on powerful hardware. A Pi4 needs about twice that long.

The CLI takes `opendex-cli` commands without the need to prepend `opendex-cli`, e.g. simply type `getinfo` to get basic information about your opendex node. Run `help` to get an always up-to-date list of commands. Append `-j` to any command to get JSON instead of the formatted output, e.g. using `listpeers` to see other opendexd nodes on the network:

```
mainnet > listpeers -j
{
  "peersList": [
    {
      "address": "rgz5icb5jdxzmu7r7tbis64q23ioytzd4tqikuyb5kz75w75rbe6veyd.onion:8885",
      "nodePubKey": "02529a91d073dda641565ef7affccf035905f3d8c88191bdea83a35f37ccce5d64",
      "lndPubKeysMap": [
        [
          "BTC",
          "035cb9afb06a83e65fbab15c900d78580673cf56ce38c5814fb71f1eb57fcba7ee"
        ],
        [
          "LTC",
          "036cf16cd7de6193efb2855e784409c3633f893662dd6edcf7a545a99659232373"
        ]
      ],
      "inbound": false,
      "pairsList": [
        "LTC/BTC",
        "ETH/BTC",
      ],
      "opendexdVersion": "1.2.7",
      "secondsConnected": 100,
      "connextAddress": "0xe802431257a1d9366BD5747F0F52bAd25A6C3092"
    }
  ]
}
```

### Your First Trade

Start by depositing some funds into your opendex node:

```bash
deposit btc #Send BTC to this address
deposit ltc #Send LTC to this address
deposit eth #Send ETH to this address
```

The deposit command for BTC & LTC is powered by [Boltz](https://boltz.exchange). Boltz will automatically open a balanced lightning channel to you, if you don't have a channel yet. This can take several minutes to complete and we'd kindly ask you to wait patiently for your funds to appear in the `getbalance` overview. If you want to follow what is happening under the hood, you can do so by typing `logs boltz`. For ETH, currently one still needs to trigger a manual channel creation in a second step after funds were deposited:

```
openchannel ETH 13.37
```

Check existing orders for all activated pairs with the command `orderbook`. It might take several seconds to see orders after opendexd was started due to the decentralized nature of the order exchange. Use `orderbook btc/usdt` to show the order book for BTC/USDT only:

```
mainnet > orderbook btc/usdt

Trading pair: BTC/USDT
┌───────────────────────────────────────┬───────────────────────────────────────┐
│ Buy                                   │ Sell                                  │
├───────────────────┬───────────────────┼───────────────────┬───────────────────┤
│ Quantity          │ Price             │ Price             │ Quantity          │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.28918298        │ 7171.56           │ 7172.253          │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 1                 │ 7171.1937         │ 7172.9757         │ 0.1               │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7171.083          │ 7316.0663         │ 1                 │
├───────────────────┼───────────────────┼───────────────────┼───────────────────┤
│ 0.1               │ 7170.899          │ 7316.44           │ 0.22393946        │
└───────────────────┴───────────────────┴───────────────────┴───────────────────┘
```

Use `getbalance` to check your balance *before* the swap.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.10944853    │ 2.5                        │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5000          │ 5000                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

Issue a regular limit order with e.g. `sell 0.1 btc/usdt 7171` to sell 0.1 btc for a price of 7171 USDT per BTC. If your order was matched, settlement shouldn't take longer than a couple of seconds.

```
mainnet > sell 0.1 btc/usdt 7171
swapped 0.1 BTC with peer order ca24fe00-1c1e-11ea-8b1b-3b2ec0335696
```

Use `getbalance` to check your balance *after* the swap. You are now owning 0.1 BTC less and 717 USDT more.

```
mainnet > getbalance

Balance:
┌──────────┬───────────────┬────────────────────────────┬───────────────────────────────┐
│ Currency │ Total Balance │ Channel Balance (Tradable) │ Wallet Balance (Not Tradable) │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ BTC      │ 6.00944842    │ 2.39999989                 │ 3.60944853                    │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ USDT     │ 5717          │ 5717                       │ 0                             │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ LTC      │ 21            │ 11                         │ 10                            │
├──────────┼───────────────┼────────────────────────────┼───────────────────────────────┤
│ ETH      │ 500           │ 500                        │ 0                             │
└──────────┴───────────────┴────────────────────────────┴───────────────────────────────┘
```

### Connect Swap Provider Bot

WIP

## Report Issues

Please give us feedback and report bugs by running `report` from within `opendex ctl` or our "help" channel on [Discord](https://discord.gg/aS5RMchDrU)!

### References

* [bitcoind config options](https://github.com/bitcoin/bitcoin/blob/master/share/examples/bitcoin.conf)
* [litecoind config options](https://litecoin.info/index.php/Litecoin.conf#litecoin.conf_Configuration_File)
* [geth config options](https://github.com/ethereum/go-ethereum/blob/master/README.md#configuration)
* [lnd config options](https://github.com/lightningnetwork/lnd/blob/master/sample-lnd.conf)
* [connext config options](https://docs.connext.network/en/latest/quickstart/clientInstantiation.html#client-options)
* [opendexd config options](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf)


# 📈-Day Traders

The [OpenDEX Desktop App](https://github.com/opendexnetwork/opendex-desktop/releases) is the recommended way for high-frequency trading on the OpenDEX Network with a nice user interface. If preferred, trading entirely via the command line is possible though following [this guide](/docs/liquidity-providers).


# 👨‍💻-Developers

This guide is intended to help developers who want to contribute to `opendexd`. Developers who want to build services on top of `opendexd`, should check out the node's [API Documentation](https://api.opendex.network/).

### Contribution Guidelines

Be sure to read the [Contribution Guidelines](/docs/contribute) before starting to work or opening a Pull Request.

### Recommended Development Environments

The following development environments are known to be compatible with `opendexd` and are recommended for developers that are unsure what tools to use.

#### Visual Studio Code

[Visual Studio Code](https://code.visualstudio.com/) is a cross-platform code editor that's compatible with most popular programming languages and extensible via a large collection of plug-ins.

**Visual Studio Code Plugins**

Consider using the following plugins for working with `opendexd`.

* [TSLint](https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-tslint-plugin)
* [vscode-proto3](https://marketplace.visualstudio.com/items?itemName=zxh404.vscode-proto3)
* [Bracket Pair Colorizer](https://marketplace.visualstudio.com/items?itemName=coenraads.bracket-pair-colorizer) (definitely optional)

**Visual Studio Code Environment Config**

Adding the two files from [this gist](https://gist.github.com/sangaman/117af412eefc28c4f763c0152ddd3b99) into a `.vscode` folder within the folder where you've cloned `opendexd` will automatically provide debug configurations and general settings that are helpful when developing `opendexd`.

### `opendexd` Setup

#### Auto-restart `opendexd` on file change

Auto restart on every file change under `dist` folder with `nodemon`:

```
nodemon --watch dist -e js bin/opendexd
```

With some sample args disabling lndbtc/lndltc:

```
nodemon --watch dist -e js bin/opendexd --lndbtc.disable=true --lndltc.disable=true
```

#### Connect `opendexd` to testnet

We recommend to connect the `opendexd` instance you are developing on to testnet. Combined with above restarting mechanism, this lets you instantly see how your changes behave in a real-world trading environment.

1. Start testnet with default settings as described [here](/docs/liquidity-providers).
2. Once the environment is up and running, exit from the cli session by typing `exit` or open a second terminal.
3. Stop the opendexd container with `docker stop testnet_opendexd_1`.
4. Copy the testnet lndbtc & lndltc folders into some path that you can easily access. E.g. into your home directory:

```
sudo cp -R ~/.opendex-docker/testnet/data/lndbtc ~/
sudo cp -R ~/.opendex-docker/testnet/data/lndltc ~/
```

1. Ensure that you own the copied folders:

```
sudo chown -R <youruser> ~/lndbtc
sudo chown -R <youruser> ~/lndltc
```

1. Create/change `opendex.conf` in `~/.opendexd` to contain the following:

```bash
[lnd.BTC]
cltvdelta = 40
disable = false
host = "localhost"
nomacaroons = false
port = 20009
certpath = "/home/<youruser>/lndbtc/tls.cert"
macaroonpath = "/home/<youruser>/lndbtc/data/chain/bitcoin/testnet/admin.macaroon"
[lnd.LTC]
cltvdelta = 576
disable = false
host = "localhost"
nomacaroons = false
port = 21009
certpath = "/home/<youruser>/lndltc/tls.cert"
macaroonpath = "/home/<youruser>/lndltc/data/chain/litecoin/testnet/admin.macaroon"
[connext]
disable = false
host = "localhost"
port = 18000
```

1. Now you can start your local `opendexd` instance and it should connect to the running testnet docker environment. You can check that everything works with `~/opendexd/bin$ ./opendex-cli -p 18886 getinfo`.

### References

* [Official TypeScript Documentation](https://www.typescriptlang.org/docs/home.html)
* [Official Node.js Documentation](https://nodejs.org/en/docs/)
* [LND Developer Guide](https://dev.lightning.community/)
* [Official gRPC Documentation](https://grpc.io/docs/)


# 🤝-Code Contribution

Yay! Thanks for helping us build OpenDEX! Any contributions are welcome no matter how big or small. From typos and bug fixes to entire modules...

### Contribution Guidelines

If you are new to contributing to open sources projects on GitHub, check out [this how-to](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github/).

#### Feature Branches & Pull Requests

We use [feature branches](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) for devlopment. Each branch and pull request should focus on a particular feature or issue. Ensure that new branches are created from the latest code in `main`. A branch must be in a working and stable state before it can be merged into `main`.

Pull requests will be reviewed and changes may be requested. If changes are required, make new commits directly to the feature branch. If there have been conflicting commits to `main` since a feature branch was created, rebase the branch onto main using `git rebase`.

For pull requests of small scope, you may squash multiple commits into a single commit or a maintainer will squash them before merging. For more complex pull requests that touch many parts of the code or which contain commits from multiple contributors, please collapse commits by author and affected files or components of the project. This can be performed through an interactive rebase with `git rebase -i`. Use `git commit --amend` when fixing minor typos or bugs with the most recent commit. These practices help maintain a clean and coherent commit history while preserving contribution authorship.

#### Linting & Testing

New test cases are appreciated for any pull requests that changes or adds new functionality. Although the current test suites are in early stages, thorough testing and code coverage is an important long term goal.

All code is linted with [tslint](https://github.com/palantir/tslint) using a slightly modified [tslint adaptation](https://github.com/progre/tslint-config-airbnb) of [Airbnb's javascript style guide](https://github.com/airbnb/javascript). Ensure that your contributions pass all linting rules by running `npm run lint` or using a code editor with a tslint plugin. Per-line or per-file exceptions to linting rules are allowable in certain cases.

#### Commenting & Documentation

Make your code legible by using descriptive variable, function, and class names. For blocks of codes whose function is not readily apparent, add comments explaining what they do. If a pull request changes the interface to `opendexd` or introduces new functionality, update the README to describe these changes.

`opendexd` uses [TypeDoc](http://typedoc.org/guides/doccomments/) and any comments documenting specific classes, methods, properties should follow this convention.

Commit messages should be concise and descriptive. For larger or more complex commits, add details of what has changed in the commit description.

If you see something missing or want to develop another cool feature or bug fix which doesn't have an issue yet, open one and we'll take it from there. We don't recommend working on things without a GitHub issue.


# ✋-Dockerless Setup

This page contains instructions how to natively install `opendexd` and its minimal dependencies `lnd` (BTC) & `connext` (ETH & ERC20) on linux. It is mainly geared towards developers and administrators which prefer a native installation over docker.

## Requirements

Make sure to have the following installed:

* [Node.js](https://nodejs.org/en/download/), current active LTS (we recommend [installing via nvm](https://nodejs.org/en/download/package-manager/#nvm))
* [Go](https://golang.org/), v1.14 or higher
* a user called `opendexd`

## opendexd

### Option 1: Installing latest release via npm

This is the easiest and fastest way to install `opendexd` on a `amd64` machine:

```bash
sudo npm install opendexd -g --unsafe-perm
```

### Option 2: Cloning from GitHub

Testers and developers are encouraged to clone the repository from GitHub and install from source:

```bash
git clone https://github.com/opendexnetwork/opendexd
cd opendexd
npm install
npm run compile
npm run compile:seedutil
```

If you are on an architecture that is *not* `amd64`, you'll have to remove `grpc-tools` and potentially others from the `devDependencies` section of [`package.json`](https://github.com/opendexnetwork/opendexd/blob/main/package.json).

### Daemonize `opendexd`

If you want to daemonize `opendexd`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```toml
[Unit]
Description=opendexd

[Service]
User=opendexd
Group=opendexd
Type=simple
Environment=NODE_ENV=production
ExecStart=/home/opendexd/opendexd/bin/opendexd --mainnet
KillMode=process
KillSignal=SIGINT
```

## LND (BTC)

Follow the [lnd installation guide](https://github.com/lightningnetwork/lnd/blob/master/docs/INSTALL.md#installing-lnd).

### Daemonize `lnd`

If you want to daemonize `lnd`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```toml
[Unit]
Description=LND

[Service]
User=opendexd
Group=opendexd
Type=simple
ExecStart=/home/opendexd/lnd/bin/lnd --bitcoin.mainnet
KillMode=process
KillSignal=SIGINT
```

## Connext

Follow the [docs](https://github.com/connext/vector#quick-start), you want the **`node`: vector node + database** stack.

### Daemonize `connext`

If you want to daemonize `connext`, so that it starts on boot without needing its own terminal, you can do this using `systemd`:

```toml
[Unit]
Description=Connext

[Service]
User=opendexd
Group=opendexd
Type=simple
Environment="NODE_ENV=production"
Environment="CONNEXT_NODE_URL=https://connext.boltz.exchange"
Environment="CONNEXT_ETH_PROVIDER_URL=http://eth.kilrau.com:41007"
Environment="LEGACY_MODE=true"
WorkingDirectory=/home/opendexd/connext/
ExecStart=node /home/opendexd/connext/build/src/index.js
KillMode=process
KillSignal=SIGINT
```

## Tor

You can install tor via `sudo apt install tor` on most linux distros nowadays, just make sure [the version is fairly recent](https://github.com/torproject/tor/releases). If not, consult the [tor installation guides](https://2019.www.torproject.org/docs/installguide.html.en). Run `systemctl status tor` or `ps aux | grep tor` to verify the tor process is running.

## Putting it all together

Create the following `opendexd.conf` in `/home/opendexd/.opendexd`:

```toml
mainnet = true

[p2p]
tor = true
torport = 9050

[connext]
disable = false
host = "localhost"
port = 8000
webhookhost = "localhost"
webhookport = 8887

[lnd.BTC]
disable = false
host = "localhost"
certpath = "/home/opendexd/.lnd/tls.cert"
macaroonpath = "/home/opendexd/.lnd/admin.macaroon"

[lnd.LTC]
disable = true
```

For convenience, consider adding `alias opendex-cli='/home/opendexd/opendexd/bin/opendex-cli -p 8886'` to the opendexd user's `.bashrc` and source it. Then restart `opendexd` once (e.g. with `systemctl restart opendexd`) and try running `opendex-cli getinfo`, which should return with an overview of opendexd's, as well as lnd's and connext status.

Ping us in the help channel of our [Discord server](https://discord.gg/aS5RMchDrU) for support.

## Tips 'n Tricks

* When installing on a Raspberry Pi you might see `Unexpected error during initialization`. [Here](https://github.com/ExchangeUnion/xud/issues/1199#issuecomment-527819108) is the solution.
* If you see an `install error` when installing via `npm install`, try `npm install --production` & `npm install typescript`.


# 🛑-How-to Close Shop

This guide is written for anyone looking to "close shop", to withdraw all funds from an opendex environment.

## Close Shop

Enter your environment via:

```bash
bash ~/opendex.sh
1) Simnet
2) Testnet
3) Mainnet
Please choose the network: 3
```

Stop arby to prevent it from issuing orders:

```bash
stop arby
```

Close all BTC & LTC channels:

```bash
lndbtc-lncli closeallchannels
lndltc-lncli closeallchannels
```

Check your ETH/ERC20 channel balances with `getbalance` and close channels using the full channel balance in the following command:

```bash
closechannel ETH --amount 0.5234
closechannel USDT --amount 124.12
```

`getbalance` should now show all **channel** balances as `0`. Once your ETH/ERC20 channel balances are available as `Wallet Balance (Not Tradable)`, you can import your seed/private key into a wallet like metamask. To do this, run the following command and follow the instructions:

```bash
getethmnemonic
```

Once your BTC and LTC channel balances are available as `Wallet Balance (Not Tradable)`, run:

```bash
lndbtc-lncli sendcoins --sweepall --addr <YOUR_EXTERNAL_BTC_ADDRESS>
lndltc-lncli sendcoins --sweepall --addr <YOUR_EXTERNAL_LTC_ADDRESS>
```

One more check that all balances are indeed `0` with `getbalance` and you can safely `down` and delete your environment.


# 💻-CLI Docs

`opendex-cli` is the command line interface that handles much of the basic interaction with a running `opendexd` instance. If `opendexd` is installed globally, it can be launched from any directory. In the recommended [opendex-docker](/docs/liquidity-providers) setup, it can be used from within the `opendexd ctl` shell.

To get a list of up-to-date commands, run:

```
opendex-cli --help
```

Calling any one of the listed commands with the `--help` flag will output additional instructions for that particular command.

Examples for commands:

```bash
# Manually connect to another opendexd instance (has to be running the same network: simnet/testnet/mainnet)
$ opendex-cli connect 025fbfe0e92bf0e5e64500ed542d51f4f9d59111a2d3fa142e90567ec417c4a617@1.opendex.network:8885

# Places a new limit order BUYING 10 LTC for a price of 0.0079 BTC per LTC
$ opendex-cli buy 10 LTC/BTC 0.0079

# Places a new limit order SELLING 5 LTC for the best market price
$ opendex-cli sell 5 LTC/BTC market
```

By default, the CLI output is formatted and abbreviated. Append `-j` to any of the CLI calls to receive the full output in JSON format.


# 🎚️-Config Docs

An *optional* configuration file uses [TOML](https://github.com/toml-lang/toml) and by default should be saved at `~/.opendexd/opendex.conf` on Linux or `AppData\Local\OpenDEX\opendex.conf` on Windows. Run `opendexd` at least once for this folder to be created. The `opendexd` repository contains an up-to-date [`sample-opendex.conf`](https://github.com/opendexnetwork/opendexd/blob/main/sample-opendex.conf) which serves as template for creating `opendex.conf`. It is possible to overwrite the default data directory by launching `opendexd` with `opendexd --opendexdir=/path/to/custom/opendexdir`.

### Precedence

The precedence order in which configuration option values are applied is as follows (high to low):

1. Option given on the command line
2. Option read from the config file
3. Option default value (as seen in the output of `opendexd --help`)


# 📜-Intro

These **BOLD (for Basis of Layer-3 DEX)** documents describe a protocol for p2p trading of cryptocurrencies with the following design goals:

* decentralized order exchange
* native cross-chain capability
* instantaneous off-chain settlement

Nodes running implementations of the protocol comprise the OpenDEX network. Click "Next" below to start reading the BOLD protocol specifications.


# 1️⃣-Message Format

## Overview

All messages sent between nodes have headers. The initial handshake messages are sent unencrypted, and all other messages are encrypted and authenticated using the keys that are generated during the initial handshake.

All messages payloads are serialized using **Protocol Buffers**.

Protocol buffers are a language-neutral, platform-neutral, extensible mechanism for serializing structured data. You can find [documentation on the Google Developers site](https://developers.google.com/protocol-buffers/).

To develop with protocol buffers you will need to install the protocol buffer compiler (to compile `.proto` files) and the protocol buffer runtime for your chosen programming language.

Protocol buffers currently support development in Java, Python, Go, Rust, C, C++, Objective-C, C#, Dart, Ruby, Perl, Haskell, Javascript, [and more](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md#programming-languages).

### The unencrypted message

| Size (bytes) | Name     | Data Type | Description                                             |
| ------------ | -------- | --------- | ------------------------------------------------------- |
| 4            | magic    | uint32    | Magic value to specify the message's network            |
| 4            | length   | uint32    | Payload length                                          |
| 4            | type     | uint32    | Message type                                            |
| 4            | checksum | uint32    | First 4 bytes of sha256 hash of JSON-serialized message |
| length       | payload  | bytes     | The actual data                                         |

#### Magic values

| Network | Magic value  |
| ------- | ------------ |
| mainnet | `0xd9b4bef9` |
| testnet | `0x0709110b` |
| simnet  | `0x12141c16` |
| regnet  | `0xdab5bffa` |

### The encrypted message

| Size (bytes) | Name       | Data Type | Description           |
| ------------ | ---------- | --------- | --------------------- |
| 4            | length     | uint32    | Length of the payload |
| length       | ciphertext | bytes     | The encrypted data    |

#### Ciphertext pre-encryption format

| Size (bytes) | Name    | Data Type | Description     |
| ------------ | ------- | --------- | --------------- |
| 4            | length  | uint32    | Payload length  |
| 4            | type    | uint32    | Message type    |
| length       | payload | bytes     | The actual data |


# 2️⃣-Peer Protocol

## Overview

The current protocol requires a direct connection between two nodes for performing updates, trades, and swaps. This section describes how the connection is set up.

Each node maintains a persistent **secp256k1** private key with a corresponding public key, node key for short, which uniquely identifies the node in the network. We recommend only allowing manual resets of the private key, for example by deleting a file or database entry.

An initial handshake is required to establish a secure TCP-based session between two nodes. The default listening TCP port is **8885**.

## Handshake Protocol

The communication session is established by creating a TCP connection and agreeing on ephemeral key material for further encrypted communication, in addition to utilizing the persistent key for authentication. The process of establishing this session is the “handshake” and is carried out between the “initiator” (the peer that opened the TCP connection) and the “recipient” (the peer that accepted it).

The handshake consists of *each side* sending the `SessionInit` message, and waiting to receive the `SessionAck` message back. The first `SessionInit` message is expected to be sent by the initiator.

The initiator must know the recipient's identity (node key) in advance. The recipient learns the initiator's identity by receiving the `SessionInit` message.

By the end of the handshake, two distinct shared keys are created, one for each side of the communication, to be used to encrypt all messages during the session's lifetime.

## Handshake Messages

These messages are used in the initial handshake:

### SessionInit Message (0x00)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string sign = 2`
secp256k1 signature over sha256 hash of a JSON-serialized msg containing fields 3-7

`string peer_pub_key = 3`
The target node secp256k1 public key (in hex)

`string ephemeral_pub_key = 4`
An ephemeral secp256k1 public key (in hex), generated by the sender, for ECDH key exchange

`NodeState node_state = 5`
General info regarding the sender's current node state

`string version = 6`
OpenDEX client version

`string node_pub_key = 7`
The sender's secp256k1 public key (in hex)
```

Once received by the destination node, the message is authenticated as follows:

* `peer_pub_key` should match the destination node's public key
* `node_pub_key` should match the sender node expected public key (relevant for the initiator node only since he already knows the recipient node's identity)
* `sign` should be a valid secp256k1 signature over the sha256 hash of a JSON-serialized msg containing fields 3-7

If the fields of the `SessionInit` message are valid, the receiver replies with a `SessionAck` message. If a `SessionAck` message is not received within a reasonable time frame (10 seconds is recommended), the sender may disconnect.

### SessionAck Message (0x01)

```
`string id = 1`
The message's globally unique identifier, generated by the sender

`string req_id = 2`
The id of the received SessionInit message

`string ephemeral_pub_key = 3`
An ephemeral secp256k1 public key (in hex), generated by the sender, for ECDH key exchange
```

Once the receiver of the `SessionInit` message (Bob) has generated his ECDH keys, he can calculate the shared key by using the `ephemeral_pub_key` from the `SessionInit` message. Once the `SessionAck` message is received by the sender of the `SessionInit` message (Alice), she can compute the shared key as well. All future communication from Alice to Bob must be encrypted with aes-256-cbc symmetric encryption using the shared key.

## Coordination Messages

These messages are used to maintain the P2P overlay after a session has been established via the initial handshake.

### Ping Message (0x04)

```
`string id = 1`
The message's globally unique identifier, generated by the sender
```

In order to allow long-lived TCP connections, both ends keep the TCP connection alive at the application level using `Ping` and `Pong` messages.

It is recommended to send a `Ping` message every 30 seconds.

The sender of a `Ping` message may disconnect if a `Pong` message is not received within 10 seconds.

### Pong Message (0x05)

```
`string id = 1` 
The message's globally unique identifier, generated by the sender

`string req_id = 2`
The id of the received Ping message
```

The `Pong` message is sent in response to the `Ping` message. It serves to keep the connection alive by explicitly notifying the other end that the receiver is still active.

### Disconnecting Message (0x03)

```
`string id = 1`
The message's unique identifier, generated by the sender 

`uint32 reason = 2`
The reason for the imminent disconnection 

`string payload = 3`
Optional payload to specify the disconnection reason
```

The `Disconnecting` message is used to inform a connected peer that a disconnection is imminent and that the peer should disconnect immediately. A well-behaved host that sends a `Disconnecting` message allows the peer at least 2 seconds to disconnect before disconnecting itself.

`reason` is an optional parameter for specifying one of the following reasons for the disconnection:

| Reason | Meaning                                     |
| ------ | ------------------------------------------- |
| `0x01` | Response stalling                           |
| `0x02` | Incompatible client protocol version        |
| `0x03` | Unexpected identity                         |
| `0x04` | Forbidden identity update                   |
| `0x05` | Connected to self                           |
| `0x06` | Not accepting new connections               |
| `0x07` | Banned                                      |
| `0x08` | Already connected                           |
| `0x09` | Shutdown                                    |
| `0x0a` | Malformed version                           |
| `0x0b` | Authentication failure: invalid target node |
| `0x0c` | Authentication failure: invalid signature   |
| `0x0d` | Wire protocol error                         |

### GetNodes Message (0x0a)

```
`string id = 1`
Message's globally unique identifier, generated by the sender
```

The `GetNodes` message is used to query a peer for its list of known, reachable OpenDEX nodes.

### Nodes Message (0x0b)

```
`string id = 1`
Message's globally unique identifier, generated by the sender 

`string req_id = 2`
Link to the id field from the received GetNodes message

`repeated Node nodes = 2`
The list of known nodes
```

The `Nodes` message is used to respond to the `GetNodes` message.

### NodeStateUpdate Message (0x02)

```
`string id = 1`
Message's globally unique identifier, generated by the sender 

`NodeState node_state = 2`
The updated node state.
```

The `NodeStateUpdate` message is used to tell a peer about a change in the node state. An example of an update is the removal or addition of a supported trading pair.

## Custom types

### NodeState type

```
`repeated Address addresses = 1`
The sender's listening TCP addresses

`repeated string pairs = 2`
The sender's list of trading pair symbols, constructed with the base currency first, followed by a  '/' separator and the quote currency (e.g., [“LTC/BTC”, “DAI/BTC”])

`string connext_identifier = 3`
The sender's Connext identifier (e.g. `indra123abc`)

`map<string, string> lnd_pub_keys = 4`
The sender's list of LND public keys

`map<string, string> token_identifiers = 5`
Mapping between currency symbols and chain identifiers or ETH-ERC20 token contract addresses (e.g., { BTC: 'bitcoin-mainnet', LTC: 'litecoin-mainnet', ETH:,'0x0000000000000000000000000000000000000000' })

`map<string, LndUris> lnd_uris = 6`
Mapping between currency symbols to LND listening URIs (should be reachable from the internet e.g., { BTC: ['2w526cyown43ovsvsojdowheqmukbykrexzyccp6v6j4pm5ve3hjzrid.onion:9735'], LTC: '['lndltc.kilrau.com:9735', 'qiyibtczmuhutusmygvc2injxl7v4yfcodwj3pft63edycud5gr3giad.onion:10735']' })
```

### Address type

```
`string host = 1`

`uint32 port = 2`
```

### LndUris type

```
`repeated string lnd_uri = 1`
```

### Node type

```
`string node_pub_key = 1`
The node's public key upon which its identity should be verified

`repeated Address addresses = 2`
The node's listening TCP addresses
```


# 3️⃣-Trade Protocol

## Overview

OpenDEX does not rely on a central order book or matching engine. Instead, each node on the network maintains its own local order book and matching engine.

Order matching systems of major exchanges differentiate between two participants: the taker and the maker. A taker "fills" the order of a maker.

Similarly, we distinguish between these two types of participants in a trade on OpenDEX:

* The **Maker**: submits an order which cannot be matched immediately by an existing order in the order book. The order is added to the order book and propagated to all connected peers.
* The **Taker**: issues an order which can immediately be matched with an existing (maker) order in the order book.

## Order Type

```
`string id = 1`
The order's globally unique identifier, generated by the sender 

`string pair_id = 1`
A trading pair symbol, constructed with the base currency first, followed by a '/' separator and the quote currency (e.g., “LTC/BTC”)

`double price = 3`
The price for the order expressed in units of the quote currency

`uint64 quantity = 4`
The number of satoshis (or equivalent) for the order

`bool is_buy = 5`
Whether the order is a buy (true) or a sell (false)

`string replace_order_id = 6`
The id of an order that this order is replacing, the specified order should be removed
```

## Trade Protocol

### Order Message (0x06)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`Order order = 2`
The order
```

The `Order` message is used to tell a peer about a new maker order. It should only be sent to peers after the order (or part of the order) could not be matched in the local order book.

### OrderInvalidation Message (0x07)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string order_id = 2`
The order’s unique identifier

`string pair_id = 3`
The trading pair symbol associated with the order

`uint64 quantity = 4`
The number of satoshis (or equivalent) to invalidate from the order sum
```

The `OrderInvalidation` message is used to tell a peer about the full or partial invalidation of a previously sent order. It allows the peer to remove the order from his local order book. Order invalidation is a common event which occurs due to order cancellation or filling (by another node). Failing to send updates about the order will result in peers having a stale order in their local order books. These peers might fill the order and instantiate swap procedures which are doomed to fail. In this case, the maker node’s reputation may be penalized.

### The GetOrders Message (0x08)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`repeated string pair_ids = 2`
The requested orders trading pair symbols, constructed with the base currency first, followed by a  '/' separator and the quote currency (e.g., [“LTC/BTC”, “DAI/BTC”])
```

The `GetOrders` message is used to query a peer for a list of all open orders for the specified trading pairs. It is mainly used to initialize the local order book with a snapshot of the peer's existing open orders after establishing a connection to the peer. New orders are expected to get pushed by the peer via the `Order` message, instead of being queried for.

### The Orders Message (0x09)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`string req_id = 2`
The id from the received `GetOrders` message

`repeated Order orders = 3`
The list of orders
```

The `Orders` message is used to respond to the `GetOrders` message.


# 4️⃣-Swap Protocol

## Overview

Once an order match is found in the taker’s order book, the swap protocol should be initiated. The current swap protocol assumes that the taker and maker are connected via a payment channel network (e.g. [Lightning](http://lightning.network/) or [Connext](https://connext.network/)) with sufficient balance available for the swap. The following is the swap protocol's "happy" flow:

1. Taker finds a match, e.g. buying 1 BTC for 10k DAI
2. Taker creates the private `r_preimage` and the public `r_hash` for the atomic swap
3. Taker sends the `SwapRequest` message to the maker, which includes `r_hash`
4. Maker confirms full or partial quantity in the `SwapAccepted` message
5. Taker starts the swap by dispatching the first-leg HTLCs on the DAI payment channel to the maker end, using `r_hash`
6. Maker listens for an incoming HTLC on the DAI payment channel. Once it arrives he verifies price and quantity and then dispatches the second-leg HTLCs on the BTC payment channel to the taker end.
7. Taker listens for an incoming HTLC on the BTC payment channel. Once it arrives he releases `r_preimage`. This allows **both** the taker and the maker payments to finalize.
8. Both nodes locally mark the swap as completed once the respective HTLC is resolved and the payment is finalized.

Possible misbehaviors and their outcome:

| Misbehavior                                                                         | Outcome                                              | Effect on payment channels                                  |
| ----------------------------------------------------------------------------------- | ---------------------------------------------------- | ----------------------------------------------------------- |
| Maker doesn't respond to the `SwapRequest` message                                  | Taker should timeout the swap and penalize the maker | None                                                        |
| Taker doesn't start the swap after receiving the `SwapAccepted` message             | Maker should timeout the swap and penalize the taker | None                                                        |
| Maker receives the first-leg HTLC with insufficient amount or incorrect CLTV delta  | Maker should send the taker a `SwapError` message    | Taker funds are locked until HTLC expiration                |
| Maker doesn't continue the swap after receiving the first-leg HTLC                  | Taker should timeout the swap and penalize the maker | Taker funds are locked until HTLC expiration                |
| Taker receives the second-leg HTLC with insufficient amount or incorrect CLTV delta | Taker should sends the maker a `SwapError` message   | Both Taker and Maker funds are locked until HTLC expiration |
| Taker doesn't release `r_preimage` after receiving the second-leg HTLC              | Maker should timeout the swap and penalize the taker | Both Taker and Maker funds are locked until HTLC expiration |

## Swap Protocol

### SwapRequest Message (0x0c)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 proposed_quantity = 2`
The proposed quantity

`string pair_id = 3`
The trading pair for the swap

`string order_id = 4`
The unique identifier of the maker order

`string r_hash = 5`
The taker preimage hash (in hex)

`uint32 taker_cltv_delta = 6`
The CLTV delta from the current height that should be used to set the timelock for the final hop when sending to the taker
```

The `SwapRequest` message is sent by the taker to the maker to start the swap negotiation.

### SwapAccepted Message (0x0d)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 req_id = 2`
The id from the received SwapRequest message

`string r_hash = 3`
The taker’s preimage hash (in hex) from the received SwapRequest message

`string quantity = 4`
The accepted quantity (which may be less than the proposed quantity)

`uint32 maker_cltv_delta = 5`
The CLTV delta from the current height that should be used to set the timelock for the final hop when sending to the maker
```

The `SwapAccepted` message is sent by the maker to the taker to accept the swap request.

### SwapFailed Message (0x0f)

```
`string id = 1`
The message's globally unique identifier, generated by the sender 

`uint64 req_id = 2`
An optional id from the received SwapRequest message. Otherwise, this field is empty

`string r_hash = 3`
The taker’s preimage hash (in hex)

`string error_message = 4`
Additional information regarding the failure reason

`uint32 failure_reason = 5`
The failure reason
```

The `SwapFailed` message can be sent by either side of the swap protocol, at any time, to announce the swap termination.

`failure_reason` is an optional parameter for specifying the failure reason:

| Failure Reason | Meaning                       | Description                                                                                              |
| -------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------- |
| `0x00`         | Order Not Found               | Could not find the order specified by a swap request                                                     |
| `0x01`         | Order On Hold                 | The order specified by a swap request is on hold for a different ongoing swap                            |
| `0x02`         | Invalid Swap Request          | The swap request contained invalid data                                                                  |
| `0x03`         | Swap Client Not Setup         | We are not connected to both swap clients, or we are missing public key identifiers for the peer's nodes |
| `0x04`         | No Route Found                | Could not find a route to complete the swap                                                              |
| `0x05`         | Unexpected Client Error       | A swap client call failed for an unexpected reason                                                       |
| `0x06`         | Invalid Swap Message Received | Received a swap message with invalid data                                                                |
| `0x07`         | Send Payment Failure          | The call to send payment failed                                                                          |
| `0x08`         | Invalid Resolve Request       | The swap resolver request was invalid                                                                    |
| `0x09`         | Payment Hash Reuse            | The swap request attempts to reuse a payment hash                                                        |
| `0x0a`         | Swap Timed Out                | The swap timed out while we were waiting for it to complete execution                                    |
| `0x0b`         | Deal Timed Out                | The deal timed out while we were waiting for the peer to respond to our swap request                     |
| `0x0c`         | Unknown Error                 | The swap failed due to an unrecognized error                                                             |


