├── .gitignore ├── .gitmodules ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── alts ├── README.md ├── bots.yml ├── clightning-docker-compose.yml ├── cln-proxy.yml ├── navfiber.yml ├── no-alice.yml ├── no-dave-cln-proxy.yml ├── no-tribes.yml ├── proxy-no-dave.yml ├── proxy.yml └── v2.yml ├── aperture ├── aperture.yaml └── staticroot.json ├── bitcoind └── bitcoin.conf ├── boltwall ├── .env ├── .gitignore └── setup │ └── index.js ├── botSandBox ├── isEnvAvailible.js └── sphinx-ml-bot │ ├── .gitignore │ ├── package-lock.json │ ├── package.json │ ├── src │ └── index.ts │ └── tsconfig.json ├── cache └── .gitignore ├── clearall.sh ├── cln ├── .gitignore ├── btc1 │ └── .gitkeep ├── clear.sh ├── cln-vls.yml ├── cln.yml ├── cln1 │ └── .gitkeep ├── cln2 │ └── .gitkeep ├── dave-cln │ ├── cln_vol │ │ └── entrypoint.sh │ └── setup_script.sh ├── readme.md ├── setup.md ├── setup1.sh ├── setup2.sh └── vls.md ├── docker-compose.override.yml ├── docker-compose.yml ├── docs ├── bots.md ├── developingOnSphinx.md └── img │ ├── bots.png │ ├── newbot.png │ └── startup.png ├── init.sql ├── jitsi ├── .env ├── README.md ├── docker-compose.yml └── setup.sh ├── lnd └── setup │ ├── .gitignore │ ├── alice.conf │ ├── bitcoind.js │ ├── bob.conf │ ├── carol.conf │ ├── dave.conf │ ├── fetch.js │ ├── index.js │ ├── lightning.js │ ├── nodes.js │ ├── nodes │ ├── clnProxyNodes.js │ ├── nodes.js │ └── proxynodes.js │ └── wallet.js ├── memes └── .gitkeep ├── proxy └── lnd_proxy.conf ├── relay ├── alice-db.json ├── alice.json ├── bob-db.json ├── bob.json ├── botConfig.json ├── carol-db.json ├── carol.json ├── cln-dave.json ├── dave-db.json ├── dave.json ├── db │ └── .gitkeep ├── nodes_partial.json ├── nodes_partial │ ├── cln_proxy_nodes_partial.json │ ├── nodes_partial.json │ └── proxy_nodes_partial.json └── setup │ ├── fetch.js │ ├── index.js │ ├── paths.js │ ├── rncryptor.js │ ├── rsa.js │ ├── signup.js │ └── sjcl.js ├── start-bot.sh ├── tribes ├── script.sh └── setup │ └── index.js ├── utils ├── genkeys.js ├── viewkeys.js └── writeToEnv.js ├── v2 ├── fetch.js ├── paths.js └── setup.js └── zmq └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | notes.md 2 | .DS_Store 3 | relay/db/* 4 | relay/NODES.json 5 | relay/botEnvVars.json 6 | !relay/db/.gitkeep 7 | bitcoind/* 8 | !bitcoind/bitcoin.conf 9 | lnd/* 10 | !lnd/setup 11 | zmq/* 12 | !zmq/index.js 13 | memes/* 14 | !memes/.gitkeep 15 | pgdata 16 | proxy/*/* 17 | !proxy/*/.gitkeep 18 | redisData 19 | relay/aliceTransportPublicKey.pem 20 | relay/aliceTransportPrivateKey.pem 21 | relay/bobTransportPublicKey.pem 22 | relay/bobTransportPrivateKey.pem 23 | relay/carolTransportPublicKey.pem 24 | relay/carolTransportPrivateKey.pem 25 | admin 26 | cln-notes.md 27 | .idea/ 28 | alts/bitcoind 29 | jitsi/config/* 30 | .vscode 31 | neo4j 32 | neo4j/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "botSandBox/sphinx-example-bot"] 2 | path = botSandBox/sphinx-example-bot 3 | url = https://github.com/stakwork/sphinx-example-bot.git 4 | [submodule "botSandBox/sphinx-betting-bot"] 5 | path = botSandBox/sphinx-betting-bot 6 | url = https://github.com/stakwork/sphinx-betting-bot.git 7 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Stakwork & Sphinx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sphinx-stack 2 | 3 | Full stack Sphinx cluster, including: 4 | 5 | - bitcoind 6 | - LND 7 | - relay 8 | - sphinx-tribes 9 | - sphinx-memes 10 | - sphinx-auth 11 | - sphinx-mqtt 12 | 13 | ### run 14 | 15 | Open a terminal inside the root directory of this repository. Then: 16 | 17 | `docker-compose pull` 18 | 19 | `docker-compose up -d` 20 | 21 | ### stop 22 | 23 | `docker-compose down` 24 | 25 | Running `docker-compose down` instead of sending a SIGINT or SIGTERM is very important! Otherwise `bitcoind` will not finish writing to its database, and on the next run LND will crash with a block index mismatch. 26 | 27 | You can also run with `Docker Desktop` and just use the "play" and "stop" buttons (and view the logs from each container). 28 | 29 | ### clear 30 | 31 | Clear the existing configs, so you can start fresh: 32 | 33 | `./clearall.sh` 34 | 35 | ### aperture enabled paywall 36 | 37 | The sphinx-stack docker compose file uses profiles to opt-in to particular services. 38 | To run with an aperture-enabled paywall, start the stack with the 39 | following command: 40 | 41 | ```shell 42 | docker compose -f docker-compose.yml --profile aperture --project-directory . up -d 43 | ``` 44 | 45 | This will use the configs set in `/aperture/aperture.yaml`. 46 | To update the timeout and other paywall related configs, edit that file. 47 | 48 | ### developing/contributing to Sphinx 49 | 50 | - Run one of the sphinx clients on your local computer, and enter the `exported_keys` that you can find in `/relay/NODES.json` (make sure to copy the trailing `=` equal signs if there are any!) 51 | - the easiest client to get up and running is [Sphinx Desktop](https://github.com/stakwork/sphinx-win-linux-desktop) 52 | - To find out how to modify sphinx components and contribute to the stack vist [Developing/Contributing on Sphinx](https://github.com/stakwork/sphinx-stack/blob/master/docs/developingOnSphinx.md) 53 | 54 | - To find out how to develop bots on the sphinx stack visit [Developing bots on sphinx](https://github.com/stakwork/sphinx-stack/blob/master/docs/bots.md) 55 | 56 | ### troubleshooting 57 | 58 | There's lots of moving pieces! On a slower computer (or an M1 mac), do `export COMPOSE_HTTP_TIMEOUT=120` first 59 | -------------------------------------------------------------------------------- /alts/README.md: -------------------------------------------------------------------------------- 1 | # alternate clusters 2 | 3 | ### no alice relay 4 | 5 | Use this to develop on sphinx-relay 6 | 7 | ``` 8 | docker-compose -f ./alts/no-alice.yml --project-directory . up -d 9 | ``` 10 | 11 | Then in sphinx-relay: 12 | 13 | - find `testing/stack/alice.json`: 14 | - change `tls_location` to point back to the cert generated by stack 15 | - change `macaroon_location` to point back to the macaroon generated by stack 16 | - and `testing/stack/alice-db.json`: 17 | - change `storage` to point to alice's DB file generated by stack 18 | - then run: 19 | 20 | ``` 21 | *be sure to update the alice.json and alice-db.json files with your project dir and make sure to use the full path* 22 | node ./dist/app.js --config="testing/stack/alice.json" --db="testing/stack/alice-db.json" 23 | ``` 24 | 25 | ### no tribes server or frontend 26 | 27 | Use this to develop on sphinx tribes server and frontend 28 | 29 | ``` 30 | docker-compose -f ./alts/no-tribes.yml --project-directory . up -d 31 | 32 | Make a .env file in your sphinx-tribes with: 33 | ``` 34 | 35 | PORT=13000 36 | DATABASE_URL=postgres://postgres:sphinx@localhost:5433/postgres?sslmode=disable 37 | SKIP_LOOPS=true 38 | 39 | ``` 40 | 41 | ``` 42 | 43 | ### LSAT-based paywall 44 | 45 | To use [aperture](https://docs.lightning.engineering/the-lightning-network/lsat/aperture) 46 | as a way to protect certain endpoints in meme server using lightning enabled 47 | LSATs, you can use the alt `alts/lsat.yml` config with the normal base compose. 48 | By default the configuration assumes that alice's node will be used to generate 49 | invoices protecting endpoints. This (and other items) can be configured via another 50 | yaml file for the aperture configurations in `aperture/aperture.yaml` 51 | 52 | Some configs to look at for more customization: 53 | 54 | - `listenaddr` - for where the proxy is accessible from 55 | - `authenticator` - lightning node configurations including host and where credentials can be found 56 | - `services` - a list of services that will be protected by aperture. 57 | These have other options that can be used to customize the endpoint and protection conditions 58 | - `services.price` to change the price for access to meme server 59 | - `services.timeout` to change the relative expiration for lsats minted by aperture. 60 | To run sphinx stack with aperture: 61 | 62 | ``` 63 | docker compose -f docker-compose.yml -f ./alts/lsat.yml --project-directory . up -d 64 | ``` 65 | 66 | #### Local Development with Meme 67 | 68 | There is also a special service and profile in the main docker compose file 69 | that allows for running with a local development instance of a service. 70 | By commenting out one of the `depends_on` services listed in the `exclude-services` 71 | service, everything but that service or services will be run. 72 | 73 | Furthermore, by using `profiles` you can make services that will only run with that 74 | specific profile passed. For example, to run a local meme for developing against, 75 | comment out `meme` from the exclude-services list, and then run: 76 | 77 | ``` 78 | $ docker compose -f docker-compose.yml --profile aperture --project-directory . up exclude-services 79 | ``` 80 | 81 | Once your meme server is running and connected to the other services, everything should be working. 82 | 83 | ### no dave proxy relay 84 | 85 | ``` 86 | docker-compose -f ./alts/proxy-no-dave.yml --project-directory . up -d 87 | ``` 88 | -------------------------------------------------------------------------------- /alts/bots.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | exampleBot: 5 | image: node:16-buster-slim 6 | container_name: example-bot-sphinx 7 | restart: on-failure 8 | working_dir: "/example_bot" 9 | depends_on: 10 | - relaysetup 11 | command: 12 | - /bin/sh 13 | - -c 14 | - | 15 | npm install 16 | npm install -g nodemon 17 | node ./isEnvAvailible.js && nodemon src/index.ts 18 | volumes: 19 | - ./relay/botEnvVars.json:/example_bot/botEnvVars.json 20 | - ./botSandBox/isEnvAvailible.js:/example_bot/isEnvAvailible.js 21 | - ./botSandBox/sphinx-example-bot/src:/example_bot/src 22 | - ./botSandBox/sphinx-example-bot/tsconfig.json:/example_bot/tsconfig.json 23 | - ./botSandBox/sphinx-example-bot/package.json:/example_bot/package.json 24 | environment: 25 | - IS_SPHINX_STACK=true 26 | - CHOKIDAR_USEPOLLING=true 27 | - SPHINX_INDEX=0 28 | ports: 29 | - 3333:3333 30 | 31 | BetBot: 32 | image: node:12-buster-slim 33 | container_name: bet-bot-sphinx 34 | restart: on-failure 35 | working_dir: "/bet_bot" 36 | depends_on: 37 | - relaysetup 38 | command: 39 | - /bin/sh 40 | - -c 41 | - | 42 | npm install 43 | npm install -g nodemon 44 | npm install typescript@4.9.5 45 | node ./isEnvAvailible.js && nodemon --legacy-watch --watch "src/**" --ext "ts,json,js" --exec 'npm run build && npm run start' 46 | volumes: 47 | - ./relay/botEnvVars.json:/bet_bot/botEnvVars.json 48 | - ./botSandBox/isEnvAvailible.js:/bet_bot/isEnvAvailible.js 49 | - ./botSandBox/sphinx-betting-bot/src:/bet_bot/src 50 | - ./botSandBox/sphinx-betting-bot/package.json:/bet_bot/package.json 51 | - ./botSandBox/sphinx-betting-bot/tsconfig.json:/bet_bot/tsconfig.json 52 | - ./botSandBox/sphinx-betting-bot/webpack.config.json:/bet_bot/webpack.config.json 53 | environment: 54 | - IS_SPHINX_STACK=true 55 | - CHOKIDAR_USEPOLLING=true 56 | - SPHINX_INDEX=1 57 | - REDIS_URL=redis://db.bettingBot:6379 58 | - FLUSH_ALL=1 59 | ports: 60 | - 3334:3334 61 | 62 | redis: 63 | image: redis:alpine 64 | container_name: db.bettingBot 65 | command: redis-server --appendonly yes 66 | ports: 67 | - 6379:6379 68 | volumes: 69 | - ./redisData/data:/data 70 | restart: always 71 | environment: 72 | - REDIS_REPLICATION_MODE=master 73 | 74 | mlBotServer: 75 | image: node:16-buster-slim 76 | container_name: ml-bot-sphinx-server 77 | working_dir: "/ml_bot" 78 | command: 79 | - /bin/sh 80 | - -c 81 | - | 82 | npm install 83 | npm run dev 84 | volumes: 85 | - ./botSandBox/sphinx-ml-bot/package.json:/ml_bot/package.json 86 | - ./botSandBox/sphinx-ml-bot/src:/ml_bot/src 87 | - ./botSandBox/sphinx-ml-bot/tsconfig.json:/ml_bot/tsconfig.json 88 | ports: 89 | - 3500:3500 90 | -------------------------------------------------------------------------------- /alts/clightning-docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | services: 3 | bitcoind: 4 | image: ruimarinho/bitcoin-core:23.0 5 | command: 6 | -regtest=1 7 | -rpcallowip=0.0.0.0/0 8 | -rpcbind=0.0.0.0 9 | -rpcpassword=bar 10 | -rpcport=18443 11 | -rpcuser=foo 12 | -server 13 | ports: 14 | - 18443:18443 15 | 16 | lightningd: 17 | image: elementsproject/lightningd 18 | container_name: lightningd 19 | command: 20 | - --bitcoin-rpcconnect=bitcoind 21 | - --bitcoin-rpcport=18443 22 | - --bitcoin-rpcuser=foo 23 | - --bitcoin-rpcpassword=bar 24 | - --network=regtest 25 | - --log-level=debug 26 | - --alias=omoniyi24-cln 27 | environment: 28 | EXPOSE_TCP: "true" 29 | expose: 30 | - "9735" 31 | ports: 32 | - "0.0.0.0:9735:9735" 33 | links: 34 | - bitcoind -------------------------------------------------------------------------------- /alts/cln-proxy.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v25.0 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.16.2-beta 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.16.2-beta 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.16.2-beta 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | lndsetup: 53 | image: node:12-buster-slim 54 | depends_on: 55 | - alice-lnd 56 | - bob-lnd 57 | - carol-lnd 58 | - dave-cln 59 | restart: "no" 60 | entrypoint: ["node", "/lndsetup/index.js"] 61 | volumes: 62 | - ./lnd/alice/.lnd:/alice/.lnd 63 | - ./lnd/setup:/lndsetup 64 | - ./lnd/setup/nodes/proxynodes.js:/lndsetup/nodes.js 65 | environment: 66 | - CLN_PROXY=true 67 | 68 | db: 69 | image: postgres 70 | container_name: db.sphinx 71 | restart: on-failure 72 | environment: 73 | - POSTGRES_PASSWORD=sphinx 74 | - POSTGRES_USER=postgres 75 | volumes: 76 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 77 | - ./pgdata:/var/lib/postgresql/data 78 | ports: 79 | - 5433:5432 80 | 81 | tribes: 82 | image: sphinxlightning/sphinx-tribes:latest 83 | container_name: tribes.sphinx 84 | restart: on-failure 85 | depends_on: 86 | - db 87 | environment: 88 | - PORT=13000 89 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 90 | - LN_SERVER_BASE_URL=http://localhost:13000 91 | volumes: 92 | - ./tribes/script.sh:/app/script.sh 93 | ports: 94 | - 5002:5002 95 | - 13007:13007 96 | - 13000:13000 97 | entrypoint: 98 | - "sh" 99 | - "-c" 100 | - | 101 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 102 | 103 | auth: 104 | image: sphinxlightning/sphinx-auth:0.2.3 105 | container_name: auth.sphinx 106 | restart: on-failure 107 | depends_on: 108 | - db 109 | environment: 110 | - JWT_KEY=19e0bb49bhyuibme 111 | - HOST=localhost:9090 112 | ports: 113 | - 9090:9090 114 | 115 | mqtt: 116 | image: sphinxlightning/sphinx-mqtt:test-2 117 | container_name: mqtt.sphinx 118 | restart: on-failure 119 | depends_on: 120 | - auth 121 | ports: 122 | - 1883:1883 123 | 124 | meme: 125 | image: sphinxlightning/sphinx-meme:0.2.2 126 | container_name: meme.sphinx 127 | restart: on-failure 128 | depends_on: 129 | - db 130 | volumes: 131 | - ./memes:/app/files 132 | environment: 133 | - PORT=5555 134 | - JWT_KEY=19e0bb49bhyuibme 135 | - STORAGE_MODE=local 136 | - LOCAL_DIR=app/files 137 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 138 | - HOST=meme.sphinx:5555 139 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 140 | ports: 141 | - 5555:5555 142 | 143 | alice: 144 | image: sphinxlightning/sphinx-relay 145 | container_name: alice.sphinx 146 | user: root 147 | restart: on-failure 148 | depends_on: 149 | - alice-lnd 150 | entrypoint: 151 | [ 152 | "node", 153 | "/relay/dist/app.js", 154 | "--config=/relay/configs/alice.json", 155 | "--db=/relay/configs/alice-db.json", 156 | ] 157 | volumes: 158 | - ./relay:/relay/configs 159 | - ./lnd/alice/.lnd:/relay/alice/.lnd 160 | environment: 161 | - NODE_ENV=${GITACTION_ENV:-development} 162 | - PORT=3001 163 | - TRIBES_HOST=host.docker.internal:13000 164 | ports: 165 | - 3001:3001 166 | extra_hosts: 167 | - "host.docker.internal:host-gateway" 168 | 169 | bob: 170 | image: sphinxlightning/sphinx-relay 171 | container_name: bob.sphinx 172 | user: root 173 | restart: on-failure 174 | depends_on: 175 | - bob-lnd 176 | entrypoint: 177 | [ 178 | "node", 179 | "/relay/dist/app.js", 180 | "--config=/relay/configs/bob.json", 181 | "--db=/relay/configs/bob-db.json", 182 | ] 183 | volumes: 184 | - ./relay:/relay/configs 185 | - ./lnd/bob/.lnd:/relay/bob/.lnd 186 | environment: 187 | - NODE_ENV=${GITACTION_ENV:-development} 188 | - PORT=3002 189 | - TRIBES_HOST=host.docker.internal:13000 190 | ports: 191 | - 3002:3002 192 | extra_hosts: 193 | - "host.docker.internal:host-gateway" 194 | 195 | carol: 196 | image: sphinxlightning/sphinx-relay 197 | container_name: carol.sphinx 198 | user: root 199 | restart: on-failure 200 | depends_on: 201 | - carol-lnd 202 | entrypoint: 203 | [ 204 | "node", 205 | "/relay/dist/app.js", 206 | "--config=/relay/configs/carol.json", 207 | "--db=/relay/configs/carol-db.json", 208 | ] 209 | volumes: 210 | - ./relay:/relay/configs 211 | - ./lnd/carol/.lnd:/relay/carol/.lnd 212 | environment: 213 | - NODE_ENV=${GITACTION_ENV:-development} 214 | - PORT=3003 215 | - TRIBES_HOST=host.docker.internal:13000 216 | ports: 217 | - 3003:3003 218 | extra_hosts: 219 | - "host.docker.internal:host-gateway" 220 | 221 | dave: 222 | image: sphinxlightning/sphinx-relay 223 | container_name: dave.sphinx 224 | user: root 225 | restart: on-failure 226 | depends_on: 227 | - dave-cln 228 | - proxy 229 | entrypoint: 230 | [ 231 | "node", 232 | "/relay/dist/app.js", 233 | "--config=/relay/configs/cln-dave.json", 234 | "--db=/relay/configs/dave-db.json", 235 | ] 236 | volumes: 237 | - ./relay:/relay/configs 238 | - ./cln/dave-cln/regtest:/relay/dave/regtest 239 | - ./proxy:/proxy 240 | environment: 241 | - NODE_ENV=${GITACTION_ENV:-development} 242 | - PORT=3004 243 | - TRIBES_HOST=host.docker.internal:13000 244 | ports: 245 | - 3004:3004 246 | 247 | relaysetup: 248 | image: node:12-buster-slim 249 | depends_on: 250 | - alice 251 | - bob 252 | - carol 253 | - dave 254 | - lndsetup 255 | - tribes 256 | restart: on-failure 257 | entrypoint: ["node", "/relay/setup/index.js"] 258 | volumes: 259 | - ./relay:/relay 260 | - ./relay/nodes_partial/cln_proxy_nodes_partial.json:/relay/nodes_partial.json 261 | environment: 262 | - DAVE_IP=http://host.docker.internal:3004 263 | 264 | proxy: 265 | image: sphinxlightning/sphinx-proxy:latest 266 | container_name: proxy.sphinx 267 | restart: always 268 | user: root 269 | depends_on: 270 | - dave-cln 271 | volumes: 272 | - ./lnd/dave/.lnd:/lnd/.lnd 273 | - ./proxy/cert:/cert 274 | - ./proxy/macaroons:/macaroons 275 | - ./proxy/badger:/badger 276 | - ./cln/dave-cln/regtest:/cln/creds 277 | - type: bind 278 | source: ./proxy/lnd_proxy.conf 279 | target: /lnd_proxy.conf 280 | entrypoint: 281 | [ 282 | "/app/sphinx-proxy", 283 | "--rpclisten=0.0.0.0:11111", 284 | "--tlscertpath=/cert/tls.cert", 285 | "--tlskeypath=/cert/tls.key", 286 | "--bitcoin.regtest", 287 | "--bitcoin.active", 288 | "--bitcoin.basefee=0", 289 | "--store-key=4967BC847DDEFF47C4BC890038F5A495", 290 | "--unlock-pwd=hi123456", 291 | "--server-macaroons-dir=/macaroons", 292 | "--channels-start=2", 293 | "--admin-token=r46bnf8ibrhbb424heba", 294 | "--admin-port=5050", 295 | "--admin-pubkey=037ec785c6004d512ebaeb0020f81a2bcdb6fccc9539f7b891f704289ebc65a4e3", 296 | "--initial-msat=500000", 297 | "--mqtt-broker=tcps://mqtt.sphinx:1883", 298 | "--topic-uuid=YLkmJR_jaWBRICt21_IG01sopeqvE_8JUv3NXbBV9egjj2Y9AFf8iTmugbxtlxcnNc-RjYpbdN9E_vMWm4LHXTCbhL4O", 299 | "--tlsextradomain=proxy.sphinx", 300 | "--use-hd-keys", 301 | "--mode=cln", 302 | "--cln-ca-cert=/cln/creds/ca.pem", 303 | "--cln-client-cert=/cln/creds/client.pem", 304 | "--cln-client-key=/cln/creds/client-key.pem", 305 | "--cln-ip=dave-cln.sphinx", 306 | "--cln-port=10012", 307 | "--cln-server-name=cln", 308 | "--htlc-interceptor-ip=dave-cln.sphinx", 309 | "--htlc-interceptor-port=10212", 310 | ] 311 | ports: 312 | - 11111:11111 313 | - 5050:5050 314 | 315 | boltwall: 316 | image: sphinxlightning/sphinx-boltwall:latest 317 | container_name: boltwall.sphinx 318 | restart: on-failure 319 | depends_on: 320 | - boltwallsetup 321 | volumes: 322 | - ./boltwall/.env:/usr/src/app/.env 323 | ports: 324 | - 8444:8444 325 | 326 | boltwallsetup: 327 | image: node:12-buster-slim 328 | restart: on-failure 329 | entrypoint: ["node", "/boltwall/setup/index.js"] 330 | volumes: 331 | - ./boltwall:/boltwall 332 | - ./boltwall/.env:/boltwall/.env 333 | - ./lnd:/lnd 334 | 335 | dave-cln: 336 | image: sphinxlightning/cln-sphinx:latest 337 | container_name: dave-cln.sphinx 338 | restart: on-failure 339 | command: 340 | - --addr=0.0.0.0:19846 341 | - --bitcoin-rpcconnect=bitcoind.sphinx 342 | - --bitcoin-rpcport=18443 343 | - --bitcoin-rpcuser=evan 344 | - --bitcoin-rpcpassword=thepass 345 | - --network=regtest 346 | - --log-level=debug 347 | - --alias=dave-cln 348 | - --grpc-port=10012 349 | - --accept-htlc-tlv-type=133773310 350 | - --plugin=/usr/local/libexec/c-lightning/plugins/gateway-cln-extension 351 | environment: 352 | - EXPOSE_TCP=true 353 | - GREENLIGHT_VERSION=v23.08-56-g0c8094c-modded 354 | - FM_CLN_EXTENSION_LISTEN_ADDRESS=0.0.0.0:10212 355 | ports: 356 | - "0.0.0.0:19846:19846" 357 | - 10012:10012 358 | - 10212:10212 359 | links: 360 | - bitcoind 361 | volumes: 362 | - ./cln/dave-cln:/root/.lightning 363 | - ./cln/dave-cln/setup_script.sh:/setup_script.sh 364 | - ./cln/dave-cln/cln_vol/entrypoint.sh:/entrypoint.sh 365 | 366 | tribes-setup: 367 | image: node:12-buster-slim 368 | restart: on-failure 369 | entrypoint: ["node", "/tribes/setup/index.js"] 370 | depends_on: 371 | - relaysetup 372 | volumes: 373 | - ./tribes:/tribes 374 | - ./tribes/.env:/tribes/.env 375 | - ./relay:/relay -------------------------------------------------------------------------------- /alts/no-alice.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | lndsetup: 53 | image: node:12-buster-slim 54 | depends_on: 55 | - alice-lnd 56 | - bob-lnd 57 | - carol-lnd 58 | restart: "no" 59 | entrypoint: ["node", "/lndsetup/index.js"] 60 | volumes: 61 | - ./lnd/alice/.lnd:/alice/.lnd 62 | - ./lnd/setup:/lndsetup 63 | - ./lnd/setup/nodes/nodes.js:/lndsetup/nodes.js 64 | 65 | db: 66 | image: postgres 67 | container_name: db.sphinx 68 | restart: on-failure 69 | environment: 70 | - POSTGRES_PASSWORD=sphinx 71 | - POSTGRES_USER=postgres 72 | volumes: 73 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 74 | - ./pgdata:/var/lib/postgresql/data 75 | ports: 76 | - 5433:5432 77 | 78 | tribes: 79 | image: sphinxlightning/sphinx-tribes:latest 80 | container_name: tribes.sphinx 81 | restart: on-failure 82 | depends_on: 83 | - db 84 | environment: 85 | - PORT=13000 86 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 87 | - LN_SERVER_BASE_URL=http://localhost:13000 88 | volumes: 89 | - ./tribes/script.sh:/app/script.sh 90 | ports: 91 | - 5002:5002 92 | - 13007:13007 93 | - 13000:13000 94 | entrypoint: 95 | - "sh" 96 | - "-c" 97 | - | 98 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 99 | 100 | auth: 101 | image: sphinxlightning/sphinx-auth:latest 102 | container_name: auth.sphinx 103 | restart: on-failure 104 | depends_on: 105 | - db 106 | environment: 107 | - JWT_KEY=19e0bb49bhyuibme 108 | - HOST=localhost:9090 109 | ports: 110 | - 9090:9090 111 | 112 | mqtt: 113 | image: sphinxlightning/sphinx-mqtt:latest 114 | container_name: mqtt.sphinx 115 | restart: on-failure 116 | depends_on: 117 | - auth 118 | ports: 119 | - 1883:1883 120 | 121 | meme: 122 | image: sphinxlightning/sphinx-meme:latest 123 | container_name: meme.sphinx 124 | restart: on-failure 125 | depends_on: 126 | - db 127 | volumes: 128 | - ./memes:/app/files 129 | environment: 130 | - PORT=5555 131 | - JWT_KEY=19e0bb49bhyuibme 132 | - STORAGE_MODE=local 133 | - LOCAL_DIR=app/files 134 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 135 | - HOST=localhost:5555 136 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 137 | 138 | bob: 139 | image: sphinxlightning/sphinx-relay 140 | container_name: bob.sphinx 141 | user: root 142 | restart: on-failure 143 | depends_on: 144 | - bob-lnd 145 | entrypoint: 146 | [ 147 | "node", 148 | "/relay/dist/app.js", 149 | "--config=/relay/configs/bob.json", 150 | "--db=/relay/configs/bob-db.json", 151 | ] 152 | volumes: 153 | - ./relay:/relay/configs 154 | - ./lnd/bob/.lnd:/relay/bob/.lnd 155 | environment: 156 | - NODE_ENV=${GITACTION_ENV:-development} 157 | - PORT=3002 158 | - TRIBES_HOST=host.docker.internal:13000 159 | - MEDIA_HOST=localhost:5555 160 | ports: 161 | - 3002:3002 162 | extra_hosts: 163 | - "host.docker.internal:host-gateway" 164 | 165 | carol: 166 | image: sphinxlightning/sphinx-relay 167 | container_name: carol.sphinx 168 | user: root 169 | restart: on-failure 170 | depends_on: 171 | - carol-lnd 172 | entrypoint: 173 | [ 174 | "node", 175 | "/relay/dist/app.js", 176 | "--config=/relay/configs/carol.json", 177 | "--db=/relay/configs/carol-db.json", 178 | ] 179 | volumes: 180 | - ./relay:/relay/configs 181 | - ./lnd/carol/.lnd:/relay/carol/.lnd 182 | environment: 183 | - NODE_ENV=${GITACTION_ENV:-development} 184 | - PORT=3003 185 | - TRIBES_HOST=host.docker.internal:13000 186 | - MEDIA_HOST=localhost:5555 187 | ports: 188 | - 3003:3003 189 | extra_hosts: 190 | - "host.docker.internal:host-gateway" 191 | 192 | relaysetup: 193 | image: node:12-buster-slim 194 | depends_on: 195 | - bob 196 | - carol 197 | - lndsetup 198 | - tribes 199 | restart: on-failure 200 | entrypoint: ["node", "/relay/setup/index.js"] 201 | volumes: 202 | - ./relay:/relay 203 | - ./relay/nodes_partial/nodes_partial.json:/relay/nodes_partial.json 204 | environment: 205 | - ALICE_IP=http://host.docker.internal:3001 206 | 207 | etcd: 208 | image: "quay.io/coreos/etcd" 209 | container_name: etcd.sphinx 210 | profiles: 211 | - aperture 212 | environment: 213 | - ETCD_ADVERTISE_CLIENT_URLS=http://etcd.sphinx:2379 214 | - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 215 | command: "etcd -name etcd-meme-aperture" 216 | 217 | aperture: 218 | image: "lightninglabs/aperture:v0.1.12-beta" 219 | container_name: aperture.sphinx 220 | profiles: 221 | - aperture 222 | ports: 223 | # for now we will have aperture run on the default meme port 224 | # so that it's easier to use this as a drop in replacement for any existing setups 225 | - 5555:8081 226 | volumes: 227 | - ./aperture:/aperture 228 | # using alice's lnd node as the backend for aperture 229 | - ./lnd/alice/.lnd:/lnd 230 | # want to restart on failure b/c the lightning node needs to be 231 | # fully operational so that aperture can connect to it and successfully start 232 | restart: on-failure 233 | depends_on: 234 | - etcd 235 | - alice-lnd 236 | entrypoint: ["aperture", "--configfile=/aperture/aperture.yaml"] 237 | 238 | # an override service that runs everything in the 239 | # depends_on list. Comment out to use overrides 240 | exclude-services: 241 | image: nginx 242 | command: echo done 243 | depends_on: 244 | - bitcoind 245 | - alice-lnd 246 | - bob-lnd 247 | - carol-lnd 248 | - lndsetup 249 | - db 250 | - tribes 251 | - auth 252 | - mqtt 253 | # - meme 254 | - bob 255 | - carol 256 | - relaysetup 257 | - aperture 258 | - etcd 259 | profiles: 260 | - aperture 261 | 262 | boltwall: 263 | image: sphinxlightning/sphinx-boltwall:latest 264 | # image: tobi-boltwall 265 | container_name: boltwall.sphinx 266 | restart: on-failure 267 | depends_on: 268 | - boltwallsetup 269 | volumes: 270 | - ./boltwall/.env:/usr/src/app/.env 271 | ports: 272 | - 8444:8444 273 | 274 | boltwallsetup: 275 | image: node:12-buster-slim 276 | restart: on-failure 277 | entrypoint: ["node", "/boltwall/setup/index.js"] 278 | volumes: 279 | - ./boltwall:/boltwall 280 | - ./boltwall/.env:/boltwall/.env 281 | - ./lnd:/lnd 282 | 283 | tribes-setup: 284 | image: node:12-buster-slim 285 | restart: on-failure 286 | entrypoint: ["node", "/tribes/setup/index.js"] 287 | depends_on: 288 | - relaysetup 289 | volumes: 290 | - ./tribes:/tribes 291 | - ./tribes/.env:/tribes/.env 292 | - ./relay:/relay 293 | 294 | networks: 295 | default: 296 | name: sphinx-stack 297 | -------------------------------------------------------------------------------- /alts/no-dave-cln-proxy.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | lndsetup: 53 | image: node:12-buster-slim 54 | depends_on: 55 | - alice-lnd 56 | - bob-lnd 57 | - carol-lnd 58 | - dave-cln 59 | restart: "no" 60 | entrypoint: ["node", "/lndsetup/index.js"] 61 | volumes: 62 | - ./lnd/alice/.lnd:/alice/.lnd 63 | - ./lnd/setup:/lndsetup 64 | - ./lnd/setup/nodes/proxynodes.js:/lndsetup/nodes.js 65 | environment: 66 | - CLN_PROXY=true 67 | 68 | db: 69 | image: postgres 70 | container_name: db.sphinx 71 | restart: on-failure 72 | environment: 73 | - POSTGRES_PASSWORD=sphinx 74 | - POSTGRES_USER=postgres 75 | volumes: 76 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 77 | - ./pgdata:/var/lib/postgresql/data 78 | ports: 79 | - 5433:5432 80 | 81 | tribes: 82 | image: sphinxlightning/sphinx-tribes:latest 83 | container_name: tribes.sphinx 84 | restart: on-failure 85 | depends_on: 86 | - db 87 | environment: 88 | - PORT=13000 89 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 90 | - LN_SERVER_BASE_URL=http://localhost:13000 91 | volumes: 92 | - ./tribes/script.sh:/app/script.sh 93 | ports: 94 | - 5002:5002 95 | - 13007:13007 96 | - 13000:13000 97 | entrypoint: 98 | - "sh" 99 | - "-c" 100 | - | 101 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 102 | 103 | auth: 104 | image: sphinxlightning/sphinx-auth:0.2.3 105 | container_name: auth.sphinx 106 | restart: on-failure 107 | depends_on: 108 | - db 109 | environment: 110 | - JWT_KEY=19e0bb49bhyuibme 111 | - HOST=localhost:9090 112 | ports: 113 | - 9090:9090 114 | 115 | mqtt: 116 | image: sphinxlightning/sphinx-mqtt:test-2 117 | container_name: mqtt.sphinx 118 | restart: on-failure 119 | depends_on: 120 | - auth 121 | ports: 122 | - 1883:1883 123 | 124 | meme: 125 | image: sphinxlightning/sphinx-meme:0.2.2 126 | container_name: meme.sphinx 127 | restart: on-failure 128 | depends_on: 129 | - db 130 | volumes: 131 | - ./memes:/app/files 132 | environment: 133 | - PORT=5555 134 | - JWT_KEY=19e0bb49bhyuibme 135 | - STORAGE_MODE=local 136 | - LOCAL_DIR=app/files 137 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 138 | - HOST=localhost:5555 139 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 140 | ports: 141 | - 5555:5555 142 | 143 | alice: 144 | image: sphinxlightning/sphinx-relay 145 | container_name: alice.sphinx 146 | user: root 147 | restart: on-failure 148 | depends_on: 149 | - alice-lnd 150 | entrypoint: 151 | [ 152 | "node", 153 | "/relay/dist/app.js", 154 | "--config=/relay/configs/alice.json", 155 | "--db=/relay/configs/alice-db.json", 156 | ] 157 | volumes: 158 | - ./relay:/relay/configs 159 | - ./lnd/alice/.lnd:/relay/alice/.lnd 160 | environment: 161 | - NODE_ENV=${GITACTION_ENV:-development} 162 | - PORT=3001 163 | - TRIBES_HOST=host.docker.internal:13000 164 | - MEDIA_HOST=localhost:5555 165 | ports: 166 | - 3001:3001 167 | extra_hosts: 168 | - "host.docker.internal:host-gateway" 169 | 170 | bob: 171 | image: sphinxlightning/sphinx-relay 172 | container_name: bob.sphinx 173 | user: root 174 | restart: on-failure 175 | depends_on: 176 | - bob-lnd 177 | entrypoint: 178 | [ 179 | "node", 180 | "/relay/dist/app.js", 181 | "--config=/relay/configs/bob.json", 182 | "--db=/relay/configs/bob-db.json", 183 | ] 184 | volumes: 185 | - ./relay:/relay/configs 186 | - ./lnd/bob/.lnd:/relay/bob/.lnd 187 | environment: 188 | - NODE_ENV=${GITACTION_ENV:-development} 189 | - PORT=3002 190 | - TRIBES_HOST=host.docker.internal:13000 191 | - MEDIA_HOST=localhost:5555 192 | ports: 193 | - 3002:3002 194 | extra_hosts: 195 | - "host.docker.internal:host-gateway" 196 | 197 | carol: 198 | image: sphinxlightning/sphinx-relay 199 | container_name: carol.sphinx 200 | user: root 201 | restart: on-failure 202 | depends_on: 203 | - carol-lnd 204 | entrypoint: 205 | [ 206 | "node", 207 | "/relay/dist/app.js", 208 | "--config=/relay/configs/carol.json", 209 | "--db=/relay/configs/carol-db.json", 210 | ] 211 | volumes: 212 | - ./relay:/relay/configs 213 | - ./lnd/carol/.lnd:/relay/carol/.lnd 214 | environment: 215 | - NODE_ENV=${GITACTION_ENV:-development} 216 | - PORT=3003 217 | - TRIBES_HOST=host.docker.internal:13000 218 | - MEDIA_HOST=localhost:5555 219 | ports: 220 | - 3003:3003 221 | extra_hosts: 222 | - "host.docker.internal:host-gateway" 223 | 224 | relaysetup: 225 | image: node:12-buster-slim 226 | depends_on: 227 | - alice 228 | - bob 229 | - carol 230 | - lndsetup 231 | - tribes 232 | restart: on-failure 233 | entrypoint: ["node", "/relay/setup/index.js"] 234 | volumes: 235 | - ./relay:/relay 236 | - ./relay/nodes_partial/cln_proxy_nodes_partial.json:/relay/nodes_partial.json 237 | environment: 238 | - DAVE_IP=http://host.docker.internal:3004 239 | 240 | proxy: 241 | image: sphinxlightning/sphinx-proxy:0.1.31 242 | container_name: proxy.sphinx 243 | restart: always 244 | user: root 245 | depends_on: 246 | - dave-cln 247 | volumes: 248 | - ./lnd/dave/.lnd:/lnd/.lnd 249 | - ./proxy/cert:/cert 250 | - ./proxy/macaroons:/macaroons 251 | - ./proxy/badger:/badger 252 | - ./cln/dave-cln/regtest:/cln/creds 253 | - type: bind 254 | source: ./proxy/lnd_proxy.conf 255 | target: /lnd_proxy.conf 256 | entrypoint: 257 | [ 258 | "/app/sphinx-proxy", 259 | "--rpclisten=0.0.0.0:11111", 260 | "--tlscertpath=/cert/tls.cert", 261 | "--tlskeypath=/cert/tls.key", 262 | "--bitcoin.regtest", 263 | "--bitcoin.active", 264 | "--bitcoin.basefee=0", 265 | "--store-key=4967BC847DDEFF47C4BC890038F5A495", 266 | "--unlock-pwd=hi123456", 267 | "--server-macaroons-dir=/macaroons", 268 | "--channels-start=2", 269 | "--admin-token=r46bnf8ibrhbb424heba", 270 | "--admin-port=5050", 271 | "--admin-pubkey=037ec785c6004d512ebaeb0020f81a2bcdb6fccc9539f7b891f704289ebc65a4e3", 272 | "--initial-msat=500000", 273 | "--mqtt-broker=tcps://mqtt.sphinx:1883", 274 | "--topic-uuid=YLkmJR_jaWBRICt21_IG01sopeqvE_8JUv3NXbBV9egjj2Y9AFf8iTmugbxtlxcnNc-RjYpbdN9E_vMWm4LHXTCbhL4O", 275 | "--tlsextradomain=proxy.sphinx", 276 | "--use-hd-keys", 277 | "--mode=cln", 278 | "--cln-ca-cert=/cln/creds/ca.pem", 279 | "--cln-client-cert=/cln/creds/client.pem", 280 | "--cln-client-key=/cln/creds/client-key.pem", 281 | "--cln-ip=dave-cln.sphinx", 282 | "--cln-port=10012", 283 | "--cln-server-name=cln", 284 | "--htlc-interceptor-ip=dave-cln.sphinx", 285 | "--htlc-interceptor-port=10212", 286 | ] 287 | ports: 288 | - 11111:11111 289 | - 5050:5050 290 | 291 | boltwall: 292 | image: sphinxlightning/sphinx-boltwall:latest 293 | container_name: boltwall.sphinx 294 | restart: on-failure 295 | depends_on: 296 | - boltwallsetup 297 | volumes: 298 | - ./boltwall/.env:/usr/src/app/.env 299 | ports: 300 | - 8444:8444 301 | 302 | boltwallsetup: 303 | image: node:12-buster-slim 304 | restart: on-failure 305 | entrypoint: ["node", "/boltwall/setup/index.js"] 306 | volumes: 307 | - ./boltwall:/boltwall 308 | - ./boltwall/.env:/boltwall/.env 309 | - ./lnd:/lnd 310 | 311 | dave-cln: 312 | image: sphinxlightning/cln-sphinx:0.1.2 313 | container_name: dave-cln.sphinx 314 | command: 315 | - --addr=0.0.0.0:19846 316 | - --bitcoin-rpcconnect=bitcoind.sphinx 317 | - --bitcoin-rpcport=18443 318 | - --bitcoin-rpcuser=evan 319 | - --bitcoin-rpcpassword=thepass 320 | - --network=regtest 321 | - --log-level=debug 322 | - --alias=dave-cln 323 | - --grpc-port=10012 324 | - --accept-htlc-tlv-types=133773310 325 | - --plugin=/usr/local/libexec/c-lightning/plugins/gateway-cln-extension 326 | environment: 327 | - EXPOSE_TCP=true 328 | - GREENLIGHT_VERSION=v23.02.2-50-gd15200c 329 | - FM_CLN_EXTENSION_LISTEN_ADDRESS=0.0.0.0:10212 330 | ports: 331 | - "0.0.0.0:19846:19846" 332 | - 10012:10012 333 | - 10212:10212 334 | links: 335 | - bitcoind 336 | volumes: 337 | - ./cln/dave-cln:/root/.lightning 338 | - ./cln/dave-cln/setup_script.sh:/setup_script.sh 339 | - ./cln/dave-cln/cln_vol/entrypoint.sh:/entrypoint.sh 340 | 341 | tribes-setup: 342 | image: node:12-buster-slim 343 | restart: on-failure 344 | entrypoint: ["node", "/tribes/setup/index.js"] 345 | depends_on: 346 | - relaysetup 347 | volumes: 348 | - ./tribes:/tribes 349 | - ./tribes/.env:/tribes/.env 350 | - ./relay:/relay 351 | -------------------------------------------------------------------------------- /alts/no-tribes.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | lndsetup: 53 | image: node:12-buster-slim 54 | depends_on: 55 | - alice-lnd 56 | - bob-lnd 57 | - carol-lnd 58 | restart: "no" 59 | entrypoint: ["node", "/lndsetup/index.js"] 60 | volumes: 61 | - ./lnd/alice/.lnd:/alice/.lnd 62 | - ./lnd/setup:/lndsetup 63 | - ./lnd/setup/nodes/nodes.js:/lndsetup/nodes.js 64 | 65 | db: 66 | image: postgres 67 | container_name: db.sphinx 68 | restart: on-failure 69 | environment: 70 | - POSTGRES_PASSWORD=sphinx 71 | - POSTGRES_USER=postgres 72 | volumes: 73 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 74 | - ./pgdata:/var/lib/postgresql/data 75 | ports: 76 | - 5433:5432 77 | 78 | auth: 79 | image: sphinxlightning/sphinx-auth:latest 80 | container_name: auth.sphinx 81 | restart: on-failure 82 | depends_on: 83 | - db 84 | environment: 85 | - JWT_KEY=19e0bb49bhyuibme 86 | - HOST=localhost:9090 87 | ports: 88 | - 9090:9090 89 | 90 | mqtt: 91 | image: sphinxlightning/sphinx-mqtt:latest 92 | container_name: mqtt.sphinx 93 | restart: on-failure 94 | depends_on: 95 | - auth 96 | ports: 97 | - 1883:1883 98 | 99 | meme: 100 | image: sphinxlightning/sphinx-meme:latest 101 | container_name: meme.sphinx 102 | restart: on-failure 103 | depends_on: 104 | - db 105 | volumes: 106 | - ./memes:/app/files 107 | environment: 108 | - PORT=5555 109 | - JWT_KEY=19e0bb49bhyuibme 110 | - STORAGE_MODE=local 111 | - LOCAL_DIR=app/files 112 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 113 | - HOST=localhost:5555 114 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 115 | 116 | alice: 117 | image: sphinxlightning/sphinx-relay 118 | container_name: alice.sphinx 119 | user: root 120 | restart: on-failure 121 | depends_on: 122 | - alice-lnd 123 | entrypoint: 124 | [ 125 | "node", 126 | "/relay/dist/app.js", 127 | "--config=/relay/configs/alice.json", 128 | "--db=/relay/configs/alice-db.json", 129 | ] 130 | volumes: 131 | - ./relay:/relay/configs 132 | - ./lnd/alice/.lnd:/relay/alice/.lnd 133 | environment: 134 | - NODE_ENV=${GITACTION_ENV:-development} 135 | - PORT=3001 136 | - TRIBES_HOST=host.docker.internal:13000 137 | - MEDIA_HOST=localhost:5555 138 | ports: 139 | - 3001:3001 140 | extra_hosts: 141 | - "host.docker.internal:host-gateway" 142 | 143 | bob: 144 | image: sphinxlightning/sphinx-relay 145 | container_name: bob.sphinx 146 | user: root 147 | restart: on-failure 148 | depends_on: 149 | - bob-lnd 150 | entrypoint: 151 | [ 152 | "node", 153 | "/relay/dist/app.js", 154 | "--config=/relay/configs/bob.json", 155 | "--db=/relay/configs/bob-db.json", 156 | ] 157 | volumes: 158 | - ./relay:/relay/configs 159 | - ./lnd/bob/.lnd:/relay/bob/.lnd 160 | environment: 161 | - NODE_ENV=${GITACTION_ENV:-development} 162 | - PORT=3002 163 | - TRIBES_HOST=host.docker.internal:13000 164 | - MEDIA_HOST=localhost:5555 165 | ports: 166 | - 3002:3002 167 | extra_hosts: 168 | - "host.docker.internal:host-gateway" 169 | 170 | carol: 171 | image: sphinxlightning/sphinx-relay 172 | container_name: carol.sphinx 173 | user: root 174 | restart: on-failure 175 | depends_on: 176 | - carol-lnd 177 | entrypoint: 178 | [ 179 | "node", 180 | "/relay/dist/app.js", 181 | "--config=/relay/configs/carol.json", 182 | "--db=/relay/configs/carol-db.json", 183 | ] 184 | volumes: 185 | - ./relay:/relay/configs 186 | - ./lnd/carol/.lnd:/relay/carol/.lnd 187 | environment: 188 | - NODE_ENV=${GITACTION_ENV:-development} 189 | - PORT=3003 190 | - TRIBES_HOST=host.docker.internal:13000 191 | - MEDIA_HOST=localhost:5555 192 | ports: 193 | - 3003:3003 194 | extra_hosts: 195 | - "host.docker.internal:host-gateway" 196 | 197 | relaysetup: 198 | image: node:12-buster-slim 199 | depends_on: 200 | - alice 201 | - bob 202 | - carol 203 | - lndsetup 204 | restart: on-failure 205 | entrypoint: ["node", "/relay/setup/index.js"] 206 | volumes: 207 | - ./relay:/relay 208 | - ./relay/nodes_partial/nodes_partial.json:/relay/nodes_partial.json 209 | 210 | etcd: 211 | image: "quay.io/coreos/etcd" 212 | container_name: etcd.sphinx 213 | profiles: 214 | - aperture 215 | environment: 216 | - ETCD_ADVERTISE_CLIENT_URLS=http://etcd.sphinx:2379 217 | - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 218 | command: "etcd -name etcd-meme-aperture" 219 | 220 | aperture: 221 | image: "lightninglabs/aperture:v0.1.12-beta" 222 | container_name: aperture.sphinx 223 | profiles: 224 | - aperture 225 | ports: 226 | # for now we will have aperture run on the default meme port 227 | # so that it's easier to use this as a drop in replacement for any existing setups 228 | - 5555:8081 229 | volumes: 230 | - ./aperture:/aperture 231 | # using alice's lnd node as the backend for aperture 232 | - ./lnd/alice/.lnd:/lnd 233 | # want to restart on failure b/c the lightning node needs to be 234 | # fully operational so that aperture can connect to it and successfully start 235 | restart: on-failure 236 | depends_on: 237 | - etcd 238 | - alice-lnd 239 | entrypoint: ["aperture", "--configfile=/aperture/aperture.yaml"] 240 | 241 | # an override service that runs everything in the 242 | # depends_on list. Comment out to use overrides 243 | exclude-services: 244 | image: nginx 245 | command: echo done 246 | depends_on: 247 | - bitcoind 248 | - alice-lnd 249 | - bob-lnd 250 | - carol-lnd 251 | - lndsetup 252 | - db 253 | - auth 254 | - mqtt 255 | # - meme 256 | - alice 257 | - bob 258 | - carol 259 | - relaysetup 260 | - aperture 261 | - etcd 262 | profiles: 263 | - aperture 264 | 265 | networks: 266 | default: 267 | name: sphinx-stack 268 | -------------------------------------------------------------------------------- /alts/proxy-no-dave.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | dave-lnd: 53 | image: lightninglabs/lnd:v0.14.3-beta.rc1 54 | container_name: dave-lnd.sphinx 55 | volumes: 56 | - ./lnd/dave/.lnd:/root/.lnd 57 | - ./lnd/setup:/lndsetup 58 | ports: 59 | - 9738:9735 60 | - 10012:10012 61 | - 38884:38884 62 | command: --configfile=/lndsetup/dave.conf 63 | 64 | lndsetup: 65 | image: node:12-buster-slim 66 | depends_on: 67 | - alice-lnd 68 | - bob-lnd 69 | - carol-lnd 70 | - dave-lnd 71 | restart: "no" 72 | entrypoint: ["node", "/lndsetup/index.js"] 73 | volumes: 74 | - ./lnd/alice/.lnd:/alice/.lnd 75 | - ./lnd/setup:/lndsetup 76 | environment: 77 | - PROXY=true 78 | 79 | db: 80 | image: postgres 81 | container_name: db.sphinx 82 | restart: on-failure 83 | environment: 84 | - POSTGRES_PASSWORD=sphinx 85 | - POSTGRES_USER=postgres 86 | volumes: 87 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 88 | - ./pgdata:/var/lib/postgresql/data 89 | ports: 90 | - 5433:5432 91 | 92 | tribes: 93 | image: sphinxlightning/sphinx-tribes:latest 94 | container_name: tribes.sphinx 95 | restart: on-failure 96 | depends_on: 97 | - db 98 | environment: 99 | - PORT=13000 100 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 101 | - LN_SERVER_BASE_URL=http://localhost:13000 102 | volumes: 103 | - ./tribes/script.sh:/app/script.sh 104 | ports: 105 | - 5002:5002 106 | - 13007:13007 107 | - 13000:13000 108 | entrypoint: 109 | - "sh" 110 | - "-c" 111 | - | 112 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 113 | 114 | auth: 115 | # image: sphinxlightning/sphinx-auth:latest 116 | image: sphinxlightning/sphinx-auth:0.2.1 117 | container_name: auth.sphinx 118 | restart: on-failure 119 | depends_on: 120 | - db 121 | environment: 122 | - JWT_KEY=19e0bb49bhyuibme 123 | - HOST=localhost:9090 124 | ports: 125 | - 9090:9090 126 | 127 | mqtt: 128 | image: sphinxlightning/sphinx-mqtt:test-2 129 | container_name: mqtt.sphinx 130 | restart: on-failure 131 | depends_on: 132 | - auth 133 | ports: 134 | - 1883:1883 135 | 136 | meme: 137 | image: sphinxlightning/sphinx-meme:latest 138 | container_name: meme.sphinx 139 | restart: on-failure 140 | depends_on: 141 | - db 142 | volumes: 143 | - ./memes:/app/files 144 | environment: 145 | - PORT=5555 146 | - JWT_KEY=19e0bb49bhyuibme 147 | - STORAGE_MODE=local 148 | - LOCAL_DIR=app/files 149 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 150 | - HOST=localhost:5555 151 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 152 | ports: 153 | - 5555:5555 154 | 155 | alice: 156 | image: sphinxlightning/sphinx-relay 157 | container_name: alice.sphinx 158 | user: root 159 | restart: on-failure 160 | depends_on: 161 | - alice-lnd 162 | entrypoint: 163 | [ 164 | "node", 165 | "/relay/dist/app.js", 166 | "--config=/relay/configs/alice.json", 167 | "--db=/relay/configs/alice-db.json", 168 | ] 169 | volumes: 170 | - ./relay:/relay/configs 171 | - ./lnd/alice/.lnd:/relay/alice/.lnd 172 | environment: 173 | - NODE_ENV=${GITACTION_ENV:-development} 174 | - PORT=3001 175 | - TRIBES_HOST=host.docker.internal:13000 176 | - MEDIA_HOST=localhost:5555 177 | ports: 178 | - 3001:3001 179 | extra_hosts: 180 | - "host.docker.internal:host-gateway" 181 | 182 | bob: 183 | image: sphinxlightning/sphinx-relay 184 | container_name: bob.sphinx 185 | user: root 186 | restart: on-failure 187 | depends_on: 188 | - bob-lnd 189 | entrypoint: 190 | [ 191 | "node", 192 | "/relay/dist/app.js", 193 | "--config=/relay/configs/bob.json", 194 | "--db=/relay/configs/bob-db.json", 195 | ] 196 | volumes: 197 | - ./relay:/relay/configs 198 | - ./lnd/bob/.lnd:/relay/bob/.lnd 199 | environment: 200 | - NODE_ENV=${GITACTION_ENV:-development} 201 | - PORT=3002 202 | - TRIBES_HOST=host.docker.internal:13000 203 | - MEDIA_HOST=localhost:5555 204 | ports: 205 | - 3002:3002 206 | extra_hosts: 207 | - "host.docker.internal:host-gateway" 208 | 209 | carol: 210 | image: sphinxlightning/sphinx-relay 211 | container_name: carol.sphinx 212 | user: root 213 | restart: on-failure 214 | depends_on: 215 | - carol-lnd 216 | entrypoint: 217 | [ 218 | "node", 219 | "/relay/dist/app.js", 220 | "--config=/relay/configs/carol.json", 221 | "--db=/relay/configs/carol-db.json", 222 | ] 223 | volumes: 224 | - ./relay:/relay/configs 225 | - ./lnd/carol/.lnd:/relay/carol/.lnd 226 | environment: 227 | - NODE_ENV=${GITACTION_ENV:-development} 228 | - PORT=3003 229 | - TRIBES_HOST=host.docker.internal:13000 230 | - MEDIA_HOST=localhost:5555 231 | ports: 232 | - 3003:3003 233 | extra_hosts: 234 | - "host.docker.internal:host-gateway" 235 | 236 | relaysetup: 237 | image: node:12-buster-slim 238 | depends_on: 239 | - alice 240 | - bob 241 | - carol 242 | - lndsetup 243 | - tribes 244 | restart: on-failure 245 | entrypoint: ["node", "/relay/setup/index.js"] 246 | volumes: 247 | - ./relay:/relay 248 | - ./relay/nodes_partial/proxy_nodes_partial.json:/relay/nodes_partial.json 249 | environment: 250 | - DAVE_IP=http://host.docker.internal:3004 251 | 252 | proxy: 253 | # image: sphinxlightning/sphinx-proxy 254 | # image: sphinx-proxy 255 | image: sphinxlightning/sphinx-proxy:0.1.31 256 | container_name: proxy.sphinx 257 | restart: always 258 | user: root 259 | depends_on: 260 | - dave-lnd 261 | volumes: 262 | - ./lnd/dave/.lnd:/lnd/.lnd 263 | - ./proxy/cert:/cert 264 | - ./proxy/macaroons:/macaroons 265 | - ./proxy/badger:/badger 266 | - type: bind 267 | source: ./proxy/lnd_proxy.conf 268 | target: /lnd_proxy.conf 269 | entrypoint: 270 | [ 271 | "/app/sphinx-proxy", 272 | "--rpclisten=0.0.0.0:11111", 273 | "--tlscertpath=/cert/tls.cert", 274 | "--tlskeypath=/cert/tls.key", 275 | "--bitcoin.regtest", 276 | "--bitcoin.active", 277 | "--bitcoin.basefee=0", 278 | "--store-key=4967BC847DDEFF47C4BC890038F5A495", 279 | "--unlock-pwd=hi123456", 280 | "--server-macaroons-dir=/macaroons", 281 | "--channels-start=2", 282 | "--admin-token=r46bnf8ibrhbb424heba", 283 | "--admin-port=5050", 284 | "--admin-pubkey=030841d1519f19c68e80efc5ef5af3460ca4bfa17486fda9baca878b9ef255358f", 285 | "--initial-msat=500000", 286 | "--macaroon-location=/lnd/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 287 | "--tls-location=/lnd/.lnd/tls.cert", 288 | "--lnd-ip=dave-lnd.sphinx", 289 | "--lnd-port=10012", 290 | "--mqtt-broker=tcps://mqtt.sphinx:1883", 291 | "--topic-uuid=YLkmJR_jaWBRICt21_IG01sopeqvE_8JUv3NXbBV9egjj2Y9AFf8iTmugbxtlxcnNc-RjYpbdN9E_vMWm4LHXTCbhL4O", 292 | "--tlsextradomain=proxy.sphinx", 293 | "--use-hd-keys", 294 | ] 295 | ports: 296 | - 11111:11111 297 | - 5050:5050 298 | 299 | cache: 300 | image: sphinxlightning/sphinx-cache:0.1.17 301 | container_name: cache.sphinx 302 | depends_on: 303 | - mqtt 304 | restart: on-failure 305 | volumes: 306 | - ./cache/store:/store 307 | environment: 308 | - ROCKET_ADDRESS=0.0.0.0 309 | - ROCKET_PORT=8008 310 | - STORE_PATH=/store 311 | - PRIVATE_KEY=b3cd3f01bb4def01ab4def01abcd3f01a4cdef01abcdef21a4cdef01abc3ef01 312 | - RSA_KEY=MIIEogIBAAKCAQEAt2RSUo/xlB1dGQBn6Ko4j6w6FyLIQ7CL47qm4ihDapne6bG5dmiBT3lcGmrvjLBJqIKHLejhgRY2VgVU8YK0R94/HWWyz709d7nLhtYBbdWmwIjGD7aDxeRX5ATp0THZbEebfUc/237iqD5Enf6pmzdD9JQgtFU9A8uNjexuULmV1Kq2nr3w2OUlTP1a84UP1Qs0XSlFA0HOBj6OLGcP/VD7H4wbfrZXCIMGQo4LPy+htM4k31Qn0K3LgKfU1bKHzJk+kGYTHThOEpHRUIbd8lOAnZwzIg0P47QvY1pVs5Te26sXvnt5Uxj+hrilg829GfvrIG/TDzb1EXIqZmwM3wIDAQABAoIBABF6aDYiLd315neJiF2uS3G18lteH0QEQXDUyy7ms3YncA1JuOlGEHzojhSeeHIqIvsCZavEdCl/WnJcU7oowNHQpqdAmAggewk8Fd+l6cD0Cc5zupyowmpL1uyOY1Jis9wT/wezkKx0rVlnhdag/L0kST+4Fl3ZedUwwy7xh5n9zKuTk5byo5jErTPzW7I+i8tonvB50082xQGsbNlCNrgFkYTeGNKSOeDnDqYerneFder4c5iePEnt5fW+Cl21VQ+I9G6jqZnxJHXMyILrPmhYxFsKAFpTclRLElERag2PPvKzWGC0k50zSvwFzs9qrWatEggf14UsDR/OSi48UzECgYEA0Nfc9HbRqSq+ex0h+kP4Vs0ig3w7d9h/FKFllY3sJSwdcMY/mh/7JZO7640IqM6nRpBqYpOQeV1DnQZBG3ss6chBBfQzkXb3x6spPEkZUp0MkGSIe5VZBS4qp//nHWt4l1/1d/ZCRGz/oscpdbt0YetN80VMFfOf/58nzZVWTKUCgYEA4M0/5fTYQaN7wN4bfp86LMciOKl781LXiUIIVHDxH1oVZLShxPhN/MiY4+c5Sj/YDmXz1+SRZSkj2o2VMq7iS+1PSZhXOGHbRcVhRhoLsl5o7ZuX4auIfNNRWkxDTU8GXyzsAnmSoCDBEQR3N3AV8Pj34NrRIAHJMhynPOhtKDMCgYAMuwvqDxAqysM/x//ZPKl3yRtwfnM1lAnzHP+PRU5+2ZiV1k/sOkTZ/o53Bmrft3E0+PqzNaGZ9Fh5yvbPEQwk2CM2lLNMC7+A+WsTFLWpdo9cgfRb7De3/B93jD7vaSy5tYzGGknh1+8hYhih56Jpkal3yeKgd/Bp6a7IdnEDTQKBgEtI8alVgkcZNQy2VYbmVFlCp1dKi1RF3iD9mESPPnE9fgSn6bVJYvTRSUKp4SnYj8bipfMbfQXf7T34RIsgvnCnHPKMrkkXnJOVMqqDdn9Z1tIcVZUiGSeUrZ4MBE4TtRKSvMdnZ49w6LeGQ1axlueIuZr4LSkG8BZ0Oh3PyR65AoGAUPrimvzCwUaw+Mtwgsnfam8ZrMV+MFc1wTA/gnsXpvgOUGpYPQTamYtHQscYQt4rRfIpuEO3wNKTwQIa3dkqpyhLVeUYg9WPIrvQnZ75aRCGZbZA2DUG7iv6vAPvGsgjpq0nqS++WtNBZ49ppHwXcI9X0TTtiZpcnRtf8MdUId0= 313 | - MQTT_HOST=mqtt.sphinx 314 | - MQTT_PORT=1883 315 | - MQTT_CLIENT_ID=sphinx-cache-test-1 316 | - MEME_HOST=meme.sphinx 317 | ports: 318 | - 8008:8008 319 | 320 | tribes-setup: 321 | image: node:12-buster-slim 322 | restart: on-failure 323 | entrypoint: ["node", "/tribes/setup/index.js"] 324 | depends_on: 325 | - relaysetup 326 | volumes: 327 | - ./tribes:/tribes 328 | - ./tribes/.env:/tribes/.env 329 | - ./relay:/relay 330 | -------------------------------------------------------------------------------- /alts/proxy.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | dave-lnd: 53 | image: lightninglabs/lnd:v0.14.3-beta.rc1 54 | container_name: dave-lnd.sphinx 55 | volumes: 56 | - ./lnd/dave/.lnd:/root/.lnd 57 | - ./lnd/setup:/lndsetup 58 | ports: 59 | - 9738:9735 60 | - 10012:10012 61 | - 38884:38884 62 | command: --configfile=/lndsetup/dave.conf 63 | 64 | lndsetup: 65 | image: node:12-buster-slim 66 | depends_on: 67 | - alice-lnd 68 | - bob-lnd 69 | - carol-lnd 70 | - dave-lnd 71 | restart: "no" 72 | entrypoint: ["node", "/lndsetup/index.js"] 73 | volumes: 74 | - ./lnd/alice/.lnd:/alice/.lnd 75 | - ./lnd/setup:/lndsetup 76 | - ./lnd/setup/nodes/proxynodes.js:/lndsetup/nodes.js 77 | environment: 78 | - PROXY=true 79 | 80 | db: 81 | image: postgres 82 | container_name: db.sphinx 83 | restart: on-failure 84 | environment: 85 | - POSTGRES_PASSWORD=sphinx 86 | - POSTGRES_USER=postgres 87 | volumes: 88 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 89 | - ./pgdata:/var/lib/postgresql/data 90 | ports: 91 | - 5433:5432 92 | 93 | tribes: 94 | image: sphinxlightning/sphinx-tribes:latest 95 | container_name: tribes.sphinx 96 | restart: on-failure 97 | depends_on: 98 | - db 99 | environment: 100 | - PORT=13000 101 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 102 | - LN_SERVER_BASE_URL=http://localhost:13000 103 | volumes: 104 | - ./tribes/script.sh:/app/script.sh 105 | ports: 106 | - 5002:5002 107 | - 13007:13007 108 | - 13000:13000 109 | entrypoint: 110 | - "sh" 111 | - "-c" 112 | - | 113 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 114 | 115 | auth: 116 | image: sphinxlightning/sphinx-auth:latest 117 | container_name: auth.sphinx 118 | restart: on-failure 119 | depends_on: 120 | - db 121 | environment: 122 | - JWT_KEY=19e0bb49bhyuibme 123 | - HOST=localhost:9090 124 | ports: 125 | - 9090:9090 126 | 127 | mqtt: 128 | image: sphinxlightning/sphinx-mqtt:test-2 129 | container_name: mqtt.sphinx 130 | restart: on-failure 131 | depends_on: 132 | - auth 133 | ports: 134 | - 1883:1883 135 | 136 | meme: 137 | image: sphinxlightning/sphinx-meme:latest 138 | container_name: meme.sphinx 139 | restart: on-failure 140 | depends_on: 141 | - db 142 | volumes: 143 | - ./memes:/app/files 144 | environment: 145 | - PORT=5555 146 | - JWT_KEY=19e0bb49bhyuibme 147 | - STORAGE_MODE=local 148 | - LOCAL_DIR=app/files 149 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 150 | - HOST=meme.sphinx:5555 151 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 152 | ports: 153 | - 5555:5555 154 | 155 | alice: 156 | image: sphinxlightning/sphinx-relay 157 | container_name: alice.sphinx 158 | user: root 159 | restart: on-failure 160 | depends_on: 161 | - alice-lnd 162 | entrypoint: 163 | [ 164 | "node", 165 | "/relay/dist/app.js", 166 | "--config=/relay/configs/alice.json", 167 | "--db=/relay/configs/alice-db.json", 168 | ] 169 | volumes: 170 | - ./relay:/relay/configs 171 | - ./lnd/alice/.lnd:/relay/alice/.lnd 172 | environment: 173 | - NODE_ENV=${GITACTION_ENV:-development} 174 | - PORT=3001 175 | - TRIBES_HOST=host.docker.internal:13000 176 | ports: 177 | - 3001:3001 178 | extra_hosts: 179 | - "host.docker.internal:host-gateway" 180 | 181 | bob: 182 | image: sphinxlightning/sphinx-relay 183 | container_name: bob.sphinx 184 | user: root 185 | restart: on-failure 186 | depends_on: 187 | - bob-lnd 188 | entrypoint: 189 | [ 190 | "node", 191 | "/relay/dist/app.js", 192 | "--config=/relay/configs/bob.json", 193 | "--db=/relay/configs/bob-db.json", 194 | ] 195 | volumes: 196 | - ./relay:/relay/configs 197 | - ./lnd/bob/.lnd:/relay/bob/.lnd 198 | environment: 199 | - NODE_ENV=${GITACTION_ENV:-development} 200 | - PORT=3002 201 | - TRIBES_HOST=host.docker.internal:13000 202 | ports: 203 | - 3002:3002 204 | extra_hosts: 205 | - "host.docker.internal:host-gateway" 206 | 207 | carol: 208 | image: sphinxlightning/sphinx-relay 209 | container_name: carol.sphinx 210 | user: root 211 | restart: on-failure 212 | depends_on: 213 | - carol-lnd 214 | entrypoint: 215 | [ 216 | "node", 217 | "/relay/dist/app.js", 218 | "--config=/relay/configs/carol.json", 219 | "--db=/relay/configs/carol-db.json", 220 | ] 221 | volumes: 222 | - ./relay:/relay/configs 223 | - ./lnd/carol/.lnd:/relay/carol/.lnd 224 | environment: 225 | - NODE_ENV=${GITACTION_ENV:-development} 226 | - PORT=3003 227 | - TRIBES_HOST=host.docker.internal:13000 228 | ports: 229 | - 3003:3003 230 | extra_hosts: 231 | - "host.docker.internal:host-gateway" 232 | 233 | dave: 234 | image: sphinxlightning/sphinx-relay 235 | container_name: dave.sphinx 236 | user: root 237 | restart: on-failure 238 | depends_on: 239 | - dave-lnd 240 | - proxy 241 | entrypoint: 242 | [ 243 | "node", 244 | "/relay/dist/app.js", 245 | "--config=/relay/configs/dave.json", 246 | "--db=/relay/configs/dave-db.json", 247 | ] 248 | volumes: 249 | - ./relay:/relay/configs 250 | - ./lnd/dave/.lnd:/relay/dave/.lnd 251 | - ./proxy:/proxy 252 | environment: 253 | - NODE_ENV=${GITACTION_ENV:-development} 254 | - PORT=3004 255 | - TRIBES_HOST=host.docker.internal:13000 256 | ports: 257 | - 3004:3004 258 | 259 | relaysetup: 260 | image: node:12-buster-slim 261 | depends_on: 262 | - alice 263 | - bob 264 | - carol 265 | - dave 266 | - lndsetup 267 | - tribes 268 | restart: on-failure 269 | entrypoint: ["node", "/relay/setup/index.js"] 270 | volumes: 271 | - ./relay:/relay 272 | - ./relay/nodes_partial/proxy_nodes_partial.json:/relay/nodes_partial.json 273 | environment: 274 | - DAVE_IP=http://host.docker.internal:3004 275 | 276 | proxy: 277 | image: sphinxlightning/sphinx-proxy:latest 278 | container_name: proxy.sphinx 279 | restart: always 280 | user: root 281 | depends_on: 282 | - dave-lnd 283 | volumes: 284 | - ./lnd/dave/.lnd:/lnd/.lnd 285 | - ./proxy/cert:/cert 286 | - ./proxy/macaroons:/macaroons 287 | - ./proxy/badger:/badger 288 | - type: bind 289 | source: ./proxy/lnd_proxy.conf 290 | target: /lnd_proxy.conf 291 | entrypoint: 292 | [ 293 | "/app/sphinx-proxy", 294 | "--rpclisten=0.0.0.0:11111", 295 | "--tlscertpath=/cert/tls.cert", 296 | "--tlskeypath=/cert/tls.key", 297 | "--bitcoin.regtest", 298 | "--bitcoin.active", 299 | "--bitcoin.basefee=0", 300 | "--store-key=4967BC847DDEFF47C4BC890038F5A495", 301 | "--unlock-pwd=hi123456", 302 | "--server-macaroons-dir=/macaroons", 303 | "--channels-start=2", 304 | "--admin-token=r46bnf8ibrhbb424heba", 305 | "--admin-port=5050", 306 | "--admin-pubkey=030841d1519f19c68e80efc5ef5af3460ca4bfa17486fda9baca878b9ef255358f", 307 | "--initial-msat=500000", 308 | "--macaroon-location=/lnd/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 309 | "--tls-location=/lnd/.lnd/tls.cert", 310 | "--lnd-ip=dave-lnd.sphinx", 311 | "--lnd-port=10012", 312 | "--mqtt-broker=tcps://mqtt.sphinx:1883", 313 | "--topic-uuid=YLkmJR_jaWBRICt21_IG01sopeqvE_8JUv3NXbBV9egjj2Y9AFf8iTmugbxtlxcnNc-RjYpbdN9E_vMWm4LHXTCbhL4O", 314 | "--tlsextradomain=proxy.sphinx", 315 | "--use-hd-keys", 316 | ] 317 | ports: 318 | - 11111:11111 319 | - 5050:5050 320 | 321 | boltwall: 322 | image: sphinxlightning/sphinx-boltwall:latest 323 | container_name: boltwall.sphinx 324 | restart: on-failure 325 | depends_on: 326 | - boltwallsetup 327 | volumes: 328 | - ./boltwall/.env:/usr/src/app/.env 329 | ports: 330 | - 8444:8444 331 | 332 | boltwallsetup: 333 | image: node:12-buster-slim 334 | restart: on-failure 335 | entrypoint: ["node", "/boltwall/setup/index.js"] 336 | volumes: 337 | - ./boltwall:/boltwall 338 | - ./boltwall/.env:/boltwall/.env 339 | - ./lnd:/lnd 340 | 341 | tribes-setup: 342 | image: node:12-buster-slim 343 | restart: on-failure 344 | entrypoint: ["node", "/tribes/setup/index.js"] 345 | depends_on: 346 | - relaysetup 347 | volumes: 348 | - ./tribes:/tribes 349 | - ./tribes/.env:/tribes/.env 350 | - ./relay:/relay 351 | -------------------------------------------------------------------------------- /alts/v2.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | broker: 5 | image: sphinxlightning/sphinx-broker:latest 6 | restart: on-failure 7 | container_name: broker.sphinx 8 | environment: 9 | - SEED=8A048DC1F0020127E0E8DD72ACEFC62B8A048DC1F0020127E0E8DD72ACEFC62B 10 | - NETWORK=regtest 11 | - BROKER_MQTT_PORT=1883 12 | ports: 13 | - 1883:1883 14 | 15 | mixer: 16 | image: sphinxlightning/sphinx-mixer:latest 17 | restart: on-failure 18 | container_name: mixer.sphinx 19 | environment: 20 | - TESTING_ONLY_ADD_TO_SENDER=1 21 | - SEED=8A048DC1F0020127E0E8DD72ACEFC62B8A048DC1F0020127E0E8DD72ACEFC62B 22 | - NETWORK=regtest 23 | - BROKER_URL=broker.sphinx:1883 24 | - NO_GATEWAY=true 25 | - NO_LIGHTNING=true 26 | - ROCKET_ADDRESS=0.0.0.0 27 | - ROCKET_PORT=8888 28 | - DB_PATH=/home/data 29 | - ADMIN_ROUTES=true 30 | ports: 31 | - 8888:8888 32 | 33 | db: 34 | image: postgres 35 | container_name: db.sphinx 36 | restart: on-failure 37 | environment: 38 | - POSTGRES_PASSWORD=sphinx 39 | - POSTGRES_USER=postgres 40 | volumes: 41 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 42 | - ./pgdata:/var/lib/postgresql/data 43 | ports: 44 | - 5433:5432 45 | 46 | tribes: 47 | image: sphinxlightning/sphinx-tribes:latest 48 | container_name: tribes.sphinx 49 | restart: on-failure 50 | depends_on: 51 | - db 52 | environment: 53 | - PORT=13000 54 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 55 | - LN_SERVER_BASE_URL=http://localhost:13000 56 | - V2_BOT_URL=http://host.docker.internal:3002 57 | - V2_BOT_TOKEN=xyzxyzxyz 58 | volumes: 59 | - ./tribes/script.sh:/app/script.sh 60 | ports: 61 | - 5002:5002 62 | - 13007:13007 63 | - 13000:13000 64 | 65 | alice: 66 | image: sphinxlightning/sphinx-bot:latest 67 | restart: on-failure 68 | container_name: alice.sphinx 69 | environment: 70 | - PORT=3001 71 | - SEED=8DDDB00FFDE4581983FAA55AED83560486874391FDF93776DBBABBFE1C243C14 72 | - NETWORK=regtest 73 | - BROKER=http://broker.sphinx:1883 74 | - MY_ALIAS=alice 75 | - ADMIN_TOKEN=xyzxyzxyz 76 | - INITIAL_DELAY=5000 77 | ports: 78 | - 3001:3001 79 | 80 | bob: 81 | image: sphinxlightning/sphinx-bot:latest 82 | restart: on-failure 83 | container_name: bob.sphinx 84 | environment: 85 | - PORT=3002 86 | - SEED=7A9039255E3776858BDF7E51B840ED795F99FCF0358C201BAAC4AB1FEB45C236 87 | - NETWORK=regtest 88 | - BROKER=http://broker.sphinx:1883 89 | - MY_ALIAS=bob 90 | - ADMIN_TOKEN=xyzxyzxyz 91 | - INITIAL_DELAY=5000 92 | ports: 93 | - 3002:3002 94 | 95 | v2setup: 96 | image: node:12-buster-slim 97 | depends_on: 98 | - alice 99 | - bob 100 | - tribes 101 | restart: on-failure 102 | entrypoint: ["node", "/v2/setup.js"] 103 | volumes: 104 | - ./relay:/relay 105 | - ./v2:/v2 -------------------------------------------------------------------------------- /aperture/aperture.yaml: -------------------------------------------------------------------------------- 1 | # these configs are based on the sample available in the main repo 2 | # https://github.com/lightninglabs/aperture/blob/master/sample-conf.yaml 3 | 4 | # The address which the proxy can be reached at. 5 | listenaddr: "aperture.sphinx:8081" 6 | 7 | # The root path of static content to serve upon receiving a request the proxy 8 | # cannot handle. 9 | staticroot: "./aperture/staticroot.json" 10 | 11 | # Should the static file server be enabled that serves files from the directory 12 | # specified in `staticroot`? 13 | # Only really want this for testing purposes so should disable 14 | servestatic: false 15 | 16 | # The log level that should be used for the proxy. 17 | # 18 | # Valid options include: trace, debug, info, warn, error, critical, off. 19 | debuglevel: "debug" 20 | 21 | # Whether the proxy should create a valid certificate through Let's Encrypt for 22 | # the fully qualifying domain name. 23 | autocert: false 24 | # servername: aperture.example.com 25 | 26 | # Settings for the lnd node used to generate payment requests. All of these 27 | # options are required. 28 | authenticator: 29 | # The host:port which lnd's RPC can be reached at. 30 | # using alice's node as primary 31 | lndhost: "alice-lnd.sphinx:10009" 32 | 33 | # The path to lnd's TLS certificate. 34 | tlspath: "/lnd/tls.cert" 35 | 36 | # The path to lnd's macaroon directory. 37 | macdir: "/lnd/data/chain/bitcoin/regtest" 38 | 39 | # The chain network the lnd is active on. 40 | network: "regtest" 41 | 42 | # Settings for the etcd instance which the proxy will use to reliably store and 43 | # retrieve token information. 44 | etcd: 45 | # The client host:port which the etcd instance can be reached at. 46 | # this assumes docker networking from lsat.yml 47 | host: "etcd.sphinx:2379" 48 | 49 | # If authentication is enabled, the user and password required to access the 50 | # etcd instance. 51 | # user: "user" 52 | # password: "password" 53 | 54 | # List of services that should be reachable behind the proxy. Requests will be 55 | # matched to the services in order, picking the first that satisfies hostregexp 56 | # and (if set) pathregexp. So order is important! 57 | # 58 | # Use single quotes for regular expressions with special characters in them to 59 | # avoid YAML parsing errors! 60 | services: 61 | # The identifying name of the service. This will also be used to identify 62 | # which capabilities caveat (if any) corresponds to the service. 63 | - name: "sphinx_meme" 64 | 65 | # The regular expression used to match the service host. 66 | hostregexp: "^localhost.*$" 67 | 68 | # The regular expression used to match the path of the URL. 69 | # matches all paths if not included. we create a "block list" 70 | # by hacking a negative match in the authwhitelistpaths config below 71 | # pathregexp: "^/(ask).*$" 72 | 73 | # The host:port which the service can be reached at. 74 | address: "meme.sphinx:5555" 75 | 76 | # The HTTP protocol that should be used to connect to the service. Valid 77 | # options include: http, https. 78 | # meme.sphinx is the local docker host and can be accessed with http 79 | protocol: http 80 | 81 | # If required, a path to the service's TLS certificate to successfully 82 | # establish a secure connection. 83 | # tlscertpath: "path-to-optional-tls-cert/tls.cert" 84 | 85 | # A comma-delimited list of capabilities that will be granted for tokens of 86 | # the service at the base tier. 87 | capabilities: "large_upload" 88 | 89 | # The set of constraints that are applied to tokens of the service at the 90 | # base tier. Can also add these on the other side 91 | # should be of format of: [capability]_[constraint]_[constraint_unit] 92 | # with the unit being dependent on the actual constraint itself 93 | constraints: 94 | "large_upload_max_mb": "500" 95 | 96 | # a caveat will be added that expires the LSAT 97 | # after this many seconds, 31557600 = 1 year. 98 | timeout: 31557600 99 | 100 | # The LSAT value in satoshis for the service. It is ignored if 101 | # dynamicprice.enabled is set to true. 102 | price: 25000 103 | 104 | # List of regular expressions for paths that don't require authentication 105 | authwhitelistpaths: 106 | # generated negative match for "largefile" using 107 | # https://www.formauri.es/personal/pgimeno/misc/non-match-regex 108 | - "^([^l]|l(l|a(l|r(l|g(l|e(l|f(l|il(argefil)*(l|a(l|r(l|g(l|e(l|fl)))))))))))*([^al]|a([^lr]|r([^gl]|g([^el]|e([^fl]|f([^il]|i([^l]|l(argefil)*([^ael]|a([^lr]|r([^gl]|g([^el]|e([^fl]|f([^il]|i[^l]))))))))))))))*(l(l|a(l|r(l|g(l|e(l|f(l|il(argefil)*(l|a(l|r(l|g(l|e(l|fl)))))))))))*(a((r(g?|ge(fi?)?))?|rgefil(argefil)*(a(r(g?|ge(fi?)?))?)?))?)?$" 109 | 110 | # Settings for a Tor instance to allow requests over Tor as onion services. 111 | # Configuring Tor is optional. 112 | # tor: 113 | # # The host:port which Tor's control can be reached at. 114 | # control: "localhost:9051" 115 | 116 | # # The internal port we should listen on for client requests over Tor. Note 117 | # # that this port should not be exposed to the outside world, it is only 118 | # # intended to be reached by clients through the onion service. 119 | # listenport: 8082 120 | 121 | # # The port through which the onion services to be created can be reached at. 122 | # virtualport: 8082 123 | 124 | # # Whether a v2 onion service should be created to handle requests. 125 | # v2: false 126 | 127 | # # Whether a v3 onion service should be created to handle requests. 128 | # v3: false 129 | 130 | # Enable the Lightning Node Connect hashmail server, allowing up to 1k messages 131 | # per burst and a new message every 20 milliseconds. 132 | hashmail: 133 | enabled: true 134 | messagerate: 20ms 135 | messageburstallowance: 1000 136 | -------------------------------------------------------------------------------- /aperture/staticroot.json: -------------------------------------------------------------------------------- 1 | { 2 | "message": "you reached unprotected content that aperture didn't know how to deal with" 3 | } 4 | -------------------------------------------------------------------------------- /bitcoind/bitcoin.conf: -------------------------------------------------------------------------------- 1 | 2 | regtest=1 3 | rpcallowip=0.0.0.0/0 4 | fallbackfee=0.0002 5 | rpcuser=evan 6 | rpcpassword=thepass 7 | zmqpubhashblock=tcp://0.0.0.0:28332 8 | zmqpubhashtx=tcp://0.0.0.0:28333 9 | 10 | [regtest] 11 | txindex=1 12 | server=1 13 | rpcport=18443 14 | rpcbind=bitcoind.sphinx 15 | rpcbind=127.0.0.1 -------------------------------------------------------------------------------- /boltwall/.env: -------------------------------------------------------------------------------- 1 | PORT=8000 2 | 3 | LND_SOCKET=bob-lnd.sphinx:10010 4 | LIQUID_SERVER=http://demo1310255.mockable.io/ 5 | JARVIS_BACKEND_URL=http://jarvis-backend.sphinx:5000 6 | HOST_URL=http://boltwall.sphinx:8444 7 | ADMIN_TOKEN=navfiber_e2e_testing 8 | STAKWORK_SECRET=navfiber-tester -------------------------------------------------------------------------------- /boltwall/.gitignore: -------------------------------------------------------------------------------- 1 | .env -------------------------------------------------------------------------------- /boltwall/setup/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const os = require('os') 3 | 4 | const envFilePath = '/boltwall/.env'; 5 | 6 | const readEnvVars = () => fs.readFileSync(envFilePath, "utf-8").split(os.EOL); 7 | const lnd_cert = fs.readFileSync('./lnd/bob/.lnd/tls.cert', {encoding: 'hex'}); 8 | console.log(lnd_cert) 9 | 10 | const lnd_macaroon = fs.readFileSync('./lnd/bob/.lnd/data/chain/bitcoin/regtest/admin.macaroon', {encoding: 'hex'}) 11 | console.log(lnd_macaroon) 12 | 13 | const setEnvValue = (key, value) => { 14 | const envVars = readEnvVars(); 15 | const targetLine = envVars.find((line) => line.split("=")[0] === key); 16 | if (targetLine !== undefined) { 17 | // update existing line 18 | const targetLineIndex = envVars.indexOf(targetLine); 19 | // replace the key/value with the new value 20 | envVars.splice(targetLineIndex, 1, `${key}="${value}"`); 21 | } else { 22 | // create new key value 23 | envVars.push(`${key}="${value}"`); 24 | } 25 | // write everything back to the file system 26 | fs.writeFileSync(envFilePath, envVars.join(os.EOL)); 27 | }; 28 | 29 | setEnvValue('LND_TLS_CERT', lnd_cert) 30 | setEnvValue('LND_MACAROON', lnd_macaroon) 31 | -------------------------------------------------------------------------------- /botSandBox/isEnvAvailible.js: -------------------------------------------------------------------------------- 1 | var fs = require("fs"); 2 | 3 | let index = process.env.SPHINX_INDEX; 4 | var envVars = require("./botEnvVars.json"); 5 | 6 | if (!fs.existsSync("./botEnvVars.json")) { 7 | let envVars = require("./botEnvVars"); 8 | if (envVars.length == 0) { 9 | process.abort(); 10 | } 11 | } 12 | 13 | //So this script is run when the bots are initialized so we can 14 | //insert the SPHINX_TOKEN and PORT for the bots before they spin up 15 | //the docker container restarts on failure and the command to run 16 | //the bot depends on this file getting to process.exit() 17 | if (envVars[index].SPHINX_TOKEN != null) { 18 | fs.writeFileSync( 19 | ".env", 20 | `SPHINX_TOKEN=${envVars[index].SPHINX_TOKEN} 21 | PORT=${envVars[index].PORT}` 22 | ); 23 | 24 | process.exit(); 25 | } else { 26 | process.abort(); 27 | } 28 | -------------------------------------------------------------------------------- /botSandBox/sphinx-ml-bot/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build -------------------------------------------------------------------------------- /botSandBox/sphinx-ml-bot/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sphinx-ml-bot", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "dev": "nodemon src/index.ts", 8 | "build": "rm -rf ./build && tsc", 9 | "start": "npm run build && node build/index.js", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [], 13 | "author": "Bamidele Oluwatobi", 14 | "license": "ISC", 15 | "devDependencies": { 16 | "@types/express": "^4.17.17", 17 | "@types/node": "^20.5.0", 18 | "nodemon": "^3.0.1", 19 | "ts-node": "^10.9.1", 20 | "typescript": "^5.1.6" 21 | }, 22 | "dependencies": { 23 | "axios": "^1.4.0", 24 | "express": "^4.18.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /botSandBox/sphinx-ml-bot/src/index.ts: -------------------------------------------------------------------------------- 1 | import express, { Request, Response } from "express"; 2 | import axios from "axios"; 3 | 4 | const app = express(); 5 | 6 | app.use(express.json()); 7 | 8 | function sendWebhook(url: string, process_id: string, msg: string) { 9 | try { 10 | axios.post(url, { body: { process_id, response: msg } }); 11 | } catch (error) { 12 | console.log(`Error sending webhook: ${error}`); 13 | } 14 | } 15 | 16 | function generateProcessId() { 17 | const process_id = Math.random().toString(36).substring(2, 10); 18 | return process_id; 19 | } 20 | 21 | app.post("/test", (req: Request, res: Response) => { 22 | return res.status(200).json({ msg: "Test is working" }); 23 | }); 24 | 25 | app.post("/text", (req: Request, res: Response) => { 26 | const process_id = generateProcessId(); 27 | setTimeout(() => { 28 | sendWebhook( 29 | req.body.webhook, 30 | process_id, 31 | "This is a response from test ml-bot server built in sphinx-stack" 32 | ); 33 | }, 5000); 34 | return res.status(200).json({ body: { process_id } }); 35 | }); 36 | 37 | app.post("/image", (req: Request, res: Response) => { 38 | const process_id = generateProcessId(); 39 | setTimeout(() => { 40 | sendWebhook( 41 | req.body.webhook, 42 | process_id, 43 | "https://res.cloudinary.com/teebams/image/upload/v1648478325/elite/wiot5aymifdzqwplyu1a.png" 44 | ); 45 | }, 5000); 46 | return res.status(200).json({ body: { process_id } }); 47 | }); 48 | 49 | const port = 3500; 50 | 51 | app.listen(port, () => { 52 | console.log(`Server is running on port ${port}`); 53 | }); 54 | -------------------------------------------------------------------------------- /botSandBox/sphinx-ml-bot/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "lib": ["es6"], 6 | "allowJs": true, 7 | "outDir": "build", 8 | "rootDir": "src", 9 | "strict": true, 10 | "noImplicitAny": true, 11 | "esModuleInterop": true, 12 | "resolveJsonModule": true 13 | } 14 | } -------------------------------------------------------------------------------- /cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitkeep 3 | !.gitignore -------------------------------------------------------------------------------- /clearall.sh: -------------------------------------------------------------------------------- 1 | 2 | 3 | rm -rf ./bitcoind/regtest 4 | 5 | rm -rf ./lnd/alice 6 | 7 | rm -rf ./lnd/bob 8 | 9 | rm -rf ./lnd/carol 10 | 11 | rm -rf ./lnd/dave 12 | 13 | rm -rf ./relay/db/alice.db 14 | 15 | rm -rf ./relay/db/bob.db 16 | 17 | rm -rf ./relay/db/carol.db 18 | 19 | rm -rf ./relay/db/dave.db 20 | 21 | rm -rf ./relay/NODES.json 22 | 23 | rm -rf ./pgdata 24 | 25 | #Redis data is for the sphinx-betting-bot 26 | rm -rf ./redisData 27 | 28 | #SPHINX_TOKEN for bots 29 | rm -rf ./relay/botEnvVars.json 30 | 31 | #Remove the certs for proxy 32 | rm -rf ./proxy/badger 33 | rm -rf ./proxy/cert 34 | rm -rf ./proxy/macaroons 35 | 36 | #transport keys 37 | rm ./relay/*.pem 38 | 39 | #Remove cln 40 | rm -rf ./cln/dave-cln/regtest 41 | 42 | rm -rf ./cln/dave-cln/lightningd-regtest.pid 43 | 44 | #remove neo4j 45 | rm -rf ./neo4j 46 | -------------------------------------------------------------------------------- /cln/.gitignore: -------------------------------------------------------------------------------- 1 | regtest 2 | cln2/bitcoin 3 | cln1/bitcoin 4 | lightningd-regtest.pid 5 | lightningd-bitcoin.pid 6 | remote_hsmd_vls 7 | broker/* 8 | !broker/.gitkeep 9 | .jules-bashrc -------------------------------------------------------------------------------- /cln/btc1/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/cln/btc1/.gitkeep -------------------------------------------------------------------------------- /cln/clear.sh: -------------------------------------------------------------------------------- 1 | rm -rf cln/btc1/regtest 2 | rm -rf cln/cln1/regtest 3 | rm -rf cln/cln1/bitcoin 4 | rm cln/cln1/lightningd-bitcoin.pid 5 | rm cln/cln1/lightningd-regtest.pid 6 | rm -rf cln/cln2/regtest 7 | rm -rf cln/cln2/bitcoin 8 | rm cln/cln2/lightningd-bitcoin.pid 9 | rm cln/cln2/lightningd-regtest.pid -------------------------------------------------------------------------------- /cln/cln-vls.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: ruimarinho/bitcoin-core:23.0 6 | container_name: bitcoincore 7 | command: 8 | -regtest=1 9 | -rpcallowip=0.0.0.0/0 10 | -rpcbind=0.0.0.0 11 | -rpcpassword=bar 12 | -rpcport=18443 13 | -rpcuser=foo 14 | -server 15 | ports: 16 | - 18443:18443 17 | volumes: 18 | - ./cln/btc1:/home/bitcoin/.bitcoin 19 | 20 | cln1: 21 | # image: sphinx-cln 22 | image: sphinxlightning/sphinx-cln-vls:0.1.5 23 | container_name: cln1 24 | command: 25 | - --bitcoin-rpcconnect=bitcoind 26 | - --bitcoin-rpcport=18443 27 | - --bitcoin-rpcuser=foo 28 | - --bitcoin-rpcpassword=bar 29 | - --network=regtest 30 | - --log-level=debug 31 | - --alias=sphinx-cln1 32 | - --grpc-port=10019 33 | - --subdaemon=hsmd:/usr/local/libexec/c-lightning/sphinx-key-broker 34 | - --accept-htlc-tlv-types=133773310 35 | # - --rpc-file=/socket 36 | environment: 37 | - EXPOSE_TCP=true 38 | - GREENLIGHT_VERSION=v0.11.0.1-793-g243f8e3 39 | ports: 40 | - "0.0.0.0:9735:9735" 41 | - 10019:10019 42 | - 1883:1883 43 | - 8000:8000 44 | links: 45 | - bitcoind 46 | volumes: 47 | - ./cln/cln1:/root/.lightning 48 | 49 | cln2: 50 | image: sphinxlightning/sphinx-cln-test:0.1.0 51 | container_name: cln2 52 | command: 53 | - --addr=0.0.0.0:9736 54 | - --bitcoin-rpcconnect=bitcoind 55 | - --bitcoin-rpcport=18443 56 | - --bitcoin-rpcuser=foo 57 | - --bitcoin-rpcpassword=bar 58 | - --network=regtest 59 | - --log-level=debug 60 | - --alias=sphinx-cln2 61 | - --grpc-port=10020 62 | - --accept-htlc-tlv-types=133773310 63 | environment: 64 | - EXPOSE_TCP=true 65 | ports: 66 | - "0.0.0.0:9736:9736" 67 | - 10020:10020 68 | links: 69 | - bitcoind 70 | volumes: 71 | - ./cln/cln2:/root/.lightning 72 | 73 | -------------------------------------------------------------------------------- /cln/cln.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | bitcoind: 5 | image: ruimarinho/bitcoin-core:23.0 6 | container_name: bitcoincore 7 | command: 8 | -regtest=1 9 | -rpcallowip=0.0.0.0/0 10 | -rpcbind=0.0.0.0 11 | -rpcpassword=bar 12 | -rpcport=18443 13 | -rpcuser=foo 14 | -server 15 | ports: 16 | - 18443:18443 17 | volumes: 18 | - ./cln/btc1:/home/bitcoin/.bitcoin 19 | 20 | cln1: 21 | image: sphinxlightning/sphinx-cln-test:0.1.0 22 | container_name: cln1 23 | command: 24 | - --bitcoin-rpcconnect=bitcoind 25 | - --bitcoin-rpcport=18443 26 | - --bitcoin-rpcuser=foo 27 | - --bitcoin-rpcpassword=bar 28 | - --network=regtest 29 | - --log-level=debug 30 | - --alias=sphinx-cln1 31 | - --grpc-port=10019 32 | - --accept-htlc-tlv-types=133773310 33 | environment: 34 | - EXPOSE_TCP=true 35 | ports: 36 | - "0.0.0.0:9735:9735" 37 | - 10019:10019 38 | links: 39 | - bitcoind 40 | volumes: 41 | - ./cln/cln1:/root/.lightning 42 | 43 | cln2: 44 | image: sphinxlightning/sphinx-cln-test:0.1.0 45 | container_name: cln2 46 | command: 47 | - --addr=0.0.0.0:9736 48 | - --bitcoin-rpcconnect=bitcoind 49 | - --bitcoin-rpcport=18443 50 | - --bitcoin-rpcuser=foo 51 | - --bitcoin-rpcpassword=bar 52 | - --network=regtest 53 | - --log-level=debug 54 | - --alias=sphinx-cln2 55 | - --grpc-port=10020 56 | - --accept-htlc-tlv-types=133773310 57 | environment: 58 | - EXPOSE_TCP=true 59 | ports: 60 | - "0.0.0.0:9736:9736" 61 | - 10020:10020 62 | links: 63 | - bitcoind 64 | volumes: 65 | - ./cln/cln2:/root/.lightning 66 | -------------------------------------------------------------------------------- /cln/cln1/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/cln/cln1/.gitkeep -------------------------------------------------------------------------------- /cln/cln2/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/cln/cln2/.gitkeep -------------------------------------------------------------------------------- /cln/dave-cln/cln_vol/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./setup_script.sh 4 | 5 | : "${EXPOSE_TCP:=false}" 6 | 7 | networkdatadir="${LIGHTNINGD_DATA}/${LIGHTNINGD_NETWORK}" 8 | 9 | if [ "$EXPOSE_TCP" == "true" ]; then 10 | set -m 11 | lightningd "$@" & 12 | 13 | echo "Core-Lightning starting" 14 | while read -r i; do if [ "$i" = "lightning-rpc" ]; then break; fi; done \ 15 | < <(inotifywait -e create,open --format '%f' --quiet "${networkdatadir}" --monitor) 16 | echo "Core-Lightning started" 17 | echo "Core-Lightning started, RPC available on port $LIGHTNINGD_RPC_PORT" 18 | socat "TCP4-listen:$LIGHTNINGD_RPC_PORT,fork,reuseaddr" "UNIX-CONNECT:${networkdatadir}/lightning-rpc" & 19 | fg %- 20 | else 21 | exec lightningd --network="${LIGHTNINGD_NETWORK}" "$@" 22 | fi 23 | -------------------------------------------------------------------------------- /cln/dave-cln/setup_script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo "Tobi is testing out script" 4 | 5 | echo -e "0\ncomfort thumb render rubber plunge know average congress obey shy forward lawn\n" | lightning-hsmtool generatehsm hsm_secret 6 | mkdir root 7 | mkdir root/.lightning 8 | mkdir root/.lightning/regtest 9 | touch root/.lightning/regtest/hsm_secret 10 | chmod 777 ./root/.lightning/regtest/hsm_secret 11 | cp hsm_secret ./root/.lightning/regtest/hsm_secret 12 | chmod 0400 ./root/.lightning/regtest/hsm_secret 13 | 14 | echo "Done with new setup" 15 | 16 | # echo "Core lighting Stopped" 17 | # lightningd --addr=0.0.0.0:19846 --bitcoin-rpcconnect=bitcoind.sphinx --bitcoin-rpcport=18443 --network=regtest --bitcoin-rpcuser=evan --bitcoin-rpcpassword=thepass --log-level=debug --alias=dave-cln --grpc-port=10012 --accept-htlc-tlv-types=133773310 --plugin=/usr/local/libexec/c-lightning/plugins/gateway-cln-extension 18 | # echo "Core ligthning restarted" 19 | -------------------------------------------------------------------------------- /cln/readme.md: -------------------------------------------------------------------------------- 1 | 2 | ### run 3 | 4 | docker-compose -f ./cln/cln.yml --project-directory . up -d --force-recreate 5 | 6 | ./cln/setup1.sh 7 | ./cln/setup2.sh bcrt1qnwze8xczdn2gfmk7n40rgrwh3k2x20r2td7txs 8 | 9 | docker-compose -f ./cln/cln.yml --project-directory . down 10 | 11 | ./cln/clear.sh 12 | 13 | export CLN="docker exec -it lightningd usr/local/bin/lightning-cli --network regtest" 14 | 15 | docker exec -it lightningd usr/local/bin/lightning-cli --lightning-dir root/.lightning --network regtest getinfo 16 | 17 | docker exec -it lightningd usr/local/bin/lightningd --version 18 | 19 | docker exec -it lightningd /usr/local/libexec/c-lightning/sphinx-key-broker --version 20 | 21 | docker exec -it lightningd /bin/bash 22 | 23 | ### down 24 | 25 | docker rm cln1.sphinx -f 26 | 27 | docker-compose down 28 | 29 | docker volume rm $(docker volume ls -q) 30 | 31 | ### logs 32 | 33 | docker logs cln1.sphinx 34 | 35 | ### bins 36 | 37 | find . -name 'lightning*' 38 | 39 | /usr/local/libexec/c-lightning 40 | 41 | lightning_hsmd 42 | 43 | ### inside 44 | 45 | export BTC="docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar" 46 | 47 | $BTC -getinfo 48 | 49 | docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar -getinfo 50 | 51 | docker exec -it cln1.sphinx bash 52 | 53 | /usr/local/libexec/c-lightning/vls-proxy/remote_hsmd_vls 54 | 55 | lightning-cli --network=regtest getinfo 56 | 57 | lightning-cli --network=regtest help 58 | 59 | lightning-cli --network=regtest signmessage hello 60 | 61 | ### build rust hsmd proxy 62 | 63 | Cross.toml: 64 | ```toml 65 | [build] 66 | passthrough=["RUSTFLAGS"] 67 | ``` 68 | 69 | in validating-lightning-signer 70 | 71 | cargo install cross 72 | 73 | RUSTFLAGS='-C link-arg=-s' cross build --target=x86_64-unknown-linux-musl --bin=remote_hsmd_vls 74 | 75 | RUSTFLAGS='-C target-feature=+crt-static' cross build --release --target=x86_64-unknown-linux-musl --bin=remote_hsmd_vls 76 | 77 | file target/x86_64-unknown-linux-musl/release/remote_hsmd_vls 78 | 79 | ### copy to place 80 | 81 | in sphinx-stack 82 | 83 | cp ../validating-lightning-signer/target/x86_64-unknown-linux-musl/debug/remote_hsmd_vls ./cln 84 | 85 | ### copy broker executable 86 | 87 | cid=$(docker create sphinx-key-broker) 88 | docker cp $cid:/usr/src/sphinx-key-broker - > cln/broker/sphinx-key-broker 89 | docker rm -v $cid 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /cln/setup.md: -------------------------------------------------------------------------------- 1 | 2 | export BTC="docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar" 3 | 4 | # cln1 5 | 6 | export CLN1="docker exec -it cln1 usr/local/bin/lightning-cli --network regtest" 7 | 8 | `$CLN1 getinfo` 9 | 10 | 02c7046d20f62012362ccf835fe5b4d4a1708e518592f216afeefabeadfc20154b 11 | 12 | # cln2 13 | 14 | export CLN2="docker exec -it cln2 usr/local/bin/lightning-cli --network regtest" 15 | 16 | `$CLN2 getinfo` 17 | 18 | export CLN2_PUBKEY=038655ec57fe06611cde27a386c52c5bdcb82c468386db02ef24e14a6e861f4c25 19 | 20 | # connect 21 | 22 | `$CLN1 newaddr` 23 | 24 | export CLN1_ADDY=bcrt1qerw8fc2palc4vazppjn5ya7qdpj37apefnd9ew 25 | 26 | `$BTC generatetoaddress 101 $CLN1_ADDY` 27 | 28 | `$BTC generatetoaddress 101 $CLN1_ADDY` 29 | 30 | `$CLN1 connect $CLN2_PUBKEY cln2:9736` 31 | 32 | channel id: 33 | 038655ec57fe06611cde27a386c52c5bdcb82c468386db02ef24e14a6e861f4c25 34 | 35 | `$CLN1 fundchannel 038655ec57fe06611cde27a386c52c5bdcb82c468386db02ef24e14a6e861f4c25 100000` 36 | 37 | `$BTC generatetoaddress 101 $CLN1_ADDY` 38 | 39 | `$CLN1 keysend $CLN2_PUBKEY 1000` 40 | 41 | # check 42 | 43 | `$CLN2 waitanyinvoice 0 0` 44 | 45 | # with TLVs 46 | 47 | `$CLN1 keysend $CLN2_PUBKEY 1000 label 0.5 60 1 5000 {\"133773310\":\"444444444444444444444444444444444444444444444444444444444444444444\"}` 48 | 49 | # check 50 | 51 | `$CLN2 waitanyinvoice 1 0` 52 | 53 | 54 | ### DEMO TEST 55 | 56 | SEED=56b289899f2871f77260a0ec8f1c2f1006b7ae4a74be4bb472a97945e416b191 BROKER=192.168.86.240:1886 ./target/debug/sphinx-key-tester 57 | 58 | SEED=55b289899f2871f77260b0ac8f1c2f1016b7ae4a74be4bb472a97345e416b191 BROKER=192.168.86.240:1889 STORE_PATH=teststore2 ./target/debug/sphinx-key-tester 59 | 60 | ### TEST ONLINE 61 | 62 | SEED=56b289899f2871f77260a0ec8f1c2f1006b7ae4a74be4bb472a97945e416b191 BROKER=44.211.127.45:1886 ./target/debug/sphinx-key-tester 63 | 64 | SEED=55b289899f2871f77260b0ac8f1c2f1016b7ae4a74be4bb472a97345e416b191 BROKER=44.211.127.45:1889 STORE_PATH=teststore2 ./target/debug/sphinx-key-tester -------------------------------------------------------------------------------- /cln/setup1.sh: -------------------------------------------------------------------------------- 1 | BTC="docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar" 2 | 3 | # $BTC -getinfo 4 | 5 | $BTC createwallet cln 6 | 7 | ADDY=`$BTC getnewaddress` 8 | 9 | echo "ADDY:" 10 | echo $ADDY 11 | 12 | # $BTC generatetoaddress 101 $(docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar getnewaddress) -------------------------------------------------------------------------------- /cln/setup2.sh: -------------------------------------------------------------------------------- 1 | BTC="docker exec -it bitcoincore bitcoin-cli -regtest -rpcuser=foo -rpcpassword=bar" 2 | 3 | $BTC generatetoaddress 101 $1 -------------------------------------------------------------------------------- /cln/vls.md: -------------------------------------------------------------------------------- 1 | docker-compose -f ./cln/cln-vls.yml --project-directory . up -d --force-recreate 2 | 3 | docker-compose -f ./cln/cln-vls.yml --project-directory . down 4 | 5 | ### get the version 6 | 7 | `git describe --tags --long --always --match='v*.*'` 8 | 9 | and only take the last 8 chars of the last string 10 | 11 | or 12 | 13 | docker run -it --entrypoint "/bin/bash" cln-sphinx 14 | 15 | `docker run -it --entrypoint "/bin/bash" sphinxlightning/sphinx-cln-vls:0.1.5` 16 | 17 | `lightningd --version` 18 | 19 | ### build c-lightning 20 | 21 | docker build . -t sphinx-cln 22 | 23 | docker tag sphinx-cln sphinxlightning/sphinx-cln-vls:0.1.5 24 | 25 | docker push sphinxlightning/sphinx-cln-vls:0.1.5 26 | 27 | ### testing 28 | 29 | in sphinx-key: 30 | 31 | cargo run --bin sphinx-key-tester -- --log 32 | -------------------------------------------------------------------------------- /docker-compose.override.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | meme: 5 | # in some environments, like alt/lsat.yml, we don't want 6 | # to expose the meme server to the outside world because we need 7 | # requests to go through the aperture proxy first. This will 8 | # add this mapping to the default configuration, but allows 9 | # the meme server configs in the lsat setup to not expose them. 10 | # see here for more details: https://mindbyte.nl/2018/04/04/overwrite-ports-in-docker-compose.html 11 | ports: 12 | - 5555:5555 13 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.5" 2 | 3 | services: 4 | bitcoind: 5 | image: lncm/bitcoind:v0.21.1 6 | restart: on-failure 7 | container_name: bitcoind.sphinx 8 | volumes: 9 | - ./bitcoind:/data/.bitcoin 10 | ports: 11 | - 18443:18443 12 | - 8333:8333 13 | - 28332:28332 14 | - 28333:28333 15 | 16 | alice-lnd: 17 | image: lightninglabs/lnd:v0.14.3-beta.rc1 18 | container_name: alice-lnd.sphinx 19 | volumes: 20 | - ./lnd/alice/.lnd:/root/.lnd 21 | - ./lnd/setup:/lndsetup 22 | ports: 23 | - 9735:9735 24 | - 10009:10009 25 | - 38881:38881 26 | command: --configfile=/lndsetup/alice.conf 27 | 28 | bob-lnd: 29 | image: lightninglabs/lnd:v0.14.3-beta.rc1 30 | container_name: bob-lnd.sphinx 31 | volumes: 32 | - ./lnd/bob/.lnd:/root/.lnd 33 | - ./lnd/setup:/lndsetup 34 | ports: 35 | - 9736:9735 36 | - 10010:10010 37 | - 38882:38882 38 | command: --configfile=/lndsetup/bob.conf 39 | 40 | carol-lnd: 41 | image: lightninglabs/lnd:v0.14.3-beta.rc1 42 | container_name: carol-lnd.sphinx 43 | volumes: 44 | - ./lnd/carol/.lnd:/root/.lnd 45 | - ./lnd/setup:/lndsetup 46 | ports: 47 | - 9737:9735 48 | - 10011:10011 49 | - 38883:38883 50 | command: --configfile=/lndsetup/carol.conf 51 | 52 | lndsetup: 53 | image: node:12-buster-slim 54 | depends_on: 55 | - alice-lnd 56 | - bob-lnd 57 | - carol-lnd 58 | restart: "no" 59 | entrypoint: ["node", "/lndsetup/index.js"] 60 | volumes: 61 | - ./lnd/alice/.lnd:/alice/.lnd 62 | - ./lnd/setup:/lndsetup 63 | - ./lnd/setup/nodes/nodes.js:/lndsetup/nodes.js 64 | 65 | db: 66 | image: postgres 67 | container_name: db.sphinx 68 | restart: on-failure 69 | environment: 70 | - POSTGRES_PASSWORD=sphinx 71 | - POSTGRES_USER=postgres 72 | volumes: 73 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 74 | - ./pgdata:/var/lib/postgresql/data 75 | ports: 76 | - 5433:5432 77 | 78 | tribes: 79 | image: sphinxlightning/sphinx-tribes:latest 80 | container_name: tribes.sphinx 81 | restart: on-failure 82 | depends_on: 83 | - db 84 | environment: 85 | - PORT=13000 86 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 87 | - LN_SERVER_BASE_URL=http://localhost:13000 88 | volumes: 89 | - ./tribes/script.sh:/app/script.sh 90 | ports: 91 | - 5002:5002 92 | - 13007:13007 93 | - 13000:13000 94 | entrypoint: 95 | - "sh" 96 | - "-c" 97 | - | 98 | chmod +x /app/script.sh && source /app/script.sh && /app/sphinx-tribes 99 | 100 | auth: 101 | image: sphinxlightning/sphinx-auth:latest 102 | container_name: auth.sphinx 103 | restart: on-failure 104 | depends_on: 105 | - db 106 | environment: 107 | - JWT_KEY=19e0bb49bhyuibme 108 | - HOST=localhost:9090 109 | ports: 110 | - 9090:9090 111 | 112 | mqtt: 113 | image: sphinxlightning/sphinx-mqtt:latest 114 | container_name: mqtt.sphinx 115 | restart: on-failure 116 | depends_on: 117 | - auth 118 | ports: 119 | - 1883:1883 120 | 121 | meme: 122 | image: bucko/sphinx-meme:latest 123 | container_name: meme.sphinx 124 | restart: on-failure 125 | depends_on: 126 | - db 127 | volumes: 128 | - ./memes:/app/files 129 | environment: 130 | - PORT=5555 131 | - JWT_KEY=19e0bb49bhyuibme 132 | - STORAGE_MODE=local 133 | - LOCAL_DIR=app/files 134 | - LOCAL_ENCRYPTION_KEY=88303a55f5829d9e35936364204bcb007fe330db649902fa1085a7bce3732347 135 | - HOST=localhost:5555 136 | - DATABASE_URL=postgres://postgres:sphinx@db.sphinx:5432/postgres?sslmode=disable 137 | 138 | alice: 139 | # image: sphinx-relay 140 | image: sphinxlightning/sphinx-relay 141 | container_name: alice.sphinx 142 | user: root 143 | restart: on-failure 144 | depends_on: 145 | - alice-lnd 146 | entrypoint: 147 | [ 148 | "node", 149 | "/relay/dist/app.js", 150 | "--config=/relay/configs/alice.json", 151 | "--db=/relay/configs/alice-db.json", 152 | ] 153 | volumes: 154 | - ./relay:/relay/configs 155 | - ./lnd/alice/.lnd:/relay/alice/.lnd 156 | environment: 157 | - NODE_ENV=${GITACTION_ENV:-development} 158 | - PORT=3001 159 | - TRIBES_HOST=host.docker.internal:13000 160 | - MEDIA_HOST=localhost:5555 161 | ports: 162 | - 3001:3001 163 | extra_hosts: 164 | - "host.docker.internal:host-gateway" 165 | 166 | bob: 167 | # image: sphinx-relay 168 | image: sphinxlightning/sphinx-relay 169 | container_name: bob.sphinx 170 | user: root 171 | restart: on-failure 172 | depends_on: 173 | - bob-lnd 174 | entrypoint: 175 | [ 176 | "node", 177 | "/relay/dist/app.js", 178 | "--config=/relay/configs/bob.json", 179 | "--db=/relay/configs/bob-db.json", 180 | ] 181 | volumes: 182 | - ./relay:/relay/configs 183 | - ./lnd/bob/.lnd:/relay/bob/.lnd 184 | environment: 185 | - NODE_ENV=${GITACTION_ENV:-development} 186 | - PORT=3002 187 | - TRIBES_HOST=host.docker.internal:13000 188 | - MEDIA_HOST=localhost:5555 189 | ports: 190 | - 3002:3002 191 | extra_hosts: 192 | - "host.docker.internal:host-gateway" 193 | 194 | carol: 195 | # image: sphinx-relay 196 | image: sphinxlightning/sphinx-relay 197 | container_name: carol.sphinx 198 | user: root 199 | restart: on-failure 200 | depends_on: 201 | - carol-lnd 202 | entrypoint: 203 | [ 204 | "node", 205 | "/relay/dist/app.js", 206 | "--config=/relay/configs/carol.json", 207 | "--db=/relay/configs/carol-db.json", 208 | ] 209 | volumes: 210 | - ./relay:/relay/configs 211 | - ./lnd/carol/.lnd:/relay/carol/.lnd 212 | environment: 213 | - NODE_ENV=${GITACTION_ENV:-development} 214 | - PORT=3003 215 | - TRIBES_HOST=host.docker.internal:13000 216 | - MEDIA_HOST=localhost:5555 217 | ports: 218 | - 3003:3003 219 | extra_hosts: 220 | - "host.docker.internal:host-gateway" 221 | 222 | relaysetup: 223 | image: node:12-buster-slim 224 | depends_on: 225 | - alice 226 | - bob 227 | - carol 228 | - lndsetup 229 | - tribes 230 | restart: on-failure 231 | entrypoint: ["node", "/relay/setup/index.js"] 232 | volumes: 233 | - ./relay:/relay 234 | - ./relay/nodes_partial/nodes_partial.json:/relay/nodes_partial.json 235 | 236 | etcd: 237 | image: "quay.io/coreos/etcd" 238 | container_name: etcd.sphinx 239 | profiles: 240 | - aperture 241 | environment: 242 | - ETCD_ADVERTISE_CLIENT_URLS=http://etcd.sphinx:2379 243 | - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379 244 | command: "etcd -name etcd-meme-aperture" 245 | 246 | aperture: 247 | # image: "lightninglabs/aperture:v0.1.12-beta" 248 | # hopefully this is a temporary replacement to use the new aperture 249 | # support for a timeout caveat 250 | image: "bucko/aperture:timeoutv2" 251 | container_name: aperture.sphinx 252 | profiles: 253 | - aperture 254 | ports: 255 | # for now we will have aperture run on the default meme port 256 | # so that it's easier to use this as a drop in replacement for any existing setups 257 | - 5555:8081 258 | volumes: 259 | - ./aperture:/aperture 260 | # using alice's lnd node as the backend for aperture 261 | - ./lnd/alice/.lnd:/lnd 262 | # want to restart on failure b/c the lightning node needs to be 263 | # fully operational so that aperture can connect to it and successfully start 264 | restart: on-failure 265 | depends_on: 266 | - etcd 267 | - alice-lnd 268 | entrypoint: ["aperture", "--configfile=/aperture/aperture.yaml"] 269 | 270 | # an override service that runs everything in the 271 | # depends_on list. Comment out to use overrides 272 | exclude-services: 273 | image: nginx 274 | command: echo done 275 | depends_on: 276 | - bitcoind 277 | - alice-lnd 278 | - bob-lnd 279 | - carol-lnd 280 | - lndsetup 281 | - db 282 | - tribes 283 | - auth 284 | - mqtt 285 | # - meme 286 | - alice 287 | - bob 288 | - carol 289 | - relaysetup 290 | - aperture 291 | - etcd 292 | profiles: 293 | - aperture 294 | 295 | boltwall: 296 | image: sphinxlightning/sphinx-boltwall 297 | # image: tobi-boltwall 298 | container_name: boltwall.sphinx 299 | restart: on-failure 300 | depends_on: 301 | - boltwallsetup 302 | volumes: 303 | - ./boltwall/.env:/usr/src/app/.env 304 | ports: 305 | - 8444:8444 306 | 307 | boltwallsetup: 308 | image: node:12-buster-slim 309 | restart: on-failure 310 | entrypoint: ["node", "/boltwall/setup/index.js"] 311 | volumes: 312 | - ./boltwall:/boltwall 313 | - ./boltwall/.env:/boltwall/.env 314 | - ./lnd:/lnd 315 | 316 | nav-fiber: 317 | image: sphinxlightning/sphinx-nav-fiber 318 | container_name: nav-fiber.sphinx 319 | restart: on-failure 320 | ports: 321 | - 3000:3000 322 | 323 | tribes-setup: 324 | image: node:12-buster-slim 325 | restart: on-failure 326 | entrypoint: ["node", "/tribes/setup/index.js"] 327 | depends_on: 328 | - relaysetup 329 | volumes: 330 | - ./tribes:/tribes 331 | - ./tribes/.env:/tribes/.env 332 | - ./relay:/relay 333 | 334 | jitsi-web: 335 | extends: 336 | file: ./jitsi/docker-compose.yml 337 | service: web 338 | container_name: jitsi-web.sphinx 339 | networks: 340 | meet.jitsi: 341 | profiles: 342 | - jitsi 343 | 344 | prosody: 345 | extends: 346 | file: ./jitsi/docker-compose.yml 347 | service: prosody 348 | container_name: prosody.sphinx 349 | networks: 350 | meet.jitsi: 351 | aliases: 352 | - ${XMPP_SERVER:-xmpp.meet.jitsi} 353 | profiles: 354 | - jitsi 355 | 356 | 357 | jicofo: 358 | extends: 359 | file: ./jitsi/docker-compose.yml 360 | service: jicofo 361 | container_name: jicofo.sphinx 362 | depends_on: 363 | - prosody 364 | networks: 365 | meet.jitsi: 366 | profiles: 367 | - jitsi 368 | 369 | jvb: 370 | extends: 371 | file: ./jitsi/docker-compose.yml 372 | service: jvb 373 | container_name: jvb.sphinx 374 | depends_on: 375 | - prosody 376 | networks: 377 | meet.jitsi: 378 | profiles: 379 | - jitsi 380 | 381 | networks: 382 | default: 383 | name: sphinx-stack 384 | meet.jitsi: 385 | 386 | -------------------------------------------------------------------------------- /docs/bots.md: -------------------------------------------------------------------------------- 1 | # building a Sphinx bot 2 | 3 | ### setup 4 | 5 | Setup and run the `sphinx-stack` cluster. 6 | 7 | But instead of just `docker-compose up -d` we want to run our bots aswell 8 | Ensure you're in the sphinx-stack directory, then run the following commads on your terminal: 9 | 10 | `chmod 777 ./start-bot.sh` 11 | 12 | `start-bot.sh` 13 | 14 | ### frontend 15 | 16 | Run one of the Sphinx frontends. The easiest one to get up and running is [sphinx-desktop](https://github.com/stakwork/sphinx-win-linux-desktop). This repository is for the Windows/Linux desktop app, but it runs fine on Mac as well. 17 | 18 | Once you have the Desktop App running, open the `NODES.json` file in `sphinx-stack/relay`. You will see an `exported_keys` string under "alice"... copy that string (make sure to include the trailing equals sign if it exists!). Enter the string into the Desktop App, then enter the PIN (111111). Now you are connected to the local Docker cluster! 19 | 20 | ![startup](https://github.com/stakwork/sphinx-stack/raw/master/docs/img/startup.png) 21 | 22 | Now our example bot is already running when we created the spinx-stack. 23 | 24 | The sphinx-example-bot is located under `./sphinx-stack/botSandBox/sphinx-example-bot` 25 | 26 | ### use the bot! 27 | 28 | Back in the Desktop App, create a new tribe using the main menu. In tribes that you create, you can run MotherBot commands to serach, install, and uninstall bots. 29 | 30 | - `/bot search example`: will return your newly created example bot 31 | - `/bot install example`: will install the bot in your new tribe! 32 | - `/example test`: will run the "test" command in your bot! 33 | 34 | ### make a change to the bot 35 | 36 | Open the file under `./sphinx-stack/botSandBox/sphinx-example-bot/index.js` and edit the response under `case 'test'` 37 | now try calling that command again.... CONGRATS!! You are offically a bot developer! 38 | -------------------------------------------------------------------------------- /docs/developingOnSphinx.md: -------------------------------------------------------------------------------- 1 | # Developing/Contributing on Sphinx-Stack! 2 | 3 | Hey there congragulations if you'd made it to this point you probably have already gotten `sphinx-stack` up and running are ready to develop either on its parts or around it (ie bots). If you havent reached this point yet we would recommend that you checkout the [setup tutorial](https://github.com/stakwork/sphinx-stack#readme). 4 | 5 | # Components to stack 6 | 7 | Now as may know there are multiple parts to the `sphinx-stack` some being but not limited to `sphinx-relay` `sphinx-tribes` `sphinx-meme` and more parts. 8 | 9 | As of now these are the components to the stack that are in the default `docker-compose.yml` 10 | 11 | ``` 12 | sphinx-relay [node typescript] 13 | alice.sphinx 14 | bob.sphinx 15 | carol.sphinx 16 | 17 | db (tribes db) [posgres] 18 | db.sphinx 19 | 20 | sphinx-tribes (GO lang and ReactJs Frontend) 21 | tribes.sphinx 22 | 23 | sphinx-auth [Go lang] 24 | auth.sphinx 25 | 26 | sphinx-mqtt [Go Lang] 27 | mqtt.sphinx 28 | 29 | sphinx-meme [Go Lang] 30 | meme.sphinx 31 | 32 | lightninglabs/lnd (lighting node) [not sphinx maintained] 33 | alice-lnd.sphinx 34 | bob-lnd.sphinx 35 | carol-lnd.sphinx 36 | 37 | lncm/bitcoind (bitcoin node) [not sphinx maintained] 38 | bitcoind.sphinx 39 | ``` 40 | 41 | But as you're developing on the sphinx infrastructure there maybe a few things you want to know or some knowlege base that you would like to have 42 | 43 | 1. How to modify image in the stack 44 | 2. How to troubleshoot stack if not working 45 | 46 | # How to modify an Image in the stack 47 | 48 | This is when we want to modify one of the containers that are running in the stack and I can run through the steps in an example 49 | Example 50 | Say we wanted to updtate `sphinx-relay` such that it clears your db's old message after a certain age. Then we must make a change in `sphinx-relay` so... 51 | 52 | 1. Make sure `sphinx-stack` is up and running, and test that the change is not working yet 53 | 2. Go into `sphinx-relay` and update the code 54 | 3. To update the image first do what every you need to build the code/make generated files locally for `sphinx-relay` this is `npm run build` 55 | 4. Now build the new image `docker build -t sphinxlightning/sphinx-relay .` (dont forget the dot at the end) 56 | 5. go back to `sphinx-stack` and run `docker-compose up -d` and it should restart the stack with the new changes you've made 57 | 6. **optional** if you come accross issues trying to run the stack it might be worth checking out the troubleshooting section 58 | 59 | And there you go you have offically modified an image in the stack, the proccess should be similar for every image you would want to update. 60 | 61 | # Troubleshooting the stack 62 | 63 | Now some times there will be issues with your stack and below are some common issues and how to resolve them and if none of these issues look like what you're experiencing head over to the [Developing on Sphinx Tribe](https://tribes.sphinx.chat/t/developingonsphinx) and there should be someone over there to help you 64 | 65 | 1. An error that looks something like this 66 | 67 | dockerDameonError 68 | 69 | This just means the `docker deamon` isnt running you just need to start that up and this error should go away 70 | 71 | 2. Simply is not working with tests or client 72 | 73 | This may be because the `./realy/NODES.json` file and the application trying to connect to the stack are not using the same info. A simple solution is doing the following in `sphinx-stack` 74 | 75 | > `docker-compose down` 76 | 77 | > `./clearAll.sh` 78 | 79 | > `docker-compose up -d` 80 | 81 | Then after the `./relay/NODES.json` file is generated then use that file wherever outside the stack 82 | 83 | 3. When the `./relay/NODES.json` file is not generating 84 | 85 | This is usually because the `sphinx-stack_relaysetup_1` container never exits, at this point you should be checking the logs of that container and also `alice,bob,carol.sphinx` containers aswell 86 | 87 | you can do this by doing 88 | 89 | `docker logs sphinx-stack_relaysetup_1` and `docker logs alice.sphinx` 90 | 91 | from there you need to debug what the issue is 92 | -------------------------------------------------------------------------------- /docs/img/bots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/docs/img/bots.png -------------------------------------------------------------------------------- /docs/img/newbot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/docs/img/newbot.png -------------------------------------------------------------------------------- /docs/img/startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/docs/img/startup.png -------------------------------------------------------------------------------- /init.sql: -------------------------------------------------------------------------------- 1 | 2 | 3 | CREATE TABLE media ( 4 | id TEXT NOT NULL PRIMARY KEY, 5 | owner_pub_key TEXT NOT NULL, 6 | name TEXT, 7 | description TEXT, 8 | price BIGINT, 9 | tags TEXT[] not null default '{}', 10 | ttl BIGINT, 11 | filename TEXT, 12 | size BIGINT, 13 | mime TEXT, 14 | nonce TEXT, 15 | created timestamptz, 16 | updated timestamptz, 17 | expiry timestamptz, -- optional permanent deletion of file 18 | total_sats BIGINT, 19 | total_buys BIGINT, 20 | template boolean, 21 | width INT, 22 | height INT 23 | ); 24 | 25 | ALTER TABLE media ADD COLUMN tsv tsvector; 26 | 27 | CREATE INDEX media_tsv ON media USING GIN(tsv); 28 | 29 | 30 | 31 | CREATE TABLE tribes ( 32 | uuid TEXT NOT NULL PRIMARY KEY, 33 | owner_pub_key TEXT NOT NULL, 34 | owner_alias TEXT, 35 | group_key TEXT, 36 | name TEXT, 37 | description TEXT, 38 | tags TEXT[] not null default '{}', 39 | img TEXT, 40 | price_to_join BIGINT, 41 | price_per_message BIGINT, 42 | escrow_amount BIGINT, 43 | escrow_millis BIGINT, 44 | created timestamptz, 45 | updated timestamptz, 46 | member_count BIGINT, 47 | unlisted boolean, 48 | private boolean, 49 | deleted boolean, 50 | app_url TEXT, 51 | feed_url TEXT, 52 | last_active BIGINT, 53 | bots TEXT, 54 | owner_route_hint TEXT, 55 | unique_name TEXT, 56 | feed_type INT, 57 | pin TEXT, 58 | preview TEXT, 59 | profile_filters TEXT, 60 | badges TEXT[] not null default '{}' 61 | ); 62 | 63 | ALTER TABLE tribes ADD COLUMN tsv tsvector; 64 | 65 | CREATE INDEX tribes_tsv ON tribes USING GIN(tsv); 66 | 67 | 68 | 69 | CREATE TABLE bots ( 70 | uuid TEXT NOT NULL PRIMARY KEY, 71 | owner_pub_key TEXT NOT NULL, 72 | owner_alias TEXT, 73 | name TEXT, 74 | unique_name TEXT, 75 | description TEXT, 76 | tags TEXT[] not null default '{}', 77 | img TEXT, 78 | price_per_use BIGINT, 79 | created timestamptz, 80 | updated timestamptz, 81 | member_count BIGINT, 82 | unlisted boolean, 83 | deleted boolean, 84 | owner_route_hint text 85 | ); 86 | 87 | ALTER TABLE bots ADD COLUMN tsv tsvector; 88 | 89 | CREATE INDEX bots_tsv ON bots USING GIN(tsv); 90 | 91 | 92 | 93 | 94 | 95 | CREATE TABLE people ( 96 | id SERIAL PRIMARY KEY, 97 | uuid TEXT, 98 | owner_pub_key TEXT NOT NULL, 99 | owner_alias TEXT, 100 | owner_route_hint TEXT, 101 | owner_contact_key TEXT, 102 | description TEXT, 103 | tags TEXT[] not null default '{}', 104 | img TEXT, 105 | created timestamptz, 106 | updated timestamptz, 107 | unlisted boolean, 108 | deleted boolean, 109 | unique_name TEXT, 110 | price_to_meet BIGINT, 111 | extras JSONB, 112 | twitter_confirmed BOOLEAN, 113 | github_issues JSONB 114 | ); 115 | 116 | ALTER TABLE people ADD COLUMN tsv tsvector; 117 | 118 | CREATE INDEX people_tsv ON people USING GIN(tsv); -------------------------------------------------------------------------------- /jitsi/.env: -------------------------------------------------------------------------------- 1 | # shellcheck disable=SC2034 2 | 3 | ################################################################################ 4 | ################################################################################ 5 | # Welcome to the Jitsi Meet Docker setup! 6 | # 7 | # This sample .env file contains some basic options to get you started. 8 | # The full options reference can be found here: 9 | # https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker 10 | ################################################################################ 11 | ################################################################################ 12 | 13 | 14 | # 15 | # Basic configuration options 16 | # 17 | 18 | # Directory where all configuration will be stored 19 | CONFIG=~/.jitsi-meet-cfg 20 | 21 | # Exposed HTTP port 22 | HTTP_PORT=8000 23 | 24 | # Exposed HTTPS port 25 | HTTPS_PORT=8443 26 | 27 | # System time zone 28 | TZ=UTC 29 | 30 | # Public URL for the web service (required) 31 | #PUBLIC_URL=https://meet.example.com 32 | 33 | # Media IP addresses to advertise by the JVB 34 | # This setting deprecates DOCKER_HOST_ADDRESS, and supports a comma separated list of IPs 35 | # See the "Running behind NAT or on a LAN environment" section in the Handbook: 36 | # https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker#running-behind-nat-or-on-a-lan-environment 37 | #JVB_ADVERTISE_IPS=192.168.1.1,1.2.3.4 38 | 39 | 40 | # 41 | # JaaS Components (beta) 42 | # https://jaas.8x8.vc 43 | # 44 | 45 | # Enable JaaS Components (hosted Jigasi) 46 | # NOTE: if Let's Encrypt is enabled a JaaS account will be automatically created, using the provided email in LETSENCRYPT_EMAIL 47 | #ENABLE_JAAS_COMPONENTS=0 48 | 49 | # 50 | # Let's Encrypt configuration 51 | # 52 | 53 | # Enable Let's Encrypt certificate generation 54 | #ENABLE_LETSENCRYPT=1 55 | 56 | # Domain for which to generate the certificate 57 | #LETSENCRYPT_DOMAIN=meet.example.com 58 | 59 | # E-Mail for receiving important account notifications (mandatory) 60 | #LETSENCRYPT_EMAIL=alice@atlanta.net 61 | 62 | # Use the staging server (for avoiding rate limits while testing) 63 | #LETSENCRYPT_USE_STAGING=1 64 | 65 | 66 | # 67 | # Etherpad integration (for document sharing) 68 | # 69 | 70 | # Set etherpad-lite URL in docker local network (uncomment to enable) 71 | #ETHERPAD_URL_BASE=http://etherpad.meet.jitsi:9001 72 | 73 | # Set etherpad-lite public URL, including /p/ pad path fragment (uncomment to enable) 74 | #ETHERPAD_PUBLIC_URL=https://etherpad.my.domain/p/ 75 | 76 | # Name your etherpad instance! 77 | ETHERPAD_TITLE=Video Chat 78 | 79 | # The default text of a pad 80 | ETHERPAD_DEFAULT_PAD_TEXT="Welcome to Web Chat!\n\n" 81 | 82 | # Name of the skin for etherpad 83 | ETHERPAD_SKIN_NAME=colibris 84 | 85 | # Skin variants for etherpad 86 | ETHERPAD_SKIN_VARIANTS="super-light-toolbar super-light-editor light-background full-width-editor" 87 | 88 | 89 | # 90 | # Basic Jigasi configuration options (needed for SIP gateway support) 91 | # 92 | 93 | # SIP URI for incoming / outgoing calls 94 | #JIGASI_SIP_URI=test@sip2sip.info 95 | 96 | # Password for the specified SIP account as a clear text 97 | #JIGASI_SIP_PASSWORD=passw0rd 98 | 99 | # SIP server (use the SIP account domain if in doubt) 100 | #JIGASI_SIP_SERVER=sip2sip.info 101 | 102 | # SIP server port 103 | #JIGASI_SIP_PORT=5060 104 | 105 | # SIP server transport 106 | #JIGASI_SIP_TRANSPORT=UDP 107 | 108 | 109 | # 110 | # Authentication configuration (see handbook for details) 111 | # 112 | 113 | # Enable authentication 114 | #ENABLE_AUTH=1 115 | 116 | # Enable guest access 117 | #ENABLE_GUESTS=1 118 | 119 | # Select authentication type: internal, jwt, ldap or matrix 120 | #AUTH_TYPE=internal 121 | 122 | # JWT authentication 123 | # 124 | 125 | # Application identifier 126 | #JWT_APP_ID=my_jitsi_app_id 127 | 128 | # Application secret known only to your token generator 129 | #JWT_APP_SECRET=my_jitsi_app_secret 130 | 131 | # (Optional) Set asap_accepted_issuers as a comma separated list 132 | #JWT_ACCEPTED_ISSUERS=my_web_client,my_app_client 133 | 134 | # (Optional) Set asap_accepted_audiences as a comma separated list 135 | #JWT_ACCEPTED_AUDIENCES=my_server1,my_server2 136 | 137 | # LDAP authentication (for more information see the Cyrus SASL saslauthd.conf man page) 138 | # 139 | 140 | # LDAP url for connection 141 | #LDAP_URL=ldaps://ldap.domain.com/ 142 | 143 | # LDAP base DN. Can be empty 144 | #LDAP_BASE=DC=example,DC=domain,DC=com 145 | 146 | # LDAP user DN. Do not specify this parameter for the anonymous bind 147 | #LDAP_BINDDN=CN=binduser,OU=users,DC=example,DC=domain,DC=com 148 | 149 | # LDAP user password. Do not specify this parameter for the anonymous bind 150 | #LDAP_BINDPW=LdapUserPassw0rd 151 | 152 | # LDAP filter. Tokens example: 153 | # %1-9 - if the input key is user@mail.domain.com, then %1 is com, %2 is domain and %3 is mail 154 | # %s - %s is replaced by the complete service string 155 | # %r - %r is replaced by the complete realm string 156 | #LDAP_FILTER=(sAMAccountName=%u) 157 | 158 | # LDAP authentication method 159 | #LDAP_AUTH_METHOD=bind 160 | 161 | # LDAP version 162 | #LDAP_VERSION=3 163 | 164 | # LDAP TLS using 165 | #LDAP_USE_TLS=1 166 | 167 | # List of SSL/TLS ciphers to allow 168 | #LDAP_TLS_CIPHERS=SECURE256:SECURE128:!AES-128-CBC:!ARCFOUR-128:!CAMELLIA-128-CBC:!3DES-CBC:!CAMELLIA-128-CBC 169 | 170 | # Require and verify server certificate 171 | #LDAP_TLS_CHECK_PEER=1 172 | 173 | # Path to CA cert file. Used when server certificate verify is enabled 174 | #LDAP_TLS_CACERT_FILE=/etc/ssl/certs/ca-certificates.crt 175 | 176 | # Path to CA certs directory. Used when server certificate verify is enabled 177 | #LDAP_TLS_CACERT_DIR=/etc/ssl/certs 178 | 179 | # Wether to use starttls, implies LDAPv3 and requires ldap:// instead of ldaps:// 180 | # LDAP_START_TLS=1 181 | 182 | 183 | # 184 | # Security 185 | # 186 | # Set these to strong passwords to avoid intruders from impersonating a service account 187 | # The service(s) won't start unless these are specified 188 | # Running ./gen-passwords.sh will update .env with strong passwords 189 | # You may skip the Jigasi and Jibri passwords if you are not using those 190 | # DO NOT reuse passwords 191 | # 192 | 193 | # XMPP password for Jicofo client connections 194 | JICOFO_AUTH_PASSWORD=a2095994a39db788838cdb37916291e2 195 | 196 | # XMPP password for JVB client connections 197 | JVB_AUTH_PASSWORD=f04e4edddb14346744f24192c961a6f8 198 | 199 | # XMPP password for Jigasi MUC client connections 200 | JIGASI_XMPP_PASSWORD=44b6f82f3a22e865c09ca232a92d47f4 201 | 202 | # XMPP recorder password for Jibri client connections 203 | JIBRI_RECORDER_PASSWORD=b417481a05df96dea10bc94d473acf3c 204 | 205 | # XMPP password for Jibri client connections 206 | JIBRI_XMPP_PASSWORD=de1ce0c12a1718a307f6d0e97dfd729f 207 | 208 | # 209 | # Docker Compose options 210 | # 211 | 212 | # Container restart policy 213 | #RESTART_POLICY=unless-stopped 214 | 215 | # Jitsi image version (useful for local development) 216 | #JITSI_IMAGE_VERSION=latest 217 | -------------------------------------------------------------------------------- /jitsi/README.md: -------------------------------------------------------------------------------- 1 | # Sphinx-Jitsi 2 | 3 | Jitsi is a collection of open source projects that provide state-of-the-art video conferencing capabilities that are secure, easy to use, and easy to self-host. 4 | Sphinx uses Jitsi to host virtual meetings for one-to-one calls and tribe calls. Sphinx Jitsi now runs on Docker, using the Docker compose file directly. 5 | 6 | The Sphinx Jitsi stack comprises four services: 7 | 8 | - jitsi-web.sphinx: Jitsi meet web UI, served with nginx. 9 | - prosody.sphinx: the XMPP server. 10 | - jicofo.sphinx: the XMPP focus component. 11 | - jvb.sphinx: the video router. 12 | 13 | ### run 14 | 15 | Running the Sphinx stack (docker compose in the root directory) spins up the entire Sphinx infrastructure. 16 | which include tribe, relay, boltwall, and so on. Along side sphinx jitsi. 17 | 18 | *Read more: https://jitsi.github.io/handbook/docs/devops-guide/devops-guide-docker/* -------------------------------------------------------------------------------- /jitsi/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | services: 4 | # Frontend 5 | web: 6 | image: jitsi/web:${JITSI_IMAGE_VERSION:-stable-8138-1} 7 | restart: ${RESTART_POLICY:-unless-stopped} 8 | ports: 9 | - 8000:80 10 | - 8443:443 11 | volumes: 12 | - ./config/web:/config:Z 13 | - ./config/web/crontabs:/var/spool/cron/crontabs:Z 14 | - ./config/transcripts:/usr/share/jitsi-meet/transcripts:Z 15 | environment: 16 | - AMPLITUDE_ID 17 | - ANALYTICS_SCRIPT_URLS 18 | - ANALYTICS_WHITELISTED_EVENTS 19 | - AUDIO_QUALITY_OPUS_BITRATE 20 | - AUTO_CAPTION_ON_RECORD 21 | - BRANDING_DATA_URL 22 | - CALLSTATS_CUSTOM_SCRIPT_URL 23 | - CALLSTATS_ID 24 | - CALLSTATS_SECRET 25 | - CHROME_EXTENSION_BANNER_JSON 26 | - CONFCODE_URL 27 | - CONFIG_EXTERNAL_CONNECT 28 | - DEFAULT_LANGUAGE 29 | - DEPLOYMENTINFO_ENVIRONMENT 30 | - DEPLOYMENTINFO_ENVIRONMENT_TYPE 31 | - DEPLOYMENTINFO_REGION 32 | - DEPLOYMENTINFO_SHARD 33 | - DEPLOYMENTINFO_USERREGION 34 | - DESKTOP_SHARING_FRAMERATE_MIN 35 | - DESKTOP_SHARING_FRAMERATE_MAX 36 | - DIALIN_NUMBERS_URL 37 | - DIALOUT_AUTH_URL 38 | - DIALOUT_CODES_URL 39 | - DISABLE_AUDIO_LEVELS 40 | - DISABLE_DEEP_LINKING 41 | - DISABLE_GRANT_MODERATOR 42 | - DISABLE_HTTPS 43 | - DISABLE_KICKOUT 44 | - DISABLE_LOCAL_RECORDING 45 | - DISABLE_POLLS 46 | - DISABLE_PRIVATE_CHAT 47 | - DISABLE_PROFILE 48 | - DISABLE_REACTIONS 49 | - DISABLE_REMOTE_VIDEO_MENU 50 | - DISABLE_START_FOR_ALL 51 | - DROPBOX_APPKEY 52 | - DROPBOX_REDIRECT_URI 53 | - DYNAMIC_BRANDING_URL 54 | - ENABLE_AUDIO_PROCESSING 55 | - ENABLE_AUTH 56 | - ENABLE_BREAKOUT_ROOMS 57 | - ENABLE_CALENDAR 58 | - ENABLE_COLIBRI_WEBSOCKET 59 | - ENABLE_E2EPING 60 | - ENABLE_FILE_RECORDING_SHARING 61 | - ENABLE_GUESTS 62 | - ENABLE_HSTS 63 | - ENABLE_HTTP_REDIRECT 64 | - ENABLE_IPV6 65 | - ENABLE_LETSENCRYPT 66 | - ENABLE_LIPSYNC 67 | - ENABLE_NO_AUDIO_DETECTION 68 | - ENABLE_NOISY_MIC_DETECTION 69 | - ENABLE_OCTO 70 | - ENABLE_OPUS_RED 71 | - ENABLE_PREJOIN_PAGE 72 | - ENABLE_P2P 73 | - ENABLE_WELCOME_PAGE 74 | - ENABLE_CLOSE_PAGE 75 | - ENABLE_LIVESTREAMING 76 | - ENABLE_LOCAL_RECORDING_NOTIFY_ALL_PARTICIPANT 77 | - ENABLE_LOCAL_RECORDING_SELF_START 78 | - ENABLE_RECORDING 79 | - ENABLE_REMB 80 | - ENABLE_REQUIRE_DISPLAY_NAME 81 | - ENABLE_SERVICE_RECORDING 82 | - ENABLE_SIMULCAST 83 | - ENABLE_STATS_ID 84 | - ENABLE_STEREO 85 | - ENABLE_SUBDOMAINS 86 | - ENABLE_TALK_WHILE_MUTED 87 | - ENABLE_TCC 88 | - ENABLE_TRANSCRIPTIONS 89 | - ENABLE_XMPP_WEBSOCKET 90 | - ENABLE_JAAS_COMPONENTS 91 | - ETHERPAD_PUBLIC_URL 92 | - ETHERPAD_URL_BASE 93 | - E2EPING_NUM_REQUESTS 94 | - E2EPING_MAX_CONFERENCE_SIZE 95 | - E2EPING_MAX_MESSAGE_PER_SECOND 96 | - GOOGLE_ANALYTICS_ID 97 | - GOOGLE_API_APP_CLIENT_ID 98 | - HIDE_PREMEETING_BUTTONS 99 | - HIDE_PREJOIN_DISPLAY_NAME 100 | - HIDE_PREJOIN_EXTRA_BUTTONS 101 | - INVITE_SERVICE_URL 102 | - JICOFO_AUTH_USER 103 | - LETSENCRYPT_DOMAIN 104 | - LETSENCRYPT_EMAIL 105 | - LETSENCRYPT_USE_STAGING 106 | - MATOMO_ENDPOINT 107 | - MATOMO_SITE_ID 108 | - MICROSOFT_API_APP_CLIENT_ID 109 | - NGINX_RESOLVER 110 | - NGINX_WORKER_PROCESSES 111 | - NGINX_WORKER_CONNECTIONS 112 | - PEOPLE_SEARCH_URL 113 | - PREFERRED_LANGUAGE 114 | - PUBLIC_URL 115 | - P2P_PREFERRED_CODEC 116 | - RESOLUTION 117 | - RESOLUTION_MIN 118 | - RESOLUTION_WIDTH 119 | - RESOLUTION_WIDTH_MIN 120 | - START_AUDIO_MUTED 121 | - START_AUDIO_ONLY 122 | - START_BITRATE 123 | - START_SILENT 124 | - START_WITH_AUDIO_MUTED 125 | - START_VIDEO_MUTED 126 | - START_WITH_VIDEO_MUTED 127 | - TESTING_CAP_SCREENSHARE_BITRATE 128 | - TESTING_OCTO_PROBABILITY 129 | - TOKEN_AUTH_URL 130 | - TOOLBAR_BUTTONS 131 | - TRANSLATION_LANGUAGES 132 | - TRANSLATION_LANGUAGES_HEAD 133 | - TZ 134 | - USE_APP_LANGUAGE 135 | - VIDEOQUALITY_BITRATE_H264_LOW 136 | - VIDEOQUALITY_BITRATE_H264_STANDARD 137 | - VIDEOQUALITY_BITRATE_H264_HIGH 138 | - VIDEOQUALITY_BITRATE_VP8_LOW 139 | - VIDEOQUALITY_BITRATE_VP8_STANDARD 140 | - VIDEOQUALITY_BITRATE_VP8_HIGH 141 | - VIDEOQUALITY_BITRATE_VP9_LOW 142 | - VIDEOQUALITY_BITRATE_VP9_STANDARD 143 | - VIDEOQUALITY_BITRATE_VP9_HIGH 144 | - VIDEOQUALITY_ENFORCE_PREFERRED_CODEC 145 | - VIDEOQUALITY_PREFERRED_CODEC 146 | - XMPP_AUTH_DOMAIN 147 | - XMPP_BOSH_URL_BASE 148 | - XMPP_DOMAIN 149 | - XMPP_GUEST_DOMAIN 150 | - XMPP_MUC_DOMAIN 151 | - XMPP_RECORDER_DOMAIN 152 | - XMPP_PORT 153 | # networks: 154 | # meet.jitsi: 155 | 156 | # XMPP server 157 | prosody: 158 | image: jitsi/prosody:${JITSI_IMAGE_VERSION:-stable-8138-1} 159 | restart: ${RESTART_POLICY:-unless-stopped} 160 | expose: 161 | - '${XMPP_PORT:-5222}' 162 | - '5347' 163 | - '5280' 164 | volumes: 165 | - ./config/prosody/config:/config:Z 166 | - ./config/prosody/prosody-plugins-custom:/prosody-plugins-custom:Z 167 | environment: 168 | - AUTH_TYPE 169 | - DISABLE_POLLS 170 | - ENABLE_AUTH 171 | - ENABLE_AV_MODERATION 172 | - ENABLE_BREAKOUT_ROOMS 173 | - ENABLE_END_CONFERENCE 174 | - ENABLE_GUESTS 175 | - ENABLE_IPV6 176 | - ENABLE_LOBBY 177 | - ENABLE_RECORDING 178 | - ENABLE_XMPP_WEBSOCKET 179 | - ENABLE_JAAS_COMPONENTS 180 | - GC_TYPE 181 | - GC_INC_TH 182 | - GC_INC_SPEED 183 | - GC_INC_STEP_SIZE 184 | - GC_GEN_MIN_TH 185 | - GC_GEN_MAX_TH 186 | - GLOBAL_CONFIG 187 | - GLOBAL_MODULES 188 | - JIBRI_RECORDER_USER 189 | - JIBRI_RECORDER_PASSWORD 190 | - JIBRI_XMPP_USER 191 | - JIBRI_XMPP_PASSWORD 192 | - JICOFO_AUTH_USER 193 | - JICOFO_AUTH_PASSWORD=a2095994a39db788838cdb37916291e2 194 | - JICOFO_COMPONENT_SECRET 195 | - JIGASI_XMPP_USER 196 | - JIGASI_XMPP_PASSWORD=44b6f82f3a22e865c09ca232a92d47f4 197 | - JVB_AUTH_USER 198 | - JVB_AUTH_PASSWORD=f04e4edddb14346744f24192c961a6f8 199 | - JWT_APP_ID 200 | - JWT_APP_SECRET 201 | - JWT_ACCEPTED_ISSUERS 202 | - JWT_ACCEPTED_AUDIENCES 203 | - JWT_ASAP_KEYSERVER 204 | - JWT_ALLOW_EMPTY 205 | - JWT_AUTH_TYPE 206 | - JWT_ENABLE_DOMAIN_VERIFICATION 207 | - JWT_TOKEN_AUTH_MODULE 208 | - MATRIX_UVS_URL 209 | - MATRIX_UVS_ISSUER 210 | - MATRIX_UVS_AUTH_TOKEN 211 | - MATRIX_UVS_SYNC_POWER_LEVELS 212 | - LOG_LEVEL 213 | - LDAP_AUTH_METHOD 214 | - LDAP_BASE 215 | - LDAP_BINDDN 216 | - LDAP_BINDPW 217 | - LDAP_FILTER 218 | - LDAP_VERSION 219 | - LDAP_TLS_CIPHERS 220 | - LDAP_TLS_CHECK_PEER 221 | - LDAP_TLS_CACERT_FILE 222 | - LDAP_TLS_CACERT_DIR 223 | - LDAP_START_TLS 224 | - LDAP_URL 225 | - LDAP_USE_TLS 226 | - MAX_PARTICIPANTS 227 | - PROSODY_RESERVATION_ENABLED 228 | - PROSODY_RESERVATION_REST_BASE_URL 229 | - PUBLIC_URL 230 | - TURN_CREDENTIALS 231 | - TURN_HOST 232 | - TURNS_HOST 233 | - TURN_PORT 234 | - TURNS_PORT 235 | - TURN_TRANSPORT 236 | - TZ 237 | - XMPP_DOMAIN 238 | - XMPP_AUTH_DOMAIN 239 | - XMPP_GUEST_DOMAIN 240 | - XMPP_MUC_DOMAIN 241 | - XMPP_INTERNAL_MUC_DOMAIN 242 | - XMPP_MODULES 243 | - XMPP_MUC_MODULES 244 | - XMPP_MUC_CONFIGURATION 245 | - XMPP_INTERNAL_MUC_MODULES 246 | - XMPP_RECORDER_DOMAIN 247 | - XMPP_PORT 248 | # networks: 249 | # meet.jitsi: 250 | # aliases: 251 | # - ${XMPP_SERVER:-xmpp.meet.jitsi} 252 | 253 | # Focus component 254 | jicofo: 255 | image: jitsi/jicofo:${JITSI_IMAGE_VERSION:-stable-8138-1} 256 | restart: ${RESTART_POLICY:-unless-stopped} 257 | volumes: 258 | - ./config/jicofo:/config:Z 259 | environment: 260 | - AUTH_TYPE 261 | - BRIDGE_AVG_PARTICIPANT_STRESS 262 | - BRIDGE_STRESS_THRESHOLD 263 | - ENABLE_AUTH 264 | - ENABLE_AUTO_OWNER 265 | - ENABLE_CODEC_VP8 266 | - ENABLE_CODEC_VP9 267 | - ENABLE_CODEC_H264 268 | - ENABLE_OCTO 269 | - ENABLE_RECORDING 270 | - ENABLE_SCTP 271 | - ENABLE_AUTO_LOGIN 272 | - JICOFO_AUTH_USER 273 | - JICOFO_AUTH_PASSWORD=a2095994a39db788838cdb37916291e2 274 | - JICOFO_ENABLE_BRIDGE_HEALTH_CHECKS 275 | - JICOFO_CONF_INITIAL_PARTICIPANT_WAIT_TIMEOUT 276 | - JICOFO_CONF_SINGLE_PARTICIPANT_TIMEOUT 277 | - JICOFO_ENABLE_HEALTH_CHECKS 278 | - JIBRI_BREWERY_MUC 279 | - JIBRI_REQUEST_RETRIES 280 | - JIBRI_PENDING_TIMEOUT 281 | - JIGASI_BREWERY_MUC 282 | - JIGASI_SIP_URI 283 | - JVB_BREWERY_MUC 284 | - MAX_BRIDGE_PARTICIPANTS 285 | - OCTO_BRIDGE_SELECTION_STRATEGY 286 | - SENTRY_DSN="${JICOFO_SENTRY_DSN:-0}" 287 | - SENTRY_ENVIRONMENT 288 | - SENTRY_RELEASE 289 | - TZ 290 | - XMPP_DOMAIN 291 | - XMPP_AUTH_DOMAIN 292 | - XMPP_INTERNAL_MUC_DOMAIN 293 | - XMPP_MUC_DOMAIN 294 | - XMPP_RECORDER_DOMAIN 295 | - XMPP_SERVER 296 | - XMPP_PORT 297 | # networks: 298 | # meet.jitsi: 299 | 300 | # Video bridge 301 | jvb: 302 | image: jitsi/jvb:${JITSI_IMAGE_VERSION:-stable-8138-1} 303 | restart: ${RESTART_POLICY:-unless-stopped} 304 | ports: 305 | - '${JVB_PORT:-10000}:${JVB_PORT:-10000}/udp' 306 | - '127.0.0.1:${JVB_COLIBRI_PORT:-8080}:8080' 307 | volumes: 308 | - ./config/jvb:/config:Z 309 | environment: 310 | - DOCKER_HOST_ADDRESS 311 | - ENABLE_COLIBRI_WEBSOCKET 312 | - ENABLE_OCTO 313 | - JVB_ADVERTISE_IPS 314 | - JVB_ADVERTISE_PRIVATE_CANDIDATES 315 | - JVB_AUTH_USER 316 | - JVB_AUTH_PASSWORD=f04e4edddb14346744f24192c961a6f8 317 | - JVB_BREWERY_MUC 318 | - JVB_DISABLE_STUN 319 | - JVB_PORT 320 | - JVB_MUC_NICKNAME 321 | - JVB_STUN_SERVERS 322 | - JVB_OCTO_BIND_ADDRESS 323 | - JVB_OCTO_REGION 324 | - JVB_OCTO_RELAY_ID 325 | - JVB_WS_DOMAIN 326 | - JVB_WS_SERVER_ID 327 | - PUBLIC_URL 328 | - SENTRY_DSN="${JVB_SENTRY_DSN:-0}" 329 | - SENTRY_ENVIRONMENT 330 | - SENTRY_RELEASE 331 | - COLIBRI_REST_ENABLED 332 | - SHUTDOWN_REST_ENABLED 333 | - TZ 334 | - XMPP_AUTH_DOMAIN 335 | - XMPP_INTERNAL_MUC_DOMAIN 336 | - XMPP_SERVER 337 | - XMPP_PORT 338 | # networks: 339 | # meet.jitsi: 340 | 341 | # Custom network so all services can communicate using a FQDN 342 | #networks: 343 | # meet.jitsi: 344 | -------------------------------------------------------------------------------- /jitsi/setup.sh: -------------------------------------------------------------------------------- 1 | RESTART_POLICY=unless-stopped 2 | HTTP_PORT=8000 3 | HTTPS_PORT=8443 4 | # XMPP password for Jicofo client connections 5 | JICOFO_AUTH_PASSWORD=a2095994a39db788838cdb37916291e2 6 | 7 | # XMPP password for JVB client connections 8 | JVB_AUTH_PASSWORD=f04e4edddb14346744f24192c961a6f8 9 | 10 | # XMPP password for Jigasi MUC client connections 11 | JIGASI_XMPP_PASSWORD=44b6f82f3a22e865c09ca232a92d47f4 12 | 13 | # XMPP recorder password for Jibri client connections 14 | JIBRI_RECORDER_PASSWORD=b417481a05df96dea10bc94d473acf3c 15 | 16 | # XMPP password for Jibri client connections 17 | JIBRI_XMPP_PASSWORD=de1ce0c12a1718a307f6d0e97dfd729f 18 | 19 | export RESTART_POLICY 20 | export HTTP_PORT 21 | export HTTPS_PORT 22 | export JICOFO_AUTH_PASSWORD 23 | export JVB_AUTH_PASSWORD 24 | export JIGASI_XMPP_PASSWORD 25 | export JIBRI_RECORDER_PASSWORD 26 | export JIBRI_XMPP_PASSWORD -------------------------------------------------------------------------------- /lnd/setup/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | package-lock.json -------------------------------------------------------------------------------- /lnd/setup/alice.conf: -------------------------------------------------------------------------------- 1 | bitcoin.active=true 2 | bitcoin.regtest=true 3 | debuglevel=info 4 | rpclisten=0.0.0.0:10009 5 | restlisten=0.0.0.0:38881 6 | tlsextradomain=alice-lnd.sphinx 7 | accept-keysend=true 8 | alias=alice-lnd 9 | bitcoin.node=bitcoind 10 | bitcoin.defaultchanconfs=2 11 | bitcoind.rpcuser=evan 12 | bitcoind.rpcpass=thepass 13 | bitcoind.rpchost=bitcoind.sphinx 14 | bitcoind.zmqpubrawblock=tcp://bitcoind.sphinx:28332 15 | bitcoind.zmqpubrawtx=tcp://bitcoind.sphinx:28333 -------------------------------------------------------------------------------- /lnd/setup/bitcoind.js: -------------------------------------------------------------------------------- 1 | const fetch = require("./fetch"); 2 | 3 | async function mine(n, addy) { 4 | try { 5 | let num = n || 1; 6 | const r = await fetch("http://evan:thepass@bitcoind.sphinx:18443", { 7 | method: "POST", 8 | body: JSON.stringify({ 9 | jsonrpc: "1.0", 10 | id: "1", 11 | method: "generatetoaddress", 12 | params: [num, addy], 13 | }), 14 | }); 15 | const j = await r.text(); 16 | return j; 17 | } catch (e) { 18 | throw e; 19 | } 20 | } 21 | 22 | module.exports = { 23 | mine, 24 | }; 25 | -------------------------------------------------------------------------------- /lnd/setup/bob.conf: -------------------------------------------------------------------------------- 1 | bitcoin.active=true 2 | bitcoin.regtest=true 3 | debuglevel=info 4 | rpclisten=0.0.0.0:10010 5 | restlisten=0.0.0.0:38882 6 | tlsextradomain=bob-lnd.sphinx 7 | accept-keysend=true 8 | alias=bob-lnd 9 | bitcoin.node=bitcoind 10 | bitcoin.defaultchanconfs=2 11 | bitcoind.rpcuser=evan 12 | bitcoind.rpcpass=thepass 13 | bitcoind.rpchost=bitcoind.sphinx 14 | bitcoind.zmqpubrawblock=tcp://bitcoind.sphinx:28332 15 | bitcoind.zmqpubrawtx=tcp://bitcoind.sphinx:28333 -------------------------------------------------------------------------------- /lnd/setup/carol.conf: -------------------------------------------------------------------------------- 1 | bitcoin.active=true 2 | bitcoin.regtest=true 3 | debuglevel=info 4 | rpclisten=0.0.0.0:10011 5 | restlisten=0.0.0.0:38883 6 | tlsextradomain=carol-lnd.sphinx 7 | accept-keysend=true 8 | alias=carol-lnd 9 | bitcoin.node=bitcoind 10 | bitcoin.defaultchanconfs=2 11 | bitcoind.rpcuser=evan 12 | bitcoind.rpcpass=thepass 13 | bitcoind.rpchost=bitcoind.sphinx 14 | bitcoind.zmqpubrawblock=tcp://bitcoind.sphinx:28332 15 | bitcoind.zmqpubrawtx=tcp://bitcoind.sphinx:28333 -------------------------------------------------------------------------------- /lnd/setup/dave.conf: -------------------------------------------------------------------------------- 1 | bitcoin.active=true 2 | bitcoin.regtest=true 3 | debuglevel=info 4 | rpclisten=0.0.0.0:10012 5 | restlisten=0.0.0.0:38884 6 | tlsextradomain=dave-lnd.sphinx 7 | accept-keysend=true 8 | alias=dave-lnd 9 | bitcoin.node=bitcoind 10 | bitcoin.defaultchanconfs=2 11 | bitcoind.rpcuser=evan 12 | bitcoind.rpcpass=thepass 13 | bitcoind.rpchost=bitcoind.sphinx 14 | bitcoind.zmqpubrawblock=tcp://bitcoind.sphinx:28332 15 | bitcoind.zmqpubrawtx=tcp://bitcoind.sphinx:28333 16 | -------------------------------------------------------------------------------- /lnd/setup/index.js: -------------------------------------------------------------------------------- 1 | var wallet = require("./wallet"); 2 | var nodes = require("./nodes"); 3 | var lightning = require("./lightning"); 4 | var bitcoind = require("./bitcoind"); 5 | 6 | if (process.env.PROXY === "true") { 7 | console.log("test proxy nodes!"); 8 | nodes = require("./nodes/proxynodes"); 9 | } 10 | 11 | if (process.env.CLN_PROXY === "true") { 12 | console.log("test cln proxy nodes!"); 13 | nodes = require("./nodes/clnProxyNodes"); 14 | } 15 | // if (process.env.DAVE_IP) { 16 | // if (nodes.nodes["dave"]) { 17 | // nodes.nodes["dave"].hostname = process.env.DAVE_IP; 18 | // } 19 | // } 20 | 21 | async function createOrUnlockWallet(node) { 22 | if (node.type === "lnd") { 23 | console.log("[LND] setup", node.alias); 24 | try { 25 | const r = await wallet.initWallet(node); 26 | console.log("[LND] INIT WALLET", node.alias); 27 | 28 | //code is the "wallet already exisits" code there is also an error message in r 29 | // we go into this block of code if we've already initialized a wallet for the node 30 | if (r.code === 2) { 31 | // first mine blocks 32 | await bitcoind.mine(6, "bcrt1qsrq4qj4zgwyj8hpsnpgeeh0p0aqfe5vqhv7yrr"); 33 | const r2 = await wallet.unlockWallet(node); 34 | console.log("[LND] WALLET UNLOCKED", node.alias); 35 | } 36 | } catch (e) { 37 | console.log("=> err", e); 38 | } 39 | } 40 | } 41 | 42 | async function coinsAndChannels(node) { 43 | try { 44 | const coins_success = await coins(node); 45 | if (coins_success) { 46 | await channels(node); 47 | } 48 | } catch (e) { 49 | console.log("=> err", e); 50 | } 51 | } 52 | 53 | async function coins(node) { 54 | try { 55 | const balres = await lightning.getBalance(node); 56 | const confirmed = parseInt(balres.confirmed_balance); 57 | console.log("=> ALICE confirmed balance:", confirmed); 58 | if (!confirmed) { 59 | const ares = await lightning.newAddress(node); 60 | const addy = ares.address; 61 | console.log("=> ALICE address", addy); 62 | await bitcoind.mine(101, addy); 63 | console.log("=> 101 blocks mined to alice!", addy); 64 | await sleep(5000); 65 | } 66 | return true; 67 | } catch (e) { 68 | console.log("=> err:", e); 69 | } 70 | } 71 | 72 | async function channels(node) { 73 | try { 74 | const ps = await lightning.listPeers(node); 75 | const peers = ps.peers; 76 | const peersToMake = node.channels 77 | ? node.channels.filter((ch) => { 78 | const exists = peers.find((p) => p.pub_key === ch.pubkey); 79 | return exists ? false : true; 80 | }) 81 | : []; 82 | console.log("peers to make:", peersToMake); 83 | await asyncForEach(peersToMake, async (p) => { 84 | await lightning.addPeer(node, p); 85 | }); 86 | 87 | const chans = await lightning.listChannels(node); 88 | const channels = chans.channels || []; 89 | await bitcoind.mine(6, "bcrt1qsrq4qj4zgwyj8hpsnpgeeh0p0aqfe5vqhv7yrr"); 90 | console.log("=> 6 blocked mined to Alice!"); 91 | await sleep(20000); 92 | if (!channels.length) { 93 | console.log("=> alice opening channels..."); 94 | // open channels here 95 | await asyncForEach(peersToMake, async (p) => { 96 | console.log("open channel with:", p); 97 | 98 | //create a small channel for bob, to ensure sats reversal works 99 | if ( 100 | p.pubkey === 101 | "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d" 102 | ) { 103 | await lightning.openChannel(node, { 104 | pubkey: p.pubkey, 105 | amount: 1000000, 106 | push_amount: 500000, 107 | }); 108 | } else { 109 | await lightning.openChannel(node, { 110 | pubkey: p.pubkey, 111 | amount: 2000000, 112 | push_amount: 1000000, 113 | }); 114 | } 115 | }); 116 | await bitcoind.mine(6, "bcrt1qsrq4qj4zgwyj8hpsnpgeeh0p0aqfe5vqhv7yrr"); 117 | console.log("=> 6 blocked mined to Alice!"); 118 | } 119 | await sleep(4000); 120 | const chans2 = await lightning.listChannels(node); 121 | console.log("FINAL CHANS", chans2.channels); 122 | } catch (e) { 123 | console.log("=> err:", e); 124 | } 125 | } 126 | 127 | async function unlockAll() { 128 | await sleep(3500); 129 | // createOrUnlockWallet(nodes.nodes.alice); 130 | await asyncForEach(Object.values(nodes.nodes), async (node) => { 131 | await createOrUnlockWallet(node); 132 | }); 133 | await sleep(5000); 134 | await coinsAndChannels(nodes.nodes.alice); 135 | } 136 | 137 | unlockAll(); 138 | 139 | async function sleep(ms) { 140 | return new Promise((resolve) => setTimeout(resolve, ms)); 141 | } 142 | 143 | async function asyncForEach(array, callback) { 144 | for (let index = 0; index < array.length; index++) { 145 | await callback(array[index], index, array); 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /lnd/setup/lightning.js: -------------------------------------------------------------------------------- 1 | var fetch = require("./fetch"); 2 | const https = require("https"); 3 | var fs = require("fs"); 4 | 5 | const httpsAgent = new https.Agent({ 6 | rejectUnauthorized: false, 7 | }); 8 | 9 | // const address_type_p2wkh = "0"; 10 | // const address_type_np2wkh = "1"; 11 | 12 | async function getInfo(node) { 13 | return await doRequest(node, "v1/getinfo"); 14 | } 15 | 16 | async function getBalance(node) { 17 | return await doRequest(node, "v1/balance/blockchain"); 18 | } 19 | 20 | async function newAddress(node) { 21 | return await doRequest(node, "v1/newaddress?type=1"); 22 | } 23 | 24 | async function listChannels(node) { 25 | return await doRequest(node, "v1/channels"); 26 | } 27 | 28 | async function listPeers(node) { 29 | return await doRequest(node, "v1/peers"); 30 | } 31 | 32 | // addr = pubkey@host format 33 | async function addPeer(node, addr) { 34 | console.log(addr); 35 | let response; 36 | do { 37 | response = await doRequest(node, "v1/peers", { 38 | addr, 39 | }); 40 | console.log(response); 41 | await sleep(10000); 42 | } while (response.code === 2); 43 | } 44 | 45 | async function openChannel(node, chan) { 46 | return await doRequest(node, "v1/channels", { 47 | node_pubkey: Buffer.from(chan.pubkey, "hex").toString("base64"), 48 | local_funding_amount: chan.amount, 49 | push_sat: chan.push_amount, 50 | }); 51 | } 52 | 53 | module.exports = { 54 | listChannels, 55 | newAddress, 56 | getInfo, 57 | getBalance, 58 | openChannel, 59 | listPeers, 60 | addPeer, 61 | }; 62 | 63 | async function doRequest(node, theurl, body) { 64 | try { 65 | const macLocation = node.macaroon; 66 | if (!macLocation) { 67 | throw new Error("no macaroon"); 68 | } 69 | // console.log(macLocation); 70 | var macaroonString = fs.readFileSync(macLocation); 71 | var mac = Buffer.from(macaroonString, "utf8").toString("hex").toUpperCase(); 72 | const theParams = { 73 | method: body ? "POST" : "GET", 74 | agent: httpsAgent, 75 | headers: { 76 | "Grpc-Metadata-macaroon": mac, 77 | "Content-Type": "application/json", 78 | }, 79 | }; 80 | if (body) { 81 | theParams.body = JSON.stringify(body || {}); 82 | } 83 | const url = `https://${node.hostname}/${theurl}`; 84 | const r = await fetch(url, theParams); 85 | if (!r.ok) { 86 | console.log("=> Request Failed:", r.status, r.statusText); 87 | } 88 | const j = await r.json(); 89 | return j; 90 | } catch (e) { 91 | throw e; 92 | } 93 | } 94 | 95 | async function sleep(ms) { 96 | return new Promise((resolve) => setTimeout(resolve, ms)); 97 | } 98 | 99 | /* 100 | curl --insecure --header "Grpc-Metadata-macaroon: 0201036C6E6402F801030A1067F4815F726C260716FCCB223852C3D11201301A160A0761646472657373120472656164120577726974651A130A04696E666F120472656164120577726974651A170A08696E766F69636573120472656164120577726974651A210A086D616361726F6F6E120867656E6572617465120472656164120577726974651A160A076D657373616765120472656164120577726974651A170A086F6666636861696E120472656164120577726974651A160A076F6E636861696E120472656164120577726974651A140A057065657273120472656164120577726974651A180A067369676E6572120867656E65726174651204726561640000062084FA3B5506DFF35DDF896EFF1DE39B307C43529F8A29F4A528EF3841C8DCA27E" https://localhost:38881/v1/getinfo 101 | */ 102 | -------------------------------------------------------------------------------- /lnd/setup/nodes.js: -------------------------------------------------------------------------------- 1 | const macpath = ".lnd/data/chain/bitcoin/regtest/admin.macaroon"; 2 | 3 | const nodes = { 4 | alice: { 5 | alias: "alice", 6 | hostname: "alice-lnd.sphinx:38881", 7 | password: "alice12345", 8 | macaroon: "/alice/" + macpath, 9 | type: "lnd", 10 | channels: [ 11 | { 12 | host: "bob-lnd.sphinx:9735", 13 | pubkey: 14 | "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 15 | }, 16 | { 17 | host: "carol-lnd.sphinx:9735", 18 | pubkey: 19 | "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 20 | }, 21 | ], 22 | mnemonic: [ 23 | "above", 24 | "hair", 25 | "trigger", 26 | "live", 27 | "innocent", 28 | "monster", 29 | "surprise", 30 | "discover", 31 | "art", 32 | "broccoli", 33 | "cable", 34 | "balcony", 35 | "exclude", 36 | "maple", 37 | "luggage", 38 | "dragon", 39 | "erosion", 40 | "basic", 41 | "census", 42 | "earn", 43 | "ripple", 44 | "gossip", 45 | "record", 46 | "monster", 47 | ], 48 | }, 49 | bob: { 50 | alias: "bob", 51 | hostname: "bob-lnd.sphinx:38882", 52 | password: "bob12345", 53 | macaroon: "/bob/" + macpath, 54 | type: "lnd", 55 | mnemonic: [ 56 | "above", 57 | "street", 58 | "spoon", 59 | "mercy", 60 | "shoot", 61 | "mammal", 62 | "color", 63 | "comic", 64 | "distance", 65 | "myself", 66 | "buyer", 67 | "response", 68 | "senior", 69 | "timber", 70 | "attract", 71 | "neither", 72 | "half", 73 | "laundry", 74 | "ethics", 75 | "swarm", 76 | "will", 77 | "boss", 78 | "spoil", 79 | "genius", 80 | ], 81 | }, 82 | carol: { 83 | alias: "carol", 84 | hostname: "carol-lnd.sphinx:38883", 85 | password: "carol12345", 86 | macaroon: "/carol/" + macpath, 87 | type: "lnd", 88 | mnemonic: [ 89 | "about", 90 | "coconut", 91 | "future", 92 | "area", 93 | "gym", 94 | "prison", 95 | "panic", 96 | "estate", 97 | "diary", 98 | "treat", 99 | "belt", 100 | "pair", 101 | "lens", 102 | "vacuum", 103 | "water", 104 | "poet", 105 | "armed", 106 | "elegant", 107 | "enforce", 108 | "home", 109 | "fine", 110 | "reason", 111 | "genre", 112 | "master", 113 | ], 114 | }, 115 | }; 116 | 117 | /* 118 | able 119 | stuff 120 | magic 121 | beach 122 | ankle 123 | exotic 124 | blood 125 | capital 126 | motor 127 | crouch 128 | once 129 | pigeon 130 | awake 131 | same 132 | ill 133 | crane 134 | write 135 | resource 136 | interest 137 | rail 138 | cigar 139 | duty 140 | body 141 | outdoor 142 | 143 | */ 144 | module.exports = { 145 | nodes, 146 | }; 147 | -------------------------------------------------------------------------------- /lnd/setup/nodes/clnProxyNodes.js: -------------------------------------------------------------------------------- 1 | const macpath = ".lnd/data/chain/bitcoin/regtest/admin.macaroon"; 2 | 3 | const nodes = { 4 | alice: { 5 | alias: "alice", 6 | hostname: "alice-lnd.sphinx:38881", 7 | password: "alice12345", 8 | macaroon: "/alice/" + macpath, 9 | type: "lnd", 10 | channels: [ 11 | { 12 | host: "bob-lnd.sphinx:9735", 13 | pubkey: 14 | "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 15 | }, 16 | { 17 | host: "carol-lnd.sphinx:9735", 18 | pubkey: 19 | "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 20 | }, 21 | { 22 | host: "dave-cln.sphinx:19846", 23 | pubkey: 24 | "037ec785c6004d512ebaeb0020f81a2bcdb6fccc9539f7b891f704289ebc65a4e3", 25 | }, 26 | ], 27 | mnemonic: [ 28 | "above", 29 | "hair", 30 | "trigger", 31 | "live", 32 | "innocent", 33 | "monster", 34 | "surprise", 35 | "discover", 36 | "art", 37 | "broccoli", 38 | "cable", 39 | "balcony", 40 | "exclude", 41 | "maple", 42 | "luggage", 43 | "dragon", 44 | "erosion", 45 | "basic", 46 | "census", 47 | "earn", 48 | "ripple", 49 | "gossip", 50 | "record", 51 | "monster", 52 | ], 53 | }, 54 | bob: { 55 | alias: "bob", 56 | hostname: "bob-lnd.sphinx:38882", 57 | password: "bob12345", 58 | type: "lnd", 59 | macaroon: "/bob/" + macpath, 60 | mnemonic: [ 61 | "above", 62 | "street", 63 | "spoon", 64 | "mercy", 65 | "shoot", 66 | "mammal", 67 | "color", 68 | "comic", 69 | "distance", 70 | "myself", 71 | "buyer", 72 | "response", 73 | "senior", 74 | "timber", 75 | "attract", 76 | "neither", 77 | "half", 78 | "laundry", 79 | "ethics", 80 | "swarm", 81 | "will", 82 | "boss", 83 | "spoil", 84 | "genius", 85 | ], 86 | }, 87 | carol: { 88 | alias: "carol", 89 | hostname: "carol-lnd.sphinx:38883", 90 | password: "carol12345", 91 | type: "lnd", 92 | macaroon: "/carol/" + macpath, 93 | mnemonic: [ 94 | "about", 95 | "coconut", 96 | "future", 97 | "area", 98 | "gym", 99 | "prison", 100 | "panic", 101 | "estate", 102 | "diary", 103 | "treat", 104 | "belt", 105 | "pair", 106 | "lens", 107 | "vacuum", 108 | "water", 109 | "poet", 110 | "armed", 111 | "elegant", 112 | "enforce", 113 | "home", 114 | "fine", 115 | "reason", 116 | "genre", 117 | "master", 118 | ], 119 | }, 120 | dave: { 121 | alias: "dave", 122 | type: "cln", 123 | hostname: "dave-lnd.sphinx:38884", 124 | }, 125 | // dave: { 126 | // alias: "dave", 127 | // hostname: "dave-lnd.sphinx:38884", 128 | // password: "dave12345", 129 | // macaroon: "/dave/" + macpath, 130 | // mnemonic: [ 131 | // "able", 132 | // "stuff", 133 | // "magic", 134 | // "beach", 135 | // "ankle", 136 | // "exotic", 137 | // "blood", 138 | // "capital", 139 | // "motor", 140 | // "crouch", 141 | // "once", 142 | // "pigeon", 143 | // "awake", 144 | // "same", 145 | // "ill", 146 | // "crane", 147 | // "write", 148 | // "resource", 149 | // "interest", 150 | // "rail", 151 | // "cigar", 152 | // "duty", 153 | // "body", 154 | // "outdoor", 155 | // ], 156 | // }, 157 | }; 158 | 159 | /* 160 | able 161 | stuff 162 | magic 163 | beach 164 | ankle 165 | exotic 166 | blood 167 | capital 168 | motor 169 | crouch 170 | once 171 | pigeon 172 | awake 173 | same 174 | ill 175 | crane 176 | write 177 | resource 178 | interest 179 | rail 180 | cigar 181 | duty 182 | body 183 | outdoor 184 | 185 | */ 186 | module.exports = { 187 | nodes, 188 | }; 189 | -------------------------------------------------------------------------------- /lnd/setup/nodes/nodes.js: -------------------------------------------------------------------------------- 1 | const macpath = ".lnd/data/chain/bitcoin/regtest/admin.macaroon"; 2 | 3 | const nodes = { 4 | alice: { 5 | alias: "alice", 6 | hostname: "alice-lnd.sphinx:38881", 7 | password: "alice12345", 8 | macaroon: "/alice/" + macpath, 9 | type: "lnd", 10 | channels: [ 11 | { 12 | host: "bob-lnd.sphinx:9735", 13 | pubkey: 14 | "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 15 | }, 16 | { 17 | host: "carol-lnd.sphinx:9735", 18 | pubkey: 19 | "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 20 | }, 21 | ], 22 | mnemonic: [ 23 | "above", 24 | "hair", 25 | "trigger", 26 | "live", 27 | "innocent", 28 | "monster", 29 | "surprise", 30 | "discover", 31 | "art", 32 | "broccoli", 33 | "cable", 34 | "balcony", 35 | "exclude", 36 | "maple", 37 | "luggage", 38 | "dragon", 39 | "erosion", 40 | "basic", 41 | "census", 42 | "earn", 43 | "ripple", 44 | "gossip", 45 | "record", 46 | "monster", 47 | ], 48 | }, 49 | bob: { 50 | alias: "bob", 51 | hostname: "bob-lnd.sphinx:38882", 52 | password: "bob12345", 53 | type: "lnd", 54 | macaroon: "/bob/" + macpath, 55 | mnemonic: [ 56 | "above", 57 | "street", 58 | "spoon", 59 | "mercy", 60 | "shoot", 61 | "mammal", 62 | "color", 63 | "comic", 64 | "distance", 65 | "myself", 66 | "buyer", 67 | "response", 68 | "senior", 69 | "timber", 70 | "attract", 71 | "neither", 72 | "half", 73 | "laundry", 74 | "ethics", 75 | "swarm", 76 | "will", 77 | "boss", 78 | "spoil", 79 | "genius", 80 | ], 81 | }, 82 | carol: { 83 | alias: "carol", 84 | hostname: "carol-lnd.sphinx:38883", 85 | password: "carol12345", 86 | type: "lnd", 87 | macaroon: "/carol/" + macpath, 88 | mnemonic: [ 89 | "about", 90 | "coconut", 91 | "future", 92 | "area", 93 | "gym", 94 | "prison", 95 | "panic", 96 | "estate", 97 | "diary", 98 | "treat", 99 | "belt", 100 | "pair", 101 | "lens", 102 | "vacuum", 103 | "water", 104 | "poet", 105 | "armed", 106 | "elegant", 107 | "enforce", 108 | "home", 109 | "fine", 110 | "reason", 111 | "genre", 112 | "master", 113 | ], 114 | }, 115 | }; 116 | 117 | /* 118 | able 119 | stuff 120 | magic 121 | beach 122 | ankle 123 | exotic 124 | blood 125 | capital 126 | motor 127 | crouch 128 | once 129 | pigeon 130 | awake 131 | same 132 | ill 133 | crane 134 | write 135 | resource 136 | interest 137 | rail 138 | cigar 139 | duty 140 | body 141 | outdoor 142 | 143 | */ 144 | module.exports = { 145 | nodes, 146 | }; 147 | -------------------------------------------------------------------------------- /lnd/setup/nodes/proxynodes.js: -------------------------------------------------------------------------------- 1 | const macpath = ".lnd/data/chain/bitcoin/regtest/admin.macaroon"; 2 | 3 | const nodes = { 4 | alice: { 5 | alias: "alice", 6 | hostname: "alice-lnd.sphinx:38881", 7 | password: "alice12345", 8 | macaroon: "/alice/" + macpath, 9 | type: "lnd", 10 | channels: [ 11 | { 12 | host: "bob-lnd.sphinx:9735", 13 | pubkey: 14 | "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 15 | }, 16 | { 17 | host: "carol-lnd.sphinx:9735", 18 | pubkey: 19 | "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 20 | }, 21 | { 22 | host: "dave-lnd.sphinx:9735", 23 | pubkey: 24 | "030841d1519f19c68e80efc5ef5af3460ca4bfa17486fda9baca878b9ef255358f", 25 | }, 26 | ], 27 | mnemonic: [ 28 | "above", 29 | "hair", 30 | "trigger", 31 | "live", 32 | "innocent", 33 | "monster", 34 | "surprise", 35 | "discover", 36 | "art", 37 | "broccoli", 38 | "cable", 39 | "balcony", 40 | "exclude", 41 | "maple", 42 | "luggage", 43 | "dragon", 44 | "erosion", 45 | "basic", 46 | "census", 47 | "earn", 48 | "ripple", 49 | "gossip", 50 | "record", 51 | "monster", 52 | ], 53 | }, 54 | bob: { 55 | alias: "bob", 56 | hostname: "bob-lnd.sphinx:38882", 57 | password: "bob12345", 58 | type: "lnd", 59 | macaroon: "/bob/" + macpath, 60 | mnemonic: [ 61 | "above", 62 | "street", 63 | "spoon", 64 | "mercy", 65 | "shoot", 66 | "mammal", 67 | "color", 68 | "comic", 69 | "distance", 70 | "myself", 71 | "buyer", 72 | "response", 73 | "senior", 74 | "timber", 75 | "attract", 76 | "neither", 77 | "half", 78 | "laundry", 79 | "ethics", 80 | "swarm", 81 | "will", 82 | "boss", 83 | "spoil", 84 | "genius", 85 | ], 86 | }, 87 | carol: { 88 | alias: "carol", 89 | hostname: "carol-lnd.sphinx:38883", 90 | password: "carol12345", 91 | type: "lnd", 92 | macaroon: "/carol/" + macpath, 93 | mnemonic: [ 94 | "about", 95 | "coconut", 96 | "future", 97 | "area", 98 | "gym", 99 | "prison", 100 | "panic", 101 | "estate", 102 | "diary", 103 | "treat", 104 | "belt", 105 | "pair", 106 | "lens", 107 | "vacuum", 108 | "water", 109 | "poet", 110 | "armed", 111 | "elegant", 112 | "enforce", 113 | "home", 114 | "fine", 115 | "reason", 116 | "genre", 117 | "master", 118 | ], 119 | }, 120 | dave: { 121 | alias: "dave", 122 | type: "lnd", 123 | hostname: "dave-lnd.sphinx:38884", 124 | password: "dave12345", 125 | macaroon: "/dave/" + macpath, 126 | mnemonic: [ 127 | "able", 128 | "stuff", 129 | "magic", 130 | "beach", 131 | "ankle", 132 | "exotic", 133 | "blood", 134 | "capital", 135 | "motor", 136 | "crouch", 137 | "once", 138 | "pigeon", 139 | "awake", 140 | "same", 141 | "ill", 142 | "crane", 143 | "write", 144 | "resource", 145 | "interest", 146 | "rail", 147 | "cigar", 148 | "duty", 149 | "body", 150 | "outdoor", 151 | ], 152 | }, 153 | }; 154 | 155 | /* 156 | able 157 | stuff 158 | magic 159 | beach 160 | ankle 161 | exotic 162 | blood 163 | capital 164 | motor 165 | crouch 166 | once 167 | pigeon 168 | awake 169 | same 170 | ill 171 | crane 172 | write 173 | resource 174 | interest 175 | rail 176 | cigar 177 | duty 178 | body 179 | outdoor 180 | 181 | */ 182 | module.exports = { 183 | nodes, 184 | }; 185 | -------------------------------------------------------------------------------- /lnd/setup/wallet.js: -------------------------------------------------------------------------------- 1 | var fetch = require("./fetch"); 2 | const https = require("https"); 3 | 4 | const httpsAgent = new https.Agent({ 5 | rejectUnauthorized: false, 6 | }); 7 | 8 | async function initWallet(node) { 9 | var root = `https://${node.hostname}/v1/`; 10 | var pass = Buffer.from(node.password).toString("base64"); 11 | console.log("WALLET URL", root + "initwallet"); 12 | const r = await fetch(root + "initwallet", { 13 | method: "POST", 14 | body: JSON.stringify({ 15 | wallet_password: pass, 16 | cipher_seed_mnemonic: node.mnemonic, 17 | }), 18 | headers: { 19 | "Content-Type": "application/json", 20 | }, 21 | agent: httpsAgent, 22 | }); 23 | const j = await r.json(); 24 | return j; 25 | } 26 | 27 | async function unlockWallet(node) { 28 | var root = `https://${node.hostname}/v1/`; 29 | var pass = Buffer.from(node.password).toString("base64"); 30 | const r = await fetch(root + "unlockwallet", { 31 | method: "POST", 32 | body: JSON.stringify({ 33 | wallet_password: pass, 34 | }), 35 | headers: { 36 | "Content-Type": "application/json", 37 | }, 38 | agent: httpsAgent, 39 | }); 40 | const j = await r.json(); 41 | return j; 42 | } 43 | 44 | module.exports = { 45 | unlockWallet, 46 | initWallet, 47 | }; 48 | -------------------------------------------------------------------------------- /memes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/memes/.gitkeep -------------------------------------------------------------------------------- /proxy/lnd_proxy.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/proxy/lnd_proxy.conf -------------------------------------------------------------------------------- /relay/alice-db.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "./configs/db/alice.db" 5 | }, 6 | "gitactionenv": { 7 | "dialect": "sqlite" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /relay/alice.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "node_ip": "127.0.0.1", 4 | "lnd_ip": "alice-lnd.sphinx", 5 | "lnd_port": "10009", 6 | "tls_location": "/relay/alice/.lnd/tls.cert", 7 | "macaroon_location": "/relay/alice/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 8 | "node_http_protocol": "http", 9 | "node_http_port": "3001", 10 | "tribes_mqtt_port": "1883", 11 | "tribes_insecure": true, 12 | "public_url": "127.0.0.1:3001", 13 | "transportPrivateKeyLocation": "/relay/configs/aliceTransportPrivateKey.pem", 14 | "transportPublicKeyLocation": "/relay/configs/aliceTransportPublicKey.pem", 15 | "host_name": "http://alice.sphinx:3001", 16 | "media_host": "meme.sphinx:5555" 17 | }, 18 | "gitactionenv": { 19 | "node_ip": "127.0.0.1", 20 | "lnd_ip": "alice-lnd.sphinx", 21 | "lnd_port": "10009", 22 | "tls_location": "/relay/alice/.lnd/tls.cert", 23 | "macaroon_location": "/relay/alice/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 24 | "node_http_protocol": "http", 25 | "node_http_port": "3001", 26 | "tribes_mqtt_port": "1883", 27 | "tribes_insecure": true, 28 | "public_url": "127.0.0.1:3001", 29 | "connect_ui": true, 30 | "transportPrivateKeyLocation": "/relay/configs/aliceTransportPrivateKey.pem", 31 | "transportPublicKeyLocation": "/relay/configs/aliceTransportPublicKey.pem", 32 | "sql_log": true, 33 | "host_name": "http://alice.sphinx:3001", 34 | "media_host": "meme.sphinx:5555" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /relay/bob-db.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "./configs/db/bob.db" 5 | }, 6 | "gitactionenv": { 7 | "dialect": "sqlite" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /relay/bob.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "node_ip": "127.0.0.1", 4 | "lnd_ip": "bob-lnd.sphinx", 5 | "lnd_port": "10010", 6 | "tls_location": "/relay/bob/.lnd/tls.cert", 7 | "macaroon_location": "/relay/bob/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 8 | "node_http_protocol": "http", 9 | "node_http_port": "3002", 10 | "tribes_mqtt_port": "1883", 11 | "tribes_insecure": true, 12 | "public_url": "127.0.0.1:3002", 13 | "connect_ui": true, 14 | "transportPrivateKeyLocation": "/relay/configs/bobTransportPrivateKey.pem", 15 | "transportPublicKeyLocation": "/relay/configs/bobTransportPublicKey.pem", 16 | "media_host": "meme.sphinx:5555" 17 | }, 18 | "gitactionenv": { 19 | "node_ip": "127.0.0.1", 20 | "lnd_ip": "bob-lnd.sphinx", 21 | "lnd_port": "10010", 22 | "tls_location": "/relay/bob/.lnd/tls.cert", 23 | "macaroon_location": "/relay/bob/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 24 | "node_http_protocol": "http", 25 | "node_http_port": "3002", 26 | "tribes_mqtt_port": "1883", 27 | "tribes_insecure": true, 28 | "public_url": "127.0.0.1:3002", 29 | "connect_ui": true, 30 | "transportPrivateKeyLocation": "/relay/configs/bobTransportPrivateKey.pem", 31 | "transportPublicKeyLocation": "/relay/configs/bobTransportPublicKey.pem", 32 | "media_host": "meme.sphinx:5555" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /relay/botConfig.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "example", 4 | "webhook": "http://example-bot-sphinx:3333", 5 | "port": 3333 6 | }, 7 | { 8 | "name": "bet", 9 | "webhook": "http://bet-bot-sphinx:3334", 10 | "port": 3334 11 | } 12 | ] 13 | -------------------------------------------------------------------------------- /relay/carol-db.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "./configs/db/carol.db" 5 | }, 6 | "gitactionenv": { 7 | "dialect": "sqlite" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /relay/carol.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "node_ip": "127.0.0.1", 4 | "lnd_ip": "carol-lnd.sphinx", 5 | "lnd_port": "10011", 6 | "tls_location": "/relay/carol/.lnd/tls.cert", 7 | "macaroon_location": "/relay/carol/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 8 | "node_http_protocol": "http", 9 | "node_http_port": "3003", 10 | "tribes_mqtt_port": "1883", 11 | "tribes_insecure": true, 12 | "public_url": "127.0.0.1:3003", 13 | "connect_ui": true, 14 | "transportPrivateKeyLocation": "/relay/configs/carolTransportPrivateKey.pem", 15 | "transportPublicKeyLocation": "/relay/configs/carolTransportPublicKey.pem", 16 | "media_host": "meme.sphinx:5555" 17 | }, 18 | "gitactionenv": { 19 | "node_ip": "127.0.0.1", 20 | "lnd_ip": "carol-lnd.sphinx", 21 | "lnd_port": "10011", 22 | "tls_location": "/relay/carol/.lnd/tls.cert", 23 | "macaroon_location": "/relay/carol/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 24 | "node_http_protocol": "http", 25 | "node_http_port": "3003", 26 | "tribes_mqtt_port": "1883", 27 | "tribes_insecure": true, 28 | "public_url": "127.0.0.1:3003", 29 | "connect_ui": true, 30 | "transportPrivateKeyLocation": "/relay/configs/carolTransportPrivateKey.pem", 31 | "transportPublicKeyLocation": "/relay/configs/carolTransportPublicKey.pem", 32 | "media_host": "meme.sphinx:5555" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /relay/cln-dave.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "lightning_provider": "CLN", 4 | "hub_api_url": "None", 5 | "proxy_initial_sats": 20000, 6 | "proxy_new_nodes": 2, 7 | "proxy_lnd_ip": "proxy.sphinx", 8 | "proxy_admin_token": "r46bnf8ibrhbb424heba", 9 | "proxy_admin_url": "http://proxy.sphinx:5050", 10 | "dont_ping_hub": true, 11 | "proxy_lnd_port": "11111", 12 | "proxy_tls_location": "/proxy/cert/tls.cert", 13 | "proxy_macaroons_dir": "/proxy/macaroons", 14 | "node_ip": "127.0.0.1", 15 | "lnd_ip": "dave-cln.sphinx", 16 | "lnd_port": "10012", 17 | "cln_ca_cert": "/relay/dave/regtest/ca.pem", 18 | "cln_device_key": "/relay/dave/regtest/client-key.pem", 19 | "cln_device_cert": "/relay/dave/regtest/client.pem", 20 | "node_http_protocol": "http", 21 | "node_http_port": "3004", 22 | "tribes_mqtt_port": "1883", 23 | "tribes_insecure": true, 24 | "public_url": "127.0.0.1:3004", 25 | "connect_ui": true, 26 | "logging_level": "debug", 27 | "proxy_hd_keys": true, 28 | "allow_swarm_invite": true, 29 | "host_name": "localhost:3004", 30 | "media_host": "meme.sphinx:5555" 31 | }, 32 | "gitactionenv": { 33 | "lightning_provider": "CLN", 34 | "hub_api_url": "None", 35 | "proxy_initial_sats": 20000, 36 | "proxy_new_nodes": 4, 37 | "proxy_lnd_ip": "proxy.sphinx", 38 | "proxy_admin_token": "r46bnf8ibrhbb424heba", 39 | "proxy_admin_url": "http://proxy.sphinx:5050", 40 | "dont_ping_hub": true, 41 | "proxy_lnd_port": "11111", 42 | "proxy_tls_location": "/proxy/cert/tls.cert", 43 | "proxy_macaroons_dir": "/proxy/macaroons", 44 | "node_ip": "127.0.0.1", 45 | "lnd_ip": "dave-cln.sphinx", 46 | "lnd_port": "10012", 47 | "cln_ca_cert": "/relay/dave/regtest/ca.pem", 48 | "cln_device_key": "/relay/dave/regtest/client-key.pem", 49 | "cln_device_cert": "/relay/dave/regtest/client.pem", 50 | "node_http_protocol": "http", 51 | "node_http_port": "3004", 52 | "tribes_mqtt_port": "1883", 53 | "tribes_insecure": true, 54 | "public_url": "127.0.0.1:3004", 55 | "connect_ui": true, 56 | "logging_level": "debug", 57 | "proxy_hd_keys": true, 58 | "allow_swarm_invite": true, 59 | "host_name": "localhost:3004", 60 | "media_host": "meme.sphinx:5555" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /relay/dave-db.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "dialect": "sqlite", 4 | "storage": "./configs/db/dave.db" 5 | } 6 | , 7 | "gitactionenv": { 8 | "dialect": "sqlite" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /relay/dave.json: -------------------------------------------------------------------------------- 1 | { 2 | "development": { 3 | "hub_api_url": "None", 4 | "proxy_initial_sats": 20000, 5 | "proxy_new_nodes": 2, 6 | "proxy_lnd_ip": "proxy.sphinx", 7 | "proxy_admin_token": "r46bnf8ibrhbb424heba", 8 | "proxy_admin_url": "http://proxy.sphinx:5050", 9 | "dont_ping_hub": true, 10 | "proxy_lnd_port": "11111", 11 | "proxy_tls_location": "/proxy/cert/tls.cert", 12 | "proxy_macaroons_dir": "/proxy/macaroons", 13 | "node_ip": "127.0.0.1", 14 | "lnd_ip": "dave-lnd.sphinx", 15 | "lnd_port": "10012", 16 | "tls_location": "/relay/dave/.lnd/tls.cert", 17 | "macaroon_location": "/relay/dave/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 18 | "node_http_protocol": "http", 19 | "node_http_port": "3004", 20 | "tribes_mqtt_port": "1883", 21 | "tribes_insecure": true, 22 | "public_url": "127.0.0.1:3004", 23 | "connect_ui": true, 24 | "logging_level": "debug", 25 | "proxy_hd_keys": true, 26 | "allow_swarm_invite": true, 27 | "host_name": "http://dave.sphinx:3004", 28 | "media_host": "meme.sphinx:5555" 29 | }, 30 | "gitactionenv": { 31 | "hub_api_url": "None", 32 | "proxy_initial_sats": 20000, 33 | "proxy_new_nodes": 4, 34 | "proxy_lnd_ip": "proxy.sphinx", 35 | "proxy_admin_token": "r46bnf8ibrhbb424heba", 36 | "proxy_admin_url": "http://proxy.sphinx:5050", 37 | "dont_ping_hub": true, 38 | "proxy_lnd_port": "11111", 39 | "proxy_tls_location": "/proxy/cert/tls.cert", 40 | "proxy_macaroons_dir": "/proxy/macaroons", 41 | "node_ip": "127.0.0.1", 42 | "lnd_ip": "dave-lnd.sphinx", 43 | "lnd_port": "10012", 44 | "tls_location": "/relay/dave/.lnd/tls.cert", 45 | "macaroon_location": "/relay/dave/.lnd/data/chain/bitcoin/regtest/admin.macaroon", 46 | "node_http_protocol": "http", 47 | "node_http_port": "3004", 48 | "tribes_mqtt_port": "1883", 49 | "tribes_insecure": true, 50 | "public_url": "127.0.0.1:3004", 51 | "connect_ui": true, 52 | "logging_level": "debug", 53 | "proxy_hd_keys": true, 54 | "allow_swarm_invite": true, 55 | "host_name": "http://dave.sphinx:3004", 56 | "media_host": "meme.sphinx:5555" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /relay/db/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/relay/db/.gitkeep -------------------------------------------------------------------------------- /relay/nodes_partial.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/relay/nodes_partial.json -------------------------------------------------------------------------------- /relay/nodes_partial/cln_proxy_nodes_partial.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "alias": "alice", 4 | "pubkey": "03a394d0ebf0d003124ab130c6b12b8b990a50a30a464354800a51981ba745bb07", 5 | "ip": "http://alice.sphinx:3001", 6 | "external_ip": "http://localhost:3001" 7 | }, 8 | { 9 | "alias": "bob", 10 | "pubkey": "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 11 | "ip": "http://bob.sphinx:3002", 12 | "external_ip": "http://localhost:3002" 13 | }, 14 | { 15 | "alias": "carol", 16 | "pubkey": "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 17 | "ip": "http://carol.sphinx:3003", 18 | "external_ip": "http://localhost:3003" 19 | }, 20 | { 21 | "alias": "dave", 22 | "pubkey": "037ec785c6004d512ebaeb0020f81a2bcdb6fccc9539f7b891f704289ebc65a4e3", 23 | "ip": "http://dave.sphinx:3004", 24 | "external_ip": "http://localhost:3004", 25 | "proxy_ip": "http://proxy.sphinx:5050", 26 | "admin_token": "r46bnf8ibrhbb424heba" 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /relay/nodes_partial/nodes_partial.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "alias": "alice", 4 | "pubkey": "03a394d0ebf0d003124ab130c6b12b8b990a50a30a464354800a51981ba745bb07", 5 | "ip": "http://alice.sphinx:3001", 6 | "external_ip": "http://localhost:3001" 7 | }, 8 | { 9 | "alias": "bob", 10 | "pubkey": "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 11 | "ip": "http://bob.sphinx:3002", 12 | "external_ip": "http://localhost:3002" 13 | }, 14 | { 15 | "alias": "carol", 16 | "pubkey": "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 17 | "ip": "http://carol.sphinx:3003", 18 | "external_ip": "http://localhost:3003" 19 | } 20 | ] 21 | -------------------------------------------------------------------------------- /relay/nodes_partial/proxy_nodes_partial.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "alias": "alice", 4 | "pubkey": "03a394d0ebf0d003124ab130c6b12b8b990a50a30a464354800a51981ba745bb07", 5 | "ip": "http://alice.sphinx:3001", 6 | "external_ip": "http://localhost:3001" 7 | }, 8 | { 9 | "alias": "bob", 10 | "pubkey": "02a38857848aca6b32ebcc3c85d07ee41354988f4f1e0b4e6ccd255eee6ed75b8d", 11 | "ip": "http://bob.sphinx:3002", 12 | "external_ip": "http://localhost:3002" 13 | }, 14 | { 15 | "alias": "carol", 16 | "pubkey": "0364c05cbcbb9612036cc66297445a88bcfc21941fd816e17a56b54b0b52ff02b9", 17 | "ip": "http://carol.sphinx:3003", 18 | "external_ip": "http://localhost:3003" 19 | }, 20 | { 21 | "alias": "dave", 22 | "pubkey": "030841d1519f19c68e80efc5ef5af3460ca4bfa17486fda9baca878b9ef255358f", 23 | "ip": "http://dave.sphinx:3004", 24 | "external_ip": "http://localhost:3004", 25 | "proxy_ip": "http://proxy.sphinx:5050", 26 | "admin_token": "r46bnf8ibrhbb424heba" 27 | } 28 | ] 29 | -------------------------------------------------------------------------------- /relay/setup/index.js: -------------------------------------------------------------------------------- 1 | var signup = require("./signup"); 2 | var fs = require("fs"); 3 | var paths = require("./paths"); 4 | var fetch = require("./fetch"); 5 | // var rsa = require("./rsa"); 6 | 7 | async function setup() { 8 | await preSetup(); 9 | var nodes = require(paths.pathToWrite); 10 | console.log("nodes we're working with after presetup", nodes); 11 | if (process.env.ALICE_IP) { 12 | nodes[0].ip = process.env.ALICE_IP; 13 | } 14 | 15 | if (process.env.DAVE_IP && nodes.length > 3) { 16 | let change = true; 17 | index = 3; 18 | while (change) { 19 | if (nodes[index]) { 20 | nodes[index].ip = process.env.DAVE_IP; 21 | index += 1; 22 | } else { 23 | change = false; 24 | } 25 | } 26 | } 27 | await asyncForEach(nodes, async function (n, i) { 28 | await pollReady(n, i); 29 | await sleep(1000); 30 | console.log("=========> SETUP <=========="); 31 | await signup.run_signup(n, i); 32 | }); 33 | 34 | /*Bot creation is being done here 35 | we want to generate new bot env vars 36 | if we do not have any generated yet 37 | this comes in handy when a person fresh 38 | installs the sphinx-stack*/ 39 | botEnvVars = require(paths.botEnvVars); 40 | botConfig = require(paths.botConfig); 41 | 42 | if (botEnvVars.length != botConfig.length) { 43 | var finalNodes = require(paths.pathToWrite); 44 | 45 | let newBotEnvVars = []; 46 | 47 | await asyncForEach(botConfig, async function (botConfigValues, botIndex) { 48 | function sleep(ms) { 49 | return new Promise((resolve) => setTimeout(resolve, ms)); 50 | } 51 | 52 | await sleep(20000); 53 | const nextKeyPortPair = await createBotKey( 54 | botConfigValues, 55 | botIndex, 56 | finalNodes[0] 57 | ); 58 | 59 | newBotEnvVars[botIndex] = nextKeyPortPair; 60 | }); 61 | 62 | fs.writeFileSync(paths.botEnvVars, JSON.stringify(newBotEnvVars, null, 2)); 63 | } 64 | 65 | console.log("======================================"); 66 | console.log("== =="); 67 | console.log("== => SETUP COMPLETE! <= =="); 68 | console.log("== =="); 69 | console.log("======================================"); 70 | } 71 | setup(); 72 | 73 | async function createBotKey(botConfigValues, botIndex, n) { 74 | const { name, webhook } = botConfigValues; 75 | 76 | try { 77 | const r = await fetch(n.ip + "/bot/", { 78 | method: "POST", 79 | headers: { 80 | "Content-Type": "application/json", 81 | "x-user-token": n.authToken, 82 | }, 83 | body: JSON.stringify({ 84 | name: name, 85 | webhook: webhook, 86 | }), 87 | }); 88 | 89 | //We're aborting if the relay service isn't availible yet 90 | const NODES = require(paths.pathToWrite); 91 | if (r.status == 401) { 92 | process.abort(); 93 | } 94 | 95 | const botResponse = await r.json(); 96 | const botResponseBody = botResponse.response; 97 | 98 | let url = "http://alice.sphinx:3001/action"; 99 | if (process.env.ALICE_IP) { 100 | url = process.env.ALICE_IP + "/action"; 101 | } 102 | return { 103 | SPHINX_TOKEN: 104 | Buffer.from(botResponseBody.id).toString("base64") + 105 | "." + 106 | Buffer.from(botResponseBody.secret).toString("base64") + 107 | "." + 108 | Buffer.from(url).toString("base64"), 109 | PORT: botConfig[botIndex].port, 110 | }; 111 | } catch (e) { 112 | console.log(e); 113 | } 114 | } 115 | 116 | async function preSetup() { 117 | try { 118 | let exists = fs.existsSync(paths.pathToWrite); 119 | const botKeysExist = fs.existsSync(paths.botEnvVars); 120 | 121 | if (!botKeysExist) { 122 | console.log( 123 | "=>", 124 | paths.botEnvVars, 125 | "does not exist, creating now", 126 | botKeysExist 127 | ); 128 | fs.writeFileSync(paths.botEnvVars, JSON.stringify([])); 129 | } 130 | if (!exists) { 131 | console.log( 132 | "=>", 133 | paths.pathToWrite, 134 | "does not exist, creating now", 135 | exists 136 | ); 137 | fs.copyFileSync(paths.path, paths.pathToWrite); 138 | const existingNodes = require(paths.pathToWrite); 139 | for (const node of existingNodes) { 140 | if (node.admin_token) { 141 | await writeVirtualNodes(node); 142 | } 143 | } 144 | } else { 145 | console.log("=>", paths.pathToWrite, "exists"); 146 | // check ready to go! All fields there 147 | let clearAll = false; 148 | var nodes = require(paths.pathToWrite); 149 | nodes.forEach((n) => { 150 | if (!n.authToken) clearAll = true; 151 | if (!n.contact_key) clearAll = true; 152 | if (!n.privkey) clearAll = true; 153 | if (!n.exported_keys) clearAll = true; 154 | }); 155 | 156 | if (clearAll) { 157 | // delete the database files 158 | fs.unlinkSync(paths.pathToWrite); 159 | fs.unlinkSync("/relay/db/alice.db"); 160 | fs.unlinkSync("/relay/db/bob.db"); 161 | fs.unlinkSync("/relay/db/carol.db"); 162 | fs.unlinkSync("/relay/db/dave.db"); 163 | } 164 | } 165 | } catch (e) { 166 | console.log("=> preSetup error", e); 167 | } 168 | } 169 | 170 | async function writeVirtualNodes(node) { 171 | //const virtualNodes = await fetch("http://proxy.sphinx:5050/list", {"x-admin-token": "r46bnf8ibrhbb424heba"}) 172 | 173 | return new Promise(async function (resolve, reject) { 174 | let ok = false; 175 | let count = 0; 176 | while (!ok && count < 100) { 177 | try { 178 | await sleep(2000); 179 | const r = await fetch(node.proxy_ip + "/list", { 180 | method: "GET", 181 | headers: { 182 | "Content-Type": "application/json", 183 | "x-admin-token": node.admin_token, 184 | }, 185 | }); 186 | const json = await r.json(); 187 | if (json.length > 0) { 188 | console.log("THIS IS THE RESPONSE OF LIST FROM PROXY: ", json); 189 | var nodesPartial = require(paths.pathToWrite); 190 | // nodesPartial.pop(); 191 | json.forEach((privateChannel, index) => { 192 | console.log(privateChannel); 193 | const pushValue = { 194 | pubkey: privateChannel.pubkey, 195 | routeHint: node.pubkey + ":" + privateChannel.channel, 196 | alias: `virtualNode${index}`, 197 | ip: node.ip, 198 | external_ip: node.external_ip, 199 | }; 200 | nodesPartial.push(pushValue); 201 | }); 202 | const jsonString = JSON.stringify(nodesPartial, null, 2); 203 | console.log(nodesPartial); 204 | 205 | console.log("this is what we're writing", jsonString); 206 | //fs.copyFileSync(jsonString, paths.pathToWrite); 207 | fs.writeFileSync(paths.pathToWrite, []); 208 | } 209 | if (r.ok && json.length > 0) ok = true; 210 | } catch (e) { 211 | console.log(e); 212 | } 213 | count++; 214 | } 215 | resolve(); 216 | }); 217 | } 218 | 219 | function pollReady(n, i) { 220 | return new Promise(async function (resolve, reject) { 221 | let ok = false; 222 | while (!ok) { 223 | try { 224 | await sleep(10000); 225 | console.log("=> try ", n.ip + "/is_setup"); 226 | const r = await fetch(n.ip + "/is_setup"); 227 | // const txt = await r.json(); 228 | if (r.ok) ok = true; 229 | } catch (e) {} 230 | } 231 | resolve(); 232 | }); 233 | } 234 | 235 | async function sleep(ms) { 236 | return new Promise((resolve) => setTimeout(resolve, ms)); 237 | } 238 | 239 | async function asyncForEach(array, callback) { 240 | for (let index = 0; index < array.length; index++) { 241 | await callback(array[index], index, array); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /relay/setup/paths.js: -------------------------------------------------------------------------------- 1 | // paths to the nodes.json files 2 | 3 | const path = "/relay/nodes_partial.json"; 4 | const pathToWrite = "/relay/NODES.json"; 5 | 6 | const botConfig = "/relay/botConfig.json"; 7 | const botEnvVars = "/relay/botEnvVars.json"; 8 | 9 | module.exports = { 10 | path, 11 | pathToWrite, 12 | botConfig, 13 | botEnvVars, 14 | }; 15 | -------------------------------------------------------------------------------- /relay/setup/rncryptor.js: -------------------------------------------------------------------------------- 1 | var sjcl = require("./sjcl"); 2 | 3 | var RNCryptor = {}; 4 | 5 | /* 6 | Takes password string and salt WordArray 7 | Returns key bitArray 8 | */ 9 | 10 | RNCryptor.KeyForPassword = function (password, salt) { 11 | var hmacSHA1 = function (key) { 12 | var hasher = new sjcl.misc.hmac(key, sjcl.hash.sha1); 13 | this.encrypt = function () { 14 | return hasher.encrypt.apply(hasher, arguments); 15 | }; 16 | }; 17 | return sjcl.misc.pbkdf2(password, salt, 10000, 32 * 8, hmacSHA1); 18 | }; 19 | 20 | /* 21 | Takes password string and plaintext bitArray 22 | options: 23 | iv 24 | encryption_salt 25 | html_salt 26 | Returns ciphertext bitArray 27 | */ 28 | RNCryptor.Encrypt = function (password, plaintext, options) { 29 | options = options || {}; 30 | var encryption_salt = 31 | options["encryption_salt"] || sjcl.random.randomWords(8 / 4); // FIXME: Need to seed PRNG 32 | var encryption_key = RNCryptor.KeyForPassword(password, encryption_salt); 33 | 34 | var hmac_salt = options["hmac_salt"] || sjcl.random.randomWords(8 / 4); 35 | var hmac_key = RNCryptor.KeyForPassword(password, hmac_salt); 36 | 37 | var iv = options["iv"] || sjcl.random.randomWords(16 / 4); 38 | 39 | var version = sjcl.codec.hex.toBits("03"); 40 | var options = sjcl.codec.hex.toBits("01"); 41 | 42 | var message = sjcl.bitArray.concat(version, options); 43 | message = sjcl.bitArray.concat(message, encryption_salt); 44 | message = sjcl.bitArray.concat(message, hmac_salt); 45 | message = sjcl.bitArray.concat(message, iv); 46 | 47 | var aes = new sjcl.cipher.aes(encryption_key); 48 | sjcl.beware[ 49 | "CBC mode is dangerous because it doesn't protect message integrity." 50 | ](); 51 | var encrypted = sjcl.mode.cbc.encrypt(aes, plaintext, iv); 52 | 53 | message = sjcl.bitArray.concat(message, encrypted); 54 | 55 | var hmac = new sjcl.misc.hmac(hmac_key).encrypt(message); 56 | message = sjcl.bitArray.concat(message, hmac); 57 | 58 | return message; 59 | }; 60 | 61 | /* 62 | Takes password string and message (ciphertext) bitArray 63 | options: 64 | iv 65 | encryption_salt 66 | html_salt 67 | Returns plaintext bitArray 68 | */ 69 | RNCryptor.Decrypt = function (password, message, options) { 70 | options = options || {}; 71 | 72 | var version = sjcl.bitArray.extract(message, 0 * 8, 8); 73 | var options = sjcl.bitArray.extract(message, 1 * 8, 8); 74 | 75 | var encryption_salt = sjcl.bitArray.bitSlice(message, 2 * 8, 10 * 8); 76 | var encryption_key = RNCryptor.KeyForPassword(password, encryption_salt); 77 | 78 | var hmac_salt = sjcl.bitArray.bitSlice(message, 10 * 8, 18 * 8); 79 | var hmac_key = RNCryptor.KeyForPassword(password, hmac_salt); 80 | 81 | var iv = sjcl.bitArray.bitSlice(message, 18 * 8, 34 * 8); 82 | 83 | var ciphertext_end = sjcl.bitArray.bitLength(message) - 32 * 8; 84 | 85 | var ciphertext = sjcl.bitArray.bitSlice(message, 34 * 8, ciphertext_end); 86 | 87 | var hmac = sjcl.bitArray.bitSlice(message, ciphertext_end); 88 | 89 | var expected_hmac = new sjcl.misc.hmac(hmac_key).encrypt( 90 | sjcl.bitArray.bitSlice(message, 0, ciphertext_end) 91 | ); 92 | 93 | // .equal is of consistent time 94 | if (!sjcl.bitArray.equal(hmac, expected_hmac)) { 95 | throw new sjcl.exception.corrupt("HMAC mismatch or bad password."); 96 | } 97 | 98 | var aes = new sjcl.cipher.aes(encryption_key); 99 | sjcl.beware[ 100 | "CBC mode is dangerous because it doesn't protect message integrity." 101 | ](); 102 | var decrypted = sjcl.mode.cbc.decrypt(aes, ciphertext, iv); 103 | 104 | return decrypted; 105 | }; 106 | 107 | var JSCryptor = {}; 108 | // returns base64 109 | JSCryptor.Encrypt = function (plaintext_in, password) { 110 | const plaintext = sjcl.codec.utf8String.toBits(plaintext_in); 111 | var enc = RNCryptor.Encrypt(password, plaintext); 112 | const b64 = sjcl.codec.base64.fromBits(enc); 113 | return b64; 114 | }; 115 | // takes base64, returns unicode 116 | JSCryptor.Decrypt = function (pwd, msg) { 117 | const msgbits = sjcl.codec.base64.toBits(msg); 118 | var dec = RNCryptor.Decrypt(pwd, msgbits); 119 | const plaintext = sjcl.codec.utf8String.fromBits(dec); 120 | return plaintext; 121 | }; 122 | 123 | module.exports = { 124 | JSCryptor, 125 | }; 126 | -------------------------------------------------------------------------------- /relay/setup/rsa.js: -------------------------------------------------------------------------------- 1 | const crypto = require("crypto"); 2 | 3 | const BLOCK_SIZE = 256; 4 | const MAX_CHUNK_SIZE = BLOCK_SIZE - 11; // 11 is the PCKS1 padding 5 | 6 | function encrypt(key, txt) { 7 | try { 8 | const buf = Buffer.from(txt); 9 | let finalBuf = Buffer.from([]); 10 | const n = Math.ceil(buf.length / MAX_CHUNK_SIZE); 11 | const arr = Array(n).fill(0); 12 | const pubc = cert.pub(key); 13 | arr.forEach((_, i) => { 14 | const f = crypto.publicEncrypt( 15 | { 16 | key: pubc, 17 | padding: crypto.constants.RSA_PKCS1_PADDING, // RSA_PKCS1_OAEP_PADDING 18 | }, 19 | buf.subarray(i * MAX_CHUNK_SIZE, i * MAX_CHUNK_SIZE + MAX_CHUNK_SIZE) 20 | ); 21 | finalBuf = Buffer.concat([finalBuf, f]); 22 | }); 23 | return finalBuf.toString("base64"); 24 | } catch (e) { 25 | console.log("encrypt ERROR", e); 26 | return ""; 27 | } 28 | } 29 | 30 | function decrypt(privateKey, enc) { 31 | try { 32 | const buf = Buffer.from(enc, "base64"); 33 | let finalDec = ""; 34 | const n = Math.ceil(buf.length / BLOCK_SIZE); 35 | const arr = Array(n).fill(0); 36 | const privc = cert.priv(privateKey); 37 | arr.forEach((_, i) => { 38 | const b = crypto.privateDecrypt( 39 | { 40 | key: privc, 41 | padding: crypto.constants.RSA_PKCS1_PADDING, 42 | }, 43 | buf.subarray(i * BLOCK_SIZE, i * BLOCK_SIZE + BLOCK_SIZE) 44 | ); 45 | finalDec += b.toString("utf-8"); 46 | }); 47 | return finalDec; 48 | } catch (e) { 49 | console.log("RSA decrypt ERROR", enc); 50 | return ""; 51 | } 52 | } 53 | 54 | function genKeys() { 55 | return new Promise((resolve, reject) => { 56 | crypto.generateKeyPair( 57 | "rsa", 58 | { 59 | modulusLength: 2048, 60 | }, 61 | (err, publicKey, privKey) => { 62 | const pubPEM = publicKey.export({ 63 | type: "pkcs1", 64 | format: "pem", 65 | }); 66 | const pubBase64 = cert.unpub(pubPEM); 67 | const privPEM = privKey.export({ 68 | type: "pkcs1", 69 | format: "pem", 70 | }); 71 | const privBase64 = cert.unpriv(privPEM); 72 | resolve({ 73 | public: pubBase64, 74 | private: privBase64, 75 | }); 76 | } 77 | ); 78 | }); 79 | } 80 | 81 | const cert = { 82 | unpub: function (key) { 83 | let s = key; 84 | s = s.replace("-----BEGIN RSA PUBLIC KEY-----", ""); 85 | s = s.replace("-----END RSA PUBLIC KEY-----", ""); 86 | return s.replace(/[\r\n]+/gm, ""); 87 | }, 88 | unpriv: function (key) { 89 | let s = key; 90 | s = s.replace("-----BEGIN RSA PRIVATE KEY-----", ""); 91 | s = s.replace("-----END RSA PRIVATE KEY-----", ""); 92 | return s.replace(/[\r\n]+/gm, ""); 93 | }, 94 | pub: function (key) { 95 | return ( 96 | "-----BEGIN RSA PUBLIC KEY-----\n" + 97 | key + 98 | "\n" + 99 | "-----END RSA PUBLIC KEY-----" 100 | ); 101 | }, 102 | priv: function (key) { 103 | return ( 104 | "-----BEGIN RSA PRIVATE KEY-----\n" + 105 | key + 106 | "\n" + 107 | "-----END RSA PRIVATE KEY-----" 108 | ); 109 | }, 110 | }; 111 | 112 | module.exports = { encrypt, decrypt, genKeys }; 113 | -------------------------------------------------------------------------------- /relay/setup/signup.js: -------------------------------------------------------------------------------- 1 | const Crypto = require("crypto"); 2 | var fs = require("fs"); 3 | var rsa = require("./rsa"); 4 | var fetch = require("./fetch"); 5 | var JSCryptor = require("./rncryptor"); 6 | var paths = require("./paths"); 7 | 8 | async function run_signup(n, i) { 9 | try { 10 | var finalNodes = require(paths.pathToWrite); 11 | if (finalNodes[i].authToken) return; // ALREADY SIGNED UP! 12 | const token = await signup(n); 13 | n = require(paths.pathToWrite)[i]; 14 | n.authToken = token; 15 | 16 | await createContactKey(n); 17 | } catch (e) { 18 | console.log(e); 19 | } 20 | } 21 | 22 | function headers(token, transportToken) { 23 | const h = { "Content-Type": "application/json" }; 24 | 25 | if (token && !transportToken) h["x-user-token"] = token; 26 | if (token && transportToken) { 27 | h["x-transport-token"] = rsa.encrypt( 28 | transportToken, 29 | `${token}|${Date.now()}` 30 | ); 31 | } 32 | return h; 33 | } 34 | function proxyHeaders(token) { 35 | const h = { "Content-Type": "application/json" }; 36 | if (token) h["x-admin-token"] = token; 37 | return h; 38 | } 39 | 40 | async function signup(n) { 41 | try { 42 | const token = Crypto.randomBytes(20).toString("base64").slice(0, 20); 43 | let transportToken = await getTransportToken(n); 44 | const r = await fetch(n.ip + "/contacts/tokens", { 45 | method: "POST", 46 | headers: headers(token, transportToken), 47 | body: JSON.stringify({ 48 | pubkey: n.pubkey, 49 | }), 50 | }); 51 | const json = await r.json(); 52 | 53 | addFieldToNodeJson(n.pubkey, "authToken", token); 54 | addFieldToNodeJson(n.pubkey, "transportToken", transportToken); 55 | 56 | return token; 57 | } catch (e) { 58 | console.log(e); 59 | } 60 | } 61 | 62 | async function getTransportToken(n) { 63 | const r = await fetch(n.ip + "/request_transport_key", { 64 | method: "GET", 65 | headers: headers(), 66 | }); 67 | const j = await r.json(); 68 | return j.response.transport_key; 69 | } 70 | 71 | async function getOwner(n) { 72 | console.log("-> getOwner"); 73 | try { 74 | const transportToken = await getTransportToken(n); 75 | const r = await fetch(n.ip + "/contacts", { 76 | method: "GET", 77 | headers: headers(n.authToken, transportToken), 78 | }); 79 | if (!r.ok) { 80 | console.log(await r.text()); 81 | throw new Error("couldnt getOwner"); 82 | } 83 | const j = await r.json(); 84 | const owner = j.response.contacts.find((c) => c.is_owner); 85 | // const id = owner.id; 86 | return owner; 87 | } catch (e) { 88 | console.log(e); 89 | throw e; 90 | } 91 | } 92 | 93 | async function createContactKey(n) { 94 | try { 95 | // console.log("NODE",n) 96 | 97 | const owner = await getOwner(n); 98 | const id = owner.id; 99 | const { public, private } = await rsa.genKeys(); 100 | addFieldToNodeJson(n.pubkey, "contact_key", public); 101 | addFieldToNodeJson(n.pubkey, "privkey", private); 102 | 103 | const r = await fetch(n.ip + "/contacts/" + id, { 104 | method: "PUT", 105 | headers: headers(n.authToken), 106 | body: JSON.stringify({ 107 | contact_key: public, 108 | alias: n.alias, 109 | }), 110 | }); 111 | const j = await r.json(); 112 | const owner2 = await getOwner(n); 113 | 114 | const str = `${private}::${public}::${n.external_ip}::${n.authToken}`; 115 | const pin = "111111"; 116 | const enc = JSCryptor.JSCryptor.Encrypt(str, pin); 117 | const final = Buffer.from(`keys::${enc}`).toString("base64"); 118 | addFieldToNodeJson(n.pubkey, "exported_keys", final); 119 | addFieldToNodeJson(n.pubkey, "pin", pin); 120 | console.log("===> contacts exchange key call finished"); 121 | } catch (e) { 122 | console.log(e); 123 | } 124 | } 125 | 126 | async function clearNode(n) { 127 | const r2 = await fetch(n.ip + "/test_clear", { 128 | headers: headers(n.authToken, n.transportToken), 129 | }); 130 | const j2 = await r2.json(); 131 | } 132 | 133 | async function addFieldToNodeJson(pubkey, key, value) { 134 | var nodes = require(paths.pathToWrite); 135 | const idx = nodes.findIndex((n) => n.pubkey === pubkey); 136 | if (idx < 0) return; 137 | nodes[idx][key] = value; 138 | const jsonString = JSON.stringify(nodes, null, 2); 139 | fs.writeFileSync(paths.pathToWrite, jsonString); 140 | } 141 | 142 | async function sleep(ms) { 143 | return new Promise((resolve) => setTimeout(resolve, ms)); 144 | } 145 | 146 | module.exports = { run_signup }; 147 | -------------------------------------------------------------------------------- /start-bot.sh: -------------------------------------------------------------------------------- 1 | echo '[]' > ./relay/botEnvVars.json 2 | 3 | docker-compose -f ./alts/proxy.yml -f ./alts/bots.yml --project-directory . up -d -------------------------------------------------------------------------------- /tribes/script.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stakwork/sphinx-stack/588840489e59c24d3b1b437fa6a2e63a0b58cb47/tribes/script.sh -------------------------------------------------------------------------------- /tribes/setup/index.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | 3 | const scriptPath = "./tribes/script.sh"; 4 | 5 | let interval; 6 | 7 | interval = setInterval(() => { 8 | try { 9 | const nodes = fs.readFileSync("./relay/NODES.json", "utf-8"); 10 | 11 | if (nodes) { 12 | console.log("Nodes:", nodes); 13 | const parsedNodes = JSON.parse(nodes); 14 | if (!Array.isArray(parsedNodes)) return; 15 | const node = parsedNodes.find((n) => n.alias === "bob"); 16 | if (!node) return; 17 | if (node.authToken && node.ip) { 18 | // Content of the Bash script 19 | finish(` 20 | #!/bin/bash 21 | echo "Hello from the Bash script!" 22 | export RELAY_URL=${node.ip} 23 | export RELAY_AUTH_KEY=${node.authToken} 24 | `); 25 | } 26 | if (node.adminToken && node.ip && node.v2 === true) { 27 | finish(` 28 | #!/bin/bash 29 | echo "Hello from the Bash script v2!" 30 | export V2_BOT_URL=${node.ip} 31 | export V2_BOT_TOKEN=${node.adminToken} 32 | `); 33 | } 34 | } 35 | } catch (error) { 36 | console.log( 37 | "Error trying to read relay nodes file: ", 38 | JSON.stringify(error) 39 | ); 40 | } 41 | }, 10000); 42 | 43 | function finish(bashScriptContent) { 44 | // Write to the file 45 | fs.writeFileSync(scriptPath, bashScriptContent); 46 | console.log(`Bash script written to: ${scriptPath}`); 47 | if (interval) { 48 | clearInterval(interval); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /utils/genkeys.js: -------------------------------------------------------------------------------- 1 | var JSCryptor = require("../relay/setup/rncryptor"); 2 | 3 | // your private "contact key" (for end-to-end RSA encryption) 4 | const private_key = "xxx"; 5 | // you public "contact key" 6 | const public_key = "xxx"; 7 | // ip / domain of your node 8 | const ip = "xxx"; 9 | // your sphinx relay auth token 10 | const auth_token = "xxx"; 11 | // app PIN code 12 | const pin = "111111"; 13 | 14 | const str = `${private_key}::${public_key}::${ip}::${auth_token}`; 15 | const enc = JSCryptor.JSCryptor.Encrypt(str, pin); 16 | const final = Buffer.from(`keys::${enc}`).toString("base64"); 17 | console.log(final); 18 | -------------------------------------------------------------------------------- /utils/viewkeys.js: -------------------------------------------------------------------------------- 1 | var JSCryptor = require("../relay/setup/rncryptor"); 2 | 3 | // your exported key string 4 | const exported_keys = 5 | "a2V5czo6QXdHalFrVXlPRHAyenNsNVk5bVpYTGt3MXRTeGZCcVMzTWRmdGtWM3krZ2k5S1pnZnNQVjNSeGZObWhjWG0rdGZ1TjM3ak5nd00yWTFYL1VzT0NhbGhqbVNKSi9nZVBHeE9JNGdJSDhhYTBLSE53Tnc5UjRNT3BFMXZ3Uk9hNkhUQ2M9"; 6 | // app PIN code 7 | const pin = "111111"; 8 | 9 | const buf = Buffer.from(exported_keys, "base64"); 10 | const keyz = buf.toString().substr(6); 11 | const dec = JSCryptor.JSCryptor.Decrypt(pin, keyz); 12 | 13 | const arr = dec.split("::"); 14 | 15 | console.log("=> private_key:", arr[0]); 16 | console.log("=> public_key:", arr[1]); 17 | console.log("=> ip:", arr[2]); 18 | console.log("=> auth_token:", arr[3]); 19 | -------------------------------------------------------------------------------- /utils/writeToEnv.js: -------------------------------------------------------------------------------- 1 | const readEnvVars = (envFilePath) => 2 | fs.readFileSync(envFilePath, "utf-8").split(os.EOL); 3 | 4 | export default function setEnvValue(key, value, envFilePath) { 5 | const envVars = readEnvVars(envFilePath); 6 | const targetLine = envVars.find((line) => line.split("=")[0] === key); 7 | if (targetLine !== undefined) { 8 | // update existing line 9 | const targetLineIndex = envVars.indexOf(targetLine); 10 | // replace the key/value with the new value 11 | envVars.splice(targetLineIndex, 1, `${key}="${value}"`); 12 | } else { 13 | // create new key value 14 | envVars.push(`${key}="${value}"`); 15 | } 16 | // write everything back to the file system 17 | fs.writeFileSync(envFilePath, envVars.join(os.EOL)); 18 | } 19 | -------------------------------------------------------------------------------- /v2/paths.js: -------------------------------------------------------------------------------- 1 | // paths to the nodes.json files 2 | 3 | const path = "/relay/nodes_partial.json"; 4 | const pathToWrite = "/relay/NODES.json"; 5 | 6 | module.exports = { 7 | path, 8 | pathToWrite, 9 | }; 10 | -------------------------------------------------------------------------------- /v2/setup.js: -------------------------------------------------------------------------------- 1 | var fetch = require("./fetch"); 2 | const ADMIN_TOKEN = process.env.ADMIN_TOKEN || "xyzxyzxyz"; 3 | var fs = require("fs"); 4 | var paths = require("./paths"); 5 | 6 | async function collect_contact(external_ip) { 7 | const ip = external_ip.replace("localhost", "host.docker.internal"); 8 | const ci = await get(ip, "account"); 9 | const arr = ci.contact_info.split("_"); 10 | return { 11 | pubkey: arr[0], 12 | routeHint: `${arr[1]}_${arr[2]}`, 13 | alias: ci.alias, 14 | ip, 15 | external_ip, 16 | adminToken: ADMIN_TOKEN, 17 | v2: true, 18 | }; 19 | } 20 | 21 | async function setup() { 22 | await sleep(30000); 23 | 24 | const ALICE = "http://localhost:3001"; 25 | const BOB = "http://localhost:3002"; 26 | 27 | const alice = await collect_contact(ALICE); 28 | const bob = await collect_contact(BOB); 29 | 30 | const nodes = [alice, bob]; 31 | const jsonString = JSON.stringify(nodes, null, 2); 32 | console.log(nodes); 33 | 34 | console.log("this is what we're writing", jsonString); 35 | fs.writeFileSync(paths.pathToWrite, jsonString); 36 | 37 | console.log("======================================"); 38 | console.log("== =="); 39 | console.log("== => SETUP COMPLETE! <= =="); 40 | console.log("== =="); 41 | console.log("======================================"); 42 | } 43 | setup(); 44 | 45 | async function post(root, path, body) { 46 | const headers = { 47 | "Content-Type": "application/json", 48 | }; 49 | headers["x-admin-token"] = ADMIN_TOKEN; 50 | const r = await fetch(root + "/" + path, { 51 | method: "POST", 52 | headers, 53 | body: JSON.stringify(body), 54 | }); 55 | const j = await r.json(); 56 | return j; 57 | } 58 | 59 | async function get(root, path) { 60 | const headers = {}; 61 | headers["x-admin-token"] = ADMIN_TOKEN; 62 | const r = await fetch(root + "/" + path, { 63 | method: "GET", 64 | headers, 65 | }); 66 | const j = await r.json(); 67 | return j; 68 | } 69 | 70 | async function sleep(ms) { 71 | return new Promise((resolve) => setTimeout(resolve, ms)); 72 | } 73 | -------------------------------------------------------------------------------- /zmq/index.js: -------------------------------------------------------------------------------- 1 | const zmq = require("zeromq"); 2 | 3 | async function run() { 4 | const sock = new zmq.Subscriber(); 5 | 6 | sock.connect("tcp://0.0.0.0:28332"); 7 | sock.subscribe("hashblock"); 8 | sock.subscribe("rawblock"); 9 | 10 | console.log("Subscriber connected"); 11 | 12 | for await (const [topic, msg] of sock) { 13 | console.log( 14 | "received a message related to: [", 15 | topic.toString(), 16 | "] containing message:", 17 | msg 18 | ); 19 | } 20 | } 21 | 22 | run(); 23 | --------------------------------------------------------------------------------