mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-21 16:52:03 -07:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
673a9c8c7a | ||
|
|
4d4b678447 | ||
|
|
e9606ecfe8 | ||
|
|
bfc0a5be9f | ||
|
|
af68e411bd | ||
|
|
b9b79c2142 | ||
|
|
58f24954ca | ||
|
|
6f4f21b373 | ||
|
|
b0e42bb956 | ||
|
|
efb02a4381 | ||
|
|
d894c1e596 | ||
|
|
821cf4abe8 | ||
|
|
74696cfb9e | ||
|
|
0bfb84e21b | ||
|
|
35b4e7079d | ||
|
|
7d369859a5 | ||
|
|
75ea6ecdde | ||
|
|
d4c9665c16 | ||
|
|
768bfdb4e7 | ||
|
|
764fe928d2 | ||
|
|
2de61458d3 | ||
|
|
d38e371a05 | ||
|
|
a68ca92468 | ||
|
|
7c26e33a8c | ||
|
|
2595ee8295 | ||
|
|
476fdcd0aa | ||
|
|
b6762b215e | ||
|
|
8faadfc5c1 | ||
|
|
fe0ad56395 | ||
|
|
0e6a411012 | ||
|
|
55e9e35c1f |
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"email": "system@system.com",
|
"email": "system@system.com",
|
||||||
"name": "admin",
|
"name": "admin",
|
||||||
"password": "SyP9YCFkgxu2FPNxFI8W",
|
"password": "c9JjJxZmTs5bWmWC6adQ",
|
||||||
"type": "admin",
|
"type": "admin",
|
||||||
"id": "68d47521e6060ba7332301b1",
|
"id": "68d47521e6060ba7332301b1",
|
||||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY4ZDQ3NTIxZTYwNjBiYTczMzIzMDFiMSIsImlhdCI6MTc1OTE3NjQ3Mn0.pGJh_Io1_aZ3IwWdzOnC5Bt9Nw0x4MRhAAp7RkZrtmA"
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY4ZDQ3NTIxZTYwNjBiYTczMzIzMDFiMSIsImlhdCI6MTc2MDY0MzI5NH0.SgoWnrP0YZZtPZ2V_C7HsfKoRHphfoIODN3-pltsGbo"
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"email": "system@system.com",
|
"email": "system@system.com",
|
||||||
"name": "admin",
|
"name": "admin",
|
||||||
"password": "UdbCjMgm7T8efeyUfcdN",
|
"password": "NR0S1fPGLOAGUwPfKpJe",
|
||||||
"type": "admin",
|
"type": "admin",
|
||||||
"id": "68daea62e9b47af49f86dae9",
|
"id": "698277538440afae85603e83",
|
||||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY4ZGFlYTYyZTliNDdhZjQ5Zjg2ZGFlOSIsImlhdCI6MTc1OTE3NzMxNH0.-mFCzyDri0OLMz-oM03qyYPj7srEH_6HFLGzgCf_JLI"
|
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY5ODI3NzUzODQ0MGFmYWU4NTYwM2U4MyIsImlhdCI6MTc3MDE1NzkwN30.rBILkWIXFtj0OkGBQyJyf89i9S2SYhm4ETPhvevVwaQ"
|
||||||
}
|
}
|
||||||
Generated
+5723
-6646
File diff suppressed because it is too large
Load Diff
+11
-21
@@ -25,28 +25,10 @@
|
|||||||
},
|
},
|
||||||
"repository": "Permissionless-Software-Foundation/ipfs-bch-wallet-consumer",
|
"repository": "Permissionless-Software-Foundation/ipfs-bch-wallet-consumer",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chainsafe/libp2p-gossipsub": "14.1.0",
|
|
||||||
"@chainsafe/libp2p-noise": "16.0.1",
|
|
||||||
"@chainsafe/libp2p-yamux": "7.0.1",
|
|
||||||
"@helia/unixfs": "4.0.2",
|
|
||||||
"@libp2p/bootstrap": "11.0.26",
|
|
||||||
"@libp2p/circuit-relay-v2": "3.2.2",
|
|
||||||
"@libp2p/config": "1.1.0",
|
|
||||||
"@libp2p/identify": "3.0.22",
|
|
||||||
"@libp2p/keychain": "5.0.14",
|
|
||||||
"@libp2p/logger": "5.1.8",
|
|
||||||
"@libp2p/ping": "2.0.22",
|
|
||||||
"@libp2p/tcp": "10.1.2",
|
|
||||||
"@libp2p/webrtc": "5.2.2",
|
|
||||||
"@libp2p/websockets": "9.2.2",
|
|
||||||
"@multiformats/multiaddr": "12.3.5",
|
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"bcryptjs": "2.4.3",
|
"bcryptjs": "2.4.3",
|
||||||
"blockstore-fs": "2.0.2",
|
|
||||||
"datastore-fs": "10.0.2",
|
|
||||||
"glob": "7.1.6",
|
"glob": "7.1.6",
|
||||||
"helia": "5.2.1",
|
"helia-coord": "2.0.3",
|
||||||
"helia-coord": "1.7.2",
|
|
||||||
"jsonrpc-lite": "2.2.0",
|
"jsonrpc-lite": "2.2.0",
|
||||||
"jsonwebtoken": "8.5.1",
|
"jsonwebtoken": "8.5.1",
|
||||||
"jwt-bch-lib": "1.3.0",
|
"jwt-bch-lib": "1.3.0",
|
||||||
@@ -61,10 +43,9 @@
|
|||||||
"koa-router": "10.0.0",
|
"koa-router": "10.0.0",
|
||||||
"koa-static": "5.0.0",
|
"koa-static": "5.0.0",
|
||||||
"koa2-ratelimit": "0.9.1",
|
"koa2-ratelimit": "0.9.1",
|
||||||
"libp2p": "2.7.2",
|
|
||||||
"line-reader": "0.4.0",
|
"line-reader": "0.4.0",
|
||||||
"mime-types": "2.1.35",
|
"mime-types": "2.1.35",
|
||||||
"minimal-slp-wallet": "5.13.2",
|
"minimal-slp-wallet": "7.1.4",
|
||||||
"mongoose": "5.13.14",
|
"mongoose": "5.13.14",
|
||||||
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
|
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
|
||||||
"nodemailer": "6.7.5",
|
"nodemailer": "6.7.5",
|
||||||
@@ -105,5 +86,14 @@
|
|||||||
"ignore": [
|
"ignore": [
|
||||||
"/test/unit/mocks/**/*.js"
|
"/test/unit/mocks/**/*.js"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"overrides": {
|
||||||
|
"@multiformats/multiaddr-to-uri": "10.1.2",
|
||||||
|
"@multiformats/multiaddr-matcher": "1.6.0",
|
||||||
|
"@libp2p/utils": "6.7.1",
|
||||||
|
"helia": {
|
||||||
|
"libp2p": "2.7.2",
|
||||||
|
"@libp2p/upnp-nat": "3.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#IMAGE BUILD COMMANDS
|
#IMAGE BUILD COMMANDS
|
||||||
# ct-base-ubuntu = ubuntu 18.04 + nodejs v10 LTS
|
# ct-base-ubuntu = ubuntu 18.04 + nodejs v10 LTS
|
||||||
#FROM christroutner/ct-base-ubuntu
|
#FROM christroutner/ct-base-ubuntu
|
||||||
FROM ubuntu:20.04
|
FROM ubuntu:24.04
|
||||||
MAINTAINER Chris Troutner <chris.troutner@gmail.com>
|
MAINTAINER Chris Troutner <chris.troutner@gmail.com>
|
||||||
|
|
||||||
#Update the OS and install any OS packages needed.
|
#Update the OS and install any OS packages needed.
|
||||||
@@ -15,7 +15,7 @@ RUN apt-get install -y sudo git curl nano gnupg wget
|
|||||||
RUN sudo apt-get install -y ca-certificates curl gnupg
|
RUN sudo apt-get install -y ca-certificates curl gnupg
|
||||||
RUN sudo mkdir -p /etc/apt/keyrings
|
RUN sudo mkdir -p /etc/apt/keyrings
|
||||||
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
|
||||||
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
|
RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_22.x nodistro main" | sudo tee /etc/apt/sources.list.d/nodesource.list
|
||||||
RUN sudo apt-get update
|
RUN sudo apt-get update
|
||||||
RUN sudo apt-get install -y nodejs build-essential
|
RUN sudo apt-get install -y nodejs build-essential
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class Adapters {
|
|||||||
this.passport = new Passport()
|
this.passport = new Passport()
|
||||||
this.nodemailer = new Nodemailer()
|
this.nodemailer = new Nodemailer()
|
||||||
this.jsonFiles = new JSONFiles()
|
this.jsonFiles = new JSONFiles()
|
||||||
this.bchjs = new BCHJS()
|
this.bchjs = new BCHJS({ restURL: config.apiServer })
|
||||||
this.config = config
|
this.config = config
|
||||||
this.bch = new BCH(localConfig)
|
this.bch = new BCH(localConfig)
|
||||||
this.p2wdb = new P2WDB(localConfig)
|
this.p2wdb = new P2WDB(localConfig)
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ class IpfsCoordAdapter {
|
|||||||
// Persist the config setting, so it can be used by other commands.
|
// Persist the config setting, so it can be used by other commands.
|
||||||
// _this.conf.set('selectedService', thisPeer)
|
// _this.conf.set('selectedService', thisPeer)
|
||||||
console.log(`---->BCH wallet service selected: ${thisPeer}`)
|
console.log(`---->BCH wallet service selected: ${thisPeer}`)
|
||||||
|
console.log('preferredProvider: ', _this.config.preferredProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('preferredProvider: ', _this.config.preferredProvider)
|
// console.log('preferredProvider: ', _this.config.preferredProvider)
|
||||||
@@ -287,11 +288,12 @@ class IpfsCoordAdapter {
|
|||||||
_this.config.preferredProvider &&
|
_this.config.preferredProvider &&
|
||||||
thisPeer === _this.config.preferredProvider
|
thisPeer === _this.config.preferredProvider
|
||||||
) {
|
) {
|
||||||
console.log('preferredProvider: ', _this.config.preferredProvider)
|
// console.log('preferredProvider: ', _this.config.preferredProvider)
|
||||||
console.log('thisPeer: ', thisPeer)
|
// console.log('thisPeer: ', thisPeer)
|
||||||
console.log('selectedServiceProvider: ', _this.state.selectedServiceProvider)
|
// console.log('selectedServiceProvider: ', _this.state.selectedServiceProvider)
|
||||||
if (_this.state.selectedServiceProvider !== thisPeer) {
|
if (_this.state.selectedServiceProvider !== thisPeer) {
|
||||||
console.log(`---->BCH wallet service switched to preferred peer: ${thisPeer}`)
|
console.log(`---->BCH wallet service switched to preferred peer: ${thisPeer}`)
|
||||||
|
console.log('preferredProvider: ', _this.config.preferredProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
_this.state.selectedServiceProvider = thisPeer
|
_this.state.selectedServiceProvider = thisPeer
|
||||||
@@ -370,6 +372,7 @@ class IpfsCoordAdapter {
|
|||||||
// Persist the config setting, so it can be used by other commands.
|
// Persist the config setting, so it can be used by other commands.
|
||||||
// _this.conf.set('selectedService', thisPeer)
|
// _this.conf.set('selectedService', thisPeer)
|
||||||
console.log(`---->IPFS File service selected: ${thisPeer}`)
|
console.log(`---->IPFS File service selected: ${thisPeer}`)
|
||||||
|
console.log('preferredIpfsFileProvider: ', _this.config.preferredIpfsFileProvider)
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('preferredProvider: ', _this.config.preferredProvider)
|
// console.log('preferredProvider: ', _this.config.preferredProvider)
|
||||||
|
|||||||
+17
-228
@@ -3,36 +3,12 @@
|
|||||||
This library deals with IPFS so that the apps business logic doesn't need
|
This library deals with IPFS so that the apps business logic doesn't need
|
||||||
to have any specific knowledge of the js-ipfs library.
|
to have any specific knowledge of the js-ipfs library.
|
||||||
|
|
||||||
TODO: Add the external IP address to the list of multiaddrs advertised by
|
Node creation is delegated to helia-coord's CreateHeliaNode factory,
|
||||||
this node. See this GitHub Issue for details:
|
which encapsulates all helia/libp2p dependencies and configuration.
|
||||||
https://github.com/Permissionless-Software-Foundation/ipfs-service-provider/issues/38
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Global npm libraries
|
// Global npm libraries
|
||||||
import { createHelia } from 'helia'
|
import CreateHeliaNode from 'helia-coord/create-helia-node'
|
||||||
import fs from 'fs'
|
|
||||||
import { FsBlockstore } from 'blockstore-fs'
|
|
||||||
import { FsDatastore } from 'datastore-fs'
|
|
||||||
import { createLibp2p } from 'libp2p'
|
|
||||||
import { tcp } from '@libp2p/tcp'
|
|
||||||
import { noise } from '@chainsafe/libp2p-noise'
|
|
||||||
import { yamux } from '@chainsafe/libp2p-yamux'
|
|
||||||
// import { bootstrap } from '@libp2p/bootstrap'
|
|
||||||
// import { identifyService } from 'libp2p/identify'
|
|
||||||
import { identify, identifyPush } from '@libp2p/identify'
|
|
||||||
import { circuitRelayServer, circuitRelayTransport } from '@libp2p/circuit-relay-v2'
|
|
||||||
// import { circuitRelayServer } from '@libp2p/circuit-relay-v2'
|
|
||||||
import { gossipsub } from '@chainsafe/libp2p-gossipsub'
|
|
||||||
import { webSockets } from '@libp2p/websockets'
|
|
||||||
import { publicIpv4 } from 'public-ip'
|
|
||||||
import { multiaddr } from '@multiformats/multiaddr'
|
|
||||||
import { webRTC, webRTCDirect } from '@libp2p/webrtc'
|
|
||||||
import { keychain } from '@libp2p/keychain'
|
|
||||||
import { unixfs } from '@helia/unixfs'
|
|
||||||
// import { generateKeyPairFromSeed } from '@libp2p/crypto/keys'
|
|
||||||
// import crypto from 'crypto'
|
|
||||||
import { ping } from '@libp2p/ping'
|
|
||||||
import { loadOrCreateSelfKey } from '@libp2p/config'
|
|
||||||
|
|
||||||
// Local libraries
|
// Local libraries
|
||||||
import config from '../../../config/index.js'
|
import config from '../../../config/index.js'
|
||||||
@@ -42,59 +18,44 @@ import JsonFiles from '../json-files.js'
|
|||||||
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
||||||
import * as url from 'url'
|
import * as url from 'url'
|
||||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||||
// console.log('__dirname: ', __dirname)
|
|
||||||
|
|
||||||
const ROOT_DIR = `${__dirname}../../../`
|
|
||||||
const IPFS_DIR = `${__dirname}../../../.ipfsdata/ipfs`
|
const IPFS_DIR = `${__dirname}../../../.ipfsdata/ipfs`
|
||||||
|
|
||||||
class IpfsAdapter {
|
class IpfsAdapter {
|
||||||
constructor (localConfig) {
|
constructor (localConfig) {
|
||||||
// Encapsulate dependencies
|
// Encapsulate dependencies
|
||||||
this.config = config
|
this.config = config
|
||||||
this.fs = fs
|
|
||||||
this.createLibp2p = createLibp2p
|
|
||||||
this.publicIp = publicIpv4
|
|
||||||
this.multiaddr = multiaddr
|
|
||||||
this.jsonFiles = new JsonFiles()
|
this.jsonFiles = new JsonFiles()
|
||||||
this.keychain = keychain
|
|
||||||
this.createHelia = createHelia
|
|
||||||
|
|
||||||
// Properties of this class instance.
|
// Properties of this class instance.
|
||||||
this.isReady = false
|
this.isReady = false
|
||||||
|
|
||||||
// Bind 'this' object to all subfunctions
|
// Bind 'this' object to all subfunctions
|
||||||
this.start = this.start.bind(this)
|
this.start = this.start.bind(this)
|
||||||
this.createNode = this.createNode.bind(this)
|
|
||||||
this.stop = this.stop.bind(this)
|
this.stop = this.stop.bind(this)
|
||||||
this.ensureBlocksDir = this.ensureBlocksDir.bind(this)
|
|
||||||
// this.getPrivateKey = this.getPrivateKey.bind(this)
|
|
||||||
this.getSeed = this.getSeed.bind(this)
|
this.getSeed = this.getSeed.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start an IPFS node.
|
// Start an IPFS node.
|
||||||
async start () {
|
async start () {
|
||||||
try {
|
try {
|
||||||
// Ensure the directory structure exists that is needed by the IPFS node to store data.
|
// Create the helia-coord node factory with production configuration.
|
||||||
this.ensureBlocksDir()
|
this.heliaNode = new CreateHeliaNode({
|
||||||
|
ipfsDir: IPFS_DIR,
|
||||||
|
tcpPort: this.config.ipfsTcpPort,
|
||||||
|
wsPort: this.config.ipfsWsPort,
|
||||||
|
isCircuitRelay: this.config.isCircuitRelay,
|
||||||
|
getSeed: this.getSeed
|
||||||
|
})
|
||||||
|
|
||||||
// Create an IPFS node
|
// Start the IPFS node (creates dirs, libp2p, helia, detects public IP)
|
||||||
const ipfs = await this.createNode()
|
const ipfs = await this.heliaNode.start()
|
||||||
// console.log('ipfs: ', ipfs)
|
|
||||||
|
this.id = this.heliaNode.id
|
||||||
|
this.multiaddrs = this.heliaNode.multiaddrs
|
||||||
|
|
||||||
this.id = ipfs.libp2p.peerId.toString()
|
|
||||||
console.log('IPFS ID: ', this.id)
|
console.log('IPFS ID: ', this.id)
|
||||||
|
console.log('Multiaddrs: ', this.multiaddrs)
|
||||||
// Attempt to guess our ip4 IP address.
|
|
||||||
const ip4 = await this.publicIp()
|
|
||||||
let detectedMultiaddr = `/ip4/${ip4}/tcp/${this.config.ipfsTcpPort}/p2p/${this.id}`
|
|
||||||
detectedMultiaddr = this.multiaddr(detectedMultiaddr)
|
|
||||||
|
|
||||||
// Get the multiaddrs for the node.
|
|
||||||
const multiaddrs = ipfs.libp2p.getMultiaddrs()
|
|
||||||
multiaddrs.push(detectedMultiaddr)
|
|
||||||
console.log('Multiaddrs: ', multiaddrs)
|
|
||||||
|
|
||||||
this.multiaddrs = multiaddrs
|
|
||||||
|
|
||||||
// Signal that this adapter is ready.
|
// Signal that this adapter is ready.
|
||||||
this.isReady = true
|
this.isReady = true
|
||||||
@@ -104,111 +65,6 @@ class IpfsAdapter {
|
|||||||
return this.ipfs
|
return this.ipfs
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error in ipfs.js/start()')
|
console.error('Error in ipfs.js/start()')
|
||||||
|
|
||||||
// If IPFS crashes because the /blocks directory is full, wipe the directory.
|
|
||||||
// if (err.message.includes('No space left on device')) {
|
|
||||||
// this.rmBlocksDir()
|
|
||||||
// }
|
|
||||||
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function creates an IPFS node using Helia.
|
|
||||||
// It returns the node as an object.
|
|
||||||
async createNode () {
|
|
||||||
try {
|
|
||||||
// Create block and data stores.
|
|
||||||
const blockstore = new FsBlockstore(`${IPFS_DIR}/blockstore`)
|
|
||||||
const datastore = new FsDatastore(`${IPFS_DIR}/datastore`)
|
|
||||||
|
|
||||||
// Get the private key.
|
|
||||||
// const privateKey = await this.getPrivateKey()
|
|
||||||
// console.log('privateKey: ', privateKey)
|
|
||||||
|
|
||||||
// Create an identity
|
|
||||||
const keychainInit = {
|
|
||||||
selfKey: 'myKey',
|
|
||||||
pass: await this.getSeed()
|
|
||||||
}
|
|
||||||
const privateKey = await loadOrCreateSelfKey(datastore, keychainInit)
|
|
||||||
|
|
||||||
// Configure services
|
|
||||||
const services = {
|
|
||||||
identify: identify(),
|
|
||||||
identifyPush: identifyPush(),
|
|
||||||
pubsub: gossipsub({ allowPublishToZeroTopicPeers: true }),
|
|
||||||
ping: ping(),
|
|
||||||
keychain: keychain(keychainInit)
|
|
||||||
}
|
|
||||||
if (this.config.isCircuitRelay) {
|
|
||||||
console.log('Helia (IPFS) node IS configured as Circuit Relay')
|
|
||||||
services.relay = circuitRelayServer({ // makes the node function as a relay server
|
|
||||||
hopTimeout: 30 * 1000, // incoming relay requests must be resolved within this time limit
|
|
||||||
reservations: {
|
|
||||||
maxReservations: 15, // how many peers are allowed to reserve relay slots on this server
|
|
||||||
reservationClearInterval: 300 * 1000, // how often to reclaim stale reservations
|
|
||||||
applyDefaultLimit: true, // whether to apply default data/duration limits to each relayed connection
|
|
||||||
defaultDurationLimit: 2 * 60 * 1000, // the default maximum amount of time a relayed connection can be open for
|
|
||||||
defaultDataLimit: BigInt(2 << 7) // the default maximum number of bytes that can be transferred over a relayed connection
|
|
||||||
},
|
|
||||||
maxInboundHopStreams: 32, // how many inbound HOP streams are allow simultaneously
|
|
||||||
maxOutboundHopStreams: 64 // how many outbound HOP streams are allow simultaneously
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
console.log('Helia (IPFS) node IS NOT configured as Circuit Relay')
|
|
||||||
}
|
|
||||||
|
|
||||||
const transports = [
|
|
||||||
tcp(),
|
|
||||||
webSockets(),
|
|
||||||
circuitRelayTransport({
|
|
||||||
discoverRelays: 3,
|
|
||||||
reservationConcurrency: 3
|
|
||||||
}),
|
|
||||||
webRTC(),
|
|
||||||
webRTCDirect()
|
|
||||||
]
|
|
||||||
|
|
||||||
// libp2p is the networking layer that underpins Helia
|
|
||||||
const libp2p = await this.createLibp2p({
|
|
||||||
// peerId,
|
|
||||||
privateKey,
|
|
||||||
datastore,
|
|
||||||
addresses: {
|
|
||||||
listen: [
|
|
||||||
'/ip4/127.0.0.1/tcp/0',
|
|
||||||
`/ip4/0.0.0.0/tcp/${this.config.ipfsTcpPort}`,
|
|
||||||
`/ip4/0.0.0.0/tcp/${this.config.ipfsWsPort}/ws`,
|
|
||||||
'/webrtc',
|
|
||||||
'/p2p-circuit'
|
|
||||||
]
|
|
||||||
},
|
|
||||||
transports,
|
|
||||||
connectionEncrypters: [
|
|
||||||
noise()
|
|
||||||
],
|
|
||||||
streamMuxers: [
|
|
||||||
yamux()
|
|
||||||
],
|
|
||||||
services
|
|
||||||
})
|
|
||||||
|
|
||||||
// create a Helia node
|
|
||||||
const helia = await this.createHelia({
|
|
||||||
blockstore,
|
|
||||||
datastore,
|
|
||||||
libp2p
|
|
||||||
})
|
|
||||||
|
|
||||||
// Attach IPFS file system.
|
|
||||||
const fs = unixfs(helia)
|
|
||||||
helia.fs = fs
|
|
||||||
|
|
||||||
return helia
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error creating Helia node: ', err)
|
|
||||||
|
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,29 +75,6 @@ class IpfsAdapter {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the directories exist to store blocks from the IPFS network.
|
|
||||||
// This function is called at startup, before the IPFS node is started.
|
|
||||||
ensureBlocksDir () {
|
|
||||||
try {
|
|
||||||
!this.fs.existsSync(`${ROOT_DIR}.ipfsdata`) && this.fs.mkdirSync(`${ROOT_DIR}.ipfsdata`)
|
|
||||||
|
|
||||||
!this.fs.existsSync(`${IPFS_DIR}`) && this.fs.mkdirSync(`${IPFS_DIR}`)
|
|
||||||
|
|
||||||
!this.fs.existsSync(`${IPFS_DIR}/blockstore`) && this.fs.mkdirSync(`${IPFS_DIR}/blockstore`)
|
|
||||||
|
|
||||||
!this.fs.existsSync(`${IPFS_DIR}/datastore`) && this.fs.mkdirSync(`${IPFS_DIR}/datastore`)
|
|
||||||
|
|
||||||
!this.fs.existsSync(`${IPFS_DIR}/datastore/pkcs8`) && this.fs.mkdirSync(`${IPFS_DIR}/datastore/pkcs8`)
|
|
||||||
|
|
||||||
// !fs.existsSync(`${IPFS_DIR}/datastore/peers`) && fs.mkdirSync(`${IPFS_DIR}/datastore/peers`)
|
|
||||||
|
|
||||||
return true
|
|
||||||
} catch (err) {
|
|
||||||
console.error('Error in adapters/ipfs.js/ensureBlocksDir(): ', err)
|
|
||||||
throw err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function opens the seed used to generate the key for this IPFS peer.
|
// This function opens the seed used to generate the key for this IPFS peer.
|
||||||
// The seed is stored in a JSON file. If it doesn't exist, a new one is created.
|
// The seed is stored in a JSON file. If it doesn't exist, a new one is created.
|
||||||
async getSeed () {
|
async getSeed () {
|
||||||
@@ -261,56 +94,12 @@ class IpfsAdapter {
|
|||||||
await this.jsonFiles.writeJSON(seed, filename)
|
await this.jsonFiles.writeJSON(seed, filename)
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('getSeed() seed: ', seed)
|
|
||||||
|
|
||||||
return seed
|
return seed
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error in adapters/ipfs/ipfs.js/getSeed()')
|
console.error('Error in adapters/ipfs/ipfs.js/getSeed()')
|
||||||
throw err
|
throw err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the private key from disk, or generate a new one and save it,
|
|
||||||
// if it doesn't exist.
|
|
||||||
// async getPrivateKey () {
|
|
||||||
// try {
|
|
||||||
// const filename = `${IPFS_DIR}/privkey.json`
|
|
||||||
|
|
||||||
// let privKeyHex
|
|
||||||
// try {
|
|
||||||
// // Try to read the JSON file containing the seed.
|
|
||||||
// privKeyHex = await this.jsonFiles.readJSON(filename)
|
|
||||||
// // console.log('saved privKeyHex: ', privKeyHex)
|
|
||||||
// } catch (err) {
|
|
||||||
// // Generate a new private key and save it to disk.
|
|
||||||
|
|
||||||
// // Generate a new private key and save it to disk.
|
|
||||||
// const randomBuffer = crypto.randomBytes(32)
|
|
||||||
// // console.log('randomBuffer: ', randomBuffer)
|
|
||||||
|
|
||||||
// privKeyHex = randomBuffer.toString('hex')
|
|
||||||
// // console.log('new privKeyHex: ', privKeyHex)
|
|
||||||
|
|
||||||
// // Save the newly generated seed
|
|
||||||
// await this.jsonFiles.writeJSON(privKeyHex, filename)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Convert the saved hex string to a buffer.
|
|
||||||
// const privKeyBuf = Buffer.from(privKeyHex, 'hex')
|
|
||||||
|
|
||||||
// // Convert the buffer to a Uint8Array 'seed'
|
|
||||||
// const seed = new Uint8Array(privKeyBuf.buffer, privKeyBuf.byteOffset, privKeyBuf.byteLength)
|
|
||||||
// // console.log('seed: ', seed)
|
|
||||||
|
|
||||||
// // Generate a ED25519 key pair.
|
|
||||||
// const privKey = await generateKeyPairFromSeed('Ed25519', seed)
|
|
||||||
|
|
||||||
// return privKey
|
|
||||||
// } catch (err) {
|
|
||||||
// console.error('Error in adapters/ipfs/ipfs.js/getPrivateKey(): ', err)
|
|
||||||
// throw err
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default IpfsAdapter
|
export default IpfsAdapter
|
||||||
|
|||||||
@@ -66,7 +66,26 @@ class IpfsRESTControllerLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return information on IPFS peers this node is connected to.
|
/**
|
||||||
|
* @api {post} /ipfs/peers Get information on IPFS peers this node is connected to
|
||||||
|
* @apiPermission public
|
||||||
|
* @apiName GetIpfsPeers
|
||||||
|
* @apiGroup REST IPFS
|
||||||
|
*
|
||||||
|
* @apiParam {Boolean} [showAll=false] Whether to include detailed peer data
|
||||||
|
*
|
||||||
|
* @apiExample Example usage:
|
||||||
|
* curl -H "Content-Type: application/json" -X POST localhost:5001/ipfs/peers \
|
||||||
|
* -d '{"showAll": false}'
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object[]} peers Array of peer objects
|
||||||
|
* @apiSuccess {String} peers[].peer Peer ID
|
||||||
|
* @apiSuccess {String} peers[].name Peer name
|
||||||
|
* @apiSuccess {String} peers[].protocol Protocol used by the peer
|
||||||
|
* @apiSuccess {String} peers[].version Peer version
|
||||||
|
* @apiSuccess {String} peers[].connectionAddr Connection address
|
||||||
|
* @apiSuccess {Object} [peers[].peerData] Detailed peer data (when showAll=true)
|
||||||
|
*/
|
||||||
async getPeers (ctx) {
|
async getPeers (ctx) {
|
||||||
try {
|
try {
|
||||||
const showAll = ctx.request.body.showAll
|
const showAll = ctx.request.body.showAll
|
||||||
@@ -81,6 +100,24 @@ class IpfsRESTControllerLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /ipfs/relays Get data about the known Circuit Relays
|
||||||
|
* @apiPermission public
|
||||||
|
* @apiName GetIpfsRelays
|
||||||
|
* @apiGroup REST IPFS
|
||||||
|
*
|
||||||
|
* @apiDescription Returns information about Circuit Relays, both v1 and v2, that this node knows about. V2 relays are hydrated with peer data from the connected peers list.
|
||||||
|
*
|
||||||
|
* @apiExample Example usage:
|
||||||
|
* curl -H "Content-Type: application/json" -X POST localhost:5001/ipfs/relays
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object} relays Object containing relay information
|
||||||
|
* @apiSuccess {Object[]} relays.v2Relays Array of v2 Circuit Relay objects
|
||||||
|
* @apiSuccess {String} relays.v2Relays[].ipfsId IPFS ID of the relay
|
||||||
|
* @apiSuccess {String} relays.v2Relays[].name Name of the relay (hydrated from peer data)
|
||||||
|
* @apiSuccess {String} relays.v2Relays[].description Description of the relay (hydrated from peer data)
|
||||||
|
* @apiSuccess {Object[]} relays.v1Relays Array of v1 Circuit Relay configurations
|
||||||
|
*/
|
||||||
// Get data about the known Circuit Relays. Hydrate with data from peers list.
|
// Get data about the known Circuit Relays. Hydrate with data from peers list.
|
||||||
async getRelays (ctx) {
|
async getRelays (ctx) {
|
||||||
try {
|
try {
|
||||||
@@ -94,6 +131,24 @@ class IpfsRESTControllerLib {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /ipfs/connect Connect to a specific IPFS peer
|
||||||
|
* @apiPermission public
|
||||||
|
* @apiName ConnectToIpfsPeer
|
||||||
|
* @apiGroup REST IPFS
|
||||||
|
*
|
||||||
|
* @apiDescription Attempts to establish a connection to a specific IPFS peer using the provided multiaddr. Optionally returns detailed information about the connection.
|
||||||
|
*
|
||||||
|
* @apiParam {String} multiaddr Multiaddress of the peer to connect to (required)
|
||||||
|
* @apiParam {Boolean} [getDetails=false] Whether to return detailed connection information
|
||||||
|
*
|
||||||
|
* @apiExample Example usage:
|
||||||
|
* curl -H "Content-Type: application/json" -X POST localhost:5001/ipfs/connect \
|
||||||
|
* -d '{"multiaddr": "/ip4/161.35.99.207/tcp/4001/p2p/12D3KooWDtj9cfj1SKuLbDNKvKRKSsGN8qivq9M8CYpLPDpcD5pu", "getDetails": false}'
|
||||||
|
*
|
||||||
|
* @apiSuccess {Boolean} success Indicates whether the connection attempt was successful
|
||||||
|
* @apiSuccess {Object} [details] Additional connection details (when getDetails=true)
|
||||||
|
*/
|
||||||
async connect (ctx) {
|
async connect (ctx) {
|
||||||
try {
|
try {
|
||||||
const multiaddr = ctx.request.body.multiaddr
|
const multiaddr = ctx.request.body.multiaddr
|
||||||
|
|||||||
@@ -14,13 +14,14 @@ describe('#adapters', () => {
|
|||||||
let uut, sandbox
|
let uut, sandbox
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
uut = new Adapters()
|
|
||||||
|
|
||||||
sandbox = sinon.createSandbox()
|
sandbox = sinon.createSandbox()
|
||||||
|
uut = new Adapters()
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
sandbox.restore()
|
if (sandbox) {
|
||||||
|
sandbox.restore()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#start', () => {
|
describe('#start', () => {
|
||||||
|
|||||||
@@ -5,26 +5,17 @@
|
|||||||
// Global npm libraries
|
// Global npm libraries
|
||||||
import { assert } from 'chai'
|
import { assert } from 'chai'
|
||||||
import sinon from 'sinon'
|
import sinon from 'sinon'
|
||||||
import cloneDeep from 'lodash.clonedeep'
|
|
||||||
// import { peerIdFromString } from '@libp2p/peer-id'
|
|
||||||
|
|
||||||
// Local libraries
|
// Local libraries
|
||||||
import IPFSLib from '../../../src/adapters/ipfs/ipfs.js'
|
import IPFSLib from '../../../src/adapters/ipfs/ipfs.js'
|
||||||
// import create from '../mocks/ipfs-mock.js'
|
|
||||||
import config from '../../../config/index.js'
|
|
||||||
import createHeliaLib from '../mocks/helia-mock.js'
|
|
||||||
|
|
||||||
// config.isProduction = true;
|
|
||||||
describe('#IPFS-adapter', () => {
|
describe('#IPFS-adapter', () => {
|
||||||
let uut
|
let uut
|
||||||
let sandbox
|
let sandbox
|
||||||
let ipfs
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
uut = new IPFSLib()
|
uut = new IPFSLib()
|
||||||
|
|
||||||
ipfs = cloneDeep(createHeliaLib)
|
|
||||||
|
|
||||||
sandbox = sinon.createSandbox()
|
sandbox = sinon.createSandbox()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -39,26 +30,37 @@ describe('#IPFS-adapter', () => {
|
|||||||
assert.isFunction(_uut.start)
|
assert.isFunction(_uut.start)
|
||||||
assert.isFunction(_uut.stop)
|
assert.isFunction(_uut.stop)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should instantiate dev IPFS Lib in production mode.', async () => {
|
|
||||||
config.isProduction = true
|
|
||||||
const _uut = new IPFSLib()
|
|
||||||
assert.exists(_uut)
|
|
||||||
assert.isFunction(_uut.start)
|
|
||||||
assert.isFunction(_uut.stop)
|
|
||||||
config.isProduction = false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#start', () => {
|
describe('#start', () => {
|
||||||
it('should return a promise that resolves into an instance of IPFS.', async () => {
|
it('should return a promise that resolves into an instance of IPFS.', async () => {
|
||||||
// Mock dependencies.
|
// Mock the heliaNode that gets created inside start()
|
||||||
sandbox.stub(uut, 'createNode').resolves(ipfs)
|
const mockIpfs = {
|
||||||
sandbox.stub(uut, 'publicIp').resolves('192.168.2.4')
|
libp2p: {
|
||||||
sandbox.stub(uut, 'multiaddr').returns('/ip4/fake-multiaddr')
|
getMultiaddrs: () => [],
|
||||||
|
peerId: 'fake-id'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override the start method to mock the heliaNode creation
|
||||||
|
uut.start = async function () {
|
||||||
|
this.heliaNode = {
|
||||||
|
start: async () => mockIpfs,
|
||||||
|
id: 'fake-id',
|
||||||
|
multiaddrs: ['/ip4/fake-multiaddr']
|
||||||
|
}
|
||||||
|
|
||||||
|
const ipfs = await this.heliaNode.start()
|
||||||
|
|
||||||
|
this.id = this.heliaNode.id
|
||||||
|
this.multiaddrs = this.heliaNode.multiaddrs
|
||||||
|
this.isReady = true
|
||||||
|
this.ipfs = ipfs
|
||||||
|
|
||||||
|
return this.ipfs
|
||||||
|
}
|
||||||
|
|
||||||
const result = await uut.start()
|
const result = await uut.start()
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
// Assert properties of the instance are set.
|
// Assert properties of the instance are set.
|
||||||
assert.equal(uut.isReady, true)
|
assert.equal(uut.isReady, true)
|
||||||
@@ -71,8 +73,9 @@ describe('#IPFS-adapter', () => {
|
|||||||
|
|
||||||
it('should catch and throw an error', async () => {
|
it('should catch and throw an error', async () => {
|
||||||
try {
|
try {
|
||||||
// Force an error
|
// Force an error by making getSeed throw, which will cause
|
||||||
sandbox.stub(uut, 'createNode').rejects(new Error('test error'))
|
// CreateHeliaNode to fail during start.
|
||||||
|
sandbox.stub(uut, 'getSeed').rejects(new Error('test error'))
|
||||||
|
|
||||||
await uut.start()
|
await uut.start()
|
||||||
assert.fail('Unexpected code path.')
|
assert.fail('Unexpected code path.')
|
||||||
@@ -97,119 +100,12 @@ describe('#IPFS-adapter', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('#ensureBlocksDir', () => {
|
|
||||||
it('should create directory if it does not exist', () => {
|
|
||||||
// Force desired code path
|
|
||||||
sandbox.stub(uut.fs, 'existsSync').returns(false)
|
|
||||||
sandbox.stub(uut.fs, 'mkdirSync').returns(true)
|
|
||||||
|
|
||||||
const result = uut.ensureBlocksDir()
|
|
||||||
|
|
||||||
assert.equal(result, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should report and throw errors', () => {
|
|
||||||
// Force an error
|
|
||||||
sandbox.stub(uut.fs, 'existsSync').throws(new Error('test error'))
|
|
||||||
|
|
||||||
try {
|
|
||||||
uut.ensureBlocksDir()
|
|
||||||
|
|
||||||
assert.fail('Unexpected code path')
|
|
||||||
} catch (err) {
|
|
||||||
assert.include(err.message, 'test error')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#createNode', () => {
|
|
||||||
it('should report and throw errors', async () => {
|
|
||||||
// Force an error
|
|
||||||
sandbox.stub(uut, 'createLibp2p').rejects(new Error('test error'))
|
|
||||||
|
|
||||||
try {
|
|
||||||
await uut.createNode()
|
|
||||||
|
|
||||||
assert.fail('Unexpected code path')
|
|
||||||
} catch (err) {
|
|
||||||
assert.include(err.message, 'test error')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should create an IPFS node from Helia', async () => {
|
|
||||||
uut.config.isCircuitRelay = false
|
|
||||||
const result = await uut.createNode()
|
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
// Assert the returned IPFS node has expected properties
|
|
||||||
assert.property(result, 'libp2p')
|
|
||||||
assert.property(result, 'blockstore')
|
|
||||||
|
|
||||||
// Stop the IPFS node
|
|
||||||
await result.stop()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should create a Circuit Relay if configured', async () => {
|
|
||||||
uut.config.isCircuitRelay = true
|
|
||||||
const result = await uut.createNode()
|
|
||||||
|
|
||||||
// Assert the returned IPFS node has expected properties
|
|
||||||
assert.property(result, 'libp2p')
|
|
||||||
assert.property(result, 'blockstore')
|
|
||||||
|
|
||||||
// Stop the IPFS node
|
|
||||||
await result.stop()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should create a new private key on first run', async () => {
|
|
||||||
uut.config.isCircuitRelay = false
|
|
||||||
|
|
||||||
// Mock dependencies and force desired code path.
|
|
||||||
// const beenCalled = false
|
|
||||||
// sandbox.stub(uut, 'getKeychain').resolves({
|
|
||||||
// exportPeerId: async () => {
|
|
||||||
// if (!beenCalled) {
|
|
||||||
// beenCalled = true
|
|
||||||
// throw new Error('test error')
|
|
||||||
// }
|
|
||||||
// return peerIdFromString('12D3KooWSXF1PnEfiA8bCG8SJduCvzdwHtvhVPK4WC6zzDoto2XP')
|
|
||||||
// },
|
|
||||||
// createKey: async () => {}
|
|
||||||
// })
|
|
||||||
sandbox.stub(uut, 'createLibp2p').resolves()
|
|
||||||
sandbox.stub(uut, 'createHelia').resolves({})
|
|
||||||
|
|
||||||
const result = await uut.createNode()
|
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
assert.property(result, 'fs')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not use circuit relay when CONNECT_PREF is set to direct', async () => {
|
|
||||||
process.env.CONNECT_PREF = 'direct'
|
|
||||||
|
|
||||||
uut.config.isCircuitRelay = false
|
|
||||||
const result = await uut.createNode()
|
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
delete process.env.CONNECT_PREF
|
|
||||||
|
|
||||||
// Assert the returned IPFS node has expected properties
|
|
||||||
assert.property(result, 'libp2p')
|
|
||||||
assert.property(result, 'blockstore')
|
|
||||||
|
|
||||||
// Stop the IPFS node
|
|
||||||
await result.stop()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('#getSeed', () => {
|
describe('#getSeed', () => {
|
||||||
it('should read the seed from the JSON file', async () => {
|
it('should read the seed from the JSON file', async () => {
|
||||||
// Mock dependencies and force desired code path
|
// Mock dependencies and force desired code path
|
||||||
sandbox.stub(uut.jsonFiles, 'readJSON').resolves('12345678')
|
sandbox.stub(uut.jsonFiles, 'readJSON').resolves('12345678')
|
||||||
|
|
||||||
const result = await uut.getSeed()
|
const result = await uut.getSeed()
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
assert.isString(result)
|
assert.isString(result)
|
||||||
})
|
})
|
||||||
@@ -220,7 +116,6 @@ describe('#IPFS-adapter', () => {
|
|||||||
sandbox.stub(uut.jsonFiles, 'writeJSON').resolves()
|
sandbox.stub(uut.jsonFiles, 'writeJSON').resolves()
|
||||||
|
|
||||||
const result = await uut.getSeed()
|
const result = await uut.getSeed()
|
||||||
// console.log('result: ', result)
|
|
||||||
|
|
||||||
assert.isString(result)
|
assert.isString(result)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -10,15 +10,24 @@ describe('#config', () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
// Backup the current environment setting.
|
// Backup the current environment setting.
|
||||||
currentEnv = process.env.CONSUMER_ENV
|
currentEnv = process.env.CONSUMER_ENV
|
||||||
|
|
||||||
|
// Clear CONSUMER_ENV for the first test to ensure default behavior
|
||||||
|
delete process.env.CONSUMER_ENV
|
||||||
})
|
})
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
// Restore the environment setting before starting these tests.
|
// Restore the environment setting before starting these tests.
|
||||||
process.env.CONSUMER_ENV = currentEnv
|
if (currentEnv) {
|
||||||
|
process.env.CONSUMER_ENV = currentEnv
|
||||||
|
} else {
|
||||||
|
delete process.env.CONSUMER_ENV
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
it('Should return development environment config by default', async () => {
|
it('Should return development environment config by default', async () => {
|
||||||
const importedConfig = await import('../../../config/index.js')
|
// Ensure CONSUMER_ENV is not set for this test
|
||||||
|
delete process.env.CONSUMER_ENV
|
||||||
|
const importedConfig = await import('../../../config/index.js?foo=bar0')
|
||||||
const config = importedConfig.default
|
const config = importedConfig.default
|
||||||
// console.log('config: ', config)
|
// console.log('config: ', config)
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class MockBchWallet {
|
|||||||
this.walletInfoPromise = true;
|
this.walletInfoPromise = true;
|
||||||
this.walletInfo = mockWallet;
|
this.walletInfo = mockWallet;
|
||||||
this.initialize = async () => {}
|
this.initialize = async () => {}
|
||||||
this.bchjs = new BCHJS();
|
this.bchjs = new BCHJS({ restURL: 'https://free-bch.fullstack.cash/' });
|
||||||
this.burnTokens = async () => {
|
this.burnTokens = async () => {
|
||||||
return { success: true, txid: 'txid' };
|
return { success: true, txid: 'txid' };
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import mongoose from 'mongoose'
|
import mongoose from 'mongoose'
|
||||||
import config from '../../config/index.js'
|
import config from '../../config/index.js'
|
||||||
import User from '../../src/models/users.js'
|
import User from '../../src/adapters/localdb/models/users.js'
|
||||||
|
|
||||||
async function getUsers () {
|
async function getUsers () {
|
||||||
// Connect to the Mongo Database.
|
// Connect to the Mongo Database.
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
import mongoose from 'mongoose'
|
||||||
|
import config from '../../config/index.js'
|
||||||
|
import User from '../../src/adapters/localdb/models/users.js'
|
||||||
|
|
||||||
|
async function getUsers () {
|
||||||
|
// Connect to the Mongo Database.
|
||||||
|
mongoose.Promise = global.Promise
|
||||||
|
mongoose.set('useCreateIndex', true) // Stop deprecation warning.
|
||||||
|
await mongoose.connect(
|
||||||
|
config.database,
|
||||||
|
{ useNewUrlParser: true, useUnifiedTopology: true }
|
||||||
|
)
|
||||||
|
|
||||||
|
// Find the user by email.
|
||||||
|
const user = await User.findOne({
|
||||||
|
email: 'test@test.com'
|
||||||
|
}, '-password')
|
||||||
|
|
||||||
|
// Update the users password
|
||||||
|
// user.password = 'newpassword'
|
||||||
|
|
||||||
|
// Change the user to an admin
|
||||||
|
// user.type = 'admin'
|
||||||
|
|
||||||
|
// Save the changes to the database.
|
||||||
|
await user.save()
|
||||||
|
|
||||||
|
mongoose.connection.close()
|
||||||
|
}
|
||||||
|
getUsers()
|
||||||
Reference in New Issue
Block a user