mirror of
https://github.com/Permissionless-Software-Foundation/ipfs-bch-wallet-consumer.git
synced 2026-09-21 16:52:03 -07:00
fixed merge conflicts with helia branch
This commit is contained in:
Generated
+11628
-8430
File diff suppressed because it is too large
Load Diff
+10
-1
@@ -24,10 +24,18 @@
|
||||
},
|
||||
"repository": "Permissionless-Software-Foundation/ipfs-bch-wallet-consumer",
|
||||
"dependencies": {
|
||||
"@psf/bch-js": "6.7.3",
|
||||
"@chainsafe/libp2p-gossipsub": "10.1.0",
|
||||
"@chainsafe/libp2p-noise": "13.0.1",
|
||||
"@chainsafe/libp2p-yamux": "5.0.0",
|
||||
"@libp2p/bootstrap": "9.0.8",
|
||||
"@libp2p/tcp": "8.0.9",
|
||||
"axios": "0.27.2",
|
||||
"bcryptjs": "2.4.3",
|
||||
"blockstore-fs": "1.1.6",
|
||||
"datastore-fs": "9.1.5",
|
||||
"glob": "7.1.6",
|
||||
"helia": "2.0.3",
|
||||
"helia-coord": "../helia-coord",
|
||||
"ipfs-coord-esm": "9.1.13",
|
||||
"ipfs-http-client": "58.0.0",
|
||||
"jsonrpc-lite": "2.2.0",
|
||||
@@ -44,6 +52,7 @@
|
||||
"koa-router": "10.0.0",
|
||||
"koa-static": "5.0.0",
|
||||
"koa2-ratelimit": "0.9.1",
|
||||
"libp2p": "0.46.14",
|
||||
"line-reader": "0.4.0",
|
||||
"minimal-slp-wallet": "5.11.1",
|
||||
"mongoose": "5.13.14",
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import IpfsCoord from 'ipfs-coord-esm'
|
||||
// import IpfsCoord from 'ipfs-coord-esm'
|
||||
import IpfsCoord from 'helia-coord'
|
||||
|
||||
// import BCHJS from '@psf/bch-js'
|
||||
import SlpWallet from 'minimal-slp-wallet'
|
||||
@@ -94,13 +95,15 @@ class IpfsCoordAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
const nullLog = () => {}
|
||||
|
||||
const ipfsCoordOptions = {
|
||||
ipfs: this.ipfs,
|
||||
type: 'node.js',
|
||||
// type: 'browser',
|
||||
wallet: this.wallet,
|
||||
privateLog: console.log, // Default to console.log
|
||||
bchjs: this.bchjs,
|
||||
// privateLog: console.log, // Default to console.log
|
||||
privateLog: nullLog,
|
||||
isCircuitRelay: this.config.isCircuitRelay,
|
||||
circuitRelayInfo,
|
||||
apiInfo: this.config.apiInfo,
|
||||
@@ -109,9 +112,9 @@ class IpfsCoordAdapter {
|
||||
}
|
||||
|
||||
// Production env uses external go-ipfs node.
|
||||
if (this.config.isProduction) {
|
||||
ipfsCoordOptions.nodeType = 'external'
|
||||
}
|
||||
// if (this.config.isProduction) {
|
||||
// ipfsCoordOptions.nodeType = 'external'
|
||||
// }
|
||||
|
||||
this.ipfsCoord = new this.IpfsCoord(ipfsCoordOptions)
|
||||
|
||||
|
||||
+96
-58
@@ -9,25 +9,35 @@
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
// const IPFS = require('ipfs')
|
||||
// const IPFS = require('@chris.troutner/ipfs')
|
||||
// import IPFSembedded from 'ipfs';
|
||||
|
||||
import { create } from 'ipfs-http-client'
|
||||
import { createHelia } from 'helia'
|
||||
import fs from 'fs'
|
||||
import http from 'http'
|
||||
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 { gossipsub } from '@chainsafe/libp2p-gossipsub'
|
||||
|
||||
// Local libraries
|
||||
import config from '../../../config/index.js'
|
||||
|
||||
const IPFS_DIR = './.ipfsdata/ipfs'
|
||||
// Hack to get __dirname back.
|
||||
// https://blog.logrocket.com/alternatives-dirname-node-js-es-modules/
|
||||
import * as url from 'url'
|
||||
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
||||
console.log('__dirname: ', __dirname)
|
||||
|
||||
const IPFS_DIR = `${__dirname}../../../.ipfsdata/ipfs`
|
||||
|
||||
class IpfsAdapter {
|
||||
constructor (localConfig) {
|
||||
// Encapsulate dependencies
|
||||
this.config = config
|
||||
this.fs = fs
|
||||
this.create = create
|
||||
// this.create = create
|
||||
|
||||
// Choose the IPFS constructor based on the config settings.
|
||||
// this.IPFS = IPFSembedded // default
|
||||
@@ -37,67 +47,33 @@ class IpfsAdapter {
|
||||
|
||||
// Properties of this class instance.
|
||||
this.isReady = false
|
||||
|
||||
// Bind 'this' object to all subfunctions
|
||||
this.start = this.start.bind(this)
|
||||
this.createNode = this.createNode.bind(this)
|
||||
this.stop = this.stop.bind(this)
|
||||
}
|
||||
|
||||
// Start an IPFS node.
|
||||
async start () {
|
||||
try {
|
||||
// Ipfs Options
|
||||
const ipfsOptionsEmbedded = {
|
||||
repo: IPFS_DIR,
|
||||
start: true,
|
||||
config: {
|
||||
relay: {
|
||||
enabled: true, // enable circuit relay dialer and listener
|
||||
hop: {
|
||||
enabled: config.isCircuitRelay // enable circuit relay HOP (make this node a relay)
|
||||
}
|
||||
},
|
||||
pubsub: true, // enable pubsub
|
||||
Swarm: {
|
||||
ConnMgr: {
|
||||
HighWater: 30,
|
||||
LowWater: 10
|
||||
}
|
||||
},
|
||||
Addresses: {
|
||||
Swarm: [
|
||||
`/ip4/0.0.0.0/tcp/${this.config.ipfsTcpPort}`,
|
||||
`/ip4/0.0.0.0/tcp/${this.config.ipfsWsPort}/ws`
|
||||
]
|
||||
},
|
||||
Datastore: {
|
||||
StorageMax: '2GB',
|
||||
StorageGCWatermark: 50,
|
||||
GCPeriod: '15m'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create an IPFS node
|
||||
const ipfs = await this.createNode()
|
||||
// console.log('ipfs: ', ipfs)
|
||||
|
||||
const ipfsOptionsExternal = {
|
||||
host: this.config.ipfsHost,
|
||||
port: this.config.ipfsApiPort,
|
||||
agent: http.Agent({ keepAlive: true, maxSockets: 200 })
|
||||
}
|
||||
// Get the multiaddrs for the node.
|
||||
const multiaddrs = ipfs.libp2p.getMultiaddrs()
|
||||
console.log('Multiaddrs: ', multiaddrs)
|
||||
|
||||
let ipfsOptions = ipfsOptionsEmbedded
|
||||
if (this.config.isProduction) {
|
||||
ipfsOptions = ipfsOptionsExternal
|
||||
}
|
||||
|
||||
// Create a new IPFS node.
|
||||
this.ipfs = await this.create(ipfsOptions)
|
||||
|
||||
// Set the 'server' profile so the node does not scan private networks.
|
||||
await this.ipfs.config.profiles.apply('server')
|
||||
|
||||
// Debugging: Display IPFS config settings.
|
||||
// const configSettings = await this.ipfs.config.getAll()
|
||||
// console.log(`configSettings: ${JSON.stringify(configSettings, null, 2)}`)
|
||||
this.multiaddrs = multiaddrs
|
||||
this.id = ipfs.libp2p.peerId.toString()
|
||||
console.log('IPFS ID: ', this.id)
|
||||
|
||||
// Signal that this adapter is ready.
|
||||
this.isReady = true
|
||||
|
||||
this.ipfs = ipfs
|
||||
|
||||
return this.ipfs
|
||||
} catch (err) {
|
||||
console.error('Error in ipfs.js/start()')
|
||||
@@ -111,6 +87,68 @@ class IpfsAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
// 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`)
|
||||
|
||||
// libp2p is the networking layer that underpins Helia
|
||||
const libp2p = await createLibp2p({
|
||||
datastore,
|
||||
addresses: {
|
||||
listen: [
|
||||
'/ip4/127.0.0.1/tcp/0',
|
||||
`/ip4/0.0.0.0/tcp/${this.config.ipfsTcpPort}`
|
||||
]
|
||||
},
|
||||
transports: [
|
||||
tcp()
|
||||
],
|
||||
connectionEncryption: [
|
||||
noise()
|
||||
],
|
||||
streamMuxers: [
|
||||
yamux()
|
||||
],
|
||||
peerDiscovery: [
|
||||
bootstrap({
|
||||
list: [
|
||||
// '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
|
||||
// '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
|
||||
// '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
|
||||
// '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt'
|
||||
'/ip4/5.161.108.190/tcp/4102/p2p/12D3KooWKNuBjaMgEDN2tGqzmdfM2bmd22VEuboC4X7x8ua4DvUg',
|
||||
'/ip4/5.161.108.190/tcp/4001/p2p/12D3KooWMW3u8ygGHqNHjxXsw7TA39vgrSQEx7vEGoUh7EiCwGGv',
|
||||
'/ip4/137.184.13.92/tcp/4001/p2p/12D3KooWMbpo92kSGwWiN6QH7fvstMWiLZKcxmReq3Hhbpya2bq4',
|
||||
'/ip4/78.46.129.7/tcp/4001/p2p/12D3KooWJyc54njjeZGbLew4D8u1ghrmZTTPyh3QpBF7dxtd3zGY',
|
||||
'/ip4/5.161.72.148/tcp/4001/p2p/12D3KooWAVG5kn46P9mjKCLUSPesmmLeKf2a79qRt6u22hJaEARJ',
|
||||
'/ip4/161.35.99.207/tcp/4001/p2p/12D3KooWDtj9cfj1SKuLbDNKvKRKSsGN8qivq9M8CYpLPDpcD5pu',
|
||||
'/ip4/192.168.2.173/tcp/4001/p2p/12D3KooWAz2hbriyU9o1wHNU2nxqG8mMgAdWnXCSfWiv5kxSfW49'
|
||||
]
|
||||
})
|
||||
],
|
||||
services: {
|
||||
identify: identifyService(),
|
||||
pubsub: gossipsub({ allowPublishToZeroPeers: true })
|
||||
}
|
||||
})
|
||||
|
||||
// create a Helia node
|
||||
const helia = await createHelia({
|
||||
blockstore,
|
||||
datastore,
|
||||
libp2p
|
||||
})
|
||||
|
||||
return helia
|
||||
} catch (err) {
|
||||
console.error('Error creating Helia node: ', err)
|
||||
}
|
||||
}
|
||||
|
||||
async stop () {
|
||||
await this.ipfs.stop()
|
||||
|
||||
|
||||
@@ -2,21 +2,28 @@
|
||||
Unit tests for the IPFS Adapter.
|
||||
*/
|
||||
|
||||
// Global npm libraries
|
||||
import { assert } from 'chai'
|
||||
|
||||
import sinon from 'sinon'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
// Local libraries
|
||||
import IPFSLib from '../../../src/adapters/ipfs/ipfs.js'
|
||||
import create from '../mocks/ipfs-mock.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', () => {
|
||||
let uut
|
||||
let sandbox
|
||||
let ipfs
|
||||
|
||||
beforeEach(() => {
|
||||
uut = new IPFSLib()
|
||||
|
||||
ipfs = cloneDeep(createHeliaLib)
|
||||
|
||||
sandbox = sinon.createSandbox()
|
||||
})
|
||||
|
||||
@@ -45,35 +52,26 @@ describe('#IPFS-adapter', () => {
|
||||
describe('#start', () => {
|
||||
it('should return a promise that resolves into an instance of IPFS.', async () => {
|
||||
// Mock dependencies.
|
||||
uut.create = create
|
||||
sandbox.stub(uut, 'createNode').resolves(ipfs)
|
||||
|
||||
const result = await uut.start()
|
||||
// console.log('result: ', result)
|
||||
|
||||
// Assert properties of the instance are set.
|
||||
assert.equal(uut.isReady, true)
|
||||
assert.property(uut, 'multiaddrs')
|
||||
assert.property(uut, 'id')
|
||||
|
||||
assert.property(result, 'config')
|
||||
})
|
||||
|
||||
it('should return a promise that resolves into an instance of IPFS in production mode.', async () => {
|
||||
// Mock dependencies.
|
||||
uut.create = create
|
||||
uut.config.isProduction = true
|
||||
const result = await uut.start()
|
||||
// console.log('result: ', result)
|
||||
|
||||
assert.equal(uut.isReady, true)
|
||||
|
||||
assert.property(result, 'config')
|
||||
// Output should be an instance of IPFS
|
||||
assert.property(result, 'libp2p')
|
||||
})
|
||||
|
||||
it('should catch and throw an error', async () => {
|
||||
try {
|
||||
// Force an error
|
||||
sandbox.stub(uut, 'create').rejects(new Error('test error'))
|
||||
sandbox.stub(uut, 'createNode').rejects(new Error('test error'))
|
||||
|
||||
await uut.start()
|
||||
|
||||
assert.fail('Unexpected code path.')
|
||||
} catch (err) {
|
||||
// console.log(err)
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
Mocking library for helia.
|
||||
This is used to replace the helia library when running unit tests.
|
||||
*/
|
||||
|
||||
const ipfs = {
|
||||
libp2p: {
|
||||
getMultiaddrs: () => [],
|
||||
peerId: 'fake-id'
|
||||
}
|
||||
}
|
||||
|
||||
export default ipfs
|
||||
Reference in New Issue
Block a user