From d97a824362dbae09280e0ff5cf86b0553764d554 Mon Sep 17 00:00:00 2001 From: Daniel Gonzalez Date: Tue, 21 Sep 2021 11:08:15 -0400 Subject: [PATCH] feat(wallet): Poll for wallet services --- package.json | 1 + .../admin-lte/configure/ipfs-tab/index.js | 3 +- .../admin-lte/configure/lib/ipfs-control.js | 65 +++++++++++++++++++ 3 files changed, 68 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 45141a1..caff56b 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "react-jdenticon": "0.0.9", "react-qr-reader": "^2.2.1", "react-redux": "^7.2.4", + "semver": "^7.3.5", "stream-browserify": "^3.0.0", "stream-http": "^3.2.0" }, diff --git a/src/components/admin-lte/configure/ipfs-tab/index.js b/src/components/admin-lte/configure/ipfs-tab/index.js index 48d4675..39e41e9 100644 --- a/src/components/admin-lte/configure/ipfs-tab/index.js +++ b/src/components/admin-lte/configure/ipfs-tab/index.js @@ -155,7 +155,8 @@ class IPFS extends React.Component { // handleChatLog: _this.onCommandLog handleChatLog: _this.incommingChat, bchWallet: bchWallet || _this.props.bchWallet, // bch wallet instance - privateLog: _this.privLogChat + privateLog: _this.privLogChat, + pollLog: _this.onAppStatus } // Retrieve last ipfs control const { menuNavigation } = _this.props diff --git a/src/components/admin-lte/configure/lib/ipfs-control.js b/src/components/admin-lte/configure/lib/ipfs-control.js index 814b084..c031907 100644 --- a/src/components/admin-lte/configure/lib/ipfs-control.js +++ b/src/components/admin-lte/configure/lib/ipfs-control.js @@ -7,9 +7,12 @@ */ import IPFS from '@chris.troutner/ipfs' import IpfsCoord from 'ipfs-coord' +const semver = require('semver') // CHANGE THESE VARIABLES const CHAT_ROOM_NAME = 'psf-ipfs-chat-001' +const MIN_BCH_WALLET_VERSION = '1.11.0' +const WALLET_PROTOCOL = 'bch-wallet' // JSON-LD schema used in announcement. // Customize this data for your own app. @@ -35,7 +38,11 @@ class IpfsControl { this.handleChatLog = ipfsConfig.handleChatLog this.wallet = ipfsConfig.bchWallet this.privateLog = ipfsConfig.privateLog + this.pollLog = ipfsConfig.pollLog + this.serviceProviders = [] + this.selectedServiceProvider = null + this.semver = semver _this = this } @@ -141,6 +148,8 @@ class IpfsControl { console.log('IPFS node setup complete.') this.statusLog('IPFS node setup complete.') _this.statusLog(' ') + + setInterval(this.pollForServices, 10000) } catch (err) { console.error('Error in startIpfs(): ', err) this.statusLog( @@ -164,6 +173,62 @@ class IpfsControl { announceJsonLd } } + + // Poll the ipfs-coord coordination channel for available service providers. + pollForServices () { + try { + // An array of IPFS IDs of other nodes in the coordination pubsub channel. + const peers = _this.ipfsCoord.thisNode.peerList + // console.log(`peers: ${JSON.stringify(peers, null, 2)}`) + + // Array of objects. Each object is the IPFS ID of the peer and contains + // data about that peer. + const peerData = _this.ipfsCoord.thisNode.peerData + // console.log(`peerData: ${JSON.stringify(peerData, null, 2)}`) + + for (let i = 0; i < peers.length; i++) { + const thisPeer = peers[i] + const thisData = peerData.filter(x => x.from === thisPeer) + const thisPeerData = thisData[0] + + // Create a 'fingerprint' that defines the wallet service. + const protocol = thisPeerData.data.jsonLd.protocol + const version = thisPeerData.data.jsonLd.version + // console.log( + // `debug: peer ${thisPeer} uses protocol: ${protocol} v${version}`, + // ) + + let versionMatches = false + if (version) { + versionMatches = _this.semver.gt(version, MIN_BCH_WALLET_VERSION) + } + + // Ignore any peers that don't match the fingerprint for a BCH wallet + // service. + if (protocol && protocol.includes(WALLET_PROTOCOL) && versionMatches) { + // console.log('Matching peer: ', thisPeerData) + + // Temporary business logic. + // Use the first available wallet service detected. + if (_this.serviceProviders.length === 0) { + _this.selectedServiceProvider = thisPeer + + // Persist the config setting, so it can be used by other commands. + // _this.conf.set('selectedService', thisPeer) + const pollLog = `---->BCH wallet service selected: ${thisPeer}` + console.log(pollLog) + _this.pollLog(pollLog) + } + + // Add the peer to the list of serviceProviders. + _this.serviceProviders.push(thisPeer) + } + } + } catch (err) { + console.error('Error in pollForServices(): ', err) + // Do not throw error. This is a top-level function. + } + } } // module.exports = AppIpfs