
This guide explains how to run your own MoonRamp server.
MoonRamp is a self-hosted crypto payment gateway which features a REST and JsonRPC API. It features a programmable WASM runtime that can be used to run custom programs to process sales. Bitcoin (BTC), Bitcoin Cash (BCH), Monero (XMR), Ethereum (ETH), and Ethereum Classic +ERC-20 Tokens are supported.
Moonramp is written in Rust and is free and open source software.
Installation
Choose an Install Method
Docker
A docker image is built with every release that contains all MoonRamp bins and WASM programs.
The ENTRYPOINT
of the image is set to the moonramp
bin and the CMD
must be overrided by the user.
Docker images run as a non-priviledged user moonramp
and group moonramp
with uid:gid
1337:1337
.
The following ports are defined via EXPOSE
- 9370
, 9371
, and 9372
.
No other libraries or bins are included in the image. If you wish to build an image that includes other tooling you can use a multi-stage build to copy the MoonRamp bins. The docker image is very lean at around 35 MB.
For more information on docker see here.
CLI
docker run moonramp/moonramp:0.1.18 help
DockerFile
FROM moonramp/moonramp:0.1.18
Binary
Pre-compiled binaries are provided as Github Releases.
Each release tag is signed and the download includes both bins and WASM programs.
curl https://github.com/MoonRamp/moonramp/releases/latest/download/moonramp.tar.gz
Source
To install from source:
Step 1 - Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Step 2 - Get the source
2a - MoonRamp
git clone git@github.com:MoonRamp/moonramp.git
2b - Required libaries
Please install sqlite-dev
and mysql-dev
packages from your systems package manager. MoonRamp uses rust-tls and as such openssl-dev
is not needed.
Step 3 - Build bins
cd moonramp && cargo build --release
Step 4 - Build WASM programs
cargo --manifest-path=programs/default-sale/Cargo.toml build --release --target=wasm32-wasi
Notes
MacOS DOES NOT ship with a WASM supported version of clang. Please install clang via homebrew and set CC
and AR
env vars.
Example
PATH="/usr/local/opt/llvm/bin:${PATH}" CC=/usr/local/opt/llvm/bin/clang AR=/usr/local/opt/llvm/bin/llvm-ar cargo [COMMAND]
Crates.io
MoonRamp is published to Crates.io with every version release.
CLI
cargo install moonramp
Binaries
moonramp
Crypto payment gateway that can process BTC, BCH, XRM, ETH, and ETC payments. Exposes a REST and JsonRpc 2.0 API. Support for SQL based data stores.
moonrampctl
CLI interface for remote JsonRpc API calls to a moonramp server
Setup
MoonRamp requires minimal setup and is a stateless application utilizing SQL based backends for storage.
The following guides will show what is required to run MoonRamp.
Master Key Encryption Key
MoonRamp uses a key encryption key scheme to uniquely encrypt all records independently of the underlying data store. The Master Key Encryption Key
is a 256 bit key used to protect all data MoonRamp manages.
When the program boots, it will use the provided Master Key Encryption Key
to create or decrypt the current Key Encryption Key
.
The Master Key Encryption Key
will be purged from memory and the Key Encryption Key
held in memory to decrypt Encryption Key
records that are in turn used to decrypt specific record data.
This means that all data is secured via the Master Key Encryption Key
. As such, if this key is lost ALL DATA will be lost! To repeat this any hot wallets managed by the system will be UNRECOVERABLE if the Master Key Encryption Key
is lost.
MoonRamp uses Rust Crypto.
Rotating the Master Key Encryption Key
TODO1
Rotating the Key Encryption Key
TODO2
Shamir Secret Sharing
TODO3
Encryption Stack
MoonRamp recommends a holistic approach to securing your data.
For the highest level of security Merchants should:
- Maintain network firewall configurations to minimize network traffic to host running your data store and MoonRamp
- Run MoonRamp as a non-root user
- Run your data store on seperate hosts as a non-root user
- Enable full disk encryption for both your data store and MoonRamp hosts
- Enable transparent encryption for your data store (Sqlcipher, pgcrypto, etc)
- Run all network traffic with TLS
- Utilize cold wallet support for high risk scenarios
MoonRamp will support Master Key Encryption Key
rotation
MoonRamp will support Key Encryption Key
rotation
MoonRamp will support Shamir secret sharing to constitute a Master Key Encryption Key
from multiple key shares
Master Merchant
MoonRamp is a multi-tennant system that supports any number of merchant accounts. Data and permissions are scoped to merchants. The general exception to this rule is the Master Merchant
which has an elevated role in the system. The primary value the Master Merchant
provides is setting the default programs and creating other merchants.
The next sections of the guide will go through running MoonRamp with each of the support data stores.
Sqlite
Run a bitcoin node in regtest mode
docker run --rm --name bitcoin -d moonramp/bitcoin:0.1.3-v23 -regtest
Setup the Sqlite DB File
Create a docker volume and set the correct file permissions.
docker volume create moonramp
docker run --rm -v moonramp:/db busybox /bin/sh -c 'touch /db/moonramp.db && chown -R 1337:1337 /db'
Run the migrations to setup the db.
docker run -v moonramp:/home/moonramp/db --entrypoint=moonramp-migration moonramp/moonramp:0.1.18 -u "sqlite://db/moonramp.db" migrate
Server Setup (Sqlite)
Create the Master Merchant
The following command will generate a new merchant entry with the provided metadata and return a json blob.
docker run -v moonramp:/home/moonramp/db --entrypoint=moonramp-migration moonramp/moonramp:0.1.18 -u "sqlite://db/moonramp.db" create-merchant -n "My Merchant" -a "An Address" -e "email@example.com" -p "12223334444"
To run the next set of commands we need to come up with a secure Master Key Encryption Key. We recommend at least a 32 character random password. For our example we will use: an example very very secret key.
Using the hash
field from the create-merchant
command replace MERCHANT_HASH
and with your password replace MKEK
in the following command to issue an API token for the master merchant. This API token has complete access to the merchant master account.
docker run -v moonramp:/home/moonramp/db --entrypoint=moonramp-migration moonramp/moonramp:0.1.18 -u "sqlite://db/moonramp.db" create-api-token -m MERCHANT_HASH -M MKEK
The api token record will be in the token
field and the Bearer Auth
string will be in the api_credential
field of the json blob returned. The secret that is generated and encoded into the api_credential
field is not stored in the database and if lost you will need to regenerate a new token.
Run the Server
docker run --rm --name moonramp --link bitcoin -v moonramp:/home/moonramp/db -d moonramp/moonramp:0.1.18 node -u "sqlite://db/moonramp.db" -n example-node-id -m MERCHANT_HASH -M MKEK -N regtest
Verify Servers
docker ps
You should see two docker containers running (bitcoin
, moonramp
). The output should look like the following.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4bd611af09c6 moonramp/moonramp:0.1.18 "moonramp node -u sq…" 2 minutes ago Up 2 minutes moonramp
633e8855d98d moonramp/bitcoin:0.1.3-v23 "bitcoind -regtest" 2 minutes ago Up 2 minutes 8332/tcp, 18332/tcp, 18443/tcp, 38332/tcp bitcoin
Congratulations! You now have a MoonRamp server running using sqlite as a data store and connected to a bitcoin node in regtest mode.
Continue to the CLI Section
Postgres
MoonRamp Setup (Postgres)
CockroachDB
MoonRamp Setup (CockroachDB)
MySql
MoonRamp Setup (MySql)
Moonrampctl
Validate Moonramp
API_TOKEN
is the api_credential
field returned from the json blob output of the moonramp-migration create-api-token
command run during your desired database setup (Sqlite, Postgres, CockroachDB, MySql).
docker exec moonramp moonrampctl -a API_TOKEN program version
You should see something like
{
"id": "69e78dd9e523458d92a889fa39ff0b82",
"jsonrpc": "2.0",
"result": "0.1.18"
}
Moonrampctl (Program)
Configure the Default Sale Program
docker exec moonramp moonrampctl -a API_TOKEN program create -n moonramp-program-default-sale -P /home/moonramp/moonramp_program_default_sale.wasm -v test
You should see a result like
{
"id": "a7e2344df06a4636a9bc8d09ba3346ce",
"jsonrpc": "2.0",
"result": {
"createdAt": "2022-08-03T00:15:23.787162657Z",
"description": null,
"hash": "2CkZM8YwroAXMTCFjWdSW3t4FpK2TBArgfRz9KouR8z6",
"name": "moonramp-default-sale-program",
"private": true,
"revision": 0,
"url": null,
"version": "test"
}
}
The program is processed then stored encrypted in the datastore ready for invocation. We are now ready to start storing wallets and processing crypto payments. For more information about programs capabilites see the Programs section of this guide.
To get more info from moonrampctl
on programs run the following.
docker exec moonramp moonrampctl help program
To get more info on any program subcommand run the following.
docker exec moonramp moonrampctl help program SUBCOMMAND
Moonrampctl (Wallet)
MoonRamp supports both hot and cold wallets. By default all BTC and BCH wallets support BIP32 HD Wallets. For XMR view-only wallets are supported. ETH and ETC wallets support ERC-20 Tokens.
Let's create a new BTC wallet to accept payment from a customer.
docker exec moonramp moonrampctl -a API_TOKEN wallet create -w hot -t btc
You should see something like
{
"id": "7edc7b3b369e44598e0c5a0497aed044",
"jsonrpc": "2.0",
"result": {
"createdAt": "2022-08-03T15:58:29.890989554Z",
"hash": "2kg8XtHv1t5e5soBBFTGehn32sUwuqDmzyJjBtCg5K6q",
"network": "Regtest",
"pubkey": "tpubD6NzVbkrYhZ4WgTtjp7GR15TdZ35AUBAuxi8rxYTNTsLGf3j9AGYZrjwbLH5xDsJr3RE4vXxFK44fkRyA3UUBGRRDhYfagAu3vsntG9DTAb",
"ticker": "BTC",
"walletType": "Hot"
}
}
Great job taking financial independence! We now have a MoonRamp managed BTC wallet to accept payments. As mentioned in the Master Key Encryption Key section this wallets mnemoic code is stored with several layers of encryption. Mnemic codes are exportable and only the operator of the MoonRamp server has access to this information.
Impl Details
Bitcoin
MoonRamp uses the following libaries for bitcoin and bitcoin cash support
Monero
TODO
Ethereum
TODO
Moonrampctl (Sale)
Now it's time to create an invoice and get paid! WALLET_HASH
is the hash
field returned from the json blob of the moonrampctl wallet create
command in the previous section.
docker exec moonramp moonrampctl -a API_TOKEN sale invoice -H WALLET_HASH -c btc -a 0.25
You should see something like
{
"id": "c8ad22f454764bd7807c967353034d27",
"jsonrpc": "2.0",
"result": {
"address": "bcrt1qhe8apwuv2dsr95yknu826qad3cdxvs323ygc80",
"amount": 0.25,
"createdAt": "2022-08-03T20:49:52.483993Z",
"currency": "BTC",
"expiresAt": "2022-08-03T21:04:52.483994Z",
"hash": "HhfxubuY8e36GQNhQVBMuEzTWMZcpfA7nzC12REuNf7e",
"invoiceStatus": "Pending",
"network": "Regtest",
"pubkey": "tpubDCPc8xDGjqgqgW63nqsFiSTsJR8RRBjV4Npb5j3fMfu3Y9uTXB8AmbQpYKLNQGpGeJHmn6VYNHFoGpu76GT3JfabcJyaidsKNG2yq2PwvMH",
"ticker": "BTC",
"updatedAt": "2022-08-03T20:49:52.483994Z",
"uri": "bitcoin:bcrt1qhe8apwuv2dsr95yknu826qad3cdxvs323ygc80;version=1.0&amount=0.25",
"userData": null,
"walletHash": "BvY3SinZbHkbnG1azbR8NcxzX88kVyc8TDzNxYa9TKbB"
}
}
You have just created an invoice that expects payment of 0.25 btc
to the wallet BvY3SinZbHkbnG1azbR8NcxzX88kVyc8TDzNxYa9TKbB
at the address bcrt1qhe8apwuv2dsr95yknu826qad3cdxvs323ygc80
within 15 minutes
.
The fields address
and uri
are of particular note. address
is a unique one-time address to receive payment. For Bitcoin, each call to generate a new invoice will generate a new address for a given wallet. The uri
field is data that can be handled by a mobile OS url handler (iOS, Android). Most wallets support these type of uris when scanned as a QR code.
Details About MoonRamp's Modeling
MoonRamp models payments as four objects.
An Invoice
, Sale
, Refund
, and Credit
.
Invoice
An Invoice
is a request to receive payment within a specific window of time for a specific amount to a specific address.
Example: A merchant has a good or service they wish to collect payment for.
Sale
A Sale
is a "capture" of an invoice that has been successfully funded in full.
Example: A customer has fully funded an invoice and expects a good or service in return.
Refund
A Refund
is a partial or full repayment of a specifc Sale
to a specific address.
Example: A customer wishes to return a good in exchange for their original payment.
Credit
A Credit
is a repayment for a specific Invoice
that was only partially funded to a specific address.
Example: A customer only partially funded an invoice and should have their funds sent back.
Transfers
A Refund
and Credit
will make use of a Transfer
which is a transaction from a specific wallet to a specific address. API tokens that have access to the wallet transfer API should be treated with extreme care.
Example: A merchant wants to send funds from a hot wallet to an address.