diff --git a/config/env/common.js b/config/env/common.js index b51a21c..c839c56 100644 --- a/config/env/common.js +++ b/config/env/common.js @@ -48,6 +48,8 @@ module.exports = { // IPFS settings. isCircuitRelay: process.env.ENABLE_CIRCUIT_RELAY ? true : false, + // SSL domain used for websocket connection via browsers. + crDomain: process.env.CR_DOMAIN ? process.env.CR_DOMAIN : '', // Information passed to other IPFS peers about this node. apiInfo: 'https://ipfs-service-provider.fullstack.cash/', diff --git a/package-lock.json b/package-lock.json index 1685763..31b122c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "axios": "^0.21.1", "bcryptjs": "^2.4.3", "glob": "^7.1.6", - "ipfs-coord": "^6.7.0", + "ipfs-coord": "^6.7.1", "jsonrpc-lite": "^2.2.0", "jsonwebtoken": "^8.5.1", "jwt-bch-lib": "^1.3.0", @@ -34,6 +34,7 @@ "node-fetch": "npm:@achingbrain/node-fetch@^2.6.7", "nodemailer": "^6.4.17", "passport-local": "^1.0.0", + "public-ip": "^4.0.4", "winston": "^3.3.3", "winston-daily-rotate-file": "^4.5.0" }, @@ -56,6 +57,38 @@ "uuid": "^8.3.2" } }, + "../ipfs-coord": { + "version": "6.0.0", + "extraneous": true, + "license": "MIT", + "dependencies": { + "axios": "^0.21.4", + "bch-encrypt-lib": "^2.0.0", + "orbit-db": "^0.26.1" + }, + "devDependencies": { + "@psf/bch-js": "^4.20.10", + "apidoc": "^0.25.0", + "chai": "^4.2.0", + "coveralls": "^3.1.0", + "eslint": "7.17.0", + "eslint-config-prettier": "^7.1.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-prettier": "^3.3.1", + "eslint-plugin-standard": "^4.0.0", + "husky": "^4.3.6", + "lodash.clonedeep": "^4.5.0", + "mocha": "^8.4.0", + "nyc": "^15.1.0", + "semantic-release": "^17.4.4", + "sinon": "^9.2.2", + "standard": "^16.0.3" + }, + "peerDependencies": { + "@chris.troutner/ipfs": "^2.0.2" + } + }, "node_modules/@assemblyscript/loader": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/@assemblyscript/loader/-/loader-0.9.4.tgz", @@ -1017,9 +1050,9 @@ } }, "node_modules/@ethersproject/bignumber": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", - "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.2.tgz", + "integrity": "sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA==", "funding": [ { "type": "individual", @@ -6480,6 +6513,17 @@ "node": ">=6" } }, + "node_modules/dns-socket": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.2.tgz", + "integrity": "sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==", + "dependencies": { + "dns-packet": "^5.2.4" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -7694,9 +7738,9 @@ } }, "node_modules/ethers": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.6.tgz", - "integrity": "sha512-F7LXARyB/Px3AQC6/QKedWZ8eqCkgOLORqL4B/F0Mag/K+qJSFGqsR36EaOZ6fKg3ZonI+pdbhb4A8Knt/43jQ==", + "version": "5.4.7", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.7.tgz", + "integrity": "sha512-iZc5p2nqfWK1sj8RabwsPM28cr37Bpq7ehTQ5rWExBr2Y09Sn1lDKZOED26n+TsZMye7Y6mIgQ/1cwpSD8XZew==", "funding": [ { "type": "individual", @@ -7714,7 +7758,7 @@ "@ethersproject/address": "5.4.0", "@ethersproject/base64": "5.4.0", "@ethersproject/basex": "5.4.0", - "@ethersproject/bignumber": "5.4.1", + "@ethersproject/bignumber": "5.4.2", "@ethersproject/bytes": "5.4.0", "@ethersproject/constants": "5.4.0", "@ethersproject/contracts": "5.4.1", @@ -10375,9 +10419,9 @@ } }, "node_modules/ipfs-coord": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ipfs-coord/-/ipfs-coord-6.7.0.tgz", - "integrity": "sha512-aIOgtyY9xLMfUcVlASLCXEl6njCJmzcpBO3QQH/OPVYtU0getNX6EeEx+2/qAHe+Yt28nqMscEN9EeU+3sEIsg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/ipfs-coord/-/ipfs-coord-6.7.1.tgz", + "integrity": "sha512-II0z1fNeWIHmEkRC9b2bNyMt0qJXH8+XNH7352iF7V/5hn7ix8+gNfmgDtno+C8DDy3kk6voQntf0v/WSzC45Q==", "dependencies": { "axios": "^0.21.4", "bch-encrypt-lib": "^2.0.0", @@ -19691,11 +19735,10 @@ } }, "node_modules/orbit-db-access-controllers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/orbit-db-access-controllers/-/orbit-db-access-controllers-0.3.0.tgz", - "integrity": "sha512-H7xfgpcyAx9ToFYMvpP7StCt269uaqM33lnMdY9T1o3gbP8IYe0wPurkPQwg6IVZHrDeeBvTDA7kbOqShf9vJw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/orbit-db-access-controllers/-/orbit-db-access-controllers-0.3.2.tgz", + "integrity": "sha512-FbeWkDoMdLESifPlXu8HBLCSD+JAIRu9Hs9oxppgKzp7YxC7ok+JDy8Z6VaR2jgaZFmiShLB1febX9sNMk91sw==", "dependencies": { - "orbit-db-io": "^0.3.0", "p-map-series": "^1.0.0" } }, @@ -21729,9 +21772,9 @@ } }, "node_modules/protocol-buffers-schema": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.2.tgz", - "integrity": "sha512-LPzSaBYp/TcbuSlpGwqT5jR9kvJ3Zp5ic2N5c2ybx6XB/lSfEHq2D7ja8AgoxHoMD91wXFALJoXsvshKPuXyew==" + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, "node_modules/protons": { "version": "2.0.3", @@ -21778,6 +21821,22 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "node_modules/public-ip": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.4.tgz", + "integrity": "sha512-EJ0VMV2vF6Cu7BIPo3IMW1Maq6ME+fbR0NcPmqDfpfNGIRPue1X8QrGjrg/rfjDkOsIkKHIf2S5FlEa48hFMTA==", + "dependencies": { + "dns-socket": "^4.2.2", + "got": "^9.6.0", + "is-ip": "^3.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -26897,9 +26956,9 @@ } }, "@ethersproject/bignumber": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.1.tgz", - "integrity": "sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==", + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.4.2.tgz", + "integrity": "sha512-oIBDhsKy5bs7j36JlaTzFgNPaZjiNDOXsdSgSpXRucUl+UA6L/1YLlFeI3cPAoodcenzF4nxNPV13pcy7XbWjA==", "requires": { "@ethersproject/bytes": "^5.4.0", "@ethersproject/logger": "^5.4.0", @@ -31254,6 +31313,14 @@ "@leichtgewicht/ip-codec": "^2.0.1" } }, + "dns-socket": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/dns-socket/-/dns-socket-4.2.2.tgz", + "integrity": "sha512-BDeBd8najI4/lS00HSKpdFia+OvUMytaVjfzR9n5Lq8MlZRSvtbI+uLtx1+XmQFls5wFU9dssccTmQQ6nfpjdg==", + "requires": { + "dns-packet": "^5.2.4" + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -32205,9 +32272,9 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "ethers": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.6.tgz", - "integrity": "sha512-F7LXARyB/Px3AQC6/QKedWZ8eqCkgOLORqL4B/F0Mag/K+qJSFGqsR36EaOZ6fKg3ZonI+pdbhb4A8Knt/43jQ==", + "version": "5.4.7", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.4.7.tgz", + "integrity": "sha512-iZc5p2nqfWK1sj8RabwsPM28cr37Bpq7ehTQ5rWExBr2Y09Sn1lDKZOED26n+TsZMye7Y6mIgQ/1cwpSD8XZew==", "requires": { "@ethersproject/abi": "5.4.1", "@ethersproject/abstract-provider": "5.4.1", @@ -32215,7 +32282,7 @@ "@ethersproject/address": "5.4.0", "@ethersproject/base64": "5.4.0", "@ethersproject/basex": "5.4.0", - "@ethersproject/bignumber": "5.4.1", + "@ethersproject/bignumber": "5.4.2", "@ethersproject/bytes": "5.4.0", "@ethersproject/constants": "5.4.0", "@ethersproject/contracts": "5.4.1", @@ -34259,9 +34326,9 @@ } }, "ipfs-coord": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/ipfs-coord/-/ipfs-coord-6.7.0.tgz", - "integrity": "sha512-aIOgtyY9xLMfUcVlASLCXEl6njCJmzcpBO3QQH/OPVYtU0getNX6EeEx+2/qAHe+Yt28nqMscEN9EeU+3sEIsg==", + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/ipfs-coord/-/ipfs-coord-6.7.1.tgz", + "integrity": "sha512-II0z1fNeWIHmEkRC9b2bNyMt0qJXH8+XNH7352iF7V/5hn7ix8+gNfmgDtno+C8DDy3kk6voQntf0v/WSzC45Q==", "requires": { "axios": "^0.21.4", "bch-encrypt-lib": "^2.0.0", @@ -41599,11 +41666,10 @@ } }, "orbit-db-access-controllers": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/orbit-db-access-controllers/-/orbit-db-access-controllers-0.3.0.tgz", - "integrity": "sha512-H7xfgpcyAx9ToFYMvpP7StCt269uaqM33lnMdY9T1o3gbP8IYe0wPurkPQwg6IVZHrDeeBvTDA7kbOqShf9vJw==", + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/orbit-db-access-controllers/-/orbit-db-access-controllers-0.3.2.tgz", + "integrity": "sha512-FbeWkDoMdLESifPlXu8HBLCSD+JAIRu9Hs9oxppgKzp7YxC7ok+JDy8Z6VaR2jgaZFmiShLB1febX9sNMk91sw==", "requires": { - "orbit-db-io": "^0.3.0", "p-map-series": "^1.0.0" } }, @@ -43131,9 +43197,9 @@ } }, "protocol-buffers-schema": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.2.tgz", - "integrity": "sha512-LPzSaBYp/TcbuSlpGwqT5jR9kvJ3Zp5ic2N5c2ybx6XB/lSfEHq2D7ja8AgoxHoMD91wXFALJoXsvshKPuXyew==" + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" }, "protons": { "version": "2.0.3", @@ -43182,6 +43248,16 @@ "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==", "dev": true }, + "public-ip": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/public-ip/-/public-ip-4.0.4.tgz", + "integrity": "sha512-EJ0VMV2vF6Cu7BIPo3IMW1Maq6ME+fbR0NcPmqDfpfNGIRPue1X8QrGjrg/rfjDkOsIkKHIf2S5FlEa48hFMTA==", + "requires": { + "dns-socket": "^4.2.2", + "got": "^9.6.0", + "is-ip": "^3.1.0" + } + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", diff --git a/package.json b/package.json index 99a7f9f..baca57a 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ }, "repository": "Permissionless-Software-Foundation/ipfs-service-provider", "dependencies": { + "@chris.troutner/ipfs": "2.0.2", "@psf/bch-js": "^4.20.13", "axios": "^0.21.1", "bcryptjs": "^2.4.3", "glob": "^7.1.6", - "@chris.troutner/ipfs": "2.0.2", - "ipfs-coord": "^6.7.0", + "ipfs-coord": "^6.7.1", "jsonrpc-lite": "^2.2.0", "jsonwebtoken": "^8.5.1", "jwt-bch-lib": "^1.3.0", @@ -48,6 +48,7 @@ "node-fetch": "npm:@achingbrain/node-fetch@^2.6.7", "nodemailer": "^6.4.17", "passport-local": "^1.0.0", + "public-ip": "^4.0.4", "winston": "^3.3.3", "winston-daily-rotate-file": "^4.5.0" }, diff --git a/production/docker/start-production.sh b/production/docker/start-production.sh index 8398de2..b1d6034 100755 --- a/production/docker/start-production.sh +++ b/production/docker/start-production.sh @@ -4,6 +4,7 @@ # This mnemonic is used to set up persistent public key for e2ee # Replace this with your own 12-word mnemonic. +# You can get one at https://wallet.fullstack.cash. export MNEMONIC="olive two muscle bottom coral ancient wait legend bronze useful process session" # The human readable name this IPFS node identifies as. @@ -11,6 +12,9 @@ export COORD_NAME=ipfs-service-provider-generic # Allow this node to function as a circuit relay. It must not be behind a firewall. #export ENABLE_CIRCUIT_RELAY=true +# For browsers to use your circuit realy, you must set up a domain, SSL certificate, +# and you must forward that subdomain to the IPFS_WS_PORT. +#export CR_DOMAIN=subdomain.yourdomain.com # Debug level. 0 = minimal info. 2 = max info. export DEBUG_LEVEL=1 diff --git a/ipfs-service-provider.sh b/shell-scripts/ipfs-service-provider-generic.sh similarity index 55% rename from ipfs-service-provider.sh rename to shell-scripts/ipfs-service-provider-generic.sh index 993860e..75afe63 100755 --- a/ipfs-service-provider.sh +++ b/shell-scripts/ipfs-service-provider-generic.sh @@ -1,18 +1,22 @@ #!/bin/bash +# This script is an example for running a generic ipfs-service-provider instance. + # Ports export PORT=5001 # REST API port export IPFS_TCP_PORT=5268 export IPFS_WS_PORT=5269 -#export ENABLE_CIRCUIT_RELAY=1 - -# Production database connection string. -#export DBURL=mongodb://localhost:27017/bch-service-dev - +# The human-readible name that is used when displaying data about this node. export COORD_NAME=ipfs-service-provider-generic + +# This is used for end-to-end encryption (e2ee). export MNEMONIC="churn aisle shield silver ladder swear hunt slim pen demand spoil veteran" +# 0 = less verbose. 3 = most verbose export DEBUG_LEVEL=1 +# MongoDB connection string. +#export DBURL=mongodb://localhost:27017/bch-service-dev + npm start diff --git a/shell-scripts/ipfs-service-provider-relay.sh b/shell-scripts/ipfs-service-provider-relay.sh new file mode 100755 index 0000000..9d31ac9 --- /dev/null +++ b/shell-scripts/ipfs-service-provider-relay.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# This script is an example for running a ipfs-service-provider as a Circuit Relay. +# Circuit Relays are help other nodes on the network communicate. They are +# critical for reliable functioning of the network, and for circumventing +# censorship. + +# Ports +export PORT=5001 # REST API port +export IPFS_TCP_PORT=5268 +export IPFS_WS_PORT=5269 + +# The human-readible name that is used when displaying data about this node. +export COORD_NAME=ipfs-service-provider-generic + +# This is used for end-to-end encryption (e2ee). +export MNEMONIC="churn aisle shield silver ladder swear hunt slim pen demand spoil veteran" + +# 0 = less verbose. 3 = most verbose +export DEBUG_LEVEL=1 + +# MongoDB connection string. +#export DBURL=mongodb://localhost:27017/bch-service-dev + +# Comment to disable circuit relay functionality. Or set to 1 to enable. +export ENABLE_CIRCUIT_RELAY=1 +# For browsers to use your circuit realy, you must set up a domain, SSL certificate, +# and you must forward that subdomain to the IPFS_WS_PORT. +#export CR_DOMAIN=subdomain.yourdomain.com + +npm start diff --git a/src/adapters/ipfs/ipfs-coord.js b/src/adapters/ipfs/ipfs-coord.js index feb4ec9..cbb546f 100644 --- a/src/adapters/ipfs/ipfs-coord.js +++ b/src/adapters/ipfs/ipfs-coord.js @@ -7,6 +7,7 @@ // Global npm libraries const IpfsCoord = require('ipfs-coord') const BCHJS = require('@psf/bch-js') +const publicIp = require('public-ip') // Local libraries const config = require('../../../config') @@ -38,6 +39,24 @@ class IpfsCoordAdapter { } async start () { + const circuitRelayInfo = {} + + // If configured as a Circuit Relay, get the public IP addresses for this node. + if (this.config.isCircuitRelay) { + try { + const ip4 = await publicIp.v4() + // const ip6 = await publicIp.v6() + + circuitRelayInfo.ip4 = ip4 + circuitRelayInfo.tcpPort = this.config.ipfsTcpPort + + // Domain used by browser-based secure websocket connections. + circuitRelayInfo.crDomain = this.config.crDomain + } catch (err) { + /* exit quietly */ + } + } + this.ipfsCoord = new this.IpfsCoord({ ipfs: this.ipfs, type: 'node.js', @@ -45,6 +64,7 @@ class IpfsCoordAdapter { bchjs: this.bchjs, privateLog: console.log, // Default to console.log isCircuitRelay: this.config.isCircuitRelay, + circuitRelayInfo, apiInfo: this.config.apiInfo, announceJsonLd: this.config.announceJsonLd, debugLevel: this.config.debugLevel