mirror of
https://github.com/Permissionless-Software-Foundation/bch-dex.git
synced 2026-09-21 16:52:00 -07:00
221 lines
6.2 KiB
JavaScript
221 lines
6.2 KiB
JavaScript
/*
|
|
REST API Controller library for the /ipfs route
|
|
*/
|
|
|
|
// Global npm libraries
|
|
import { exporter } from 'ipfs-unixfs-exporter'
|
|
import fs from 'fs'
|
|
|
|
// Local libraries
|
|
import wlogger from '../../../adapters/wlogger.js'
|
|
|
|
class IpfsRESTControllerLib {
|
|
constructor (localConfig = {}) {
|
|
// Dependency Injection.
|
|
this.adapters = localConfig.adapters
|
|
if (!this.adapters) {
|
|
throw new Error(
|
|
'Instance of Adapters library required when instantiating /ipfs REST Controller.'
|
|
)
|
|
}
|
|
this.useCases = localConfig.useCases
|
|
if (!this.useCases) {
|
|
throw new Error(
|
|
'Instance of Use Cases library required when instantiating /ipfs REST Controller.'
|
|
)
|
|
}
|
|
|
|
// Encapsulate dependencies
|
|
// this.UserModel = this.adapters.localdb.Users
|
|
// this.userUseCases = this.useCases.user
|
|
this.fs = fs
|
|
|
|
// Bind 'this' object to all subfunctions
|
|
this.getStatus = this.getStatus.bind(this)
|
|
this.getPeers = this.getPeers.bind(this)
|
|
this.getRelays = this.getRelays.bind(this)
|
|
this.handleError = this.handleError.bind(this)
|
|
this.connect = this.connect.bind(this)
|
|
this.getThisNode = this.getThisNode.bind(this)
|
|
this.downloadFile = this.downloadFile.bind(this)
|
|
}
|
|
|
|
/**
|
|
* @api {get} /ipfs Get status on IPFS infrastructure
|
|
* @apiPermission public
|
|
* @apiName GetIpfsStatus
|
|
* @apiGroup REST BCH
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -H "Content-Type: application/json" -X GET localhost:5001/ipfs
|
|
*
|
|
*/
|
|
async getStatus (ctx) {
|
|
try {
|
|
const status = await this.adapters.ipfs.getStatus()
|
|
|
|
ctx.body = { status }
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/getStatus(): ')
|
|
// ctx.throw(422, err.message)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
// Return information on IPFS peers this node is connected to.
|
|
async getPeers (ctx) {
|
|
try {
|
|
const showAll = ctx.request.body.showAll
|
|
|
|
const peers = await this.adapters.ipfs.getPeers(showAll)
|
|
|
|
ctx.body = { peers }
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/getPeers(): ')
|
|
// ctx.throw(422, err.message)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
// Get data about the known Circuit Relays. Hydrate with data from peers list.
|
|
async getRelays (ctx) {
|
|
try {
|
|
const relays = await this.adapters.ipfs.getRelays()
|
|
|
|
ctx.body = { relays }
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/getRelays(): ')
|
|
// ctx.throw(422, err.message)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
async connect (ctx) {
|
|
try {
|
|
const multiaddr = ctx.request.body.multiaddr
|
|
const getDetails = ctx.request.body.getDetails
|
|
|
|
// console.log('this.adapters.ipfs.ipfsCoordAdapter.ipfsCoord.adapters.ipfs: ', this.adapters.ipfs.ipfsCoordAdapter.ipfsCoord.adapters.ipfs)
|
|
const result = await this.adapters.ipfs.ipfsCoordAdapter.ipfsCoord.adapters.ipfs.connectToPeer({ multiaddr, getDetails })
|
|
// console.log('result: ', result)
|
|
|
|
ctx.body = result
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/connect():', err)
|
|
// ctx.throw(422, err.message)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @api {get} /ipfs/node Get a copy of the thisNode object from helia-coord
|
|
* @apiPermission public
|
|
* @apiName GetThisNode
|
|
* @apiGroup REST BCH
|
|
*
|
|
* @apiExample Example usage:
|
|
* curl -H "Content-Type: application/json" -X GET localhost:5001/ipfs/node
|
|
*
|
|
*/
|
|
async getThisNode (ctx) {
|
|
try {
|
|
const thisNode = this.adapters.ipfs.ipfsCoordAdapter.ipfsCoord.thisNode
|
|
|
|
ctx.body = { thisNode }
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/getThisNode(): ')
|
|
// ctx.throw(422, err.message)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
async downloadFile (ctx) {
|
|
try {
|
|
// const { cid } = ctx.params
|
|
|
|
// const multiaddr = ctx.request.body.multiaddr
|
|
// const getDetails = ctx.request.body.getDetails
|
|
const { cid, fileName, path } = ctx.request.body
|
|
|
|
console.log(`downloadFile() retrieving this CID: ${cid}, with fileName: ${fileName}, and path: ${path}`)
|
|
|
|
// const file = await this.adapters.ipfs.ipfs.blockstore.get(cid)
|
|
// console.log('file: ', file)
|
|
// return file
|
|
|
|
// const ipfsFs = this.adapters.ipfs.ipfs.fs
|
|
// console.log('ipfsFs: ', ipfsFs)
|
|
//
|
|
// const buf = []
|
|
// for await (const chunk of ipfsFs.cat(cid)) {
|
|
// // text += decoder.decode(chunk, {
|
|
// // stream: true
|
|
// // })
|
|
//
|
|
// buf.push(chunk)
|
|
// }
|
|
// console.log(`buf: `, buf)
|
|
|
|
const blockstore = this.adapters.ipfs.ipfs.blockstore
|
|
const entry = await exporter(cid, blockstore)
|
|
|
|
console.info(entry.cid) // Qmqux
|
|
console.info(entry.path) // Qmbaz/foo/bar.txt
|
|
console.info(entry.name) // bar.txt
|
|
console.log('entry: ', entry)
|
|
// console.info(entry.unixfs.fileSize()) // 4
|
|
|
|
// stream content from unixfs node
|
|
// const bytes = new Uint8Array(Number(entry.size))
|
|
// let offset = 0
|
|
|
|
const filePath = `${path}/${fileName}`
|
|
const writableStream = fs.createWriteStream(filePath)
|
|
|
|
writableStream.on('error', (error) => {
|
|
console.log(`An error occured while writing to the file. Error: ${error.message}`)
|
|
})
|
|
|
|
writableStream.on('finish', () => {
|
|
console.log(`CID ${cid} downloaded to ${filePath}`)
|
|
})
|
|
|
|
for await (const buf of entry.content()) {
|
|
// bytes.set(buf, offset)
|
|
// offset += buf.length
|
|
|
|
writableStream.write(buf)
|
|
}
|
|
|
|
writableStream.end()
|
|
|
|
// console.info(bytes) // 0, 1, 2, 3
|
|
|
|
ctx.body = {
|
|
success: true
|
|
}
|
|
} catch (err) {
|
|
wlogger.error('Error in ipfs/controller.js/downloadFile(): ', err)
|
|
this.handleError(ctx, err)
|
|
}
|
|
}
|
|
|
|
// DRY error handler
|
|
handleError (ctx, err) {
|
|
// If an HTTP status is specified by the buisiness logic, use that.
|
|
if (err.status) {
|
|
if (err.message) {
|
|
ctx.throw(err.status, err.message)
|
|
} else {
|
|
ctx.throw(err.status)
|
|
}
|
|
} else {
|
|
// By default use a 422 error if the HTTP status is not specified.
|
|
ctx.throw(422, err.message)
|
|
}
|
|
}
|
|
}
|
|
|
|
// module.exports = IpfsRESTControllerLib
|
|
export default IpfsRESTControllerLib
|