Compare commits
5 Commits
fix-typo
...
githubacti
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c33784f485 | ||
|
|
c57ff65ecb | ||
|
|
baa3918a5e | ||
|
|
0226e6508c | ||
|
|
9ab33ca6d3 |
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Compress Images
|
||||
uses: calibreapp/image-actions@main
|
||||
|
||||
2
.github/workflows/scheduled-publishing.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Check for scheduled posts
|
||||
|
||||
2
.github/workflows/sync-staging.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Sync target branch
|
||||
|
||||
@@ -50,8 +50,8 @@ Now edit the metadata at the top of the file.
|
||||
- `description` - used as the meta description tag on the post-page. **required**
|
||||
- `date` - the "_published at_" date, shown on the [blog index page](https://blog.ipfs.io), please update at posting time to reflect current date - **required** (posts will not be displayed until this date on the live blog, but you will see them locally when using `make dev`)
|
||||
- `author` - used to give you credit for your words - **required**
|
||||
- `permalink` - the path to the blog post. Please start and end URLs with a `/` (`/my/url/`). **required**
|
||||
- `tags` - used to categorize the blog post
|
||||
- `permalink` - can be used to override the post URL if needed. Please start and end URLs with a `/` (`/my/url/`).
|
||||
- `header_image` - name of the image displayed on the [blog homepage](https://blog.ipfs.tech/). See [Custom header image](#custom-header-image) for more details.
|
||||
|
||||
#### Custom header image
|
||||
@@ -105,12 +105,6 @@ To build a local copy, run the following:
|
||||
npm start
|
||||
```
|
||||
|
||||
1. On the latest version of Node (>=18) you'll encounter `ERR_OSSL_EVP_UNSUPPORTED` errors. To fix this, either use Node 16 or:
|
||||
|
||||
```bash
|
||||
NODE_OPTIONS=--openssl-legacy-provider npm start
|
||||
```
|
||||
|
||||
1. Open [localhost:8080](http://localhost:8080) in your browser.
|
||||
|
||||
You can close the local server with `CTRL` + `c`. To restart the local server, run `npm start` from inside the `ipfs-blog` directory.
|
||||
|
||||
16
package-lock.json
generated
@@ -6364,9 +6364,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001651",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||
"version": "1.0.30001470",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
|
||||
"integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -6376,10 +6376,6 @@
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -30071,9 +30067,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001651",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||
"version": "1.0.30001470",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz",
|
||||
"integrity": "sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
|
||||
@@ -35,13 +35,12 @@ export default {
|
||||
window.DiscourseEmbed = {
|
||||
discourseUrl: 'https://discuss.ipfs.tech/',
|
||||
discourseEmbedUrl: safePermalink(this.$frontmatter.permalink, this.$frontmatter.date),
|
||||
discourseReferrerPolicy: 'strict-origin-when-cross-origin', // https://meta.discourse.org/t/embed-discourse-comments-on-another-website-via-javascript/31963#setting-the-referrer-policy-7
|
||||
}
|
||||
const d = document.createElement('script')
|
||||
d.type = 'text/javascript'
|
||||
d.async = true
|
||||
d.src = window.DiscourseEmbed.discourseUrl + 'javascripts/embed.js'
|
||||
;(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d)
|
||||
document.getElementsByTagName('body')[0].appendChild(d)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
>
|
||||
<div class="flex-shrink lg:max-w-sm xl:max-w-xl mb-4 lg:mb-0">
|
||||
<h2 class="type-h2">Stay informed</h2>
|
||||
<p class="mt-2 mb-6 mr-2">
|
||||
<p class="mt-2 mr-2">
|
||||
Sign up for the IPFS newsletter (<router-link
|
||||
:to="latestWeeklyPost ? latestWeeklyPost.path : ''"
|
||||
class="text-blueGreenLight hover:underline"
|
||||
@@ -13,43 +13,69 @@
|
||||
>) for the latest on releases, upcoming developments, community events,
|
||||
and more.
|
||||
</p>
|
||||
<a target="_blank" href="https://ipfs.fyi/newsletter">
|
||||
<button
|
||||
type="button"
|
||||
class="
|
||||
px-3
|
||||
py-2
|
||||
text-white
|
||||
bg-blueGreen
|
||||
font-semibold
|
||||
rounded
|
||||
hover:bg-blueGreenScreen
|
||||
transition
|
||||
duration-300
|
||||
"
|
||||
>
|
||||
Sign up
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
<form
|
||||
id="mc-embedded-subscribe-form"
|
||||
name="mc-embedded-subscribe-form"
|
||||
class="flex lg:justify-end max-w-lg xl:w-2/5"
|
||||
action="https://ipfs.us4.list-manage.com/subscribe/post?u=25473244c7d18b897f5a1ff6b&id=cad54b2230"
|
||||
method="post"
|
||||
target="_blank"
|
||||
@submit="subscribeClick"
|
||||
>
|
||||
<div id="mc_embed_signup_scroll" class="grid gric-col-2 w-full">
|
||||
<div class="fields flex flex-col sm:flex-row col-start-1 col-span-2">
|
||||
<div class="sm:ml-4 sm:pt-0"></div>
|
||||
<input
|
||||
id="mce-EMAIL"
|
||||
v-model="email"
|
||||
required
|
||||
type="email"
|
||||
aria-label="Email Address"
|
||||
class="flex-grow text-black p-2 rounded"
|
||||
placeholder="email@your.domain"
|
||||
name="EMAIL"
|
||||
/>
|
||||
<div class="sm:ml-4 sm:pt-0 pt-2">
|
||||
<input
|
||||
id="mc-embedded-subscribe"
|
||||
type="submit"
|
||||
value="Subscribe"
|
||||
name="subscribe"
|
||||
class="p-2 text-white font-semibold bg-blueGreen hover:bg-blueGreenScreen transition duration-300 rounded cursor-pointer w-full"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<label class="pt-2 col-start-1 col-span-2" for="gdpr_28879">
|
||||
<input
|
||||
id="gdpr_28879"
|
||||
type="checkbox"
|
||||
class=""
|
||||
required
|
||||
name="gdpr[28879]"
|
||||
value="Y"
|
||||
/><span class="pl-2">Please send me the newsletter</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mergeRow-gdpr">
|
||||
<div style="position: absolute; left: -5000px" aria-hidden="true">
|
||||
<input
|
||||
type="text"
|
||||
name="b_25473244c7d18b897f5a1ff6b_cad54b2230"
|
||||
tabindex="-1"
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'NewsletterForm',
|
||||
props: {},
|
||||
@@ -59,6 +85,10 @@ export default {
|
||||
computed: {
|
||||
...mapState('appState', ['latestWeeklyPost']),
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
subscribeClick() {
|
||||
countly.trackEvent(countly.events.NEWSLETTER_SUBSCRIBE)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -19,14 +19,7 @@
|
||||
:block-lazy-load="blockLazyLoad"
|
||||
/>
|
||||
<div
|
||||
class="
|
||||
grid-margins
|
||||
pt-8
|
||||
grid grid-cols-1
|
||||
md:grid-cols-2
|
||||
lg:grid-cols-3
|
||||
gap-8
|
||||
"
|
||||
class="grid-margins pt-8 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"
|
||||
itemscope
|
||||
itemtype="http://schema.org/Blog"
|
||||
>
|
||||
@@ -44,17 +37,7 @@
|
||||
class="flex justify-center mt-8 pb-4"
|
||||
>
|
||||
<button
|
||||
class="
|
||||
px-3
|
||||
py-2
|
||||
text-white text-xl
|
||||
bg-blueGreen
|
||||
font-semibold
|
||||
rounded
|
||||
hover:bg-blueGreenScreen
|
||||
transition
|
||||
duration-300
|
||||
"
|
||||
class="px-3 py-2 text-white text-xl bg-blueGreen font-semibold rounded hover:bg-blueGreenScreen transition duration-300"
|
||||
@click="handleLoadMoreClick"
|
||||
>
|
||||
Load More
|
||||
@@ -344,7 +327,7 @@ export default {
|
||||
(item) =>
|
||||
item.frontmatter &&
|
||||
item.frontmatter.tags &&
|
||||
item.frontmatter.tags.find((tag) => tag.name === 'newsletter')
|
||||
item.frontmatter.tags.find((tag) => tag.name === 'weekly')
|
||||
)
|
||||
.sort(
|
||||
(a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date)
|
||||
|
||||
@@ -8,7 +8,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.type-rich {
|
||||
@apply text-18
|
||||
}
|
||||
@@ -37,10 +37,7 @@ export function loadScript() {
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cly, s);
|
||||
})();`
|
||||
|
||||
// Countly was disabled in 2024Q1
|
||||
// https://github.com/ipfs/ipfs-webui/issues/2198
|
||||
// https://github.com/ipfs-shipyard/ignite-metrics/issues/133
|
||||
// document.body.appendChild(countlyScript)
|
||||
document.body.appendChild(countlyScript)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -79,7 +79,7 @@ We have two consecutive goals regarding Wikipedia on IPFS: Our first goal is to
|
||||
|
||||
The easy way to get Wikipedia content on IPFS is to periodically -- say every week -- take snapshots of all the content and add it to IPFS. That way the majority of Wikipedia users -- who only read Wikipedia and don’t edit -- could use all the information on Wikipedia with all the benefits of IPFS. Users couldn't edit it, but users could download and archive swaths of articles, or even the whole thing. People could serve it to each other peer-to-peer, reducing the bandwidth load on Wikipedia servers. People could even distribute it to each other in closed, censored, or resource-constrained networks -- with IPFS, peers do not need to be connected to the original source of the content, being connected to anyone who has the content is enough. Effectively, the content can jump from computer to computer in a peer-to-peer way, and avoid having to connect to the content source or even the internet backbone. We've been in discussions with many groups about the potential of this kind of thing, and how it could help billions of people around the world to access information better -- either free of censorship, or circumventing serious bandwidth or latency constraints.
|
||||
|
||||
So far, we have achieved part of this goal: we have static snapshots of all of Wikipedia on IPFS. This is already a huge result that will help people access, keep, archive, cite, and distribute lots of content. In particular, we hope that this distribution helps people in Turkey, who find themselves in a tough situation. We are still working out a process to continue updating these snapshots, we hope to have someone at Wikimedia in the loop as they are the authoritative source of the content. **If you could help with this, please get in touch with us at `wikipedia-project [AT] ipfs.io`**
|
||||
So far, we have achieved part of this goal: we have static snapshots of all of Wikipedia on IPFS. This is already a huge result that will help people access, keep, archive, cite, and distribute lots of content. In particular, we hope that this distribution helps people in Turkey, who find themselves in a tough situation. We are still working out a process to continue updating these snapshots, we hope to have someone at Wikimedia in the loop as they are the authoritative source of the content. **If you could help with this, please get in touch with us at wikipedia-project@ipfs.io.**
|
||||
|
||||
### (Goal 2) Fully Read-Write Wikipedia on IPFS
|
||||
|
||||
@@ -193,4 +193,4 @@ If people start relying on this information over time, it will be important to e
|
||||
* Turkish Wikipedia (most recent snapshot): [/ipns/tr.wikipedia-on-ipfs.org/](https://ipfs.io/ipns/tr.wikipedia-on-ipfs.org/)
|
||||
* If people start relying on this information, we will encourage Wikimedia to take over generating these snapshots
|
||||
* We are encouraging Wikimedia to publish DNSLink or even IPNS record that is always up to date AND is cryptographically signed by Wikimedia
|
||||
* If you want to mirror the data, run an ipfs node and pin the Wikipedia data onto your node
|
||||
* If you want to mirror the data, run an ipfs node and pin the Wikipedia data onto your node
|
||||
@@ -1,130 +0,0 @@
|
||||
---
|
||||
title: 'Introducing Nabu: Unleashing IPFS on the JVM'
|
||||
description: 'Learn about a new fast IPFS implementation in Java'
|
||||
author: Ian Preston
|
||||
date: 2023-11-07
|
||||
permalink: '/2023-11-introducing-nabu/'
|
||||
header_image: '/nabu-banner-2023.png'
|
||||
tags:
|
||||
- 'ipfs'
|
||||
- 'nabu'
|
||||
- 'bitswap'
|
||||
---
|
||||
|
||||
Greetings from the [Peergos](https://peergos.org) team! We are thrilled to unveil what we've been working on this year: [Nabu](https://github.com/peergos/nabu) – our sleek and versatile Java implementation of IPFS. Named after the ancient Mesopotamian god of literacy, rational arts, and wisdom, Nabu makes decentralised data storage and retrieval available to the large JVM ecosystem. It's now *production ready*, as we are using it in Peeergos - a decentralised, secure file storage, sharing and social network.
|
||||
|
||||
## Introducing Nabu: Empowering Java with IPFS Magic
|
||||
At its core, Nabu is a minimal IPFS implementation for storing and retrieving data blocks over the libp2p protocol. But we didn't stop there – we've also added a touch of innovation with features like authed bitswap. This addition enables the creation of private data blocks, accessible only to those with authorized permissions. Intrigued? Dive into the finer details of this innovation in our dedicated post on [authed bitswap](https://peergos.org/posts/bats).
|
||||
|
||||
Our journey in crafting Nabu involved the implementation of additional libp2p protocols, including:
|
||||
|
||||
* Kademlia (including IPNS): The very backbone of IPFS, aiding in the discovery of blocks and their owners.
|
||||
* Bitswap + Auth Extension: A protocol that facilitates the exchange of data blocks.
|
||||
|
||||
We built upon the solid foundation of [jvm-libp2p](https://github.com/libp2p/jvm-libp2p). As we delved deeper, we realized the need to implement several crucial components. These include the [yamux muxer](https://github.com/libp2p/jvm-libp2p/tree/develop/libp2p/src/main/kotlin/io/libp2p/mux/yamux), the [TLS security provider](https://github.com/libp2p/jvm-libp2p/blob/develop/libp2p/src/main/kotlin/io/libp2p/security/tls/TLSSecureChannel.kt) (complete with ALPN early muxer negotiation), and a substantial portion of a quic transport (still a work in progress). While much of this effort started in a fork, we collaborated with [Consensys](https://consensys.io) to upstream our contributions into the main project which has now released [v1.0.0](https://github.com/libp2p/jvm-libp2p/releases/tag/1.0.0) as a result. This is used in [Teku](https://github.com/ConsenSys/teku), a Java Ethereum 2 implementation.
|
||||
|
||||
[<img src="../assets/nabu/modules.png" width="500" height="300"/>](../assets/nabu/modules.png)
|
||||
|
||||
Nabu's API empowers developers with the following methods:
|
||||
* [id](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-id)
|
||||
* [version](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-version)
|
||||
* [block/get](https://github.com/Peergos/nabu/blob/master/src/main/java/org/peergos/BlockService.java#L12)
|
||||
* [block/put](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-block-put)
|
||||
* [block/rm](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-block-rm)
|
||||
* [block/stat](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-block-stat)
|
||||
* [block/has](https://github.com/Peergos/nabu/blob/master/src/main/java/org/peergos/blockstore/Blockstore.java#L25)
|
||||
* [refs/local](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-refs-local)
|
||||
* [bloom/add](https://github.com/Peergos/nabu/blob/master/src/main/java/org/peergos/blockstore/Blockstore.java#L37)
|
||||
* [dht/findprovs](https://docs.ipfs.tech/reference/kubo/rpc/#api-v0-dht-findprovs)
|
||||
|
||||
Most of these functions align with [Kubo](https://github.com/ipfs/kubo), but we've added block/has, which is a much more efficient way to ask if we have a block or not, as well as bloom/add which is useful if you are adding blocks to the blockstore externally (typically with multiple servers and S3 blockstore, and using a bloom filter). In addition we've added a few extra optional parameters to block/get, which you'll hear more about in the Performance section below.
|
||||
|
||||
## Unique Features
|
||||
|
||||
Nabu boasts some distinctive features that simplify building on IPFS:
|
||||
|
||||
* P2P HTTP Proxy: This feature facilitates HTTP requests to listening peers, encrypting communication over libp2p streams. Bid farewell to the complexities of TLS certificate authorities and DNS.
|
||||
* Built-in S3 Blockstore: Seamlessly integrate external blockstores like S3.
|
||||
* [Infini-Filter](https://dl.acm.org/doi/10.1145/3589285): A bloom filter replacement that offers infinite expandability.
|
||||
* Peer-Specific Block Retrieval: Nabu empowers developers to fetch blocks from specific peers, streamlining data retrieval and improving privacy (See Performance section below).
|
||||
|
||||
Let's shed some light on the first of these gems – the P2P HTTP proxy. A component we initially implemented in [Kubo in 2018](https://peergos.org/posts/dev-update#Decentralization) (behind an experimental flag), this feature introduces a new gateway endpoint with paths in the format:
|
||||
|
||||
**/p2p/$peerid/http/**
|
||||
|
||||
Its function is simple yet transformative: it proxies incoming HTTP requests to the specified $peerid while trimming the preceding "/p2p/$peerid/http" path. On the other end, the setup forwards incoming requests to a designated endpoint. This paradigm grants the convenience of traditional HTTP-based architecture, sans the complexities of DNS and TLS certificate authorities. By addressing the node using its public key, secure connections become effortlessly achievable. The diagram below illustrates how we use this proxy in Peergos.
|
||||
|
||||
[<img src="../assets/nabu/p2p-http-proxy.png" width="640" height="340"/>](../assets/nabu/p2p-http-proxy.png)
|
||||
|
||||
For a simpler example of using this, see our single file demo [chat app](https://github.com/Peergos/nabu-chat/blob/main/src/main/java/chat/Chat.java).
|
||||
|
||||
## Performance
|
||||
### Faster, more private block retrieval
|
||||
Drawing from experience, we recognized the inefficiency of requesting every single block from the DHT or connected peers. This practice leads to excessive bandwidth consumption and sluggish content retrieval. Enter our solution: a new optional parameter,"peers" in block/get allowing retrieval from pre-specified peer IDs. In cases of unreachability, a DHT lookup through dht/findprovs api serves as a fallback option. This design of taking a set of peerids that you want to ask for blocks, encourages users to design their programs to route at a higher level than blocks, improving speed, bandwidth usage and privacy. Many apps will know which peers they want to retrieve data from in advance, and with this parameter they can massively reduce bandwidth and speed up retrieval. The motto here is "Route your peers, not your data". In Peergos, for example, given a capability to a file we can lookup the file owner's home server (specifically its peer id) and directly send bitswap requests there, so we only need to fallback to DHT lookups if their home server is unreachable.
|
||||
|
||||
### Reduced bandwidth and CPU usage
|
||||
We believe that *providing* (announcing to the DHT that you have a given cid) every single block of data you have does not scale, This is because the number of DHT lookups and provide calls increases with the amount of data you are storing. The issues trying to scale this have been [documented](https://blog.ipfs.tech/2023-09-amino-refactoring/#making-reprovides-to-amino-lightning-fast). Compare this to bittorrent, which has been around much longer and has a much larger DHT, but where providing doesn't scale with the amount of data in a torrent and idle bandwidth usage is much lower. For this reason, we've made providing blocks in Nabu optional, and disabled it in Peergos (unless you are running a mirror).
|
||||
|
||||
This leads us to the next optimisation, enabled by only sending block requests to peers we think have the data. In Kubo, bitswap will broadcast block wants to all connected peers (typically in the 100s). This is both a privacy issue and a bandwidth hog as it means joining the main IPFS DHT is very resource intensive. Nabu has an option to block such aggressive peers that flood us with requests for blocks we don't have. With this option enabled, the incoming idle bandwidth usage is reduced by 10X.
|
||||
|
||||
### Benchmark
|
||||
We benchmarked Nabu against a real-world dataset – the Peergos PKI – consisting of a [CHAMP](https://blog.acolyer.org/2015/11/27/hamt/) structure with six layers, 6000 blocks, and a total size of ~2 MiB. The results speak volumes: while standard Kubo took 120 seconds to retrieve this dataset using the pin command, Nabu accomplished the task in a mere 5 seconds. And, this was achieved without any significant optimization or parallelisation, leaving much room for further enhancement.
|
||||
|
||||
[<img src="../assets/nabu/nabu-speed.png" width="604" height="340"/>](../assets/nabu/nabu-speed.png)
|
||||
|
||||
## Compatibility
|
||||
|
||||
Ensuring seamless integration, we subjected Nabu to a suite of interoperability tests against all libp2p implementations, including go-libp2p, rust-libp2p, js-libp2p, and nim-libp2p across historical versions. The results of these tests are documented [here](https://github.com/libp2p/test-plans/actions/runs/5671451848/attempts/1#summary-15368587233). Some of the results are below.
|
||||
|
||||
[<img src="../assets/nabu/nabu-interop.png" width="808" height="340"/>](../assets/nabu/nabu-interop.png)
|
||||
|
||||
## Bringing Nabu to Life: Integration and Usage
|
||||
Getting started with Nabu is simple. Choose between utilizing it through the HTTP API or embedding it directly into your process. Here's a compilable example of the embedding process in Java:
|
||||
```java
|
||||
List<MultiAddress> swarmAddresses = List.of(new MultiAddress("/ip6/::/tcp/4001"));
|
||||
List<MultiAddress> bootstrapAddresses = List.of(new MultiAddress("/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa"));
|
||||
BlockRequestAuthoriser authoriser = (cid, block, peerid, auth) -> CompletableFuture.completedFuture(true);
|
||||
HostBuilder builder = new HostBuilder().generateIdentity();
|
||||
PrivKey privKey = builder.getPrivateKey();
|
||||
PeerId peerId = builder.getPeerId();
|
||||
IdentitySection identity = new IdentitySection(privKey.bytes(), peerId);
|
||||
boolean provideBlocks = true;
|
||||
|
||||
SocketAddress httpTarget = new InetSocketAddress("localhost", 10000);
|
||||
Optional<HttpProtocol.HttpRequestProcessor> httpProxyTarget =
|
||||
Optional.of((s, req, h) -> HttpProtocol.proxyRequest(req, httpTarget, h));
|
||||
|
||||
EmbeddedIpfs ipfs = EmbeddedIpfs.build(new RamRecordStore(),
|
||||
new FileBlockstore(Path.of("/home/alice/ipfs")),
|
||||
provideBlocks,
|
||||
swarmAddresses,
|
||||
bootstrapAddresses,
|
||||
identity,
|
||||
authoriser,
|
||||
httpProxyTarget
|
||||
);
|
||||
ipfs.start();
|
||||
|
||||
List<Want> wants = List.of(new Want(Cid.decode("zdpuAwfJrGYtiGFDcSV3rDpaUrqCtQZRxMjdC6Eq9PNqLqTGg")));
|
||||
Set<PeerId> retrieveFrom = Set.of(PeerId.fromBase58("QmVdFZgHnEgcedCS2G2ZNiEN59LuVrnRm7z3yXtEBv2XiF"));
|
||||
boolean addToLocal = true;
|
||||
List<HashedBlock> blocks = ipfs.getBlocks(wants, retrieveFrom, addToLocal);
|
||||
byte[] data = blocks.get(0).block;
|
||||
```
|
||||
|
||||
If you want a working example app you can fork, have a look at our [chat example](https://github.com/Peergos/nabu-chat). This is a simple CLI app where two users exchange peerid (out of band) and then connect and send messages via p2p http requests, which are printed to the console.
|
||||
|
||||
## Future plans
|
||||
We still have lots planned for Nabu including the following:
|
||||
* NAT traversal with circuit-relay-v2, dcutr and AutoRelay
|
||||
* mDNS peer discovery
|
||||
* Android compatibility and demo app
|
||||
* Quic integration
|
||||
|
||||
## Gratitude and Acknowledgments
|
||||
None of this would have been possible without the support of the [IPFS Implementations Fund](https://arcological.xyz/#ipfs-pool). We extend our heartfelt thanks for making this endeavor a reality.
|
||||
|
||||
## Experience Nabu Today!
|
||||
We invite you to embark on an exploration of Nabu's capabilities. Feel free to give it a whirl, and we eagerly await your feedback and suggestions for improving Nabu. The easiest route is to open an issue on the github repo.
|
||||
|
||||
[Discover Nabu on GitHub](https://github.com/peergos/nabu) and unlock a world of decentralized possibilities.
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
title: 'Connect with us in Istanbul and Prague'
|
||||
description: 'Connect with the PL IPFS Implementers in Istanbul and Prague for DevConnect and DCxPrague! We want to hear from IPFS users to shape our 2024 plans.'
|
||||
author: Cameron Wood
|
||||
date: 2023-11-06
|
||||
permalink: '/2023-11-connect-in-istanbul-and-prauge'
|
||||
header_image: ''
|
||||
tags:
|
||||
- 'ipfs'
|
||||
- 'kubo'
|
||||
- 'helia'
|
||||
- 'event'
|
||||
- 'community'
|
||||
---
|
||||
|
||||
Hello, IPFS enthusiasts and users! We want to connect with you and hear your thoughts as we shape the future of IPFS for 2024. Your input is invaluable in guiding our efforts, so we're inviting you to meet with us in Istanbul and Prague at two exciting events: DevConnect / IPFS Connect in Istanbul 🇹🇷 and DCxPrague in Prague 🇨🇿.
|
||||
|
||||
|
||||
## 🌐 Who We Are: The PL IPFS Implementers and Network Infrastructure Operators
|
||||
|
||||
We are the PL IPFS implementers and network infrastructure operators, working on projects like Kubo, Helia, and managing the IPFS.io gateway. Our goal is to create a better IPFS ecosystem, and your insights are a crucial part of this journey.
|
||||
|
||||
|
||||
## 👋 We Want to Hear from You
|
||||
|
||||
Your input matters! We would be thrilled to connect with as many of our current and prospective users as possible during these upcoming events. Your thoughts and experiences will help us understand your needs and use cases, ultimately guiding our plans for 2024.
|
||||
|
||||
|
||||
## 👂 We're Eager to Listen
|
||||
|
||||
Are you planning to attend any of these events? If so, we would love to connect with you and learn more about your experiences with IPFS. Whether you have feedback, insights, or simply want to share your thoughts, we're all ears. Your feedback will help us figure out how to make the most of our time and resources for the IPFS community.
|
||||
|
||||
|
||||
## ❓ How Can You Get Involved?
|
||||
|
||||
If you're interested in sharing your thoughts and connecting with us during these events, please fill out [this form](https://forms.gle/CxUQPsEUg2CGkLgh6). We're eager to schedule time to meet with you to discuss your current IPFS challenges, needs, and hopes.
|
||||
|
||||
<br />
|
||||
<a href="https://forms.gle/CxUQPsEUg2CGkLgh6" class="cta-button"> Fill out this form to connect</a>
|
||||
|
||||
|
||||
🙏 Thank You!
|
||||
@@ -1,95 +0,0 @@
|
||||
---
|
||||
title: dAppling - a New Way to Deploy IPFS Sites in Minutes
|
||||
description: Introducing a seamless way to launch your code on IPFS, featuring straightforward setup, automatic deployments, and more.
|
||||
author: 🙏 namaskar
|
||||
date: 2023-11-28
|
||||
permalink: '/2023-11-dappling/'
|
||||
header_image: '/2023-12-introducing-dappling-header.png'
|
||||
tags:
|
||||
- 'web3'
|
||||
- 'tooling'
|
||||
- 'ipns'
|
||||
---
|
||||
|
||||
Welcome! I would love to share what I'm building at [dAppling](https://dappling.network), a platform that aims to simplify the build and deployment process for sites hosted on IPFS. I'll share a bit about us, a bit about the platform, and a bit about what you will get. By the end, it should be clear if [dAppling](https://dappling.network) is a tool you'll want to add to your developer toolbox.
|
||||
|
||||
## A Bit about Us
|
||||
|
||||
I'm Kyle. My co-founder Russell and I have been professional developers (whatever that means) for the last 7 years. We've worked at startups, big tech, and things in between. The last 2 of those years has been in the web3 space; started with the creation of a DeFi protocol. We're excited to now be building tools for developers working on the next generation of the web.
|
||||
|
||||
## A Bit about dAppling
|
||||
|
||||
The first of those tools is dAppling. The word is a portmanteau of "dApp", a term short for decentralized application, and "sapling," because nature is wonderful 🌱. However, we support all kinds of web projects, not just [dApps](https://app.gogopool.com.dappling.eth.limo/): [landing pages](https://arbor-landing.dappling.eth.limo/), [blogs](https://blog.dappling.network), or even a simple page of content arguing against the [usage of acronyms](https://nomoreacronyms-0u5spi.dappling.network).
|
||||
|
||||
Basically, we fetch your code, build it into html/css/js files, and host those files on IPFS. What makes us special are the features we provide to make your experience easier. Even if you have an existing site, you can use [dAppling](https://dappling.network) to create a resilient "alternative frontend" that is hosted on IPFS.
|
||||
|
||||
## A Bit about What You Get
|
||||
|
||||
When you add a project to [dAppling](https://dappling.network), you will tell us where the code is and what commands to use. After it's built you will get:
|
||||
|
||||
- automatic updates when your code on **GitHub** changes
|
||||
- hosting on the **InterPlanetary File System** (IPFS)
|
||||
- a working **dappling.network** subdomain
|
||||
- a working **dappling.eth** ENS subdomain
|
||||
- an automatically updating **IPNS** key
|
||||
|
||||
## Our Focuses
|
||||
|
||||
We have two major focuses at [dAppling](https://dappling.network): **simplicity** and **access**.
|
||||
|
||||
We want to make it as easy as possible to get your code hosted. After that, we want it to be accessible and fast. What we want to avoid is a first-time experience where you only see an error screen or have your users waiting forever to load your site.
|
||||
|
||||
### Simplicity
|
||||
|
||||
We simplify the setup process by automatically detecting your app's configuration. If something does go wrong, we have easy to use debugging tools.
|
||||
|
||||
#### Simple Setup
|
||||
|
||||
Since we have access to your code, we look at a few things like what package manager you use, what sort of framework the project is built with, and certain configuration files. We use this information to prefill the configuration form, so you don't have to.
|
||||
|
||||
We have support for environment variables to use during the build process that can be used to configure things like your database URL. Additionally, we support monorepos.
|
||||
|
||||

|
||||
|
||||
#### Simple Debugging
|
||||
|
||||
Try as we might, projects fail to build. Quite a bit! From a linting error to a missing dependency, seeing the error screen seems inevitable. We want to make it as easy as possible to understand what went wrong and how to fix it. We parse the logs and show you the error in, what I think, is a pretty readable format.
|
||||
|
||||

|
||||
|
||||
If reading logs isn't your thing, we have a button that sends your logs to be parsed by AI and returns a summary of the error. And while it's not perfect, the output has been helpful more often than not.
|
||||
|
||||
### Accessibility
|
||||
|
||||
Websites need to be accessed, even if the reader is only you! We think the more points of access the better, and each should be available and fast.
|
||||
|
||||
#### Speed of Access
|
||||
|
||||
The foundation of our storage starts with [Filebase](https://filebase.com/) whose geo-redundant storage locations keep your files available. On top of that, the CDN quickly fetches and caches those files.
|
||||
|
||||
#### Points of Access
|
||||
|
||||
There are a couple of ways to access your site. When the code is built and uploaded to IPFS, you will receive what is called a [Content Identifier (CID)](https://docs.ipfs.tech/concepts/content-addressing/). It's basically the hash of all your files.
|
||||
|
||||
You will receive a new CID every time your site is re-built because the resulting files have changed. Luckily, we use the [InterPlanetary Name System (IPNS)](https://docs.ipfs.tech/concepts/ipns/) to create a key that will always point to the most recent CID.
|
||||
|
||||
So the most straightforward way to fetch your content would be directly from an [IPFS node](https://docs.ipfs.tech/concepts/nodes/). Since not everyone is running an IPFS node (yet), you can instead use an [IPFS gateway](https://docs.ipfs.tech/concepts/ipfs-gateway/) in which a third party fetches the content from their node and serves it over HTTPS.
|
||||
|
||||
Since we store the on our `dappling.eth` ENS name, you can also fetch the content through a service like [eth.limo](https://eth.limo). This service first reads the IPNS key that we set, resolves it to a CID, and then serves the content like a gateway.
|
||||
|
||||
Even simpler would be using the existing DNS system either using our custom `*.dappling.network` subdomain that we created for you. We also allow adding your custom domain like `ipfs.crypto-protocol.app`.
|
||||
|
||||
## Future
|
||||
|
||||
We plan to be constantly upgrading the platform as new decentralization techniques appear. As a user, you will notice more points of access, quicker speeds, and features to make usage easier. We hope to increase decentralization
|
||||
|
||||
- SSR: Serverless applications are popular on platforms like Next.js and we will be using decentralized compute to increase the types of applications we support.
|
||||
- Collaboration: The more participants in a project the better the decentralizaton becomes. We are working on tools to allow multiple people configure the project.
|
||||
|
||||
## Get Involved
|
||||
|
||||
As we continue to improve [dAppling](https://dappling.network), we're always looking for user feedback to guide us. Our focus remains on providing a platform that is not just decentralized but also highly performant and user-friendly.
|
||||
|
||||
[Deploy a site](https://dappling.network), and if you run into **any** problems, want to connect, or just say hi, my DMs are open on [𝕏](https://x.com/0xBookland). I would love to hear about what you're building and help you get all of your projects deployed as we transition to the infrastructure of the future.
|
||||
|
||||
🙏
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: 'IPFS Companion MV3 Update'
|
||||
description: 'A quick update on the status of IPFS Companion in the MV3 world.'
|
||||
author: Whizzzkid
|
||||
date: 2023-12-05
|
||||
permalink: '/2023-ipfs-companion-mv3-update/'
|
||||
header_image: '/ipfs-companion-mv3-banner.png'
|
||||
tags:
|
||||
- 'ipfs'
|
||||
- 'chrome extension'
|
||||
- 'firefox extension'
|
||||
- 'mv3'
|
||||
- 'web-extension'
|
||||
- 'ipfs-companion'
|
||||
---
|
||||
|
||||
[IPFS companion](https://docs.ipfs.tech/install/ipfs-companion/#install) is a browser extension, one of the key tools that enhances the IPFS experience in the browser. It is available for [Firefox](https://addons.mozilla.org/en-US/firefox/addon/ipfs-companion/) and [Chrome/Brave/Opera/Edge](https://chrome.google.com/webstore/detail/ipfs-companion/nibjojkomfdiaoajekhjakgkdhaomnch) (and all other Chromium-based browsers) and is used by thousands of people every day.
|
||||
|
||||
In September, IPFS-Companion built on MV3 (Manifest V3) was shipped on the main channel, which brings exciting improvements and changes the way you interact with this powerful tool. This blog post will give you a quick overview of the journey, changes, and what to expect.
|
||||
|
||||
## What is MV3?
|
||||
|
||||
MV3, or Manifest V3, is the latest iteration of the manifest file format used by browser extensions. MV3 introduces several key changes compared to the previous MV2, such as the adoption of a service worker model for background scripts, increased permissions granularity, a few new APIs like declarativeNetRequest, and deprecation in the behavior of a few APIs like webRequest and their blocking nature on intercepted requests.
|
||||
|
||||
Both [Chrome](https://developer.chrome.com/docs/extensions/mv3/intro/mv3-overview/) and [Firefox](https://extensionworkshop.com/documentation/develop/manifest-v3-migration-guide/) have published documentation on the changes and how to migrate your extension to MV3, but both of them are pretty recent and are still evolving. They also don't seem to agree on how the background scripts should behave or the `host_permissions` should be handled, which makes it even more challenging to build a cross-browser extension.
|
||||
|
||||
Chrome's changes have been much more invasive, as they remove support for blocking `webRequest` API, push for the use of background service workers, and the adoption of the `declarativeNetRequest` API. Firefox, on the other hand, has been more conservative and has been trying to keep the extension ecosystem as close to MV2 as possible, with the exception of the `host_permissions` change.
|
||||
|
||||
While we are making sure that the extension continues to work on Firefox without regressions, Chromium-based browsers make up ~90% of the IPFS-Companion user base, which makes Chrome's implementation of MV3 the lowest common denominator that informs our design decisions and feature set.
|
||||
|
||||
## What's the fuss around `declarativeNetRequest` API?
|
||||
|
||||
When MV3 changes got announced, there was [uproar in the community](https://arstechnica.com/gadgets/2022/09/chromes-new-ad-blocker-limiting-extension-platform-will-launch-in-2023/) that the `webRequest` API was going to be deprecated and replaced by `declarativeNetRequest`. The main reason for this was that the `declarativeNetRequest` API is not as powerful as the `webRequest` API, and it doesn't allow extensions to block requests. Instead, it allows the extension to add and update a limited number of rules per-extension. This was promoted as a way to improve performance and privacy, as the browser would be able to block requests without having to load the extension's code. However, this also meant that the extension would not be able to intercept the requests, and extensions would have to rely on the browser to do that, and for a limited number of domains.
|
||||
|
||||
In practice, there are no privacy or security benefits of `declarativeNetRequest`, and the old behaviour (required by IPFS Companion) can be reimplemented with extra steps. Even though the MV3 extension cannot intercept and block a request in-flight, it can still observe all HTTP requests without blocking them and work around rule count limit by adding or updating dynamic rules on the fly. When a matching request is found by read-only observer, extension can programmatically reload document to force fresh page load against updated dynamic rules. In other words, the MV3 version of Companion extension can emulate the behaviour from MV2:
|
||||
|
||||

|
||||
|
||||
This type of additional complexity is necessary in MV3 world if a genuine extension like IPFS-Companion wants to intercept requests to a given IPFS resource and redirect those to be loaded via the local gateway. This is a key feature of the extension, as it allows users to access the content via the local gateway instead of delegating trust to the public HTTP gateway, which is a centralized service.
|
||||
|
||||
## The Plan
|
||||
|
||||
The discussions around this topic started soon after the announcement of MV3. There are many scenarios and information in [Issue #666](https://github.com/ipfs/ipfs-companion/issues/666). The first step was to prototype a rudimentary version of the extension using the MV3 APIs and see if the MV3 version could achieve comparable functionality. That work was done in [PR #1078](https://github.com/ipfs/ipfs-companion/pull/1078) by [@MeanDaveJustice](https://github.com/meandavejustice), which helped a lot in understanding the challenges.
|
||||
|
||||
Based on both of these a detailed migration plan was laid out in [Issue #1152](https://github.com/ipfs/ipfs-companion/issues/1152), a few important points from the plan were:
|
||||
|
||||
- Implementing request manipulation logic in the browser to support both Chromium and Firefox. The extension will need to identify capabilities of the browser runtime and use the appropriate logic.
|
||||
- Patching packages that now need to account to the new `ServiceWorker` scope. Packages like [`debug`](https://www.npmjs.com/package/debug) and [`countly-sdk-web`](https://www.npmjs.com/package/countly-sdk-web) rely on `window`, `localStorage`, `XMLHttpRequest`, etc which are not available in the service worker scope.
|
||||
- Implementing a collector branch to collect all changes, because the transition in this case could not be done incrementally and instead had to be done in one go. This meant that the collector branch would have to be maintained for a while until the migration was complete. In the meanwhile the `main` branch was still being used to ship security and bug fixes.
|
||||
- Migrating all of the existing battery of tests that used to test various scenarios collected over the years in the MV2 world, over to the MV3 world. This was a huge task and took a lot of time and effort. The tests had to be refactored as such that it would work for browsers that supported request blocking (Firefox) and those that didn't (Chromium).
|
||||
- Implement improved metrics collection to understand IPFS users, by understanding the number of IPFS resources resolved by Companion running in the browser.
|
||||
|
||||
## The migration
|
||||
|
||||
The migration was done in multiple steps:
|
||||
|
||||
- The first step was to implement the [standard checklist](https://github.com/ipfs/ipfs-companion/pull/1170) which outlined the known breaking changes in MV3 and how to fix those.
|
||||
- A parallel step was to implement a [collector branch](https://github.com/ipfs/ipfs-companion/pull/1182) and [build-pipeline](https://github.com/ipfs/ipfs-companion/pull/1183) to go with it.
|
||||
- The next step was to implement the replacement APIs in the `ServiceWorker` context, e.g. [`XMLHttpRequest` migration](https://github.com/ipfs/ipfs-companion/pull/1179)
|
||||
- This was soon followed by the [first iteration](https://github.com/ipfs/ipfs-companion/pull/1181) of blocking by observing logic.
|
||||
- Which allowed for the publication of the [first RC](https://github.com/ipfs/ipfs-companion/pull/1192) and a corresponding announcement on the [discuss forum](https://discuss.ipfs.tech/t/announcing-ipfs-companion-mv3-rc-beta/16442).
|
||||
- This was followed by a series of bug fixes which is a list item in the original [migration plan](https://github.com/ipfs/ipfs-companion/issues/1152).
|
||||
- It was also decided that it would be the right time to remove the experimental embedded `js-ipfs` backend, as it was not useful due to the lack of gateway functionality in extension context, and `js-ipfs` itself being superseded by [`helia`](https://helia.io). This was done in [PR #1225](https://github.com/ipfs/ipfs-companion/pull/1225).
|
||||
- Apart from the plethora of UX regression fixes around context menus (because MV3 changed how context menus were handled), timing issues between observing a request, and actually adding a rule to block those, the most important PR was the test migration which affirmed that the solution handled all the scenarios covered in the MV2 world. This was done in [PR #1236](https://github.com/ipfs/ipfs-companion/pull/1236)
|
||||
- One of the last fixes was to add an additional permission check for requesting [`host_permissions`](https://github.com/ipfs/ipfs-companion/pull/1250) on Firefox which allowed the actual blocking of requests on Firefox.
|
||||
|
||||
## The learnings
|
||||
|
||||
It took more than 6 months to plan, implement, and test the migration. Over 40 PRs were merged and more than 18k lines of code were touched. The migration was a huge effort, and it was only possible because of the amazing community that helped in testing and reporting issues. The migration also highlighted a few key learnings:
|
||||
|
||||
- The world of web browsers is constantly evolving, and it is important to keep up with the changes. This is especially true for extensions, as they are the first to be impacted by these changes. It is important to keep an eye on the changes and plan ahead. The browser vendors also don't seem to agree on how to handle the changes, which makes it even more challenging to build a cross-browser extension.
|
||||
- The MV3 changes will be a huge effort for any extension that relies on observing, intercepting, or blocking a user request... was this needed? Probably not, as the `declarativeNetRequest` API is not as different from the `webRequest` API as it was made out to be. A motivated entity can still implement comparable functionality but that now involves more steps. However, it is important to note that the `ServiceWorker` based background scripts are potentially a huge improvement especially on low-end devices as it allows extension to `sleep` when not in use. This may not be true in every case (e.g. IPFS-companion is always observing requests, so the service-worker may never go to sleep) but it is a step in the right direction as it allows the browser to manage the resources better and would probably someday allow extensions to be used on mobile devices.
|
||||
- A better rollout strategy and feature-flagging capabilities would have helped testing changes in the wild, but this is not possible with the current extension ecosystem. The only way to test changes is to publish them on the main channel and hope that the users report issues. This is not ideal, as it can lead to a bad user experience and a lot of frustration. Transition from MV2 to MV3 was even more challenging as Chrome Webstore would not allow downgrade from MV3 to MV2 in case a faulty release went out. It had to be perfect the first time, otherwise the users would be stuck with a broken extension until the next release.
|
||||
|
||||
## Current status
|
||||
|
||||
MV3 changes went live towards the end of September 2023 when the collector-branch was merged to main and released on both the [Chrome Web Store](https://chrome.google.com/webstore/detail/ipfs-companion/nibjojkomfdiaoajekhjakgkdhaomnch) and [Firefox Add-ons](https://addons.mozilla.org/en-US/firefox/addon/ipfs-companion/). We've not seen any major issues so far. The extension is working as expected and the user base is consistent. There were some minor regressions and bugs reported, but nothing that's a show-stopper. Those are being fixed as they are reported.
|
||||
|
||||
## What's next?
|
||||
|
||||
The next step will be to implement the [new Brave APIs](https://github.com/ipfs/ipfs-companion/issues/1281) to allow for finer control of the IPFS node provided in the Brave Browser. This will provide a much more polished experience for the users of Brave Browser that also want to enable the IPFS Companion extension for additional UI and more file-grained control over redirects. There also are plans to experiment with a [Helia based built-in gateway](https://github.com/ipfs/ipfs-companion/issues/1284) on which some progress has already been made as proof-of-concepts in [helia-service-worker-gateway](https://github.com/ipfs-shipyard/helia-service-worker-gateway) and [helia-http-gateway](https://github.com/ipfs/helia-http-gateway). The learnings from these projects will be used to work with browser vendors to close API gaps and eventually implement a gateway that can be used by IPFS Companion to host an IPFS node in the browser extension itself, which will allow users to access IPFS resources when not running a local node.
|
||||
|
||||
## Conclusion
|
||||
|
||||
It's an exciting new world! Try out [IPFS-companion](https://github.com/ipfs/ipfs-companion) and share your thoughts on [discuss](https://discuss.ipfs.tech/tag/ipfs-companion) or [github](https://github.com/ipfs/ipfs-companion/issues).
|
||||
@@ -1,174 +0,0 @@
|
||||
---
|
||||
title: 'Migrating from Brave to IPFS Desktop'
|
||||
description: 'Complete Guide to Migrating Your IPFS Data'
|
||||
permalink: '/2024-brave-migration-guide/'
|
||||
date: 2024-08-26
|
||||
header_image: '/brave2desktop.jpg'
|
||||
tags:
|
||||
- brave
|
||||
- browsers
|
||||
- IPFS Desktop
|
||||
---
|
||||
|
||||
|
||||
In [2021](https://brave.com/blog/ipfs-support/), IPFS maintainers worked with the Brave team to add native support for IPFS in the Brave Browser. This was the first deep integration of an IPFS node in a browser.
|
||||
|
||||
After over three years, the Brave team [decided](https://github.com/brave/brave-browser/issues/37735) to remove support for running IPFS node as we could not find a mutually agreeable set of terms to make this integration sustainable. The removal was implemented in the latest stable release ([v1.69.153](https://github.com/brave/brave-browser/blob/56f6418ac301a4b015c1188786f6f4497b6ac393/CHANGELOG_DESKTOP.md#169153)) which shipped on Aug 22nd.
|
||||
|
||||
While this change may be disappointing for some, it presents an opportunity to adopt a more robust and flexible IPFS setup.
|
||||
|
||||
This guide will walk you through the process of moving your IPFS data from Brave to [IPFS Desktop](https://github.com/ipfs/ipfs-desktop), ensuring you don't lose any of your important files, and keep access to IPFS resources in your browser.
|
||||
|
||||
## Why Migrate?
|
||||
|
||||
- **Imminent Removal:** The IPFS node feature in Brave is being [phased out](https://github.com/brave/brave-browser/issues/37735#issuecomment-2247764368) and will happen once you update to v1.69.153 or later. Although upgrading will not delete data associated with the IPFS node, migration is necessary to ensure uninterrupted access to your IPFS data, especially if you pinned something, or published with IPNS.
|
||||
- **Improved Functionality:** Migrating to a standalone IPFS solution like IPFS Desktop offers several advantages:
|
||||
1. Automatic security and performance updates without relying on browser updates.
|
||||
2. Ability to customize your IPFS node configuration, no vendor-specific overrides.
|
||||
3. Browser-agnostic background service, allowing your node to run independently of any specific browser.
|
||||
4. Easy access to your files in [WebUI](https://github.com/ipfs/ipfs-webui/#readme) via system status bar icon, and right-click file manager integration (on Windows).
|
||||
|
||||
### Time Investment
|
||||
|
||||
Migrating your IPFS node is a relatively quick process. Most users can complete the transition in 5 to 15 minutes, depending on their familiarity with IPFS and their system configuration.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before we begin, you'll need to install two key components that will replace the functionality that was in Brave with an IPFS stack that will still work in Brave, but also in most other browsers.
|
||||
|
||||
- [IPFS Desktop](https://docs.ipfs.tech/install/ipfs-desktop/) is a full node application that runs [Kubo](https://github.com/ipfs/kubo/) on your computer, managing your IPFS repository and providing a graphical interface for IPFS operations. Download IPFS Desktop by following the [install guide here](https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions). Choose the appropriate version for your operating system ([Windows](https://docs.ipfs.tech/install/ipfs-desktop/#windows), [macOS](https://docs.ipfs.tech/install/ipfs-desktop/#macos), or [Linux](https://docs.ipfs.tech/install/ipfs-desktop/#ubuntu)) and follow the installation instructions.
|
||||
- [IPFS Companion](https://docs.ipfs.tech/install/ipfs-companion/) is a browser extension that allows you to interact with IPFS content directly from your web browser, load it from your local IPFS node, and keep provisional support for `ipfs://` and `ipns://` in address bar. The easiest way to install IPFS Companion is through your browser's specific [extensions and add-ons store](https://docs.ipfs.tech/install/ipfs-companion/#install).
|
||||
|
||||
## Moving the Brave IPFS Repository
|
||||
|
||||
The IPFS repository, often referred to as `$IPFS_PATH` (aka `~/.ipfs`), contains all your IPFS data, IPNS keys, and PeerID identify of your IPFS node. Brave's IPFS Node used the same repository format as Kubo, making migration to IPFS Desktop relatively easy.
|
||||
|
||||
If you did not use IPFS Desktop before, you can simply swap `.ipfs` created by IPFS Desktop with the one from your Brave node. This is the simplest way of migrating your node, all data, pins, IPNS keys, addresses and PeerID will remain the same and IPNS publishing will continue working.
|
||||
|
||||
First, we need to locate your Brave IPFS repository. The configuration directory for the Brave managed IPFS node can be found in the browser’s profile directory in a subfolder named `brave_ipfs`. You can find your IPFS directory by opening `brave://version/`, finding "Profile Path", and replacing `/Default` with `/brave_ipfs`:
|
||||
|
||||
<!-- TODO: confirm these paths are valid -->
|
||||
- Windows: `%LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\brave_ipfs`
|
||||
- example: `C:\Users\YOURUSERNAME\AppData\Local\BraveSoftware\Brave-Browser\User Data\brave_ipfs`
|
||||
- macOS: `~/Library/Application Support/BraveSoftware/Brave-Browser/brave_ipfs`
|
||||
- example: `/Users/YOURUSERNAME/Library/Application Support/BraveSoftware/Brave-Browser/brave_ipfs`
|
||||
- Linux: `~/.config/BraveSoftware/Brave-Browser/brave_ipfs`
|
||||
- example: `/home/YOURUSERNAME/.config/BraveSoftware/Brave-Browser/brave_ipfs`
|
||||
|
||||
To confirm you've found the right directory, open `brave_ipfs/config` and write down the value of `PeerID`, it will act as unique identifier of your Brave repository.
|
||||
|
||||
Now, we'll move this repository to the default location for IPFS Desktop:
|
||||
|
||||
- Windows: `%USERPROFILE%/.ipfs`
|
||||
- example: `C:\Users\YOURUSERNAME\.ipfs`
|
||||
- macOS: `~/.ipfs`
|
||||
- example: `/Users/YOURUSERNAME/.ipfs`
|
||||
- Linux: `~/.ipfs`
|
||||
- example: `/home/YOURUSERNAME/.ipfs`
|
||||
|
||||
Before proceeding, make sure the `.ipfs` directory does not exist at the destination. If you already had `.ipfs`, shut down IPFS Desktop and rename `.ipfs` to `.ipfs.old` as a precaution to avoid data loss.
|
||||
|
||||
Now, move the `brave_ipfs` directory from Brave profile, to the location expected by IPFS Desktop.
|
||||
|
||||
You can use the following commands in your terminal or command prompt:
|
||||
|
||||
For Windows:
|
||||
|
||||
```
|
||||
IF NOT EXIST "%USERPROFILE%\.ipfs" MOVE "%LOCALAPPDATA%\BraveSoftware\Brave-Browser\User Data\brave_ipfs" "%USERPROFILE%\.ipfs"
|
||||
```
|
||||
|
||||
For macOS:
|
||||
```
|
||||
test ! -d ~/.ipfs && mv ~/Library/Application\ Support/BraveSoftware/Brave-Browser/brave_ipfs ~/.ipfs
|
||||
```
|
||||
|
||||
Linux:
|
||||
```
|
||||
test ! -d ~/.ipfs && mv ~/.config/BraveSoftware/Brave-Browser/brave_ipfs ~/.ipfs
|
||||
```
|
||||
|
||||
## Starting IPFS Desktop with Migrated IPFS Repository
|
||||
|
||||
Once move is completed, you can confirm it was successful if `.ipfs/config` exists in your home directory, and includes `PeerID` of your Brave node.
|
||||
|
||||
If `.ipfs/config` exists, you can now start IPFS Desktop. If everything went as expected, your IPFS node should start and run without Brave.
|
||||
|
||||
## Optional: Adjusting Configuration
|
||||
|
||||
Brave-integrated IPFS node had some drawbacks. The access to WebUI was hidden behind `brave://ipfs-internal`. DNSLink detection was based on HTTP header rather than DNS TXT lookup. Running IPFS node required the Brave browser to be open for content and IPNS announcements to function, and in early days did not even start `ipfs daemon` before `ipfs://` was used for the first time, leading to content from local repository not being provided to IPFS Mainnet peers. Repository cache was artificaially limited to 1GiB in size, and evicted along with browser cache, degrading the utility of peers cohosting casually browsed data.
|
||||
|
||||
Switching to IPFS Desktop+Companion solves most of these shortcomings, however you may need to adjust some settings to get full benefit of a standalone IPFS node.
|
||||
|
||||
### Updating Cache Size
|
||||
|
||||
[`Datastore.StorageMax`](https://github.com/ipfs/kubo/blob/master/docs/config.md#datastorestoragemax) controls how much space is allocated to data that is not pinned, such as visited IPFS websites, or other content you've viewed but do not want to pin forever. Having a bigger cache improves the data availability on the network, making websites more resilient.
|
||||
|
||||
To increase IPFS block cache size ([`Datastore.StorageMax`](https://github.com/ipfs/kubo/blob/master/docs/config.md#datastorestoragemax)) from 1GB to at least 100GB (the current default in Kubo):
|
||||
```
|
||||
$ ipfs config Datastore.StorageMax
|
||||
1GB
|
||||
$ ipfs config Datastore.StorageMax 100GB ~
|
||||
```
|
||||
|
||||
### Updating RPC URL in IPFS Companion
|
||||
|
||||
Brave used custom ports: `45001` for RPC and `48080` for Gateway.
|
||||
|
||||
If IPFS Companion browser extension does not detect your node after migrating repository from Brave, you need to update RPC and Gateway URLs in Companion preferences.
|
||||
|
||||
- Change the **Kubo RPC URL** from `http://127.0.0.1:5001` to `http://127.0.0.1:45001`
|
||||
- Change the **Local Gateway** from `http://127.0.0.1:8080` to `http://127.0.0.1:48080`
|
||||
|
||||
Alternative is to update `.ipfs/config` and replace all occurences of `45001` with `5001` and `48080` with `8080`. Make sure you do not have anything listening on these ports before you make the change.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Congratulations! You've successfully migrated your IPFS data from Brave to IPFS Desktop.
|
||||
|
||||
If you encountered any challenges during the migration process or need further assistance, please don't hesitate to leave a comment in the thread below. The community is here to help, and your feedback can also assist others who might be going through the same process.
|
||||
|
||||
## FAQ
|
||||
|
||||
### Is it possible to move `brave_ipfs` to a different location than `.ipfs`?
|
||||
|
||||
Yes, but you need to set the `IPFS_PATH` environment variable before running IPFS Desktop to point at the new location.
|
||||
|
||||
See [How does IPFS Desktop select the IPFS repo location?](https://github.com/ipfs/ipfs-desktop/?tab=readme-ov-file#how-does-ipfs-desktop-select-the-ipfs-repo-location)
|
||||
|
||||
### Where can I find FAQ/Troubleshooting for IPFS Desktop?
|
||||
|
||||
See [github.com/ipfs/ipfs-desktop/#faq--troubleshooting](https://github.com/ipfs/ipfs-desktop/?tab=readme-ov-file#faq--troubleshooting)
|
||||
|
||||
### Can Kubo be used instead?
|
||||
|
||||
Yes, advanced users who are comfortable with command-line can use [Kubo](https://docs.ipfs.tech/install/command-line/) instead of IPFS Desktop, and run it against a custom `IPFS_PATH` to run a headless daemon, or perform selective manual migration via CLI.
|
||||
|
||||
### How to export my Files (MFS) with Kubo CLI?
|
||||
|
||||
To export contents of MFS to a CAR, run the following commands:
|
||||
```
|
||||
$ export IPFS_PATH=/path/to/brave_ipfs
|
||||
$ export MFS_ROOT="$(ipfs files stat / | head -1)"
|
||||
$ ipfs dag export $MFS_ROOT > mfs-backup.car
|
||||
```
|
||||
|
||||
Then, it can be imported on another node and added to MFS there:
|
||||
|
||||
```
|
||||
$ export IPFS_PATH=/path/to/some/other/.ipfs
|
||||
$ ipfs dag import ./mfs-backup.car
|
||||
$ ipfs files cp /ipfs/$MFS_ROOT /brave_mfs_backup
|
||||
$ ipfs pin rm $MFS_ROOT
|
||||
```
|
||||
|
||||
Note: low-level pin (created by `dag import`) can be removed (`pin rm`) after import because presence in MFS is enough to protect data from garbage-collection.
|
||||
|
||||
### How to manually migrate my IPNS names with Kubo CLI?
|
||||
|
||||
To export IPNS keys, and re-publish with them, see `ipfs key --help` and `ipfs name --help`.
|
||||
|
||||
### How to fix `Error: ipfs repo needs migration, please run migration tool.` ?
|
||||
|
||||
IPFS Desktop should run migrations the first time you start, but if you use Kubo CLI
|
||||
you may need to run `ipfs daemon --migrate=true` once, to upgrade to latest version.
|
||||
@@ -8,7 +8,6 @@ permalink: brave-new-wallet
|
||||
translationKey: ''
|
||||
header_image: "/ipfs-blog-brave-2021-07-23.jpg"
|
||||
tags:
|
||||
- brave
|
||||
- browsers
|
||||
- API
|
||||
|
||||
@@ -73,4 +72,4 @@ Introducing (a sneak peek of) the Brave Wallet. The Brave Wallet will launch wit
|
||||
|
||||
**NFT Support.** Users can view their complete NFT collections directly in the wallet.
|
||||
|
||||
Keep an eye out for more updates about the Brave Wallet, coming to the Brave browser this year!
|
||||
Keep an eye out for more updates about the Brave Wallet, coming to the Brave browser this year!
|
||||
@@ -1,532 +0,0 @@
|
||||
---
|
||||
date: 2024-01-29
|
||||
permalink: /dapps-ipfs/
|
||||
title: 'The State of Dapps on IPFS: Trust vs. Verification'
|
||||
description: 'Overview of the current landscape of dapps on IPFS through the lens of trust and verifiability'
|
||||
author: Daniel Norman
|
||||
header_image: /dapps-ipfs/header.png
|
||||
tags:
|
||||
- ipfs
|
||||
- dapps
|
||||
- Helia
|
||||
- js-ipfs
|
||||
- ipns
|
||||
- ens
|
||||
---
|
||||
|
||||
## Preface <!-- omit from toc -->
|
||||
|
||||
This blog post provides a comprehensive overview of the current landscape of dapps on IPFS through the lens of trust and verifiability. Given the nuance and breadth of this topic, this blog post is rather long.
|
||||
|
||||
For easier navigation, use the [table of contents](#contents).
|
||||
|
||||
## Contents <!-- omit from toc -->
|
||||
|
||||
- [Trust vs. verification in dapps](#trust-vs-verification-in-dapps)
|
||||
- [The benefits of IPFS for (d)app developers and users](#the-benefits-of-ipfs-for-dapp-developers-and-users)
|
||||
- [Primer on web app architectures: SPAs, MPA, PWA and dapps](#primer-on-web-app-architectures-spas-mpa-pwa-and-dapps)
|
||||
- [The client-server spectrum](#the-client-server-spectrum)
|
||||
- [SPA and MPA can be easily published to IPFS](#spa-and-mpa-can-be-easily-published-to-ipfs)
|
||||
- [SPA and MPA can also be PWA](#spa-and-mpa-can-also-be-pwa)
|
||||
- [Dapps](#dapps)
|
||||
- [How dapps get chain state](#how-dapps-get-chain-state)
|
||||
- [Publishing dapps: approaches and trade-offs](#publishing-dapps-approaches-and-trade-offs)
|
||||
- [Without IPFS](#without-ipfs)
|
||||
- [Publishing to IPFS](#publishing-to-ipfs)
|
||||
- [Loading dapps from IPFS: approaches and trade-offs](#loading-dapps-from-ipfs-approaches-and-trade-offs)
|
||||
- [From a public gateway](#from-a-public-gateway)
|
||||
- [With a local IPFS node](#with-a-local-ipfs-node)
|
||||
- [With a local IPFS node \& IPFS Companion browser extension](#with-a-local-ipfs-node--ipfs-companion-browser-extension)
|
||||
- [With the Brave browser](#with-the-brave-browser)
|
||||
- [When running a Kubo node is not an option](#when-running-a-kubo-node-is-not-an-option)
|
||||
- [What if content addressing were native to the web?](#what-if-content-addressing-were-native-to-the-web)
|
||||
- [In-browser CID verification with JavaScript](#in-browser-cid-verification-with-javascript)
|
||||
- [Browser constraints](#browser-constraints)
|
||||
- [Approaches to IPFS in the browser](#approaches-to-ipfs-in-the-browser)
|
||||
- [Helia and IPFS in the browser](#helia-and-ipfs-in-the-browser)
|
||||
- [Verifying top-level pages, sub-resources, and async data](#verifying-top-level-pages-sub-resources-and-async-data)
|
||||
- [Fetching and verifying async data with Helia](#fetching-and-verifying-async-data-with-helia)
|
||||
- [Making Helia lighter and developer-friendly](#making-helia-lighter-and-developer-friendly)
|
||||
- [Helia in a Service Worker](#helia-in-a-service-worker)
|
||||
- [Local app installer](#local-app-installer)
|
||||
- [Most users don’t use CIDs directly](#most-users-dont-use-cids-directly)
|
||||
- [Naming systems and mutable pointer](#naming-systems-and-mutable-pointer)
|
||||
- [DNSLink](#dnslink)
|
||||
- [Ethereum Name System (ENS)](#ethereum-name-system-ens)
|
||||
- [IPNS](#ipns)
|
||||
- [Conclusion](#conclusion)
|
||||
|
||||
## Trust vs. verification in dapps
|
||||
|
||||
If you are a decentralized web app (dapp) developer, there’s a good chance that you already publish the frontend of your dapp to IPFS. However, today, even if you do so, your users cannot benefit from the integrity IPFS provides without running their own IPFS node. If your users’ browser isn’t verifying that the frontend's source and resources match the CID you published, they are exposed to a wider attack surface, which can lead in the worst case to stolen funds.
|
||||
|
||||
The root of the problem lies in the **difficulty users face verifying the integrity of dapps deployed to IPFS in a browser without running an IPFS node**. This hurdle means that many users are **trusting** —often unknowingly– a specific IPFS gateway. This goes against the IPFS principle that [**verification matters**](https://specs.ipfs.tech/architecture/principles/#verification-matters) and puts users at risk.
|
||||
|
||||
Over the last couple of months, the [IPFS Shipyard](https://ipfs-shipyard.org/) team has been working with several teams in the dapp ecosystem to understand the challenges they face and the broader problem space. With the formation of the [IPFS Dapps Working Group](https://github.com/ipfs/dapps-wg/) by the IPFS Shipyard team along with the [Liquity team](https://www.liquity.org/) and the IPFS community, we aim to address some of the immediate pain points faced by the dapp developers and users and provide better tooling. One of the main goals is to **establish verified retrieval as the norm for retrieving CIDs on the web**.
|
||||
|
||||
This is not a new problem. Making CIDs native to the web platform has been a long-time goal of the IPFS project and remains a core goal of the [IPFS Ecosystem Working Group](https://blog.ipfs.tech/2023-introducing-the-ecosystem-working-group/). Making CIDs native to the web is an arduous road that involves wide-spanning collaboration with stakeholders including standard bodies, spec writers, browser vendors, and IPFS implementors.
|
||||
|
||||
It’s worth noting that _trustlessness_ is an aspirational property of dapps, but a misleading term because trust cannot be completely eliminated. A better way to look at this is in terms of **verifiability** that content addressing enables, in addition to less reliance on authority, e.g. PKI, DNS and authoritative servers. Moreover, the web’s trust model is deeply ingrained and rooted in the [**Same-origin policy**](https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy). One of the engineering challenges the working group faces is to meet the goal above within the boundaries and constraints of the same-origin policy.
|
||||
|
||||
> **Note:** while this blog post is heavily focused on Dapps, almost all of it applies to any static web application that can be published to IPFS. That is, Progressive Web Apps (**PWA**), Single Page Applications (**SPA**) and any app that does not rely on server side rendering.
|
||||
|
||||
## The benefits of IPFS for (d)app developers and users
|
||||
|
||||
IPFS is supposed to provide several benefits for web app developers and users:
|
||||
|
||||
- **Resilience & censorship resistance:** by having multiple copies of the frontend’s CID on the IPFS network you ensure that even if multiple providers are unavailable or censored, the frontend is still retrievable and usable. In the most extreme case, it’s enough for there to be a single provider for content to be retrievable.
|
||||
- **End-to-end integrity:** as long as a user of your Dapp has the CID you shared, they can be sure they are running the exact code that you published by **verifying** locally. Local verification is crucial since Dapps interact with a blockchain and malicious code can lead to loss of user funds. Integrity is adjacent to trustlessness — because verification eliminates the need to trust the source of data.
|
||||
- **Legal and regulatory compliance:** as regulatory bodies adopt regulation, e.g. **[MiCA](https://www.esma.europa.eu/esmas-activities/digital-finance-and-innovation/markets-crypto-assets-regulation-mica),** which applies to crypto assets and their Dapps, the degree to which services are decentralized comes under scrutiny. While the legal question cannot be answered by the blog post (this is not legal advice), IPFS, through the former two points, should provide the means to maximize decentralization and do so provably.
|
||||
- **Data portability, no vendor lock-in, and [credible exit](https://subconscious.substack.com/p/credible-exit):** once you onboard data and make it content-addressed with CIDs, you are free to move it between implementations, services, and jurisdictions, theoretically, without paying the onboarding cost again.
|
||||
|
||||
The reality, however, is more complex because there are various approaches to publishing and fetching dapps from IPFS that make subtle trade-offs between **trustlessness, resilience, UX, and performance.**
|
||||
|
||||
In the next section, we’ll take a look at web app architectures, and what dapps are, and then dive deeper into the actual approaches you see in the wild.
|
||||
|
||||
## Primer on web app architectures: SPAs, MPA, PWA and dapps
|
||||
|
||||
The rapidly evolving nature of web application architectures has given birth to many terms, abbreviations, and web development frameworks. This section will attempt to provide a high-level overview of some of the main web app architecture patterns, how dapps and how they relate to publishing to IPFS. If you are already familiar with these, feel free to skip ahead.
|
||||
|
||||
### The client-server spectrum
|
||||
|
||||
Today’s web applications can be seen as being positioned somewhere on a **server-client spectrum** regarding where the logic (rendering, authorization, processing user input) lives. On the server end of the spectrum, you have server-rendered apps where most logic is encapsulated in the server, e.g. WordPress, Laravel, and Ruby on Rail apps. On the client end, you have Single Page Applications (SPA), where all routing and rendering logic is client side. SPAs typically have a single entry index.html with a JavaScript bundle that routes all use. Once the JS is loaded, it takes over rendering, navigation, and network (asynchronously submitting user input) responsibilities. Another approach that sits somewhere in the middle is the multi-page application (MPA) with a pre-rendered HTML file per route that typically contains only the necessary JS for the given route.
|
||||
|
||||
It’s worth noting that many modern web development frameworks support more than one architecture and even the blending of different approaches on a per-route basis. For example, a [Next.js supports both MPAs with Static Exports](https://nextjs.org/docs/pages/building-your-application/deploying/static-exports) and server-side rendering.
|
||||
|
||||
[web.dev has a useful article that delves into this topic in more detail](https://web.dev/articles/rendering-on-the-web).
|
||||
|
||||
### SPA and MPA can be easily published to IPFS
|
||||
|
||||
Because SPA and MPA are statically generated, you can easily host them on any server that can serve static files (HTML, JS, CSS, etc.). That makes them a great fit for publishing on both traditional CDNs and IPFS.
|
||||
|
||||
### SPA and MPA can also be PWA
|
||||
|
||||
A progressive web app ([PWA](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/What_is_a_progressive_web_app)), is a web app that runs in a browser while providing a user experience like that of a platform-specific native app, e.g. the ability to function offline, update in the background, and send notifications to the OS.
|
||||
|
||||
The key thing to understand is that what makes an app a PWA (web app manifest and and service worker) is complementary to MPAs and SPAs. [In other words, both SPA and MPA architectures can be used to build a PWA.](https://web.dev/learn/pwa/architecture)
|
||||
|
||||
### Dapps
|
||||
|
||||
Dapps, short for Decentralised Apps, is an umbrella term for applications deployed as a smart contract to a blockchain. Since interacting with smart contracts directly can be a clunky experience, dapps are typically comprised of two components:
|
||||
|
||||
- Smart contracts deployed to a smart contract blockchain like Ethereum (and other EVM chains, e.g. Filecoin).
|
||||
- A frontend to interact with those contracts from the web browser. Typically the frontend will be a static app (SPA/MPA) that is deployed to a CDN and/or published to IPFS.
|
||||
|
||||
### How dapps get chain state
|
||||
|
||||
In this architecture, the static site will need to fetch blockchain state, specifically the state associated with the Dapp’s smart contracts. This can be done using the following approaches:
|
||||
|
||||
- The most naive is to use the [Ethereum JSON-RPC API](https://ethereum.org/en/developers/docs/apis/json-rpc/) which every Ethereum execution client/node exposes. The Ethereum execution client is software that keeps an up-to-date full state by synching with the rest of the network and updating the state tree every time a new block is produced. Dapps that rely on the JSON-RPC API will either use a hosted Ethereum node provider like Quicknode, Alchemy, and Infura, or run their own node.
|
||||
- Since the JSON-RPC API is usually too low-level with unindexed data to provide rich frontend functionality, many Dapps will instead query an additional indexing layer like [The Graph](https://thegraph.com/). The Graph is a protocol for indexing and querying blockchain data and makes it possible to efficiently query chain state using GraphQL. For example, Uniswap uses [this approach](https://docs.uniswap.org/api/subgraph/overview) to fetch data from the Uniswap smart contracts.
|
||||
|
||||
In both approaches, retrieval of chain state happens as async requests invoked by the frontend code.
|
||||
|
||||
It’s also pretty common for the smart contracts and frontend of a dapp to be open source, which allows anyone to audit the code. For example, Uniswap publishes both the source of their [smart contracts](https://github.com/Uniswap/v3-core) and [interface](https://github.com/Uniswap/interface) on [GitHub](https://github.com/Uniswap).
|
||||
|
||||
One thing to note is that the degree of decentralization of a Dapp can vary based on several factors that are beyond the scope of this post.
|
||||
|
||||
**As a general rule of thumb, it’s only as decentralized as the least decentralized component.**
|
||||
|
||||
This blog post is mostly concerned with the frontend component and the different ways that IPFS enables maximizing decentralization of its distribution and trustlessness. Throughout the post, we’ll be looking at Uniswap as an example, given its importance and the amount of money it secures. That being said, the insights apply to any Dapp of this structure.
|
||||
|
||||
## Publishing dapps: approaches and trade-offs
|
||||
|
||||
### Without IPFS
|
||||
|
||||
The most naive and common approach is to just deploy the dapp to a web server or CDN like Vercel, AWS, Netlify, and Cloudflare.
|
||||
|
||||
For example, [the Uniswap team deploys](https://github.com/Uniswap/interface/actions/runs/7036990525/job/19150799879#step:11:1) their frontend to Cloudflare Pages (as well as IPFS as we'll see in the section below) and makes the latest version available at https://app.uniswap.org.
|
||||
|
||||
From the perspective of a user, this is arguably the most user-friendly and performant (with Cloudflare’s CDN), at the cost of being the least verifiable.
|
||||
|
||||
Dapp users have no way to verify that the source of the frontend matches the original code published on GitHub. Moreover, the reliance on DNS comes with risks such as fat finger human errors and other DNS attacks, e.g. DNS takeovers — these are admittedly unlikely but important to consider.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------ |
|
||||
| Verifiable | ❌ |
|
||||
| Resilience/Censorship resistance | ❌ |
|
||||
|
||||
#### At the mercy of multiple authorities
|
||||
|
||||
Another thing to consider about deploying without IPFS is that the app must comply with **the terms of service of multiple authorities**:
|
||||
|
||||
1. “.org” TLD owner
|
||||
2. “uniswap.org” DNS Registrar
|
||||
3. “uniswap.org” DNS Nameserver (when different to the registrar)
|
||||
4. Certificate Authority (CA) that provides TLS cert for https://app.uniswap.org
|
||||
5. CDN/HTTP Hosting service serves the site traffic
|
||||
6. ISP/[AS](<https://en.wikipedia.org/wiki/Autonomous_system_(Internet)>) of the HTTP Hosting provider
|
||||
|
||||
### Publishing to IPFS
|
||||
|
||||
From the perspective of a Dapp developer, publishing to IPFS is pretty straightforward. You take your frontend build and add it to your IPFS node or to a pinning service. Publishing to IPFS results in a CID which represents that version of the frontend.
|
||||
|
||||
Uniswap, for example, has automated [publishing to IPFS with Pinata](https://github.com/Uniswap/interface/actions/runs/7036990525/job/19150799879#step:8:21) as part of their build process, and they publish the CID for each version in the release:
|
||||
|
||||

|
||||
|
||||
One thing to consider here is where the CID is generated. In the ideal case, this should happen in the build process, e.g. by packing the build outputs into a CAR file with a CID in the build process. If you upload the raw files to a pinning service, you are trusting the pinning service to generate the CID for the input data.
|
||||
|
||||
To increase the resilience and censorship resistance of your deployed app, you can pin the CID to more than one pinning service or IPFS node.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------ |
|
||||
| Verifiable | 👍 |
|
||||
| Resilience/Censorship resistance | 👍 |
|
||||
|
||||
## Loading dapps from IPFS: approaches and trade-offs
|
||||
|
||||
### From a public gateway
|
||||
|
||||
With the CID of a dapp at hand, you can load the frontend from any public IPFS gateway directly in your browser, e.g.:
|
||||
|
||||
https://bafybeihwj3n7fgccypsiisijwuklg3souaoiqs7yosk5k5lc6ngnhnmnu4.ipfs.dweb.link/
|
||||
|
||||
https://bafybeihwj3n7fgccypsiisijwuklg3souaoiqs7yosk5k5lc6ngnhnmnu4.ipfs.cf-ipfs.com/
|
||||
|
||||
The problem with this approach is that you haven’t verified the response, so you don’t know if you the response **matches the CID.** In effect, you are **trusting the gateway** to return the correct response.
|
||||
|
||||
Another minor challenge that arises is that each version you load and each gateway you load it from will have a different origin, so any local state the dapp relies on in localStorage or IndexedDB will be tied to that specific version of the dapp (CID) at that specific gateway, i.e., `bafy1.ipfs.cf-ipfs.com` is a different origin to `bafy1.ipfs.dweb.link` even though they are the same CID.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------------------- |
|
||||
| Verifiable | ❌ |
|
||||
| Resilience/Censorship resistance | 👍 (other gateways) |
|
||||
|
||||
> **Note:** Resilience depends on whether the content has been cached and the number of providers/copies on the network
|
||||
|
||||
Note that some Dapp developers will run their own dedicated gateways either on their infrastructure or by using a dedicated gateway service, e.g. Pinata, Filebase. This can result in better performance. As for trust, it shifts it around, and without verification, the users are left to decide whether they trust the gateway operator.
|
||||
|
||||
### With a local IPFS node
|
||||
|
||||
If you have a local IPFS node installed, e.g. [Kubo](https://docs.ipfs.tech/install/command-line/) or [IPFS Desktop](https://docs.ipfs.io/install/ipfs-desktop/), then you can use the IPFS gateway exposed by your local node. It looks as follows: http://bafybeihwj3n7fgccypsiisijwuklg3souaoiqs7yosk5k5lc6ngnhnmnu4.ipfs.localhost:8080/
|
||||
|
||||
Note that it will only work if you are running an IPFS node with the gateway listening on port 8080)
|
||||
|
||||
When you open this URL, the local IPFS node will handle content routing (finding providers for the CID), fetching the content, and verification.
|
||||
|
||||
The main hurdle with this approach is that it requires running an IPFS node in addition to typing a long URL. But you get the full benefits of **verifiability. The only thing you need to trust is the CID you received is indeed the one published by Uniswap.**
|
||||
|
||||
From a performance perspective, it may be slow on the first load, but once fetched and cached locally, a given CID will essentially load instantly.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------ |
|
||||
| Verifiable | 👍 |
|
||||
| Resilience/Censorship resistance | 👍 |
|
||||
|
||||
(Depends on whether the gateway has it cached and the number of providers/copies on the network)
|
||||
|
||||
### With a local IPFS node & IPFS Companion browser extension
|
||||
|
||||
[IPFS Companion](https://docs.ipfs.tech/install/ipfs-companion/) is a browser extension that simplifies access to IPFS resources and adds browser support for the IPFS protocol. It allows you to type IPFS protocol URLs, i.e., `ipfs://bafy...` directly in the browser, thereby improving the UX.
|
||||
|
||||
Under the hood, IPFS companion handles IPFS URLs and redirects them to the gateway of the local IPFS node.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------ |
|
||||
| Verifiable | 👍 |
|
||||
| Resilience/Censorship resistance | 👍 |
|
||||
|
||||
IPFS Companion also supports [DNSLink](https://dnslink.dev/) resolution (DNSLink is covered in more detail at the bottom of the article). When a user visits a URL, Companion will check for a [DNSLink](https://dnslink.dev/) DNS record for the hostname and, if found, will load the dapp from the local gateway instead of the remote origin. In this instance, trust is only delegated for the DNS resolution (hostname → CID).
|
||||
|
||||
### With the Brave browser
|
||||
|
||||
[Brave Browser](https://brave.com/ipfs-support/) comes with native support for IPFS URLs that can be resolved by a public gateway or the built-in IPFS node. The latter is practically the same as the previous approach with a local IPFS node and the IPFS companion browser extension, though the user experience is better because it works out of the box.
|
||||
|
||||
| | Rating |
|
||||
| -------------------------------- | ------ |
|
||||
| Verifiable | 👍 |
|
||||
| Resilience/Censorship resistance | 👍 |
|
||||
|
||||
## When running a Kubo node is not an option
|
||||
|
||||
All the previous examples that are verifiable depend on the user running an IPFS node, typically Kubo, a Go-based implementation of IPFS that runs as a separate process to the browser. Having a separate process frees you from the constraints imposed by browsers and affords more resources for the node to establish more connectivity to other IPFS nodes.
|
||||
|
||||

|
||||
|
||||
**However, running a Kubo node comes at the cost of a higher barrier to adoption, and in the case of mobile phones, is not an option.**
|
||||
|
||||
## What if content addressing were native to the web?
|
||||
|
||||
In an ideal world, content addressing would be native to the web, but what could that look like?
|
||||
|
||||
Content addressing is a paradigm shift to security on the web that is rooted in the same-origin policy. In many ways, this requires a reimagining of parts of the web which is beyond the scope of this post (though if you’re interested, check out Robin Berjon’s work on the [Web Tiles](https://berjon.com/web-tiles/).)
|
||||
|
||||
Browser vendors tend to be defensive about adding new browser APIs and implementing specs for a myriad of reasons: maintenance burden, security risks, and lack of financial incentive.
|
||||
|
||||
At a minimum, native IPFS support would involve the ability for the web browser itself to verify the integrity of content-addressed sites. A glimpse into that future is presented by `ipfs://` and `ipns://` in [Brave](https://brave.com/ipfs-support/) and [ipfs-chromium](https://github.com/little-bear-labs/ipfs-chromium/). It may arrive sooner in mainstream browsers if WebExtensions like [IPFS Companion](https://github.com/ipfs/ipfs-companion) can [register a protocol handler that is backed by a Service Worker](https://github.com/ipfs/in-web-browsers/issues/212).
|
||||
|
||||

|
||||
|
||||
Since it will likely take time to come to fruition, the next section below will cover the pragmatic interim approaches to in-browser verified retrieval of CIDs.
|
||||
|
||||
## In-browser verified retrieval of CIDs
|
||||
|
||||
To understand the emerging landscape of approaches to IPFS in the browser, it’s crucial to first understand some of the inherent constraints of the browser.
|
||||
|
||||
### Browser constraints
|
||||
|
||||
Browsers are sandboxed runtime environments that place critical constraints for using IPFS:
|
||||
|
||||
- Limits on the type (WebSockets, WebRTC, WebTransport) and number of connections a browser tab can open and/or [fail to dial before being blocked or throttled](https://github.com/ipfs/in-web-browsers/issues/211). This can hinder content routing DHT traversals and content retrieval connections.
|
||||
- If a website is in a [secure context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts) when served over HTTPS, like most websites today, you are constrained to only opening connections to origins with a CA-signed TLS certificate, something that peers in the IPFS network rarely have. As you’ll see, there are two exceptions to this, namely WebTransport and WebRTC, that we’ll look into in the next section.
|
||||
- Limits on the resources an inactive browser tab consumes, i.e., when you keep a tab open but it becomes inactive by moving to a different tab.
|
||||
|
||||
### Approaches to IPFS in the browser
|
||||
|
||||
From a high level, several threads of work remove the need to run a Kubo node:
|
||||
|
||||
- [**Trustless Gateway**](https://specs.ipfs.tech/http-gateways/trustless-gateway/): a *subset* of the [path-gateway](https://specs.ipfs.tech/http-gateways/path-gateway/) that allows for light IPFS clients to retrieve both the CIDs bytes and verification metadata (the Merkle DAG), thereby allowing you to [verify its integrity without trusting the gateway](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval).
|
||||
- [Delegated routing](https://docs.ipfs.tech/concepts/how-ipfs-works/#how-content-routing-works-in-ipfs): a mechanism for IPFS implementations to use for [offloading content routing, peer routing, and naming to another server over HTTP](https://specs.ipfs.tech/routing/http-routing-v1/). This allows browsers to skip traversing the DHT and opening many connections in the process.
|
||||
- [WebTransport](https://connectivity.libp2p.io/#webtransport): a new browser API to open persistent duplex connections from the browser in a similar fashion to WebSockets. But in contrast with WebSocket, [WebTransport supports self-signed certificates](https://connectivity.libp2p.io/#webtransport?tab=certificate-hashes), allowing its use in a p2p setting without reliance on certificate authorities. WebTransport support was also added to Kubo over a year ago, which in theory means that browsers should be able to connect to any arbitrary Kubo node even in a [Secure Context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts).
|
||||
- WebRTC Direct: though WebRTC was designed for browser-to-browser, it can also be used for [browser-to-server connectivity](https://connectivity.libp2p.io/#webrtc?tab=browser-to-standalone-node) without trusted TLS certificates (see [spec](https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md)). This is useful in browsers like Safari and Firefox where WebTransport might not be available (as of Q1 2024).
|
||||
- [Service Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API): a browser API that allows, among other things, intercepting network requests in web applications for either caching or providing offline functionality. Service workers can be used to implement a caching and verification layer by intercepting HTTP requests to IPFS gateways in existing apps that already use IPFS gateways without verifying.
|
||||
|
||||
[**Helia**](https://helia.io/) is where most of the active work is happening and implements many of these approaches for better IPFS support in the browser.
|
||||
|
||||
### Helia and IPFS in the browser
|
||||
|
||||
[Helia](https://github.com/ipfs/helia) is a lean, modular TypeScript implementation of IPFS that can run in server JS runtimes, e.g. Node.js and Deno, as well as in the browser. To explain browser-specific use-cases, this section will focus solely on **Helia in the browser.**
|
||||
|
||||
From a high level, Helia can do two main things in the browser:
|
||||
|
||||
- **Manage content-addressed data:** serializing user input and objects into content-addressable representation like dag-json or UnixFS (typically referred to as codecs in IPLD land), and packing CAR files.
|
||||
- **Verified retrieval of CIDs**: e.g. given a CID, find providers for it, fetch it and verify the data for it. Helia can retrieve CIDs using both [Bitswap](https://specs.ipfs.tech/bitswap-protocol/) (over libp2p) and the [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) (over HTTPS).
|
||||
|
||||
> **Note:** the short-lived nature of a browser tab makes it **unsuitable for providing CIDs to the network**. Even though in theory, Helia is capable of this, it's not recommended. The most practical approach to publishing CIDs from the browser is to delegate that to a long-running IPFS node, either by uploading directly to a [pinning service](https://docs.ipfs.tech/concepts/persistence/#pinning-services) or uploading CIDs to a self-hosted IPFS node.
|
||||
|
||||
### Verifying top-level pages, sub-resources, and async data
|
||||
|
||||
An important distinction to make in web applications is between top-level pages, sub-resources, and async resources and how they can be verified:
|
||||
|
||||
- **Top-level pages** refers initial HTML payload that is returned to the first request by the browser to a given address and bootstraps the loading of an app. For example, the `index.html` file in a given version of the IPFS website: [bafybeidfqp36qutohidaaapir743mvjefv5ipkbrvqx3li3x6vm47vrdam](https://explore.ipld.io/#/explore/bafybeidfqp36qutohidaaapir743mvjefv5ipkbrvqx3li3x6vm47vrdam/index.html).
|
||||
**Verification:** as discussed above, this is currently only possible with a local IPFS node that does top level verification when you load a CID via the local gateway, i.e. `cid.ipfs.localhost:8080`.
|
||||
- **Sub-resources** refer to resources loaded after the initial HTML of the page was loaded, like a JS, CSS, and image files files that are included in script tags of the initial HTML. These resources may be from the same or other origins (unless explicitly prohibited by the [Content security policy](https://web.dev/articles/csp) set by the server).
|
||||
**Verification:** Either by loading the top level CID from a local gateway and ensuring that sub-resources are also loaded from the local node by using relative path.
|
||||
Another way relies on a feature called [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) that ensures the browser verifies the hash of `<script>` and `<link>` elements with the integrity attribute, however, this has limited utility for CIDs since the SHA256 hash matches the hash in the CID only if the resources were encoded with raw leaves and fit into a single IPFS Block; because [IPFS chunks files before hashing and may result in different hashes](https://docs.ipfs.tech/concepts/faq/#why-doesn-t-my-sha-hash-match-my-cid).
|
||||
Another way, which is explored in more detail below, is to abstract much of the verification and fetching of CIDs into service workers, which allows you to intercept network requests and verify resources.
|
||||
- **Async data** refers to data that is fetched asynchronously during the runtime of the app with the `fetch` API, e.g. JSON returned from an API.
|
||||
**Verification:** possible by using Helia or one of the abstractions on top of Helia to fetch CIDs. Like sub-resources, this can be abstracted into a service worker, so that the application code is just making fetch requests to relative path style gateways, e.g. `/ipfs/[CID]` in the app.
|
||||
|
||||
ℹ️ **Today, Helia can fetch and verify async data and sub-resources. However, top-level verification without deeper browser integration remains an open engineering problem that the [IPFS Dapps working group](https://ipfs.fyi/dapps-wg) is working on.**
|
||||
|
||||
### Verified retrieval data with Helia
|
||||
|
||||
Let’s look at a real-world example, and how you could add Helia (or another library) to add verification. The Uniswap frontend makes a bunch of trusted async fetch requests to the Cloudflare IPFS gateway without verifying the response.
|
||||
|
||||
One of them is to the following URL: `https://cloudflare-ipfs.com/ipns/tokens.uniswap.org` whose response is a JSON object of the tokens supported by Uniswap. This URL contains a [DNSlink](#dnslink) (which is covered in more detail below) to resolve to a CID. For the sake of simplicity, let's assume that we already have the resolved CID: `bafybeia5ci747h54m2ybc4rf6yqdtm6nzdisxv57pk66fgubjsnnja6wq4`.
|
||||
|
||||
The code for fetching this token list JSON from a trusted gateway looks along the lines of :
|
||||
|
||||
```jsx
|
||||
const fetchJsonFromGateway = async (url) => {
|
||||
const response = await fetch(url)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('failed to fetch')
|
||||
}
|
||||
|
||||
json = await response.json()
|
||||
|
||||
return json
|
||||
}
|
||||
|
||||
const tokenListUrl = `https://cloudflare-ipfs.com/ipfs/bafybeia5ci747h54m2ybc4rf6yqdtm6nzdisxv57pk66fgubjsnnja6wq4`
|
||||
const tokenList = await fetchJsonFromGateway(tokenListUrl)
|
||||
```
|
||||
|
||||
With Helia, fetching and verifying the CID could look as follows:
|
||||
|
||||
```ts
|
||||
import { createHeliaHTTP } from '@helia/http'
|
||||
import { CID } from 'multiformats'
|
||||
import { unixfs } from '@helia/unixfs'
|
||||
|
||||
const verifiedFetch = async (cid: string) => {
|
||||
const helia = await createHeliaHTTP()
|
||||
const fs = unixfs(helia)
|
||||
|
||||
const decoder = new TextDecoder()
|
||||
let unparsedJson = ''
|
||||
|
||||
for await (const chunk of fs.cat(CID.parse(cid))) {
|
||||
unparsedJson += decoder.decode(chunk, {
|
||||
stream: true,
|
||||
})
|
||||
}
|
||||
|
||||
return JSON.parse(unparsedJson)
|
||||
}
|
||||
|
||||
const tokenListCid = `bafybeia5ci747h54m2ybc4rf6yqdtm6nzdisxv57pk66fgubjsnnja6wq4`
|
||||
const tokenList = await verifiedFetch()
|
||||
```
|
||||
|
||||
The example above is more convoluted than necessary because the JSON is encoded as UnixFS, which is the default encoding for files and directories in IPFS. When working with JSON, it's better to to encode the data with one of `json`, `dag-json`, or `dag-cbor` codecs which are more suitable and provide better ergonomics for working with JSON data.
|
||||
|
||||
To demonstrate, here's an example with the same token list JSON encoded as `json` which has the CID `bagaaieracglt4ey6qsxtvzqsgwnsw3b6p2tb7nmx5wdgxur2zia7q6nnzh7q`
|
||||
|
||||
```ts
|
||||
import { CID } from 'multiformats'
|
||||
import { createHeliaHTTP } from '@helia/http'
|
||||
import { json } from '@helia/json'
|
||||
|
||||
const fetchJsonCid = async (cid: string) => {
|
||||
const helia = await createHeliaHTTP()
|
||||
const j = json(helia)
|
||||
|
||||
return await j.get(CID.parse(cid))
|
||||
}
|
||||
|
||||
const tokenListCid = `bagaaieracglt4ey6qsxtvzqsgwnsw3b6p2tb7nmx5wdgxur2zia7q6nnzh7q`
|
||||
const tokenList = await fetchJsonCid(tokenListCid)
|
||||
```
|
||||
|
||||
See how these two compare below:
|
||||
|
||||
<iframe src="https://codesandbox.io/embed/qx7tw3?view=Editor+%2B+Preview&module=%2Fsrc%2Findex.ts"
|
||||
style="width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="helia-json-vs-unixfs-fetch (@helia/http@1)"
|
||||
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||
></iframe>
|
||||
|
||||
This is more involved than the `fetch` API, but comes with all the benefits of IPFS: data is verified and can be fetched from more than one gateway, thereby increasing resilience.
|
||||
|
||||
### Making Helia lighter and developer-friendly
|
||||
|
||||
To make it easier for developers to adopt Helia in dapps that lean heavily on gateways, we've been working on a couple of improvements:
|
||||
|
||||
- [Configurable block brokers](https://github.com/ipfs/helia/pull/280): a generic interface for resolving CIDs to blocks. Allows developers to choose (and even implement their own) block fetching approach for their app, e.g. Trustless Gateways, Bitswap, or a combination of the two. [Released in Helia v2.1.0](https://github.com/ipfs/helia/releases/tag/helia-v2.1.0)
|
||||
- [@helia/http](https://github.com/ipfs/helia/issues/289): A browser optimised version of Helia that leans on trustless gateways and delegated routing to enable verified retrieval. This was the package that was used in the examples above.
|
||||
- [@helia/verified-fetch](https://github.com/ipfs/helia/issues/348): A library that would provide a similar interface to the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and accept native `ipfs://` and `ipns://` URIs and function like an IPFS gateway. We intend for it to serve as a drop-in replacement for `fetch` requests to trusted gateways.
|
||||
|
||||
### Helia in a Service Worker
|
||||
|
||||
Another thread of work involves a [Service Worker](https://github.com/w3c/ServiceWorker/blob/main/explainer.md) registered by the app that intercepts CID requests to gateways (that are unverified) and uses Helia to fetch and verify. This works for sub-resources and async data and assumes that the app already fetches CIDs from a trusted IPFS gateway, e.g. `fetch('/ipfs/[CID]')...` , because they can be detected and handled by the service worker.
|
||||
|
||||
From a technical perspective, the service worker is tied to the app’s origin and registered by the app’s code. Helia is imported and handles CID requests by fetching the raw blocks of the requested CID from trustless gateways (or directly from peers with supported transports), verifying, and caching.
|
||||
|
||||
It’s worth noting that caching is one of the primary reasons that service workers allow intercepting HTTP requests. Since CIDs are immutable, they make for an easy cache.
|
||||
|
||||
The benefit of this approach is that it can be adopted by apps that already rely on trusted gateways without significant architectural changes.
|
||||
|
||||
Check out the [Helia service worker gateway repo](https://github.com/ipfs-shipyard/helia-service-worker-gateway) to learn more about this approach or try it out on https://helia-service-worker-gateway.on.fleek.co/.
|
||||
|
||||
### Local app installer
|
||||
|
||||
The local app installer approach was recently laid out in a [blog post](https://www.liquity.org//blog/decentralizing-defi-frontends-protecting-users-and-protocol-authors) by the Liquity team. The idea is that you have a static web app that serves as a local installer which facilitates the fetching and verifying of dapps directly in the browser. The [local app installer](https://github.com/edmulraney/nohost) consists of PWA and utilizes a service worker with the ENS client library and Helia to resolve ENS names, download and verify dapps and cache them locally. The local app installer is developed in the [nohost](https://github.com/edmulraney/nohost) repository.
|
||||
|
||||

|
||||
|
||||
Top level integrity remains a challenge for verifying the initial installer PWA code. To address this, the Liquity team is exploring packaging the installer as part of a browser extension.
|
||||
|
||||
It’s worth pointing out that in this approach, each locally installed dapp must still be isolated into its own origin. The challenge here is that the initial payload (for the first load) for each origin, must still come from somewhere, i.e. a trusted server. Following initial payload, the frontend must only be fetched and verified once because it’s locally cached by the service worker.
|
||||
|
||||
For this reason, along with the inherent challenges of the web security model laid out earlier in this post, it’s useful to think about trust as a spectrum. In this approach trust is minimised to the initial interaction. To delve deeper into this approach, check out Liquity’s blog [post](https://www.liquity.org/blog/decentralizing-defi-frontends-protecting-users-and-protocol-authors).
|
||||
|
||||
## Most users don’t use CIDs directly
|
||||
|
||||
For the sake of simplicity, we assumed throughout this post that the starting point for a user is a CID, but in reality, this is rarely the case.
|
||||
|
||||
CIDs are long and not very human-readable, so they tend to be abstracted from the user. Moreover, because CIDs represent an immutable version of the frontend, giving users the latest versions requires something like a persistent address that can be updated upon every release.
|
||||
|
||||
## Naming systems and mutable pointer
|
||||
|
||||
There are three common approaches to this problem that provide a **stable identifier** that can change upon version releases. The following is a high level comparison:
|
||||
|
||||
- **DNSLink**
|
||||
- **What are they:** A DNS TXT record points to a specific CID.
|
||||
- **Human friendly:** 👍
|
||||
- **Verifiable:** 👎
|
||||
- **Example name:** [`blog.ipfs.tech`](http://blog.ipfs.tech) (technically `_dnslink.blog.ipfs.tech`)
|
||||
- **Integration with the IPFS:** through IPFS gateways under the `/ipns` namespace: [`ipfs.io/ipns/blog.ipfs.tech/`](http://ipfs.io/ipns/DNS.NAME) or using subdomain resolution: [`https://blog-ipfs-tech.ipns.cf-ipfs.com/`](https://blog-ipfs-tech.ipns.cf-ipfs.com/)
|
||||
- **Ethereum Name System** (**ENS):**
|
||||
- **What are they:** records for a `.ETH` name are stored on-chain and can point to any URL or CID, e.g. `ipfs://bafy...`
|
||||
- **Human friendly:** 👍
|
||||
- **Verifiable:** Potentially
|
||||
- **Example name:** `vitalik.eth`
|
||||
- **Integration with the IPFS:**
|
||||
- **IPFS path gateways:** under the `/ipns` namespace: [ipfs.io/ipns/vitalik.eth](http://ipfs.io/ipns/vitalik.eth)`
|
||||
- **Subdomain gateways:** subdomain resolution (dots become dashes): [vitalik-eth.ipns.dweb.link](https://vitalik-eth.ipns.dweb.link/)
|
||||
- Using an ENS resolver like [eth.link](http://eth.link) or eth.limo: [vitalik.eth.limo](https://vitalik.eth.limo)
|
||||
- **IPNS**
|
||||
- **What are they:** mutable pointers based on public keys and signed IPNS records pointing to a CID. Typically published to the DHT, though IPNS is transport agnostic and can be resolved and advertised using the delegated routing HTTP API.
|
||||
- **Human friendly:** 👎
|
||||
- **Verifiable:** 👍
|
||||
- **Example name:** `k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s`
|
||||
- **Integration with the IPFS:** through IPFS gateways
|
||||
- Path resolution: `https://cloudflare-ipfs.com/ipns/k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s`
|
||||
- Subdomain resolution : `https://k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s.ipns.dweb.link/`
|
||||
|
||||
Some of these approaches can be combined, and there are some crucial security implications to each of the approaches and the way they are implemented.
|
||||
|
||||
In the next paragraph, we’ll dive into the details and trade-offs of how each of these approaches.
|
||||
|
||||
### DNSLink
|
||||
|
||||
[DNSLink](https://dnslink.dev/) uses DNS [TXT](https://en.wikipedia.org/wiki/TXT_record) records in the `_dnslink` subdomain to map a DNS name, such as `blog.ipfs.tech` to an IPFS path, e.g. `/ipfs/bafy..`
|
||||
|
||||
The main benefit of DNSLink is that it relies on all existing DNS infrastructure and tooling to provide stable human-friendly names that can be updated. The main drawback of DNSLink is that it comes with the same risks and attack surface associated with DNS records mentioned earlier in the post, most notably is the lack of verifiability. This can potentially be addressed by things like DNSSec and querying multiple DNS resolvers.
|
||||
|
||||
For example, the Spark UI from the MakerDAO ecosystem is published to IPFS and uses DNSLink. Their DNSLink TXT record is `_dnslink.app.spark.fi` and has the value set to (at the time of writing):
|
||||
|
||||
`dnslink=/ipfs/bafybeihxc3olye3k2z4ty6ete7qe6mvtplq52ixpqgwkaupqxwxsmduscm`
|
||||
|
||||
DNSLinks can be resolved in a browser in ways:
|
||||
|
||||
- Using an IPFS gateway, under the ipns namespace, e.g. [ipfs.io/ipns/blog.ipfs.tech/](http://ipfs.io/ipns/DNS.NAME) or to ensure origin isolation, with the subdomain gateway would be [https://blog-ipfs-tech.ipns.dweb.link](https://blog-ipfs-tech.ipns.dweb.link/). (when using the subdomain gateway, dots are converted to dashes to avoid origin and TLS certificate complexity).
|
||||
- Directly with the DNS name when its pointing to an IPFS Gateway. The IPFS gateway will resolve the DNSLink based on the `host:` header, e.g. https://app.spark.fi/.
|
||||
|
||||
### Ethereum Name System (ENS)
|
||||
|
||||
ENS is a crypto native on-chain domain registry. Records for a `.ETH` namespace can be purchased and configured on-chain, by interacting with the ENS smart contracts.
|
||||
|
||||
Each ENS name can have multiple records to link different profiles, e.g. GitHub, Twitter, and IPFS CIDs. The `contenthash` field can be used to point to a `ipfs://bafy...` URL, as specified [ENSIP-7](https://docs.ens.domains/ens-improvement-proposals/ensip-7-contenthash-field).
|
||||
|
||||
While ENS has a lot of similarities with DNS, like the dot-separated hierarchical structure, it is a fundamentally different system. Most notably, `.eth` is not a valid TLD in DNS, which means that it doesn’t natively resolve in most browsers.
|
||||
|
||||
To address this challenge, several solutions have emerged to allow easily resolving `.eth` domains in the browser:
|
||||
|
||||
- Cloudflare operates [eth.link](http://eth.link), which allows resolving ENS names with a content hash by appending `.link` to the ENS name. For example, [vitalik.eth.link](http://vitalik.eth.link) will load the content hash set on `vitalik.eth`.
|
||||
Under the hood, eth.link uses EthDNS to access information from ENS via DNS. In other words, it provides a DNS interface to the on-chain ENS registry. eth.link also provides a [DNS-over-HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS) endpoint to perform DNS resolution of .eth records: `https://eth.link/dns-query`. For example, `curl -s -H "accept: application/dns-json" "https://eth.link/dns-query?name=vitalik.eth&type=TXT"` will return the ENS records of `vitalik.eth`.
|
||||
- [Eth.limo](http://Eth.limo) is a similar service to [eth.link](http://eth.link) that functions similarly, e.g. [vitalik.eth.limo](http://vitalik.eth.limo).
|
||||
- Using an IPFS gateway, under the `ipns` namespace, e.g. [ipfs.io/ipns/vitalik.eth](http://ipfs.io/ipns/vitalik.eth) (path resolution) or [vitalik-eth.ipns.dweb.link](http://vitalik-eth.ipns.dweb.link) for subdomain resolution (when using the subdomain gateway, dots are converted to dashes to avoid origin and TLS certificate complexity).
|
||||
Under the hood, the IPFS gateway treats these the same way as DNSLink, but resolves `.eth` TLD via special ENS2DNS bridges (the default one is DoH at `resolver.cloudflare-eth.com`, [configurable in Kubo](https://github.com/ipfs/kubo/blob/master/docs/config.md#dnsresolvers)).
|
||||
- The Metamask browser plugin will automatically redirect .eth addresses to an IPFS gateway, as described above.
|
||||
- The Brave browser supports `.eth` domains and resolves them using the Cloudflare EthDNS resolver.
|
||||
|
||||
#### Verifiability of ENS
|
||||
|
||||
The fact that ENS domains are registered is on-chain makes them verifiable in principle. However, in the solutions laid out above, trust is delegated to a trusted server which handles the resolution of the ENS name to the CID, e.g. [eth.limo](http://eth.limo), or the DoH resolver at https://resolver.cloudflare-eth.com/dns-query.
|
||||
|
||||
ENS names can be resolved in the browser using the Ethereum RPC API by retrieving the state from the chain, howerver, trust is just shifted to the Ethereum RPC API endpoint.
|
||||
|
||||
A more verifiable approach would be to use an Ethereum light client, like [Helios](https://github.com/a16z/helios) or [eth-verifiable-rpc](https://github.com/dappnetbby/eth-verifiable-rpc), to verify ENS state using merkle proofs and the Ethereum state root hash, though this is still experimental and far from a common pattern in dapps.
|
||||
|
||||
### IPNS
|
||||
|
||||
IPNS is a system for creating [cryptographically verifiable mutable pointers](https://specs.ipfs.tech/ipns/ipns-record/) to CIDs known as **IPNS names**, for example, [`k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s`](https://cid.ipfs.tech/#k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s) is a base36-encoded IPNS name with its public key in-line. The public key can be used to verify corresponding IPNS records, which point to a CID and are signed by the private key. In other words, an IPNS name can be thought of as stable link that can be updated over time.
|
||||
|
||||
IPNS names are key pairs that are not human-friendly (like DNS and ENS), so while they offer a stable pointer that can change over time, you still need to get the IPNS name from _somewhere_.
|
||||
|
||||
A pretty common pattern is for ENS names to point to an IPNS name. Since updating ENS names requires paying gas for the on-chain transaction, this can be avoided by pointing the ENS name to an IPNS name, and updating the IPNS name to a new CID, upon new releases or updates.
|
||||
|
||||
Like CIDs, IPNS names can be resolved using IPFS gateways, either in a [verifiable](https://specs.ipfs.tech/http-gateways/trustless-gateway/#ipns-record-responses-application-vnd-ipfs-ipns-record) or trusted way. Trusted resolution is as simple as adding the name to the URL: `https://cloudflare-ipfs.com/ipns/k51qzi5uqu5dhp48cti0590jyvwgxssrii0zdf19pyfsxwoqomqvfg6bg8qj3s`. Verified IPNS resolution is a bit [more involved](https://specs.ipfs.tech/ipns/ipns-record/#record-verification), but can be done end-to-end with Helia in the browser as follows:
|
||||
|
||||
<iframe src="https://codesandbox.io/embed/f59ttx?view=Editor+%2B+Preview&module=%2Fsrc%2Findex.ts"
|
||||
style="width:100%; height: 500px; border:0; border-radius: 4px; overflow:hidden;"
|
||||
title="Helia-ipns"
|
||||
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||
></iframe>
|
||||
|
||||
## Conclusion
|
||||
|
||||
If you reached this far, congratulations. Hopefully, this blog post gave you an overview of the state of dapps on IPFS and the ongoing efforts to make verified retrieval of CIDs the norm.
|
||||
|
||||
While trust remains central to the web, leaning on the verifiability of CIDs is a net win for both dapp developers and users.
|
||||
|
||||
As we make more progress on the [`@helia/verified-fetch`](https://github.com/ipfs/helia/pull/392) library, we will publish more guides and examples demonstrating its broad applicability in dapps.
|
||||
|
||||
If you’re a dapp developer or user using IPFS, your input is valuable. We invite you to join the [IPFS Dapps Working Group](https://ipfs.fyi/dapps-wg) and help us shape the future of dapps on IPFS.
|
||||
@@ -4,7 +4,6 @@ permalink: '/2021-01-21-how-we-put-ipfs-in-brave/'
|
||||
translationKey: ''
|
||||
tags:
|
||||
- browsers
|
||||
- brave
|
||||
header_image: '/2021-01-21-how-we-put-ipfs-in-brave.jpg'
|
||||
title: How we put IPFS in Brave
|
||||
description:
|
||||
|
||||
@@ -11,9 +11,6 @@ tags:
|
||||
- CID
|
||||
|
||||
---
|
||||
|
||||
**Update (2024Q1): This is an old blogpost. [Reframe was deprecated in 2022](https://github.com/ipfs/kubo/issues/9479) and ecosystem replaced it with modern [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) (`/routing/v1`) which is also [supported by Kubo](https://github.com/ipfs/kubo/blob/master/docs/delegated-routing.md) and [Someguy](https://github.com/ipfs-shipyard/someguy).**
|
||||
|
||||
[kubo v0.14.0 added support](https://github.com/ipfs/kubo/releases/tag/v0.14.0#delegated-routing) for the [Reframe protocol](https://github.com/ipfs/specs/tree/main/reframe#readme), which enables users to configure how their kubo node discovers content, peers, and handles IPNS records by just adding an HTTP endpoint to their config file. This means if you have a new content routing system you’d like to try out next to, or instead of, the IPFS Public DHT it’s now simple to do so. Similarly, Reframe starts enabling applications like public IPFS HTTP Gateways to decouple their DHT nodes from their content serving nodes so that they can be scaled and load-balanced independently.
|
||||
|
||||
You can see more information and a demo utilizing Reframe in this [presentation](https://www.youtube.com/watch?v=lpphD7OJ28U&list=PLuhRWgmPaHtSF3oIY3TzrM-Nq5IU_RTXb) from IPFS Thing 2022.
|
||||
@@ -168,6 +165,4 @@ For example, support for querying the endpoint at [cid.contact](http://cid.conta
|
||||
|
||||
See [https://github.com/ipfs/kubo/blob/master/docs/config.md#routing](https://github.com/ipfs/kubo/blob/master/docs/config.md#routing "https://github.com/ipfs/kubo/blob/master/docs/config.md#routing") for more details.
|
||||
|
||||
Note: further work to homogenize routing configuration across the multiple routing systems used in Kubo including the IPFS Public DHT and various Reframe endpoints is happening [here](https://github.com/ipfs/kubo/issues/9150).
|
||||
|
||||
**Update (2024Q1):** [Reframe was deprecated in 2022](https://github.com/ipfs/kubo/issues/9479) and ecosystem replaced it with modern [Delegated Routing V1 HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) (`/routing/v1`) which is also [supported by Kubo](https://github.com/ipfs/kubo/blob/master/docs/delegated-routing.md) and [Someguy](https://github.com/ipfs-shipyard/someguy).
|
||||
Note: further work to homogenize routing configuration across the multiple routing systems used in Kubo including the IPFS Public DHT and various Reframe endpoints is happening [here](https://github.com/ipfs/kubo/issues/9150).
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
title: Announcing the IPFS Camp 2024 Track List
|
||||
description: "To give you a taste of what kinds of topics IPFS Camp will cover this year, we’re excited to share the 2024 track list!"
|
||||
date: 2024-04-11
|
||||
permalink: "/ipfs-camp-2024-track-list"
|
||||
header_image: "/ipfs-camp-2024.png"
|
||||
tags:
|
||||
- camp
|
||||
---
|
||||
|
||||
IPFS Camp 2024 is back this summer! It will take place on July 11-13 in Brussels, Belgium alongside EthCC and today we’re announcing a track list so hip you’ll be grooving just reading the headlines. Three days workshops, discussion circles, hacking time, and more — all focused on connecting builders and users to make the internet more sustainable, democratic, and secure.
|
||||
|
||||
Excited? Don’t just [register today](https://2024.ipfs.camp/), also go [submit a talk](https://airtable.com/appM094R1Ma5HG757/shrWn6XaRgUkYWPm3)! We’d love to hear from you! (Yes, *you*!)
|
||||
|
||||
<a href="https://2024.ipfs.camp/" class="cta-button">Register Today</a>
|
||||
|
||||
|
||||
## 2024 Track List
|
||||
|
||||
### Opening Keynotes
|
||||
A warm and wonderful kickoff to IPFS Camp with keynote speakers, fireside chats, and a smörgåsbord of community talks and perspectives on the present and future of IPFS.
|
||||
|
||||
### Decentralized Apps and Publishing
|
||||
Explore the latest tools, frameworks, and best practices for building and deploying dApps that are resilient, fully decentralized, hard to phish, and respect people’s privacy.
|
||||
|
||||
### Public Records and Human Rights
|
||||
Discover how IPFS is being used to protect public records, to authenticate pictures online, and support human rights initiatives worldwide.
|
||||
|
||||
### AI in 2024: Ethics, Ownership, and Data
|
||||
In this track, we'll explore urgent topics of attribution, ethics, and payment in the age of AI-generated art, music, and text. Then, we’ll dive into how content-addressed data forges new opportunities for creators and developers.
|
||||
|
||||
### Climate Resilience and IPFS
|
||||
In the face of the growing climate crisis, reliable and transparent environmental data is more crucial than ever. This track explores real-world applications of IPFS in environmental monitoring, climate modeling, and disaster response.
|
||||
|
||||
### Syncing Bytes at Scale
|
||||
Dive into the latest techniques and tools for efficiently syncing bytes at scale with IPFS. Learn how to optimize data transfer, ensure data integrity, and reduce bandwidth costs. Whether you're working with scientific, media, or enterprise data — or any kind of large-scale data whatsoever to be honest, it’s all about the bytes — this track has something for you.
|
||||
|
||||
### Libp2p Day
|
||||
Join us for a full day dedicated to libp2p, the modular networking stack that powers IPFS, Ethereum, and other decentralized protocols. Learn about the latest developments in libp2p, including new transports, improved NAT traversal, and enhanced security features. Hear from the core developers and researchers behind libp2p, and discover how you can use this powerful library to build your own networks and applications.
|
||||
|
||||
### IPLD, Databases, and the People Who Love Them
|
||||
Meet the passionate developers and researchers pushing the boundaries of what's possible with IPLD. Learn how experts use IPLD to build more efficient, interoperable databases and data structures, and join the efforts to push IPLD forward.
|
||||
|
||||
### Startup Showcase
|
||||
Lightning talks from projects and startups using IPFS to solve real-world problems, plus roundtables on how to solve shared challenges.
|
||||
|
||||
<a href="https://2024.ipfs.camp/" class="cta-button">Register Today</a>
|
||||
|
||||
[Submit a talk](https://airtable.com/appM094R1Ma5HG757/shrWn6XaRgUkYWPm3)
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
date: 2024-10-07
|
||||
permalink: /ipfs-check/
|
||||
title: 'Improved Debugging with IPFS Check'
|
||||
description: 'IPFS Check is a debugging tool for IPFS Mainnet. It helps you check if data is routable and retrievable by CID on IPFS Mainnet.'
|
||||
author: Daniel Norman
|
||||
header_image: /ipfs-check-cover.jpg
|
||||
tags:
|
||||
- ipfs
|
||||
- cid
|
||||
- debugging
|
||||
- ipni
|
||||
- dht
|
||||
---
|
||||
|
||||
## 🎉 Improved retrievability debugging with IPFS Check
|
||||
|
||||
The [Shipyard team](https://ipshipyard.com/) is thrilled to share an overhauled version of [IPFS Check](https://check.ipfs.network), a debugging tool for the [IPFS Mainnet](https://docs.ipfs.tech/concepts/glossary/#mainnet) public network. This new version is both simpler to use and more powerful.
|
||||
|
||||
Try it out at [check.ipfs.network](https://check.ipfs.network/?cid=bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi)
|
||||
|
||||
@[youtube](XeNOQDOrdC0)
|
||||
|
||||
## 🧰 Debugging retrievability on IPFS can be tricky
|
||||
|
||||
[Content Identifiers (CIDs)]((https://docs.ipfs.tech/concepts/glossary/#cid)), which lie at the heart of IPFS, free you from reliance on any single data provider. This is pretty magical, because as long as there is at least one provider for that data, you can always retrieve it via CID without needing to know the provider in advance. As a result, data retrieval on IPFS remains resilient even if individual providers become unavailable.
|
||||
|
||||
However, decoupling data from a single provider comes with a tradeoff: failure modes are more nuanced than in the client-server model.
|
||||
|
||||
In IPFS, when you try to fetch a CID, some providers may be online, while others may be offline, use other non-compatible network protocols, be slow, overloaded, or behind NAT and require hole punching to be reached.
|
||||
|
||||
Moreover, with the advent of [Delegated Routing](https://docs.ipfs.tech/concepts/how-ipfs-works/#how-content-routing-works-in-ipfs) and the [Network Indexer](https://docs.ipfs.tech/concepts/ipni/), CIDs may be routed by either the DHT or the Network Indexer, or both.
|
||||
|
||||
As a result, the likelihood of encountering an error when retrieving data is dependent on several dynamic factors:
|
||||
|
||||
1. Provider availability, which can constantly change
|
||||
2. Network conditions of both client and providers
|
||||
3. Successful announcement of CIDs to the DHT or Network Indexer.
|
||||
|
||||

|
||||
|
||||
As a user looking to retrieve data by CID, you may experience different things, depending on the CID you are looking for, and the network conditions when you try to retrieve it.
|
||||
|
||||
Up until now, there was no easy way to get a detailed overview of whether a given CID is retrievable, and if not, why.
|
||||
|
||||
## 🔍 IPFS Check helps you debug retrievability of data
|
||||
|
||||
[IPFS Check](https://check.ipfs.network/) fills a gap for users and developers working with the IPFS Mainnet public network: the ability to easily check if data is routable and retrievable by CID.
|
||||
|
||||
IPFS Check provides insights into accessibility and routing for any data on the IPFS Mainnet public network. It is a web app and doesn't require any setup or installation.
|
||||
|
||||
You can use IPFS Check to:
|
||||
|
||||
1. Verify if data is routable and retrievable by CID on IPFS Mainnet (and if not, get a detailed explanation of why for each provider).
|
||||
2. View the multiaddresses and network transports used to connect to providers.
|
||||
3. Determine if NAT hole punching was necessary.
|
||||
|
||||
It's especially useful to get an _outside perspective_ of your IPFS node's network setup, and whether it is correctly configured.
|
||||
|
||||
## Recent updates to IPFS Check
|
||||
|
||||
As part of the recent overhaul, we've made several improvements to IPFS Check:
|
||||
|
||||
- **Support for CID-only checks**: you can now check whether a CID is available from _any_ provider, without needing to pass a specific provider's multiaddr.
|
||||
- **IPNI support**: By default, IPFS Check will search for providers both in the IPNI and the DHT.
|
||||
- **NAT traversal**: you can now in the results whether retrieval requires NAT traversal (if there are two successful sonnection multiaddrs and one of them contains `p2p-circuit`).
|
||||
- **Network Protocol**: you can now see in the results which specific multiaddr was used for the connection, which tells you which network protocol was used, e.g. QUIC.
|
||||
|
||||
Give it a try at [check.ipfs.network](https://check.ipfs.network/). We hope you find it useful!
|
||||
|
||||
If you have any questions or feedback, open an issue or a discussion in the [GitHub repo](https://github.com/ipfs/ipfs-check/).
|
||||
@@ -3,7 +3,6 @@ date: 2021-01-19
|
||||
permalink: '/2021-01-19-ipfs-in-brave/'
|
||||
translationKey: ''
|
||||
tags:
|
||||
- brave
|
||||
- browsers
|
||||
header_image: '/2021-01-19-ipfs-in-brave.png'
|
||||
title: IPFS in Brave - Native Access to the Distributed Web
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
---
|
||||
title: IPFS URL support in CURL
|
||||
description: 'CURL 8.4.0 shipped with built-in support for ipfs:// and ipns:// addresses.'
|
||||
author: Mark Gaiser
|
||||
date: 2023-10-16
|
||||
permalink: '/ipfs-uri-support-in-curl/'
|
||||
header_image: '/curl.png'
|
||||
tags:
|
||||
- 'community'
|
||||
- 'URI'
|
||||
- 'URL'
|
||||
- 'HTTP'
|
||||
- 'curl'
|
||||
---
|
||||
|
||||
# `ipfs://` URL support in `curl`
|
||||
|
||||
[CURL 8.4.0](https://github.com/curl/curl/releases/tag/curl-8_4_0) shipped with built-in support for `ipfs://` and `ipns://` addresses.
|
||||
|
||||
This enables `curl` to seamlessly integrate with the user's preferred [IPFS gateway](https://docs.ipfs.tech/reference/http/gateway/) through the `IPFS_GATEWAY` environment variable or a `gateway` file. Best of all, these capabilities are available for immediate use today:
|
||||
|
||||
```bash
|
||||
$ export IPFS_GATEWAY="http://127.0.0.1:8080" # local (trusted) gateway provided by ipfs daemon like Kubo
|
||||
$ curl ipfs://bafkreih3wifdszgljcae7eu2qtpbgaedfkcvgnh4liq7rturr2crqlsuey
|
||||
hello from IPFS
|
||||
```
|
||||
|
||||
In this blog post, we will:
|
||||
- explore the journey of implementing IPFS URI support in CURL,
|
||||
- delve into the mechanics of [how CURL locates an IPFS gateway](#how-does-curl-find-an-ipfs-gateway),
|
||||
- learn how to be immune to [malicious gateways](#malicious-gateways-and-data-integrity),
|
||||
- and finally, provide [practical CURL examples](#curl-examples) for leveraging IPFS URLs for either deserialized or verifiable responses.
|
||||
|
||||
## A brief history
|
||||
|
||||
Supporting IPFS in CURL has been attempted [before](https://github.com/curl/curl/pull/8468) as a CURL library feature. Some discussions lead to a belief that this should be implemented in the CURL tool itself, not its library. A renewed [implementation attempt](https://github.com/curl/curl/pull/8805) took the tool-side approach which ultimately was accepted and is available right now in CURL 8.4.0!
|
||||
|
||||
The support of IPFS in CURL is effectively consisting of two implementation details.
|
||||
|
||||
1. CURL tries to find a locally installed or [configured gateway](#how-does-curl-find-an-ipfs-gateway).
|
||||
2. It then rewrites an `ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi` to a gateway URL. This is how curl handles it internally, you see nothing of this URL rewriting.
|
||||
|
||||
If you have IPFS installed locally then running `curl ipfs://` will Just Work™. If not, CURL will return an error with details about how to set up the gateway preference. This ensures the user agency is respected, no third-party gateway is used as implicit default.
|
||||
|
||||
## Why `ipfs://` URL support is so important?
|
||||
|
||||
Why isn't `https://ipfs.io/ipfs/bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi` equally acceptable?
|
||||
Or why isn't a local URL `http://localhost:8080/ipfs/bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi` fine?
|
||||
|
||||
Both addresses are tied to a specific _location_.
|
||||
|
||||
IPFS is a modular suite of protocols purpose built for the organization and transfer of [content-addressed](https://docs.ipfs.tech/concepts/content-addressing) data. It shouldn't matter where the content is. Content Identifier ([CID](https://docs.ipfs.tech/concepts/glossary/#cid)) is all that is required. The "where" part is implementation detail an IPFS system takes care of. Hardcoding a location in addition to a CID (like a specific HTTP gateway) limits end users to IPFS resources available through that one specific, centralized point of entry.
|
||||
|
||||
If we pull the URL apart we see:
|
||||
|
||||

|
||||
|
||||
Users of the IPFS system should not care about the _where_ part, nor be coerced to use a specific, hard-coded entry point into the system.
|
||||
|
||||
Public gateways like `ipfs.io` are always owned by some entity and could get censored or shut down at any time. Many gateways will not allow playback of deserialized videos or only respond to CIDs from allowlists to reduce costs. Other gateways will block specific CIDs from resolving in specific jurisdictions for legal reasons. Community-run public gateways will have limits and throttle usage.
|
||||
|
||||
These are not limitations of IPFS but purely a limitation a specific gateway has set through custom configuration. IPFS user should always have ability to avoid such limitations if they choose to self-host and [run their own IPFS node with a local gateway](https://docs.ipfs.tech/install/).
|
||||
|
||||
<!-- TODO: remove? feels like duplicate of we already say in this and "malicious" sections, but mentioning ffmpeg blogpost feels like something we should keep somewhere
|
||||
|
||||
This is why running a local node (and therefore a local gateway, it's part of a node) is so important. Even though you still effectively use `http://localhost:8080` as gateway, it's hosted by you locally backed by the many peers your node is connected with. Your experience in using IPFS is going to be best and fastest with a local node. Even when your local gateway isn't working it's easy for you to restart your node and get that gateway back and running. You can't do that on public gateways that you don't control.
|
||||
|
||||
One of the many reasons why we're putting in the effort to make applications recognize IPFS URIs (like [ffmpeg](https://blog.ipfs.tech/2022-08-01-ipfs-and-ffmpeg/)) `ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi` is to let the application in the background find that gateway you're running and giving you the freedom of being truly distributed! This also allows url's to be shared as IPFS url's (like `ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi`) without any trace of a (central) gateway and bring us one step closer to a distributed world where it doesn't matter anymore where that data is located.
|
||||
|
||||
-->
|
||||
|
||||
## How does CURL find an IPFS Gateway?
|
||||
|
||||
Any IPFS implementation that has support for [IPIP-280](https://github.com/ipfs/specs/pull/280) exposes an IPFS gateway that CURL (and [ffmpeg](https://blog.ipfs.tech/2022-08-01-ipfs-and-ffmpeg/)) can use. At the moment of writing that's just [Kubo](https://github.com/ipfs/kubo/releases).
|
||||
|
||||
CURL 8.4.0 and greater looks for a gateway in the following order:
|
||||
|
||||
1. `IPFS_GATEWAY`, if set it's used.
|
||||
2. The `--ipfs-gateway` CLI argument.
|
||||
3. The `~/.ipfs/gateway` file, where it reads the first line.
|
||||
|
||||
If a gateway hint is found at any of those places, and if that is a valid HTTP URL, then CURL will use it. If not, then you'll be getting an error message pointing to the [CURL documentation related to IPFS](https://curl.se/docs/ipfs.html) to help you further.
|
||||
|
||||
One can specify any IPFS gateway that is in compliance with [Gateway Specifications](https://specs.ipfs.tech/http-gateways/). It is highly recommended to use a local gateway, as it provides the best security guarantees.
|
||||
|
||||
## Malicious gateways and data integrity?
|
||||
|
||||
Requesting deserialized responses and delegating hash verification to a third-party gateway comes with risks. It is possible that a public gateway is malicious. Or, that a well-known and respected gateway gets hacked and changed to return payload that does not match requested CID. How can one protect themselves against that?
|
||||
|
||||
If deserialized responses are necessary, one should run their own gateway in a local, controlled environment. Every block of data retrieved though self-hosted IPFS gateway is verified to match the hash from CID. For the maximum flexibility and security, find an implementation that provides the gateway endpoint (i.e. [Kubo](https://docs.ipfs.tech/install/command-line/)) and run it yourself!
|
||||
|
||||
When using a third-party gateway that one can't fully trust, the only secure option is to [request verifiable response types](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) such as [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) (a single block) or [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car) (multiple blocks in CAR archive). Both allow to locally verify if the data returned by gateway match the requested CID, removing the surface for [Man-in-the-middle attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack).
|
||||
|
||||
## CURL Examples
|
||||
|
||||
### Deserialized responses
|
||||
|
||||
::: callout
|
||||
|
||||
By default, a trusted local gateway acts as a bridge between traditional HTTP clients and IPFS.
|
||||
|
||||
It performs necessary hash verification, UnixFS _deserialization_ and return reassembled files to the client, as if they were stored in a traditional HTTP server. This means all validation happens on the gateway, and clients trust that the gateway is correctly validating content-addressed data before returning it to them.
|
||||
|
||||
:::
|
||||
|
||||
#### Downloading a file from IPFS with CURL
|
||||
|
||||
```bash
|
||||
$ curl ipfs://bafkreih3wifdszgljcae7eu2qtpbgaedfkcvgnh4liq7rturr2crqlsuey -o out.txt
|
||||
```
|
||||
|
||||
If curl responds with `curl: IPFS automatic gateway detection failure`, make sure `IPFS_GATEWAY` is set (see examples below).
|
||||
|
||||
#### Explicitly specifying a gateway
|
||||
|
||||
To use local gateway on custom port 48080:
|
||||
|
||||
```bash
|
||||
$ export IPFS_GATEWAY=http://127.0.0.1:48080
|
||||
$ curl ipfs://bafkreih3wifdszgljcae7eu2qtpbgaedfkcvgnh4liq7rturr2crqlsuey
|
||||
hello from IPFS
|
||||
```
|
||||
|
||||
When setting environment variable is not feasible, one can use `--ipfs-gateway` instead:
|
||||
|
||||
```bash
|
||||
$ curl --ipfs-gateway http://127.0.0.1:48080 ipfs://bafkreih3wifdszgljcae7eu2qtpbgaedfkcvgnh4liq7rturr2crqlsuey
|
||||
hello from IPFS
|
||||
```
|
||||
|
||||
#### Following subdomain redirects
|
||||
|
||||
::: callout
|
||||
|
||||
By default, the URL resolution in `curl` does not follow HTTP redirects and assumes the endpoint implements deserializing [path gateway](https://specs.ipfs.tech/http-gateways/path-gateway/), or at the very least, the [trustless gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/).
|
||||
When pointing `curl` at a [subdomain gateway](https://specs.ipfs.tech/http-gateways/subdomain-gateway) (like `https://dweb.link` or the `http://localhost:8080` provided by a [local Kubo node](https://docs.ipfs.tech/how-to/command-line-quick-start/)) one has to pass `-L` in the curl command to follow the redirect.
|
||||
|
||||
:::
|
||||
|
||||
```bash
|
||||
$ IPFS_GATEWAY=https://localhost:8080 curl -s -L ipfs://bafkreih3wifdszgljcae7eu2qtpbgaedfkcvgnh4liq7rturr2crqlsuey
|
||||
hello from IPFS
|
||||
```
|
||||
|
||||
#### Piping and streaming responses
|
||||
|
||||
Deserialized response returned by CURL can be piped directly to a video player:
|
||||
|
||||
```
|
||||
$ curl ipfs://bafybeigagd5nmnn2iys2f3doro7ydrevyr2mzarwidgadawmamiteydbzi | ffplay -
|
||||
```
|
||||
|
||||
### Verifiable responses
|
||||
|
||||
::: callout
|
||||
|
||||
By explicitly requesting [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw) (a block) or [application/vnd.ipld.car](https://www.iana.org/assignments/media-types/application/vnd.ipld.car) (a stream of blocks) responses, by means defined in [Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/), the user is able to fetch raw content-addressed data and [perform hash verification themselves](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval).
|
||||
|
||||
:::
|
||||
|
||||
#### Fetching and verifying a directory from an untrusted gateway
|
||||
|
||||
Requesting [trustless and verifiable](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) CAR response via `Accept` HTTP header:
|
||||
|
||||
```bash
|
||||
$ export IPFS_GATEWAY="https://ipfs.io" # using untrusted public gateway
|
||||
$ curl -H "Accept: application/vnd.ipld.car" "ipfs://bafybeiakou6e7hnx4ms2yangplzl6viapsoyo6phlee6bwrg4j2xt37m3q" > dag.car
|
||||
```
|
||||
|
||||
Then, CAR can be moved around and imported into some other IPFS node:
|
||||
|
||||
```bash
|
||||
$ ipfs dag import dag.car
|
||||
```
|
||||
|
||||
or verified and unpacked locally, without having to run a full IPFS node, with tools like [go-car](https://github.com/ipld/go-car/tree/master/cmd/car#readme) or [ipfs-car](https://www.npmjs.com/package/ipfs-car):
|
||||
|
||||
```
|
||||
$ npm i -g ipfs-car
|
||||
$ ipfs-car unpack dag.car --output dag.out
|
||||
$ ls dag.out
|
||||
1007 - Sustainable - alt.txt
|
||||
1007 - Sustainable - transcript.txt
|
||||
1007 - Sustainable.png
|
||||
```
|
||||
|
||||
## What's next?
|
||||
|
||||
More places supporting IPFS addresses. Everyone can integrate `ipfs://` and `ipns://` URL support into their application. See specifications proposed in [IPIP-280](https://github.com/ipfs/specs/pull/280) for technical details. We are [tracking potential project](https://github.com/ipfs/integrations/issues) where an integration makes sense! If you feel up to the challenge, don't hesitate to drop a comment in one of the [potential projects](https://github.com/ipfs/integrations/issues) for IPFS URL integration or find us on:
|
||||
|
||||
* [Matrix](https://matrix.to/#/#ipfs-space:ipfs.io), [Discord](https://discord.com/invite/ipfs) or [Slack](https://filecoin.io/slack)
|
||||
* [Discussion Forum](https://discuss.ipfs.tech/)
|
||||
|
||||
Or one of the other many places where the [IPFS community](https://docs.ipfs.tech/community/) is active.
|
||||
|
||||
@@ -1,199 +0,0 @@
|
||||
---
|
||||
title: Introducing Major Improvements to Omnilingo
|
||||
description: 'We’re happy to introduce some major improvements to Omnilingo, the decentralised language learning platform designed with special attention to small and marginalised language communities.'
|
||||
date: 2023-11-20
|
||||
permalink: '/major-improvements-to-omnilingo/'
|
||||
header_image: "/omnilingo-x-ipfs.jpg"
|
||||
tags:
|
||||
- omnilingo
|
||||
---
|
||||
|
||||
## Introduction
|
||||
|
||||
Nearly two years ago, the IPFS Dev Grants program funded the first grant for Omnilingo to explore how IPFS could meet the needs of their users - groups with limited bandwidth and applications which work offline-first, allowing full user control of data. You can read the [original post from 2021](https://blog.ipfs.tech/2021-12-17-omnilingo/), and several iterations of the grant later (generously provided by the Filecoin Foundation) we're happy to share an update.
|
||||
|
||||
The mission of Omnilingo is inspiring, and its authors are an incredible team who are pushing on a lot of hard problems all at once, including new approaches to consent-driven data access and revocation patterns. This is critical work and an extraordinarily important use of IPFS that we are happy to shine a light on.
|
||||
|
||||
-- Dietrich Ayala, technical grant advisor to Omnilingo
|
||||
|
||||
## Project Update: Omnilingo
|
||||
|
||||
We're happy to introduce some major improvements to Omnilingo, the decentralised language learning platform designed with special attention to small and marginalised language communities. We now have an experimental
|
||||
contribution system, including an encryption-based consent model.
|
||||
|
||||
## Overview
|
||||
|
||||
We developed Omnilingo two years ago with the goal of making it possible for minority and marginalised language communities to create and curate language-learning data in their languages by developing and publishing formats for language source material hosted on the decentralised filesystem IPFS. Anyone can publish new source material on IPFS, and a compatible Omnilingo client can use this source material to generate language-learning exercises.
|
||||
|
||||
The source material is published in the form of Omnilingo data structures on IPFS; previously this had to be done by a knowledgeable web developer operating an IPFS node. We are happy to present now an interface for contributing samples from our demonstration web client!
|
||||
|
||||
As with any networked system, collecting and preserving data from our users can be done only with their consent. Managing that consent within the context of a decentralised filesystem comes with its own special challenges, and we designed what we think is as good of a privacy- and consent-respecting system as we can.
|
||||
|
||||
Here's a sample user story illustrating how this might be used:
|
||||
|
||||
A language activist encourages members of their endangered language community to contribute their voices, producing a large corpus of spoken audio clips; children of their community and in diaspora can now use Omnilingo to practise outside of the classroom, supporting revitalisation of the language. Decentralisation and the consent system allow the community as a whole as well as individuals to decide who has access to their voices.
|
||||
|
||||
As opposed to most current systems for data collection via crowd sourcing, in Omnilingo, contributors own their own data and can define their own terms and conditions for its use.
|
||||
|
||||
## Omnilingo privacy structures
|
||||
|
||||
Our contribution privacy initiative brings with it a handful of new structures. These are introduced bottom-up; read this section backwards if you prefer a top-down introduction.
|
||||
|
||||
### Omnilingo session keys
|
||||
|
||||
An Omnilingo session key is a [JSON Web Key]; our implementation uses the [SubtleCrypto WebAPI] to generate and encode these keys. Currently we recommend only 256-bit AES-GCM keys, and our Web client supports only this configuration.
|
||||
|
||||
[JSON Web Key]: https://datatracker.ietf.org/doc/html/rfc7517
|
||||
[SubtleCrypto WebAPI]: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto
|
||||
|
||||
Omnilingo session keys form the unit of "consent": for a given session key, users may have contributed several samples. If a user wishes to revoke their consent for a sample, they signal this by unpublishing the session key, thus revoking consent for all samples contributed with that key.
|
||||
|
||||
For a more positive user experience, we recommend the user-facing interface reference session keys by the [pgpfone wordlist] encoding of their fingerprint.
|
||||
|
||||
[pgpfone wordlist]: https://web.archive.org/web/20100326141145/http://web.mit.edu/network/pgpfone/manual/index.html#PGP000062
|
||||
|
||||
### Omnilingo encrypted object
|
||||
|
||||
An Omnilingo encrypted object is an object which has been encrypted by an Omnilingo session key; the structure is:
|
||||
|
||||
```
|
||||
{ "alg": alg // AesKeyGenParams
|
||||
, "keyfpr": keyfpr // key fingerprint: hexadecimal string encoding of the SHA-1 digest of the key
|
||||
, "iv": iv // initialisation vector used
|
||||
, "encdata": encdata // Uint8Array of the encrypted data
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
See [MDN SubtleCrypto digest documentation] for details of how we generate the fingerprint.
|
||||
|
||||
[MDN SubtleCrypto digest documentation]: https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest
|
||||
|
||||
We wrap in encrypted objects the MP3 of the contribution as well as the list of Omnilingo clip structures.
|
||||
|
||||
Encrypted clip:
|
||||
```
|
||||
{ "chars_sec": chars_sec
|
||||
, "clip_cid": CID(encrypt(clip_mp3))
|
||||
, "length": length
|
||||
, "meta_cid": meta_cid
|
||||
, "sentence_cid": sentence_cid
|
||||
}
|
||||
```
|
||||
|
||||
### Omnilingo encrypted index
|
||||
|
||||
An Omnilingo encrypted index is similar to the classic Omnilingo root index: a JSON dictionary with language codes as keys and Omnilingo language indices as the values. The `cids` entry of the Omnilingo language index is a list of IPFS CIDs referencing the encrypted lists of Omnilingo clip structures.
|
||||
|
||||
An example:
|
||||
```
|
||||
{ "ab": { "cids": CID(encrypt(clip_list)) } }
|
||||
```
|
||||
|
||||
### Omnilingo encrypted root
|
||||
|
||||
An Omnilingo encrypted root is a JSON dictionary; the keys are fingerprints of Omnilingo session keys, and each value is the CID of an Omnilingo encrypted index encrypted with the corresponding session key.
|
||||
|
||||
```
|
||||
{ "ea6b0c9b2f697c3cbc16fb7978af16aae53bdeb8": "QmdzHipTQWgguLci211Cp3Eh8SWhEnsZA34mGJgGQXYcUV" }
|
||||
```
|
||||
|
||||
Encrypted roots can optionally contain some of the referenced session keys, allowing decryption. In this example, the key `ea6b0c9b...` is included.
|
||||
|
||||
```
|
||||
{ "keys": {
|
||||
"ea6b0c9b2f697c3cbc16fb7978af16aae53bdeb8": JWK(key)
|
||||
}
|
||||
, "dab24db69f6856652275e06c5f092f68623a4041": "QmWug9ie3bpkzVvKDVfuLtksaWsa5Q1DZxsnwmCCAASYj8"
|
||||
, "ea6b0c9b2f697c3cbc16fb7978af16aae53bdeb8": "QmdzHipTQWgguLci211Cp3Eh8SWhEnsZA34mGJgGQXYcUV"
|
||||
}
|
||||
```
|
||||
|
||||
### Omnilingo identity
|
||||
|
||||
An Omnilingo identity is a IPNS key (colloquially referred to as a `k5`). Published to this `k5` is an encrypted root, containing the session keys for which the user (the one controlling the private part of the `k5`). The Omnilingo client has been updated to accept Omnilingo identities, fetching and decrypting the contained encrypted indices.
|
||||
|
||||
In the example encrypted root:
|
||||
```
|
||||
{ "keys":{
|
||||
"ea6b0c9b2f697c3cbc16fb7978af16aae53bdeb8": JWK(key)
|
||||
}
|
||||
, "dab24db69f6856652275e06c5f092f68623a4041": "QmWug9ie3bpkzVvKDVfuLtksaWsa5Q1DZxsnwmCCAASYj8"
|
||||
, "ea6b0c9b2f697c3cbc16fb7978af16aae53bdeb8": "QmdzHipTQWgguLci211Cp3Eh8SWhEnsZA34mGJgGQXYcUV"
|
||||
}
|
||||
```
|
||||
|
||||
The material encrypted by session key `ea6b0c9b2` can be used with the controlling user's consent, whereas the material encrypted by session key `dab24db6` cannot be any longer, as the user has unpublished the key.
|
||||
|
||||
## Data flows
|
||||
|
||||
There are two new data flows introduced with this system: contributing data, and retrieving contributed data.
|
||||
|
||||
### Contribution
|
||||
|
||||
A contributor client will be drawing sentences from a (presumably classic) Omnilingo language index, and contributing new clips. They start by generating an Omnilingo identity (`k5`) and a session key. The session key is stored locally.
|
||||
|
||||
When the user makes their first contribution (an MP3 recording of them reading a sentence), a new Omnilingo encrypted root index is published to their `k5`:
|
||||
|
||||
```
|
||||
{ "keys": {
|
||||
fpr(key): JWK(key)
|
||||
}
|
||||
, fpr(key): CID({ // encrypted language index
|
||||
"XX": {
|
||||
"cids": [CID(encrypt([ // encrypted clip list
|
||||
encrypted_clip
|
||||
]))]
|
||||
}
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
As the user makes more contributions, the encrypted clip list grows in length, updating the encrypted language index and encrypted root index, each time republished to the `k5`, all under the same session key:
|
||||
|
||||
```
|
||||
{ "keys": {
|
||||
fpr(key): JWK(key)
|
||||
}
|
||||
, fpr(key): CID({ "XX": { "cids": [CID(encrypt(clip_list))] } })
|
||||
}
|
||||
```
|
||||
|
||||
At some point, the user decides to "roll" their session key, creating a new session. (A client might decide to do this automatically, e.g. each time it is opened, or each time the language is switched.) A new session key is generated, and everything propagates up to the user identity (`k5`):
|
||||
|
||||
```
|
||||
{ "keys": {
|
||||
fpr(key1): JWK(key1)
|
||||
, fpr(key2): JWK(key2)
|
||||
}
|
||||
, fpr(key1): CID({ "XX": { "cids": [CID(encrypt(clip_list1))] } })
|
||||
, fpr(key2): CID({ "XX": { "cids": [CID(encrypt(clip_list2))] } })
|
||||
}
|
||||
```
|
||||
|
||||
At some later time, the user decides to revoke consent to use the material recorded under `key1`; the JSON Web Key encoded copy of `key1` is removed, only `fpr(key1)` remains published under their identity:
|
||||
|
||||
```
|
||||
{ "keys": {
|
||||
fpr(key2): JWK(key2)
|
||||
}
|
||||
, fpr(key1): CID({ "XX": { "cids": [CID(encrypt(clip_list1))] } }) // consent revoked
|
||||
, fpr(key2): CID({ "XX": { "cids": [CID(encrypt(clip_list2))] } })
|
||||
}
|
||||
```
|
||||
|
||||
Consumers who have stored `key1` will retain access to this data, just as they would if they had stored the decrypted copies; however, use of it would constitute a violation of the user's consent.
|
||||
|
||||
### Consumption
|
||||
|
||||
Omnilingo consumers now have two types of root indices to deal with: classic root indices and encrypted root indices. An encrypted root index may be detected by the presence of the `keys` field; iterating over this dictionary then gives the consumer a list of fingerprints to look up in the encrypted root index, as well as the key needed to decode the resulting encrypted language index.
|
||||
|
||||
## Concluding remarks
|
||||
|
||||
Omnilingo now has support for user contributions with sovereignty protections, enabling marginalised language communities to produce and control their own data and integrate it into compatible Omnilingo clients in a user-respecting way. Due to the decentralisation allowed by IPFS, such clients can be hosted anywhere on anyone's infrastructure. We look forward to continuing to improve language learner and language activist access to decentralised and sovereignty-preserving language learning systems.
|
||||
|
||||
We invite everyone interested to get involved! Read our [technical paper](https://arxiv.org/abs/2310.06764), check out our [live demo](https://demo.omnilingo.cc), [fork us on GitHub](https://github.com/omnilingo/omnilingo), and join us on Matrix in `#OmniLingo:matrix.org` ([chat now](https://app.element.io/#/room/#OmniLingo:matrix.org)). Our near-term plans include:
|
||||
* full p2p (dropping the required remote Kubo instance)
|
||||
* experimenting with isolated networks (useful e.g. for rural communities)
|
||||
* integration with FileCoin and/or pinning services
|
||||
|
||||
@@ -4,31 +4,6 @@ type: News coverage
|
||||
sitemap:
|
||||
exclude: true
|
||||
data:
|
||||
- title: Cloudflare’s public IPFS gateways and supporting Interplanetary Shipyard
|
||||
date: 2024-05-14
|
||||
publish_date:
|
||||
path: https://blog.cloudflare.com/cloudflares-public-ipfs-gateways-and-supporting-interplanetary-shipyard
|
||||
tags:
|
||||
- Cloudflare
|
||||
- IPFS
|
||||
- gateway
|
||||
- IPShipyard
|
||||
- title: Filecoin Foundation Successfully Deploys IPFS in Space
|
||||
date: 2024-01-16
|
||||
publish_date:
|
||||
path: https://fil.org/blog/filecoin-foundation-successfully-deploys-interplanetary-file-system-ipfs-in-space/
|
||||
tags:
|
||||
- space
|
||||
- IPFS
|
||||
- satellite
|
||||
- title: Advancing IPFS and libp2p Governance
|
||||
date: 2023-11-14
|
||||
publish_date:
|
||||
path: https://protocol.ai/blog/advancing-ipfs-and-libp2p-governance/
|
||||
tags:
|
||||
- IPFS
|
||||
- libp2p
|
||||
- governance
|
||||
- title: Brave announces automatic NFT backups and enhanced IPFS/Filecoin support in Brave Wallet
|
||||
date: 2023-05-02
|
||||
publish_date:
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
---
|
||||
title: Welcome to IPFS News 198!
|
||||
description: Featuring announcements about Brave's New IPFS Infobar, Amino, and IPFS Connect!
|
||||
date: 2023-10-03
|
||||
permalink: "/newsletter-198"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **IPFS Connect 2023 Istanbul 🔭**
|
||||
|
||||
IPFS Connect is a community-run regional conference bringing together all of the builders and ecosystems that rely on and use IPFS as the most widely used decentralized content addressing protocol for files and data. This year's event is happening alongside Devconnect and LabWeek23 in Istanbul, Turkey on November 16. Join the IPFS Community for a full day of workshops, lightning talks, and demos showcasing technology, tools, and innovative projects in the IPFS ecosystem.
|
||||
|
||||
There are several opportunities for you to get involved with this event whether you're a business, organization, or individual.
|
||||
|
||||
<a href="https://blog.ipfs.tech/_2023-ipfs-connect-istanbul/" class="cta-button">Read the blog post</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Brave Browser's New IPFS Infobar](https://blog.ipfs.tech/_2023-brave-infobar/)
|
||||
|
||||
- We’re excited to share a new IPFS-related feature that appears in the most recent version of Brave’s web browser. A new IPFS Infobar will appear at the top of the browser when you visit an IPFS compatible resource such as a CID on a public gateway or a website with a DNSLink. [Learn more here!](https://blog.ipfs.tech/_2023-brave-infobar/)
|
||||
|
||||
[IPFS support was merged into curl](https://twitter.com/bmann/status/1705572964068930010?s=20)
|
||||
|
||||
- Thanks to the hard work and dedication of [Mark Gaiser](https://github.com/markg85), IPFS support was recently [merged into curl](https://github.com/curl/curl/pull/8805#issuecomment-1732260385), a command line tool and library for transferring data with URL syntax. More information and an official announcement are to come, but we're excited for this important milestone. IPFS is already in the curl documentation: [https://curl.se/docs/ipfs.html](https://curl.se/docs/ipfs.html)
|
||||
|
||||
[Amino (the Public IPFS DHT) is getting a facelift](https://blog.ipfs.tech/2023-09-amino-refactoring/)
|
||||
|
||||
- [Read the blog post](https://blog.ipfs.tech/2023-09-amino-refactoring/) to learn all the details and follow this discussion forum thread if you want to be kept up-to-date about further developments: [https://discuss.ipfs.tech/t/dht-discussion-and-contribution-opportunities-in-2023q4/16937/2](https://discuss.ipfs.tech/t/dht-discussion-and-contribution-opportunities-in-2023q4/16937/2)
|
||||
|
||||
[The ProbeLab team needs your help — fill out this survey!](https://tally.so/r/npoo6q)
|
||||
|
||||
- The ProbeLab team developed tools and infrastructure to capture the metrics you see at [https://probelab.io/](https://probelab.io). We want to expand the list of metrics we capture and build new open-source tools that will help protocol designers and application developers get a better idea of where the performance of their application can improve. This is your chance to influence where our team focuses next. [Please fill in the survey and let us know if and how you would be interested to contribute to this line of work.](https://tally.so/r/npoo6q)
|
||||
|
||||
[awesome-ipfs reboot](https://awesome.ipfs.tech/)
|
||||
|
||||
- After lying dormant for many months, the awesome-ipfs website has been cleaned up and rebooted. [Check out the updated version here!](https://awesome.ipfs.tech/)
|
||||
|
||||
[IPFS & Filecoin Ecosystem Roundup](https://www.youtube.com/watch?v=bdOPPnuZnhw)
|
||||
|
||||
- The September Filecoin & IPFS Ecosystem Roundup is online! Check out the video for the latest updates, developments, and insights straight from the community. [Watch it here!](https://www.youtube.com/watch?v=bdOPPnuZnhw)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[IPFS on AWS, Part 1 – Discover IPFS on a virtual machine](https://aws.amazon.com/blogs/database/part-1-ipfs-on-aws-discover-ipfs-on-a-virtual-machine/)
|
||||
|
||||
- Did you know you can run IPFS on AWS? In this 3-part series on the AWS Database Blog, you'll learn how to do it thanks to a step-by-step guide. [Check it out!](https://aws.amazon.com/blogs/database/part-1-ipfs-on-aws-discover-ipfs-on-a-virtual-machine/)
|
||||
|
||||
[OrbitDB v1.0 releases](https://github.com/orbitdb/orbitdb)
|
||||
|
||||
- "OrbitDB is a serverless, distributed, peer-to-peer database. OrbitDB uses IPFS as its data storage and Libp2p Pubsub to automatically sync databases with peers. It's an eventually consistent database that uses Merkle-CRDTs for conflict-free database writes and merges making OrbitDB an excellent choice for p2p and decentralized apps, blockchain applications and local-first web applications." [Learn more here!](https://github.com/orbitdb/orbitdb)
|
||||
|
||||
[New in the Ecoystem Directory: dAppling](https://ecosystem.ipfs.tech/project/dappling/)
|
||||
|
||||
- Easy way for web3 developers to deploy their frontend to IPFS with a great developer experience. Connect your github and have a deployed site in a few clicks. Automatic CI/CD / Preview Builds / ENS support. [Check it out here!](https://ecosystem.ipfs.tech/project/dappling/)
|
||||
|
||||
[New in the Ecosystem Directory: ODD SDK](https://ecosystem.ipfs.tech/project/odd-sdk/)
|
||||
|
||||
- ODD SDK is Fission's true local-first, edge computing stack. ODD SDK empowers you to build fully distributed web applications with auth and storage without needing a complex backend. [View it here!](https://ecosystem.ipfs.tech/project/odd-sdk/)
|
||||
|
||||
[Popular on the Forums: Questions about a Private IPFS Setup](https://discuss.ipfs.tech/t/how-to-set-up-my-own-bootstrap-nodes-to-enable-discovery-and-connection-between-nodes-with-public-ip-and-nodes-on-a-local-network/16910)
|
||||
|
||||
- "How [do I] set up my own bootstrap nodes to enable discovery and connection between nodes with public IP and nodes on a local network?" [Read the discussion.](https://discuss.ipfs.tech/t/how-to-set-up-my-own-bootstrap-nodes-to-enable-discovery-and-connection-between-nodes-with-public-ip-and-nodes-on-a-local-network/16910)
|
||||
|
||||
[Job Alert: Filebase is hiring a Senior Digital Marketing Strategist](https://wellfound.com/jobs/2807523-senior-digital-marketing-strategist)
|
||||
|
||||
- "Are you a creative and strategic thinker with a passion for driving digital marketing excellence? Do you thrive in dynamic, cutting-edge environments and have a deep understanding of the tech industry? Join us at Filebase, a leading player in the decentralized storage revolution, as a Senior Digital Marketing Strategist." [Learn more here!](https://wellfound.com/jobs/2807523-senior-digital-marketing-strategist)
|
||||
|
||||
[LabWeek23 is happening November 13-17](https://23.labweek.io/)
|
||||
|
||||
- Have you booked your travel yet? LabWeek23 is happening in Istanbul, Türkiye, from November 13-17, alongside Devconnect! This is your chance to connect and collaborate with visionaries and teams that are domain leaders in ZK Proofs, AI and blockchain, DeSci, decentralized storage, gaming in Web3, public goods funding, cryptoeconomics, and much more. [Learn more about it here!](https://23.labweek.io/)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
As part of our ongoing efforts to empower and promote community contributors, we're providing a new way for you to have a chance to influence the monthly IPFS newsletter! If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for promotion via IPFS communication channels.
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
---
|
||||
title: Welcome to IPFS News 199!
|
||||
description: Featuring CURL supporting IPFS and a new IPFS implementation called Nabu.
|
||||
date: 2023-11-09
|
||||
permalink: "/newsletter-199"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **IPFS URL support in CURL 🔭**
|
||||
|
||||
We're excited to share that thanks to the hard work of Mark Gaiser, CURL 8.4.0 shipped with built-in support for ipfs:// and ipns:// addresses. This is an important advancement, and we've got a blog you can read to learn more:
|
||||
|
||||
<a href="https://blog.ipfs.tech/ipfs-uri-support-in-curl/" class="cta-button">Read the blog post</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Introducing Nabu: Unleashing IPFS on the JVM](https://blog.ipfs.tech/2023-11-introducing-nabu/)
|
||||
|
||||
- Learn about a new fast IPFS implementation in Java by checking out this recent post on the IPFS blog. [Read it here!](https://blog.ipfs.tech/2023-11-introducing-nabu/)
|
||||
|
||||
[IPFS Connect Istanbul](https://istanbul2023.ipfsconnect.org/)
|
||||
|
||||
- IPFS Connect is a community-run regional conference bringing together all of the builders and ecosystems that rely on and use IPFS as the most widely used decentralized content addressing protocol for files and data. This year's event is happening alongside Devconnect and LabWeek23 in Istanbul, Turkey on November 16. [Register today!](https://istanbul2023.ipfsconnect.org/)
|
||||
|
||||
[Connect with the PL IPFS Implementers in Istanbul and Prague](https://forms.gle/CxUQPsEUg2CGkLgh6)
|
||||
|
||||
- We want to connect with you and hear your thoughts as we shape the future of IPFS for 2024. Your input is invaluable in guiding our efforts, so we're inviting you to meet with us in Istanbul and Prague at two exciting events: DevConnect / IPFS Connect in Istanbul 🇹🇷 and DCxPrague in Prague 🇨🇿. If you're interested in sharing your thoughts and connecting with us during these events, [please fill out this form.](https://forms.gle/CxUQPsEUg2CGkLgh6)
|
||||
|
||||
[New Release: Kubo v0.24.0](https://github.com/ipfs/kubo/releases/tag/v0.24.0)
|
||||
|
||||
- Support for content blocking
|
||||
- Gateway: the root of the CARs are no longer meaningful
|
||||
- IPNS: improved publishing defaults
|
||||
- IPNS: record TTL is used for caching
|
||||
- Experimental Transport: WebRTC Direct
|
||||
|
||||
[New Release: Kubo v0.23.0](https://github.com/ipfs/kubo/releases/tag/v0.23.0)
|
||||
|
||||
[New Release: Boxo v0.15.0](https://discuss.ipfs.tech/t/boxo-v0-15-0-is-out/17175)
|
||||
|
||||
[New Release: Iroh v0.10.0](https://github.com/n0-computer/iroh/releases/tag/v0.10.0)
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly)
|
||||
|
||||
- Help: [How to diagnose file not propagating to other Gateways?](https://discuss.ipfs.tech/t/how-to-diagnose-file-not-propagating-to-other-gateways/17071)
|
||||
- Help: [Files pinned to my IPFS node don’t show up on any other gateway](https://discuss.ipfs.tech/t/files-pinned-to-my-ipfs-node-dont-show-up-on-any-other-gateway/17132)
|
||||
- Helia: [Connection closes during bitswap fetches](https://discuss.ipfs.tech/t/connection-closes-during-bitswap-fetches/17041)
|
||||
|
||||
[IPFS & Filecoin Ecosystem Roundup](https://www.youtube.com/watch?v=rn1nLUqJ4HM)
|
||||
|
||||
- The October Filecoin & IPFS Ecosystem Roundup is online! Check out the video for the latest updates, developments, and insights straight from the community. [Watch it here!](https://www.youtube.com/watch?v=rn1nLUqJ4HM)
|
||||
|
||||
[Helia Report 2023-10](https://pl-strflt.notion.site/Helia-Report-2023-10-ddd18180aec54ff9ad06f0771340b850)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Call for submissions: awesome-ipfs](https://github.com/ipfs/awesome-ipfs)
|
||||
|
||||
- This is a community list of awesome projects, apps, tools, and services related to IPFS. We'd love to see more projects added to it, [so submit yours today!](https://github.com/ipfs/awesome-ipfs)
|
||||
|
||||
[IPFS Naming from Scaleaway](https://labs.scaleway.com/en/ipfs-naming/)
|
||||
|
||||
- Scaleway is opening a new service around called IPFS Naming. It is an IPNS managed service to solve the problem of managing and dynamically updating immutable IPFS addresses. [Learn more about it here!](https://labs.scaleway.com/en/ipfs-naming/)
|
||||
|
||||
[The Principles and Practices of IPFS](https://www.amazon.co.jp/o/ASIN/4297138379/gihyojp-22)
|
||||
|
||||
- This book has been translated to Japanese and will be published on November 8, [pre-order is available on Amazon.](https://www.amazon.co.jp/o/ASIN/4297138379/gihyojp-22)
|
||||
|
||||
[Peergos v0.14.0 featuring Nabu](https://peergos.net/public/peergos/releases)
|
||||
|
||||
- The Peergos team just published a new Peergos release, v0.14.0, in which they switch to their new Java implementation of IPFS, Nabu. This reduces idle bandwidth usage by about 10x, as well as CPU and RAM usage, and generally makes p2p stuff faster. [Check out the release notes here!](https://peergos.net/public/peergos/releases)
|
||||
|
||||
[Job Alert: Filebase is hiring a Senior Digital Marketing Strategist](https://wellfound.com/jobs/2807523-senior-digital-marketing-strategist)
|
||||
|
||||
- "Are you a creative and strategic thinker with a passion for driving digital marketing excellence? Do you thrive in dynamic, cutting-edge environments and have a deep understanding of the tech industry? Join us at Filebase, a leading player in the decentralized storage revolution, as a Senior Digital Marketing Strategist." [Learn more here!](https://wellfound.com/jobs/2807523-senior-digital-marketing-strategist)
|
||||
|
||||
[Reality Studies Podcast](https://www.youtube.com/watch?v=902OA94avbY)
|
||||
|
||||
- A recent episode of the Reality Studies podcast, by Protocol Labs Arts & Culture Advisor Jesse Damiani, features Asad J. Malik, CEO of Jadu AR. In 2021 and 2022, Jadu released successful NFT collections which were stored using IPFS. Now, owners of those NFTs can integrate them into the company's recently launched mobile AR game. [Watch the interview here!](https://www.youtube.com/watch?v=902OA94avbY)
|
||||
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: Welcome to IPFS News 200!
|
||||
description: Featuring a big announcement about IPFS and libp2p.
|
||||
date: 2023-12-18
|
||||
permalink: "/newsletter-200"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Advancing IPFS and libp2p Governance 🔭**
|
||||
|
||||
We have some exciting news to share! IPFS and libp2p are officially taking big steps forward in project maturity, with independent foundations and funding structures in the Protocol Labs network! You can learn more about this news [on the Protocol Labs blog.](https://protocol.ai/blog/advancing-ipfs-and-libp2p-governance/)
|
||||
|
||||
<a href="https://protocol.ai/blog/advancing-ipfs-and-libp2p-governance/" class="cta-button">Read the blog post</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Videos: IPFS Connect Istanbul Talks](https://www.youtube.com/playlist?list=PLfW9my7NCey-y5_j6QGCtGoigQuVlZ3Bj)
|
||||
|
||||
- IPFS Connect was a community-run regional conference bringing together all of the builders and ecosystems that rely on and use IPFS as the most widely used decentralized content addressing protocol for files and data. This year's event happened alongside Devconnect and LabWeek23 in Istanbul, Turkey on November 16. [Watch the talks here!](https://www.youtube.com/playlist?list=PLfW9my7NCey-y5_j6QGCtGoigQuVlZ3Bj)
|
||||
|
||||
[IPFS Companion MV3 Update](https://blog.ipfs.tech/2023-ipfs-companion-mv3-update/)
|
||||
|
||||
- In September, IPFS-Companion built on MV3 (Manifest V3) was shipped on the main channel, which brings exciting improvements and changes the way you interact with this powerful tool. [This blog post](https://blog.ipfs.tech/2023-ipfs-companion-mv3-update/) will give you a quick overview of the journey, changes, and what to expect.
|
||||
|
||||
[Incident Report - Increased Latency on the Amino DHT](https://discuss.ipfs.tech/t/incident-report-increased-latency-on-the-amino-dht/17338)
|
||||
|
||||
- Since 4 December, the ProbeLab team which monitors the IPFS network observed two major anomalies in Amino (The public IPFS DHT). [Learn more about it here!](https://discuss.ipfs.tech/t/incident-report-increased-latency-on-the-amino-dht/17338)
|
||||
|
||||
[Built with IPFS - Mintter and The Hypermedia Protocol](https://www.youtube.com/watch?v=K3U6A4sgKo4)
|
||||
|
||||
- In this episode of Built with IPFS, we dive into Mintter and The Hypermedia Protocol. Mintter Hypermedia is an open system, built on IPFS that allows communities to collaborate on content that is structured and deeply linked. All content in the system is cryptographically signed, versioned, and made permanent with IPFS. [Watch the video here!](https://www.youtube.com/watch?v=K3U6A4sgKo4)
|
||||
|
||||
[New Release: Kubo v0.25.0](https://github.com/ipfs/kubo/releases/tag/v0.25.0)
|
||||
|
||||
- Commands `ipfs key sign` and `ipfs key verify`
|
||||
|
||||
[New Release: Boxo v0.16.0](https://github.com/ipfs/boxo/releases/tag/v0.16.0)
|
||||
|
||||
[New Release: Iroh v0.11.0](https://github.com/n0-computer/iroh/releases/tag/v0.11.0)
|
||||
|
||||
[New Release: curl v8.5.0 - improved IPFS and IPNS URL support](https://github.com/zuoxiaofeng/curl/commit/7afa1be7d799a73f3ab6fb0b0072159103da802a)
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly)
|
||||
|
||||
- Help: [Constant 100% CPU utilization on AWS EC2 IPFS node](https://discuss.ipfs.tech/t/constant-100-cpu-utilization-on-aws-ec2-ipfs-node/17172)
|
||||
- Help: [Double-hashed entries in denylists](https://discuss.ipfs.tech/t/double-hashed-entries-in-denylists/17199)
|
||||
- Help: [How to find these files through CID?](https://discuss.ipfs.tech/t/how-to-find-these-files-through-cid-the-files-are-very-important-to-me/17297)
|
||||
|
||||
[Helia Reports](https://pl-strflt.notion.site/Helia-Report-2023-10-ddd18180aec54ff9ad06f0771340b850)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Blog: Introducing Major Improvements to Omnilingo](https://blog.ipfs.tech/major-improvements-to-omnilingo/)
|
||||
|
||||
- From the Omnilingo team: "We're happy to introduce some major improvements to Omnilingo, the decentralised language learning platform designed with special attention to small and marginalised language communities. We now have an experimental contribution system, including an encryption-based consent model." [Read more about it here!](https://blog.ipfs.tech/major-improvements-to-omnilingo/)
|
||||
|
||||
[Blog: dAppling - a New Way to Deploy IPFS Sites in Minutes](https://blog.ipfs.tech/2023-11-dappling/)
|
||||
|
||||
- Introducing a seamless way to launch your code on IPFS, featuring straightforward setup, automatic deployments, and more. [Learn more about it here!](https://blog.ipfs.tech/2023-11-dappling/)
|
||||
|
||||
[Dumb Pipe by number 0](https://www.dumbpipe.dev/)
|
||||
|
||||
- Easy, direct connections that punch through NATs & stay connected as network conditions change. [Learn more here!](https://www.dumbpipe.dev/)
|
||||
|
||||
[Call for submissions: awesome-ipfs](https://github.com/ipfs/awesome-ipfs)
|
||||
|
||||
- This is a community list of awesome projects, apps, tools, and services related to IPFS. We'd love to see more projects added to it, so [submit yours today!](https://github.com/ipfs/awesome-ipfs)
|
||||
|
||||
[Upholding a Free Tier: The IPFS Challenge](https://filebase.com/blog/upholding-a-free-tier-the-ipfs-challenge/)
|
||||
|
||||
- From the Filebase Team: "Four years into our journey at Filebase, we stand amid a shifting technological landscape where continuity and reliability are more valued than ever. In such times, we are not just continuing but reaffirming our pledge to offer a free IPFS tier." [Read the blog post here!](https://filebase.com/blog/upholding-a-free-tier-the-ipfs-challenge/)
|
||||
|
||||
[IPFS-based CDN faster than Akamai in some cases](https://github.com/p2p-cdn/speedtest-site/blob/master/final-report.pdf)
|
||||
|
||||
- A group of students at MIT ran a speedtest of IPFS vs a large web2 CDN, and IPFS was significantly faster for some file sizes! [Check out the full report here.](https://github.com/p2p-cdn/speedtest-site/blob/master/final-report.pdf)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
title: IPFS News Issue 201
|
||||
description: Featuring the announcement of a recent demonstration of the InterPlanetary File System (IPFS) in space!
|
||||
date: 2024-01-23
|
||||
permalink: "/newsletter-201"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Filecoin Foundation Successfully Demonstrates IPFS in Space 🔭**
|
||||
|
||||
The Filecoin Foundation (FF) successfully completed a first-of-its-kind mission demonstrating the InterPlanetary File System (IPFS) in space. The recent demonstration involved sending files from Earth to orbit and back using an implementation of the IPFS protocol designed for space communications.
|
||||
|
||||
<a href="https://fil.org/blog/filecoin-foundation-successfully-deploys-interplanetary-file-system-ipfs-in-space/" class="cta-button">Read the blog post</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Decentralizing DeFi frontends: protecting users and protocol authors](https://www.liquity.org/blog/decentralizing-defi-frontends-protecting-users-and-protocol-authors)
|
||||
|
||||
- A blog post from Liquity that features IPFS and talks about the need for decentralized frontends that are trustless and verifiable. [Read the post here!](https://www.liquity.org/blog/decentralizing-defi-frontends-protecting-users-and-protocol-authors)
|
||||
|
||||
[New Release: Kubo v0.26.0](https://github.com/ipfs/kubo/releases/tag/v0.26.0)
|
||||
|
||||
- Several deprecated commands have been removed
|
||||
- Support optional pin names
|
||||
- jaeger trace exporter has been removed
|
||||
|
||||
[New Release: Boxo v0.17.0](https://github.com/ipfs/boxo/releases/tag/v0.17.0)
|
||||
|
||||
- pinning/pinner: you can now give a custom name when pinning a CID. To reflect this, the Pinner has been adjusted. Note that calling Pin for the same CID with a different name will replace its current name by the newly given name.
|
||||
|
||||
[New Release: Iroh v0.12.0](https://github.com/n0-computer/iroh/releases/tag/v0.12.0)
|
||||
|
||||
- (bytes) Switch to a single directory for the flat store
|
||||
- (net) Add Magicsock::network_change
|
||||
- Usage metrics reporting
|
||||
- Remove derp regions in favor of direct urls
|
||||
- Additional public get utils
|
||||
|
||||
[New Release: OrbitDB v2.0](https://www.npmjs.com/package/@orbitdb/core)
|
||||
|
||||
- This version of OrbitDB replaces js-ipfs with Helia, IPFS's implementation for Javascript.
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly)
|
||||
|
||||
- Help: [Feasibility for Self-Hosting Scientific Datasets?](https://discuss.ipfs.tech/t/feasibility-for-self-hosting-scientific-datasets/17355)
|
||||
- Ecosystem: [Cloudflare IPFS gateway goes premium, longetivity of free version?](https://discuss.ipfs.tech/t/cloudflare-ipfs-gateway-goes-premium-longetivity-of-free-version/17388)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Sendme, built on iroh](https://iroh.computer/sendme)
|
||||
|
||||
- It's like scp without needing to know the IP address. Add some files to sendme, and it will give you a pastable ticket that you can give to anyone who needs your files. Sendme will connect your devices directly & transfer the data without any accounts or configuration. [Learn more here!](https://iroh.computer/sendme)
|
||||
|
||||
[All-in-one Docker image with IPFS node best practices](https://discuss.ipfs.tech/t/all-in-one-docker-image-with-ipfs-node-best-practices/17408)
|
||||
|
||||
- A post in the IPFS community forum about putting together an all-in-one docker image for self hosting an IPFS node / gateway. [Read the forum thread here!](https://discuss.ipfs.tech/t/all-in-one-docker-image-with-ipfs-node-best-practices/17408)
|
||||
|
||||
[What's IPFS and how it compares to BitTorrent](https://norman.life/posts/ipfs-bittorrent)
|
||||
|
||||
- A new blog post from Daniel Norman, Developer Advocate for IPFS, about the differences between IPFS and BitTorrent. [Read the entire post here!](https://norman.life/posts/ipfs-bittorrent)
|
||||
|
||||
[Encrypted Blockstore from Fireproof](https://www.npmjs.com/package/@fireproof/encrypted-blockstore)
|
||||
|
||||
- Multi-writer self-hosted local-first IPFS-compatible blockstore with end-to-end encryption. [Learn more here!](https://www.npmjs.com/package/@fireproof/encrypted-blockstore)
|
||||
|
||||
[Community contribution of nfs mounting as an alternative to fuse in kubo](https://www.youtube.com/watch?v=19FkIxTzavY)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,73 +0,0 @@
|
||||
---
|
||||
title: IPFS News Issue 202
|
||||
description: Featuring the announcement of IPFS Camp 2024 and pre-reregistration for this year's exciting event!
|
||||
date: 2024-02-28
|
||||
permalink: "/newsletter-202"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Pre-register for IPFS Camp 2024 🔭**
|
||||
|
||||
Drumroll please... 🥁 IPFS Camp 2024 is coming soon! This event is for those who want to bend the arc of the Internet to be more open, efficient, and secure.
|
||||
|
||||
🗓️ July 11-13, 2024
|
||||
📍 Brussels, Belgium
|
||||
|
||||
This will be the most exciting IPFS event yet! Connecting builders and users, organized by thematic tracks, and inspired by the in-depth conversations and unbounded energy of previous IPFS gatherings, it will be an event to remember. IPFS Camp 2024 tracks include: Decentralized Apps and Publishing, Public Records and Human Rights, CIDs in the Age of Generative AI, Syncing Bytes at Scale, Libp2p Day... & more!
|
||||
|
||||
<a href="https://lu.ma/preregcamp24" class="cta-button">Pre-register to save the date</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Interplanetary Shipyard needs your help raising $3 million ](https://ipshipyard.gitwallet.co/)
|
||||
|
||||
- The core maintainers of several key IPFS implementations now operate as a separate team in the Protocol Labs network known has Shipyard – and they need your help! They're raising $3M in community contributions to sustain their work as technical stewards in 2024. [Learn more and contribute here!](https://ipshipyard.gitwallet.co/)
|
||||
|
||||
[Strategy for transitioning IPFS chat away from the Filecoin Slack](https://discuss.ipfs.tech/t/strategy-for-transitioning-ipfs-chat-away-from-filecoin-slack/17532)
|
||||
|
||||
- With the IPFS project continuing to mature, there is an increasing need for chat to begin shifting away from Filecoin Slack to its own communication platforms in order to avoid confusion and brand overlap. [Check out the proposal on the forum!](https://discuss.ipfs.tech/t/strategy-for-transitioning-ipfs-chat-away-from-filecoin-slack/17532)
|
||||
|
||||
[New Public Utilities docs page](https://docs.ipfs.tech/concepts/public-utilities/)
|
||||
|
||||
- These utilities make it easier to retrieve data from the IPFS network in resource-constrained environments such as browsers and low-powered devices. [Check out the new page here!](https://docs.ipfs.tech/concepts/public-utilities/)
|
||||
|
||||
[New Release: Kubo v0.27.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.27.md)
|
||||
|
||||
- Gateway: support for /api/v0 is deprecated
|
||||
- IPNS resolver cache's TTL can now be configured
|
||||
- RPC client: deprecated DHT API, added Routing API
|
||||
- Deprecated DHT commands removed from /api/v0/dht
|
||||
- Repository migrations are now trustless
|
||||
|
||||
[New Release: Boxo v0.18.0](https://github.com/ipfs/boxo/releases/tag/v0.18.0)
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly)
|
||||
|
||||
- General: [Setup advice - use case](https://discuss.ipfs.tech/t/setup-advice-use-case/17535)
|
||||
- General: [Updates on advancing IPFS project governance](https://discuss.ipfs.tech/t/updates-on-advancing-ipfs-project-governance/17522)
|
||||
- Comms WG: [Strategy for transitioning IPFS chat away from Filecoin Slack](https://discuss.ipfs.tech/t/strategy-for-transitioning-ipfs-chat-away-from-filecoin-slack/17532)
|
||||
- Protocol: [IPNS discovery using DIDs](https://discuss.ipfs.tech/t/ipns-discovery-using-dids/17539)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Lighthouse announces Desktop app](https://twitter.com/LighthouseWeb3/status/1752002422523019396?s=20)
|
||||
|
||||
- Lighthouse offers perpetual storage on Filecoin and IPFS. Initially a developer tool with SDKs, Lighthouse is now available to any desktop user through their new app. [Learn more and register for the closed beta!](https://twitter.com/LighthouseWeb3/status/1752002422523019396?s=20)
|
||||
|
||||
[4 new demos and tutorials from Agregore](https://agregore.mauve.moe/blog/2023/12/demos-and-tutorials-second-round#webapps-milestone-3)
|
||||
|
||||
- See how to build a basic chat app with the pubsub:// protocol that is part of IPFS, upload full directories, and build a drag-and-drop uploader. [Check out the latest demos here!](https://agregore.mauve.moe/blog/2023/12/demos-and-tutorials-second-round#webapps-milestone-3)
|
||||
|
||||
[DScan: Own Your Identity, Own your Data](https://chromewebstore.google.com/detail/dscan-own-your-identity-o/idpfgkgogjjgklefnkjdpghkifbjenap)
|
||||
|
||||
- Check out this Chrome extension that uploads content to IPFS and generates decentralized QR codes for easy file sharing. Dscan uses DIDs and UCAN for robust, decentralized user permissions. [Download the extension here!](https://chromewebstore.google.com/detail/dscan-own-your-identity-o/idpfgkgogjjgklefnkjdpghkifbjenap)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,55 +0,0 @@
|
||||
---
|
||||
title: IPFS News Issue 203
|
||||
description: Featuring more news about IPFS Camp 2024! 🏕️
|
||||
date: 2024-03-28
|
||||
permalink: "/newsletter-203"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Registration for IPFS Camp 2024 is officially open!**
|
||||
[Register soon and take advantage of a 40% off early bird discount.](https://2024.ipfs.camp/)
|
||||
|
||||
IPFS Camp is for those who want to bend the arc of the Internet to be more open, efficient, and secure. This will be the most exciting IPFS event yet! Connecting builders and users, organized by thematic tracks, and inspired by the in-depth conversations and unbounded energy of previous IPFS gatherings, it will be an event to remember.
|
||||
|
||||
- 🗓️ July 11-13, 2024
|
||||
- 📍 Brussels, Belgium
|
||||
|
||||
<a href="https://2024.ipfs.camp/" class="cta-button">Register Today</a>
|
||||
|
||||
## **Want to Speak at IPFS Camp 2024?**
|
||||
|
||||
We’re looking for talks long and short, as well as workshops and other creative formats, for numerous content tracks. Submit your proposal here:
|
||||
|
||||
<a href="https://airtable.com/appM094R1Ma5HG757/shrWn6XaRgUkYWPm3?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-899mMASAieFLwGglezvFYpc4w7Q8cU2--Dq-xjqOnU9pUEcjTXKe3f8ogOVl9RHWQ-vSMp" class="cta-button">Submit a talk</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[New Release: Kubo v0.28.0](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.28.md)
|
||||
|
||||
- RPC client: removed deprecated DHT API
|
||||
- Gateway: /api/v0 is removed
|
||||
- Removed deprecated Object API commands
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly)
|
||||
|
||||
- Help: [Unable to resolve IPNS name via remote IPFS nodes or public gateways (used to work fine)](https://discuss.ipfs.tech/t/unable-to-resolve-ipns-name-via-remote-ipfs-nodes-or-public-gateways-used-to-work-fine/17658)
|
||||
- Help: [How to upload mutiple file same in a folder](https://discuss.ipfs.tech/t/how-to-upload-mutiple-file-same-in-a-folder/17699/6)
|
||||
- Kubo: [Kubo (go-ipfs) closes db randomly](https://discuss.ipfs.tech/t/kubo-go-ipfs-closes-db-randomly/17683)
|
||||
- Ecosystem: [IPFS governance: launching a provisional Steering Committee](https://discuss.ipfs.tech/t/ipfs-governance-launching-a-provisional-steering-committee/17712/2)
|
||||
- General: [How was everyone’s ETHDenver trip?](https://discuss.ipfs.tech/t/how-was-everyones-ethdenver-trip/17662/4)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Introducing the Filebase Content Delivery Network](https://filebase.com/blog/introducing-the-filebase-content-delivery-network/)
|
||||
|
||||
- "Spanning three continents, the Filebase CDN features multiple Points of Presence (PoPs) in key locations across North America, Europe, and Asia. Leveraging geolocation-based load balancing, the Filebase CDN automatically directs traffic to the nearest data center, minimizing latency and turbocharging content delivery speed—whether over HTTPS or Bitswap. This global network ensures that no matter where users are located, they can access IPFS content quickly and reliably." [Learn more about Filebase's CDN here!](https://filebase.com/blog/introducing-the-filebase-content-delivery-network/)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
title: IPFS News Issue 204
|
||||
description: Welcome to IPFS News 204! Featuring @helia/verified-fetch and the IPFS Camp 2024 track list.
|
||||
date: 2024-04-30
|
||||
permalink: "/newsletter-204"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Register for IPFS Camp 2024**
|
||||
Register soon and take advantage of an 8% off early bird discount.
|
||||
|
||||
IPFS Camp is for those who want to bend the arc of the Internet to be more open, efficient, and secure. This will be the most exciting IPFS event yet! Connecting builders and users, organized by thematic tracks, and inspired by the in-depth conversations and unbounded energy of previous IPFS gatherings, it will be an event to remember.
|
||||
|
||||
- 🗓️ July 11-13, 2024
|
||||
- 📍 Brussels, Belgium
|
||||
|
||||
<a href="https://2024.ipfs.camp/" class="cta-button">Register Today</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Announcing @helia/verified-fetch](https://blog.ipfs.tech/verified-fetch/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- The fetch-like, Web native abstraction for retrieving content from IPFS-compatible networks has been released. [Read the blog post to learn more!](https://blog.ipfs.tech/verified-fetch/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Announcing the IPFS Camp 2024 Track List](https://blog.ipfs.tech/ipfs-camp-2024-track-list/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- To give you a taste of what kinds of topics IPFS Camp will cover this year, we’re excited to share the 2024 track list. If any of the tracks sparks your imagination or gives you an idea for something you’d like to present, be sure to submit a proposal for a talk. We’d love to hear from you! [Check out the track list!](https://blog.ipfs.tech/ipfs-camp-2024-track-list/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Helia Survey](https://airtable.com/appgppDnTDtpyEFhI/pagizuBtddTY0QDEv/form?utm_content=290129180&utm_medium=social&utm_source=twitter&hss_channel=tw-3030006159&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- The Shipyard team leading the development of Helia is conducting a survey to learn about how Helia is used so that we can make it better. Your feedback will help us understand developer needs, challenges, as well as inform our priorities and shape Helia’s roadmap. [Fill out the survey!](https://airtable.com/appgppDnTDtpyEFhI/pagizuBtddTY0QDEv/form?utm_content=290129180&utm_medium=social&utm_source=twitter&hss_channel=tw-3030006159&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Kubo v0.28.0](https://github.com/ipfs/kubo/releases/tag/v0.28.0?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- LAN and Loopback IPs are not announced when not useful, Pin roots are now prioritized when announcing, Sunset deprecated RPCs and features.
|
||||
|
||||
[Rainbow v1](https://github.com/ipfs/rainbow/releases/tag/v1.0.0?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- Performant IPFS gateway based on boxo, also replaced Kubo as backend of public gateways ipfs.io, dweb.link, and trustless-gateway.link
|
||||
|
||||
[Iroh v0.14.0](https://iroh.computer/blog/iroh-0-14-0-dial-the-world?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- Dial by just a Node ID
|
||||
- Faster relay handshakes
|
||||
- Basic Author API
|
||||
- Upgrade redb to v2.0
|
||||
|
||||
[Iroh v0.15.0](https://iroh.computer/blog/iroh-0-15-0-shut-me-down?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- Graceful Shutdown
|
||||
- Integrated Downloader
|
||||
- Expanded Support for dialing by only NodeID
|
||||
- More binaries
|
||||
- Breaking Changes
|
||||
|
||||
[Someguy v0.2](https://github.com/ipfs/someguy/releases/tag/v0.2.0?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Popular on the Forums](https://discuss.ipfs.tech/top?period=monthly&utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- [Local.storage - self hosted w3storage backend](https://discuss.ipfs.tech/t/local-storage-self-hosted-w3storage-backend/17857?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- [Next steps for the IPFS Community Calendar](https://discuss.ipfs.tech/t/next-steps-for-the-ipfs-community-calendar/17849/5?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- [Does ipfs takes more time to upload and download encrypted data?](https://discuss.ipfs.tech/t/does-ipfs-takes-more-time-to-upload-and-download-encrypted-data/17856?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- [Retrieve content using cid from ipfs cluster](https://discuss.ipfs.tech/t/retrieve-content-using-cid-from-ipfs-cluster/17818?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[ProbeLab Network Weekly Reports](https://github.com/plprobelab/network-measurements/tree/master/reports/2023)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[IPFS & libp2p Devs Go Independent: Meet Interplanetary Shipyard](https://blog.ipfs.tech/shipyard-hello-world/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- Learn more about the new independent collective of people maintaining many of the most popular implementations in the IPFS and libp2p ecosystem. [Read the new blog post!](https://blog.ipfs.tech/shipyard-hello-world/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Fireproof Roadmap Update](https://fireproof.storage/posts/roadmap-update/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- The Fireproof team has shared an in-depth update on what they're up to and where they're going. [Check it out!](https://fireproof.storage/posts/roadmap-update/?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
[Celebrating Innovation and Community at NFT.Storage's Landmark Event](https://nft.storage/blog/celebrating-innovation-and-community-at-nft-storages-landmark-event?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
- Recap of NFT.Storage's groundbreaking event at MoMA PS1 during NFT.NYC, where they unveiled a new platform upgrade and launched the NFT.Storage DAO. This blog post explores their commitment to community-driven NFT preservation, highlights from the discussions on the future of arts and NFTs, and how you can join the DAO to contribute to this innovative journey. [Read the blog post!](https://nft.storage/blog/celebrating-innovation-and-community-at-nft-storages-landmark-event?utm_source=hs_email&utm_medium=email&_hsenc=p2ANqtz-_i0pGQB-qDyxAWRjj6mhoMbeL5Q_D5uOoBYG52XQ7Pr8fD8_wMbE_jy-ovyasZ5L4aYY3p)
|
||||
|
||||
## **Have something you want featured? 📥**
|
||||
|
||||
If you have something exciting or important that you think the IPFS community should know about, then you can [submit this form](https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv) to have it be considered for inclusion in the IPFS newsletter.
|
||||
|
||||
<a href="https://airtable.com/appjqlMYucNiOYHl7/shrfPrKe112FW3ucv" class="cta-button">Submit form</a>
|
||||
@@ -1,75 +1,5 @@
|
||||
---
|
||||
data:
|
||||
- title: 'Just released: Kubo 0.32.1!'
|
||||
date: "2024-11-15"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.32.1
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.31.0!'
|
||||
date: "2024-10-16"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.31.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.30.0!'
|
||||
date: "2024-09-11"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.30.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.29.0!'
|
||||
date: "2024-06-10"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.29.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.28.0!'
|
||||
date: "2024-04-15"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.28.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.27.0!'
|
||||
date: "2024-03-04"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.27.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.26.0!'
|
||||
date: "2024-01-22"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.26.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.25.0!'
|
||||
date: "2023-12-14"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.25.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.24.0!'
|
||||
date: "2023-11-08"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.24.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.23.0!'
|
||||
date: "2023-10-05"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.23.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.22.0!'
|
||||
date: "2023-08-08"
|
||||
publish_date: null
|
||||
|
||||
@@ -1,393 +0,0 @@
|
||||
---
|
||||
date: 2024-11-25
|
||||
permalink: /2024-shipyard-improving-ipfs-on-the-web/
|
||||
title: 'IPFS on the Web in 2024: Update From Interplanetary Shipyard'
|
||||
description: 'Update from Interplanetary Shipyard on our efforts to make IPFS work on the Web.'
|
||||
author: Daniel Norman
|
||||
header_image: /ipfs-on-the-web-2024/cover.jpg
|
||||
tags:
|
||||
- ipfs
|
||||
- cid
|
||||
- 'web platform'
|
||||
- browsers
|
||||
- WebRTC
|
||||
- WebTransport
|
||||
- WebSockets
|
||||
- AutoTLS
|
||||
- Let's Encrypt
|
||||
---
|
||||
|
||||
## Update From Interplanetary Shipyard
|
||||
|
||||
Earlier this year, [we introduced Interplanetary Shipyard](https://blog.ipfs.tech/shipyard-hello-world/), as the evolution of the maintainers leading the open-source development of libp2p and the most popular IPFS implementations, tooling and infrastructure.
|
||||
|
||||
In our introduction, we shared our roadmap and vision, a key part of which is to make IPFS work on the web.
|
||||
|
||||
In this blog post, we'll share all the progress we've made since then and what we have planned for the future.
|
||||
|
||||
## IPFS on the Web
|
||||
|
||||
For as long as IPFS has existed, one of the key goals has been to make it possible to use IPFS on the web. That is, **resilient**, **decentralized**, and **verified** data retrieval on the Web.
|
||||
|
||||
But what does it mean for IPFS to work on the Web?
|
||||
|
||||
**Resilient**: Data is retrievable in a browser even if some providers go offline.
|
||||
**Decentralized**: You can connect to other peers from a browser for content routing and retrieval while immune to censorship and chokepoints that disrupt the network.
|
||||
**Verified**: You verify data locally, ensuring integrity without assuming trust (aka trustless).
|
||||
|
||||
Data refers to anything that can be addressed by a CID: files, directories, web apps/dapps, videos, etc.
|
||||
|
||||
While the Web platform has by far the widest reach, it's also the most challenging platform to make IPFS work on due to the inherent constraints of the platform and the discrepancies between browsers.
|
||||
|
||||
Gateways like `ipfs.io` are a double-edged sword, because they make IPFS content accessible to the web, but they also highlight the challenges of IPFS on the web. Initially conceived as a crutch to bootstrap the network until a more decentralized and resilient solution was in place, public gateways became entrenched as the default to access IPFS content on the web to the detriment of the principles of IPFS.
|
||||
|
||||
At [Interplanetary Shipyard](https://ipshipyard.com/), we've been tackling this challenge head on with a number of projects across the libp2p and IPFS stacks to make IPFS on the web a reality:
|
||||
|
||||
- [**Verified Fetch**](#verified-fetch)
|
||||
- [**Service Worker Gateway**](#service-worker-gateway)
|
||||
- [**New browser transports**](#browser-transports)
|
||||
- [**AutoTLS with libp2p.direct**](#autotls-with-libp2p-direct)
|
||||
- [**IPFS over HTTP**](#ipfs-over-http)
|
||||
- [**Browser Developer Tools**](#browser-developer-tools)
|
||||
- [**Delegated Routing HTTP API**](#delegated-routing-http-api)
|
||||
- [**Bitswap improvements**](#bitswap-improvements)
|
||||
- [**libp2p improvements**](#libp2p-improvements)
|
||||
|
||||
Let's take a look at each of these projects in more detail.
|
||||
|
||||
### Verified Fetch
|
||||
|
||||
[Verified Fetch](https://www.npmjs.com/package/@helia/verified-fetch) is a TypeScript library for verified retrieval of IPFS content we [released earlier this year](https://blog.ipfs.tech/verified-fetch/) and built on top of [Helia](https://github.com/ipfs/helia/). We designed it to make IPFS retrieval by CID as easy as the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) that most developers are already familiar with. We focused on getting a seamless developer experience with a simple API, while abstracting away all the complexities of IPFS: **content routing, transports, and verification**.
|
||||
|
||||
Verified Fetch works great for loading content-addressed static assets or sub-resources asynchronously as part of a web app or dapp, for example, images, videos, or JSON.
|
||||
|
||||
From a developer experience standpoint, Verified Fetch follows the following pattern:
|
||||
|
||||
- Take a CID as input
|
||||
- Return a [`Response` object](https://developer.mozilla.org/en-US/docs/Web/API/Response)
|
||||
|
||||
This foundational API surface, while simple, enables a wide range of retrieval use-cases while abstracting away the complexities of data types, content routing, transports and verification. Moreover, returning a `Response` object allows for easy integration with the browser's caching mechanisms and use in [Service Workers](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API).
|
||||
|
||||
Verified Fetch is great for loading content-addressed static assets or "sub-resources" asynchronously, for example, images, videos and even IPLD encoded data.
|
||||
|
||||
<p class="codepen" data-height="300" data-default-tab="js,result" data-slug-hash="VwoWWGQ" data-pen-title="@helia/verified-fetch Direct Retrieval with Libp2p" data-preview="true" data-editable="true" data-user="2color" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
|
||||
<span>See the Pen <a href="https://codepen.io/2color/pen/VwoWWGQ">
|
||||
@helia/verified-fetch Direct Retrieval with Libp2p</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
on <a href="https://codepen.io">CodePen</a>.</span>
|
||||
</p>
|
||||
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
|
||||
|
||||
<br />
|
||||
<a href="https://npmjs.com/package/@helia/verified-fetch" class="cta-button" target="_blank"> Install Verified Fetch</a>
|
||||
|
||||
But what about loading full dapps or websites from IPFS? Unlike static assets, web apps and websites require a way to resolve standard URLs to their corresponding content addressed resources.
|
||||
|
||||
This is where the Service Worker Gateway comes in, which builds on top of Verified Fetch.
|
||||
|
||||
## Service Worker Gateway
|
||||
|
||||
The [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway) is a Web native IPFS gateway that runs in the browser. It implements the [IPFS Gateway spec](https://specs.ipfs.tech/http-gateways/subdomain-gateway/) in a [Service Worker](https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API) and fetches IPFS content directly from providers on the network in addition to verifying it locally.
|
||||
|
||||
In a [previous blog post](https://blog.ipfs.tech/dapps-ipfs/), we looked at how web publishing works with IPFS. This can be summarized as:
|
||||
|
||||
- The web app is static, i.e. just files and directories containing HTML, JS, CSS, images, etc. that make up the app. This is typically the build output of a frontend framework or a static site generator.
|
||||
- The web app's build outputs are encoded with [UnixFS](https://docs.ipfs.tech/concepts/glossary/#unixfs) and addressed by a [CID](https://docs.ipfs.tech/concepts/content-addressing/#cid) which represents the root of the app (see diagram below).
|
||||
- There are IPFS nodes (aka providers) that have the blocks for the CID.
|
||||
|
||||

|
||||
|
||||
### Decentralized Frontends with the Service Worker Gateway
|
||||
|
||||
The Service Worker Gateway unleashes new possibilities for decentralized web publishing:
|
||||
|
||||
- **Decentralized:** with peer-to-peer retrieval.
|
||||
- **Trustless:** with local verification, removing the implicit trust in any given gateway or provider.
|
||||
- **Offline use:** Visited pages are cached in the Cache API, enabling offline support for every static web app.
|
||||
|
||||
<br />
|
||||
<a href="https://inbrowser.link" class="cta-button" target="_blank">Try the Service Worker Gateway</a>
|
||||
|
||||
For example, the IPFS blog is statically generated and has a distinct CID for each version. With the help of Fleek, each [build is encoded with UnixFS, given a CID](https://github.com/ipfs/ipfs-blog/runs/31658981603) and provided to the IPFS network. The [DNSLink](https://docs.ipfs.tech/concepts/dnslink/) record is also updated to the latest release CID.
|
||||
|
||||
Now, instead of using a trusted gateway, e.g. `https://blog-ipfs-tech.ipns.dweb.link/`, you can load the blog using the Service Worker Gateway at [blog-ipfs-tech.ipns.inbrowser.link](https://blog-ipfs-tech.ipns.inbrowser.link).
|
||||
|
||||

|
||||
|
||||
> **Note:** There's an inherent trade off with the Service Worker Gateway: it requires an initial upfront cost of fetching and installing the Service Worker which fetches and verifies data. This is why the first load may be slower than using a trusted gateway.
|
||||
|
||||
### Note on composability
|
||||
|
||||
The Service Worker Gateway also highlights the focus on composability across the JavaScript/TypeScript implementations of IPFS and libp2p:
|
||||
|
||||
The [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway) depends on [Verified Fetch](https://github.com/ipfs/helia-verified-fetch), which depends on [Helia](https://github.com/ipfs/helia) which depends on [js-libp2p](https://github.com/libp2p/js-libp2p).
|
||||
|
||||

|
||||
|
||||
### Service Worker Gateway: What's new
|
||||
|
||||
As we embarked on this project, we focused on getting the basics right:
|
||||
|
||||
- Service Worker lifecycle management with custom gateways and delegated routing configuration.
|
||||
- Subdomain origin isolation according to the [Subdomain Gateway specification](https://specs.ipfs.tech/http-gateways/subdomain-gateway/).
|
||||
- Testing infrastructure to ensure compliance with the specs.
|
||||
- Basic error handling and fallback to trusted gateways.
|
||||
- Correct caching of assets.
|
||||
- Division of responsibilities between the Verified Fetch library and the Service Worker Gateway to ensure they are both useful without duplicating functionality.
|
||||
- HTTP retrieval from recursive gateways and HTTP gateway providers.
|
||||
|
||||
> **Note:** There's a subtle difference between recursive gateways and HTTP gateway providers. Recursive gateways, like `ipfs.io` and `trustless-gateway.link`, will fetch content by CID from providers when the content is not locally available.
|
||||
> HTTP gateway providers on the other hand, are IPFS HTTP gateways discovered via the [IPNI](https://docs.ipfs.tech/concepts/ipni/) (with the `transport-ipfs-gateway-http` protocol) that only return blocks for CIDs they have.
|
||||
|
||||
Over the last few months, we've been improving the reliability and user experience. Most importantly, we've added support for direct peer-to-peer retrieval with js-libp2p under the hood. This means that the Service Worker Gateway can now leverage a broader set of provider peers that have either WebTransport or Secure WebSocket enabled.
|
||||
|
||||
This brings us to the next topic: **browser transports**, which play a crucial role in making both IPFS and libp2p on the web a reality.
|
||||
|
||||
## Browser transports
|
||||
|
||||
Browser transports (protocols) are the bread and butter of the web and the Achilles heel of IPFS on the web. If you can't communicate with other peers, you can't do much.
|
||||
|
||||
Browsers communicate over the internet using a number of transport protocols, each with their own strengths and weaknesses. Assuming a web app is in a [Secure Context](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts), i.e., served over HTTPS as most modern web apps are, the following transport protocols are available:
|
||||
|
||||
- **HTTPS**: Request/Response HTTP over TLS.
|
||||
- **Secure WebSocket**: Secure bidirectional streaming communication over WebSockets.
|
||||
- **WebRTC**: Initially conceived for real-time browser-to-browser communication, e.g. for video, audio, and data streaming.
|
||||
- **WebTransport**: A QUIC based replacement for WebSockets.
|
||||
|
||||
The following table summarizes the capabilities of each transport:
|
||||
|
||||
| | Bi-directional streaming | Requires TLS Certificate and domain | Widely supported | Useable in Service Worker | Browser-to-Browser |
|
||||
| ---------------- | ------------------------ | ----------------------------------- | ---------------- | ------------------------- | ------------------ |
|
||||
| HTTPS | ❌ | ✅ | ✅ | ✅ | ❌ |
|
||||
| Secure WebSocket | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| WebRTC | ✅ | ❌ | ✅ | ❌ | ✅ |
|
||||
| WebTransport | ✅ | ❌ | ❌ | ✅ | ❌ |
|
||||
|
||||
> **Note:** while streaming is technically possible with HTTPS, browsers don't allow reading from the response until the request has been fully sent. See [this issue](https://github.com/whatwg/fetch/issues/1254) for more details.
|
||||
|
||||
### HTTPS and Secure WebSockets
|
||||
|
||||
HTTP is widely supported in browsers and implementations of IPFS. Perhaps most common is the [IPFS HTTP Gateway](https://docs.ipfs.tech/reference/http/gateway/#trusted-vs-trustless), a general purpose retrieval API with HTTP semantics that is broadly used in IPFS implementations, tooling and infrastructure.
|
||||
|
||||
#### Request/Response vs Bi-directional streaming
|
||||
|
||||
Request/response protocols like HTTP are not very well suited for streaming protocols like [Bitswap](https://docs.ipfs.tech/concepts/bitswap/). WebSocket (and WebRTC and WebTransport), are bi-directional streaming protocols and are well suited for libp2p based protocols like Bitswap. What's more, WebSockets are supported in all modern browsers and are compatible with Service Workers.
|
||||
|
||||
#### TLS certificates for HTTP and WebSockets
|
||||
|
||||
Where things get slightly tricky is TLS for **both HTTP and WebSockets**, i.e. HTTPS and Secure WebSockets, which are required by Secure Contexts and Service Workers.
|
||||
|
||||
HTTPS and Secure WebSockets require a CA-signed TLS certificate and a domain, which most peers in the IPFS network do not have by default.
|
||||
|
||||
To address this, we've been working on a project to automate the issuance of wildcard Let's Encrypt TLS certificates for all publicly dialable IPFS nodes. More on that in the [AutoTLS](#auto-tls-with-libp2pdirect) section below.
|
||||
|
||||
### WebRTC
|
||||
|
||||
WebRTC is a browser-to-browser communication protocol, e.g. for video, audio, and data streaming.
|
||||
|
||||
In the context of IPFS and libp2p, there are two implementations of [WebRTC](https://github.com/libp2p/specs/tree/master/webrtc):
|
||||
|
||||
- **WebRTC:** for browser-to-browser communication.
|
||||
- **WebRTC-Direct:** for browser-to-server communication without the need for trusted TLS certificates.
|
||||
|
||||
The spec for [WebRTC for browser-to-browser communication in libp2p](https://github.com/libp2p/specs/blob/master/webrtc/webrtc.md) was ratified last year and includes a decentralized signalling mechanism for exchanging SDPs that leverages Circuit Relays. We've written an [extensive guide](https://docs.libp2p.io/guides/getting-started/webrtc/) to help you get started and also ran a workshop at IPFS Camp. It's also used by [Universal Connectivity](https://github.com/libp2p/universal-connectivity) and [IPFS Share](https://share.ipfs.io) to demonstrate the possibilities of browser-to-browser communication.
|
||||
|
||||
We've also seen the ecosystem thrive with projects like [Topology](https://www.youtube.com/watch?v=2FFjJ-jBymQ), [OrbitDB](https://github.com/orbitdb/orbitdb), and [Canvas](https://canvas.xyz/) that rely on js-libp2p and WebRTC as the foundation for their browser-to-browser communication.
|
||||
|
||||
It's also worth noting that WebRTC is the only browser transport with a mechanism for NAT hole-punching, which is the process of establishing a direct connection between two peers through a network address translator (NAT). This is a crucial part of establishing a direct connection between two peers in a decentralized network like IPFS.
|
||||
|
||||
### WebRTC-Direct
|
||||
|
||||
WebRTC-Direct was designed a transport protocol to allow browser-to-server communication without the need for a domain name and CA-signed TLS certificates.
|
||||
|
||||
WebRTC-direct is stable as of [go-libp2p v0.36.1](https://github.com/libp2p/go-libp2p/releases/tag/v0.36.1) and enabled by default in [Kubo as of 0.30.0](https://github.com/ipfs/kubo/releases/tag/v0.30.0).
|
||||
|
||||
This is a huge milestone, because it means that browsers can dial publicly reachable IPFS nodes with WebRTC-direct enabled without TLS certificates or domain names. We therefore recommend upgrading to the latest version of Kubo to take advantage of this.
|
||||
|
||||
### Limits of WebRTC in browsers
|
||||
|
||||
There are two caveats with WebRTC in browsers:
|
||||
|
||||
- WebRTC isn't available in Service Workers.
|
||||
- [Chrome limits the number of WebRTC connections per window to 500](https://issues.chromium.org/issues/41378764) after which it will prevent establishing new connections.
|
||||
|
||||
### WebTransport
|
||||
|
||||
[Two years ago, the IPFS and libp2p projects made a bet on the promise of WebTransport](https://blog.libp2p.io/2022-12-19-libp2p-webtransport/) and it's been a bumpy road. WebTransport is a promising protocol, especially for libp2p and IPFS, because it allows bi-directional streaming communication with many modern improvements over WebSockets, **without the need for CA-signed certificates and a domain**. This was a game changer, since most peers in the IPFS network do not have a domain name.
|
||||
|
||||
However, the WebTransport specification is still in draft, and browser implementations have had a [number of bugs and issues](https://github.com/libp2p/js-libp2p/issues/2572), that we've been working with the browser vendors to address. As such, browser compatibility breaks as soon as the interoperability target changes.
|
||||
|
||||
While we still believe in the longer term promise of WebTransport, we've reoriented our immediate priorities to WebRTC-Direct (which is now available) and Secure WebSockets (see [AutoTLS](#autotls-with-libp2pdirect) below) . Nonetheless, we continue to work with browser vendors and standard bodies to get WebTransport to a stable and interoperable state.
|
||||
|
||||
## AutoTLS with libp2p.direct
|
||||
|
||||
AutoTLS is a new feature that significantly improves how browsers (Helia, Service Worker) can connect to Kubo nodes.
|
||||
|
||||
As mentioned above, Secure WebSockets is the only streaming transport that works reliably in Service Workers, but requires a TLS certificate and domain.
|
||||
|
||||
To overcome this, the Shipyard team has been working on a project to automate the issuance of wildcard TLS certificates for publicly dialable Kubo nodes. This way, nodes can use [Secure WebSockets libp2p transport](https://github.com/libp2p/specs/blob/master/websockets/README.md) without needing to register a domain name.
|
||||
|
||||
We call this service **AutoTLS** and it's powered by the `libp2p.direct` domain.
|
||||
|
||||
[AutoTLS](https://github.com/ipfs/kubo/blob/master/docs/config.md#autotls) enables publicly reachable Kubo nodes, i.e. nodes dialable from the public internet, to get a wildcard TLS certificate unique to their PeerID at `*.<PeerID>.libp2p.direct` without needing to register and configure a domain name. This enables direct libp2p connections and direct retrieval of IPFS content from browsers using Secure WebSockets.
|
||||
|
||||
### How AutoTLS works
|
||||
|
||||
Under the hood, the infrastructure behind `libp2p.direct` has two roles:
|
||||
|
||||
- An [ACME DNS-01 Challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) broker for getting wildcard TLS certificate for `*.[PeerID].libp2p.direct`. To do so it authenticates PeerIDs requesting certificates, verifies their network reachability and sets the TXT DNS record for the [ACME challenge](https://letsencrypt.org/docs/challenge-types/#dns-01-challenge) at `_acme-challenge.<PeerID>.libp2p.direct`.
|
||||
|
||||

|
||||
|
||||
- The authoritative DNS Server for `*.libp2p.direct`. Notably, the IP addresses it resolves to are encoded in the DNS name, e.g. `1-2-3-4.<peerID>.libp2p.direct` resolves to the A record with the IP `1.1.1.1`. This keeps the DNS server stateless and simple to operate while ensuring that even when a Kubo node's IP address changes, it's resolvable without coordination.
|
||||
|
||||

|
||||
|
||||
> **Note:** AutoTLS is not a replacement for Let's Encrypt or other TLS certificate authorities. It's a complementary service for getting a TLS certificate for your Kubo node's unique PeerID without the need for your own domain name.
|
||||
|
||||
AutoTLS is provided as a public good service and operated by [Interplanetary Shipyard](https://ipshipyard.com) and is available on an [opt-in basis with Kubo 0.32.1](https://github.com/ipfs/kubo/blob/v0.32.1/docs/changelogs/v0.32.md#-autotls-automatic-certificates-for-libp2p-websockets-via-libp2pdirect).
|
||||
|
||||
We're also adding support for AutoTLS in [js-libp2p](https://github.com/libp2p/js-libp2p/pull/2800), which would allow the JavaScript ecosystem to also reap the benefits of AutoTLS.
|
||||
|
||||
AutoTLS is available in [Kubo v0.32.1](https://github.com/ipfs/kubo/releases/tag/v0.32.1) or [IPFS Desktop v0.40.0](https://github.com/ipfs/ipfs-desktop/releases/tag/v0.40.0) (which includes Kubo). We encourage you to try it out and [share your feedback](https://github.com/ipfs/kubo/issues/10560).
|
||||
|
||||
<br />
|
||||
<a href="https://github.com/ipfs/ipfs-desktop/releases/tag/v0.40.0" class="cta-button" target="_blank">Download IPFS Desktop</a>
|
||||
|
||||
## IPFS over HTTP
|
||||
|
||||
A theme that runs through many of the projects in this blog post is the use of HTTP as the blueprint for interoperability.
|
||||
|
||||
This is driven by the following reasons:
|
||||
|
||||
- HTTP is ubiquitous in the web ecosystem and is well understood by developers.
|
||||
- HTTP is supported in all modern browsers and is compatible with Service Workers.
|
||||
- HTTP has powerful caching primitives with wide adoption across both infrastructure providers and open source infrastructure, opening the door to flexible caching which matches well with the immutable nature of content addressed data.
|
||||
|
||||
More about this in a recent talk from IPFS Camp:
|
||||
|
||||
@[youtube](4GwxrQ9Z3Bk)
|
||||
|
||||
## Browser developer tools
|
||||
|
||||
Along with the new browser transports, we've also been working on a number of developer tools to make it easier to debug web applications that rely on libp2p and IPFS. Historically, debugging IPFS and libp2p in the browser meant enabling logging and then grepping through the logs.
|
||||
|
||||
We've now released a [browser extension](https://github.com/libp2p/js-libp2p-devtools) that allows you to inspect the libp2p node and interact with it straight from the browser developer tools.
|
||||
|
||||
So how does it work? The browser extension pairs with a [metrics implementation](https://github.com/libp2p/js-libp2p/tree/main/packages/metrics-devtools) that you add to your js-libp2p node. The extension then fetches the metrics from the node over RPC and displays them in the browser developer tools.
|
||||
|
||||
This relies on the same [metrics interface](https://github.com/libp2p/js-libp2p/blob/main/packages/interface/src/metrics/index.ts) that js-libp2p exposes, which can also be used for monitoring js-libp2p with Prometheus (in Node.js)
|
||||
|
||||
Learn more about the browser extension in this talk from IPFS Camp:
|
||||
|
||||
@[youtube](JChwfTA6SX0)
|
||||
|
||||
## Delegated Routing HTTP API
|
||||
|
||||
The [Delegated Content Routing HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) allows IPFS nodes to offload content and peer routing to another process/server using an HTTP API. In addition, it allows for composability and experimentation with different routing systems.
|
||||
|
||||
Since the spec was [ratified in 2022](https://specs.ipfs.tech/ipips/ipip-0337/), it's been positively received and gradually implemented and integrated in the ecosystem:
|
||||
|
||||
- The IPFS Foundation provides a [public delegated routing endpoint](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing) backed by [someguy](https://github.com/ipfs/someguy) with the URL `https://delegated-ipfs.dev/routing/v1` that is operated by Interplanetary Shipyard.
|
||||
- The [cid.contact](https://cid.contact) network indexer exposes a compatible `/routing/v1/providers` endpoint for finding providers for a CID.
|
||||
- Helia has both a [client](https://github.com/ipfs/helia-delegated-routing-v1-http-api/tree/main/packages/client) and a [server implementation](https://github.com/ipfs/helia-delegated-routing-v1-http-api/tree/main/packages/server) of the Delegated Routing HTTP API. The client is configured by default in [Helia](https://github.com/ipfs/helia) with the public Delegated Routing endpoint.
|
||||
- js-libp2p also supports the [Delegated Routing HTTP API with the Helia client](https://github.com/libp2p/js-libp2p/blob/main/doc/CONFIGURATION.md#setup-with-delegated-content-and-peer-routing)
|
||||
- The [Boxo](https://github.com/ipfs/boxo/tree/main/routing/http) SDK comes with a client and server implementation of the Delegated Routing HTTP API which is used by Kubo
|
||||
- Kubo both uses the Delegated Routing HTTP API for querying the IPNI. Additionally, you can expose a delegated routing endpoint since [Kubo v0.23](https://github.com/ipfs/kubo/blob/ecb81c92221c8c563d7d245df193dc96163a76d0/docs/changelogs/v0.23.md#self-hosting-routingv1-endpoint-for-delegated-routing-needs).
|
||||
|
||||
### How Delegated Routing HTTP API helps IPFS on the web?
|
||||
|
||||
The [Distributed Hash Table (DHT)](https://docs.ipfs.tech/concepts/dht/) is the default routing system for IPFS and is used for finding peers and providers for CIDs in the network. Traversing the DHT however requires opening connections to around log₂(N) peers in the network, where N is the total number of peers. For a network such as IPFS, this can easily mean establishing connections to tens of peers just to find a single provider.
|
||||
|
||||
The Delegated Routing HTTP API empowers resource constrained clients like web browsers by significantly reducing the number of network connections necessary to fetch content addressed data directly from provider peers.
|
||||
|
||||
In other words, you can reduce the number of connections to 1 by offloading routing to another process/server using the HTTP API, e.g. the public goods endpoint at `https://delegated-ipfs.dev/routing/v1`.
|
||||
|
||||
### Introducing filtering for Provider and Peer records
|
||||
|
||||
There are many cases where most of the results from the Delegated Routing HTTP API are not actionable by clients, because the client does not support either the **network transport protocol**, e.g. TCP, or the **transfer protocol**, e.g. GraphSync.
|
||||
|
||||
[IPIP-484](https://specs.ipfs.tech/ipips/ipip-0484/) introduces filtering for Provider and Peer records, which allows for more efficient routing. For browsers, IPIP-484 reduces the overhead of unactionable results returned by the API. For Kubo it means less load establishing connections to peer that only support GraphSync. Moreover, it makes [manual debugging easier](https://delegated-ipfs.dev/routing/v1/providers/bafybeicklkqcnlvtiscr2hzkubjwnwjinvskffn4xorqeduft3wq7vm5u4?filter-protocols=transport-bitswap,unknown&filter-addrs=!p2p-circuit,webrtc-direct,wss,tls) with the filters in the query parameters.
|
||||
|
||||
IPIP-484 is already implemented in [Boxo](https://github.com/ipfs/boxo/tree/main/routing/http) SDK, [someguy](https://github.com/ipfs/someguy), [Helia](https://github.com/ipfs/helia-delegated-routing-v1-http-api), [Kubo](https://github.com/ipfs/kubo), and [Rainbow](https://github.com/ipfs/rainbow).
|
||||
|
||||
## Bitswap improvements
|
||||
|
||||
[Bitswap](https://specs.ipfs.tech/bitswap-protocol/) is the most prevalent data transfer protocol in the IPFS network. Our experience operating the public IPFS Gateways on behalf of the IPFS Foundation gives us an opportunity to measure and optimize Bitswap at scale.
|
||||
|
||||
Based on tracing and metrics from the public IPFS Gateways, we've [identified and released](https://github.com/ipfs/boxo/blob/main/CHANGELOG.md) a number of performance improvements to the [Go implementation of Bitswap in Boxo](https://github.com/ipfs/boxo/tree/main/bitswap), which is used by Kubo and Rainbow.
|
||||
|
||||
## Libp2p improvements
|
||||
|
||||
Libp2p is a dependency of most of the above projects and is the bedrock of the entire IPFS stack.
|
||||
|
||||
Beyond the work mentioned earlier on transports, we've also been working on numerous improvements and specs to libp2p that support the above projects. Check out the [js-libp2p Roadmap](https://github.com/libp2p/js-libp2p/blob/main/ROADMAP.md) for more details.
|
||||
|
||||
### AutoNAT v2
|
||||
|
||||
[AutoNAT v2](https://github.com/libp2p/specs/blob/autonat-v2/autonat/autonat-v2.md) is a new version of the AutoNAT protocol that provides more precise reachability information for nodes.
|
||||
|
||||
It provides higher granularity in determining reachability for the node, e.g. AutoNAT v2 allows us to determine reachability for all combinations of (`ipv4/ipv6`, `tcp/udp`).
|
||||
|
||||
AutoNAT v2 is implemented in [go-libp2p](https://github.com/libp2p/go-libp2p/releases/tag/v0.36.1) and [the rollout to the public swarm started in Kubo v0.30.0](https://github.com/ipfs/kubo/blob/v0.30.0/docs/changelogs/v0.30.md#autonat-v2-service-introduced-alongside-v1).
|
||||
|
||||
While not directly related to IPFS on the web, AutoNAT v2 improves the network layer of non-browser IPFS nodes, which is a crucial part of the IPFS network infrastructure.
|
||||
|
||||
### NAT Hole Punching
|
||||
|
||||
A number of fixes and improvements to [NAT hole punching](https://blog.ipfs.tech/2022-01-20-libp2p-hole-punching/) have been implemented in go-libp2p which should help improve connectivity of IPFS nodes behind NATs.
|
||||
|
||||
> **Note:** NAT hole punching in browsers is different from NAT hole punching in QUIC and TCP. Browsers use [ICE with STUN servers for WebRTC NAT traversal](https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Protocols#ice), while non-browser libp2p peers use [Circuit Relay v2](https://docs.libp2p.io/concepts/nat/circuit-relay-v2/) and [DCUtR](https://docs.libp2p.io/concepts/nat/dcutr/).
|
||||
|
||||
### js-libp2p Amino DHT Bootstrapper
|
||||
|
||||
The [js-libp2p Amino DHT Bootstrapper](https://github.com/libp2p/js-libp2p-amino-dht-bootstrapper) is a new Amino DHT bootstrapper like the go-libp2p and rust-libp2p, but implemented in js-libp2p.
|
||||
|
||||
Beyond the obvious benefit of having another bootstrapper as a public good, it also allows us to stress test js-libp2p with high traffic. By monitoring with Prometheus, we've been able to find and resolve a number of bugs in several js-libp2p packages.
|
||||
|
||||
The bootstrapper supports TCP and Secure WebSockets and can be connected to at `/dnsaddr/va1.bootstrap.libp2p.io/p2p/12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8`.
|
||||
|
||||
### libp2p over HTTP
|
||||
|
||||
[Libp2p over HTTP](https://github.com/libp2p/specs/tree/master/http) defines how libp2p peers can use and expose libp2p protocols over HTTP. This has the benefit of allowing a wider variety of nodes to participate in the libp2p network, in addition to providing more interoperability opportunities.
|
||||
|
||||
For example, the [backend for the AutoTLS service](https://github.com/ipshipyard/p2p-forge) exposes an API which uses libp2p over HTTP to authenticate libp2p Peer IDs in HTTP requests.
|
||||
|
||||
More on this in a talk from IPFS Camp:
|
||||
@[youtube](CNZBzt5tFvg)
|
||||
|
||||
### WebSockets single encryption
|
||||
|
||||
Historically, Secure WebSockets in libp2p involved double encryption:
|
||||
|
||||
- First, a Secure WebSocket connection is secured using a CA-signed TLS certificate tied to a hostname.
|
||||
- Then, on the libp2p layer, the connection is authenticated and encrypted again using [Noise](https://noiseprotocol.org/) to prevent [MITM attacks](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) by authenticating the libp2p Peer ID.
|
||||
|
||||
While Noise is necessary for Peer ID authentication, it's not strictly needed for encryption. Seeing as double encryption is obviously suboptimal in terms of resource consumption, we've been working on an optimization to [introduce explicit opt-in delegation of encryption to TLS](https://github.com/libp2p/specs/pull/625).
|
||||
|
||||
At the time of writing, constrainsts in the WebSocket API prevent this from being implemented. If ratified and implemented, this optimization should reduce the computational overhead of each Secure WebSocket connection which can add up when opening many connections.
|
||||
|
||||
## What's next?
|
||||
|
||||
As we mark this milestone, we're also looking ahead to the next phase of our work.
|
||||
|
||||
There are several areas where we'll be focusing our efforts in the coming months:
|
||||
|
||||
- Productionising of AutoTLS infrastructure and integrations in Kubo and other IPFS implementations
|
||||
- HTTP Retrieval in Boxo/Kubo
|
||||
- More examples, documentation, and guides
|
||||
- Improved error handling in the Service Worker Gateway
|
||||
- Integration of the Service Worker Gateway into IPFS Companion
|
||||
|
||||
## Support our work
|
||||
|
||||
Interplanetary Shipyard is a small team of highly experienced full-time maintainers. If you use IPFS and libp2p, please consider [supporting our work](https://ipshipyard.gitwallet.co/).
|
||||
|
||||
## Summary
|
||||
|
||||
All the above projects are either complete or nearing completion. This is the result of arduous collaboration across both the libp2p and IPFS stacks in addition to standard bodies and browser vendors.
|
||||
|
||||
**Resilient, decentralized, and verified** IPFS retrieval on the web is finally a reality.
|
||||
|
||||
This breadth and reach of this work is only possible because of the open-source nature of the IPFS and libp2p projects. But it also underscores the importance of funding the Interplanetary Shipyard team so that we can continue to shepherd these efforts across the ecosystem.
|
||||
|
||||
🍎 We're excited to see these projects come to fruition and can't wait to see what the IPFS community builds on top of them.
|
||||
@@ -1,116 +0,0 @@
|
||||
---
|
||||
title: 'IPFS & libp2p Devs Go Independent: Meet Interplanetary Shipyard'
|
||||
|
||||
description: 'Meet the team behind Interplanetary Shipyard, the newly created entity of many core maintainers behind the most popular implementations of IPFS and libp2p.'
|
||||
author: Adin Schmahmann
|
||||
|
||||
date: 2024-04-08
|
||||
permalink: '/shipyard-hello-world/'
|
||||
header_image: '/shipyard-hello-world.png'
|
||||
tags:
|
||||
- 'ipfs'
|
||||
- 'libp2p'
|
||||
- 'shipyard'
|
||||
- 'interplanetary shipyard'
|
||||
---
|
||||
|
||||
*Last November, Protocol Labs, where IPFS was invented and incubated, [announced its commitment to decentralizing project governance](https://protocol.ai/blog/advancing-ipfs-and-libp2p-governance/). In this post, you'll hear from Adin Schmahmann of Interplanetary Shipyard, introducing the new team, its roadmap, and what this means for the IPFS community.*
|
||||
|
||||
Since its release nearly ten years ago, IPFS has become the connective tissue that powers the infrastructure layer for the decentralized web and connects web2 to web3. Well over 50 million monthly active users access IPFS-based applications, from ENS addresses (~90% of content hashes) to NFTs to blockchains to IoT to enterprise applications. IPFS has always been an open, decentralized, censorship-resistant protocol, and now the project itself is increasingly decentralized too.
|
||||
|
||||
|
||||
Now we’re delighted to announce our own "exit to community": [Interplanetary Shipyard](https://ipshipyard.com/), an **independent collective of people maintaining many of the most popular implementations in the IPFS and libp2p ecosystem**.
|
||||
|
||||
|
||||
Our founding team includes many longtime maintainers of widely-used IPFS and libp2p implementations and tools. Shipyard is laser-focused on supporting users of the open-source projects in the Interplanetary stack. We are committed to building bridges between web2 and web3 through open-source innovation. We work directly with teams building on IPFS and libp2p, both to troubleshoot and improve current implementations, and also to inform our public goods roadmap. We are registered as a Delaware nonstock corporation.
|
||||
|
||||
|
||||
Our current set of implementations maintained by Shipyard include:
|
||||
|
||||
<table style="width: 100%; border-collapse: collapse;">
|
||||
<tr style="border-width: thin; border-color: #888; text-align: center;">
|
||||
<td colspan="2" style="border-width: thin; border-color: #888;"><strong>IPFS</strong></td>
|
||||
<td style="border-width: thin; border-color: #888; text-align: center;"><strong>libp2p</strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td rowspan="2" style="border-width: thin; border-color: #888; padding: .5rem;">
|
||||
<p><a href="https://github.com/ipfs/boxo/#readme">Boxo</a> <small>(GO SDK)</small></p>
|
||||
<p><a href="https://github.com/ipfs/kubo/#readme">Kubo</a> <small>(Server, Desktop, Brave)</small></p>
|
||||
<p><a href="https://github.com/ipfs/rainbow/#readme">Rainbow</a> <small>(Gateway impl.)</small></p>
|
||||
<p><a href="https://github.com/ipfs/someguy#readme">Someguy</a> <small>(Router impl.)</small></p>
|
||||
<p><a href="https://github.com/ipfs/helia#readme">Helia</a> <small>(JS SDK)</small></p>
|
||||
<p><a href="https://github.com/ipfs/helia-verified-fetch#readme">verified-fetch</a> <small>(Web API for JS)</small></p>
|
||||
<p><a href="https://github.com/ipfs-shipyard/service-worker-gateway#readme">Service Worker Gateway</a> <small>(impl. WIP)</small></p>
|
||||
<p><a href="https://badbits.dwebops.pub/">Bad Bits Denylist</a> <s</p>
|
||||
</td>
|
||||
<td rowspan="2" style="border-width: thin; border-color: #888; padding: .5rem;">
|
||||
<p><a href="https://github.com/ipfs/ipfs-companion#readme">IPFS Companion</a> <small>(browser extension)</small></p>
|
||||
<p><a href="https://github.com/ipfs/ipfs-desktop#readme">IPFS Desktop</a> <small>(Windows/macOS/Linux)</small></p>
|
||||
<p><a href="https://ipfscluster.io/">IPFS Cluster</a> <small>(on hold)</small></p>
|
||||
<p><a href="https://docs.ipfs.tech/concepts/public-utilities/#public-ipfs-gateways">ipfs.io</a> <small>(public utility)</small></p>
|
||||
<p><a href="https://docs.ipfs.tech/concepts/public-utilities/#public-ipfs-gateways">dweb.link</a> <small>(public utility)</small></p>
|
||||
<p><a href="https://docs.ipfs.tech/concepts/public-utilities/#public-ipfs-gateways">trustless-gateway.link</a> <small>(public utility)</small></p>
|
||||
<p><a href="https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing">delegated-ipfs.dev</a> <small>(public utility)</small></p>
|
||||
<p><a href="https://docs.ipfs.tech/concepts/public-utilities/#amino-dht-bootstrappers">Amino DHT</a> <small>(public utility)</small></p>
|
||||
<p><a href="https://stats.ipfs.network">IPFS Measurements</a></p>
|
||||
</td>
|
||||
<td rowspan="2" style="border-width: thin; border-color: #888; padding: .5rem;">
|
||||
<p><a href="https://github.com/libp2p/go-libp2p#readme">go-libp2p</a></p>
|
||||
<p><a href="https://github.com/libp2p/js-libp2p#readme">js-libp2p</a></p>
|
||||
<p><a href="https://github.com/libp2p/rust-libp2p#readme">rust-libp2p</a></p>
|
||||
<p>libp2p Measurements</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr></tr>
|
||||
</table>
|
||||
|
||||
We have an extensive [initiative roadmap](https://ipshipyard.com/initiatives) and are eager to get more input from the developer community. To shout out just a few ideas we’re working on:
|
||||
|
||||
* [Reliable, decentralized, and verified retrieval of CIDs](https://ipshipyard.com/initiatives/reliable-decentralized-and-trustless-browser-fetching-of-ipfs-content) (content identifiers) in browsers. The idea is to allow web browsers to fetch CIDs in a verifiable and trustless manner without being vulnerable to centralized chokepoints. You can participate and follow along with this work in the [IPFS dApps Working Group](https://github.com/ipfs/dapps-wg).
|
||||
|
||||
* [IPFS for pioneers](https://ipshipyard.com/initiatives/ipfs-for-pioneers-enable-building-interoperable-ipfs-systems-using-http-protocols). We aim to enable the building of interoperable IPFS systems using extremely minimal HTTP-based protocols so that building IPFS-compatible tooling in something like Python (that doesn’t have much IPFS or libp2p tooling today) is super easy and appealing.
|
||||
* [Self-service tooling for debugging IPFS request handling](https://ipshipyard.com/initiatives/self-service-tooling-for-debugging-ipfs-request-handling). The idea here is that a user can hit a Boxo-based HTTP gateway and if they experience an error, get a link to download an IPFS request trace. They can then use easy tooling locally or centrally hosted to pinpoint the issue.
|
||||
|
||||
**About Shipyard**
|
||||
IPFS is a big project with big ambitions of being the essential content addressing layer for the next generation of the internet. That ecosystem comes with a sprawling set of resources that IPFS users today depend on in some way, including:
|
||||
|
||||
* People and expertise
|
||||
* Applications
|
||||
* Libraries
|
||||
* Networks
|
||||
* Infrastructure
|
||||
|
||||
Think of Shipyard as the union of dockworkers who send ships (projects) out onto the ocean of the distributed web, well-built and equipped with all they need to sail. The next era of the internet is still in its infrastructure phase; IPFS has already positioned itself as one of the core infrastructure layers for the next generation of the internet, and these implementations will be working with the foundation to continue to steward the project.
|
||||
|
||||
We want the community to inform how we grow and sustain ourselves, and are eager for community input on our roadmap. We believe the builders growing IPFS, libp2p, and ProbeLab will thrive best together, under their own roof.
|
||||
|
||||
So, a few questions might arise next.
|
||||
|
||||
**Why now?**
|
||||
|
||||
The set of projects leveraging IPFS and libp2p is now so broad and diverse that it exceeds the purview of one company. Open-source projects need to be managed and owned by their community.
|
||||
|
||||
Consider the precariousness of core IPFS development being tied to a single company, and thus a single funding source. What if that company experiences a change in strategy? What if that funding source decides to prioritize something different from what the IPFS community believes is most important? In web2, the model for supporting and promoting open-source projects was to get the largest centralized players to pay their own employees to maintain the tooling. What does that model look like for the next generation of the internet?
|
||||
|
||||
|
||||
We want to let the community decide. We believe putting control of the IPFS stack in the hands of an independent collective will foster better resiliency, transparency, open-protocol governance, and long-term future health. By **operating independently while collaborating publicly**, we will build alongside other technical teams that rely on this essential infrastructure.
|
||||
|
||||
**Who maintains and funds this work?**
|
||||
|
||||
We're grateful to Protocol Labs, our anchor financial partner for 2024-2025, for its continued support. We’re thankful as well to our early ecosystem supporters and patrons including Optimism's RetroPGF grants, Cloudflare, Pinata, Fission, and CoopHive.
|
||||
|
||||
|
||||
|
||||
We’re exploring multiple avenues for financial support, and in keeping with our new community collective approach, we’re thinking in public about what those avenues could be: public goods funding, community grants, commercial services, crypto-native funding, and more.
|
||||
|
||||
|
||||
**Our team is raising an additional $3 million in community contributions to sustain our work as technical stewards in 2024**. Here’s how you can support Shipyard:
|
||||
|
||||
* **Support Public Goods Maintenance** \
|
||||
If you or your project depends upon IPFS or libp2p, we invite you to consider contributing toward the ongoing maintenance of these important protocols as a public good. You can donate directly to IPFS or libp2p through the [Open Impact Foundation](https://openimpact.foundation/).
|
||||
* **Hire Shipyard for Commercial Services** \
|
||||
In addition to public good funding, we are also beginning to support commercial service agreements for our core users, including service tiers, contracted support, and other embedded engineering work. You can check out our [commercial services tiers](https://ipshipyard.gitwallet.co/) or reach out directly if you have a project you’d like to collaborate with us on.
|
||||
|
||||
|
||||
We're excited for Shipyard's opportunity to strengthen the IPFS and libp2p ecosystems through community feedback and patronage. If you would like to get more involved we're in the [IPFS](https://docs.ipfs.tech/community/#get-involved) and [libp2p](https://discuss.libp2p.io/) forums, and you can reach us at `contact [AT] ipshipyard.com`.
|
||||
|
||||
@@ -174,13 +174,13 @@ We’ll lean into realizing these breakthroughs and remove the more convoluted m
|
||||
|
||||
### Support Fully Speced Delegated Routing Protocols and Endpoints
|
||||
|
||||
While it will be possible from a connectivity perspective to make DHT queries from a browser, we expect various applications will want to still delegate out routing. <del>[Reframe](https://blog.ipfs.tech/2022-09-02-introducing-reframe/)</del> [HTTP Routing V1](https://specs.ipfs.tech/routing/http-routing-v1/) is a protocol for delegated routing that other IPFS implementations like Kubo have implemented. While it currently uses HTTP as a transport, it is [speced](https://specs.ipfs.tech/routing/http-routing-v1/) and not tied to the Kubo RPC API. If/when there is a speced protocol for ambient discovery of “Limited Delegated Routers” provided by libp2p, we will support that as well.
|
||||
While it will be possible from a connectivity perspective to make DHT queries from a browser, we expect various applications will want to still delegate out routing. [Reframe](https://blog.ipfs.tech/2022-09-02-introducing-reframe/) is a protocol for delegated routing that other IPFS implementations like Kubo have implemented. While it currently uses HTTP as a transport, it is speced and not tied to the Kubo RPC API. If/when there is a speced protocol for ambient discovery of “Limited Delegated Routers” provided by libp2p, we will support that as well.
|
||||
|
||||
### PL Delegate and Preload Nodes Will Be Shutting Down
|
||||
|
||||
Given the new browser-friendly p2p transports discussed above, we’ll shut down the complicated “song-and-dance” with the legacy delegate/preload nodes and the Kubo RPC API described in [js-ipfs in a Browser context](#js-ipfs-in-a-browser-context). This yields a simpler setup for one’s application and removes centralized infrastructure.
|
||||
|
||||
For delegated routing, one can configure [`/routing/v1`](https://specs.ipfs.tech/routing/http-routing-v1/) endpoints. When it comes to providing content from a browser node, it will be up to developers to account for user behavior like closing tabs or laptop lids. The general recommendation is to either run your own preload node or upload content explicitly to a pinning service for providing.
|
||||
For delegated routing, one can configure [Reframe](https://blog.ipfs.tech/2022-09-02-introducing-reframe/) endpoints. When it comes to providing content from a browser node, it will be up to developers to account for user behavior like closing tabs or laptop lids. The general recommendation is to either run your own preload node or upload content explicitly to a pinning service for providing.
|
||||
|
||||
### Release Helia in 2023
|
||||
|
||||
@@ -235,4 +235,4 @@ The timeline for enacting all of the above is still actively being figured out.
|
||||
|
||||
Thank you for reading and being on this journey to make IPFS exceptional in JS runtimes!
|
||||
|
||||
> Note: An earlier version of this blog post referred to Helia as Pomegranate. The blog post has been updated to reflect the name [chosen by the community.](https://github.com/ipfs/Helia/issues/3#issuecomment-1344434531)
|
||||
> Note: An earlier version of this blog post referred to Helia as Pomegranate. The blog post has been updated to reflect the name [chosen by the community.](https://github.com/ipfs/Helia/issues/3#issuecomment-1344434531)
|
||||
@@ -4,16 +4,6 @@ type: Tutorial
|
||||
sitemap:
|
||||
exclude: true
|
||||
data:
|
||||
- title: Browser P2P Connectivity With WebRTC and js-libp2p
|
||||
date: 2024-06-12
|
||||
publish_date:
|
||||
path: https://docs.libp2p.io/guides/getting-started/webrtc/
|
||||
card_image: "/libp2p-webrtc.png"
|
||||
tags:
|
||||
- libp2p
|
||||
- WebRTC
|
||||
- tutorial
|
||||
- pubsub
|
||||
- title: Uploading Files to IPFS from a Web Application
|
||||
date: 2021-06-28
|
||||
publish_date:
|
||||
|
||||
@@ -1,234 +0,0 @@
|
||||
---
|
||||
date: 2024-04-18
|
||||
permalink: /verified-fetch/
|
||||
title: 'Verified IPFS Retrieval in Browsers with @helia/verified-fetch'
|
||||
description: 'Verified Fetch is a library streamlining verified retrieval of IPFS content in browsers and JS runtimes, with native support for IPNS, and DNSLink resolution'
|
||||
author: Daniel Norman
|
||||
header_image: /verified-fetch/header.png
|
||||
tags:
|
||||
- ipfs
|
||||
- dapps
|
||||
- Helia
|
||||
- ipns
|
||||
- ens
|
||||
---
|
||||
|
||||
## Announcing @helia/verified-fetch
|
||||
|
||||
The Shipyard team is thrilled to announce **`@helia/verified-fetch`** is now ready for broader adoption. Verified Fetch is a [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)-like library streamlining verified retrieval of IPFS content in browsers and JS runtimes, with native support for IPNS, and DNSLink resolution. [Try it out](https://www.npmjs.com/package/@helia/verified-fetch) and let us know what you think.
|
||||
|
||||
This blog post covers the challenges of IPFS retrieval in browsers and how `@helia/verified-fetch` addresses them with runnable examples. Feel free to jump ahead to [Solution: Verified Fetch](#solution-verified-fetch)
|
||||
|
||||
## Problem: Verified IPFS retrieval in browsers is hard
|
||||
|
||||
IPFS stands out as the leading decentralized network for distributing content-addressed data (with CIDs), spanning a wide range of use cases such as [off-chain voting](https://docs.ipfs.tech/case-studies/snapshot/), NFTs, [censorship-resistant Wikipedia](https://blog.ipfs.tech/24-uncensorable-wikipedia/), and [dapp distribution](https://blog.ipfs.tech/dapps-ipfs/).
|
||||
|
||||
However, developing web applications for the browser with an IPFS implementation capable of verified content retrieval has been an ongoing challenge for developers. The main reason lies in the inherent constraints of the Web Platform: TCP connections aren't allowed, and Certificate Authority signed certificates are required in Secure Contexts which increases the overhead to peer-to-peer retrieval. Other reasons include the apparent complexity of IPFS and the historical lack of focused tooling for verified IPFS retrieval on the Web.
|
||||
|
||||
For this reason, many developers use a **trusted gateway** and call it a day. That's understandable and speaks to the ease and utility of gateways as an abstraction of IPFS.
|
||||
|
||||
### IPFS Gateways are a useful abstraction for IPFS retrieval
|
||||
|
||||
Trusted IPFS Gateways abstract much of the complexity (peer-to-peer connectivity, content routing, content retrieval, verification) of IPFS with a straightforward HTTP API to the IPFS network:
|
||||
|
||||
<img alt="gateway architecture diagram" src="../assets/verified-fetch/gateways.png" width="500">
|
||||
|
||||
The beauty of IPFS Gateways is in how simple they are to use: you append the CID to the URL of the Gateway and all IPFS magic is handled by the gateway for you.
|
||||
|
||||
For example, fetching an image with the CID: [`bafk...beom`](https://cid.ipfs.tech/#bafkreie7ohywtosou76tasm7j63yigtzxe7d5zqus4zu3j6oltvgtibeom) is as simple as constructing the URL: `https://ipfs.io/ipfs/bafkreie7ohywtosou76tasm7j63yigtzxe7d5zqus4zu3j6oltvgtibeom` which can be passed to the `src` attribute of an `<img>`, as follows:
|
||||
|
||||
<img class="py-4" alt="image loaded from an IPFS gateway" src="https://ipfs.io/ipfs/bafkreie7ohywtosou76tasm7j63yigtzxe7d5zqus4zu3j6oltvgtibeom" width="350">
|
||||
|
||||
### Trusting an IPFS Gateway without verifying is an anti-pattern
|
||||
|
||||
**Nonetheless, fetching from a third-party IPFS gateway without verifying is an anti-pattern** and goes against [the principles of IPFS](https://specs.ipfs.tech/architecture/principles/#verification-matters).
|
||||
|
||||
Content addressing in IPFS frees you from the model of a single canonical source for data. This is a powerful concept and the root of IPFS' benefits: resilience, censorship resistance, and trustlessness. But, **fully reaping the benefits of IPFS requires verification**.
|
||||
|
||||
### Verification facilitates resilience and multi-source retrieval
|
||||
|
||||
Verifying IPFS content as part of the retrieval process allows you to fetch it from multiple sources –either providers or gateways– without trusting them because verification ensures the integrity of the data.
|
||||
|
||||
This comes with the downstream benefit of resilience: if one provider or gateway is unavailable, unreachable, or censored, you can still retrieve the CID from another (as long as other providers are available). A [recent outage of the Unpkg CDN](https://www.theverge.com/2024/4/12/24128276/open-source-unpkg-cdn-down) is a great example of why multi-source retrieval is useful.
|
||||
|
||||
### Trustless IPFS Gateways enable verification in browsers
|
||||
|
||||
[Trustless IPFS Gateways](https://specs.ipfs.tech/http-gateways/trustless-gateway/) have been gaining steam as a means of enabling verification and its downstream benefits with the simplicity of IPFS Gateways over HTTP. In fact, at the time of writing, most [public gateways](https://ipfs.fyi/gateways) support Trustless Gateway responses.
|
||||
|
||||
Trustless IPFS Gateways' response types are [fully and incrementally verifiable](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval): clients can decide between a [raw block](https://docs.ipfs.tech/concepts/glossary/#block) ([`application/vnd.ipld.raw`](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw)) or a [CAR stream](https://docs.ipfs.tech/concepts/glossary/#car) ([`application/vnd.ipld.car`](https://www.iana.org/assignments/media-types/application/vnd.ipld.car)).
|
||||
|
||||
Trustless IPFS Gateways are useful for browsers because they can be composed in a way that unleashes many of the aforementioned benefits of IPFS and content addressing.
|
||||
|
||||
> **Note:** Browser constraints prevent you from opening connections to "random" addresses that don't have a CA signed certificate, making it hard to build IPFS clients for browsers that go straight to providers. Newer transport such as [WebTransport](https://docs.libp2p.io/concepts/transports/webtransport/) and [WebRTC-direct](https://docs.libp2p.io/concepts/transports/webrtc/) address this challenge in a way that may be able to reduce dependency on IPFS Gateways in the future.
|
||||
|
||||
## Solution: Verified Fetch
|
||||
|
||||
[`@helia/verified-fetch`](https://www.npmjs.com/package/@helia/verified-fetch) or simply **Verified Fetch** is a new JavaScript library by [The Shipyard team](https://blog.ipfs.tech/shipyard-hello-world/) that makes verified IPFS retrieval from trustless gateways easy. It's written in TypeScript with Web APIs so you can run it in browsers as well as modern JS runtimes.
|
||||
|
||||
It's the culmination of multiple streams of work we undertook to bring seamless and deeper IPFS integrations to browsers and improve the development experience with IPFS.
|
||||
|
||||
### Familiar, like the Fetch API
|
||||
|
||||
Verified Fetch is modeled after the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and returns [`Response` object](https://developer.mozilla.org/en-US/docs/Web/API/Response) making it easy to adopt and reason about.
|
||||
|
||||
For example, fetching the CID of a JSON object is as simple as:
|
||||
|
||||
```ts
|
||||
import { verifiedFetch } from '@helia/verified-fetch'
|
||||
const resp = await verifiedFetch(
|
||||
'ipfs://baguqeeradnk3742vd3jxhurh22rgmlpcbzxvsy3vc5bzakwiktdeplwer6pa'
|
||||
)
|
||||
const obj = await resp.json()
|
||||
```
|
||||
|
||||
Under the hood, Verified Fetch handles both fetching from trustless gateways and verification:
|
||||
|
||||
<iframe height="300" style="width: 100%;" scrolling="no" title="Fetching a CID with @helia/verified-fetch example" src="https://codepen.io/2color/embed/oNOyarL?default-tab=js%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/oNOyarL">
|
||||
Fetching a CID with @helia/verified-fetch example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>).
|
||||
</iframe>
|
||||
|
||||
### Fast and Resilient Retrieval with Multiple Gateways
|
||||
|
||||
Verified Fetch supports retrieval from multiple trustless gateways, ensuring both performance and resilience. It comes [pre-configured with three default gateways](https://github.com/ipfs/helia/blob/b67ac5f16eca1df5534c985045250bdb334a85cf/packages/block-brokers/src/trustless-gateway/index.ts#L6-L15), but can be easily customized:
|
||||
|
||||
```ts
|
||||
import { createVerifiedFetch } from '@helia/verified-fetch'
|
||||
|
||||
const verifiedFetch = await createVerifiedFetch({
|
||||
gateways: ['https://trustless-gateway.link', 'https://cloudflare-ipfs.com'],
|
||||
})
|
||||
```
|
||||
|
||||
### Mutable Pointers: DNSLink & IPNS
|
||||
|
||||
Mutable pointers are a powerful way to have a stable pointer that can be updated over time. In the IPFS ecosystem, there are two approaches to this: [IPNS](https://docs.ipfs.tech/concepts/ipns/) and [DNSLink](https://docs.ipfs.tech/concepts/dnslink/).
|
||||
|
||||
Verified Fetch supports both using the `ipns://` prefix, and resolves them to a CID, which in turn is fetched and verified.
|
||||
|
||||
### Resolving IPNS names with Verified Fetch
|
||||
|
||||
IPNS names are resolved using the [Delegated routing over HTTP](https://docs.ipfs.tech/concepts/glossary/#delegated-routing) provided by the [`https://delegated-ipfs.dev` endpoint](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing).
|
||||
|
||||
<iframe height="300" style="width: 100%;" scrolling="no" title="Resolving and Fetching a DNSLink with @helia/verified-fetch example" src="https://codepen.io/2color/embed/BaEVMWW?default-tab=js%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/BaEVMWW">
|
||||
Resolving and Fetching a DNSLink with @helia/verified-fetch example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
</iframe>
|
||||
|
||||
Note that you can deploy and configure your own Delegated Routing endpoint with [someguy](https://github.com/ipfs/someguy).
|
||||
|
||||
To configure the endpoint in Verified Fetch, pass the endpoint to the `routers` config option:
|
||||
|
||||
```ts
|
||||
import { createVerifiedFetch } from '@helia/verified-fetch'
|
||||
|
||||
const verifiedFetch = await createVerifiedFetch({
|
||||
routers: ['https://delegated-ipfs.dev'],
|
||||
})
|
||||
```
|
||||
|
||||
### Resolving DNSLink domains with Verified Fetch
|
||||
|
||||
DNSLink records are resolved to a CID with a configurable [DNS over HTTPS](https://en.wikipedia.org/wiki/DNS_over_HTTPS) endpoint, which comes preconfigured to Cloudflare and Google:
|
||||
|
||||
<iframe height="300" style="width: 100%;" scrolling="no" title="Resolving and Fetching a DNSLink with @helia/verified-fetch example" src="https://codepen.io/2color/embed/YzMvRmv?default-tab=js%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/YzMvRmv">
|
||||
Resolving and Fetching a DNSLink with @helia/verified-fetch example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
</iframe>
|
||||
|
||||
### ENS names are also supported with DNSLink
|
||||
|
||||
Verified Fetch can also resolve [ENS names](https://ens.domains/) that have the [Contenthash record](https://docs.ens.domains/ensip/7) set with the help of [EthDNS](https://eth.link/) (A DNS bridge to ENS names). To do so, pass a DNS over HTTP EthDNS endpoint to the `dnsResolvers` option, like the [one provided by eth.limo](https://github.com/ethlimo/documentation/blob/master/dns-over-https/doh.md):
|
||||
|
||||
```ts
|
||||
import { createVerifiedFetch } from '@helia/verified-fetch'
|
||||
import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
||||
|
||||
const verifiedFetch = await createVerifiedFetch({
|
||||
dnsResolvers: {
|
||||
'eth.': dnsJsonOverHttps('https://dns.eth.limo/dns-query'),
|
||||
'.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query'),
|
||||
},
|
||||
})
|
||||
const resp = await verifiedFetch(
|
||||
'ipns://vitalik.eth/images/scaling-files/cryptokitties.png'
|
||||
)
|
||||
```
|
||||
|
||||
The following example uses Verified Fetch to [resolve `vitalik.eth`](https://app.ens.domains/vitalik.eth?tab=records) to a CID, fetch the CID, and verify the bytes of the image from Vitalik's website:
|
||||
|
||||
<iframe height="500" style="width: 100%;" scrolling="no" title="Resolving and Fetching a DNSLink with @helia/verified-fetch and custom DoH endpoint example" src="https://codepen.io/2color/embed/wvZXRPa?default-tab=js%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/wvZXRPa">
|
||||
Resolving and Fetching a DNSLink with @helia/verified-fetch and custom DoH endpoint example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
</iframe>
|
||||
|
||||
### Supports a wide range of data types
|
||||
|
||||
As you may have noticed, you can use Verified Fetch to fetch a wide range of data types. Verified Fetch abstracts much of the complexity of IPLD codecs, supporting [UnixFS](https://docs.ipfs.tech/concepts/file-systems/#unix-file-system-unixfs), [dag-cbor](https://ipld.io/specs/codecs/dag-cbor/), and [dag-json](https://ipld.io/specs/codecs/dag-json/) out of the box. This frees you to focus on your application. The `text()`, `.blob()`, and .`arrayBuffer()` methods will work as expected without a detailed content type.
|
||||
|
||||
By default, if the response can be parsed as JSON, Verified Fetch sets the `Content-Type` header of the Response object to as `application/json`, otherwise it sets it as `application/octet-stream`.
|
||||
|
||||
[You can also pass the `Accept` header](https://github.com/ipfs/helia-verified-fetch/tree/main/packages/verified-fetch#the-accept-header) to override [certain](https://github.com/ipfs/helia-verified-fetch/blob/089635d6cd5b10aefbed013e95637ddb90b166e5/packages/verified-fetch/src/utils/select-output-type.ts#L12-L62) response processing to modify the `Content-Type` of the response. For example, you may want to fetch a `dag-cbor` CID with the `Accept` header set to `application/vnd.ipld.dag-json` for easier handling in JavaScript:
|
||||
|
||||
<iframe height="300" style="width: 100%;" scrolling="no" title="Fetching a CID with @helia/verified-fetch example" src="https://codepen.io/2color/embed/ExJdayy?default-tab=js%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/ExJdayy">
|
||||
Fetching a CID with @helia/verified-fetch example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
</iframe>
|
||||
|
||||
Finally, since you can store **any** kind of file with UnixFS, if you want the `Content-Type` header of the `Response` object to be sniffed on the [Magic Bytes of the retrieved binary data](https://en.wikipedia.org/wiki/Content_sniffing), you can pass the `contentTypeParser` option as follows:
|
||||
|
||||
<iframe height="300" style="width: 100%;" scrolling="no" title="Content-Type sniffing with contentTypeParser @helia/verified-fetch example" src="https://codepen.io/2color/embed/JjVmoLy?default-tab=js%2Cresult&editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
|
||||
See the Pen <a href="https://codepen.io/2color/pen/JjVmoLy">
|
||||
Content-Type sniffing with contentTypeParser @helia/verified-fetch example</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
|
||||
</iframe>
|
||||
|
||||
|
||||
### Customizable
|
||||
|
||||
By default, Verified Fetch uses [`@helia/http`](https://github.com/ipfs/helia/tree/main/packages/http#heliahttp): a lightweight version of Helia on IPFS over HTTP with Trustless Gateways. However, you can [pass an instance of Helia that is customized to your needs](https://github.com/ipfs/helia-verified-fetch/tree/main/packages/verified-fetch#usage-with-customized-helia). A common use-case might be when running on Node.js where you might want to lean more heavily on peer-to-peer retrieval using Bitswap over TCP. In that case, you would likely be better served by a Helia instance backed by libp2p as follows:
|
||||
|
||||
```ts
|
||||
import { createHelia } from 'helia'
|
||||
import { createVerifiedFetch } from '@helia/verified-fetch'
|
||||
|
||||
const verifiedFetch = await createVerifiedFetch(
|
||||
// Create a Helia instance instance backed by js-libp2p
|
||||
await createHelia()
|
||||
)
|
||||
```
|
||||
|
||||
### 📕 Docs & Examples
|
||||
|
||||
In addition to the embedded examples above, check out the [README](https://github.com/ipfs/helia-verified-fetch/tree/main/packages/verified-fetch) for a more elaborate overview of usage patterns and reconfigurability.
|
||||
|
||||
We also have a [ready-to-run example](<https://github.com/ipfs-examples/[text](https://inbrowser.dev/ipns/example.ipfs.garden)helia-examples/tree/main/examples/helia-browser-verified-fetch>) showing `@helia/verified-fetch` in the browser handling different content types.
|
||||
|
||||
## What's next for Verified Fetch?
|
||||
|
||||
This release of Verified Fetch leans heavily on IPFS Gateways. But the journey doesn't end there. Our long-term vision is to [enable direct retrieval from content providers, e.g. Kubo nodes](https://github.com/ipfs/helia/issues/255), which would further increase the resilience of retrievals.
|
||||
|
||||
Verified Fetch is already powering IPFS retrieval in the [Service Worker Gateway](https://github.com/ipfs-shipyard/service-worker-gateway), a novel approach to in-browser IPFS gateways. This has given us the chance to dogfood and refine Verified Fetch.
|
||||
|
||||
## Try it out today
|
||||
|
||||
We built Verified Fetch with app developers in mind. We understand that for developers to be productive with IPFS, you need good abstractions.
|
||||
|
||||
We invite you to try it out and can't wait to see what you build with it 🚢.
|
||||
|
||||
<br />
|
||||
<a href="https://npmjs.com/package/@helia/verified-fetch" class="cta-button">
|
||||
@helia/verified-fetch docs
|
||||
</a>
|
||||
|
||||
## Share your feedback
|
||||
|
||||
If you are new to Helia and mostly interested in retrievals, `@helia/verified-fetch` is a great place to get started.
|
||||
|
||||
For questions, discussions, and feedback join the [IPFS Forums](https://discuss.ipfs.tech/) or the [#ip-js](https://discord.com/channels/806902334369824788/1136320721044381706) channel in the [IPFS Discord](https://discord.com/invite/ipfs). Finally, the [Helia and Dapps Working Groups](https://lu.ma/ipfs?tag=helia) meet regularly to coordinate and discuss the development of the Helia and advance the tooling for Dapps in the IPFS ecosystem.
|
||||
|
||||
If you've already been using [Helia](https://github.com/ipfs/helia/), please take a moment to [fill out the Helia feedback survey](https://ipfs.fyi/helia-feedback). Your feedback will help us understand developer needs and challenges as well as inform our priorities and shape Helia’s roadmap.
|
||||
|
||||
<br />
|
||||
<a href="https://ipfs.fyi/helia-feedback" class="cta-button">
|
||||
Helia Feedback Survey
|
||||
</a>
|
||||
@@ -4,48 +4,11 @@ type: Video
|
||||
sitemap:
|
||||
exclude: true
|
||||
data:
|
||||
- title: 'Debugging CID Retrievability With IPFS Check'
|
||||
date: 2024-09-04
|
||||
publish_date: 2024-09-04T12:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=XeNOQDOrdC0
|
||||
tags:
|
||||
- IPFS Check
|
||||
- debugging
|
||||
- tutorial
|
||||
- guide
|
||||
- title: 'Built with IPFS - Mintter and The Hypermedia Protocol'
|
||||
date: 2023-11-13
|
||||
publish_date: 2023-11-13T12:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=K3U6A4sgKo4
|
||||
tags:
|
||||
- Built with IPFS
|
||||
- demo
|
||||
- interview
|
||||
- deep-dive
|
||||
- title: 'This Month in IPFS - March 2023'
|
||||
date: 2023-03-23
|
||||
publish_date: 2023-03-23T12:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=_vn52temkDU
|
||||
tags:
|
||||
- This Month in IPFS
|
||||
- community
|
||||
- demo
|
||||
- interview
|
||||
- title: 'This Month in IPFS - February 2023'
|
||||
date: 2023-02-23
|
||||
publish_date: 2023-02-23T12:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=Cflrlv31oW8
|
||||
tags:
|
||||
- This Month in IPFS
|
||||
- community
|
||||
- demo
|
||||
- interview
|
||||
- title: 'This Month in IPFS - January 2023'
|
||||
date: 2023-01-26
|
||||
publish_date: 2023-02-06T12:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=kRzNohHeRaM
|
||||
tags:
|
||||
- This Month in IPFS
|
||||
- community
|
||||
- demo
|
||||
- interview
|
||||
|
||||
@@ -23,7 +23,7 @@ Snapshot is an open-source voting platform for Web3 projects, DAOs, and communit
|
||||
|
||||
1. [IPFS Camp 2022](https://2022.ipfs.camp/) is back! Join the community in Lisbon on October 28th-30th for an event focused on celebrating and advancing IPFS, more details coming soon.
|
||||
2. Kubo (formerly go-ipfs) v0.15.0 is live. Review all the library updates and bug fixes, Blake3 support, Fx Options plugin, and more on [Github](https://github.com/ipfs/kubo/releases/tag/v0.15.0).
|
||||
3. Kubo v0.14.0 now [supports](https://github.com/ipfs/kubo/releases/tag/v0.14.0#delegated-routing) experimental protocol for delegated routing. Learn more about it on the IPFS [blog](https://blog.ipfs.tech/2022-09-02-introducing-reframe/).
|
||||
3. Kubo v0.14.0 now [supports](https://github.com/ipfs/kubo/releases/tag/v0.14.0#delegated-routing) [Reframe](https://github.com/ipfs/specs/tree/main/reframe#readme), a tool for delegated routing. Learn more about it on the IPFS [blog](https://blog.ipfs.tech/2022-09-02-introducing-reframe/).
|
||||
4. Check out [Opensquare Art](https://t.co/TrdDYttxkq)’s new Shop Builder for launching no-code minting websites that store NFTs on IPFS and Filecoin via [NFT.Storage](https://nft.storage/).
|
||||
|
||||
## **Around the ecosystem 🌎**
|
||||
@@ -58,4 +58,4 @@ Funding the Commons is back at [Schelling Point](https://schellingpoint.gitcoin.
|
||||
|
||||
[**Rust Engineer**](https://angel.co/company/fleekhq/jobs/1505997-rust-engineer-remote): Fleek is looking for an experienced and dedicated Rust Engineer to help build new canister-based products and services on Dfinity's Internet Computer. [**Fleek**](https://fleek.co/) is an Open Web developer platform with everything you need to build sites and apps on the new web and the underlying protocols that power it (Dfinity, Ethereum, IPFS, Filecoin, and more). From hosting, storage, gateways, domains, databases, and more, Fleek has everything you need to seamlessly build and manage Open Web sites. **Fleek**, Remote.
|
||||
|
||||
[**Developer Relations**](https://boards.greenhouse.io/textileio/jobs/4075619004): Textile is seeking someone to run large-scale community projects. These include amplifying our grants program to fund community projects, curating governance groups where we bring community stakeholders into our technology planning, engaging with external teams like Gitcoin and EthDenver to support large-scale developer events, and giving technical presentations at events. This position also includes day-to-day engagement with our Slack group, helping to triage GitHub issues, hacking on demos, writing blog posts and technical guides, and more. We are looking for a self-directed leader who wants to build a developer community while staying hands on with technology. **Textile**, Remote.
|
||||
[**Developer Relations**](https://boards.greenhouse.io/textileio/jobs/4075619004): Textile is seeking someone to run large-scale community projects. These include amplifying our grants program to fund community projects, curating governance groups where we bring community stakeholders into our technology planning, engaging with external teams like Gitcoin and EthDenver to support large-scale developer events, and giving technical presentations at events. This position also includes day-to-day engagement with our Slack group, helping to triage GitHub issues, hacking on demos, writing blog posts and technical guides, and more. We are looking for a self-directed leader who wants to build a developer community while staying hands on with technology. **Textile**, Remote.
|
||||
@@ -23,7 +23,7 @@ Today, only a few companies are responsible for serving up most of the web. Thes
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
1. The IPFS GUI working group is looking to improve the experience on the [**Public Gateway Checker**](https://ipfs.github.io/public-gateway-checker/). [**Book some time**](http://calendly/) to let us know your thoughts and get a swag redemption code.
|
||||
2. The new [**Kubo v0.16.0**](https://github.com/ipfs/kubo/releases/tag/v0.16.0) is now live. The release supports a more configurable experimental delegated routing system. [**See for yourself**](https://github.com/ipfs/kubo/releases/tag/v0.16.0).
|
||||
2. The new [**Kubo v0.16.0**](https://github.com/ipfs/kubo/releases/tag/v0.16.0) is now live. The release supports a more configurable delegated routing system with [**Reframe protocol**](https://github.com/ipfs/specs/tree/main/reframe#readme). [**See for yourself**](https://github.com/ipfs/kubo/releases/tag/v0.16.0).
|
||||
3. Check out [**Capyloon**](https://capyloon.org/), a web-based smartphone OS with a built-in IPFS Rust implementation.
|
||||
4. [**Fission**](https://fission.codes/) added a new feature to its SDK called WalletAuth that enables IPFS encrypted storage for any blockchain account. Learn more in this [**thread**](https://twitter.com/FISSIONcodes/status/1573092516873781248).
|
||||
|
||||
@@ -63,4 +63,4 @@ Join the IPFS community in Lisbon, Portugal on October 28 - 30th! Hosted at the
|
||||
|
||||
[**Quality Assurance, Test and Benchmarking Engineer**](https://join.com/companies/capsule/5840067-quality-assurance-test-and-benchmarking-engineer?pid=24a1b46991e3de1fbcf0): At Capsule Social, they've been building the future of decentralized discourse on top of performant, well-designed decentralization tech, cryptographic tech and blockchain tech. Capsule's Quality Assurance, Test and Benchmarking Engineer will be responsible for writing tests and creating a benchmarking infrastructure so that we can be sure that our technology scales to thousands and even millions of users prior to launch. **Capsule Social**, Remote.
|
||||
|
||||
[**Full Stack Engineer**](https://www.linkedin.com/jobs/view/3273564662/?alternateChannel=search&refId=7I%2Bx0SHdcmhdQsQzWohg0Q%3D%3D&trackingId=kJtg%2BtTFxm88myxa7QZ0Yg%3D%3D): HENI is looking to recruit a senior and mid-level, permanent Full Stack Developer who will be a key member in the applications team alongside other full-stack and front-end developers, providing fundamental input and knowledge in solving some of these challenges. This would suit someone with demonstrable technical expertise who is driven by a hands-on and stimulating role. **HENI**, London, UK.
|
||||
[**Full Stack Engineer**](https://www.linkedin.com/jobs/view/3273564662/?alternateChannel=search&refId=7I%2Bx0SHdcmhdQsQzWohg0Q%3D%3D&trackingId=kJtg%2BtTFxm88myxa7QZ0Yg%3D%3D): HENI is looking to recruit a senior and mid-level, permanent Full Stack Developer who will be a key member in the applications team alongside other full-stack and front-end developers, providing fundamental input and knowledge in solving some of these challenges. This would suit someone with demonstrable technical expertise who is driven by a hands-on and stimulating role. **HENI**, London, UK.
|
||||
|
Before Width: | Height: | Size: 130 KiB |
|
Before Width: | Height: | Size: 217 KiB |
|
Before Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 4.8 MiB |
|
Before Width: | Height: | Size: 1.9 MiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 377 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 4.1 MiB |
|
Before Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 585 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 211 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 2.0 MiB |
|
Before Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 498 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 1.6 MiB |