diff --git a/.web-extension-id b/.web-extension-id
new file mode 100644
index 0000000..5f3f5dc
--- /dev/null
+++ b/.web-extension-id
@@ -0,0 +1,3 @@
+# This file was created by https://github.com/mozilla/web-ext
+# Your auto-generated extension ID for addons.mozilla.org is:
+{c63fe9b6-dd6c-4267-8ac8-ed4c89480fcc}
\ No newline at end of file
diff --git a/icons/ipfs-offline.svg b/icons/offline.svg
similarity index 100%
rename from icons/ipfs-offline.svg
rename to icons/offline.svg
diff --git a/icons/ipfs.svg b/icons/online.svg
similarity index 100%
rename from icons/ipfs.svg
rename to icons/online.svg
diff --git a/manifest.json b/manifest.json
index 4a5b981..8b33399 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,21 +1,21 @@
{
"manifest_version": 2,
- "name": "IPFS in the browser",
- "version": "1.0",
- "description": "Adds window.ipfs to all pages and starts a daemon in the background",
+ "name": "webext-js-ipfs",
+ "version": "0.0.1",
+ "description": "",
"icons": {
- "48": "icons/ipfs.svg"
+ "48": "icons/online.svg"
},
"background": {
- "scripts": ["dist/start-daemon.js"]
+ "scripts": ["dist/bundle.js"]
},
"browser_action": {
- "default_icon": "icons/ipfs-offline.svg"
+ "default_icon": "icons/offline.svg"
},
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
- "js": ["page-script.js"],
+ "js": ["src/content-script.js"],
"run_at": "document_start"
}
],
diff --git a/testpage.html b/misc/test-page/index.html
similarity index 89%
rename from testpage.html
rename to misc/test-page/index.html
index 97244f2..48e00a0 100644
--- a/testpage.html
+++ b/misc/test-page/index.html
@@ -70,9 +70,12 @@
Cat content
$catOutput.innerText = ''
console.log('got some data')
console.log(res)
- res.on('data', (data) => {
- $catOutput.innerText = $catOutput.innerText + data
- })
+ // TODO should return a stream, but can't get the stream to be passed down
+ // correctly...
+ // res.on('data', (data) => {
+ // $catOutput.innerText = $catOutput.innerText + data
+ // })
+ $catOutput.innerText = res
})
}, false)
}
diff --git a/package.json b/package.json
index 7b6c6b9..f8c52d5 100644
--- a/package.json
+++ b/package.json
@@ -1,25 +1,26 @@
{
- "name": "js-ipfs-in-the-browser",
- "version": "1.0.0",
- "description": "",
- "main": "page-script.js",
+ "name": "webext-js-ipfs",
+ "version": "0.0.0",
+ "description": "Bundle js-ipfs into a WebExtension so that it is accessible over window.IPFS",
+ "main": "src/index.js",
"dependencies": {
- "babel-preset-es2015": "^6.22.0",
- "babelify": "^7.3.0",
- "browserify": "^14.1.0",
- "ipfs": "^0.22.0",
- "setimmediate": "^1.0.5"
+ "bl": "^1.2.1",
+ "browserify-zlib-next": "^1.0.1",
+ "ipfs": "^0.23.1",
+ "safe-buffer": "^5.0.1"
},
"devDependencies": {
- "web-ext": "^1.8.1"
+ "web-ext": "^1.9.1",
+ "webpack": "^2.5.1"
},
"scripts": {
- "test": "mocha",
- "build": "browserify start-daemon.js -o dist/start-daemon.js",
+ "build": "webpack",
"package": "web-ext build",
"sign": "web-ext sign"
},
- "keywords": [],
- "author": "",
- "license": "ISC"
+ "keywords": [
+ "IPFS",
+ "WebExtension"
+ ],
+ "license": "MIT"
}
diff --git a/readme.md b/readme.md
index 15169b3..a9be21e 100644
--- a/readme.md
+++ b/readme.md
@@ -1,11 +1,13 @@
-## js-ipfs in the browser
+## webext-js-ipfs
+
+> Run js-ipfs inside a WebExtension
### Running locally
* `npm install`
* `npm run build`
* Open `about:debugging` in Firefox and point it to the manifest.json in this repository
-* Now try the test page: https://ipfs.io/ipfs/QmcVc8eQiWkR23wMKiQjipLRSjCxR1FEj4TL99aY89J83d
+* Now try the test page: https://ipfs.io/ipfs/QmNnMpP1yJbcwREZHTPAjxFYgoNk5pGaudbHHq1t2ahDrb
### Packaging
diff --git a/spawn-node.js b/spawn-node.js
deleted file mode 100644
index e2f93dc..0000000
--- a/spawn-node.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const IPFS = require('ipfs')
-const multiaddr = require('multiaddr')
-const series = require('async/series')
-
-function spawnNode (options, callback) {
- options.path = options.path || '/ipfd/tmp/' + Math.random()
- const node = new IPFS(options)
- series([
- (cb) => node.init({ emptyRepo: true, bits: 2048 }, (err) => {
- if (err) () => {}
- cb()
- }),
- (cb) => {
- node.config.get((err, config) => {
- if (err) { return cb(err) }
-
- if (!multiaddr.isMultiaddr(multiaddr(options.signalAddr))) {
- return cb(new Error('non valid signalAddr, needs to be a multiaddr'))
- }
-
- const signalDomain = 'star-signal.cloud.ipfs.team'
- const wstarMultiaddr = `/libp2p-webrtc-star/dns/${signalDomain}/wss/ipfs/${config.Identity.PeerID}`
-
- config.Addresses.Swarm = [ wstarMultiaddr ]
- config.Discovery.MDNS.Enabled = false
-
- node.config.replace(config, cb)
- })
- },
- (cb) => node.load(cb),
- (cb) => node.goOnline(cb)
- ], (err) => callback(err, node))
-}
-
-module.exports = spawnNode
diff --git a/page-script.js b/src/content-script.js
similarity index 74%
rename from page-script.js
rename to src/content-script.js
index ddefcc8..9e1f9a6 100644
--- a/page-script.js
+++ b/src/content-script.js
@@ -5,7 +5,11 @@ const myPort = browser.runtime.connect({name: 'port-from-cs'})
const makeCall = (method, args, cb) => {
const listener = (m) => {
- let {err, res} = m
+ let { err, res } = m
+ if (res.on !== undefined) {
+ console.log('I think I got a stream')
+ console.log(res)
+ }
cb(err, cloneInto(res, window, {cloneFunctions: true}))
myPort.onMessage.removeListener(listener)
}
@@ -19,7 +23,4 @@ const ipfs = {
cat: (args, callback) => { makeCall('cat', args, callback) }
}
-window.wrappedJSObject.ipfs = cloneInto(
- ipfs,
- window,
- {cloneFunctions: true})
+window.wrappedJSObject.ipfs = cloneInto(ipfs, window, {cloneFunctions: true})
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..c564558
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,83 @@
+/* global browser */
+
+const IPFS = require('ipfs')
+const bl = require('bl')
+
+browser.browserAction.setIcon({path: '/icons/ipfs-offline.svg'})
+
+const repoPath = 'ipfs-webext-' + Math.random()
+
+const node = new IPFS({
+ repo: repoPath,
+ config: {
+ Addresses: {
+ Swarm: [
+ '/libp2p-webrtc-star/dns4/star-signal.cloud.ipfs.team/wss'
+ ]
+ }
+ }
+})
+
+node.on('err', (err) => {
+ console.log('Error spawning the node', err)
+ browser.browserAction.setIcon({ path: '/icons/offline.svg' })
+})
+
+node.on('ready', () => {
+ window.ipfs = node
+
+ browser.browserAction.setIcon({ path: '/icons/online.svg' })
+
+ setInterval(() => {
+ if (node.isOnline()) {
+ node.swarm.peers((err, peers) => {
+ if (err) {
+ console.log('Error on swarm.peers', err)
+ }
+
+ const nPeers = peers.length.toString()
+ browser.browserAction.setBadgeText({nPeers})
+ })
+ }
+ }, 1000)
+
+ browser.browserAction.onClicked.addListener(() => {
+ if (node.isOnline()) {
+ node.stop(() => {
+ browser.browserAction.setIcon({path: '/icons/offline.svg'})
+ browser.browserAction.setBadgeText({text: 'Offline'})
+ })
+ } else {
+ node.start(() => {
+ browser.browserAction.setIcon({path: '/icons/online.svg'})
+ })
+ }
+ })
+
+ const methods = {
+ 'id': (args, send) => {
+ node.id((err, id) => send({err: err, res: id}))
+ },
+ 'add': (args, send) => {
+ node.files.add(Buffer.from(args), (err, res) => send({err: err, res: res}))
+ },
+ 'cat': (args, send) => {
+ node.files.cat(args, (err, stream) => {
+ if (err) {
+ send({ err: err })
+ }
+ stream.pipe(bl((err, data) => send({ err: err, res: data })))
+ })
+ }
+ }
+
+ browser.runtime.onConnect.addListener((port) => {
+ port.onMessage.addListener((m) => {
+ if (methods[m.method] !== undefined) {
+ methods[m.method](m.args, (res) => port.postMessage(res))
+ } else {
+ throw new Error('Method ' + m.method + ' is currently not exposed')
+ }
+ })
+ })
+})
diff --git a/start-daemon.js b/start-daemon.js
deleted file mode 100644
index 75951f2..0000000
--- a/start-daemon.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* global browser */
-require('setimmediate') // TODO js-ipfs fails without this in the ID call
-const spawn = require('./spawn-node.js')
-browser.browserAction.setIcon({path: '/icons/ipfs-offline.svg'})
-
-spawn({}, (err, ipfsNode) => {
- if (err) throw err
-
- browser.browserAction.setIcon({path: '/icons/ipfs.svg'})
-
- setInterval(() => {
- if (ipfsNode.isOnline().isOnline) {
- ipfsNode.swarm.peers((err, peers) => {
- if (err) throw err
- console.log(peers)
- const text = peers.length.toString()
- browser.browserAction.setBadgeText({text})
- })
- }
- }, 1000)
-
- browser.browserAction.onClicked.addListener(() => {
- if (ipfsNode.isOnline().isOnline) {
- ipfsNode.goOffline(() => {
- browser.browserAction.setIcon({path: '/icons/ipfs-offline.svg'})
- browser.browserAction.setBadgeText({text: 'Offline'})
- })
- } else {
- ipfsNode.goOnline(() => {
- browser.browserAction.setIcon({path: '/icons/ipfs.svg'})
- })
- }
- })
-
- window.ipfs = ipfsNode
- const methods = {
- 'id': (args, send) => {
- console.log('method#id')
- ipfsNode.id((err, id) => {
- send({err, res: id})
- })
- },
- 'add': (args, send) => {
- ipfsNode.files.add(new Buffer(args), (err, res) => {
- send({err, res})
- })
- },
- 'cat': (args, send) => {
- ipfsNode.files.cat(args, (err, res) => {
- send({err, res})
- })
- }
- }
-
- browser.runtime.onConnect.addListener((port) => {
- port.onMessage.addListener((m) => {
- if (methods[m.method] !== undefined) {
- console.log('can make this call')
- methods[m.method](m.args, (res) => {
- console.log('made it and responding!')
- console.log(res)
- port.postMessage(res)
- })
- } else {
- throw new Error('Method ' + m.method + ' is currently not exposed')
- }
- })
- })
-})
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..e1c29f1
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,16 @@
+module.exports = {
+ entry: './src/index.js',
+ output: {
+ filename: 'dist/bundle.js'
+ },
+ node: {
+ fs: 'empty',
+ net: 'empty',
+ tls: 'empty'
+ },
+ resolve: {
+ alias: {
+ zlib: 'browserify-zlib-next'
+ }
+ }
+}