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.

Moonramp Rust Docs

Installation

Release CI Github Release Docker Image

Choose an Install Method

Docker

Docker Image

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

Github Release

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

Install 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

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
1

MoonRamp will support Master Key Encryption Key rotation

2

MoonRamp will support Key Encryption Key rotation

3

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.

Programs