helia-coord 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/.on-save.json +8 -0
  2. package/PEDIGREE.md +3 -0
  3. package/README.md +3 -0
  4. package/config/bootstrap-circuit-relays.js +48 -0
  5. package/examples/start-external.js +56 -0
  6. package/index.js +129 -0
  7. package/lib/adapters/bch-adapter.js +94 -0
  8. package/lib/adapters/encryption-adapter.js +123 -0
  9. package/lib/adapters/gist.js +42 -0
  10. package/lib/adapters/index.js +66 -0
  11. package/lib/adapters/ipfs-adapter.js +263 -0
  12. package/lib/adapters/logs-adapter.js +44 -0
  13. package/lib/adapters/pubsub-adapter/README.md +86 -0
  14. package/lib/adapters/pubsub-adapter/about-adapter.js +117 -0
  15. package/lib/adapters/pubsub-adapter/index.js +275 -0
  16. package/lib/adapters/pubsub-adapter/messaging.js +389 -0
  17. package/lib/adapters/pubsub-adapter/msg-router.js +58 -0
  18. package/lib/adapters/pubsub-adapter/resend-msg.js +58 -0
  19. package/lib/controllers/index.js +24 -0
  20. package/lib/controllers/timer-controller.js +417 -0
  21. package/lib/entities/this-node-entity.js +102 -0
  22. package/lib/use-cases/index.js +36 -0
  23. package/lib/use-cases/peer-use-cases.js +146 -0
  24. package/lib/use-cases/pubsub-use-cases.js +56 -0
  25. package/lib/use-cases/relay-use-cases.js +479 -0
  26. package/lib/use-cases/schema.js +158 -0
  27. package/lib/use-cases/this-node-use-cases.js +443 -0
  28. package/lib/util/utils.js +12 -0
  29. package/package.json +52 -0
  30. package/test/mocks/adapter-mock.js +119 -0
  31. package/test/mocks/circuit-relay-mocks.js +67 -0
  32. package/test/mocks/ipfs-mock.js +46 -0
  33. package/test/mocks/peers-mock.js +75 -0
  34. package/test/mocks/pubsub-mocks.js +37 -0
  35. package/test/mocks/thisnode-mocks.js +82 -0
  36. package/test/mocks/use-case-mocks.js +24 -0
  37. package/test/unit/adapters/bch-adapter-unit.js +96 -0
  38. package/test/unit/adapters/encryption-adapter-unit.js +129 -0
  39. package/test/unit/adapters/gist.unit.adapters.js +58 -0
  40. package/test/unit/adapters/index-adapters-unit.js +79 -0
  41. package/test/unit/adapters/ipfs-adapter-unit.js +215 -0
  42. package/test/unit/adapters/logs-adapter-unit.js +55 -0
  43. package/test/unit/adapters/pubsub/about-adapter-unit.js +129 -0
  44. package/test/unit/adapters/pubsub/messaging-adapter-unit.js +576 -0
  45. package/test/unit/adapters/pubsub/pubsub-adapter-unit.js +367 -0
  46. package/test/unit/adapters/pubsub/resend-msg-adapter-unit.js +58 -0
  47. package/test/unit/controllers/controllers-index-unit.js +30 -0
  48. package/test/unit/controllers/timer-controller-unit.js +261 -0
  49. package/test/unit/entities/this-node.unit.entity.js +157 -0
  50. package/test/unit/index-unit.js +160 -0
  51. package/test/unit/use-cases/peer.unit.use-cases.js +186 -0
  52. package/test/unit/use-cases/pubsub.unit.use-cases.js +114 -0
  53. package/test/unit/use-cases/relay-use-cases-unit.js +658 -0
  54. package/test/unit/use-cases/schema-use-case-unit.js +101 -0
  55. package/test/unit/use-cases/this-node-use-cases-unit.js +427 -0
  56. package/test/unit/use-cases/use-cases-index-unit.js +47 -0
  57. package/test/unit/util/utils-unit.js +31 -0
package/.on-save.json ADDED
@@ -0,0 +1,8 @@
1
+ [
2
+ {
3
+ "srcDir": "",
4
+ "destDir": "",
5
+ "files": "**/*.js",
6
+ "command": "npm run lint"
7
+ }
8
+ ]
package/PEDIGREE.md ADDED
@@ -0,0 +1,3 @@
1
+ # Pedigree
2
+
3
+ This repository was forked from [ipfs-coord-esm](https://github.com/Permissionless-Software-Foundation/ipfs-coord-esm). Code changes from that upstream repository is frequently pulled in and merged to this repository.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # helia-coord
2
+
3
+ This is a fork of [ipfs-coord-esm](https://github.com/Permissionless-Software-Foundation/ipfs-coord-esm), adpted for use with [Helia](https://github.com/ipfs/helia) instead of Kubo.
@@ -0,0 +1,48 @@
1
+ /*
2
+ This library contains known circuit relays that new IPFS nodes can use to
3
+ bootstrap themselves into the network and join the pubsub network.
4
+ */
5
+ /* eslint camelcase: 0 */
6
+
7
+ const BOOTSTRAP_BROWSER_CRs = [
8
+ {
9
+ // Based in USA, east coast.
10
+ name: 'bchd.nl',
11
+ multiaddr: '/dns4/bchd.nl/tcp/443/wss/p2p/12D3KooWRBhwfeP2Y9CDkFRBAZ1pmxUadH36TKuk3KtKm5XXP8mA',
12
+ connected: false,
13
+ ipfsId: '12D3KooWRBhwfeP2Y9CDkFRBAZ1pmxUadH36TKuk3KtKm5XXP8mA',
14
+ isBootstrap: true
15
+ },
16
+ {
17
+ name: 'ipfs-cr.fullstackslp.nl',
18
+ multiaddr: '/dns4/ipfs-cr.fullstackslp.nl/tcp/443/wss/p2p/12D3KooWJyc54njjeZGbLew4D8u1ghrmZTTPyh3QpBF7dxtd3zGY',
19
+ connected: false,
20
+ ipfsId: '12D3KooWJyc54njjeZGbLew4D8u1ghrmZTTPyh3QpBF7dxtd3zGY',
21
+ isBootstrap: true
22
+ }
23
+ ]
24
+
25
+ const BOOTSTRAP_NODE_CRs = [
26
+ {
27
+ name: 'bchd.nl',
28
+ multiaddr: '/ip4/5.161.95.233/tcp/4001/p2p/12D3KooWRBhwfeP2Y9CDkFRBAZ1pmxUadH36TKuk3KtKm5XXP8mA',
29
+ connected: false,
30
+ ipfsId: '12D3KooWRBhwfeP2Y9CDkFRBAZ1pmxUadH36TKuk3KtKm5XXP8mA',
31
+ isBootstrap: true
32
+ },
33
+ {
34
+ name: 'ipfs-cr.fullstackslp.nl',
35
+ multiaddr: '/ip4/78.46.129.7/tcp/4001/p2p/12D3KooWJyc54njjeZGbLew4D8u1ghrmZTTPyh3QpBF7dxtd3zGY',
36
+ connected: false,
37
+ ipfsId: '12D3KooWJyc54njjeZGbLew4D8u1ghrmZTTPyh3QpBF7dxtd3zGY',
38
+ isBootstrap: true
39
+ }
40
+ ]
41
+
42
+ const bootstrapCircuitRelays = {
43
+ browser: BOOTSTRAP_BROWSER_CRs,
44
+ node: BOOTSTRAP_NODE_CRs
45
+ }
46
+
47
+ // module.exports = bootstrapCircuitRelays
48
+ export default bootstrapCircuitRelays
@@ -0,0 +1,56 @@
1
+ /*
2
+ This example shows how to start an IPFS node, using ipfs-coord, with the
3
+ IPFS node running as an external node that can be controlled via the
4
+ ipfs-http-client library.
5
+
6
+ Designed to use IPFS running in this Docker container:
7
+ https://github.com/christroutner/docker-ipfs
8
+ */
9
+
10
+ // const IPFS = require('@chris.troutner/ipfs')
11
+ import { create } from 'ipfs-http-client'
12
+ // const IPFS = require('/home/trout/work/personal/js-ipfs/packages/ipfs')
13
+ // const BCHJS = require('@psf/bch-js')
14
+ import SlpWallet from 'minimal-slp-wallet'
15
+ // const IpfsCoord = require('ipfs-coord')
16
+ import IpfsCoord from '../index.js'
17
+ import http from 'http'
18
+
19
+ // Configuration for external IPFS node.
20
+ const ipfsOptions = {
21
+ protocol: 'http',
22
+ host: 'localhost',
23
+ port: 5001,
24
+ agent: http.Agent({ keepAlive: true, maxSockets: 100 })
25
+ }
26
+
27
+ async function start () {
28
+ // Create an instance of bch-js and IPFS.
29
+ // const bchjs = new BCHJS()
30
+ const wallet = new SlpWallet()
31
+ await wallet.walletInfoPromise
32
+ const ipfs = await create(ipfsOptions)
33
+
34
+ // Pass bch-js and IPFS to ipfs-coord when instantiating it.
35
+ const ipfsCoord = new IpfsCoord({
36
+ ipfs,
37
+ wallet,
38
+ type: 'node.js',
39
+ // type: 'browser'
40
+ nodeType: 'external',
41
+ debugLevel: 2
42
+ })
43
+
44
+ await ipfsCoord.start()
45
+ console.log('IPFS and the coordination library is ready.')
46
+
47
+ // Used for debugging
48
+ // setTimeout(async function () {
49
+ // const thisNode = ipfsCoord.thisNode
50
+ // console.log('\nthisNode: ', thisNode)
51
+ // // console.log(
52
+ // // `thisNode.peerData: ${JSON.stringify(thisNode.peerData, null, 2)}`
53
+ // // )
54
+ // }, 20000)
55
+ }
56
+ start()
package/index.js ADDED
@@ -0,0 +1,129 @@
1
+ /*
2
+ A JS npm library for helping IPFS peers coordinate, find a common interest,
3
+ and stay connected around that interest.
4
+
5
+ See the specification document in the dev-docs directory.
6
+ */
7
+
8
+ // Local libraries
9
+ import Adapters from './lib/adapters/index.js'
10
+ import UseCases from './lib/use-cases/index.js'
11
+ import Controllers from './lib/controllers/index.js'
12
+
13
+ class IpfsCoord {
14
+ constructor (localConfig = {}) {
15
+ // Dependency Injection
16
+ if (!localConfig.ipfs) {
17
+ throw new Error(
18
+ 'An instance of IPFS must be passed when instantiating the ipfs-coord library.'
19
+ )
20
+ }
21
+ if (!localConfig.wallet) {
22
+ throw new Error(
23
+ 'An instance of minimal-slp-wallet must be passed when instantiating the ipfs-coord library.'
24
+ )
25
+ }
26
+ this.type = localConfig.type
27
+ if (!this.type) {
28
+ throw new Error(
29
+ 'The type of IPFS node (browser or node.js) must be specified.'
30
+ )
31
+ }
32
+
33
+ // Retrieve and/or set the debug level.
34
+ // 0 = no debug information.
35
+ // 1 = status logs
36
+ // 2 = verbose errors about peer connections
37
+ this.debugLevel = parseInt(localConfig.debugLevel)
38
+ if (!this.debugLevel) this.debugLevel = 0
39
+ localConfig.debugLevel = this.debugLevel
40
+ console.log(`ipfs-coord debug level: ${localConfig.debugLevel}`)
41
+
42
+ // localConfiguration of an optional 'status' log handler for log reports. If none
43
+ // is specified, defaults to console.log.
44
+ if (localConfig.statusLog) {
45
+ this.statusLog = localConfig.statusLog
46
+ } else {
47
+ this.statusLog = console.log
48
+ }
49
+ // If the statusLog handler wasn't specified, then define it.
50
+ localConfig.statusLog = this.statusLog
51
+
52
+ // localConfiguration of an optional 'private' log handler for recieving e2e
53
+ // encrypted message. If none is specified, default to console.log.
54
+ if (localConfig.privateLog) {
55
+ this.privateLog = localConfig.privateLog
56
+ } else {
57
+ this.privateLog = console.log
58
+ }
59
+ // If the privateLog handler wasn't specified, then define it.
60
+ localConfig.privateLog = this.privateLog
61
+
62
+ // Load the adapter libraries.
63
+ this.adapters = new Adapters(localConfig)
64
+ localConfig.adapters = this.adapters
65
+
66
+ // Load the Use Cases
67
+ this.useCases = new UseCases(localConfig)
68
+ localConfig.useCases = this.useCases
69
+
70
+ // Load Controllers
71
+ this.controllers = new Controllers(localConfig)
72
+ }
73
+
74
+ // Returns a Promise that resolves to true once the IPFS node has been
75
+ // initialized and has had a chance to connect to circuit relays and
76
+ // coordination pubsub channels.
77
+ async start () {
78
+ // Wait for the IPFS to finish initializing, then retrieve information
79
+ // about the node like it's ID and multiaddrs.
80
+ await this.adapters.ipfs.start()
81
+
82
+ // Create an instance of the 'self' which represents this IPFS node, BCH
83
+ // wallet, and other things that make up this ipfs-coord powered IPFS node.
84
+ this.thisNode = await this.useCases.thisNode.createSelf({ type: this.type })
85
+ // console.log('thisNode: ', this.thisNode)
86
+
87
+ // Subscribe to Pubsub Channels
88
+ await this.useCases.pubsub.initializePubsub(this.thisNode)
89
+
90
+ // Start timer-based controllers.
91
+ await this.controllers.timer.startTimers(this.thisNode, this.useCases)
92
+
93
+ // Kick-off initial connection to Circuit Relays and Peers.
94
+ // Note: Deliberatly *not* using await here, so that it doesn't block startup
95
+ // of ipfs-service-provider.
96
+ this._initializeConnections()
97
+
98
+ return true
99
+ }
100
+
101
+ // This function kicks off initial connections to the circuit relays and then
102
+ // peers. This function is intended to be called once at startup. This handles
103
+ // the initial connections, but the timer-controller manages the connections
104
+ // after this initial function.
105
+ async _initializeConnections () {
106
+ try {
107
+ // Connect to Circuit Relays
108
+ await this.useCases.relays.initializeRelays(this.thisNode)
109
+ console.log('Initial connections to Circuit Relays complete.')
110
+
111
+ // Load list of Circuit Relays from GitHub Gist.
112
+ await this.useCases.relays.getCRGist(this.thisNode)
113
+ console.log('Finished connecting to Circuit Relays in GitHub Gist.')
114
+
115
+ await this.useCases.thisNode.refreshPeerConnections()
116
+ console.log('Initial connections to subnet Peers complete.')
117
+
118
+ return true
119
+ } catch (err) {
120
+ console.error('Error in _initializeConnections(): ', err)
121
+ // throw err
122
+
123
+ // Do not throw errors as it will prevent the node from starting.
124
+ return false
125
+ }
126
+ }
127
+ }
128
+
129
+ export default IpfsCoord
@@ -0,0 +1,94 @@
1
+ /*
2
+ A top level library for Bitcoin Cash (BCH) handling. This library will
3
+ encapsulate a lot of support libraries and contain BCH-specific methods.
4
+ */
5
+
6
+ class BchAdapter {
7
+ constructor (localConfig) {
8
+ // Dependency Injection
9
+ if (!localConfig.wallet) {
10
+ throw new Error(
11
+ 'An instance of minimal-slp-wallet must be passed when instantiating the BCH adapter library.'
12
+ )
13
+ }
14
+
15
+ this.bchjs = localConfig.wallet.bchjs
16
+ this.mnemonic = localConfig.wallet.walletInfo.mnemonic
17
+ }
18
+
19
+ // Generate a BCH key pair and address. Returns an object with this information,
20
+ // which can be used for payments and e2e encryption.
21
+ // 12-word mnemonic string input is optional. Will generate a new wallet and
22
+ // keypair if not provided. Will use the first address on the SLIP44
23
+ // derivation path of 245 if a 12 word mnemonic is provided.
24
+ async generateBchId () {
25
+ try {
26
+ // Generate a 12-word mnemonic, if one isn't provided.
27
+ // if (!this.mnemonic) {
28
+ // this.mnemonic = this.bchjs.Mnemonic.generate(
29
+ // 128,
30
+ // this.bchjs.Mnemonic.wordLists().english
31
+ // )
32
+ // }
33
+ // console.log(`mnemonic: ${mnemonic}`)
34
+
35
+ // root seed buffer
36
+ const rootSeed = await this.bchjs.Mnemonic.toSeed(this.mnemonic)
37
+
38
+ const masterHDNode = this.bchjs.HDNode.fromSeed(rootSeed)
39
+
40
+ const childNode = masterHDNode.derivePath("m/44'/245'/0'/0/0")
41
+
42
+ const outObj = {}
43
+
44
+ // Generate the cash and SLP addresses.
45
+ outObj.cashAddress = this.bchjs.HDNode.toCashAddress(childNode)
46
+ outObj.slpAddress = this.bchjs.SLP.Address.toSLPAddress(
47
+ outObj.cashAddress
48
+ )
49
+
50
+ // No need to export the private key?
51
+ // outObj.WIF = this.bchjs.HDNode.toWIF(childNode)
52
+
53
+ // Export the public key as a hex string. This will be used for e2e
54
+ // encryption.
55
+ const pubKey = this.bchjs.HDNode.toPublicKey(childNode)
56
+ outObj.publicKey = pubKey.toString('hex')
57
+
58
+ return outObj
59
+ } catch (err) {
60
+ console.error('Error in bch-lib.js/generateBchId()')
61
+ throw err
62
+ }
63
+ }
64
+
65
+ async generatePrivateKey () {
66
+ try {
67
+ // Generate a 12-word mnemonic, if one isn't provided.
68
+ // if (!this.mnemonic) {
69
+ // this.mnemonic = this.bchjs.Mnemonic.generate(
70
+ // 128,
71
+ // this.bchjs.Mnemonic.wordLists().english
72
+ // )
73
+ // }
74
+ // console.log(`mnemonic: ${mnemonic}`)
75
+
76
+ // root seed buffer
77
+ const rootSeed = await this.bchjs.Mnemonic.toSeed(this.mnemonic)
78
+
79
+ const masterHDNode = this.bchjs.HDNode.fromSeed(rootSeed)
80
+
81
+ const childNode = masterHDNode.derivePath("m/44'/245'/0'/0/0")
82
+
83
+ const privKey = this.bchjs.HDNode.toWIF(childNode)
84
+
85
+ return privKey
86
+ } catch (err) {
87
+ console.error('Error in bch-lib.js/generatePrivateKey()')
88
+ throw err
89
+ }
90
+ }
91
+ }
92
+
93
+ // module.exports = BchAdapter
94
+ export default BchAdapter
@@ -0,0 +1,123 @@
1
+ /*
2
+ A library for end-to-end encryption (e2ee). This will largely be a wrapper
3
+ for existing encryption libraries.
4
+ */
5
+
6
+ import BchEncrypt from 'bch-encrypt-lib/index.js'
7
+
8
+ class EncryptionAdapter {
9
+ constructor (localConfig = {}) {
10
+ // Dependency injection
11
+ this.bch = localConfig.bch
12
+ if (!this.bch) {
13
+ throw new Error(
14
+ 'Must pass in an instance of bch Adapter when instantiating the encryption Adapter library.'
15
+ )
16
+ }
17
+ this.bchjs = this.bch.bchjs // Copy of bch-js
18
+
19
+ this.bchEncrypt = new BchEncrypt({ bchjs: this.bchjs })
20
+ // this.ipfs = encryptConfig.ipfs
21
+ // this.orbitdb = encryptConfig.orbitdb
22
+ }
23
+
24
+ // Decrypt incoming messages on the pubsub channel for this node.
25
+ async decryptMsg (msg) {
26
+ try {
27
+ // console.log('decryptMsg msgObj: ', msg)
28
+
29
+ const privKey = await this.bch.generatePrivateKey()
30
+ // console.log(`privKey: ${privKey}`)
31
+
32
+ const decryptedHexStr = await this.bchEncrypt.encryption.decryptFile(
33
+ privKey,
34
+ msg
35
+ )
36
+ // console.log(`decryptedHexStr ${decryptedHexStr}`)
37
+
38
+ const decryptedBuff = Buffer.from(decryptedHexStr, 'hex')
39
+
40
+ const decryptedStr = decryptedBuff.toString()
41
+ // console.log(`decryptedStr: ${decryptedStr}`)
42
+
43
+ return decryptedStr
44
+ } catch (err) {
45
+ // Exit quietly if the issue is a 'Bad MAC'. This seems to be a startup
46
+ // issue.
47
+ if (err.message.includes('Bad MAC')) {
48
+ throw new Error(
49
+ 'Bad MAC. Could not decrypt message. Peer may have stale encryption data for this node.'
50
+ )
51
+ // return ''
52
+ }
53
+
54
+ console.error('Error in decryptMsg()')
55
+ throw err
56
+ }
57
+ }
58
+
59
+ // Returns an encrypted hexidecimal string derived from an input message
60
+ // (string), encrypted with the public key of a peer.
61
+ async encryptMsg (peer, msg) {
62
+ try {
63
+ // console.log('peer: ', peer)
64
+
65
+ const pubKey = peer.data.encryptPubKey
66
+ // console.log('msg to encrypt: ', msg)
67
+ // console.log(`Encrypting with public key: ${pubKey}`)
68
+
69
+ const msgBuf = Buffer.from(msg, 'utf8').toString('hex')
70
+
71
+ const encryptedHexStr = await this.bchEncrypt.encryption.encryptFile(
72
+ pubKey,
73
+ msgBuf
74
+ )
75
+
76
+ return encryptedHexStr
77
+ } catch (err) {
78
+ console.error('Error in encryption.js/encryptMsg()')
79
+ throw err
80
+ }
81
+ }
82
+
83
+ // Send an e2e encrypted message to a peer.
84
+ // async sendEncryptedMsg (peer, msg) {
85
+ // try {
86
+ // // console.log('sendEncryptedMsg peer: ', peer)
87
+ // // console.log('sendEncryptedMsg msg: ', msg)
88
+ //
89
+ // // const channel = peer.ipfsId.toString()
90
+ // const pubKey = peer.encryptPubKey
91
+ // // const orbitdbId = peer.orbitdb
92
+ //
93
+ // const msgBuf = Buffer.from(msg, 'utf8').toString('hex')
94
+ // // console.log(`msgBuf: ${msgBuf}`)
95
+ //
96
+ // const encryptedHexStr = await this.bchEncrypt.encryption.encryptFile(
97
+ // pubKey,
98
+ // msgBuf
99
+ // )
100
+ // console.log(`encryptedHexStr: ${encryptedHexStr}`)
101
+ //
102
+ // // const msgBuf2 = Buffer.from(encryptedHexStr, 'hex')
103
+ //
104
+ // // Publish the message to the pubsub channel.
105
+ // // TODO: This will be deprecated in the future in favor of publishing to
106
+ // // the peers OrbitDB.
107
+ // // await this.ipfs.pubsub.publish(channel, msgBuf2)
108
+ //
109
+ // // if (orbitdbId) {
110
+ // // console.log(
111
+ // // `Ready to send encrypted message to peer ${channel} on orbitdb ID ${orbitdbId}`
112
+ // // )
113
+ // // await this.orbitdb.sendToDb(channel, encryptedHexStr, orbitdbId)
114
+ // // }
115
+ // } catch (err) {
116
+ // console.error('Error in sendEncryptedMsg()')
117
+ // throw err
118
+ // }
119
+ // }
120
+ }
121
+
122
+ // module.exports = EncryptionAdapter
123
+ export default EncryptionAdapter
@@ -0,0 +1,42 @@
1
+ /*
2
+ This adapter library is concerned with interfacing with the GitHub Gist API.
3
+ It's used to download a more easily maintained list of Circuit Relays
4
+ operated by members of the PSF.
5
+ */
6
+
7
+ import axios from 'axios'
8
+
9
+ class Gist {
10
+ constructor (localConfig = {}) {
11
+ this.axios = axios
12
+ }
13
+
14
+ // Retrieve a JSON file from a GitHub Gist
15
+ async getCRList () {
16
+ try {
17
+ // Public CRs
18
+ // https://gist.github.com/christroutner/048ea1a4b635a055c6bb63d48c373806
19
+ const gistUrl =
20
+ 'https://api.github.com/gists/048ea1a4b635a055c6bb63d48c373806'
21
+
22
+ // Retrieve the gist from github.com.
23
+ const result = await this.axios.get(gistUrl)
24
+ // console.log('result.data: ', result.data)
25
+
26
+ // Get the current content of the gist.
27
+ const content = result.data.files['psf-public-circuit-relays.json'].content
28
+ // console.log('content: ', content)
29
+
30
+ // Parse the JSON string into an Object.
31
+ const object = JSON.parse(content)
32
+ // console.log('object: ', object)
33
+
34
+ return object
35
+ } catch (err) {
36
+ console.error('Error attempting to download GitHub Gist of alternative servers.')
37
+ throw err
38
+ }
39
+ }
40
+ }
41
+
42
+ export default Gist
@@ -0,0 +1,66 @@
1
+ /*
2
+ This is a top-level library for the Adapters. This file loads all other
3
+ adapter libraries.
4
+ */
5
+
6
+ // Public npm libraries
7
+ // const EventEmitter = require('events')
8
+ // EventEmitter.defaultMaxListeners = 200
9
+
10
+ // Local libraries
11
+ import LogsAdapter from './logs-adapter.js'
12
+ import BchAdapter from './bch-adapter.js'
13
+ import IpfsAdapter from './ipfs-adapter.js'
14
+ import EncryptionAdapter from './encryption-adapter.js'
15
+ import PubsubAdapter from './pubsub-adapter/index.js'
16
+ import Gist from './gist.js'
17
+
18
+ // const Gist = require('./gist')
19
+
20
+ class Adapters {
21
+ constructor (localConfig = {}) {
22
+ // Dependency injection
23
+ if (!localConfig.ipfs) {
24
+ throw new Error(
25
+ 'An instance of IPFS must be passed when instantiating the Adapters library.'
26
+ )
27
+ }
28
+ if (!localConfig.wallet) {
29
+ throw new Error(
30
+ 'An instance of minimal-slp-wallet must be passed when instantiating the Adapters library.'
31
+ )
32
+ }
33
+
34
+ // Input Validation
35
+ if (!localConfig.type) {
36
+ throw new Error(
37
+ 'The type of IPFS node (browser or node.js) must be specified.'
38
+ )
39
+ }
40
+
41
+ // BEGIN: Encapsulate dependencies
42
+
43
+ // Some adapter libraries depend on other adapter libraries. Pass them
44
+ // in the localConfig object.
45
+
46
+ this.log = new LogsAdapter(localConfig)
47
+ localConfig.log = this.log
48
+
49
+ this.bch = new BchAdapter(localConfig)
50
+ localConfig.bch = this.bch
51
+
52
+ this.ipfs = new IpfsAdapter(localConfig)
53
+ localConfig.ipfsAdapter = this.ipfs
54
+
55
+ this.encryption = new EncryptionAdapter(localConfig)
56
+ localConfig.encryption = this.encryption
57
+
58
+ this.pubsub = new PubsubAdapter(localConfig)
59
+ this.gist = new Gist(localConfig)
60
+
61
+ // END: Encapsulate dependencies
62
+ }
63
+ }
64
+
65
+ // module.exports = Adapters
66
+ export default Adapters