Skip to content

Commit

Permalink
Add monero support (#61)
Browse files Browse the repository at this point in the history
* base setup for monero

* update config for monero dep

* try different port

* get monero config working and add migration

* add dependency config checks for monero

* fix version and migrations

* fix nginx upload limit and misc

* add monero wallet rpc

* todo note

* Feat/monero (for comparison) (#67)

* monero-wallet-rpc service

* Fix s6 services dependencies

* fixup, tidyup things

* Fixup permissions for monero-wallet-rpc

* Final touchups I think

* Final arrangements#git commit -S -m Final

* Final touchups\! (minus the final, final ones\!)

* update config to handle multiple altcoin options

* fix check

* whoops typo

---------

Co-authored-by: Lucy Cifferello <[email protected]>

* update instructions

* fix bug with saving monero node creds to template

* Fixup final(?) monerod/monero-wallet-rpc settings

* Move disable-rpc-login to .conf file

* Fixup monero-wallet-rpc awaiting wallet files

* Adjust sleep time to something more reasonable, comments phrasing

* rework to read monero rpc creds from monero's config

* fixes for wallet rpc and update version

* remove redundant flag

* fix build

* adjust migrations

* update instructions

* rework wallet rpc config for fresh setups

* update to upstream 2.0.3

---------

Co-authored-by: gStart9 <[email protected]>
Co-authored-by: gStart9 <[email protected]>
  • Loading branch information
3 people authored Nov 25, 2024
1 parent 86b2d94 commit 09ff6d6
Showing 22 changed files with 496 additions and 114 deletions.
43 changes: 28 additions & 15 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM nicolasdorier/nbxplorer:2.5.9 AS nbx-builder
FROM btcpayserver/monero:0.18.3.4 AS monero-wallet-rpc
FROM nicolasdorier/nbxplorer:2.5.12 AS nbx-builder

FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:8.0-bookworm-slim AS actions-builder
ARG TARGETARCH
@@ -8,24 +9,31 @@ RUN dotnet restore "utils/actions/actions.csproj" -a $TARGETARCH
WORKDIR "/actions"
RUN dotnet build "utils/actions/actions.csproj" -c Release -a $TARGETARCH -o /actions/build

FROM btcpayserver/btcpayserver:2.0.0
FROM btcpayserver/btcpayserver:2.0.3-altcoins

COPY --from=nbx-builder "/app" /nbxplorer
COPY --from=actions-builder "/actions/build" /actions
COPY --from=monero-wallet-rpc "/usr/local/bin/monero-wallet-rpc" /usr/local/bin/

# arm64 or amd64
ARG PLATFORM
# aarch64 or x86_64
ARG ARCH

# install package dependencies
RUN apt-get update && \
apt-get install -y sqlite3 libsqlite3-0 curl locales jq bc wget procps postgresql-common xz-utils nginx vim && \
curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc && \
sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \
apt-get update && apt-get install -y postgresql-13 && \
wget https://github.com/mikefarah/yq/releases/download/v4.6.3/yq_linux_${PLATFORM}.tar.gz -O - |\
tar xz && mv yq_linux_${PLATFORM} /usr/bin/yq
RUN sed -i "s|http://|https://|g" /etc/apt/sources.list.d/debian.sources
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y sqlite3 libsqlite3-0 curl locales jq bc wget procps xz-utils nginx vim \
&& mkdir -p /usr/share/postgresql-common/pgdg \
&& curl -so /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc \
&& sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt bookworm-pgdg main" > /etc/apt/sources.list.d/pgdg.list' \
&& apt-get update && apt-get install -y postgresql-13 \
&& wget https://github.com/mikefarah/yq/releases/download/v4.6.3/yq_linux_${PLATFORM}.tar.gz -O - |\
tar xz && mv yq_linux_${PLATFORM} /usr/bin/yq \
&& apt-get -y autoremove \
&& apt-get clean autoclean \
&& rm -rf /var/lib/apt/lists/*

# install S6 overlay for proces mgmt
# https://github.com/just-containers/s6-overlay
@@ -61,13 +69,16 @@ ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
BTCPAY_PLUGINDIR=/datadir/plugins

# postgres setup
RUN groupadd -r postgres --gid=999; \
useradd -r -g postgres --gid=999 --home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \
mkdir -p /var/lib/postgresql; \
#RUN useradd -r -g postgres --home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \
RUN mkdir -p /var/lib/postgresql; \
chown -R postgres:postgres /var/lib/postgresql; \
mkdir -p /var/run/postgresql; \
chown -R postgres:postgres /var/run/postgresql; \
chmod 2777 /var/run/postgresql;
chmod 2770 /var/run/postgresql;

# monero setup
RUN groupadd -r monero --gid=302340; \
useradd -r -g monero --uid=30236 --gid=302340 -M --home-dir=/dev/null --shell=/sbin/nologin monero

# project specific postgres env vars
ENV POSTGRES_HOST_AUTH_METHOD=trust \
@@ -79,11 +90,13 @@ ENV POSTGRES_HOST_AUTH_METHOD=trust \
ADD ./configurator/target/${ARCH}-unknown-linux-musl/release/configurator /usr/local/bin/configurator
COPY utils/scripts/btcpay-admin.sh /usr/local/bin/btcpay-admin.sh
COPY utils/scripts/health_check.sh /usr/local/bin/health_check.sh
COPY utils/nginx.conf /etc/nginx/sites-available/default
COPY utils/config/nginx.conf /etc/nginx/sites-available/default
COPY utils/config/monero-wallet-rpc.btcpayserver.conf.template /etc/
COPY utils/scripts/postgres-init.sh /etc/s6-overlay/script/postgres-init
COPY utils/scripts/postgres-ready.sh /etc/s6-overlay/script/postgres-ready
COPY utils/scripts/postgres-shutdown.sh /etc/cont-finish.d/postgres-shutdown
RUN chmod a+x /usr/local/bin/btcpay-admin.sh /usr/local/bin/health_check.sh /etc/s6-overlay/script/* /etc/cont-finish.d/*
COPY utils/scripts/notifier.sh /usr/local/bin/notifier.sh
RUN chmod a+x /usr/local/bin/btcpay-admin.sh /usr/local/bin/health_check.sh /etc/s6-overlay/script/* /etc/cont-finish.d/* /usr/local/bin/notifier.sh

# s6-overlay initialization
ENTRYPOINT ["/init"]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ verify: $(PKG_ID).s9pk
@echo " Done!"
@echo " Filesize: $(shell du -h $(PKG_ID).s9pk) is ready"

install:
install: $(PKG_ID).s9pk
ifeq (,$(wildcard ~/.embassy/config.yaml))
@echo; echo "You must define \"host: http://server-name.local\" in ~/.embassy/config.yaml config file first"; echo
else
86 changes: 82 additions & 4 deletions configurator/src/main.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,27 @@ struct Config {
lightning: LightningConfig,
bitcoin_rpc_user: String,
bitcoin_rpc_password: String,
altcoins: AltcoinConfig,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct MoneroStart9Config {
rpc: MoneroRpcCredentials,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct MoneroRpcCredentials {
rpc_credentials: MoneroRpcCredentialValues,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct MoneroRpcCredentialValues {
enabled: Status,
password: Option<String>,
username: Option<String>,
}

#[derive(serde::Deserialize)]
@@ -26,6 +47,28 @@ enum LightningConfig {
#[serde(rename_all = "kebab-case")]
CLightning,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
enum Status {
#[serde(rename_all = "lowercase")]
Enabled,
#[serde(rename_all = "lowercase")]
Disabled,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct MoneroConfig {
status: Status,
}

#[derive(serde::Deserialize)]
#[serde(rename_all = "kebab-case")]
struct AltcoinConfig {
monero: MoneroConfig,
}

#[derive(serde::Serialize)]
pub struct Property<T> {
#[serde(rename = "type")]
@@ -43,6 +86,10 @@ fn main() -> Result<(), anyhow::Error> {
let config: Config = serde_yaml::from_reader(
File::open("/datadir/start9/config.yaml").with_context(|| "/datadir/start9/config.yaml")?,
)?;
let monero_config: MoneroStart9Config = serde_yaml::from_reader(
File::open("/mnt/monerod/start9/config.yaml")
.with_context(|| "/mnt/monerod/start9/config.yaml")?,
)?;
let tor_address = config.tor_address;
let mut nbx_config = File::create("/datadir/nbxplorer/Main/settings.config")
.with_context(|| "/datadir/nbxplorer/mainnet/settings.config")?;
@@ -60,10 +107,41 @@ fn main() -> Result<(), anyhow::Error> {
p2p_host = bitcoin_host,
p2p_port = 8333
)?;
write!(
btcpay_config,
include_str!("templates/settings-btcpay.config.template"),
)?;

match config.altcoins.monero.status {
Status::Enabled => {
match monero_config.rpc.rpc_credentials.enabled {
Status::Enabled => {
write!(
btcpay_config,
include_str!("templates/settings-btcpay.config.template"),
monero_username = &monero_config.rpc.rpc_credentials.username.unwrap(),
monero_password = &monero_config.rpc.rpc_credentials.password.unwrap(),
chains = "btc,xmr"
)?;
}
Status::Disabled => {
write!(
btcpay_config,
include_str!("templates/settings-btcpay.config.template"),
monero_username = "",
monero_password = "",
chains = "btc,xmr"
)?;
}
}
println!("{}", format!("export BTCPAYGEN_CRYPTO2='xmr'\n"));
}
Status::Disabled => {
write!(
btcpay_config,
include_str!("templates/settings-btcpay.config.template"),
monero_username = "",
monero_password = "",
chains = "btc"
)?;
}
}

let addr = tor_address.split('.').collect::<Vec<&str>>();
match addr.first() {
11 changes: 10 additions & 1 deletion configurator/src/templates/settings-btcpay.config.template
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Global settings ###
network=mainnet
chains={chains}

### Server settings ###
port=23000
@@ -16,4 +17,12 @@ sqlitefile=sqlite.db
#BTC.explorer.url=http://127.0.0.1:24444/
BTC.explorer.cookiefile=/datadir/nbxplorer/Main/.cookie
#BTC.lightning=/root/.lightning/lightning-rpc
#BTC.lightning=https://apitoken:[email protected]/
#BTC.lightning=https://apitoken:[email protected]/

### Monero settings ###
XMR_daemon_uri=http://monerod.embassy:18089
XMR_wallet_daemon_uri=http://127.0.0.1:18082
XMR_wallet_daemon_walletdir=/datadir/btcpayserver/altcoins/monero/wallets
# Only use username and password if Monero daemon's RPC is password protected
XMR_daemon_username={monero_username}
XMR_daemon_password={monero_password}
23 changes: 23 additions & 0 deletions docs/instructions.md
Original file line number Diff line number Diff line change
@@ -62,6 +62,29 @@ Next, **enable lightning** for a particular store's wallet using the connection

If you would like to connect to an external lightning node, select "Use custom node" when on the page above and follow the instructions.

## Enabling Altcoins

In config, find `Altcoin Integrations` and set the desired altcoin implemtation to "Enabled".

### Monero

This service can be installed on your server from the Community Marketplace and enabled in config by setting `Altcoin Integrations > Monero` to "Enabled". You will need a fully synced Monero node for operations to work properly.

#### Wallet

Enabling Monero requires a manual wallet setup. Fortunately, the community has put together some great guides to do so:

- [SethForPrivacy Guide](https://sethforprivacy.com/guides/accepting-monero-via-btcpay-server/#setup-your-bitcoin-and-monero-wallets)
- [Freedom Node Guide](https://freedomnode.com/blog/howto-accept-monero-for-your-services-btcpayserver/#create-a-view-only-monero-wallet-with-feather)

Using these guides, setup a Feather wallet (recommended), then proceed to upload the wallet to BTCPay Server for your store by opening the store settings and finding the "Monero" tab across the top menu bar. The Monero node will need to be fully synced before it is available to use in BTCPay Server.

If you are unable to open Feather on macOS, go to System Settings > Privacy & Security and scroll to find where "Feather" was blocked becuase it is not from an identified developer > "Open Anyway" > Enter password > Select "Open" regardless of security warning.

#### RPC

If you enable / disable RPC credentials in Monero, you will need to restart BTC Pay Server to pick up this change.

## Setting up BTCPayServer Vault

BTCPayServer Vault supports hardware wallet integrations for stores. To use, you must [install Vault](https://github.com/btcpayserver/BTCPayServer.Vault/releases) and run it on a laptop/desktop machine. Then, access your BTCPay Server service in a browser on the same device.
24 changes: 22 additions & 2 deletions manifest.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
id: btcpayserver
title: BTCPay Server
version: 2.0.0
version: 2.0.3
release-notes: |
* Major upstream release of [v2.0.0](https://github.com/btcpayserver/btcpayserver/releases/tag/v2.0.0)! This release introduces many new features and some breaking changes. Please see the [blog post](https://blog.btcpayserver.org/btcpay-server-2-0/) for more details.
* Updates to the latest upstream [release](https://github.com/btcpayserver/btcpayserver/releases/tag/v2.0.3)
* Includes major upstream release of [v2.0.0](https://github.com/btcpayserver/btcpayserver/releases/tag/v2.0.0)! This release introduces many new features and some breaking changes. Please see the [blog post](https://blog.btcpayserver.org/btcpay-server-2-0/) for more details.
* Please note: large instances may experience a few minutes of database migration.
* Adds optional Monero integration for payment processing
license: mit
wrapper-repo: "https://github.com/Start9Labs/btcpayserver-wrapper"
upstream-repo: "https://github.com/btcpayserver/btcpayserver"
@@ -29,6 +31,7 @@ main:
mounts:
lnd: /mnt/lnd
c-lightning: "/mnt/c-lightning"
monerod: "/mnt/monerod"
main: /datadir
health-checks:
explorer-synced:
@@ -88,6 +91,17 @@ dependencies:
how: Optionally use Core Lightning for internal lightning network node implementation.
description: Used to communicate with the Lightning Network.
config: ~
monerod:
version: ">=0.18.3.2 <0.20.0"
requirement:
type: "opt-in"
how: Optionally use Monero.
description: Used as an alternative integration for payment processing.
config:
check:
type: script
auto-configure:
type: script
volumes:
main:
type: data
@@ -103,6 +117,12 @@ volumes:
volume-id: main
path: "/shared"
readonly: true
monerod:
type: pointer
package-id: monerod
volume-id: main
path: "/"
readonly: false
alerts:
install:
<p>BTCPay is a self hosted payment processing system. No third party exists to backup data. You are responsible for backups of all your information!</p>
34 changes: 34 additions & 0 deletions scripts/migrations/2_0_0_up_migration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { types as T, matches } from "../deps.ts";

const { shape, string } = matches;

export const migration_up_2_0_0 = (config: T.Config): T.Config => {
if (Object.keys(config).length === 0) {
// service was never configured
return config;
}

const altcoinsConfig = shape({
monero: shape({
status: string,
}),
});

const matchConfigWithAltcoins = shape({
altcoins: altcoinsConfig,
});

if (!matchConfigWithAltcoins.test(config)) {
const newAltcoinsConfig: typeof altcoinsConfig._TYPE = {
monero: {
status: "disabled",
},
};
return {
...config,
altcoins: newAltcoinsConfig,
};
} else {
return config;
}
};
Loading

0 comments on commit 09ff6d6

Please sign in to comment.