Compare commits

...
67 Commits
Author SHA1 Message Date
Chris Troutner f022951680 Merge pull request #83 from Permissionless-Software-Foundation/ct-unstable
fix(deps): Updating dependencies
2022-11-02 04:56:51 -07:00
Chris Troutner 942a8f20ec fix(deps): Updating dependencies 2022-11-02 04:54:46 -07:00
Chris Troutner 683c1e4b2b Merge pull request #82 from Permissionless-Software-Foundation/ct-unstable
fix(getTokenData2): Adding token icon lookup
2022-10-06 21:10:50 -07:00
Chris Troutner 953690baa5 fix(getTokenData2): Adding token icon lookup 2022-10-06 21:07:12 -07:00
Chris Troutner 80a65c4e03 Merge pull request #81 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs): Swapping out IPFS docker container with bandwidth limited …
2022-08-22 16:56:28 -07:00
Chris Troutner 63ecd21734 fix(ipfs): Swapping out IPFS docker container with bandwidth limited version 2022-08-22 16:52:11 -07:00
Chris Troutner ae957a835a Merge pull request #80 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-08-03 18:34:50 -07:00
Chris Troutner c61feba1e6 Fixing merge conflicts with upstream 2022-08-03 17:47:00 -07:00
Chris Troutner 8a05f1f063 fix(deps): Updating dependencies 2022-08-03 17:43:28 -07:00
Chris Troutner b23acd3cdc Merge pull request #97 from Permissionless-Software-Foundation/ct-unstable
fix(production): Switching to Docker Image
2022-07-25 19:17:27 -07:00
Chris Troutner c71fda38ff fix(production): Switching to Docker Image 2022-07-25 19:14:44 -07:00
Chris Troutner f99f49d840 Merge pull request #96 from Permissionless-Software-Foundation/ct-unstable
Configuring ports with env vars
2022-07-25 17:58:40 -07:00
Chris Troutner 2edd924c57 fix(production): Adding 4003 websocket port 2022-07-25 17:56:02 -07:00
Chris Troutner 689c8fd8d9 fix(ipfs): Using config to set ports 2022-07-25 17:40:05 -07:00
Chris Troutner ffd6c452c9 Merge pull request #95 from Permissionless-Software-Foundation/ct-unstable
fix(mocks): Another update to IPFS test mocks
2022-07-24 08:15:55 -07:00
Chris Troutner fc8e160874 fix(mocks): Another update to IPFS test mocks 2022-07-24 08:14:27 -07:00
Chris Troutner d2f83307e6 Merge pull request #94 from Permissionless-Software-Foundation/ct-unstable
fix(mocks): Improvement to adapter mocks used in tests
2022-07-24 08:08:13 -07:00
Chris Troutner 1a09fcd26f fix(mocks): Improvement to adapter mocks used in tests 2022-07-24 08:06:32 -07:00
Chris Troutner d095d40b3f Merge pull request #79 from Permissionless-Software-Foundation/ct-unstable
fix(getTokenData): JSON controller accepts flag for showing tx history
2022-07-12 15:04:56 -07:00
Chris Troutner fac9f12072 fix(getTokenData): JSON controller accepts flag for showing tx history 2022-07-12 15:02:40 -07:00
Chris Troutner 6b00513db7 Merge pull request #78 from Permissionless-Software-Foundation/ct-unstable
Syncing with upstream ipfs-service-provider
2022-07-08 09:03:54 -07:00
Chris Troutner 4387c9a758 fix(production): Updating docker file 2022-07-08 09:01:04 -07:00
Chris Troutner 469f1e05e8 fix(startup): Fixing bug from merge with upstream 2022-07-08 08:51:16 -07:00
Chris Troutner 3b836a7a35 Fixing merge conflicts with upstream 2022-07-08 08:46:05 -07:00
Chris Troutner fd1b13a917 Minor edit to documentation 2022-07-08 08:35:26 -07:00
Chris Troutner e2c5821dbe Merge pull request #93 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating bootstrap nodes
2022-07-07 15:56:42 -07:00
Chris Troutner 9967d5145b fix(ipfs-coord): Updating bootstrap nodes 2022-07-07 15:55:33 -07:00
Chris Troutner 9d16291855 Merge pull request #92 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v8
2022-07-07 15:17:09 -07:00
Chris Troutner 1518d1a12b fix(ipfs-coord): Updating to v8 2022-07-07 15:16:03 -07:00
Chris Troutner b68a143071 Merge pull request #91 from Permissionless-Software-Foundation/ct-unstable
Added hooks for async startup
2022-06-27 11:33:50 -07:00
Chris Troutner 5c25ebeeca Renaming mock log 2022-06-27 11:32:25 -07:00
Chris Troutner 3b17ba8e8b fix(logapi): Fixing issues with unit tests 2022-06-27 11:29:27 -07:00
Chris Troutner 434a4d7bd6 Refactoring failing unit tests 2022-06-27 10:25:19 -07:00
Chris Troutner dd36ebc7a0 Got test coverage back to 100% 2022-06-27 10:15:35 -07:00
Chris Troutner f117fe15df fix(startup): Added hooks for async startup 2022-06-27 10:09:08 -07:00
Chris Troutner 0333f77f5a Fixing broken link in README 2022-06-20 07:30:10 -07:00
Chris Troutner 3c908d1a4d Merge pull request #90 from Permissionless-Software-Foundation/ct-unstable
Increasing test coverage to 100%
2022-06-20 07:22:10 -07:00
Chris Troutner eb46a4c130 fix(tests): Got to 100% test coverage for entire repo 2022-06-20 07:19:36 -07:00
Chris Troutner d0efdcfa07 fix(ipfs-coord): Increased unit test coverage to 100% 2022-06-20 07:01:43 -07:00
Chris Troutner 62a7fcb16d fix(tests): Got bin/server.js unit test coverage to 100% 2022-06-19 20:21:40 -07:00
Chris Troutner d8addd5b27 Trying to build unit tests for bin/server 2022-06-19 20:00:25 -07:00
Chris Troutner bf6f1cf62d Merge pull request #89 from Permissionless-Software-Foundation/ct-unstable
Updating dependencies
2022-06-19 13:25:07 -07:00
Chris Troutner b7df7c47a5 Updated ipfs 2022-06-19 13:23:52 -07:00
Chris Troutner ae260db4af Updated some dependencies 2022-06-19 13:19:31 -07:00
Chris Troutner 778098ca12 fix(ipfs-coord): Updating to v7.1.19 2022-05-28 09:29:31 -07:00
Chris Troutner 0c4bb9c4a1 fix(ipfs-coord): Updating to v7.1.18 2022-05-28 09:09:44 -07:00
Chris Troutner 9cb975656d Merge pull request #88 from Permissionless-Software-Foundation/ct-unstable
fix(ipfs-coord): Updating to v7.1.17
2022-05-28 08:00:57 -07:00
Chris Troutner 4f6564423e fix(ipfs-coord): Updating to v7.1.17 2022-05-28 07:59:47 -07:00
Chris Troutner 54e7e74ae5 Merge pull request #87 from Permissionless-Software-Foundation/ct-unstable
Subscribing to chat channel at startup
2022-05-26 09:14:50 -07:00
Chris Troutner 324c372119 fix(startup): Subscribing to chat pubsub channel at startup 2022-05-26 09:12:15 -07:00
Chris Troutner da62f1bbe3 linting 2022-05-26 08:24:45 -07:00
Chris Troutner 129047fe88 fix(startup): Announcing config settings at startup 2022-05-26 08:24:30 -07:00
Chris Troutner fb182ced58 Merge pull request #86 from Permissionless-Software-Foundation/ct-unstable
Updating docker-compose file
2022-05-16 12:33:03 -07:00
Chris Troutner bec7c11e46 Updating README 2022-05-16 12:31:53 -07:00
Chris Troutner fb10e10226 fix(production): Updating docker images 2022-05-16 12:30:58 -07:00
Chris Troutner 5b37e47747 Merge pull request #85 from Permissionless-Software-Foundation/ct-unstable
fix(bch-js): Updating to v6.4.1
2022-05-16 12:15:47 -07:00
Chris Troutner a3cea782ba fix(bch-js): Updating to v6.4.1 2022-05-16 12:14:20 -07:00
Chris Troutner 14ffdae194 Merge pull request #84 from Permissionless-Software-Foundation/dh-test-coverage
feat(coverage): Got ipfs-coord.js to 100% test coverage
2022-05-16 12:09:18 -07:00
Chris Troutner 79918f6376 Merge pull request #77 from Permissionless-Software-Foundation/ct-unstable
feat(getTokenData): Adding new endpoint for PS002 token data
2022-05-10 11:15:21 -07:00
Chris Troutner da5942b28f feat(getTokenData): Adding new endpoint for PS002 token data 2022-05-10 11:14:11 -07:00
Daniel Gonzalez 7e3ce1564d feat(coverage): Got ipfs-coord.js to 100% test coverage 2022-03-25 22:12:11 -04:00
Chris Troutner 8154dd96f9 Merge pull request #83 from Permissionless-Software-Foundation/ct-unstable
fix(deps): Updating bch-js
2022-03-20 07:48:42 -07:00
Chris Troutner e37223cc88 fix(deps): Updating bch-js 2022-03-20 07:46:08 -07:00
Chris Troutner 5002ef2b90 Merge pull request #82 from Permissionless-Software-Foundation/dh-test-coverage-ipfsjs
feat(test): Got ipfs.js to 100% test coverage
2022-03-18 11:27:32 -07:00
Chris Troutner 5d95109ad4 more linting 2022-03-18 11:24:15 -07:00
Chris Troutner 13b3150f62 minor linting 2022-03-18 11:24:04 -07:00
Daniel Gonzalez b3a4a7c1ab feat(test): Got ipfs.js to 100% test coverage 2022-03-15 18:58:55 -04:00
31 changed files with 8551 additions and 11197 deletions
+4 -4
View File
@@ -54,13 +54,11 @@ cd shell-scripts
The [docker](./production/docker) directory contains a Dockerfile for building a production deployment.
```
docker-compose build --no-cache
docker-compose pull
docker-compose up -d
```
- Bring the containers up once, then take them back down with `docker-compose down`.
- Copy the [swarm.key](./swarm.key) file to `ipfs-service-provider/production/data/go-ipfs/data/swarm.key`.
- Bring the containers back up with `docker-compose up -d`.
You can bring the containers back up with `docker-compose up -d`.
### Operation Notes
@@ -90,6 +88,8 @@ API documentation is written inline and generated by [apidoc](http://apidocjs.co
Visit `http://localhost:5000/docs/` to view docs
There is additional developer documentation in the [dev-docs directory](./dev-docs).
## Dependencies
- [koa2](https://github.com/koajs/koa/tree/v2.x)
+40 -24
View File
@@ -24,31 +24,37 @@ const config = require('../config') // this first.
const AdminLib = require('../src/adapters/admin')
const errorMiddleware = require('../src/controllers/rest-api/middleware/error')
const { wlogger } = require('../src/adapters/wlogger')
const Controllers = require('../src/controllers')
class Server {
constructor () {
// Encapsulate dependencies
this.adminLib = new AdminLib()
this.controllers = new Controllers()
this.mongoose = mongoose
this.config = config
this.process = process
}
async startServer () {
try {
// Create a Koa instance.
const app = new Koa()
app.keys = [config.session]
app.keys = [this.config.session]
// Connect to the Mongo Database.
mongoose.Promise = global.Promise
mongoose.set('useCreateIndex', true) // Stop deprecation warning.
this.mongoose.Promise = global.Promise
this.mongoose.set('useCreateIndex', true) // Stop deprecation warning.
console.log(
`Connecting to MongoDB with this connection string: ${config.database}`
`Connecting to MongoDB with this connection string: ${this.config.database}`
)
await mongoose.connect(config.database, {
await this.mongoose.connect(this.config.database, {
useUnifiedTopology: true,
useNewUrlParser: true
})
console.log(`Starting environment: ${config.env}`)
console.log(`Debug level: ${config.debugLevel}`)
console.log(`Starting environment: ${this.config.env}`)
console.log(`Debug level: ${this.config.debugLevel}`)
// MIDDLEWARE START
@@ -73,20 +79,24 @@ class Server {
// Dev Note: This line must come BEFORE controllers.attachRESTControllers()
app.use(cors({ origin: '*' }))
// Attach REST API and JSON RPC controllers to the app.
const Controllers = require('../src/controllers')
const controllers = new Controllers()
await controllers.attachRESTControllers(app)
// Wait for any adapters to initialize.
await this.controllers.initAdapters()
app.controllers = controllers
// Wait for any use-libraries to initialize.
await this.controllers.initUseCases()
// Attach REST API and JSON RPC controllers to the app.
await this.controllers.attachRESTControllers(app)
app.controllers = this.controllers
// MIDDLEWARE END
console.log(`Running server in environment: ${config.env}`)
wlogger.info(`Running server in environment: ${config.env}`)
console.log(`Running server in environment: ${this.config.env}`)
wlogger.info(`Running server in environment: ${this.config.env}`)
await app.listen(config.port)
console.log(`Server started on ${config.port}`)
this.server = await app.listen(this.config.port)
console.log(`Server started on ${this.config.port}`)
// Create the system admin user.
try {
@@ -100,10 +110,16 @@ class Server {
// Attach the other IPFS controllers.
// Skip if this is a test environment.
if (config.env !== 'test') {
await controllers.attachControllers(app)
if (this.config.env !== 'test') {
await this.controllers.attachControllers(app)
}
// Display configuration settings
console.log('\nConfiguration:')
console.log(`Circuit Relay: ${this.config.isCircuitRelay}`)
console.log(`IPFS TCP port: ${this.config.ipfsTcpPort}`)
console.log(`IPFS WS port: ${this.config.ipfsWsPort}\n`)
return app
} catch (err) {
console.error('Could not start server. Error: ', err)
@@ -111,14 +127,14 @@ class Server {
console.log(
'Exiting after 5 seconds. Depending on process manager to restart.'
)
await sleep(5000)
process.exit(1)
await this.sleep(5000)
this.process.exit(1)
}
}
sleep (ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
}
function sleep (ms) {
return new Promise((resolve) => setTimeout(resolve, ms))
}
module.exports = Server
+3 -1
View File
@@ -89,5 +89,7 @@ module.exports = {
ipfsHost: process.env.IPFS_HOST ? process.env.IPFS_HOST : 'localhost',
ipfsApiPort: process.env.IPFS_API_PORT
? parseInt(process.env.IPFS_API_PORT)
: 5001
: 5001,
chatPubSubChan: 'psf-ipfs-chat-001'
}
+10
View File
@@ -0,0 +1,10 @@
# Developer Documentation
This directory needs to be fleshed out with more information. The markdown files in this directory are intended to provide additional documentation for software developers that use this boilerplate to run their own forks.
## Startup
This software requires an IPFS node in order to operate the JSON RPC and ipfs-coord features. There are two ways to incorporate an IPFS node:
- js-ipfs is integrated into this repository. If you simply run `npm start`, then this app will default to the js-ipfs IPFS node. However, js-ipfs is not as full featured as go-ipfs. It has memory leaks and lags considerably behind go-ipfs in terms of features.
- go-ipfs is the preferred way to run a node. It can be run externally by following the guidence on the [IPFS homepage](https://ipfs.io). Once the IPFS node is running, this app can take control of it. Use the [local-external-ipfs-node.sh](../shell-scripts/local-external-ipfs-node.sh) shell script to start this app and attach it to the go-ipfs node.
+7772 -11066
View File
File diff suppressed because it is too large Load Diff
+10 -10
View File
@@ -24,12 +24,12 @@
},
"repository": "Permissionless-Software-Foundation/ipfs-bch-wallet-service",
"dependencies": {
"@psf/bch-js": "6.4.0",
"axios": "0.25.0",
"@psf/bch-js": "6.5.3",
"axios": "0.27.2",
"bcryptjs": "2.4.3",
"glob": "7.1.6",
"ipfs": "0.60.0",
"ipfs-coord": "7.1.6",
"ipfs": "0.62.3",
"ipfs-coord": "8.0.4",
"ipfs-http-client": "55.0.0",
"jsonrpc-lite": "2.2.0",
"jsonwebtoken": "8.5.1",
@@ -46,16 +46,16 @@
"koa-static": "5.0.0",
"koa2-ratelimit": "0.9.1",
"line-reader": "0.4.0",
"mongoose": "5.11.15",
"mongoose": "5.13.14",
"node-fetch": "npm:@achingbrain/node-fetch@2.6.7",
"nodemailer": "6.4.17",
"nodemailer": "6.7.5",
"passport-local": "1.0.0",
"public-ip": "4.0.4",
"winston": "3.3.3",
"winston-daily-rotate-file": "4.5.0"
},
"devDependencies": {
"apidoc": "0.26.0",
"apidoc": "0.51.1",
"chai": "4.3.0",
"coveralls": "3.1.0",
"eslint": "7.19.0",
@@ -65,10 +65,10 @@
"eslint-plugin-prettier": "3.3.1",
"eslint-plugin-standard": "4.0.0",
"husky": "4.3.8",
"lodash.clonedeep": "^4.5.0",
"mocha": "8.2.1",
"lodash.clonedeep": "4.5.0",
"mocha": "10.0.0",
"nyc": "15.1.0",
"semantic-release": "17.4.4",
"semantic-release": "19.0.3",
"sinon": "9.2.4",
"standard": "16.0.3",
"uuid": "8.3.2"
+1 -1
View File
@@ -73,7 +73,7 @@ RUN mkdir /home/safeuser/.ipfsdata
EXPOSE 5010
# Start the application.
COPY start-production.sh start-production.sh
#COPY start-production.sh start-production.sh
CMD ["./start-production.sh"]
#CMD ["npm", "start"]
+14 -14
View File
@@ -4,7 +4,7 @@ version: '3.9'
services:
mongo-bch-service:
image: mongo
image: mongo:4.2.0
container_name: mongo-bch-service
ports:
- '5555:27017' # <host port>:<container port>
@@ -14,10 +14,15 @@ services:
restart: always
ipfs-bch-wallet:
image: ipfs/go-ipfs:v0.12.0
image: christroutner/trickle-ipfs:v1.0.1
#build:
# context: ./
# dockerfile: Dockerfile
container_name: ipfs-bch-wallet
environment:
MY_ENV_VAR: 'placeholder'
IPFS_DAEMON_ARGUMENTS: '--enable-pubsub-experiment --migrate=true --agent-version-suffix=docker --routing=dhtclient'
UPLOAD_KBPS: '100'
DOWNLOAD_KBPS: '100'
logging:
driver: 'json-file'
options:
@@ -26,20 +31,14 @@ services:
mem_limit: 2000mb
ports:
- 4001:4001
- 4003:4003
- 172.17.0.1:5001:5001
- 172.17.0.1:8080:8080
command: [
'./start-ipfs.sh'
]
volumes:
- ../data/go-ipfs/data:/data/ipfs
- ../data/go-ipfs/export:/export
# https://docs.docker.com/compose/compose-file/compose-file-v3/#command
# https://github.com/ipfs/go-ipfs/blob/91c52657166bcf86f2476926e4fe56694dc26562/Dockerfile#L115
command:
[
'daemon',
'--migrate=true',
'--agent-version-suffix=docker',
'--enable-pubsub-experiment'
]
- ../data/go-ipfs/data:/root/.ipfs
restart: always
bch-wallet-service:
@@ -58,4 +57,5 @@ services:
- '5010:5010' # <host port>:<container port>
volumes:
- ../data/ipfsdata:/home/safeuser/ipfs-bch-wallet-service/.ipfsdata
- ./start-production.sh:/home/safeuser/ipfs-bch-wallet-service/start-production.sh
restart: always
+1 -1
View File
@@ -42,6 +42,6 @@ export SVC_ENV=production
export IPFS_HOST=172.17.0.1
export IPFS_API_PORT=5001
export IPFS_TCP_PORT=4001
#export IPFS_WS_PORT=4002
export IPFS_WS_PORT=4003
npm start
+1 -1
View File
@@ -29,6 +29,6 @@ export IPFS_TCP_PORT=4001
# MongoDB connection string.
export DBURL=mongodb://localhost:27017/ipfs-service-dev
export ENABLE_CIRCUIT_RELAY=true
#export ENABLE_CIRCUIT_RELAY=true
npm start
+6 -1
View File
@@ -50,10 +50,15 @@ class Adapters {
this.bchjs = new BCHJS({ restURL: this.config.apiServer })
}
// Start the IPFS node.
// Do not start these adapters if this is an e2e test.
if (this.config.env !== 'test') {
// Start the IPFS node.
await this.ipfs.start({ bchjs: this.bchjs })
}
console.log('Async Adapters have been started.')
return true
} catch (err) {
console.error('Error in adapters/index.js/start()')
throw err
+9 -1
View File
@@ -2,8 +2,10 @@
top-level IPFS library that combines the individual IPFS-based libraries.
*/
// Local libraries
const IpfsAdapter = require('./ipfs')
const IpfsCoordAdapter = require('./ipfs-coord')
const config = require('../../../config')
class IPFS {
constructor (localConfig = {}) {
@@ -11,6 +13,7 @@ class IPFS {
this.ipfsAdapter = new IpfsAdapter()
this.IpfsCoordAdapter = IpfsCoordAdapter
this.process = process
this.config = config
this.ipfsCoordAdapter = {} // placeholder
@@ -39,11 +42,16 @@ class IPFS {
// Start ipfs-coord
this.ipfsCoordAdapter = new this.IpfsCoordAdapter({
ipfs: this.ipfs,
bchjs
bchjs,
tcpPort: this.config.ipfsTcpPort,
wsPort: this.config.ipfsWsPort
})
await this.ipfsCoordAdapter.start()
console.log('ipfs-coord is ready.')
// Subscribe to the chat pubsub channel
await this.ipfsCoordAdapter.subscribeToChat()
return true
} catch (err) {
console.error('Error in adapters/ipfs/index.js/start()')
+9
View File
@@ -104,6 +104,15 @@ class IpfsCoordAdapter {
throw err
}
}
// Subscribe to the chat pubsub channel
async subscribeToChat () {
await this.ipfsCoord.adapters.pubsub.subscribeToPubsubChannel(
this.config.chatPubSubChan,
console.log,
this.ipfsCoord.thisNode
)
}
}
module.exports = IpfsCoordAdapter
+18 -19
View File
@@ -102,10 +102,9 @@ class IpfsAdapter {
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')) {
console.log('No space left in /blocks folder. Deleting blocks folder.')
this.rmBlocksDir()
}
// if (err.message.includes('No space left on device')) {
// this.rmBlocksDir()
// }
throw err
}
@@ -121,21 +120,21 @@ class IpfsAdapter {
// Dev Note: It's assumed this node is not pinning any data and that
// everything in this directory is transient. This folder will regularly
// fill up and prevent IPFS from starting.
rmBlocksDir () {
try {
const dir = `${IPFS_DIR}/blocks`
console.log(`Deleting ${dir} directory...`)
this.fs.rmdirSync(dir, { recursive: true })
console.log(`${dir} directory is deleted!`)
return true // Signal successful execution.
} catch (err) {
console.log('Error in rmBlocksDir()')
throw err
}
}
// rmBlocksDir () {
// try {
// const dir = `${IPFS_DIR}/blocks`
// console.log(`Deleting ${dir} directory...`)
//
// this.fs.rmdirSync(dir, { recursive: true })
//
// console.log(`${dir} directory is deleted!`)
//
// return true // Signal successful execution.
// } catch (err) {
// console.log('Error in rmBlocksDir()')
// throw err
// }
// }
}
module.exports = IpfsAdapter
+3 -1
View File
@@ -135,8 +135,10 @@ class LogsApi {
if (!filename || typeof filename !== 'string') {
throw new Error('filename must be a string')
}
// Throw an error if the file does not exist.
console.log('readLines() filename: ', filename)
// Throw an error if the file does not exist.
if (!_this.fs.existsSync(filename)) {
throw new Error('file does not exist')
}
+17 -3
View File
@@ -25,11 +25,14 @@ class Controllers {
this.useCases = new UseCases({ adapters: this.adapters })
}
async attachControllers (app) {
// Wait for any startup processes to complete for the Adapters libraries.
// Spin up any adapter libraries that have async startup needs.
async initAdapters () {
await this.adapters.start()
}
this.attachRPCControllers()
// Run any Use Cases to startup the app.
async initUseCases () {
await this.useCases.start()
}
// Top-level function for this library.
@@ -44,6 +47,17 @@ class Controllers {
restControllers.attachRESTControllers(app)
}
// Attach any other controllers other than REST API controllers.
async attachControllers (app) {
// Wait for any startup processes to complete for the Adapters libraries.
// await this.adapters.start()
// Attach the REST controllers to the Koa app.
// this.attachRESTControllers(app)
this.attachRPCControllers()
}
// Add the JSON RPC router to the ipfs-coord adapter.
attachRPCControllers () {
const jsonRpcController = new JSONRPC({
+172 -9
View File
@@ -75,6 +75,14 @@ class BCHRPC {
case 'utxoIsValid':
await this.rateLimit.limiter(rpcData.from)
return await this.utxoIsValid(rpcData)
case 'getTokenData':
await this.rateLimit.limiter(rpcData.from)
return await this.getTokenData(rpcData)
case 'getTokenData2':
await this.rateLimit.limiter(rpcData.from)
return await this.getTokenData2(rpcData)
}
} catch (err) {
console.error('Error in BCHRPC/rpcRouter()')
@@ -533,7 +541,6 @@ class BCHRPC {
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH txData()): ', err)
// throw err
// Return an error response
return {
@@ -581,7 +588,6 @@ class BCHRPC {
*
* }
*/
async pubKey (rpcData) {
try {
// console.log('createUser rpcData: ', rpcData)
@@ -602,11 +608,13 @@ class BCHRPC {
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH pubKey()')
// throw err
// Handle different error formats.
let error = err
if (err.error && typeof err.error === 'string') {
error = new Error(err.error)
}
// Return an error response
return {
success: false,
@@ -630,7 +638,7 @@ class BCHRPC {
* - id: "" - jsonrpc id
* - result: {} - Result of the petition with the RPC information
* - success: - Request status
* - publickey: - Address public key
* - isValid: - Boolean: true or false
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "utxoIsValid", "utxo": {"tx_hash": "17754221b29f189532d4fc2ae89fb467ad2dede30fdec4854eb2129b3ba90d7a", "tx_pos": 0}}}
@@ -645,10 +653,9 @@ class BCHRPC {
* "value":{
* "success": true,
* "status": 200,
* "endpoint": "pubkey",
* "pubkey": {
* "success": true,
* "publicKey": "033f267fec0f7eb2b27f8c2e3052b3d03b09d36b47de4082ffb638ffb334ef0eee"
* "endpoint": "utxoIsValid",
* "isValid": true
* }
* }
*
* }
@@ -674,7 +681,7 @@ class BCHRPC {
} catch (err) {
console.error('Error in JSON RPC BCH utxoIsValid()')
// throw err
// Handle different error formats.
let error = err
if (err.error && typeof err.error === 'string') {
error = new Error(err.error)
@@ -689,6 +696,162 @@ class BCHRPC {
}
}
}
/**
* @api {JSON} /bch getTokenData
* @apiPermission public
* @apiName getTokenData
* @apiGroup JSON BCH
* @apiDescription Get data associated with a token
* Given a token ID, this endpoint will retrieve the IPFS CIDs associated with
* the tokens mutable and immutable data. This is extension of the PS002
* specification for mutable data for tokens:
* https://github.com/Permissionless-Software-Foundation/specifications/blob/master/ps002-slp-mutable-data.md
*
* If optional parameter 'withTxHistory' is true, data will include the
* transaction history of the token.
*
* - jsonrpc: "" - jsonrpc version
* - id: "" - jsonrpc id
* - result: {} - Result of the petition with the RPC information
* - success: - Request status
* - tokenData: - Address public key
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "getTokenData", "tokenId": "c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d", "withTxHistory": true }}
*
* @apiSuccessExample {json} Success-Response:
* {
* "jsonrpc":"2.0",
* "id":"555",
* "result":{
* "method":"bch",
* "reciever":"QmU86vLVbUY1UhziKB6rak7GPKRA2QHWvzNm2AjEvXNsT6",
* "value":{
* "success": true,
* "status": 200,
* "endpoint": "getTokenData",
* "tokenData": {
* "genesisData": {
* "type": 1,
* "ticker": 'MT2',
* "name": 'Mutable Token',
* "tokenId": 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d',
* "documentUri": 'ipfs://bafybeie7oxpsr7evcnlptecxfdhaqlot4732phukd2ekgvuzoir2frost4',
* "documentHash": '56ed1a5768076a318d02b5db64e125544dca57ab6b2cc7ca61dfa4645d244463',
* "decimals": 0,
* "mintBatonIsActive": true,
* "tokensInCirculationBN": '1000',
* "tokensInCirculationStr": '1000',
* "blockCreated": 739412,
* "totalBurned": '0',
* "totalMinted": '1000'
* },
* "immutableData": 'ipfs://bafybeie7oxpsr7evcnlptecxfdhaqlot4732phukd2ekgvuzoir2frost4',
* "mutableData": 'ipfs://bafybeigotuony53ley3n63hqwyxiqruqn5uamskmci6f645putnc46jju4'
* }
* }
* }
* }
*/
async getTokenData (rpcData) {
try {
// console.log('createUser rpcData: ', rpcData)
const tokenId = rpcData.payload.params.tokenId
// console.log('tokenId: ', tokenId)
const withTxHistory = !!rpcData.payload.params.withTxHistory
const tokenData = await this.bchjs.PsfSlpIndexer.getTokenData(tokenId, withTxHistory)
const retObj = {
success: true,
status: 200,
endpoint: 'getTokenData',
tokenData
}
// retObj.status = 200
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH utxoIsValid()')
// Handle different error formats.
let error = err
if (err.error && typeof err.error === 'string') {
error = new Error(err.error)
}
// Return an error response
return {
success: false,
status: 422,
message: error.message,
endpoint: 'getTokenData'
}
}
}
/**
* @api {JSON} /bch getTokenData2
* @apiPermission public
* @apiName getTokenData2
* @apiGroup JSON BCH
* @apiDescription Get token icon and other media
*
* Get the icon for a token, given it's token ID.
* This function expects a string input of a token ID property.
* This function returns an object with a tokenIcon property that contains
* the URL to the icon.
*
* The output object always have these properties:
* - tokenIcon: A url to the token icon, if it exists.
* - tokenStats: Data about the token from psf-slp-indexer.
* - optimizedTokenIcon: An alternative, potentially more optimal, url to the token icon, if it exists.
* - iconRepoCompatible: true if the token icon is available via token.bch.sx
* - ps002Compatible: true if the token icon is compatible with PS007 specification.
*
* @apiExample Example usage:
* {"jsonrpc":"2.0","id":"555","method":"bch","params":{ "endpoint": "getTokenData2", "tokenId": "c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d", "withTxHistory": true }}
*
*/
async getTokenData2 (rpcData) {
try {
// console.log('createUser rpcData: ', rpcData)
const tokenId = rpcData.payload.params.tokenId
// console.log('tokenId: ', tokenId)
const tokenData = await this.bchjs.PsfSlpIndexer.getTokenData2(tokenId)
const retObj = {
success: true,
status: 200,
endpoint: 'getTokenData2',
tokenData
}
// retObj.status = 200
return retObj
} catch (err) {
console.error('Error in JSON RPC BCH utxoIsValid()')
// Handle different error formats.
let error = err
if (err.error && typeof err.error === 'string') {
error = new Error(err.error)
}
// Return an error response
return {
success: false,
status: 422,
message: error.message,
endpoint: 'getTokenData2'
}
}
}
}
module.exports = BCHRPC
+13
View File
@@ -21,6 +21,19 @@ class UseCases {
this.user = new UserUseCases(localConfig)
this.bch = new BCHUseCases(localConfig)
}
// Run any startup Use Cases at the start of the app.
async start () {
// try {
console.log('Async Use Cases have been started.')
return true
// } catch (err) {
// console.error('Error in use-cases/index.js/start()')
// // console.log(err)
// throw err
// }
}
}
module.exports = UseCases
+1
View File
@@ -7,6 +7,7 @@
// Public npm libraries
const assert = require('chai').assert
const axios = require('axios').default
// const sinon = require('sinon')
// Local support libraries
const config = require('../../../config')
@@ -94,4 +94,40 @@ describe('#BCH', () => {
assert.equal(result.isValid, false)
})
})
describe('#getTokenData', () => {
it('should return data for a token', async () => {
const rpcData = {
payload: {
params: {
tokenId: 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d'
}
}
}
const result = await uut.getTokenData(rpcData)
// console.log('result: ', result)
// assert.equal(result.isValid, true)
assert.property(result.tokenData, 'immutableData')
assert.property(result.tokenData, 'mutableData')
assert.equal(result.success, true)
})
it('should return data for a token with tx history', async () => {
const rpcData = {
payload: {
params: {
tokenId: '43eddfb11c9941edffb8c8815574bb0a43969a7b1de39ad14cd043eaa24fd38d',
withTxHistory: true
}
}
}
const result = await uut.getTokenData(rpcData)
// console.log('result: ', result)
assert.isArray(result.tokenData.genesisData.txs)
})
})
})
+54
View File
@@ -0,0 +1,54 @@
/*
Unit tests for the adapters index.js library
*/
// Global npm libraries
const assert = require('chai').assert
const sinon = require('sinon')
// Local libraries
const Adapters = require('../../../src/adapters')
describe('#adapters', () => {
let uut, sandbox
beforeEach(() => {
uut = new Adapters()
sandbox = sinon.createSandbox()
})
afterEach(() => {
sandbox.restore()
})
describe('#start', () => {
it('should start the async adapters', async () => {
// Mock dependencies
uut.config.getJwtAtStartup = true
sandbox.stub(uut.fullStackJwt, 'getJWT').resolves()
sandbox.stub(uut.fullStackJwt, 'instanceBchjs').resolves()
sandbox.stub(uut.ipfs, 'start').resolves()
const result = await uut.start()
assert.equal(result, true)
})
it('should catch and throw an error', async () => {
try {
// Force an error
uut.config.getJwtAtStartup = false
uut.config.env = 'dev'
sandbox.stub(uut.ipfs, 'start').rejects(new Error('test error'))
await uut.start()
assert.fail('Unexpected result')
} catch (err) {
// console.log('err: ', err)
assert.include(err.message, 'test error')
}
})
})
})
@@ -8,6 +8,7 @@ const sinon = require('sinon')
const IPFSCoordAdapter = require('../../../src/adapters/ipfs/ipfs-coord')
const IPFSMock = require('../mocks/ipfs-mock')
const IPFSCoordMock = require('../mocks/ipfs-coord-mock')
const config = require('../../../config')
describe('#IPFS', () => {
let uut
@@ -76,6 +77,16 @@ describe('#IPFS', () => {
assert.equal(result, true)
})
it('should return a promise that resolves into an instance of IPFS in production mode', async () => {
uut.config.isProduction = true
// Mock dependencies.
uut.IpfsCoord = IPFSCoordMock
const result = await uut.start()
// console.log('result: ', result)
assert.equal(result, true)
config.isProduction = false
})
})
describe('#attachRPCRouter', () => {
@@ -116,4 +127,20 @@ describe('#IPFS', () => {
}
})
})
describe('#subscribeToChat', () => {
it('should subscribe to the chat channel', async () => {
// Mock dependencies
uut.ipfsCoord = {
adapters: {
pubsub: {
subscribeToPubsubChannel: async () => {
}
}
}
}
await uut.subscribeToChat()
})
})
})
+35 -2
View File
@@ -4,10 +4,11 @@
const assert = require('chai').assert
const sinon = require('sinon')
const IPFSLib = require('../../../src/adapters/ipfs/ipfs')
const IPFSMock = require('../mocks/ipfs-mock')
const config = require('../../../config')
// config.isProduction = true;
describe('#IPFS-adapter', () => {
let uut
let sandbox
@@ -18,7 +19,27 @@ describe('#IPFS-adapter', () => {
sandbox = sinon.createSandbox()
})
afterEach(() => sandbox.restore())
afterEach(() => {
sandbox.restore()
})
describe('#constructor', () => {
it('should instantiate IPFS Lib in dev mode.', async () => {
const _uut = new IPFSLib()
assert.exists(_uut)
assert.isFunction(_uut.start)
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', () => {
it('should return a promise that resolves into an instance of IPFS.', async () => {
@@ -33,6 +54,18 @@ describe('#IPFS-adapter', () => {
assert.property(result, 'config')
})
it('should return a promise that resolves into an instance of IPFS in production mode.', async () => {
// Mock dependencies.
uut.IPFS = IPFSMock
uut.config.isProduction = true
const result = await uut.start()
// console.log('result: ', result)
assert.equal(uut.isReady, true)
assert.property(result, 'config')
})
it('should catch and throw an error', async () => {
try {
// Force an error
+25 -32
View File
@@ -32,19 +32,18 @@ describe('#LogsApiLib', () => {
})
it('should return log', async () => {
try {
const pass = 'test'
const result = await uut.getLogs(pass)
// console.log('result', result)
// Mock dependencies
sandbox.stub(uut, 'generateFileName').returns(`${__dirname.toString()}/../mocks/adapters/fake-log`)
assert.isTrue(result.success)
assert.isArray(result.data)
assert.property(result.data[0], 'message')
assert.property(result.data[0], 'level')
assert.property(result.data[0], 'timestamp')
} catch (err) {
assert(false, 'Unexpected result')
}
const pass = 'test'
const result = await uut.getLogs(pass)
// console.log('result', result)
assert.isTrue(result.success)
assert.isArray(result.data)
assert.property(result.data[0], 'message')
assert.property(result.data[0], 'level')
assert.property(result.data[0], 'timestamp')
})
it('should return false if files are not found!', async () => {
@@ -201,31 +200,25 @@ describe('#LogsApiLib', () => {
})
it('should ignore fileReader callback errors', async () => {
try {
// https://sinonjs.org/releases/latest/stubs/
// About yields
sandbox.stub(uut.lineReader, 'eachLine').yieldsRight({}, true)
// https://sinonjs.org/releases/latest/stubs/
// About yields
sandbox.stub(uut.lineReader, 'eachLine').yieldsRight({}, true)
const fileName = context.fileName
const result = await uut.readLines(fileName)
assert.isArray(result)
} catch (err) {
assert.fail('Unexpected result')
}
const fileName = `${__dirname.toString()}/../mocks/adapters/fake-log`
const result = await uut.readLines(fileName)
assert.isArray(result)
})
it('should return data', async () => {
try {
const fileName = context.fileName
const result = await uut.readLines(fileName)
const fileName = `${__dirname.toString()}/../mocks/adapters/fake-log`
assert.isArray(result)
assert.property(result[1], 'message')
assert.property(result[1], 'level')
assert.property(result[1], 'timestamp')
} catch (err) {
assert.fail('Unexpected result')
}
const result = await uut.readLines(fileName)
assert.isArray(result)
assert.property(result[1], 'message')
assert.property(result[1], 'level')
assert.property(result[1], 'timestamp')
})
})
})
+1 -1
View File
@@ -45,7 +45,7 @@ describe('#Controllers', () => {
it('should catch and throw errors', async () => {
try {
// Force an error
sandbox.stub(uut.adapters, 'start').rejects(new Error('test error'))
sandbox.stub(uut, 'attachRPCControllers').throws(new Error('test error'))
const app = {
use: () => {}
@@ -590,4 +590,100 @@ describe('#BCHRPC', () => {
assert.equal(result.endpoint, 'utxoIsValid')
})
})
describe('#getTokenData', () => {
it('should return data from PsfSlpIndexer.getTokenData()', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.PsfSlpIndexer, 'getTokenData')
.resolves({ a: 'b' })
const rpcData = {
payload: {
params: {
tokenId: 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d'
}
}
}
const result = await uut.getTokenData(rpcData)
// console.log('result: ', result)
assert.equal(result.success, true)
assert.equal(result.status, 200)
assert.equal(result.endpoint, 'getTokenData')
assert.property(result, 'tokenData')
})
it('should catch and return errors', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.PsfSlpIndexer, 'getTokenData')
.rejects(new Error('test error'))
const rpcData = {
payload: {
params: {
tokenId: 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d'
}
}
}
const result = await uut.getTokenData(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.message, 'test error')
assert.equal(result.endpoint, 'getTokenData')
})
})
describe('#getTokenData2', () => {
it('should return data from PsfSlpIndexer.getTokenData2()', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.PsfSlpIndexer, 'getTokenData2')
.resolves({ a: 'b' })
const rpcData = {
payload: {
params: {
tokenId: 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d'
}
}
}
const result = await uut.getTokenData2(rpcData)
// console.log('result: ', result)
assert.equal(result.success, true)
assert.equal(result.status, 200)
assert.equal(result.endpoint, 'getTokenData2')
assert.property(result, 'tokenData')
})
it('should catch and return errors', async () => {
// Mock dependencies
sandbox
.stub(uut.bchjs.PsfSlpIndexer, 'getTokenData2')
.rejects(new Error('test error'))
const rpcData = {
payload: {
params: {
tokenId: 'c85042ab08a2099f27de880a30f9a42874202751d834c42717a20801a00aab0d'
}
}
}
const result = await uut.getTokenData2(rpcData)
// console.log('result: ', result)
assert.equal(result.success, false)
assert.equal(result.status, 422)
assert.equal(result.message, 'test error')
assert.equal(result.endpoint, 'getTokenData2')
})
})
})
+65
View File
@@ -0,0 +1,65 @@
/*
Unit tests for the bin/server.js file
*/
// Public npm libraries
const assert = require('chai').assert
const sinon = require('sinon')
// Local libraries
const Server = require('../../../bin/server')
describe('#server', () => {
let uut, sandbox
beforeEach(() => {
sandbox = sinon.createSandbox()
uut = new Server()
})
afterEach(() => sandbox.restore())
describe('#startServer', () => {
it('should start the server', async () => {
// Mock dependencies
sandbox.stub(uut.mongoose, 'connect').resolves()
sandbox.stub(uut.controllers, 'initAdapters').resolves()
sandbox.stub(uut.controllers, 'initUseCases').resolves()
sandbox.stub(uut.controllers, 'attachRESTControllers').resolves()
sandbox.stub(uut.adminLib, 'createSystemUser').resolves(true)
sandbox.stub(uut.controllers, 'attachControllers').resolves()
uut.config.env = 'dev'
const result = await uut.startServer()
// console.log('result: ', result)
assert.property(result, 'env')
// Turn off the server.
uut.server.close()
// Restor config env
uut.config.env = 'test'
})
it('should exit on failure', async () => {
// Force an error
sandbox.stub(uut.mongoose, 'connect').rejects(new Error('test error'))
// Prevent default behavior of exiting the program.
sandbox.stub(uut, 'sleep').resolves()
sandbox.stub(uut.process, 'exit').returns()
await uut.startServer()
// Not throwing an error is a success
})
})
describe('#sleep', () => {
it('should execute', async () => {
await uut.sleep(1)
})
})
})
+70
View File
@@ -0,0 +1,70 @@
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:36:43.907Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:36:43.909Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:36:43.910Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:36:43.912Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:36:43.915Z"}
{"level":"error","message":"Error in lib/nodemailer.js/sendEmail()","timestamp":"2022-06-27T17:36:58.979Z"}
{"level":"error","message":"Error in lib/nodemailer.js/sendEmail()","timestamp":"2022-06-27T17:36:58.980Z"}
{"level":"error","message":"Error in lib/nodemailer.js/sendEmail()","timestamp":"2022-06-27T17:36:58.981Z"}
{"level":"error","message":"Error in lib/nodemailer.js/sendEmail()","timestamp":"2022-06-27T17:36:58.982Z"}
{"level":"error","message":"Error in lib/nodemailer.js/sendEmail()","timestamp":"2022-06-27T17:36:58.983Z"}
{"level":"error","message":"Error in lib/nodemailer.js/validateEmailArray()","timestamp":"2022-06-27T17:36:59.002Z"}
{"level":"error","message":"Error in lib/nodemailer.js/validateEmailArray()","timestamp":"2022-06-27T17:36:59.003Z"}
{"level":"error","message":"Error in lib/nodemailer.js/getHtmlFromObject()","timestamp":"2022-06-27T17:36:59.005Z"}
{"level":"error","message":"Error in lib/nodemailer.js/getHtmlFromObject()","timestamp":"2022-06-27T17:36:59.006Z"}
{"level":"error","message":"Error in lib/nodemailer.js/getHtmlFromObject()","timestamp":"2022-06-27T17:36:59.008Z"}
{"level":"info","message":"Warning: Can not send JSON RPC response. Can not determine which peer this message came from.","timestamp":"2022-06-27T17:36:59.353Z"}
{"level":"info","message":"Rejecting invalid JSON RPC command.","timestamp":"2022-06-27T17:36:59.354Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: ea442e78-2297-466a-823b-9cbb12c8ddd9, type: request, method: unknownMethod","timestamp":"2022-06-27T17:36:59.355Z"}
{"level":"error","message":"Error in rpc router(): test error","stack":"Error: test error\n at Context.<anonymous> (/home/trout/work/psf/code/ipfs-service-provider/test/unit/controllers/json-rpc/a10-rpc.unit.js:110:49)\n at callFn (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:366:21)\n at Test.Runnable.run (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:354:5)\n at Runner.runTest (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:666:10)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:789:12\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:581:14)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:591:7\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:474:14)\n at Immediate._onImmediate (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:559:5)\n at processImmediate (node:internal/timers:466:21)","timestamp":"2022-06-27T17:36:59.357Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: 9ef6ad90-7fc3-4cb3-8769-4498e5512b3d, type: request, method: users","timestamp":"2022-06-27T17:36:59.358Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: bd57a1cf-7f2f-4ff2-93d4-6727eec4d778, type: request, method: auth","timestamp":"2022-06-27T17:36:59.359Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: 8fd9edc8-6a45-4042-ac06-9ace60567cbf, type: request, method: about","timestamp":"2022-06-27T17:36:59.361Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: 1b27624a-e698-4bbe-9183-b860a1a0d78d, type: request, method: unknownMethod","timestamp":"2022-06-27T17:36:59.363Z"}
{"level":"info","message":"JSON RPC received from peerA, ID: 40fabddf-59c6-4910-a22c-63da7387f99a, type: request, method: unknownMethod","timestamp":"2022-06-27T17:36:59.365Z"}
{"level":"error","message":"Error in authUser(): Login credential do not match","stack":"Error: Login credential do not match\n at Context.<anonymous> (/home/trout/work/psf/code/ipfs-service-provider/test/unit/controllers/json-rpc/auth.json-rpc.controller.unit.js:144:18)\n at callFn (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:366:21)\n at Test.Runnable.run (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:354:5)\n at Runner.runTest (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:666:10)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:789:12\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:581:14)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:591:7\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:474:14)\n at Immediate.<anonymous> (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:559:5)\n at processImmediate (node:internal/timers:466:21)","timestamp":"2022-06-27T17:37:04.421Z"}
{"level":"error","message":"Error in authUser(): login must be specified","stack":"Error: login must be specified\n at AuthRPC.authUser (/home/trout/work/psf/code/ipfs-service-provider/src/controllers/json-rpc/auth/index.js:78:93)\n at Context.<anonymous> (/home/trout/work/psf/code/ipfs-service-provider/test/unit/controllers/json-rpc/auth.json-rpc.controller.unit.js:165:34)\n at callFn (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:366:21)\n at Test.Runnable.run (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:354:5)\n at Runner.runTest (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:666:10)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:789:12\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:581:14)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:591:7\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:474:14)\n at Immediate._onImmediate (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:559:5)\n at processImmediate (node:internal/timers:466:21)","timestamp":"2022-06-27T17:37:04.423Z"}
{"level":"error","message":"Error in authUser(): password must be specified","stack":"Error: password must be specified\n at AuthRPC.authUser (/home/trout/work/psf/code/ipfs-service-provider/src/controllers/json-rpc/auth/index.js:78:284)\n at Context.<anonymous> (/home/trout/work/psf/code/ipfs-service-provider/test/unit/controllers/json-rpc/auth.json-rpc.controller.unit.js:185:34)\n at callFn (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:366:21)\n at Test.Runnable.run (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runnable.js:354:5)\n at Runner.runTest (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:666:10)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:789:12\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:581:14)\n at /home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:591:7\n at next (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:474:14)\n at Immediate._onImmediate (/home/trout/work/psf/code/ipfs-service-provider/node_modules/mocha/lib/runner.js:559:5)\n at processImmediate (node:internal/timers:466:21)","timestamp":"2022-06-27T17:37:04.425Z"}
{"level":"error","timestamp":"2022-06-27T17:37:04.466Z"}
{"level":"info","message":"Running server in environment: dev","timestamp":"2022-06-27T17:37:04.487Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.495Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.495Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.496Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.497Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.497Z"}
{"level":"error","message":"Error in lib/users.js/getAllUsers()","timestamp":"2022-06-27T17:37:04.499Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.502Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.503Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.503Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.504Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.505Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:04.506Z"}
{"level":"error","message":"Error in lib/users.js/deleteUser()","timestamp":"2022-06-27T17:37:04.508Z"}
{"level":"info","message":"Running server in environment: test","timestamp":"2022-06-27T17:37:04.514Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:04.638Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:05.273Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:05.277Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:05.280Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:05.286Z"}
{"level":"error","timestamp":"2022-06-27T17:37:05.412Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac1b4f08950b955d27f, Target user: 1","timestamp":"2022-06-27T17:37:05.441Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:05.448Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac1b4f08950b955d27f, Target user: 62b9eac1b4f08950b955d27d","timestamp":"2022-06-27T17:37:05.452Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:05.457Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:05.463Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:05.467Z"}
{"level":"error","message":"Error in lib/users.js/updateUser()","timestamp":"2022-06-27T17:37:05.473Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac0b4f08950b955d274, Target user: 62b9eac1b4f08950b955d27d","timestamp":"2022-06-27T17:37:05.478Z"}
{"level":"verbose","message":"It's ok. The user is an admin.","timestamp":"2022-06-27T17:37:05.478Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac1b4f08950b955d27f, Target user: 1","timestamp":"2022-06-27T17:37:05.600Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac1b4f08950b955d27f, Target user: 62b9eac1b4f08950b955d27d","timestamp":"2022-06-27T17:37:05.603Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac0b4f08950b955d274, Target user: 62b9eac1b4f08950b955d27d","timestamp":"2022-06-27T17:37:05.615Z"}
{"level":"verbose","message":"It's ok. The user is an admin.","timestamp":"2022-06-27T17:37:05.615Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:37:05.619Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:37:05.622Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:37:05.624Z"}
{"level":"error","message":"Error in lib/contact.js/sendEmail()","timestamp":"2022-06-27T17:37:05.627Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac1b4f08950b955d2a6, Target user: Target Id","timestamp":"2022-06-27T17:37:05.754Z"}
{"level":"verbose","message":"Calling user and target user do not match! Calling user: 62b9eac0b4f08950b955d274, Target user: 62b9eac1b4f08950b955d2a6","timestamp":"2022-06-27T17:37:05.756Z"}
{"level":"verbose","message":"It's ok. The user is an admin.","timestamp":"2022-06-27T17:37:05.756Z"}
{"level":"error","message":"Error in lib/users.js/createUser()","timestamp":"2022-06-27T17:37:06.060Z"}
+23 -6
View File
@@ -2,12 +2,19 @@
Mocks for the Adapter library.
*/
const ipfs = {
ipfsAdapter: {
ipfs: {}
},
ipfsCoordAdapter: {
ipfsCoord: {
class IpfsAdapter {
constructor () {
this.ipfs = {
files: {
stat: () => {}
}
}
}
}
class IpfsCoordAdapter {
constructor () {
this.ipfsCoord = {
useCases: {
peer: {
sendPrivateMessage: () => {}
@@ -17,6 +24,12 @@ const ipfs = {
}
}
const ipfs = {
ipfsAdapter: new IpfsAdapter(),
ipfsCoordAdapter: new IpfsCoordAdapter()
}
ipfs.ipfs = ipfs.ipfsAdapter.ipfs
const localdb = {
Users: class Users {
static findById () {}
@@ -74,6 +87,10 @@ const bchjs = {
},
Util: {
chunk100: () => {}
},
PsfSlpIndexer: {
getTokenData: () => {},
getTokenData2: () => {}
}
}
+2
View File
@@ -14,6 +14,8 @@ class IPFSCoord {
}
async start () {}
async subscribeToChat() {}
}
module.exports = IPFSCoord
@@ -44,4 +44,17 @@ describe('#use-cases', () => {
}
})
})
describe('#start', () => {
it('should initialize async use cases', async () => {
const result = await uut.start()
assert.equal(result, true)
})
// it('should catch and throw errors', async () => {
// // Force an error
// sandbox.stub()
// })
})
})