7.9 KiB
Trying the swap locally
Requirements
Operating System
The code base is only tested regularly with Ubuntu 22.04 on X86-64, but we would like to support most 64-bit Linux distributions, macOS, and WSL on Windows both with X86-64 and ARM processors.
Installed Dependencies for Building/Testing
- go 1.20+ (see build instructions to download Go.)
- node/npm (to install ganache, see suggestions after list)
- ganache (can be installed with
npm install --location=global ganache) - jq, curl, bzip2, realpath
The suggested way to install
node/npm is using nvm. If you install npm using a package manager like snap, ensure
the install prefix (npm config get prefix) is a directory that you have write
access to without sudo. You can change the directory with this command:
npm config set prefix ~/.npm-packages
See this document if you want a more sophisticated setup.
If you are testing, you'll want jq installed. curl and bzip2 are normally
preinstalled, but if you are running in a docker container, you might have to
install them.
sudo apt install curl bzip2 jq
Macos Notes
On macOS, you'll need to install realpath (from the coreutils package). If you
are using Homebrew, you can use these commands to install all the needed tools:
brew install coreutils go jq nvm bash
nvm install node
npm install --location=global ganache
Set up development environment
Note: the scripts/install-monero-linux.sh script will download the monero binaries needed for you.
You can invoke it directly, but the next script below will run it if there is no symbolic link named
monero-bin to a monero installation in the project's root directory.
Use this command to launch ganache, an ethereum simulator, and monerod in regtest mode.
"regtest" mode is stand-alone (non-networked) mode of monerod for testing purposes.
Warning: the command below will kill running instances of ganache, monerod,
monero-wallet-rpc or swapd.
./scripts/setup-env.sh
To avoid confusion, delete any data directories from old runs of swapd that used
the flags --dev-xmrtaker or --dev-xmrmaker:
rm -rf "${TMPDIR:-/tmp}"/xmr[mt]aker-*
Build the Executables
You have several options. If you are looking to do production swaps, use one of
the first two release options. All 3 options create swapd and swapcli
binaries in the bin directory at the top of the project.
Build the most recent tagged release using Go
make build-release
Build the most recent tagged release using docker (Go not required)
make build-release-in-docker
Build the checked-out sources as-is
make build
Launch Alice and Bob's swapd Instances
To launch Alice's swapd instance, use this command:
./bin/swapd --dev-xmrtaker --deploy &> alice.log &
We are going to use Alice's instance as a bootnode for Bob's instance. To configure this, we need one of the multi-addresses that Alice is listening on. Alice will be listing both on a TCP port and a UDP/QUIC port, it doesn't matter which one you pick. Use this command to list Alice's listening libp2p multi-addresses:
./bin/swapcli addresses
Assign the value you picked to a variable. Your value will be different, this is just an example below:
BOOT_NODE=/ip4/127.0.0.1/udp/9933/quic-v1/p2p/12D3KooWHRi24PVZ6TBnQJHdVyewDRcKFZtYV3qmB4KQo8iMyqik
Now get the ethereum contract address that Alice deployed to. This can be pulled
from the Alice's logs, or from a version RPC request.
CONTRACT_ADDR=$(./bin/swapcli version | grep '^swap creator address' | sed 's/.*: //')
Now start Bob's swapd instance:
./bin/swapd --dev-xmrmaker --bootnodes "${BOOT_NODE}" --contract-address "${CONTRACT_ADDR}" &> bob.log &
Using swapcli To Check Balances
swapcli is an executable to interact with a swapd instance via it's RPC port on the
local host (127.0.0.1). The current security model of swapd assumes connections
originating from the local host are authorized, so you should not run swapd for
production swaps on multi-user hosts or hosts with malicious software running on them.
Note: when using the --dev-xmrtaker and --dev-xmrmaker flags, Alice's RPC server runs
on http://localhost:5000 (the default port) and Bob's runs on http://localhost:5001. Since
Bob's swapd RPC port is not the default, you will need to pass --swapd-port 5001 to
swapcli when interacting with his daemon.
Alice and Bob are both using Ethereum wallet keys that are prefunded by Ganache.
Background Monero mining was started for Bob, because his swapd instance used the
--dev-xmrmaker flag.
You can check Alice's balance with this command:
./bin/swapcli balances
And Bob's balances with this command:
./bin/swapcli balances --swapd-port 5001
If Bob doesn't have enough balance, you can mine more blocks using:
source scripts/testlib.sh
mine-monero-for-swapd 5001
Make a Swap Offer
Next we need Bob to make an offer and advertise it, so that Alice can take it. You will get notified when the swap is taken. This command will block waiting for update messages, so you will need to dedicate a separate terminal for it:
./bin/swapcli make --min-amount 0.1 --max-amount 1 --exchange-rate 0.05 --swapd-port 5001
Example output:
Published:
Offer ID: 0x09dd41c7b8620cdc3716463dc947a11edf3af45ff07c8b0ff89dd23592e732ca
Peer ID: 12D3KooWK7989g6xmAaEsKFPuZTj2CVknRxQuk7dFL55CC1rpEWW
Taker Min: 0.005 ETH
Taker Max: 0.05 ETH
> Stage updated: KeysExchanged
> Stage updated: XMRLocked
> Stage updated: Success
Alternatively, you can make the offer without subscribing to swap updates:
./bin/swapcli make --min-amount 0.1 --max-amount 1 --exchange-rate 0.05 --swapd-port 5001 --detached
Discover Swap Offers
Now, Alice can discover peers who have advertised offers.
./bin/swapcli discover --provides XMR --search-time 3
Peer 0: 12D3KooWAE3zH374qcxyFCA8B5g1uMqhgeiHoXT5KKD6A54SGGsp
Query the returned peer to find the range of XMR they are willing to swap and at what exchange rate. Note: You need to update the peer ID below with the one from your output in the previous step.
./bin/swapcli query --peer-id 12D3KooWAE3zH374qcxyFCA8B5g1uMqhgeiHoXT5KKD6A54SGGsp
Offer ID: 0xcc57d3d1b9d8186118f1f1581a8dc4dca0e5aa6c39a5255bd0c2ebb824cfe2eb
Provides: XMR
Min Amount: 0.1
Max Amount: 1
Exchange Rate: 0.05
ETH Asset: ETH
Take a Swap Offers
Alice now has the information needed to start a swap with Bob. You'll need Bob's peer ID and his offer ID from the previous step to update the command below:
./bin/swapcli take \
--peer-id 12D3KooWAE3zH374qcxyFCA8B5g1uMqhgeiHoXT5KKD6A54SGGsp \
--offer-id 0xcc57d3d1b9d8186118f1f1581a8dc4dca0e5aa6c39a5255bd0c2ebb824cfe2eb \
--provides-amount 0.05
Initiated swap with offer ID 0xcc57d3d1b9d8186118f1f1581a8dc4dca0e5aa6c39a5255bd0c2ebb824cfe2eb
> Stage updated: ExpectingKeys
> Stage updated: ETHLocked
> Stage updated: ContractReady
> Stage updated: Success
Alternatively, you can take the offer without subscribing to swap updates:
./bin/swapcli take \
--peer-id 12D3KooWAE3zH374qcxyFCA8B5g1uMqhgeiHoXT5KKD6A54SGGsp \
--offer-id 0xcc57d3d1b9d8186118f1f1581a8dc4dca0e5aa6c39a5255bd0c2ebb824cfe2eb \
--provides-amount 0.05 --detached
If all goes well, you should see Alice and Bob successfully exchange messages and execute the swap protocol.
Other swapcli Commands
To query the information for an ongoing swap, you can run:
./bin/swapcli ongoing --offer-id <id>
To query information for a past swap using its ID, you can run:
./bin/swapcli past --offer-id <id>
For both of these commands, if no --offer-id is passed, all ongoing or past swaps will be returned.