Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
feat: ipns publish example (#3207)
Browse files Browse the repository at this point in the history
This is an example for the /examples/ folder for how to `ipfs.name.publish` in `js-ipfs` and have that ipns record pubsub'd over to a friendly neighborhood `go-ipfs` node to get recorded on the `DHT`.

Co-authored-by: DougA <douganderson444@gmail.com>
  • Loading branch information
achingbrain and DougAnderson444 authored Sep 2, 2020
1 parent 9c36cb8 commit 91faec6
Show file tree
Hide file tree
Showing 18 changed files with 855 additions and 73 deletions.
2 changes: 1 addition & 1 deletion examples/browser-browserify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"browserify": "^16.2.3",
"concat-stream": "^2.0.0",
"execa": "^4.0.0",
"http-server": "^0.11.1",
"http-server": "^0.12.3",
"ipfs": "^0.49.1",
"test-ipfs-example": "^2.0.3"
},
Expand Down
2 changes: 1 addition & 1 deletion examples/browser-exchange-files/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"devDependencies": {
"browserify": "^16.2.3",
"execa": "^4.0.0",
"http-server": "^0.11.1",
"http-server": "^0.12.3",
"ipfs-http-client": "^46.0.1",
"uint8arrays": "^1.1.0"
},
Expand Down
3 changes: 3 additions & 0 deletions examples/browser-ipns-publish/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bundle.js
.cache
/node_modules/
85 changes: 85 additions & 0 deletions examples/browser-ipns-publish/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Publish to IPNS from the browser

> Use ipns from the browser!
This example is a demo web application that allows you to connect to a go-IPFS node, and publish your IPNS record to the go-DHT network but using your js-ipfs private key. We'll start two IPFS nodes; one in the browser and one on a go-Server. We'll use `ipfs-http-client` to connect to the go-Node to ensure our pubsub messages are getting through, and confirm the IPNS record resolves on the go-Node. We're aiming for something like this:

```
+-----------+ websocket +-----------+
| +-------------------> |
| js-ipfs | pubsub | go-ipfs |
| <-------------------+ |
+-----^-----+ +-----^-----+
| |
| IPFS in browser | HTTP API
| |
+-------------------------------------------------+
| Browser |
+-------------------------------------------------+
| | | |
| | | |
| IPFS direct | | js-http-client |
| a.k.a. ipfsNode | | a.k.a. ipfsAPI |
| | | |
+-------------------------------------------------+
```

## 1. Get started

With Node.js and git installed, clone the repo and install the project dependencies:

```sh
git clone https://github.com/ipfs/js-ipfs.git
cd examples/browser-ipns-publish
npm install # Installs browser-pubsub app dependencies
```

Start the example application:

```sh
npm start
```

You should see something similar to the following in your terminal and the web app should now be available if you navigate to http://127.0.0.1:1234 using your browser:

```sh
Starting up http-server, serving ./
Available on:
http://127.0.0.1:1234
```

## 2. Start two IPFS nodes

The first node is the js-ipfs made in the browser and the demo does that for you.

The second is a go-ipfs node on a server. To get our IPNS record to the DHT, we'll need [a server running go-IPFS](https://blog.ipfs.io/22-run-ipfs-on-a-vps/) with the API enabled on port 5001.

Right now the easiest way to do this is to install and start a `go-ipfs` node.

### Install and start the Go IPFS node

Head over to https://dist.ipfs.io/#go-ipfs and hit the "Download go-ipfs" button. Extract the archive and read the instructions to install.

After installation:

```sh
ipfs init
# Configure CORS to allow ipfs-http-client to access this IPFS node
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"*\"]"
# Configure go-ipfs to listen on a websocket address
npx json -I -f ~/.ipfs/config -e "this.Addresses.Swarm.push('/ip4/127.0.0.1/tcp/4003/ws')"
# Start the IPFS node, enabling pubsub and IPNS over pubsub
ipfs daemon --enable-pubsub-experiment --enable-namesys-pubsub
```

## 3. Open the demo in a browser and connect to the go-node

Now, open up the demo in a browser window.

In the "CONNECT TO GO-IPFS VIA API MULTIADDRESS" field enter `/ip4/YourServerIP/tcp/5001` (where `YourSeverIP` is your server's IP address or use `/dns4/yourdomain.com/tcp/5001`) and click connect. Once it connects, put your go-IPFS websocket address in the next field `/dns4/yourdomain.com/tcp/4003/wss/p2p/QmPeerIDHash` and hit the second "Connect" button.

This connects the API to the go-Node and connects your js-IPFS node via websocket to the go-IPFS node so pubsub will work.

You can choose whether to publish this record under the PeerId of the node that is running in the browser ('self') or choose to add a custom key to the IPFS keychain and publish under that instead. Either should work.

Finally, enter `/ipfs/QmSomeHash` as the content you want to publish to IPNS. You should see the messages sent from the browser to the server appear in the logs below, ending with "Success, resolved" if it all worked.
209 changes: 209 additions & 0 deletions examples/browser-ipns-publish/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
<!DOCTYPE html>
<html>
<head>
<title>Publish to IPNS from the browser</title>
<link
rel="stylesheet"
href="https://unpkg.com/tachyons@4.10.0/css/tachyons.min.css"
/>
<link rel="stylesheet" href="https://unpkg.com/ipfs-css@0.12.0/ipfs.css" />
</head>
<body class="sans-serif">
<header class="pv3 ph2 ph3-l bg-navy cf mb4">
<a href="https://ipfs.io/" title="ipfs.io">
<img
src="https://ipfs.io/images/ipfs-logo.svg"
class="v-mid"
style="height: 50px;"
/>
</a>
<h1 class="aqua fw2 montserrat dib ma0 pv2 ph1 v-mid fr f3 lh-copy">
IPNS Publish from JS to Go Peer
</h1>
</header>
<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">
IPNS PUBLISH SET-UP STEPS
</div>
<main class="page" data-v-4f5abb4a="">
<div class="theme-default-content content__default" data-v-4f5abb4a="">
<div
class="custom-block callout"
style="font-size: 0.75em; width: 75%; margin: 1em;"
>
<p>
Code repo for this demo
<a
href="https://github.com/js-ipfs/examples/browser-ipns-publish/"
>on Github</a
>
</p>
<p>
The idea is to publish from js-ipfs so you control your own
private keys, but publish to go-ipfs to benefit from the DHT.
Since the DHT in js-ipfs is still in the experimental phase, we need to use PubSub
and have a go-ipfs node subscribed to that PubSub to get our IPNS
record onto the DHT. In order to use PubSub between these two
nodes, you'll need a websocket to connect them.
</p>
<div>
To make this demo work, you're going to need:
<ul>
<li style="list-style-type: none;">
<b>1. Access to a go-ipfs node and it's API</b>, a-la
<pre>/dns4/domain.com/tcp/5001</pre>
</li>
<li>
This is how the demo talks to the server, to ensure things
like:
</li>
<ul>
<li>
A) pubsub is enabled, { EXPERIMENTAL: { ipnsPubsub: true } }
and --enable-pubsub-experiment
</li>
<li>
B) go-ipfs is connected to the js-ipfs node in the browser,
via node.swarm.peers(),
</li>
<li>
C) the pubsub messages are getting through to the go node,
via node.pubsub.subscribe().
</li>
</ul>
</ul>
<ul>
<li style="list-style-type: none;">
<b>2. Access to a go-ipfs Websocket port</b>, a-la
<pre>/dns4/domain.com/tcp/4003/wss/p2p/QmTheDomainPeerId</pre>
</li>
<li>
Since we need PubSub for IPNS to reach the go-IPFS node (and
further replicate through the go-DHT network) we need to
connect our pubsub enabled JS-IPFS node in the browser to our
go-IPFS node on the server. The way we connect is via
Websocket. See
<a
href="https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client/examples/browser-pubsub"
>this example</a
>
for reference.
</li>
</ul>
<p>
Once we can talk to go-IPFS and we're connected via Websocket,
then we can publish in our browser node, have the pubsub push it
to the go-IPFS server, and then check with the server that it's
confirmed as published. Once it's on the go-IPFS node it should
replicate throughout the rest of the DHT amongst the go-Nodes.
</p>
</div>
</div>
</div>
</main>
</div>
<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">
1. Connect to Go-IPFS via API MultiAddress
</div>
<input
id="api-url"
class="dib w-50 ph1 pv2 monospace input-reset ba b--black-20 border-box"
placeholder="/dns4/yourdomain.com/tcp/5001"
disabled="disabled"
/>
<button
id="node-connect"
class="dib ph3 pv2 input-reset ba b--black-20 border-box"
disabled="disabled"
>
Connect
</button>
</div>
<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">
2. Connect to Go-IPFS via Websocket MultiAddress (for PubSub to work)
</div>
<input
id="peer-addr"
class="dib w-50 ph1 pv2 monospace input-reset ba b--black-20 border-box"
placeholder="/dns4/yourdomain.com/tcp/4003/wss/p2p/QmTheirServerPeerId"
disabled="disabled"
/>
<button
id="peer-connect"
class="dib ph3 pv2 input-reset ba b--black-20 border-box"
disabled="disabled"
>
Connect
</button>
</div>

<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">
3. Choose a key:
</div>
<form>
<ul style="list-style-type: none;">
<li>
<input type="radio" id="male" name="keyName" value="self" checked />
<label for="male"
>Self (the
<a
href="https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/KEY.md#ipfskeylistoptions"
target="_blank"
>PeerId of the runing node</a
>)</label
><br />
</li>
<li>
<input type="radio" id="female" name="keyName" value="custom-key" disabled="disabled" />
<label for="female"
>Custom Key (<a
href="https://github.com/ipfs/js-ipfs/blob/master/docs/core-api/KEY.md#ipfskeyimportname-pem-password-options"
target="_blank"
>imported</a
>
onto the keychain) [waiting for <a href="https://github.com/ipfs/go-ipfs/issues/6360">#6360</a> to work]</label
><br />
</li>
</ul>
</form>
</div>
<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">
4. IPFS hash to publish
</div>
<input
id="topic"
class="dib w-50 ph1 pv2 monospace input-reset ba b--black-20 border-box"
disabled="disabled"
/>
<button
id="publish"
class="dib ph3 pv2 input-reset ba b--black-20 border-box"
disabled="disabled"
>
Publish to IPNS
</button>
</div>

<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">Browser Console</div>
<div
id="console"
class="f7 db w-100 ph1 pv2 monospace input-reset ba b--black-20 border-box overflow-scroll"
style="height: 300px;"
></div>
</div>
<div class="ph3 mb3">
<div class="fw2 tracked ttu f6 teal-muted mb2">Server Console</div>
<div
id="server-console"
class="f7 db w-100 ph1 pv2 monospace input-reset ba b--black-20 border-box overflow-scroll"
style="height: 300px;"
></div>
</div>
<script src="index.js"></script>
</body>
</html>
Loading

0 comments on commit 91faec6

Please sign in to comment.