diff --git a/.gitignore b/.gitignore index 33fae2a..663e560 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ node_modules/ .env docker-compose.override.yml build/ +wallet/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29..0000000 diff --git a/README.md b/README.md index 2205f61..e332232 100644 --- a/README.md +++ b/README.md @@ -51,3 +51,27 @@ cp sample.env .env Configure `.env` and `docker-compose.override.yml` according to your setup (they are commmented). Docker is not required; you can also run `npm run start` to run a server on port 80. You will need to run a wallet-rpc service too. + +### Wallet + +Pago should be used with a viewonly wallet. If you already have a monero wallet, you can create a view only version of it for use with pago. + +If you don't have one, create one on a secure computer. Back up the seed phrase offline and set a good password. + +Now take your wallet and go to "show keys" in the GUI or run the respective cli command. You will need 3 things: + + 1. Primary address (starts with a 4...) + 2. Private View Key (sometimes just called view key) + 3. Restore height (optional, recommended) + +Put all this information in the `.env` file and create a password, `WALLET_PASSWORD` for use with this wallet file. + +If this is your first time running pago, a viewonly wallet file will be created in `wallet/`. Pago doesn't use a database; all its payment history data are stored in this wallet file. Be sure to back up this directory as you would back up a database and remember its password. + +You can restore a wallet from a previous pago instance. Simply drop your existing `mywallet` and `mywallet.keys` files into `wallet/`. Be sure to set `WALLET_NAME=mywallet` and `WALLET_PASSWORD=...` in .env to match it. + +The `wallet/` dir and its contents should be owned by uid 101: + +```sh +sudo chown -R 101:101 wallet/ +``` diff --git a/daemon.dockerfile b/daemon.dockerfile new file mode 100644 index 0000000..e85bbcf --- /dev/null +++ b/daemon.dockerfile @@ -0,0 +1,60 @@ +# Multistage docker build, requires docker 17.05 + +# builder stage +FROM ubuntu:20.04 as builder + +RUN set -ex && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --yes install \ + automake \ + autotools-dev \ + bsdmainutils \ + build-essential \ + ca-certificates \ + ccache \ + cmake \ + curl \ + git \ + libtool \ + pkg-config \ + gperf + +RUN git clone https://gitea.gf4.pw/gf4/monero.git \ + /usr/local/src/monero +WORKDIR /usr/local/src/monero + +ARG NPROC +RUN set -ex && \ + git submodule init && git submodule update && \ + rm -rf build && \ + if [ -z "$NPROC" ] ; \ + then make -j$(nproc) depends target=x86_64-linux-gnu ; \ + else make -j$NPROC depends target=x86_64-linux-gnu ; \ + fi + +# runtime stage +FROM ubuntu:20.04 + +RUN set -ex && \ + apt-get update && \ + apt-get --no-install-recommends --yes install ca-certificates && \ + apt-get clean && \ + rm -rf /var/lib/apt +COPY --from=builder /usr/local/src/monero/build/x86_64-linux-gnu/release/bin /usr/local/bin/ + +# Create monero user +RUN adduser --system --group --disabled-password monero && \ + mkdir -p /home/monero/.bitmonero && \ + chown -R monero:monero /home/monero/.bitmonero + +# Contains the blockchain +VOLUME /home/monero/.bitmonero + +EXPOSE 18080 +EXPOSE 18081 + +# switch to user monero +USER monero + +ENTRYPOINT ["monerod"] +CMD ["--p2p-bind-ip=0.0.0.0", "--p2p-bind-port=18080", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18081", "--non-interactive", "--confirm-external-bind"] diff --git a/docker-compose.override.sample.yml b/docker-compose.override.sample.yml index f23437c..cbbc59c 100644 --- a/docker-compose.override.sample.yml +++ b/docker-compose.override.sample.yml @@ -1,5 +1,5 @@ -# Change network names and IP ranges -# Be sure to change networks: in services below too +# Optionally choose a set ip range for docker IPs +# Be sure to uncomment/change the networks section in the services below too #networks: # monero: # name: monero @@ -16,7 +16,7 @@ services: monerod: container_name: monerod - # Uncomment these lines to start a monerod node + # Comment these lines to start a monerod node # Warning: This will download the blockchain! profiles: - donotstart @@ -28,36 +28,35 @@ services: - "/var/lib/monero:/home/monero/.bitmonero:rw" # Leave this line to enable hugepages - "/dev/hugepages:/dev/hugepages:rw" - networks: - monero: - # This is the docker IP where monerod runs - ipv4_address: 172.21.0.1 +# networks: +# monero: +# ipv4_address: 172.21.0.1 smtp: container_name: smtp # Uncomment this if you already have a dockerized smtp server # profiles: # - donotstart - networks: - monero: - # Docker IP where the SMTP server will run - ipv4_address: 172.20.0.1 +# networks: +# monero: +# ipv4_address: 172.20.0.1 wallet: container_name: pago_wallet - networks: - monero: - # Docker IP where the wallet rpc will run - ipv4_address: 172.21.0.2 + volumes: + # You can keep your wallet somewhere other than ./wallet + - ./wallet:/wallet +# networks: +# monero: +# ipv4_address: 172.21.0.2 processor: container_name: pago_api - networks: - # Pago's dockerized IPs - monero: - ipv4_address: 172.21.0.10 - mail: - ipv4_address: 172.20.0.2 +# networks: +# monero: +# ipv4_address: 172.21.0.10 +# mail: +# ipv4_address: 172.20.0.2 # Uncomment these lines to listen on 0.0.0.0:8080 - #ports: - # - "8080:80/tcp" +# ports: +# - "8080:80/tcp" diff --git a/docker-compose.yml b/docker-compose.yml index 81c64a0..0668e93 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,23 +1,15 @@ networks: monero: name: monero - ipam: - config: - - subnet: "172.21.0.0/24" mail: name: mail - ipam: - config: - - subnet: "172.20.0.0/24" services: monerod: + container_name: monerod image: monero:latest build: - context: /usr/local/src/monero - args: - - MONERO_GIT_TAG=latest - container_name: monerod + dockerfile: daemon.dockerfile restart: unless-stopped volumes: - "/var/lib/monero:/home/monero/.bitmonero:rw" @@ -25,7 +17,6 @@ services: - "/dev/hugepages:/dev/hugepages:rw" networks: monero: - ipv4_address: 172.21.0.1 ports: - "18080:18080/tcp" environment: @@ -41,22 +32,26 @@ services: --rpc-bind-ip=0.0.0.0 --rpc-bind-port=18081 --confirm-external-bind - --limit-rate=1024 + --limit-rate=1024 wallet: container_name: pago_wallet - image: sethsimmons/simple-monero-wallet-rpc:latest + image: monero:latest + build: + dockerfile: wallet.dockerfile restart: unless-stopped volumes: - - /etc/pago/wallet:/home/monero/wallet - command: --wallet-file pago - --password-file wallet.passwd + - "./wallet:/wallet" + command: --wallet-dir /wallet + --non-interactive --disable-rpc-login - --rpc-bind-port=28081 - --daemon-address=${MONERO_DAEMON_URI} + --rpc-bind-ip=0.0.0.0 + --confirm-external-bind + --rpc-bind-port=18082 + --password ${WALLET_PASSWORD} + --daemon-host=${MONERO_DAEMON_HOST} networks: monero: - ipv4_address: 172.21.0.2 smtp: container_name: smtp @@ -73,7 +68,6 @@ services: - "SMTP_FROM=${MAIL_FROM}" networks: monero: - ipv4_address: 172.20.0.1 processor: container_name: pago_api @@ -82,6 +76,4 @@ services: command: start networks: monero: - ipv4_address: 172.21.0.10 mail: - ipv4_address: 172.20.0.2 diff --git a/package-lock.json b/package-lock.json index d2a5e7c..f48181f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,15 @@ "version": "1.0.0", "license": "MIT", "dependencies": { - "axios": "^1.6.8", "dotenv": "^16.4.5", "express": "^4.19.2", - "monero-ts": "^0.9.7", + "monero-wallet-rpc-js": "^1.2.5", "socket.io": "^4.7.5" }, "devDependencies": { "typescript": "^5.4.5" } }, - "node_modules/@babel/runtime": { - "version": "7.24.4", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.4.tgz", - "integrity": "sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==", - "dependencies": { - "regenerator-runtime": "^0.14.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@socket.io/component-emitter": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.1.tgz", @@ -68,68 +56,16 @@ "node": ">= 0.6" } }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, "node_modules/axios": { "version": "1.6.8", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", @@ -148,19 +84,6 @@ "node": "^4.5.0 || >= 5.9" } }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" - }, "node_modules/body-parser": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", @@ -210,11 +133,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -258,11 +176,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -275,22 +188,6 @@ "node": ">= 0.10" } }, - "node_modules/crypto-js": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz", - "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -351,15 +248,6 @@ "url": "https://dotenvx.com" } }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -503,29 +391,6 @@ "node": ">= 0.10.0" } }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, "node_modules/finalhandler": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", @@ -562,14 +427,6 @@ } } }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -625,14 +482,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, "node_modules/gopd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", @@ -644,27 +493,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/has-property-descriptors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", @@ -709,11 +537,6 @@ "node": ">= 0.4" } }, - "node_modules/html5-fs": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/html5-fs/-/html5-fs-0.1.1.tgz", - "integrity": "sha512-FqL7S02QEbAZ/xvp+BqurAolHvPQqOKPaWn1SsbP5fwpOLVcMGu12NPqr4mW5dRpdh2/UFbuxFDAhOw/LCDDvw==" - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -729,20 +552,6 @@ "node": ">= 0.8" } }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -767,55 +576,6 @@ "node": ">= 0.10" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -867,29 +627,12 @@ "node": ">= 0.6" } }, - "node_modules/monero-ts": { - "version": "0.9.7", - "resolved": "https://registry.npmjs.org/monero-ts/-/monero-ts-0.9.7.tgz", - "integrity": "sha512-YStuJuxS6MGNECIDqZYAztJcDTQZlYTfa9MSebNLhDBOoU9guMdphRwy/yhDd6DsYIaed6gflFMOq4hRuGA8Ow==", + "node_modules/monero-wallet-rpc-js": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/monero-wallet-rpc-js/-/monero-wallet-rpc-js-1.2.5.tgz", + "integrity": "sha512-AM7VUZIPURhVKUbeaSIagCtDY+7uNx+1++GO9TCylWxh2pbjIwhvJmkXGLBIDJ7mOiR4vhLFa3Ns/q9x/oerFQ==", "dependencies": { - "@babel/runtime": "^7.23.2", - "@types/node": "^20.6.0", - "ajv": "^6.12.6", - "async": "2.6.4", - "crypto-js": "^4.0.0", - "html5-fs": "0.1.1", - "net": "^1.0.2", - "promise-throttle": "^1.1.2", - "request": "^2.88.0", - "request-promise": "^4.2.6", - "serialize-javascript": "^3.1.0", - "text-encoding": "^0.7.0", - "tls": "0.0.1", - "uuid": "3.3.2", - "web-worker": "^1.3.0" - }, - "engines": { - "node": ">=10.0.0" + "axios": "^1.6.8" } }, "node_modules/ms": { @@ -905,19 +648,6 @@ "node": ">= 0.6" } }, - "node_modules/net": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", - "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -958,16 +688,6 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/promise-throttle": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/promise-throttle/-/promise-throttle-1.1.2.tgz", - "integrity": "sha512-dij7vjyXNewuuN/gyr+TX2KRjw48mbV5FEtgyXaIoJjGYAKT0au23/voNvy9eS4UNJjx2KUdEcO5Yyfc1h7vWQ==" - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -985,19 +705,6 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -1012,14 +719,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1042,95 +741,6 @@ "node": ">= 0.8" } }, - "node_modules/regenerator-runtime": { - "version": "0.14.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", - "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request-promise": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz", - "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==", - "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142", - "dependencies": { - "bluebird": "^3.5.0", - "request-promise-core": "1.1.4", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request-promise-core": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz", - "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==", - "dependencies": { - "lodash": "^4.17.19" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "request": "^2.34" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -1183,14 +793,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, - "node_modules/serialize-javascript": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", - "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", - "dependencies": { - "randombytes": "^2.1.0" - } - }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -1344,30 +946,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "node_modules/sshpk": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", - "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -1376,25 +954,6 @@ "node": ">= 0.8" } }, - "node_modules/stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/text-encoding": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.7.0.tgz", - "integrity": "sha512-oJQ3f1hrOnbRLOcwKz0Liq2IcrvDeZRHXhd9RgLrsT+DjWY/nty1Hi7v3dtkaEYbPYe0mUoOfzRrMwfXXwgPUA==", - "deprecated": "no longer maintained" - }, - "node_modules/tls": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tls/-/tls-0.0.1.tgz", - "integrity": "sha512-GzHpG+hwupY8VMR6rYsnAhTHqT/97zT45PG8WD5eTT1lq+dFE0nN+1PYpsoBcHJgSmTz5ceK2Cv88IkPmIPOtQ==" - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -1403,34 +962,6 @@ "node": ">=0.6" } }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -1469,14 +1000,6 @@ "node": ">= 0.8" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", @@ -1485,15 +1008,6 @@ "node": ">= 0.4.0" } }, - "node_modules/uuid": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -1502,24 +1016,6 @@ "node": ">= 0.8" } }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/web-worker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz", - "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==" - }, "node_modules/ws": { "version": "8.11.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", diff --git a/package.json b/package.json index d604af1..6a92b37 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { "name": "pago", - "version": "1.0.0", + "version": "1.1.0", "description": "Lightweight monero payment gateway", "main": "index.js", "scripts": { "build": "tsc", - "start": "node './build/main.js'" + "start": "node --no-experimental-fetch './build/main.js'" }, "repository": { "type": "git", @@ -17,10 +17,9 @@ "author": "Keith Irwin (www.ki9.us)", "license": "MIT", "dependencies": { - "axios": "^1.6.8", "dotenv": "^16.4.5", "express": "^4.19.2", - "monero-ts": "^0.9.7", + "monero-wallet-rpc-js": "^1.2.5", "socket.io": "^4.7.5" }, "devDependencies": { diff --git a/sample.env b/sample.env index abc444b..ed3d87a 100644 --- a/sample.env +++ b/sample.env @@ -7,15 +7,34 @@ TIMEZONE='UTC' ## Email ## MAIL_DOMAIN='example.com' MAIL_FROM='noreply@example.com' -# Change this if you changed the IP in docker-compose.override.yml -MAIL_HOST='172.20.0.1' +# Currently this is set to the smtp container in docker-compose +MAIL_HOST='smtp' # https://nodemailer.com/smtp/ -MAIL_URI='smtp://smtp:2500' +MAIL_URI="smtp://${MAIL_HOST}:2500" ## Monero ## +# Wallet filename +WALLET_FILENAME='pago' +# Wallet password (Change this!) +WALLET_PASSWORD='6vzyEYNW0uGPuIx' +# Main wallet address (Change this!) +WALLET_ADDRESS='55bcxMRhBWea6xxsot8moF1rdPprjJR2x4mfnNnTGgBJFgXa4gWXmWAYdUBKiRcJxy9AUAGJEg28DejvWdJU2VgUDrUvCHG' +# Viewkey used for the wallet (Change this!) +WALLET_VIEWKEY='03d463f03ae547b11dfdf194a07ff82c14a3c6a3de559bd89c9a5e8dc5e9ae02' +# Set this to the blockheight of first transaction +WALLET_RESTORE_HEIGHT=573936 # Which wallet account to use for payments WALLET_ACCOUNT_INDEX=1 +# Wallet RPC +WALLET_RPC_URI='http://pago_wallet:18082' +# Interval to rescan for transactions +WALLET_REFRESH_SEC=1 +# Interval to save wallet +# Disable autosave with 0 +WALLET_REFRESH_SEC=10 # Public remote node +# Find one on https://monero.fail/ +MONERO_DAEMON_HOST='xmr.gf4.pw:443' MONERO_DAEMON_URI='https://xmr.gf4.pw' # Local monero daemon (activate in docker-compose.override.yml) -#MONERO_DAEMON_URI='http://172.21.0.1' +#MONERO_DAEMON_URI='http://monerod' diff --git a/src/main.ts b/src/main.ts index 1646e7b..04f26e4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,23 +1,68 @@ -// Imports import dotenv from 'dotenv' import express, { Express, Request, Response } from 'express' -import monero from 'monero-ts' - +import Wallet from 'monero-wallet-rpc-js' (async () => { - // Config dotenv.config() - // Monero - let monerod = await monero.connectToDaemonRpc(process.env.MONERO_DAEMON_URI) + // Load monero wallet + let wallet; try { + wallet = await new Wallet({ + url: process.env.WALLET_RPC_URI, + filename: process.env.WALLET_FILENAME, + password: process.env.WALLET_PASSWORD, + address: process.env.WALLET_ADDRESS, + viewKey: process.env.WALLET_VIEWKEY, + restoreHeight: process.env.WALLET_RESTORE_HEIGHT, + }) + } catch (err) { + console.error(`Failed to open wallet: ${err}`) + } + + // Set auto save + if (Number(process.env.WALLET_AUTOSAVE_SEC) > 0) + setInterval( + wallet.store(), + Number(process.env.WALLET_AUTOSAVE_SEC) + ) + + // Set auto refresh + try { + await wallet.rpc('auto_refresh', { + enable: true, + period: Number(process.env.WALLET_REFRESH_SEC), + }) + } catch (err) { + console.error(`Failed to set auto_refresh to ${process.env.WALLET_REFRESH_SEC}: ${err}`) + } + + try { + console.log(`Wallet height: ${await wallet.getHeight()}`) + } catch (err) { + console.error(`Failed to get blockchain height: ${err}`) + } // Server const app: Express = express() + app.use(express.json()) app.listen(80) - // Get blockchain height - app.get('/daemon/height', async (req: Request, res: Response) => - res.send((await monerod.getHeight()).toString()) + + // Healthchecks + app.get('/wallet/height', async (req: Request, res: Response) => + res.send((await wallet.getHeight()).toString()) + ) + app.get('/wallet/balance', async (req: Request, res: Response) => + res.send( + ((await wallet.getBalance()).balance * 0.000000000001) + .toString() + ) ) + // New payment + //app.post('/payment', async (req: Request, res: Response) => { + // console.log(`New payment created: "${req.body.label}"`) + // return res.sendStatus(200) + //}) + })() diff --git a/wallet.dockerfile b/wallet.dockerfile new file mode 100644 index 0000000..9e4992e --- /dev/null +++ b/wallet.dockerfile @@ -0,0 +1,57 @@ +# Multistage docker build, requires docker 17.05 + +# builder stage +FROM ubuntu:20.04 as builder + +RUN set -ex && \ + apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get --no-install-recommends --yes install \ + automake \ + autotools-dev \ + bsdmainutils \ + build-essential \ + ca-certificates \ + ccache \ + cmake \ + curl \ + git \ + libtool \ + pkg-config \ + gperf + +RUN git clone https://gitea.gf4.pw/gf4/monero.git \ + /usr/local/src/monero +WORKDIR /usr/local/src/monero + +ARG NPROC +RUN set -ex && \ + git submodule init && git submodule update && \ + rm -rf build && \ + if [ -z "$NPROC" ] ; \ + then make -j$(nproc) depends target=x86_64-linux-gnu ; \ + else make -j$NPROC depends target=x86_64-linux-gnu ; \ + fi + +# runtime stage +FROM ubuntu:20.04 + +RUN set -ex && \ + apt-get update && \ + apt-get --no-install-recommends --yes install ca-certificates && \ + apt-get clean && \ + rm -rf /var/lib/apt +COPY --from=builder /usr/local/src/monero/build/x86_64-linux-gnu/release/bin /usr/local/bin/ + +# Create monero user +RUN adduser --system --group --disabled-password monero && \ + mkdir -p /wallet && \ + chown -R monero:monero /wallet + +VOLUME /wallet +EXPOSE 18082 + +# switch to user monero +USER monero + +ENTRYPOINT ["monero-wallet-rpc"] +CMD ["--disable-rpc-login", "--rpc-bind-ip=0.0.0.0", "--rpc-bind-port=18082", "--non-interactive", "--confirm-external-bind"]