mirror of
https://github.com/ipfs/ipfs-blog.git
synced 2026-03-28 17:32:37 +01:00
Compare commits
723 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f8088c3381 | ||
|
|
0f9630e68e | ||
|
|
c6ea1d6591 | ||
|
|
cc5c14d00f | ||
|
|
b53b1b01eb | ||
|
|
a8918145fd | ||
|
|
da9458a59e | ||
|
|
c24a89daff | ||
|
|
2a583f35f7 | ||
|
|
36cb7ee956 | ||
|
|
66bd44e4b6 | ||
|
|
59ea9a2b9c | ||
|
|
c4165edbed | ||
|
|
e22e2aed72 | ||
|
|
b96fb2fcff | ||
|
|
b894276863 | ||
|
|
ecf64efd1b | ||
|
|
09e9dd871d | ||
|
|
2d2d505e7c | ||
|
|
b011df8875 | ||
|
|
f08e08edb0 | ||
|
|
1dd2cccca8 | ||
|
|
3bf1044d39 | ||
|
|
a3d9de839e | ||
|
|
60268d3971 | ||
|
|
10d6cfb5e0 | ||
|
|
729c99394e | ||
|
|
b3fda7cc07 | ||
|
|
254da08e9f | ||
|
|
3d0569bfc5 | ||
|
|
0496efe55b | ||
|
|
64861f42fc | ||
|
|
398b5cb18a | ||
|
|
f2ad344944 | ||
|
|
320be76513 | ||
|
|
a2f5adcdb9 | ||
|
|
cd43d8bf9c | ||
|
|
4102890b59 | ||
|
|
32040d1e90 | ||
|
|
9fe361d557 | ||
|
|
a5039d53ae | ||
|
|
932cc2b9ae | ||
|
|
2a1a20227f | ||
|
|
43720fe540 | ||
|
|
fa6109bb57 | ||
|
|
12703fa248 | ||
|
|
4220a5e7b5 | ||
|
|
22d008625d | ||
|
|
2698a5bdab | ||
|
|
c635eec6f8 | ||
|
|
9c25aa58ae | ||
|
|
bc735e20e2 | ||
|
|
4d4655bf80 | ||
|
|
739affd649 | ||
|
|
0a45642c21 | ||
|
|
f4eb528df1 | ||
|
|
6f0977dbeb | ||
|
|
d154153730 | ||
|
|
26f2bbf2d8 | ||
|
|
c568922524 | ||
|
|
80dc5bfbce | ||
|
|
9777c23e53 | ||
|
|
fb33e12c92 | ||
|
|
3a425661e5 | ||
|
|
c53620b939 | ||
|
|
81fb0f2330 | ||
|
|
e825447b17 | ||
|
|
47031049b7 | ||
|
|
ca0bc47bc8 | ||
|
|
acdd229661 | ||
|
|
8194eaff7f | ||
|
|
52318151e8 | ||
|
|
cfc9fea66d | ||
|
|
26ff40b506 | ||
|
|
b52cbb5604 | ||
|
|
ed82724cdd | ||
|
|
4ad47dd1b8 | ||
|
|
68a7bc12f7 | ||
|
|
3abbd21e5c | ||
|
|
510e74a0ad | ||
|
|
a3a23e78ca | ||
|
|
e4547c5f60 | ||
|
|
16a364375a | ||
|
|
36970c328f | ||
|
|
a40ce95110 | ||
|
|
3431900b5f | ||
|
|
929381c390 | ||
|
|
39b17f68c2 | ||
|
|
7cd6e97cbd | ||
|
|
e25009d426 | ||
|
|
4c50608c16 | ||
|
|
1c1522258f | ||
|
|
a47a68a382 | ||
|
|
85c0b0ede2 | ||
|
|
cc3e4b4e88 | ||
|
|
40a05856ba | ||
|
|
17647d11c1 | ||
|
|
44b2194fb6 | ||
|
|
09870e84ba | ||
|
|
f48372afe6 | ||
|
|
2b5b8d4367 | ||
|
|
f53364f31e | ||
|
|
67c1eefc45 | ||
|
|
623d406fc5 | ||
|
|
82d2383357 | ||
|
|
8ab214c419 | ||
|
|
be51e7efa3 | ||
|
|
fbe8fb1ea6 | ||
|
|
c63db0d0d0 | ||
|
|
aa390803ad | ||
|
|
f8fa3f9816 | ||
|
|
eab7cee788 | ||
|
|
f3e3a447ae | ||
|
|
89f8aec5cc | ||
|
|
4842c10f94 | ||
|
|
cf2974515a | ||
|
|
b92527d1d0 | ||
|
|
d7d6da8772 | ||
|
|
ecb56c3d89 | ||
|
|
522e897675 | ||
|
|
beacdfd1c6 | ||
|
|
ff8999430a | ||
|
|
3e947b3b51 | ||
|
|
dcbe1db31c | ||
|
|
262e36fadb | ||
|
|
89eecb7d60 | ||
|
|
a46a232df8 | ||
|
|
4f67ce26bb | ||
|
|
6aefa60e13 | ||
|
|
771c8d3029 | ||
|
|
d7c47ad359 | ||
|
|
8ef53548ad | ||
|
|
de62b7c1ca | ||
|
|
1601db89b3 | ||
|
|
31f47f5440 | ||
|
|
502c7a6982 | ||
|
|
42e42ed7aa | ||
|
|
bff9a6cce7 | ||
|
|
9699289147 | ||
|
|
b06d783f1c | ||
|
|
ba9c8e2334 | ||
|
|
7ef9095e82 | ||
|
|
c7a2b8f161 | ||
|
|
b3c6e38a53 | ||
|
|
62954b2499 | ||
|
|
08e43240da | ||
|
|
7f20188e37 | ||
|
|
11c7c7a975 | ||
|
|
28851da83c | ||
|
|
aae1cb5147 | ||
|
|
af391fa9a3 | ||
|
|
1046e2faac | ||
|
|
589a4bb69d | ||
|
|
c4aa9735c8 | ||
|
|
e7dce43d4f | ||
|
|
44c16b8cc4 | ||
|
|
157c317d4c | ||
|
|
47ad75c831 | ||
|
|
59aa59e96e | ||
|
|
fd2eed86d2 | ||
|
|
0dca03f7d7 | ||
|
|
5863dda3fa | ||
|
|
c650b46fd4 | ||
|
|
cd0a9b711b | ||
|
|
1364740597 | ||
|
|
6d574aa91c | ||
|
|
f75255f809 | ||
|
|
e3684b779e | ||
|
|
05281a78e7 | ||
|
|
e7cca2a574 | ||
|
|
a2d0e64dd2 | ||
|
|
5240ba2e61 | ||
|
|
b8f11d2daf | ||
|
|
9e088d4166 | ||
|
|
ec244db92f | ||
|
|
b63347341b | ||
|
|
223a5c2d5f | ||
|
|
9c54140259 | ||
|
|
72816cfbf8 | ||
|
|
b5625f23a9 | ||
|
|
5984fab155 | ||
|
|
f6e4a0b669 | ||
|
|
c44ef3fcf3 | ||
|
|
1627a4859a | ||
|
|
12c97076f9 | ||
|
|
465ab2699b | ||
|
|
f932159488 | ||
|
|
deebe963d1 | ||
|
|
c87cc4c88c | ||
|
|
2e6bf83275 | ||
|
|
795791ed9a | ||
|
|
3f0801f1f3 | ||
|
|
0706d6fde9 | ||
|
|
58abab75fa | ||
|
|
07a7dddb8b | ||
|
|
6fbd3ce18b | ||
|
|
04c7f36d6e | ||
|
|
5af143ab8f | ||
|
|
b941c7faf4 | ||
|
|
b87d0b8ecd | ||
|
|
9f4f687010 | ||
|
|
d4132c4170 | ||
|
|
c2a84c4269 | ||
|
|
1c3e854f70 | ||
|
|
145122ee04 | ||
|
|
89471f11e9 | ||
|
|
f6841a42e9 | ||
|
|
6471d9f65e | ||
|
|
83e3ab39e0 | ||
|
|
82da27d7e9 | ||
|
|
a5c3dfdc24 | ||
|
|
37e7d7d518 | ||
|
|
6ee3eab209 | ||
|
|
89521c340e | ||
|
|
f17052b0e8 | ||
|
|
53690965e2 | ||
|
|
dee6bcf8de | ||
|
|
fbd720db74 | ||
|
|
21279f0dd0 | ||
|
|
55af49fc60 | ||
|
|
129bf382df | ||
|
|
d8c775eae2 | ||
|
|
59152063a9 | ||
|
|
32ccc676a1 | ||
|
|
374543d468 | ||
|
|
0a5dd968fa | ||
|
|
5f89271350 | ||
|
|
a0f523ec01 | ||
|
|
6d368c4a2e | ||
|
|
8e98e13922 | ||
|
|
d08fc7cbae | ||
|
|
e7dbac489e | ||
|
|
ed6ef407f4 | ||
|
|
0e846d919d | ||
|
|
d28f61562e | ||
|
|
23678aca1e | ||
|
|
a7e8038d5a | ||
|
|
69463881cf | ||
|
|
9b2af09faa | ||
|
|
f603218e16 | ||
|
|
ba35d13d19 | ||
|
|
a2efdda1f5 | ||
|
|
cbd362c3e6 | ||
|
|
93bdd71fd8 | ||
|
|
c3eb00ae80 | ||
|
|
d3ee6ba72f | ||
|
|
0bbefbd45e | ||
|
|
477ed5f848 | ||
|
|
3b3359cc9a | ||
|
|
c266a92be1 | ||
|
|
082ad182ea | ||
|
|
910498404c | ||
|
|
d78ec2094d | ||
|
|
da78c476ac | ||
|
|
3b219e9f9c | ||
|
|
8442cdc37b | ||
|
|
8f16f53b02 | ||
|
|
1c22e51168 | ||
|
|
1f3cf0e6db | ||
|
|
43f8d51184 | ||
|
|
3eeef86818 | ||
|
|
f474c040ee | ||
|
|
91992d015d | ||
|
|
e744e08d94 | ||
|
|
130cf23f20 | ||
|
|
06e34221ab | ||
|
|
0b4d7aa9de | ||
|
|
136a8b4fc7 | ||
|
|
01332d5e6d | ||
|
|
e40d083c43 | ||
|
|
fa96668946 | ||
|
|
0e9afaeb74 | ||
|
|
506c2a76a8 | ||
|
|
fd5fd97a58 | ||
|
|
371dca6a44 | ||
|
|
24869c3cba | ||
|
|
25d0b51b25 | ||
|
|
57d7276a9f | ||
|
|
789cfa894f | ||
|
|
ca4c13fae5 | ||
|
|
00e656c4bd | ||
|
|
c22a20473d | ||
|
|
41e0c20519 | ||
|
|
3af0e7180b | ||
|
|
5d4507831d | ||
|
|
afa256da3b | ||
|
|
b6dc646e56 | ||
|
|
653bc599ae | ||
|
|
db223ea026 | ||
|
|
afb3ac1ed2 | ||
|
|
0bc035fd63 | ||
|
|
e754e0485d | ||
|
|
d8ba638845 | ||
|
|
29017966f3 | ||
|
|
a9f12a1553 | ||
|
|
2ca03944d3 | ||
|
|
6b6166f9c9 | ||
|
|
131866db3b | ||
|
|
dce37a0cc6 | ||
|
|
215327bef2 | ||
|
|
2ed5554199 | ||
|
|
e25889dbcc | ||
|
|
eb7ec42ae3 | ||
|
|
3e7d4d54c0 | ||
|
|
1dec1d9cba | ||
|
|
9d1f82886b | ||
|
|
0395a8ddfb | ||
|
|
abf5be27c5 | ||
|
|
0163b9023a | ||
|
|
395b5ed2fc | ||
|
|
4e57cff9c3 | ||
|
|
10dbd7c187 | ||
|
|
055788c32b | ||
|
|
c68a88f115 | ||
|
|
8510202c1b | ||
|
|
17dbf40f05 | ||
|
|
17c71abcd1 | ||
|
|
8e2ad9b668 | ||
|
|
d6de915758 | ||
|
|
cb9d91a150 | ||
|
|
c630b720b0 | ||
|
|
a3eea803b3 | ||
|
|
d7ad16c5ae | ||
|
|
bb1fe98a9c | ||
|
|
467e3d1461 | ||
|
|
0f3c478234 | ||
|
|
593379f76c | ||
|
|
e316d7ddc7 | ||
|
|
20ce65a486 | ||
|
|
79a2aaee9d | ||
|
|
4c9fabf109 | ||
|
|
2458aa9bda | ||
|
|
d577e241ed | ||
|
|
b55bebd2f6 | ||
|
|
5d3d7dfbe7 | ||
|
|
12ec4c4ff7 | ||
|
|
35d5f72d35 | ||
|
|
b7ca433fcf | ||
|
|
57a4ad7585 | ||
|
|
da9a487a4c | ||
|
|
f9039db3be | ||
|
|
33864df00f | ||
|
|
11f201a4eb | ||
|
|
aa15363a6b | ||
|
|
83bc6e7a5c | ||
|
|
7527fb7093 | ||
|
|
975b8d129d | ||
|
|
fb004d1a01 | ||
|
|
b329884f6d | ||
|
|
7a0e96d12c | ||
|
|
fa75e458a9 | ||
|
|
a9223eeac5 | ||
|
|
d4bf6c1280 | ||
|
|
598b9fe5cd | ||
|
|
e47a45bab0 | ||
|
|
20e84d4edd | ||
|
|
11ef7f8090 | ||
|
|
364b96b084 | ||
|
|
d6f92032ad | ||
|
|
fc438ac9c8 | ||
|
|
d4087da24d | ||
|
|
962b63c128 | ||
|
|
8fc721143e | ||
|
|
e96df58758 | ||
|
|
1c351bf928 | ||
|
|
3ab94579e4 | ||
|
|
940a6094ae | ||
|
|
d94e2a806f | ||
|
|
2026c4c13c | ||
|
|
00bdf917ac | ||
|
|
480c5fa8f9 | ||
|
|
42c6639535 | ||
|
|
c3cddd4235 | ||
|
|
35bd9c577d | ||
|
|
b3531ca012 | ||
|
|
604f35514e | ||
|
|
50e1341252 | ||
|
|
18a1fcb564 | ||
|
|
dfc143258f | ||
|
|
793218485d | ||
|
|
6afffc8bb8 | ||
|
|
3d06cd2209 | ||
|
|
337868c27c | ||
|
|
42e5984afb | ||
|
|
7621239ae8 | ||
|
|
06236ad3db | ||
|
|
999a9fca5b | ||
|
|
057741536e | ||
|
|
a99e9286aa | ||
|
|
eadb3a08ac | ||
|
|
f74eb6d44a | ||
|
|
1de72140f0 | ||
|
|
e19b149834 | ||
|
|
c2179714e9 | ||
|
|
1094adfb65 | ||
|
|
30994f8fc9 | ||
|
|
4c9fadfae5 | ||
|
|
d8849053e1 | ||
|
|
ce49b67529 | ||
|
|
bf158924cd | ||
|
|
d2ac1a6f2f | ||
|
|
a7652dc8d0 | ||
|
|
856a8216a0 | ||
|
|
a2179f47cc | ||
|
|
e9beaec67b | ||
|
|
ef3093ed35 | ||
|
|
0f62e33bb4 | ||
|
|
ec8cda7a76 | ||
|
|
4c674602a6 | ||
|
|
2b3a9da379 | ||
|
|
b089e5c132 | ||
|
|
8e596fc3ec | ||
|
|
4b79eb9e0d | ||
|
|
1dbe3edee5 | ||
|
|
8caca4cd84 | ||
|
|
100f4e6385 | ||
|
|
64c76857a2 | ||
|
|
65dabefbd8 | ||
|
|
cd2c83f194 | ||
|
|
0d9a5476d8 | ||
|
|
d49fae6d43 | ||
|
|
640229ca80 | ||
|
|
4544108604 | ||
|
|
4dc23511b6 | ||
|
|
2d1e4f16ae | ||
|
|
8f1e9178f2 | ||
|
|
3b6d1d8514 | ||
|
|
356b8a49e4 | ||
|
|
5fb9793779 | ||
|
|
81b77fb32c | ||
|
|
bd2cc58a22 | ||
|
|
4f8d2dc6ba | ||
|
|
0401937ba2 | ||
|
|
194286f747 | ||
|
|
8525192fc6 | ||
|
|
866c338fdf | ||
|
|
2cea3fdf74 | ||
|
|
28464dd6a2 | ||
|
|
b3793d0166 | ||
|
|
0cdca0b936 | ||
|
|
1c52ece2ce | ||
|
|
e50ca9483d | ||
|
|
1f43bcd5a8 | ||
|
|
e9bfb1280f | ||
|
|
0e2ac03c36 | ||
|
|
b163193b72 | ||
|
|
e0c35a0760 | ||
|
|
c9de0c537b | ||
|
|
b5bd24564b | ||
|
|
63d58a0689 | ||
|
|
119de7a23c | ||
|
|
1bd66fc8f1 | ||
|
|
13b7ce6739 | ||
|
|
b630ff5efd | ||
|
|
02ce414503 | ||
|
|
2477f8e6e5 | ||
|
|
4904d52244 | ||
|
|
037a350afb | ||
|
|
62fcfe9726 | ||
|
|
3d9fb38e39 | ||
|
|
6c98053d92 | ||
|
|
dd7a96da44 | ||
|
|
20b2d4852b | ||
|
|
b4e96c779a | ||
|
|
6a54ab4dbf | ||
|
|
9535040f57 | ||
|
|
62001948f2 | ||
|
|
cb50299b22 | ||
|
|
ca9b8339e8 | ||
|
|
81f39b6a7a | ||
|
|
95d33983ed | ||
|
|
947d7d6a4f | ||
|
|
b3b09c66e9 | ||
|
|
0274612e8b | ||
|
|
37ddb7a324 | ||
|
|
4bf899b897 | ||
|
|
d264aa7187 | ||
|
|
46773b3e74 | ||
|
|
47729529c9 | ||
|
|
da9d5c9494 | ||
|
|
b16b8fcd02 | ||
|
|
802801a2d6 | ||
|
|
7dd6094ccf | ||
|
|
beeb1b17d8 | ||
|
|
01291ec23f | ||
|
|
ffd7c8bbe9 | ||
|
|
ddf9c23a1a | ||
|
|
e5d65455e1 | ||
|
|
854807950f | ||
|
|
3c6ba66c7e | ||
|
|
078dcc88a9 | ||
|
|
25a0ff1a16 | ||
|
|
5273a1283c | ||
|
|
540464fe5e | ||
|
|
14a55b34c5 | ||
|
|
6084ecc92e | ||
|
|
dab5f074c9 | ||
|
|
257637b5e2 | ||
|
|
eec170fe55 | ||
|
|
825d79e428 | ||
|
|
7d0e2638d8 | ||
|
|
c651d7b8b5 | ||
|
|
6b892382a0 | ||
|
|
3ef573d7e8 | ||
|
|
075fa0d7a9 | ||
|
|
1b831e7918 | ||
|
|
483779f914 | ||
|
|
3b1addab47 | ||
|
|
9e04fe0d1b | ||
|
|
cbf821fbb4 | ||
|
|
19df0682b0 | ||
|
|
08814f9d6e | ||
|
|
b3e7677238 | ||
|
|
17d7ce5983 | ||
|
|
ed6a118c12 | ||
|
|
21554bef52 | ||
|
|
13137fca11 | ||
|
|
595a708bec | ||
|
|
198cbe5688 | ||
|
|
3122652c62 | ||
|
|
01e5e9f7f2 | ||
|
|
18c7761d45 | ||
|
|
ea5cec846b | ||
|
|
c3ae019e94 | ||
|
|
aac58e361f | ||
|
|
11af0ee637 | ||
|
|
c4c77ad3f5 | ||
|
|
ae98c20f39 | ||
|
|
a08026b85d | ||
|
|
21009fe453 | ||
|
|
0d6ab56b55 | ||
|
|
bbf21d37e5 | ||
|
|
c3974ec39e | ||
|
|
d8e1d9f61d | ||
|
|
72d13bf888 | ||
|
|
be9a9d494f | ||
|
|
2effc6f205 | ||
|
|
996f21f073 | ||
|
|
fb32c56d64 | ||
|
|
f3c1baa214 | ||
|
|
270cd440c5 | ||
|
|
f3a424908d | ||
|
|
62083912bc | ||
|
|
a9204f9d26 | ||
|
|
8956e414a7 | ||
|
|
d0bdc365f7 | ||
|
|
7007e5c0aa | ||
|
|
5b570d1633 | ||
|
|
fc0de4cb9a | ||
|
|
647ceb76f6 | ||
|
|
3104138446 | ||
|
|
2390e976b3 | ||
|
|
0b410c28de | ||
|
|
c460a0805f | ||
|
|
fd75c5d5b7 | ||
|
|
a130738e19 | ||
|
|
718d19cea3 | ||
|
|
a7b8b72c64 | ||
|
|
f71201d66b | ||
|
|
9f6a643b90 | ||
|
|
38a5af69cc | ||
|
|
2bfee0bab9 | ||
|
|
5ef3f3a099 | ||
|
|
d07b57e7b2 | ||
|
|
a99e7c121d | ||
|
|
92ccd3a68a | ||
|
|
2728479b29 | ||
|
|
f291efa5e1 | ||
|
|
1ff0b389b8 | ||
|
|
808d1d7013 | ||
|
|
42d8b59624 | ||
|
|
d479a1d232 | ||
|
|
ae5733f3fb | ||
|
|
bdc4b13610 | ||
|
|
059d2e5948 | ||
|
|
56100f3bfb | ||
|
|
7616a301cd | ||
|
|
dc34871f80 | ||
|
|
d816906631 | ||
|
|
4a9cc61dde | ||
|
|
7ba03e948f | ||
|
|
42febcd147 | ||
|
|
a339d91cf4 | ||
|
|
760625c442 | ||
|
|
d2f5787b07 | ||
|
|
16c3dba5ea | ||
|
|
fb7e4d768e | ||
|
|
38ac3eb861 | ||
|
|
7756cb2d24 | ||
|
|
c06f1b5566 | ||
|
|
f6989a2f77 | ||
|
|
b154073461 | ||
|
|
b4b9f2de51 | ||
|
|
ff280f8649 | ||
|
|
55ed6ccb1e | ||
|
|
82479d1bc3 | ||
|
|
77123ed881 | ||
|
|
67bee86e2c | ||
|
|
4d605994a0 | ||
|
|
a59bd61a86 | ||
|
|
099b6e1a44 | ||
|
|
128e9bce31 | ||
|
|
07052b247b | ||
|
|
b2874c0b81 | ||
|
|
3a9e12c368 | ||
|
|
05c720ed3d | ||
|
|
2ab38512b7 | ||
|
|
2190fb0520 | ||
|
|
e76dfef294 | ||
|
|
386d2fe6f2 | ||
|
|
978741cb56 | ||
|
|
d9fd598eaf | ||
|
|
075485f490 | ||
|
|
be566f2e73 | ||
|
|
03f92e8593 | ||
|
|
3e0305d595 | ||
|
|
6441b3cc01 | ||
|
|
bcfbdafa30 | ||
|
|
1b9b03c1ae | ||
|
|
ebd492b8dd | ||
|
|
727e1b5aa9 | ||
|
|
9bd7ac0034 | ||
|
|
dc3fd935ff | ||
|
|
a080cdd50d | ||
|
|
e4e2e7fa73 | ||
|
|
9ae7a5bfa2 | ||
|
|
2a811f4720 | ||
|
|
4c32825969 | ||
|
|
f87add34ed | ||
|
|
5c41ea3123 | ||
|
|
90d0530c76 | ||
|
|
b3c87ecb9b | ||
|
|
917f2f381f | ||
|
|
a07798067b | ||
|
|
f3bb2de2d8 | ||
|
|
c9629616d7 | ||
|
|
36861672ea | ||
|
|
d0102204e9 | ||
|
|
25c15fd23a | ||
|
|
35ccedec98 | ||
|
|
9a73e8b61c | ||
|
|
762e7f09e3 | ||
|
|
ad547a13fe | ||
|
|
c75c8d31e9 | ||
|
|
c42f6fd09c | ||
|
|
988f07f7cc | ||
|
|
516e6fb841 | ||
|
|
22bbb008a2 | ||
|
|
4f0821b376 | ||
|
|
c23758faa7 | ||
|
|
4c52d9d0bf | ||
|
|
d2c84a6448 | ||
|
|
b4b13d2320 | ||
|
|
82c9bcc0a3 | ||
|
|
b32c3311a7 | ||
|
|
b9a3f88af2 | ||
|
|
506bab5bc2 | ||
|
|
91e93ff617 | ||
|
|
08a94e4e3f | ||
|
|
e343c554f5 | ||
|
|
5b68372330 | ||
|
|
e76e614f99 | ||
|
|
f6be10e522 | ||
|
|
40276399cb | ||
|
|
6d61839db6 | ||
|
|
9bc5d2638e | ||
|
|
ada48ed07e | ||
|
|
f0e5608a34 | ||
|
|
3ceec6233f | ||
|
|
869d0eeed3 | ||
|
|
fc8e133368 | ||
|
|
2b3432b5f4 | ||
|
|
8ade16e914 | ||
|
|
ad2ca6bee9 | ||
|
|
11eed64fbd | ||
|
|
65d28941a5 | ||
|
|
8f8328c313 | ||
|
|
05b82bb9a6 | ||
|
|
2e811ca386 | ||
|
|
dc64ebbb94 | ||
|
|
daf4841824 | ||
|
|
6d9840100e | ||
|
|
17c48aa2ff | ||
|
|
9c1a2c9dee | ||
|
|
e3bcc1ccbf | ||
|
|
cefb788dd5 | ||
|
|
a19b9f01de | ||
|
|
96bd34bdb8 | ||
|
|
31ab11fa8c | ||
|
|
c83d396433 | ||
|
|
51ca3fd187 | ||
|
|
3c8a59b809 | ||
|
|
9b4d4a789e | ||
|
|
1e998df69a | ||
|
|
5a3ac54025 | ||
|
|
ff5c338379 | ||
|
|
f8b355c8ce | ||
|
|
c94dbdaafe | ||
|
|
470902d979 | ||
|
|
5a659016da | ||
|
|
04bf79b52a | ||
|
|
b9cd27506d | ||
|
|
7973d23dab | ||
|
|
b2b0baeff1 | ||
|
|
a8d50fee21 | ||
|
|
1ba02094fe | ||
|
|
57aa8c30f0 | ||
|
|
9d65e95ed9 | ||
|
|
ed9576ce04 | ||
|
|
d383ea1d5d | ||
|
|
9707b97516 | ||
|
|
c9904fb9a9 | ||
|
|
4b823852b8 | ||
|
|
3fc9204749 | ||
|
|
0c30f57edd | ||
|
|
4048891c68 | ||
|
|
8264ff8273 | ||
|
|
97a985f4e5 | ||
|
|
236b14557a | ||
|
|
94db0def6f | ||
|
|
fd545ba73a | ||
|
|
75f05e8721 | ||
|
|
3bc0f0e6f0 |
@@ -42,8 +42,8 @@ fields:
|
||||
name: permalink
|
||||
label: Permalink
|
||||
description: 'URL for this post. Must start and end with slashes. <br>For blog posts,
|
||||
include the date: <em>/2022-09-23-descriptive-title/</em><br>For weekly newsletters,
|
||||
use the edition number: <em>/weekly-123/</em>'
|
||||
include the date: <em>/2022-09-23-descriptive-title/</em><br>For newsletters,
|
||||
use the edition number: <em>/newsletter-123/</em>'
|
||||
config:
|
||||
required: true
|
||||
- type: text
|
||||
@@ -154,6 +154,7 @@ pages:
|
||||
- src/_blog/2021-05-31-distributed-wikipedia-mirror-update.md
|
||||
- src/_blog/2022-12-07-testground-in-2022.md
|
||||
- src/_blog/2023-01-10-announcing-pin-tweet-to-ipfs.md
|
||||
- src/_blog/2023-01-26-announcing-durin.md
|
||||
- src/_blog/3s-studio-bringing-unreal-engine-to-ipfs.md
|
||||
- src/_blog/a-brave-new-wallet-the-future-of-the-browser-wallet.md
|
||||
- src/_blog/a-guide-to-ipfs-connectivity-in-web-browsers.md
|
||||
|
||||
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@@ -14,4 +14,8 @@ updates:
|
||||
assignees:
|
||||
- 'zebateira'
|
||||
labels:
|
||||
- 'dependencies'
|
||||
- 'dependencies'
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
||||
57
.github/workflows/build.yml
vendored
Normal file
57
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# Build workflow - runs for both PRs and main branch pushes
|
||||
# This workflow builds the website without access to secrets
|
||||
# For PRs: Runs on untrusted fork code safely (using pull_request event, not pull_request_target)
|
||||
# For main: Builds and uploads artifacts for deployment
|
||||
# Artifacts are passed to the deploy workflow which has access to secrets
|
||||
|
||||
name: Build
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
env:
|
||||
BUILD_PATH: 'dist'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# - For PRs: PR head commit
|
||||
# - For pushes: the pushed commit
|
||||
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci --prefer-offline --no-audit --progress=false
|
||||
|
||||
- name: Build project
|
||||
run: npm run build
|
||||
|
||||
# Upload artifact for deploy workflow
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: blog-build-${{ github.run_id }}
|
||||
path: ${{ env.BUILD_PATH }}
|
||||
retention-days: 1
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Compress Images
|
||||
uses: calibreapp/image-actions@main
|
||||
|
||||
105
.github/workflows/deploy.yml
vendored
Normal file
105
.github/workflows/deploy.yml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# Deploy workflow - triggered by workflow_run after successful build
|
||||
# This workflow has access to secrets but never executes untrusted code
|
||||
# It only downloads and deploys pre-built artifacts from the build workflow
|
||||
# Security: Fork code cannot access secrets as it only runs in build workflow
|
||||
# Deploys to IPFS for all branches
|
||||
|
||||
name: Deploy
|
||||
|
||||
# Explicitly declare permissions
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build"]
|
||||
types: [completed]
|
||||
|
||||
env:
|
||||
BUILD_PATH: 'blog-build'
|
||||
|
||||
# Prevent concurrent deployments to the same target
|
||||
# This avoids the "multiple github-pages artifacts" error
|
||||
concurrency:
|
||||
group: deploy-${{ github.event.workflow_run.head_branch }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy-ipfs:
|
||||
if: github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
cid: ${{ steps.deploy.outputs.cid }}
|
||||
environment:
|
||||
name: 'ipfs-publish'
|
||||
steps:
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: blog-build-${{ github.event.workflow_run.id }}
|
||||
path: ${{ env.BUILD_PATH }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
- name: Deploy to IPFS
|
||||
uses: ipshipyard/ipfs-deploy-action@v1
|
||||
id: deploy
|
||||
with:
|
||||
path-to-deploy: ${{ env.BUILD_PATH }}
|
||||
cluster-url: "/dnsaddr/ipfs-websites.collab.ipfscluster.io"
|
||||
cluster-user: ${{ secrets.CLUSTER_USER }}
|
||||
cluster-password: ${{ secrets.CLUSTER_PASSWORD }}
|
||||
cluster-pin-expire-in: ${{ github.event.workflow_run.head_branch != 'main' && '2160h' || '' }}
|
||||
storacha-key: ${{ secrets.STORACHA_KEY }}
|
||||
storacha-proof: ${{ secrets.STORACHA_PROOF }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
dnslink-update:
|
||||
runs-on: ubuntu-latest
|
||||
needs: deploy-ipfs
|
||||
if: github.event.workflow_run.head_branch == 'main'
|
||||
environment:
|
||||
name: 'cf-dnslink'
|
||||
url: "https://blog-ipfs-tech.ipns.inbrowser.link/"
|
||||
steps:
|
||||
- name: Update DNSLink
|
||||
uses: ipshipyard/dnslink-action@v1
|
||||
with:
|
||||
cid: ${{ needs.deploy-ipfs.outputs.cid }}
|
||||
dnslink_domain: 'blog-ipfs-tech.dnslinks.ipshipyard.tech'
|
||||
cf_zone_id: ${{ secrets.CF_DNS_ZONE_ID }}
|
||||
cf_auth_token: ${{ secrets.CF_DNS_AUTH_TOKEN }}
|
||||
github_token: ${{ github.token }}
|
||||
set_github_status: true
|
||||
|
||||
deploy-gh-pages:
|
||||
if: |
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.head_branch == 'main'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
pages: write
|
||||
id-token: write
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Download build artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: blog-build-${{ github.event.workflow_run.id }}
|
||||
path: blog-build
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ github.token }}
|
||||
|
||||
- name: Upload Pages artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
path: blog-build
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
14
.github/workflows/generated-pr.yml
vendored
Normal file
14
.github/workflows/generated-pr.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: Close Generated PRs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-generated-pr.yml@v1
|
||||
2
.github/workflows/scheduled-publishing.yml
vendored
2
.github/workflows/scheduled-publishing.yml
vendored
@@ -8,7 +8,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Check for scheduled posts
|
||||
|
||||
28
.github/workflows/stale.yml
vendored
28
.github/workflows/stale.yml
vendored
@@ -1,26 +1,14 @@
|
||||
name: Close and mark stale issue
|
||||
name: Close Stale Issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
- cron: '0 0 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v3
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'Oops, seems like we needed more information for this issue, please comment with more details or this issue will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it is missing author input.'
|
||||
stale-issue-label: 'kind/stale'
|
||||
any-of-labels: 'need/author-input'
|
||||
exempt-issue-labels: 'need/triage,need/community-input,need/maintainer-input,need/maintainers-input,need/analysis,status/blocked,status/in-progress,status/ready,status/deferred,status/inactive'
|
||||
days-before-issue-stale: 6
|
||||
days-before-issue-close: 7
|
||||
enable-statistics: true
|
||||
uses: ipdxco/unified-github-workflows/.github/workflows/reusable-stale-issue.yml@v1
|
||||
|
||||
2
.github/workflows/sync-staging.yml
vendored
2
.github/workflows/sync-staging.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Sync target branch
|
||||
|
||||
54
README.md
54
README.md
@@ -12,46 +12,6 @@ This repository contains code and content for the [IPFS Blog & News](https://blo
|
||||
|
||||
**If you just want to submit a link (event, academic paper, tutorial, video or news coverage) to add to the site, [use this easy form](https://airtable.com/shrNH8YWole1xc70I)!**
|
||||
|
||||
## For post authors/editors
|
||||
|
||||
There are 2 ways to create a new blog post:
|
||||
- Via the [Forestry](https://forestry.io) editor
|
||||
- Via a [manual pull request](#creating-a-new-blog-post-via-github-pull-request)
|
||||
|
||||
### Creating a new blog post using Forestry
|
||||
Forestry is a content management system (CMS) that automatically creates and manages Github PRs for each new post. Using Forestry offers you WYSIWYG editing (in addition to raw markdown mode), easy image upload/crop tools, and instant previews. If you're a regular contributor to the IPFS blog and would like to request Forestry access, contact Emily Vaughan.
|
||||
|
||||
Forestry uses the `staging` branch as a work-in-progress scratchpad for blog content. Once content in `staging` is approved, it can be merged into `main`, which is the branch that feeds the production site at blog.ipfs.tech. Merges into `main` are _automatically deployed_ to the production site using [Fleek](https://fleek.co/).
|
||||
|
||||
### Forestry authoring/editing tips
|
||||
|
||||
- Use the "Content Types" section of Forestry's left-hand menu to drill down to the type of item (blog post, video, news coverage, event) you want to create/edit.
|
||||
- For card and blog post header images, **be sure to use the [image crop/scale tool](https://blog.ipfs.tech/image-crop/)** to resize and save images so they're the correct dimensions. (Don't have an image? Don't worry, there are generic fallback images.)
|
||||
- Want to embed a YouTube video in a blog post? Switch to raw markdown view and use `@[youtube](videoID)`, substituting the video's unique ID from the URL (e.g. `https://www.youtube.com/watch?v=eFbKKsEoQNg`) for `videoID`.
|
||||
- To switch between WYSIWYG and raw markdown while writing a blog post, choose "Raw Editor" or "WYSIWYG Editor" from the dots menu at the top right of the page:<br/>
|
||||
|
||||
### Forestry build preview tips
|
||||
|
||||
While WYSIWYG mode usually gives you a good enough idea of what a blog post will look like, you can also load Forestry's own _build preview_ in a new tab by clicking the eye icon at the top right of the page:<br/>
|
||||
|
||||
This build preview lets you preview changes to any content type (not just blog posts), and _does not_ require you to save your changes in order to see them.
|
||||
|
||||
A few tips:
|
||||
|
||||
- Click the eye icon to _regenerate_ a build preview at any time from a Forestry edit page. You may need to reload the build preview tab if you don't see changes come through immediately.
|
||||
- Occasionally, a build preview page gets stuck at a URL ending in `forestry/pending` or simply won't load. In this case, try the following:
|
||||
- Remove `forestry/pending` from the URL and try again.
|
||||
- Check the Previews section of Forestry's [`Site > Settings` page](https://app.forestry.io/sites/lg5t7mxcqbr-da/#/settings/previews) to see the preview server's current status, start/stop/restart the server, or examine the logs for errors. Simply restarting the preview server can fix many problems.
|
||||
- If all else fails, save your changes, wait a few minutes, and take a look at [Fleek's build of the latest version of the `staging` branch](https://ipfs-blog-staging.on.fleek.co/). It's a considerably slower build/deploy time, but does reflect the latest changes once it finishes deploying.
|
||||
|
||||
### To deploy to the live site
|
||||
|
||||
Changes you _save_ in Forestry are written directly to the `staging` branch and automatically generate a staging preview at https://ipfs-blog-staging.on.fleek.co/.
|
||||
|
||||
**Once a staged post is ready to go live, please PR `staging` to `main` using [this handy shortcut](https://github.com/ipfs/ipfs-blog/compare/main...staging?expand=1).** Give your PR a title explaining what changes are inside (the default just says "Staging", which isn't helpful.) _Note that if multiple posts are in-flight in staging and only one is approved to go live, your PR may need some massaging by a reviewer._
|
||||
|
||||
_Note for PR reviewers: While we continue to dogfood Forestry, please leave your edits in comments rather than making additional commits._ As our overall workflow continues to solidify, this direction may change.
|
||||
|
||||
### Creating a new blog post via Github pull request
|
||||
|
||||
Each blog post is a markdown file in the [`src/_blog`](./src/_blog) folder, with a little metadata at the top (known as YAML frontmatter) to help us create the post index page.
|
||||
@@ -90,15 +50,15 @@ 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
|
||||
|
||||
Each post can have a custom image that is shown on the [blog homepage](https://blog.ipfs.tech/). To set an image:
|
||||
|
||||
1. Add the image into `static\header_images`. Typically the image is `2048×1152px` in jpg/png.
|
||||
1. Add the image into `assets\header_images`. Typically the image is `2048×1152px` in jpg/png.
|
||||
1. Rename the image to match the file name of your post. For example, the `2022-12-community-calendar.md` post uses `2022-12-community-calendar.png` as the header.
|
||||
1. In the post markdown, edit the front-matter to include the `header_image` variable:
|
||||
|
||||
@@ -110,7 +70,7 @@ Each post can have a custom image that is shown on the [blog homepage](https://b
|
||||
|
||||
To create a pull request, you will need to fork this repository. See the GitHub docs on [how to create a pull request from a fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). If you have the [GitHub CLI](https://cli.github.com/) installed, you can use the [`gh pr create` command](https://cli.github.com/manual/gh_pr_create) from the terminal to conveniently create a pull request.
|
||||
|
||||
Once you create the pull request, await review.
|
||||
Once you create the pull request, await review. If you have permissions to merge, always preview the post first to ensure everything looks right. You can do this by clicking on the "Details" link next to the **fleek/build** check that runs automatically. Clicking this link will take you to a staging site where you will then need to click on the intended post in the feed to see it.
|
||||
|
||||
### To add a URL redirect for a blog post
|
||||
|
||||
@@ -135,7 +95,7 @@ To build a local copy, run the following:
|
||||
1. Move into the `ipfs-blog` folder and install the npm dependencies:
|
||||
|
||||
```bash
|
||||
cd ipfs-docs
|
||||
cd ipfs-blog
|
||||
npm install
|
||||
```
|
||||
|
||||
@@ -145,6 +105,12 @@ 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
16
package-lock.json
generated
@@ -6364,9 +6364,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001376",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001376.tgz",
|
||||
"integrity": "sha512-I27WhtOQ3X3v3it9gNs/oTpoE5KpwmqKR5oKPA8M0G7uMXh9Ty81Q904HpKUrM30ei7zfcL5jE7AXefgbOfMig==",
|
||||
"version": "1.0.30001651",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -6376,6 +6376,10 @@
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -30067,9 +30071,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001376",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001376.tgz",
|
||||
"integrity": "sha512-I27WhtOQ3X3v3it9gNs/oTpoE5KpwmqKR5oKPA8M0G7uMXh9Ty81Q904HpKUrM30ei7zfcL5jE7AXefgbOfMig==",
|
||||
"version": "1.0.30001651",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz",
|
||||
"integrity": "sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"scripts": {
|
||||
"start": "npm run dev",
|
||||
"dev": "vuepress dev src",
|
||||
"build": "vuepress build src && npm run postbuild",
|
||||
"build": "NODE_OPTIONS=--openssl-legacy-provider vuepress build src && npm run postbuild",
|
||||
"postbuild": "./scripts/data/index.js",
|
||||
"lint": "prettier --write \"**/*.{json,yaml,md}\" && run-p lint:**",
|
||||
"lint:eslint": "eslint --cache \"**/*.{js,vue}\" --fix",
|
||||
|
||||
96
scripts/data/enhance-feed.js
Normal file
96
scripts/data/enhance-feed.js
Normal file
@@ -0,0 +1,96 @@
|
||||
'use strict'
|
||||
|
||||
/**
|
||||
* Enhances the RSS feed to include items from special content pages
|
||||
* (release notes, ecosystem content, etc.) that are stored as YAML
|
||||
* arrays in frontmatter rather than individual markdown files.
|
||||
*/
|
||||
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const xml2js = require('xml2js')
|
||||
const matter = require('gray-matter')
|
||||
const dayjs = require('dayjs')
|
||||
|
||||
const xmlFilePath = 'dist/index.xml'
|
||||
|
||||
// Only include items published after this date (to avoid backfilling old content)
|
||||
const CUTOFF_DATE = dayjs('2025-11-25')
|
||||
|
||||
// Content types to include in the unified feed
|
||||
// Each item in the data array should have: title, date, path (URL)
|
||||
const CONTENT_SOURCES = [
|
||||
{ file: 'releasenotes.md', category: 'Release Notes' },
|
||||
{ file: 'ecosystemcontent.md', category: 'Ecosystem' },
|
||||
{ file: 'newscoverage.md', category: 'News Coverage' },
|
||||
{ file: 'videos.md', category: 'Videos' },
|
||||
{ file: 'tutorials.md', category: 'Tutorials' },
|
||||
{ file: 'events.md', category: 'Events' },
|
||||
]
|
||||
|
||||
function parseContentFile(filename) {
|
||||
const filepath = path.resolve('src/_blog', filename)
|
||||
try {
|
||||
const content = fs.readFileSync(filepath, 'utf8')
|
||||
const { data } = matter(content)
|
||||
const now = dayjs()
|
||||
return (data.data || []).filter((item) => {
|
||||
if (item.hidden) return false
|
||||
if (item.publish_date && dayjs(item.publish_date).isAfter(now)) return false
|
||||
return dayjs(item.publish_date || item.date).isAfter(CUTOFF_DATE)
|
||||
})
|
||||
} catch (err) {
|
||||
console.error(`Warning: Could not read ${filename}:`, err.message)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
function itemToRssEntry(item, category) {
|
||||
return {
|
||||
title: [item.title],
|
||||
link: [item.path],
|
||||
pubDate: [dayjs(item.date).toDate().toUTCString()],
|
||||
description: [item.description || item.title],
|
||||
category: [category],
|
||||
guid: [{ _: item.path, $: { isPermaLink: 'true' } }],
|
||||
}
|
||||
}
|
||||
|
||||
async function enhanceFeed() {
|
||||
let xmlData, parsed
|
||||
try {
|
||||
xmlData = fs.readFileSync(xmlFilePath, 'utf8')
|
||||
parsed = await xml2js.parseStringPromise(xmlData)
|
||||
} catch (err) {
|
||||
console.error('Could not read/parse RSS feed:', err.message)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Blog posts link to the blog domain, special content links externally
|
||||
const blogDomain = parsed.rss.channel[0].link[0]
|
||||
const existingItems = (parsed.rss.channel[0].item || []).filter(
|
||||
(item) => item.link[0].startsWith(blogDomain)
|
||||
)
|
||||
|
||||
// Parse special content and convert to RSS items
|
||||
const additionalItems = CONTENT_SOURCES.flatMap((source) =>
|
||||
parseContentFile(source.file).map((i) => itemToRssEntry(i, source.category))
|
||||
)
|
||||
|
||||
// Deduplicate by guid
|
||||
const seen = new Set()
|
||||
const allItems = [...existingItems, ...additionalItems]
|
||||
.filter((item) => {
|
||||
const guid = item.guid?.[0]?._ || item.guid?.[0] || item.link[0]
|
||||
return !seen.has(guid) && seen.add(guid)
|
||||
})
|
||||
.sort((a, b) => new Date(b.pubDate[0]) - new Date(a.pubDate[0]))
|
||||
|
||||
parsed.rss.channel[0].item = allItems
|
||||
|
||||
const builder = new xml2js.Builder({ xmldec: { version: '1.0', encoding: 'UTF-8' } })
|
||||
fs.writeFileSync(xmlFilePath, builder.buildObject(parsed))
|
||||
console.log(`Enhanced RSS feed: ${allItems.length} items (${existingItems.length} posts + ${additionalItems.length} special)`)
|
||||
}
|
||||
|
||||
exports.enhanceFeed = enhanceFeed
|
||||
@@ -2,10 +2,15 @@
|
||||
|
||||
'use strict'
|
||||
|
||||
const { enhanceFeed } = require('./enhance-feed')
|
||||
const { generateIndexFile } = require('./latest-posts')
|
||||
const { generateNewsFile } = require('./latest-news')
|
||||
const { generateVideosFile } = require('./latest-videos')
|
||||
|
||||
generateIndexFile()
|
||||
generateNewsFile()
|
||||
generateVideosFile()
|
||||
// Enhance RSS feed first (adds release notes, ecosystem content, etc.)
|
||||
// then generate index.json from the enhanced feed
|
||||
enhanceFeed().then(() => {
|
||||
generateIndexFile()
|
||||
generateNewsFile()
|
||||
generateVideosFile()
|
||||
})
|
||||
|
||||
@@ -42,20 +42,18 @@ const themeConfigDefaults = {
|
||||
],
|
||||
footerLegal: '',
|
||||
headerLinks: [
|
||||
{ text: 'About', link: 'https://ipfs.tech/#why' },
|
||||
{ text: 'Install', link: 'https://ipfs.tech/#install' },
|
||||
{ text: 'About', link: 'https://ipfs.tech/' },
|
||||
{ text: 'Community', link: 'https://ipfs.tech/community/' },
|
||||
{ text: 'Developers', link: 'https://ipfs.tech/developers/' },
|
||||
{ text: 'Docs', link: 'https://docs.ipfs.tech/' },
|
||||
{ text: 'Team', link: 'https://ipfs.tech/team' },
|
||||
{ text: 'Blog', link: '/' },
|
||||
{ text: 'Help', link: 'https://ipfs.tech/help' },
|
||||
],
|
||||
mobileNavLinks: [
|
||||
{ text: 'About', link: 'https://ipfs.tech/#why' },
|
||||
{ text: 'Install', link: 'https://ipfs.tech/#install' },
|
||||
{ text: 'About', link: 'https://ipfs.tech/' },
|
||||
{ text: 'Community', link: 'https://ipfs.tech/community/' },
|
||||
{ text: 'Developers', link: 'https://ipfs.tech/developers/' },
|
||||
{ text: 'Docs', link: 'https://docs.ipfs.tech/' },
|
||||
{ text: 'Team', link: 'https://ipfs.tech/team' },
|
||||
{ text: 'Blog', link: '/' },
|
||||
{ text: 'Help', link: 'https://ipfs.tech/help' },
|
||||
],
|
||||
}
|
||||
|
||||
@@ -112,20 +110,18 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
headerLinks: [
|
||||
{ text: 'About', link: 'https://ipfs.tech/#why' },
|
||||
{ text: 'Install', link: 'https://ipfs.tech/#install' },
|
||||
{ text: 'About', link: 'https://ipfs.tech/' },
|
||||
{ text: 'Community', link: 'https://ipfs.tech/community/' },
|
||||
{ text: 'Developers', link: 'https://ipfs.tech/developers/' },
|
||||
{ text: 'Docs', link: 'https://docs.ipfs.tech/' },
|
||||
{ text: 'Team', link: 'https://ipfs.tech/team' },
|
||||
{ text: 'Blog', link: '/zh-cn' },
|
||||
{ text: 'Help', link: 'https://ipfs.tech/help' },
|
||||
],
|
||||
mobileNavLinks: [
|
||||
{ text: 'About', link: 'https://ipfs.tech/#why' },
|
||||
{ text: 'Install', link: 'https://ipfs.tech/#install' },
|
||||
{ text: 'About', link: 'https://ipfs.tech/' },
|
||||
{ text: 'Community', link: 'https://ipfs.tech/community/' },
|
||||
{ text: 'Developers', link: 'https://ipfs.tech/developers/' },
|
||||
{ text: 'Docs', link: 'https://docs.ipfs.tech/' },
|
||||
{ text: 'Team', link: 'https://ipfs.tech/team' },
|
||||
{ text: 'Blog', link: '/zh-cn/' },
|
||||
{ text: 'Help', link: 'https://ipfs.tech/help' },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -35,8 +35,7 @@ module.exports = [
|
||||
{
|
||||
defer: true,
|
||||
'data-domain': 'blog.ipfs.tech',
|
||||
'data-api': 'https://proxy.daas.workers.dev/api/event',
|
||||
src: 'https://proxy.daas.workers.dev/js/script.js',
|
||||
src: 'https://plausible.io/js/plausible.js',
|
||||
},
|
||||
],
|
||||
].concat(favicons)
|
||||
|
||||
@@ -39,6 +39,7 @@ export default {
|
||||
case 'News coverage':
|
||||
case 'Release notes':
|
||||
case 'Tutorial':
|
||||
case 'Ecosystem content':
|
||||
case 'Video':
|
||||
return LinkCard
|
||||
|
||||
|
||||
@@ -35,12 +35,13 @@ 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('body')[0].appendChild(d)
|
||||
;(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d)
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
class="text-blueGreen hover:underline"
|
||||
href="#newsletter-form"
|
||||
@click="blockLazyLoad()"
|
||||
>weekly newsletter</a
|
||||
>newsletter</a
|
||||
>{{ `, ` }}
|
||||
<a
|
||||
class="text-blueGreen hover:underline"
|
||||
|
||||
@@ -5,77 +5,51 @@
|
||||
>
|
||||
<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 mr-2">
|
||||
Sign up for the IPFS Weekly newsletter (<router-link
|
||||
<p class="mt-2 mb-6 mr-2">
|
||||
Sign up for the IPFS newsletter (<router-link
|
||||
:to="latestWeeklyPost ? latestWeeklyPost.path : ''"
|
||||
class="text-blueGreenLight hover:underline"
|
||||
>example</router-link
|
||||
>) 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>
|
||||
<form
|
||||
|
||||
<div
|
||||
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">
|
||||
<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 class="sm:ml-4 sm:pt-0"></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 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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
import countly from '../../util/countly'
|
||||
|
||||
export default {
|
||||
name: 'NewsletterForm',
|
||||
props: {},
|
||||
@@ -85,10 +59,6 @@ export default {
|
||||
computed: {
|
||||
...mapState('appState', ['latestWeeklyPost']),
|
||||
},
|
||||
methods: {
|
||||
subscribeClick() {
|
||||
countly.trackEvent(countly.events.NEWSLETTER_SUBSCRIBE)
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -19,7 +19,14 @@
|
||||
: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"
|
||||
>
|
||||
@@ -37,7 +44,17 @@
|
||||
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
|
||||
@@ -327,7 +344,7 @@ export default {
|
||||
(item) =>
|
||||
item.frontmatter &&
|
||||
item.frontmatter.tags &&
|
||||
item.frontmatter.tags.find((tag) => tag.name === 'weekly')
|
||||
item.frontmatter.tags.find((tag) => tag.name === 'newsletter')
|
||||
)
|
||||
.sort(
|
||||
(a, b) => new Date(b.frontmatter.date) - new Date(a.frontmatter.date)
|
||||
|
||||
@@ -8,3 +8,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.type-rich {
|
||||
@apply text-18
|
||||
}
|
||||
@@ -37,7 +37,10 @@ export function loadScript() {
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(cly, s);
|
||||
})();`
|
||||
|
||||
document.body.appendChild(countlyScript)
|
||||
// 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)
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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@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 [AT] 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
|
||||
|
||||
@@ -30,7 +30,7 @@ If we take a look at some recent studies, this centralized content becomes harde
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/P6q3lHFPN5o" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
|
||||
### Under the hood:
|
||||
We are using tools from the [WebRecorder](https://webrecorder.net/) team to create verifiable [WebArChiveZip](https://specs.webrecorder.net/wacz/1.1.1/) files of tweets. We then assist the user in uploading these "WACZ" files to the IPFS network via [web3.storage](https://web3.storage). Here users can store all of their archived tweets in one place, and easily access them via their own IPFS node or other pinning services.
|
||||
We are using a new tool, ["save tweet now"](https://webrecorder.github.io/save-tweet-now/), from the [WebRecorder](https://webrecorder.net/) team to create verifiable [WebArChiveZip](https://specs.webrecorder.net/wacz/1.1.1/) files of tweets. We then assist the user in uploading these "WACZ" files to the IPFS network via [web3.storage](https://web3.storage). Here users can store all of their archived tweets in one place, and easily access them via their own IPFS node or other pinning services.
|
||||
|
||||
### Where is it available?
|
||||
|
||||
@@ -46,4 +46,4 @@ Pin Tweet to IPFS is currently available in the [Chrome web store](https://chrom
|
||||
|
||||
### What's next?
|
||||
|
||||
We're continuing to iterate on *Pin Tweet to IPFS* to make archiving faster and add more verification capabilities. Take a look at our [issue tracker](https://github.com/meandavejustice/pin-tweet-to-ipfs/issues) to stay up to date on upcoming changes, and [submit your feedback](https://github.com/meandavejustice/pin-tweet-to-ipfs/issues/new).
|
||||
We're continuing to iterate on *Pin Tweet to IPFS* to make archiving faster and add more verification capabilities. Take a look at our [issue tracker](https://github.com/meandavejustice/pin-tweet-to-ipfs/issues) to stay up to date on upcoming changes, and [submit your feedback](https://github.com/meandavejustice/pin-tweet-to-ipfs/issues/new).
|
||||
|
||||
82
src/_blog/2023-01-26-announcing-durin.md
Normal file
82
src/_blog/2023-01-26-announcing-durin.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: "Announcing Durin: a New Mobile App for the IPFS Network"
|
||||
description: "Durin is a native mobile application for iOS and Android that lets you read and share content on the IPFS network"
|
||||
date: 2023-05-11
|
||||
permalink: "/announcing-durin/"
|
||||
header_image: '/durin-featured-image.png'
|
||||
author: David Justice
|
||||
tags:
|
||||
- Durin
|
||||
- mobile
|
||||
- ios
|
||||
- android
|
||||
- app store
|
||||
- web3 storage
|
||||
- web3
|
||||
---
|
||||
|
||||
Today we are excited to announce **Durin**, a native mobile application for [iOS](https://apps.apple.com/us/app/durin/id1613391995) and [Android](https://play.google.com/store/apps/details?id=ai.protocol.durin) built to give users a new way to read and share with IPFS. It also serves as a sandbox for the Browsers & Platforms team to experiment with IPFS in a mobile environment.
|
||||
|
||||
## Background
|
||||
|
||||
To date, it's been difficult to access, upload, and share IPFS content using a mobile device. This is for a number of reasons, one of which is that [Kubo](https://github.com/ipfs/kubo)(the initial implementation of the protocol) was simply not built with mobile in mind. The IPFS approach to P2P for many years was about running servers, but [that is changing](https://blog.ipfs.tech/2023-03-implementation-principles/). In the meantime, we wanted to provide a quick and easy way for users to access basic IPFS features on mobile and set up a testing ground for future explorations.
|
||||
|
||||
## Accessing IPFS Content
|
||||
|
||||
The transport-agnostic nature of IPFS content addresses means there are many ways to find and retrieve content on the IPFS public network. On a mobile device, the best balance of decentralization and device performance is to align with the network model of the device OS - transient connectivity.
|
||||
|
||||
We do this in Durin by connecting to the IPFS network via multiple HTTP gateways. On app launch, Durin pings a list of public gateways, and determines which route is the most reliable and fastest way to access the network. This approach is functional but not optimal. We're working on specifications for multi-gateway connectivity patterns which balance a number of factors - such as verifiability guarantees, reader privacy, and not overloading gateways.
|
||||
|
||||
<br>
|
||||
|
||||
<img src="../assets/announcing-durin-ipfs/gateway-durin.png" alt="gateway list">
|
||||
|
||||
IPFS addresses are not natively supported in most web browsers or any mobile operating systems today. Durin registers as an `ipfs` scheme handler so that addresses are handled when encountered in applications and on the web.
|
||||
|
||||
On iOS Safari `ipfs://` protocol links will be redirected to Durin, where the app will translate and redirect the user to the fastest public gateway, making the content available on mobile. Unfortunately the auto-redirects do not work using Chrome's android app. They have not yet [implemented `registerProtocolHandler`](https://bugs.chromium.org/p/chromium/issues/detail?id=178097&q=protocol%20handler%20mobile&can=2)).
|
||||
|
||||
<br>
|
||||
|
||||
<img src="../assets/announcing-durin-ipfs/durin-redirect.gif" alt="redirect functionality on mobile safari">
|
||||
|
||||
## Sharing to IPFS from Mobile
|
||||
|
||||
Mobile devices are transiently connected and low-powered, so they do not make good servers. For sharing files and data to IPFS, Durin uses a [pinning service](https://docs.ipfs.tech/concepts/persistence/#persistence-permanence-and-pinning) to do this on behalf of the user.
|
||||
|
||||
We currently rely on [web3.storage](https://web3.storage/) for file uploads. `web3.storage` is a service that makes decentralized file storage accessible by hosting data on IPFS for the user, the way a web host does for HTTP today. NOTE: _Using a single service like this is not ideal, as users don’t hold those keys. We plan to experiment with approaches to ensuring maximal user ownership of their data while also providing remote storage and data availability._
|
||||
|
||||
Durin also saves a local history of uploads already shared.
|
||||
|
||||
<br>
|
||||
|
||||
<img src="../assets/announcing-durin-ipfs/filelist-durin.png" alt="uploaded files list">
|
||||
|
||||
Using a single remote service is a usable first step, but doesn't provide long term user control of the data published. We're looking at tighter integration with local OS data storage, local sharing between devices when possible, and pluggable remote service support.
|
||||
|
||||
## Install Durin
|
||||
|
||||
Durin is available now for mobile phones in the iOS app store and Google Play store.
|
||||
<br />
|
||||
<a href="https://apps.apple.com/us/app/durin/id1613391995" class="cta-button"> Get Durin in iOS App Store </a>
|
||||
<br />
|
||||
<a href="https://play.google.com/store/apps/details?id=ai.protocol.durin" class="cta-button"> Get Durin in Google Play Store</a>
|
||||
|
||||
## The Future
|
||||
|
||||
Durin is an experiment in learning how to expose and integrate IPFS features into mobile operating systems in ways which align optimally with those environments. We're trying out variety of ideas from contacts integration, photo sync & backup, filecoin storage, peer to peer bluetooth connectivity.
|
||||
|
||||
We'd love to hear your ideas and feedback, and have you participate!
|
||||
|
||||
* [ipfs-shipyard/durin on Github](https://github.com/ipfs-shipyard/durin)
|
||||
* [HackMd project document](https://hackmd.io/XtxGZoxqQ46X1GO7srrhMQ)
|
||||
* [Feedback link](https://github.com/ipfs-shipyard/durin/issues)
|
||||
|
||||
Join the #browsers-and-platforms channel which is bridged across the [Filecoin Slack](https://filecoin.io/slack/), [IPFS Discord](https://discord.gg/vZTcrFePpt) and [Element/Matrix](https://matrix.to/#/#browsers-and-standards:ipfs.io).
|
||||
|
||||
Checkout the IPFS Thing talk, discussing Durin's role and some future ideas for the app.
|
||||
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/QkhnKm-fCs4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
## Shoutout
|
||||
|
||||
Shout out to [Trigram](https://www.trigram.co/) for continued work on Durin.
|
||||
180
src/_blog/2023-03-implementations-principles.md
Normal file
180
src/_blog/2023-03-implementations-principles.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: 'IPFS Implementations: It’s Definitely A Thing'
|
||||
description: 'IPFS implementations vary wildly in order to adapt to as many situations as possible, and more keep being created. To bring clarity to the ecosystem, we look at some principles that make IPFS what it is.'
|
||||
author: Robin Berjon
|
||||
date: 2023-03-31
|
||||
permalink: '/2023-03-implementation-principles/'
|
||||
header_image: '/2023-03-implementations-flower.jpg'
|
||||
tags:
|
||||
- 'community'
|
||||
- 'ipfs thing'
|
||||
- 'event'
|
||||
---
|
||||
<style>
|
||||
.type-rich li + li {
|
||||
margin-top:0em;
|
||||
}
|
||||
.type-rich h3 {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.type-rich h4 {
|
||||
font-weight: bold;
|
||||
}
|
||||
.type-rich li > ul {
|
||||
padding-top:0;
|
||||
}
|
||||
table {
|
||||
background: #fff;
|
||||
}
|
||||
thead {
|
||||
background: #34797d;
|
||||
color: #fff;
|
||||
}
|
||||
td, th {
|
||||
text-align: left;
|
||||
padding: 0.25em 0.5em;
|
||||
vertical-align: top;
|
||||
}
|
||||
tbody tr:nth-of-type(even) {
|
||||
background: rgba(245, 246, 247, var(--tw-bg-opacity));
|
||||
}
|
||||
tbody tr td:first-of-type {
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
||||
If all you had ever seen were roses, daffodils, and violets, you would probably have a simplistic intuition of what a flower is. But as you discovered more examples of the bountiful world of flowering plants, including some more unusual varieties like the [Hydnora Africana](https://en.wikipedia.org/wiki/Hydnora_africana) sci-fi monsters, the absolutely massive [Corpse Flower](https://en.wikipedia.org/wiki/Amorphophallus_titanum), or perhaps more cutely the [Swaddled Babies](https://gardenofeaden.blogspot.com/2020/03/the-swaddled-babies-orchid-anguloa.html) or the laughing [Bee Orchids](https://www.thehallofeinar.com/2017/06/bee-orchids-with-no-bees-to-love-them/) then your idea of flower would have to grow, until at some point you might start wondering if you really know what counts as a flower.
|
||||
|
||||
In July 2022, a core group of architects, implementers, and committed builders in the IPFS community met in Reykjavik, Iceland for [IPFS þing](https://blog.ipfs.tech/ipfs-ping-2022-recap/), the first-ever gathering focused on growing and diversifying implementations of the IPFS protocol.
|
||||
|
||||
The event kicked off with [a call for more and different implementations](https://www.youtube.com/watch?v=xCGjxdMuKF0&list=PLuhRWgmPaHtQhyXIhu2P6e-8WlYOf8wyH&index=6) so as to make IPFS as usable and accessible as possible in today's multifaceted software environment, able to operate in a wide variety of verticals such as gaming, of languages such as Python, or of architectural constraints such as lite nodes and satellite connectivity. And in the nine months since, that's exactly what has happened: it's springtime in the distributed hemisphere and [we are frolicking across fields of tantalizing IPFS flowers](https://docs.ipfs.tech/concepts/ipfs-implementations/). With so much efflorescence, it's worth taking a step back from this [thriving broader ecosystem](https://ecosystem.ipfs.tech/) and looking at the principles that make IPFS what it is.
|
||||
|
||||
### Table of Contents
|
||||
- [What is IPFS?](#what-is-ipfs)
|
||||
- [IPFS Implementations Today](#ipfs-implementations-today)
|
||||
- [A Broader View](#a-broader-view)
|
||||
- [IPFS Principles](#ipfs-principles)
|
||||
- [Content Addressing](#content-addressing)
|
||||
- [Robustly Transport-Agnostic](#robustly-transport-agnostic)
|
||||
- [Clearer Foundations](#clearer-foundations)
|
||||
- [See You Soon!](#see-you-soon)
|
||||
- [Appendix: Implementations](#appendix-implementations)
|
||||
|
||||
## What is IPFS?
|
||||
|
||||
Quiz time! Which one of these is IPFS?
|
||||
|
||||
- ❓ Users linking to NFT assets over IPFS gateway URLs
|
||||
- ❓ Sharing an image from your phone to Web3.storage
|
||||
- ❓ Web publishing flow of static website from Github to Fleek
|
||||
- ❓ Two people chatting over over a Bluetooth connection using IPFS CID addressed data
|
||||
- ❓ Satellite beacon emitting IPFS CIDs of imagery it'll serve to an IPFS-connected ground station in that six minute window of (relatively) high bandwidth it gets a couple of times per day
|
||||
- ❓ XR headset loading scenes of static content by IPFS CID, content shipped on the hardware by the OEM
|
||||
- ❓ People reading Wikipedia from offline or censorship-resistant sources either due to poor connectivity or to [Internet restrictions](https://twitter.com/dietrich/status/1364978192075866115)
|
||||
|
||||
Answer: *All of the above!*
|
||||
|
||||
These ways of using IPFS are very different from one another — and that's a feature — but they all share two key characteristics:
|
||||
|
||||
1. Data is addressed by unique fingerprints generated from its contents
|
||||
2. Which allows data use to be transport-agnostic.
|
||||
|
||||
This might not feel like a very thorough definition, but it already tells us a lot about what is or isn't an IPFS implementation. Let's look at the lay of the land today, and explore what being an implementation actually means.
|
||||
|
||||
## IPFS Implementations Today
|
||||
|
||||
IPFS implementations vary widely, from OS-level daemons living long and fulfilling lives in data centers, to JavaScript executing in the transient twinkle of a browser tab's eye. They have to exist in the multitude of environments where users access IPFS today, and where developers need to deploy the programs that provide that access. Many of these environments are unforgiving and may explicitly constrain available capabilities to align with the host's requirements or business model, such as mobile operating systems or IoT devices.
|
||||
|
||||
When developers have maximal control of an environment, they can implement IPFS to match the ideal of the vision articulated in the [original white paper](https://ipfs.io/ipfs/QmR7GSQM93Cx5eAg6a6yRzNde1FQv7uL6X1o4k7zrJa3LX/ipfs.draft3.pdf). When the deployment environment is very far from being able to achieve that ideal, or when the use case at hand is too different, implementing IPFS often means reliably getting content-addressed data in or out of that system by whatever means necessary.
|
||||
|
||||
The diversity this demands can be seen in our implementation ecosystem. For instance, we have implementations in [Go](https://github.com/ipfs/kubo), in [Java](https://github.com/Peergos/nabu), and in [JavaScript](https://github.com/ipfs/helia), as well as [one in Rust](https://github.com/n0-computer/iroh) that optimizes for extreme efficiency. We have some targeting [clusters](https://ipfscluster.io/) or [Filecoin](https://github.com/filecoin-project/lotus), meant to work in [mobile](https://github.com/ipfs-shipyard/gomobile-ipfs) or in other [embedded environments](https://github.com/ipfs-rust/ipfs-embed) as well as [for the cloud](https://github.com/elastic-ipfs/elastic-ipfs). And [the list keeps growing](https://docs.ipfs.tech/concepts/ipfs-implementations/).
|
||||
|
||||
## A Broader View
|
||||
|
||||
Today's IPFS ecosystem is larger than most people realize, and most of us only work with a subset of it. This makes it easy to develop a restrictive intuition of what IPFS is.
|
||||
|
||||
For instance, it can be tempting to reach the conclusion that supporting IPFS means being interoperable with [Kubo](https://github.com/ipfs/kubo) or supporting everything that Kubo does. Kubo is, of course, an outstanding implementation but there are excellent reasons to make different decisions if you're targeting different contexts or optimizing for different goals. This is notably true when considering Filecoin: making the data stored by Filecoin storage providers accessible to other IPFS nodes can't just mean connecting Lotus to Kubo.
|
||||
|
||||
Many successful protocols support implementations that only do one thing well, without exercising the entire protocol's capabilities and perhaps even without being fully compliant. For instance, you could write an HTTP server that listens on port 80, throws away any method, path, or header information you send it, and always responds with a code [`418`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/418), `Content-Type` set to `image/jpeg`, and [a classic work of art](https://ipfs.io/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi) in the body. It might not be a fully compliant implementation of HTTP, it's arguably not a very useful implementation of HTTP, but it's still an implementation of HTTP. And there are millions of HTTP servers that don't support everything in the HTTP suite of standards but that nevertheless provide services that are far more valuable than our little thought experiment. The important part is that they can be used to resolve `http` URLs with authority.
|
||||
|
||||
This is a very useful pattern that IPFS supports as well. To give a quick and very dirty example (since that's the point), this [crude 24 line script](https://gist.github.com/darobin/9c9984586dcb133f384d3fd05f3a0bb9) can expose a Git repository as an IPFS gateway simply by making all of its objects accessible via CIDs that prefix the SHA1 hashes with `f017c1114`. Such a script could be used, for instance, to integrate a git repository into an IPFS-based archival system. This is a far cry from being an elegant implementation, and bridging Git to IPFS warrants a cleaner approach, but the point remains that glueing systems into IPFS with a minimalistic approach is no less legitimate a deployment of IPFS than a Swiss Army Knife IPFS library.
|
||||
|
||||
We should also keep in mind that many systems across the IPFS network do peer discovery and content routing outside the public DHT. This includes gateways of course, but also mDNS discovery, Gossipsub peer exchange, pinning service clusters, or wholly separate DHTs. An inclusive — but principled — view of what IPFS includes makes the ecosystem richer and more valuable for all of us.
|
||||
|
||||

|
||||
|
||||
## IPFS Principles
|
||||
|
||||
There are many ways to implement and to use IPFS, and the perspective above barely scratches the surface. But we have to be careful not to be over-inclusive: if almost anything counts as being part of IPFS, what we have isn't an ecosystem but just a bag of unrelated stuff. We need concrete principles that define the ways in which a piece of software meaningfully participates in IPFS.
|
||||
|
||||
These principles provide detail to the key characteristics which we listed at the beginning:
|
||||
|
||||
1. Data is addressed by its contents
|
||||
2. Which allows data use to be transport-agnostic.
|
||||
|
||||
### Content Addressing
|
||||
|
||||
Addressing is such an elementary part of any communication protocol that it is easy to overlook how its properties define the properties of a protocol. IP addresses are assigned based on a hierarchical authority delegated by [IANA](https://www.iana.org/) and [RIRs](https://en.wikipedia.org/wiki/Regional_Internet_registry) to network administrators for local assignment. HTTP builds atop `http` URLs, which are predicated on the domain name system delegating authority to a server, and then that server's operator having full ownership of the names in that space and of the resources they map to. This idea of hierarchy and ownership is deeply ingrained in the web's fundamental architecture documents and it has consequences for how the web works: not only is everyone dependent on DNS, but when visiting a URL you are interacting with a name and a resource that are explicitly defined as someone else's property. In turn, this gives that entity power in the relationship it has with its users.
|
||||
|
||||
IPFS's first defining characteristic is content addressing, and this is reflected in the foundational role that it gives to [CIDs](https://github.com/multiformats/cid). IPFS is, at heart, the space of resources that can be interacted with using a CID.
|
||||
|
||||
This already has multiple consequences. To begin with, CIDs are defined using [multiformats](https://multiformats.io/), which makes them future-proof, self-describing, and extensible. If, for instance, a powerful new hash algorithm surfaces then we aren't either stuck in the past or forced to find a way to upgrade everything. We can progressively roll it out on the IPFS network. Endpoints that need to produce or consume it will need to be upgraded, but the rest of the network won't care.
|
||||
|
||||
This approach also means that IPFS can interoperate with existing content-addressed systems, usually with little more work that what is required to convey whatever hash they use to a CID.
|
||||
|
||||
CIDs form a powerful and load-bearing foundation, while nevertheless being quite simple: Juan's original [CID](https://github.com/multiformats/cid#how-does-it-work) spec is detailed enough for implementation but barely runs to half a page of Markdown, including an enthusiastic parting comment about its simplicity: "*That's it!*"
|
||||
|
||||

|
||||
|
||||
By founding IPFS on CIDs we are paving the way to a [self-certifying web](https://jaygraber.medium.com/web3-is-self-certifying-9dad77fd8d81) that shifts power to people. No need to delegate authority or to give ownership over a location: the CID is a direct relationship between endpoints, between a person and the content that the CID points to. (And [IPLD](https://ipld.io/), which is also distinguished for its systematic reliance on CIDs as links, brings similar benefits to data.)
|
||||
|
||||
And content-addressing is key to enabling the other foundational characteristic, which we turn to next.
|
||||
|
||||
### Robustly Transport-Agnostic
|
||||
|
||||
Addressing content is nice, but it's often more useful if you can also use it to retrieve, move, compute over, or otherwise manipulate some data. Because IPFS is built on CIDs (self-certifying, remember?), we're free to use any transport layer without introducing concerns about the integrity of the content.
|
||||
|
||||
This transport-agnosticity makes the entire network more adaptable to local or specific needs, and it enables experimentation with a wide range of properties about how bytes are located and moved around. It future-proofs the system and makes it nimble when it has to be supported in new places, under new constraints. Developers don't even need to worry about building local- or offline-first: IPFS is both, *always*.
|
||||
|
||||
In taking this aproach, IPFS is revisiting and refreshing two older principles of protocol design. The first is the robustness principle, which has been expressed in different ways over the years but can be summarized as "*Be strict when sending and tolerant when receiving.*" While that formulation of the robustness principle has generally been accepted as unchallenged wisdom, it has recently [come under criticism in the protocol design community](https://datatracker.ietf.org/doc/html/draft-iab-protocol-maintenance). When a protocol is deployed at a large scale over many years and its implementations err on the side of being tolerant, what actually tends to happen is that interoperability defects accumulate over time until new implementations become too difficult to produce and the protocol starts to decay.
|
||||
|
||||
While we want to avoid protocol decay, some degree of tolerance is nevertheless desirable as it contributes to making the system adaptable to new situations. To address this, instead of being strict in one direction and tolerant in the other, IPFS is strict at the endpoints — where CIDs are produced or verified — and tolerant in between, open to any way that will get the bytes across.
|
||||
|
||||
This new take on robustness, which we might formulate as "*Be strict about the outcomes, be tolerant about the methods*," is an implementation of the [end-to-end principle](https://en.wikipedia.org/wiki/End-to-end_principle). The end-to-end principle states that the reliability properties of a protocol have to be supported at its endpoints and not in intermediary nodes. And that's exactly what CIDs enable.
|
||||
|
||||
## Clearer Foundations
|
||||
|
||||
Put together, content-addressing using CIDs and robust transport-agnosticity are what make IPFS what it is. An IPFS implementation that doesn't build atop the excellent [libp2p](https://libp2p.io/), that doesn't do everything that Kubo does, or that only retrieves verifiable content via HTTP gateways is still an IPFS implementation.
|
||||
|
||||
In order to help clarify both this foundation and everything that sits on top of it we've progressively been [developing better specs](https://github.com/ipfs/specs/), including a [fresh evolution of the IPIP process](https://github.com/ipfs/specs/commits/main/IPIP_PROCESS.md) and a [brand new specs site](https://specs.ipfs.tech/) (and [a IPFS Thing 2023 track to go with](https://2023.ipfs-thing.io/#Standards-Governance-and-DWeb-Policy)!)
|
||||
|
||||
Part of that specification work is this proposal for [a standardized description of the principles that define IPFS](https://specs.ipfs.tech/architecture/principles/). If you are curious to read a more detailed description of the principles described in this post, I encourage you to read it.
|
||||
|
||||
## See You Soon!
|
||||
|
||||
These are exciting times: solidifying our foundations empowers us to build higher and better. The [next IPFS Thing](https://2023.ipfs-thing.io/) is just a few weeks away, April 15th-19th, in Brussels. As a community, we'll be using that opportunity to share, discuss, and blaze forward with many new IPFS capabilities and implementations. We have no doubt that, from these CIDs, many flowers will grow.
|
||||
|
||||
## Appendix: Implementations
|
||||
|
||||
The [table of implementations at docs.ipfs.tech](https://docs.ipfs.tech/concepts/ipfs-implementations/) is the one being actively maintained and you should refer to that one if you are looking for a definitive source as the ecosystem changes fast. However, for illustrative purposes, here is the list of implementations (not counting all manners of tooling and other systems) as this blog post goes to press.
|
||||
|
||||
| Name | Language | What it's trying to do |
|
||||
| -------- | -------- | -------- |
|
||||
| [Elastic provider](https://github.com/ipfs-elastic-provider/ipfs-elastic-provider) | javascript, typescript | Scalable cloud-native implementation. |
|
||||
| [Estuary](https://github.com/application-research/estuary/) | go | Daemon oriented service to pin and onboard IPFS data into Filecoin. |
|
||||
| [Kubo](https://github.com/ipfs/kubo) | go | Generalist daemon oriented IPFS implementation with an [extensive HTTP RPC API](https://docs.ipfs.tech/reference/kubo/rpc/) and [HTTP Gateway API](https://docs.ipfs.tech/reference/http/gateway/). |
|
||||
| [ipfs cluster](https://ipfscluster.io/) | go | Orchestration for multiple Kubo nodes via CRDT / Raft consensus |
|
||||
| [iroh](https://github.com/n0-computer/iroh) | rust | Extreme-efficiency oriented IPFS implementation. |
|
||||
| [Lotus](https://github.com/filecoin-project/lotus) | go | Filecoin node handling consensus, storage providing, making storage deals, importing data, ... |
|
||||
| [Nabu](https://github.com/Peergos/nabu) | java | A minimal Java implementation of IPFS |
|
||||
| [auspinner](https://github.com/2color/auspinner) | go | CLI tool to deal with the pinning service API and upload files through bitswap. |
|
||||
| [barge](https://github.com/application-research/barge) | go | CLI tool with a git like workflow to upload deltas to estuary. |
|
||||
| [Boost](https://github.com/filecoin-project/boost) | go | Daemon to get IPFS data in and out of a Filecoin storage provider. |
|
||||
| [gomobile-ipfs](https://github.com/ipfs-shipyard/gomobile-ipfs) | go | Library oriented ipfs daemon to help embeding Kubo into a mobile app. |
|
||||
| [helia](https://github.com/ipfs/helia) | javascript | A lean, modular, and modern implementation of IPFS for the prolific JS and browser environments, currently pre-alpha but [intended to replace js-ipfs](https://github.com/ipfs/js-ipfs/issues/4336). |
|
||||
| [ipfs-embed](https://github.com/ipfs-rust/ipfs-embed) | rust | Small embeddable ipfs implementation. |
|
||||
| [ipfs-lite](https://github.com/hsanjuan/ipfs-lite) | go | Minimal library oriented ipfs daemon building on the same blocks as Kubo but with a minimal glue layer. |
|
||||
| [ipfs-nucleus](https://github.com/peergos/ipfs-nucleus/) | go | Minimal IPFS replacement for P2P IPLD apps. |
|
||||
| [js-ipfs](https://github.com/ipfs/js-ipfs) | javascript, typescript | Javascript implementation targeting nodejs and browsers. [Development of js-ipfs is being discontinued](https://github.com/ipfs/js-ipfs/issues/4336). |
|
||||
| [bifrost-gateway](https://github.com/ipfs/bifrost-gateway) | go | A lightweight [HTTP+Web Gateway](https://specs.ipfs.tech/http-gateways/) daemon backed by a remote data store. [Verifies CIDs](https://docs.ipfs.tech/reference/http/gateway/#trustless-verifiable-retrieval) and enables trusted (local) use of untrusted (remote) gateways. |
|
||||
118
src/_blog/2023-05-ipfs-unresponsive-nodes-incident.md
Normal file
118
src/_blog/2023-05-ipfs-unresponsive-nodes-incident.md
Normal file
@@ -0,0 +1,118 @@
|
||||
---
|
||||
title: What happens when half of the network is down?
|
||||
description: "The IPFS DHT experienced a serious incident in the beginning of 2023, but users hardly noticed thanks to the power of a decentralized network!"
|
||||
author: Yiannis Psaras
|
||||
date: 2023-05-08
|
||||
permalink: '/2023-ipfs-unresponsive-nodes/'
|
||||
header_image: '/2023-05-ipfs-unresponsive-nodes-incident.jpeg'
|
||||
tags:
|
||||
- 'dht'
|
||||
- 'decentralization'
|
||||
- 'resource manager'
|
||||
- 'nodes'
|
||||
---
|
||||
|
||||
It depends on what type of system/network you’re running. In 90% of networks, or networked systems, this is a grand-scale disaster. Alerts are popping up everywhere, engineers go far beyond “day-time work” to get things back to normal, customers are panicking and potentially leaving the platform and the customer care lines are on fire. Half of the network is a large fraction, but I would bet that the same would happen even when 10% or 20% of the network experiences an outage.
|
||||
|
||||
It’s not like that when you run your services on a decentralized, distributed P2P network, such as IPFS! At the beginning of 2023, a critical component of the IPFS network, namely the public IPFS DHT, experienced a large-scale incident. *During this incident, [60% of the IPFS DHT Server nodes became unresponsive](https://github.com/protocol/network-measurements/blob/master/reports/2023/calendar-week-04/ipfs/plots/crawl-unresponsive.png).* Interestingly, **no content became unreachable and almost nothing in the network looked like the majority of the network was basically down**. We did observe a significant increase in the content routing/resolution latency (in the order of 25% initially), but this in no way reflected the scale of the event.
|
||||
|
||||
In this blog post, we’ll go through the timeline of the event from “Detection” to “Root Cause Analysis” and give details about the engineering team’s response. A summarizing talk on the content of this blog post was given at [IPFS Thing 2023](https://2023.ipfs-thing.io/) and can be found [on YouTube](https://youtu.be/8cGEjdCfm14).
|
||||
|
||||
## ❗️Detection: we've got a problem!
|
||||
|
||||
> At the beginning of 2023, a critical component of the IPFS network, namely the public IPFS DHT, experienced a large-scale malfunction. *During this situation, [60% of the IPFS DHT Server nodes became unresponsive](https://github.com/protocol/network-measurements/blob/master/reports/2023/calendar-week-04/ipfs/plots/crawl-unresponsive.png).*
|
||||
>
|
||||
|
||||
Unresponsive here means that nodes would seem to be online, they would accept connections from other nodes, but they wouldn’t reply to requests. Basically, when a node would try to write to one of the unresponsive nodes, the unresponsive node would terminate the connection immediately.
|
||||
|
||||
Given that these nodes seemed to be functional, they occupied several places in other nodes’ routing tables, when in fact they shouldn’t have.
|
||||
|
||||
The problem came down to a misconfiguration of the go-libp2p resource manager - a new feature that shipped with `kubo-v0.17`. The problematic configuration which was applied manually (i.e. was not based on the default values of `kubo-v0.17`) was set to such values that any attempt to interact with the nodes would be flagged as a resource exhaustion event and would trigger the corresponding “defense” mechanism. In practice, this materialized as a connection tear-down. It is worth noting that `kubo` is the most prevalent IPFS implementation using the public IPFS DHT with ~80% of nodes in the DHT being `kubo` nodes (see most recent [stats](https://github.com/protocol/network-measurements/tree/master/reports/2023/calendar-week-17/ipfs#agent-version-analysis)).
|
||||
|
||||
Content was still findable through kubo, so no alarms were raised. However, some of our research teams observed unusual error messages:
|
||||
|
||||
```go
|
||||
> Application error 0x0 (remote): conn-22188077: system: cannot reserve inbound
|
||||
connection: resource limit exceeded
|
||||
```
|
||||
|
||||
Since PUT and GET operations were completing successfully, the error didn’t seem like one that would trigger widespread panic. We were seeing slower performance than normal and had been investigating whether [recent changes with Hydra boosters](https://discuss.ipfs.tech/t/dht-hydra-peers-dialling-down-non-bridging-functionality-on-2022-12-01/15567) had bigger impacts than we were expecting. It was at this time that we had a physical meeting of our engineering teams and one of the items on the agenda was to figure out where this error was coming from.
|
||||
|
||||
## ❓ Diagnosis: what was happening?
|
||||
|
||||
We quickly realized that [there was a resource manager issue where the remote node was hitting a limit and closing the connection](https://github.com/libp2p/go-libp2p/issues/1928). After looking into the details of the resource manager and the error itself (i.e., `cannot reserve **in**bound connection`), we realized that the root cause of the issue was related to the remote node. It turned out that the resource manager was manually misconfigured by a very large percentage of nodes to values that were not in the default configuration by the “vanilla” version of the resource manager that shipped with `kubo-v0.17`.
|
||||
|
||||
As mentioned earlier, the GET and PUT operations were completing successfully, so our next step was to identify the scale of the problem. Our main goals were to figure out:
|
||||
|
||||
- what percentage of nodes in the network were affected
|
||||
- if there was a performance penalty in either the PUT or the GET operation, or both
|
||||
|
||||
Through a combination of crawling the network and attempting connections to all ~50k DHT Server nodes (i.e., those that store and serve provider records and content), we found that close to 60% of the network had been affected by the misconfiguration. Clearly this was a very large percentage of the network, which made it urgent to look into the performance impact. We followed the below methodology:
|
||||
|
||||
1. We wanted to figure out which buckets in the nodes’ routing tables did the affected nodes occupy. We found that they occupied the higher buckets of the nodes’ routing tables, which meant that most likely PUTs would get slower, but GETs should not be affected too much. This is because the DHT lookup from the GET operation terminates when it hits *one* of the 20 closest peers to the target key, while the PUT operation terminates when it has found *all* the 20 closest peers. Since a significant portion of the network was unresponsive, the PUT operation hit at least one unresponsive node, but the GET operation had good chances of finding at least one responsive node within the 20 closest.
|
||||
|
||||

|
||||
<br>
|
||||
2. After further investigation and given the very large percentage of nodes that were affected by the resource manager misconfiguration, we started looking into the impact of the incident to the GET performance.
|
||||
|
||||
A GET request that hits one of the affected, unresponsive nodes would get the connection shut down by the remote, but would get stuck there until it timed out, at which point it would re-issue the request to another peer. The relatively high concurrency factor of the IPFS DHT (`alpha = 10`) helps in this case, as it means that for any given request up to 10 concurrent requests can be in flight. This helps a lot even with a high percentage of unresponsive nodes as it means that at least one of the 10 peers contacted will respond.
|
||||
<br>
|
||||
> This is because the DHT lookup from the GET operation terminates when it hits one of the 20 closest peers to the target key, when the PUT operation terminates when it has found all the 20 closest peers.
|
||||
>
|
||||
|
||||
|
||||
<br>In the meantime, we estimated that a non negligible number of GET requests were hitting at least one unresponsive node during the lookup process. This event results in a timeout and significantly increases the request latency. There is a high probability that an unresponsive node is encountered during the last hops of the DHT walk because unresponsive peers are mostly present in higher buckets as the above figure shows.
|
||||
<br>
|
||||
3. To quantify the impact, we crawled the network and gathered the PeerIDs of unresponsive nodes. We set up six kubo nodes in several locations around the globe and attempted to: i) publish content (PUT), and, ii) retrieve content (GET) for two cases: 1) when interacting with all nodes in the network, and, 2) when ignoring all responses from the unresponsive peers, whose PeerIDs we knew and were cross-checking with in real time.
|
||||
|
||||
- The results we found were as follows:
|
||||
- The PUT operation was slowed down by approximately 10%
|
||||
<br>
|
||||

|
||||
<br>
|
||||
- The GET operation was also disrupted (in contrast to our initial assumption) and was slowed down by approximately 15%, at times reaching closer to 20%.
|
||||
<br>
|
||||

|
||||
<br>
|
||||
4. We also experimented with even higher concurrency factors, in particular with `alpha = 20`, as a potential mitigation strategy. We repeated the same experiment with one extra set of runs: the case where we interact with all nodes in the network (i.e., we do not ignore unresponsive peers), but have higher concurrency factor.
|
||||
|
||||
<br>We found that the performance increased and went back to pre-incident levels. However, it was decided *not* to go down this path, as the increased concurrency factor would: i) increase significantly the overhead/traffic in the DHT network, and, ii) stick with nodes that do not upgrade later on (when the incident is resolved) giving a clear advantage advantage to those nodes.
|
||||
|
||||
|
||||
## 🚑 Mitigation: how we stopped the bleeding.
|
||||
|
||||
The team’s immediate focus became:
|
||||
|
||||
1. [Adding/updating documentation on Kubo’s resource manager integration](https://github.com/ipfs/kubo/blob/master/docs/libp2p-resource-management.md)
|
||||
2. Triaging and responding to user questions/issues ([example](https://github.com/ipfs/kubo/issues/9432))
|
||||
3. Preparing a new kubo release (`v0.18.1`), where the default settings for the resource manager were set to more appropriate values. This reduced the likelihood that someone would need to adjust the resource manager configuration manually, thus avoiding the configuration “footguns”.
|
||||
4. Encouraging as many nodes as possible to upgrade through public forums and direct relationships with known larger scale operators.
|
||||
|
||||
In parallel, we kept monitoring the situation by instrumenting a PUT and GET measurement experiment that was running since before the `kubo-v0.18.1` update, when the affected nodes started updating gradually.
|
||||
|
||||
`kubo-v0.18.1` was [released on the 2023-01-30](https://github.com/ipfs/kubo/releases/tag/v0.18.1) and within the first 10 days, more than 8.5k nodes updated to this release. Our monitoring software allowed us to have an accurate view of the state of the network and observed that the update to the new kubo release brought significant performance increase for the GET operation - more than 40% at the 95th percentile on a sample of ~2k requests, compared to the situation before the `kubo-v0.18.1` release.
|
||||
|
||||

|
||||
|
||||
We also monitored the situation compared to the pre-incident performance by running the experiment where we ignored the set of PeerIDs that were identified as affected by the misconfiguration. As a sample from more than 20k GET operations, in the figure below we show that the impact has reduced to ~5% (mid-February 2023).
|
||||
|
||||

|
||||
|
||||
## 🔧 Addressing the Root Cause
|
||||
|
||||
Our immediate actions managed to stop the bleeding and bring the network back to normal quickly. However, it was clear that we had to implement longer term fixes to protect the nodes’ routing tables from unresponsive peers and to avoid inadvertently making nodes unresponsive. Specifically this translated to:
|
||||
|
||||
1. Revamping the Kubo resource manager UX to further reduce the likelihood of catastrophic misconfiguration. This was completed in [Kubo 0.19](https://github.com/ipfs/kubo/releases/tag/v0.19.0#improving-the-libp2p-resource-management-integration).
|
||||
2. Only adding peers to the routing table that are responsive requests [during the routing table refresh](https://github.com/libp2p/go-libp2p-kad-dht/pull/810) (done) and [upon adding a node to the routing table](https://github.com/libp2p/go-libp2p-kad-dht/issues/811) (in progress - targeting [Kubo 0.21 in May](https://github.com/ipfs/kubo/issues/9814)).
|
||||
|
||||
## 📖 Lessons Learned
|
||||
|
||||
In the days since, we have come away from this experience with several important learnings:
|
||||
|
||||
🗒️ Significant fundamental changes to the codebase (such as retroactively adding resource accounting) is ripe for disruption. This increases the necessity for documentation, announcements, and clear recommendations to node operators.
|
||||
|
||||
⏱️ Monitoring software should always be in place to help identify such events from the start.
|
||||
|
||||
📣 It is challenging to monitor and apply changes directly to the software that runs on nodes of a decentralized network. Well-established communication channels go a long way and help the engineering teams communicate directly with the community. In IPFS, we use a variety of channels including the Discord Server [[invite link](https://discord.gg/ipfs)], Filecoin Slack [[invite link](https://filecoin.io/slack)] (mostly in `#engres-ip-stewards` channel), the [Discourse discussion forum](https://discuss.ipfs.tech/), and the [blog](https://blog.ipfs.tech/).
|
||||
|
||||
🚀 Last, but certainly not least, the decentralized, P2P nature of IPFS kept the network running with all important operations completing successfully (albeit slower than normal). It is exactly because of the structure of the network that there are no single points of failure and performance is not catastrophically disrupted even when more than half of the network nodes are essentially unresponsive.
|
||||
25
src/_blog/2023-05-js-ipfs-deprecation-for-helia.md
Normal file
25
src/_blog/2023-05-js-ipfs-deprecation-for-helia.md
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: ⛔️ js-IPFS deprecation / replaced by Helia 🌞
|
||||
description: 'js-IPFS is being deprecated, and has been superseded by Helia.'
|
||||
author: Alex Potsides (@achingbrain)
|
||||
date: 2023-05-26
|
||||
permalink: '/202305-js-ipfs-deprecation-for-helia/'
|
||||
header_image: '/2023-05-js-ipfs-deprecation-for-helia-header-image.png'
|
||||
tags:
|
||||
- 'helia'
|
||||
- 'js-ipfs'
|
||||
---
|
||||
|
||||
**TL;DR: [js-IPFS](https://github.com/ipfs/js-ipfs) is being deprecated, and has been superseded by [Helia](https://github.com/ipfs/helia).**
|
||||
|
||||
There are exciting times ahead for IPFS in JS. Some of you may have already heard of [Helia](https://github.com/ipfs/helia), the new implementation that's designed as a composable, lightweight, and modern replacement for js-IPFS.
|
||||
|
||||
It has a [simplified API](https://ipfs.github.io/helia/interfaces/_helia_interface.Helia.html) which can be extended by other modules depending on the requirements of your application such as [@helia/unixfs](https://github.com/ipfs/helia-unixfs), [@helia/ipns](https://github.com/ipfs/helia-ipns), [@helia/dag-cbor](https://github.com/ipfs/helia-dag-cbor) and [others](https://github.com/ipfs/helia#-code-structure).
|
||||
|
||||
It ships with the latest and greatest libp2p, which means it has the best connectivity options, including the new [WebTransport](https://github.com/libp2p/js-libp2p-webtransport) and [WebRTC](https://github.com/libp2p/js-libp2p-webrtc) transports that dramatically improve the connectivity options for browser environments.
|
||||
|
||||
[js-IPFS is in the process of being deprecated](https://github.com/ipfs/js-ipfs/issues/4336) so you should port your apps to Helia to receive bug fixes, features, and performance improvements moving forwards.
|
||||
|
||||
📚 [Learn more about this deprecation](https://github.com/ipfs/js-ipfs/issues/4336) or [how to migrate](https://github.com/ipfs/helia/wiki/Migrating-from-js-IPFS).
|
||||
|
||||
More new blog content discussing Helia coming soon!
|
||||
193
src/_blog/2023-05-multi-gateway-browser-client.md
Normal file
193
src/_blog/2023-05-multi-gateway-browser-client.md
Normal file
@@ -0,0 +1,193 @@
|
||||
---
|
||||
title: IPFS Multi-Gateway Experiment in Chromium
|
||||
description: A new approach to implementing ipfs:// and ipns:// support natively in the browser, using a client-only approach and fetching verifiable responses from multiple HTTP gateways.
|
||||
author: John Turpish
|
||||
date: 2023-06-01
|
||||
permalink: "/2023-05-multigateway-chromium-client/"
|
||||
translationKey: 2023-05-multigateway-chromium-client
|
||||
header_image: "/multi-gateway-experiment.png"
|
||||
tags:
|
||||
- browsers
|
||||
- chromium
|
||||
|
||||
---
|
||||
|
||||
[IPFS](https://ipfs.tech) is a protocol suite for a [content-addressed networking](https://en.wikipedia.org/wiki/Content-addressable_network). If you'd like to run a [node](https://docs.ipfs.tech/concepts/glossary/#node) and participate in the peer-to-peer network, by all means [give it a try](https://ipfs.tech/#install)!
|
||||
|
||||
The most important thing to get: With IPFS you can fetch something by a Content ID ([CID](https://docs.ipfs.tech/concepts/glossary/#cid)), which represents what it is, not where it's coming from.
|
||||
|
||||
The other way of fetching things from the IPFS ecosystem is through [IPNS](https://docs.ipfs.tech/concepts/ipns/#mutability-in-ipfs), which allows someone to cryptographically sign a reference to a CID, then you can request whatever content that person/organization is currently pointing to as their site.
|
||||
|
||||
Essentially, `http://` specifies "where" to find it, `ipfs://` specifies "what" to find, and `ipns://` specifies "whose" content to find.
|
||||
|
||||
What about people who don't know about IPFS, and just run across a [link](https://docs.ipfs.tech/concepts/glossary/#link)? What if they'd like to be able to use that link in their browser? This is where a "client" fits in - software that can talk to nodes to fetch the content they want, but without running one yourself.
|
||||
|
||||
## What is this all about?
|
||||
|
||||
Most IPFS clients talk to a particular HTTP [gateway](https://docs.ipfs.tech/concepts/glossary/#gateway). Multi-Gateway Clients proposed in [IPIP-359](https://github.com/ipfs/specs/pull/359) fulfill your requests using multiple [Trustless Gateways](https://specs.ipfs.tech/http-gateways/trustless-gateway/). This gives you more resilience, as you're not dependent on a single HTTP endpoint that can be censored or blocked by your ISP. It also can result in better performance, as you can multiplex requests that would typically run through a single server.
|
||||
|
||||
Here we're talking about [a project to implement IPFS in Chromium](https://github.com/little-bear-labs/ipfs-chromium). The result is an experimental racing multi-gateway client built directly into the browser, which means the same request might get sent to multiple Trustless Gateways, and the first one to get the result verified wins. And it's built into a custom-patched build of Chromium.
|
||||
|
||||
## Why build this?
|
||||
|
||||
This is by no means the first time IPFS has been usable in a browser, or even Chromium-based browsers in particular. Javier Fernández at Igalia has written some good explanations of other approaches that have been taken over at his blog in his post *[Discovering Chrome’s pre-defined Custom Handlers](https://blogs.igalia.com/jfernandez/2022/11/14/discovering-chromes-pre-defined-custom-handlers/)*, and there's an [overview on the IPFS blog](https://blog.ipfs.tech/14-11-2022-igalia-chromium/) as well.
|
||||
|
||||
Most of these approaches share in common the idea of translating IPFS and [IPNS](https://docs.ipfs.tech/concepts/glossary/#ipns) requests, 1:1, into HTTP requests. For example, if you have an HTTP gateway running locally on your machine, something like:
|
||||
|
||||
> ipfs://bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4
|
||||
|
||||
might become:
|
||||
|
||||
> http://localhost:8080/ipfs/bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4/
|
||||
|
||||
Or maybe it could become
|
||||
|
||||
>[https://ipfs.io/ipfs/bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4/](https://ipfs.io/ipfs/bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4/)
|
||||
|
||||
Or preferably (when [Origin isolation](https://en.wikipedia.org/wiki/Same-origin_policy) matters):
|
||||
|
||||
>[https://bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4.ipfs.dweb.link/](https://bafybeihpy2n6vwt2jjq5gusv23ajtilzbao3ekfb2hiev2xvuxscdxqcp4.ipfs.dweb.link/)
|
||||
|
||||
In each case, you're delegating all the "IPFS stuff", including CID (hash) verification, to a particular node. This is effective for completing requests, but has some trade-offs, including the privacy and integrity risks when using a remote gateway provided by a third-party.
|
||||
|
||||
### Performance
|
||||
|
||||
If the gateway you're using happens to have the data you're seeking already on-hand, your performance will be great, since it can simply return to you what it already has. Perforance might even be better than the multi-gateway client, since no extraneous requests would be made. However, if you were unlucky, that gateway will have to spend more time querying the IPFS network to try to find the data you request before it gives up. The ideal gateway to use may very well depend on what you happen to be doing at the moment - and may differ from one of your tabs to another. A multi-gateway client will have the worst case performance more rarely.
|
||||
|
||||
And while we've been talking about "files" for the most part, IPFS breaks larger files down into "blocks". So you can apply these same techniques at the block level, and it's also conceivable that for a sufficiently large file which exists on multiple gateways you're talking to, a verifying multi-gateway client might be able to be faster than a single-gateway client, since you might be pulling down parts of the file from different sources concurrently. [RAPIDE](https://github.com/ipfs/go-libipfs-rapide/issues/12) is a more advanced in-development client which also makes use of this principle (along with other things). And it's showing promising results - watch a [recent talk from IPFS Thing by Jorropo](https://www.youtube.com/watch?v=Cv01ePa0G58) on it!
|
||||
|
||||
### Installation (vs. local gateway)
|
||||
|
||||
If you're reading this, installing a local node might seem like no big deal to you. However, we want IPFS to be accessible to people who haven't heard of it, and make it easy for them to click a link without having to think about which protocol-handling software they have installed ahead of time.
|
||||
|
||||
One approach is to have the browser install and start its own IPFS node. This is a pretty reasonable approach, but it can raise questions about when to dedicate resources to installation or the node's [daemon](https://docs.ipfs.tech/concepts/glossary/#daemon). The most notable example of this approach is [Brave](https://brave.com/ipfs-support/).
|
||||
|
||||

|
||||
|
||||
However, regardless of whether the browser manages a [Kubo](https://github.com/ipfs/kubo#readme) node as Brave does or implements IPFS natively, the architecture of the application has changed in a significant way - *from being strictly a client, to being a server*.
|
||||
|
||||
Including HTTP-client-only IPFS capabilities in a Chromium-based browser doesn't change the installation experience in a noticeable way, nor require any major rethink of the browser security model.
|
||||
|
||||
### Security (vs. single public gateway)
|
||||
|
||||
Content-addressed networking involves a validation step to make sure that the data you received matches the [hash](https://docs.ipfs.tech/concepts/glossary/#hash) requested (it's a part of the CID). When you're requesting a file from an HTTP gateway, by default, the verification of the content is delegated to the node running the gateway. Further, if you receive the file in its final deserialized form as a response to a single request, naively using just an HTTP client, it's no longer possible to verify locally.
|
||||
|
||||
This is probably fine if the gateway you're talking to is one you're running locally. Presumably you trust that software as much as you trust your own browser.
|
||||
|
||||
The public IPFS gateways today appear to be consistently and reliably returning the correct results. Nonetheless the possibility exists, and it would be preferable if we didn't have to trust. That's why this experimental Chromium implementation uses the [Trustless Gateway](https://specs.ipfs.tech/http-gateways/trustless-gateway/) API and verifies the retrieved content locally.
|
||||
|
||||
## Where is the code?
|
||||
|
||||
In the repo you'll see separation between [component](https://github.com/little-bear-labs/ipfs-chromium/tree/main/component) and [library](https://github.com/little-bear-labs/ipfs-chromium/tree/main/library), where the former contains Chromium-specific code, and the latter contains code that helps with IPFS implementation details that can build without Chromium.
|
||||
|
||||
This distinction disappears when you switch over to the Chromium build. Both sets of source are dumped into a component (basically a submodule) called `ipfs`, that implements the handling of `ipfs://` and `ipns://` URLs.
|
||||
|
||||
Those who embed Chromium into another application generally provide an implementation of a couple of interfaces, namely `ContentClient` and `ContentBrowserClient`. They would need to add a little code to their implementations to use the `ipfs` component. Our repo contains a patch file which alters Chrome's implementations of these two as a demonstration to show how usage might work. That patch file might be useful as-is to someone who uses a patching approach to make a Chromium-derived browser.
|
||||
|
||||
## How (in more detail)?
|
||||
|
||||
### Hooking into Chromium
|
||||
|
||||
* The `ipfs://` and `ipns://` schemes are registered in [`ContentClient::AddAdditionalSchemes`](https://source.chromium.org/chromium/chromium/src/+/main:content/public/common/content_client.h;l=156?q=AddAdditionalSchemes), so the origin will be handled properly.
|
||||
* An interceptor is created in [`ContentBrowserClient::WillCreateURLLoaderRequestInterceptors`](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/content_browser_client.h;l=1733?q=WillCreateURLLoaderRequestInterceptors), which just checks the scheme, so `ipfs://` and `ipns://` navigation requests will be handled by `components/ipfs`.
|
||||
* URL loader factories created for `ipfs` and `ipns` schemes in [`ContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories`](https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/content_browser_client.h;l=1503?q=RegisterNonNetworkSubresourceURLLoaderFactories), so in-page resources with `ipfs://` / `ipns://` URLs (or relative URLs on a page loaded as `ipfs://`), will also be handled by `components/ipfs`.
|
||||
|
||||
### Issuing HTTP(S) requests to Trustless Gateways
|
||||
|
||||
The detailed steps of the algorithm are laid out in [the design doc](https://github.com/little-bear-labs/ipfs-chromium/blob/main/DESIGN.md), but here's the basic idea:
|
||||
|
||||
* An IPFS link will have a CID in the URL. This is the [root](https://docs.ipfs.tech/concepts/glossary/#root) of its [DAG](https://en.wikipedia.org/wiki/Merkle_tree), which contains directly or indirectly all the info needed to get all the files related to the site, and will be the first [block](https://docs.ipfs.tech/concepts/glossary/#block) needed to access the file/resource.
|
||||
* For any given block that is known to be needed, but not present in-memory, send requests to several gateways which haven't responded with an error for this CID yet and don't currently have pending requests to them. These requests have `?format=raw` so that we'll get just the one block (with `Content-Type` [application/vnd.ipld.raw](https://www.iana.org/assignments/media-types/application/vnd.ipld.raw)), not the whole file.
|
||||
* When a response comes from a gateway, hash it according to the algo specified in the CID's [multihash](https://docs.ipfs.tech/concepts/glossary/#multihash). Right now, that has to be sha-256, and luckily it generally is. If the hashes don't match, the gateway's response gets treated much like an error - the gateway gets reduced in priority, and a new request goes out to a gateway that hasn't yet received this request.
|
||||
* If the hashes are equal, store the block, process the block as described in Codecs (below). If the new node includes links to more blocks we also need, send requests for those blocks.
|
||||
* When the browser has all the blocks needed, piece together the full file/resource and create an HTTP response and return it, as if it had been a single HTTP request all along.
|
||||
|
||||
### Codecs
|
||||
|
||||
If a CID is V0, we assume the [codec](https://docs.ipfs.tech/concepts/glossary/#codec) is [`dag-pb`](https://docs.ipfs.tech/concepts/glossary/#dag-pb) (see below). Other CIDs specify the codec, and right now we support these 2:
|
||||
|
||||
#### `raw` (`0x55`)
|
||||
|
||||
A block of this type is a blob - a bunch of bytes. We'll populate the body of the response with it.
|
||||
|
||||
#### `dag-pb` (`0x70`)
|
||||
|
||||
That's [ProtoBuf](https://protobuf.dev/)-encoded [Directed Acyclic Graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph). A block of this type is a node in a DAG, and contains some bytes to let you know what kind of node it is. There is one very special and important type of node ipfs-chromium deals with a lot:
|
||||
|
||||
##### UnixFS Node
|
||||
|
||||
The payload of these nodes have another ProtoBuf layer, and the DAG functions in a conceptually similar way to a read-only file system.
|
||||
|
||||
Not all kinds of UnixFS nodes are fully handled yet, but we cover these:
|
||||
|
||||
###### File (simple case)
|
||||
|
||||
These nodes each have a `data` byte array that is the contents of a file. We'll use those bytes as the body of a response.
|
||||
|
||||
###### File (multi-node)
|
||||
|
||||
In UnixFS a node can represent a file as the concatenation of other file nodes, to which it has `links`. The decision to use this kind of node generally has to do with the size of the file. A single node can't be much more than a megabyte, so files larger than that get cut into chunks and handled as a tree of nodes. There are a couple of reasons for that:
|
||||
|
||||
* Data deduplication (it's possible the same sequences of bytes, and thus same CID, appears in multiple files or even within the same file)
|
||||
* In the case that a gateway were malicious, we wouldn't want to wait until a file of potentially unbounded size finishes downloading before we verify that it's correct. "ipfs-chromium" enforces a limit of 2MB per block.
|
||||
* It enables the possibility that one could concurrently fetch different parts of the file from different gateways.
|
||||
|
||||
If we have all the nodes linked-to already, we can concatenate their data together and make a response body out of it. If we don't, we'll convert the missing links to CIDs and request them from gateways.
|
||||
|
||||
###### Directory (normal)
|
||||
|
||||
In this case the `data` field isn't really important to us. The `links`, however, represent items in the directory.
|
||||
|
||||
* If your URL has a path, find the `link` matching the first element in the path, and repeat the whole process with that `link`'s CID and the remainder of the path.
|
||||
* If you don't have a path, we'll assume you want `index.html`
|
||||
* If there's no `index.html` we'll generate an directory listing HTML file for you.
|
||||
|
||||
###### [HAMT](https://en.wikipedia.org/wiki/Hash_array_mapped_trie) (sharded) Directory
|
||||
|
||||
This is for directories with just too many entries in them to fit in a single block. The links from this directory node might be entries in the directory or they might be other HAMT nodes referring to the same directory (basically, the directory itself is getting split up over a tree of nodes).
|
||||
|
||||
* If you're coming in from another HAMT node, you might have some unused bits of the hash to select the next child.
|
||||
* If you have a path, hash the name of the item you're looking for, pop the correct number of bits off the hash, and use it to select which element you're going to next.
|
||||
* If you don't have a path, we'll assume you want `index.html`.
|
||||
* We don't generate listings of sharded directories today, and this isn't a high-priority as it's an unreasonable use case.
|
||||
|
||||
### Dealing with ipns:// links
|
||||
|
||||
The first element after `ipns://` is the "[ipns-name](https://specs.ipfs.tech/ipns/ipns-record/#ipns-name)".
|
||||
|
||||
* If the name is formatted as a CIDv1, and has its codec set to `libp2p-key` (`0x72`), ipfs-chromium will retrieve a [signed IPNS record](https://specs.ipfs.tech/ipns/ipns-record/#ipns-record) of what it points at from a gateway, and then load that content.
|
||||
* The cryptographic signature in the record is verified using the public key, which corresponds to the "ipns-name"
|
||||
* Note: only two [multibase](https://docs.ipfs.tech/concepts/glossary/#multibase) encodings are fully supported for now: base36 and base32. If your IPNS or DNSLink record points to something base58 that should work, but otherwise avoid it (don't use it in the address bar!).
|
||||
* If the name is not formatted as a CIDv1, a DNS request is created for the appropriate TXT record to resolve it as a [DNSLink](https://dnslink.dev/).
|
||||
|
||||
IPNS names may point to other IPNS names, in which case this process recurses. More commonly they point at an IPFS DAG, in which case ipfs-chromium will then load that content as described above.
|
||||
|
||||
## Bottom Line
|
||||
|
||||
So, in the end, the user gets to treat `ipfs://` links to snapshotted data like any other link, gets the result in a reasonable timeframe, and can rely on the data they get back being the correct data.
|
||||
|
||||
`ipns://` URLs of the DNSLink variety rely only on DNS being accurate.
|
||||
Regular `ipns://` URLs, however, are verified by the cryptographically signed [record](https://specs.ipfs.tech/ipns/ipns-record/).
|
||||
|
||||
## Trying it out
|
||||
|
||||
If you want to try this yourself today, you can [build it](https://github.com/little-bear-labs/ipfs-chromium/blob/main/BUILDING.md) from source, or you may install a pre-built binary from [GitHub releases](https://github.com/little-bear-labs/ipfs-chromium/releases/) or [an IPFS gateway](https://gateway.ipfs.io/ipfs/QmdsmW9pSM8kQsnwFpHrqQFskv6H26XzhnZWYHGVdAfcbm).
|
||||
|
||||
If you'd just like to see it in action, here are the links I use in the video below:
|
||||
|
||||
* `ipfs://bafybeigchjo5f3jyzfjwmbavhr27jwdhu6wwhsodxg4qq4x72aasxewp64/blog.html` - a snapshot of this blog post
|
||||
* `ipns://k51qzi5uqu5dkq4jxcqvujfm2woh4p9y6inrojofxflzdnfht168zf8ynfzuu1/blog.html` - a mutable pointer to the current version of this blog
|
||||
* `ipns://docs.ipfs.tech` - The IPFS documentation.
|
||||
* `ipns://en.wikipedia-on-ipfs.org/wiki/` - Wikipedia, as a big HAMT + DNSLink
|
||||
* `ipns://ipfs.io` - an unusual case: a DNSLink to another DNSLink
|
||||
* `https://littlebearlabs.io` - an HTTPs URL for comparison.
|
||||
|
||||
<iframe width="70%" src="https://www.youtube.com/embed/9XJOktFizlo" frameborder="1" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
|
||||
|
||||
## When could this be widespread?
|
||||
|
||||
This is very experimental, and will not be in mainstream browsers tomorrow. Feel free to vote for [the issue](https://bugs.chromium.org/p/chromium/issues/detail?id=1440503) where we discuss its future.
|
||||
|
||||
## Who is doing this?
|
||||
|
||||
[Little Bear Labs](https://littlebearlabs.io) and [Protocol Labs](https://protocol.ai)
|
||||
170
src/_blog/2023-07-rust-libp2p-based-ipfs-bootstrap-node.md
Normal file
170
src/_blog/2023-07-rust-libp2p-based-ipfs-bootstrap-node.md
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
title: A Rusty Bootstrapper
|
||||
description: 'Running rust-libp2p-server on one of our four IPFS bootstrap nodes.'
|
||||
author: Max Inden (@mxinden)
|
||||
date: 2023-07-24
|
||||
permalink: '/2023-rust-libp2p-based-ipfs-bootstrap-node/'
|
||||
header_image: ''
|
||||
tags:
|
||||
- 'Kademlia'
|
||||
- 'Rust'
|
||||
---
|
||||
|
||||
# Summary
|
||||
|
||||
As of July 13, 2023, one of the four "public good" IPFS bootstrap nodes operated by Protocol Labs has been running [rust-libp2p-server](https://github.com/mxinden/rust-libp2p-server) instead of [Kubo](https://github.com/ipfs/kubo), which uses [go-libp2p](https://github.com/libp2p/go-libp2p/). rust-libp2p-server is a thin wrapper around [rust-libp2p](https://github.com/libp2p/rust-libp2p). We run both Kubo and rust-libp2p-server on IPFS bootstrap nodes to increase resilience. A bug or vulnerability is less likely to be in both Kubo and rust-libp2p-server than Kubo alone. In addition to increasing resilience, we gain experience running large rust-libp2p based deployments on the IPFS network.
|
||||
|
||||

|
||||
|
||||
# IPFS Public DHT Bootstrap Nodes
|
||||
|
||||
_What is an IPFS bootstrap node?_
|
||||
|
||||
> A Bootstrap Node is a trusted peer on the IPFS network through which an IPFS node learns about other peers on the network. [...]
|
||||
|
||||
See [IPFS Glossary](https://docs.ipfs.tech/concepts/glossary/#bootstrap-node).
|
||||
|
||||
A new node trying to join the "[public IPFS DHT](https://github.com/ipfs/ipfs/discussions/473)", i.e. trying to bootstrap, will:
|
||||
|
||||
1. Connect to its (pre-) configured bootstrap nodes.
|
||||
2. Run some variation of the [Kademlia bootstrap process](https://github.com/libp2p/specs/tree/master/kad-dht#bootstrap-process) which boils down to iteratively:
|
||||
1. Generating random IDs.
|
||||
2. Asking already discovered nodes whether they know anyone closer to those IDs.
|
||||
|
||||
Thus the only thing that an IPFS bootstrap node needs to do is:
|
||||
|
||||
- Allow incoming connections.
|
||||
- Maintain a healthy Kademlia routing table.
|
||||
- Reply to Kademlia `FIND_NODE` requests based on nodes in its routing table.
|
||||
|
||||
Let's dive a bit deeper. In the case of Kubo the [DNSAddr](https://github.com/multiformats/multiaddr/blob/master/protocols/DNSADDR.md) addresses of the IPFS bootstrap nodes are shipped within the release binary.
|
||||
|
||||
``` go
|
||||
// DefaultBootstrapAddresses are the hardcoded bootstrap addresses
|
||||
// for IPFS. they are nodes run by the IPFS team. docs on these later.
|
||||
// As with all p2p networks, bootstrap is an important security concern.
|
||||
var DefaultBootstrapAddresses = []string{
|
||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
|
||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
|
||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
|
||||
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt",
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
See [`bootstrap_peers.go` on github.com/ipfs/kubo](https://github.com/ipfs/kubo/blob/v0.21.0/config/bootstrap_peers.go#L11C1-L24C2).
|
||||
|
||||
One can resolve those `/dnsaddr/...` through iterative DNS queries. Below is an example for the node with the peer ID `QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb`. This IPFS bootstrap node is running Kubo.
|
||||
|
||||
```
|
||||
dig +short -t txt _dnsaddr.bootstrap.libp2p.io
|
||||
"dnsaddr=/dnsaddr/am6.bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"
|
||||
[...]
|
||||
```
|
||||
|
||||
```
|
||||
dig +short -t txt _dnsaddr.am6.bootstrap.libp2p.io
|
||||
"dnsaddr=/ip6/2604:1380:4602:5c00::3/udp/4001/quic-v1/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb"
|
||||
[...]
|
||||
```
|
||||
|
||||
Finally connecting to the bootrap node shows us the protocols it supports.
|
||||
Below example uses [`libp2p-lookup`](https://github.com/mxinden/libp2p-lookup/) but `ipfs swarm connect` followed by `ipfs id` can be used instead.
|
||||
|
||||
|
||||
```
|
||||
libp2p-lookup direct --address /ip6/2604:1380:4602:5c00::3/udp/4001/quic-v1/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb
|
||||
|
||||
Lookup for peer with id PeerId("QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb") succeeded.
|
||||
|
||||
Protocol version: "ipfs/0.1.0"
|
||||
Agent version: "kubo/0.20.0/b8c4725"
|
||||
Listen addresses:
|
||||
- "/ip6/2604:1380:4602:5c00::3/udp/4001/quic-v1"
|
||||
- [...]
|
||||
Protocols:
|
||||
- /ipfs/kad/1.0.0
|
||||
- [...]
|
||||
```
|
||||
|
||||
Note the `Agent version: "kubo/0.20.0/b8c4725"` and the supported protocols `Protocols: - /ipfs/kad/1.0.0`.
|
||||
|
||||
# Motivation
|
||||
|
||||
_Why run both Kubo and rust-libp2p2-server bootstrap nodes?_
|
||||
|
||||
This choice is influenced by three main areas: the benefit of diverse implementations, the opportunity to test rust-libp2p at large scale, and the presence of Rust in the IPFS network.
|
||||
|
||||
Implementation Diversity: Operating both Kubo and rust-libp2p-server bootstrap nodes contributes to the network's overall resilience and security. It's like having a second line of defense; if one system encounters an issue, the other is there to continue functioning. For instance, a recent bug impacted Kubo IPFS bootstrap nodes, closing incoming connections, right after their successful establishment, due to a QUIC version mismatch. By using both Kubo and rust-libp2p-server, we ensure that nodes can still join the network, even if one set of bootstrap nodes is unavailable.
|
||||
|
||||
Testing Rust-Libp2p at Large Scale: Our use of rust-libp2p-server also provides a valuable opportunity to examine how it behaves at a larger scale. Software performance can vary depending on scale, and these differences are hard to predict without actual real-world deployments. Now we can gain insights similar to those we acquired from other large deployments such as [Polkadot](github.com/paritytech/polkadot/) and [Ethereum](https://blog.libp2p.io/libp2p-and-ethereum/).
|
||||
|
||||
Encouraging Rust in the IPFS Network: Lastly, by operating a rust-libp2p bootstrap node, we hope to motivate other developers to build IPFS-based applications using rust-libp2p. This could lead to an increase in the use of Rust, fostering a more diverse and vibrant ecosystem.
|
||||
|
||||
# rust-libp2p(-server) in Action
|
||||
|
||||
_What is rust-libp2p(-server) and how does it operate as an IPFS bootstrap node?_
|
||||
|
||||
[rust-libp2p](https://github.com/libp2p/rust-libp2p) is an implementation of the libp2p specification in Rust, a popular systems programming language. The rust-libp2p project was [initiated around 2018](https://www.parity.io/blog/why-libp2p) and since then, it has powered network like Ethereum through its Rust implementation [Lighthouse](https://github.com/sigp/lighthouse) and [Polkadot](github.com/paritytech/polkadot/) along with the [Substrate](https://github.com/paritytech/substrate/) ecosystem. You can find more rust-libp2p users [here](https://github.com/libp2p/rust-libp2p#notable-users).
|
||||
|
||||
[rust-libp2p-server](https://github.com/mxinden/rust-libp2p-server/) is just thin wrapper around rust-libp2p. It combines rust-libp2p's TCP, QUIC and Kademlia-DHT implementation into a single binary. Looking up the new rust-libp2p-server IPFS bootstrap node `ny5` via [`libp2p-lookup`](https://github.com/mxinden/libp2p-lookup/) confirms just that. Note the `Agent version: "rust-libp2p-server/0.12.0"`. and `Protocols: - /ipfs/kad/1.0.0`.
|
||||
|
||||
|
||||
```
|
||||
libp2p-lookup direct --address /dnsaddr/ny5.bootstrap.libp2p.io
|
||||
|
||||
Lookup for peer with id PeerId("QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa") succeeded.
|
||||
|
||||
Protocol version: "ipfs/0.1.0"
|
||||
Agent version: "rust-libp2p-server/0.12.0"
|
||||
Listen addresses:
|
||||
- [...]
|
||||
Protocols:
|
||||
- /ipfs/kad/1.0.0
|
||||
- [...]
|
||||
```
|
||||
|
||||
## Some Numbers
|
||||
|
||||
On the new bootstrap node we see around 15 new inbound connections per second. The majority of these connections are established via QUIC (see `ip4/udp/quic`).
|
||||
|
||||

|
||||
|
||||
The node is handling > 30k connections concurrently, thus being connected to roughly [15% of nodes of the public IPFS DHT](https://probelab.io/ipfsdht/#client-vs-server-node-estimate).
|
||||
|
||||

|
||||
|
||||
Across these connections the node handles around 40 Kademlia requests per second, most of which are Kademlia `FIND_NODE` requests.
|
||||
|
||||

|
||||
|
||||
The number of connections does not have a significant impact on CPU usage of the underlying machine.
|
||||
|
||||

|
||||
|
||||
The node uses `< 300 kbyte` of memory per connection.
|
||||
|
||||

|
||||
|
||||
A small tangent: in case you are interested in more IPFS public DHT metrics, take a look at the [probelab DHT metrics and reports](https://probelab.io/ipfsdht/).
|
||||
|
||||
# Closing
|
||||
|
||||
If you want to learn more:
|
||||
|
||||
- Read up on the [libp2p project](https://libp2p.io/)
|
||||
- Explore the [rust-libp2p implementation](https://github.com/libp2p/rust-libp2p)
|
||||
- See the thin rust-libp2p wrapper at [mxinden/rust-libp2p-server](https://github.com/mxinden/rust-libp2p-server/)
|
||||
- And lastly, the [public IPFS DHT measurements](https://probelab.io/ipfsdht/) are always a good read
|
||||
|
||||
A lot of this work was done by [@mcamou](https://github.com/mcamou) from the [Protocol Labs EngRes Bifrost team](https://pl-strflt.notion.site/Bifrost-2423fee6b15243158e85e35d8e22241d?pvs=4). Mario has handled the deployment and the team is operating the bootstrap nodes as a whole. Thanks, [@mcamou](https://github.com/mcamou) and team!
|
||||
|
||||
FAQ:
|
||||
|
||||
- Do I have to use the default bootstrap nodes?
|
||||
|
||||
No, you don't have to use `/dnsaddr/bootstrap.libp2p.io`. You can remove Protocol Labs' default nodes and add your own or use both for better reliability.
|
||||
|
||||
- Do we plan to run rust-libp2p-server on all IPFS bootstrap nodes?
|
||||
|
||||
No.
|
||||
92
src/_blog/2023-08-an-observatory-for-the-ipfs-network.md
Normal file
92
src/_blog/2023-08-an-observatory-for-the-ipfs-network.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
title: An Observatory for the IPFS Network
|
||||
description: 'The ProbeLab team has built a resilient and fully-automated infrastructure to monitor the performance of core IPFS protocols!'
|
||||
author: Yiannis Psaras (@yiannisbot)
|
||||
date: 2023-08-03
|
||||
permalink: '/2023-ipfs-observatory/'
|
||||
header_image: '/blog-post-probelabio.png'
|
||||
tags:
|
||||
- measurements
|
||||
- DHT
|
||||
- IPNI
|
||||
---
|
||||
|
||||
# tl;dr
|
||||
|
||||
The ProbeLab team has worked hard over the past year to build a resilient and fully-automated infrastructure to monitor the performance of core IPFS stack protocols. All of what we have so far lives at [https://probelab.io](https://probelab.io) with results being auto-updated on a daily basis.
|
||||
|
||||
|
||||
## Why measurement work is important
|
||||
|
||||
Measuring operational networked systems is the cornerstone of system reliability, stability, and great user experience. Unless someone measures the performance of their system, it is very difficult to spot problems and inconsistencies between protocol design and actual operation. Most importantly, it is very difficult to be able to direct engineering effort to the right direction in order to solve actual problems, deal with bottlenecks, and eventually improve performance.
|
||||
|
||||
System and network measurements are normally straightforward when there is a single (or a few) points of control. The task becomes significantly more challenging in the case of open-source, decentralized, and permissionless systems such as IPFS where there is no single point of control (or any gatekeeping entity).
|
||||
|
||||
## ProbeLab
|
||||
|
||||
This is where our team’s efforts come into the picture. ProbeLab is focusing on protocol measurement, benchmarking, and optimization for Web3.0 protocols in general and IPFS in particular. During the past year we strived to build all the necessary tooling and backend infrastructure in order to be able to reliably measure the most critical aspects of the decentralized network. To avoid this being our own knowledge and instead share our findings with the community, we’ve also built a public-facing front-end where our key results are being reported on a daily basis: [https://probelab.io](https://probelab.io)
|
||||
|
||||
One key thing that makes [https://probelab.io](https://probelab.io) different to a dashboard is that there is detailed explanation of the measurement methodology and the measurement setup, so that viewers can understand whether the results they’re observing fit their own setup and use-case. Ultimately, [https://probelab.io](https://probelab.io) should become the point of reference for engineers, as well as executives that are running (or are considering running) their applications on top of the IPFS network.
|
||||
|
||||
## Our focus (so far)
|
||||
|
||||
Apart from [several](https://www.notion.so/pl-strflt/Optimistic-Provide-07ce632c6de54aec953ec0e9ca2bbcf5?pvs=4) [protocol](https://github.com/plprobelab/network-measurements/blob/master/results/rfm16-bitswap-discovery-effectiveness.md) [optimization](https://github.com/plprobelab/network-measurements/blob/master/results/rfm15-nat-hole-punching.md) projects that ProbeLab has taken up so far, our primary focus on the measurements front has been the main component that supports decentralized content routing in the IPFS protocol stack, that is, the IPFS Public DHT network. Our focus has not been a random pick, but instead a thoughtful consideration given that this is where performance has been mostly unknown and mostly unpredictable - until now!
|
||||
|
||||
That said, we have extended our efforts to other critical parts of the architecture, such as the [InterPlanetary Network Indexers](https://docs.ipfs.tech/concepts/ipni/), and we plan to add more components to our monitoring infra in the near future.
|
||||
|
||||
Sample projects where our measurement infrastructure has helped the ecosystem tremendously are:
|
||||
|
||||
- **The Hydra Dial Down:** [Hydra Boosters](https://github.com/libp2p/hydra-booster) are a special type of DHT server node designed to accelerate content routing performance in the IPFS network. They were introduced in 2019 and were intended as an interim solution while exploring other DHT scalability techniques. The IPFS DHT network and its supporting protocols have advanced significantly since then, and the (not insignificant) cost of operating Hydras was put in question by our team. We have found that Hydras improve content routing performance by not more than 10-15% on average, which was considered minor, compared to its operational cost. The team carried out a progressive dial down of Hydras after communicating our intentions with the community (see [details](https://discuss.ipfs.tech/t/dht-hydra-peers-dialling-down-non-bridging-functionality-on-2022-12-01/15567)) and confirmed our performance estimates of a Hydra-less network. You can find an explanatory talk of our measurement estimates at IPFS Camp 2022 [here](https://www.youtube.com/watch?v=zhzxJGoLTg0) and the full project report [here](https://github.com/protocol/network-measurements/blob/master/results/rfm21-hydras-performance-contribution.md).
|
||||
|
||||
- **Unresponsive Nodes Incident:** ProbeLab’s measurement work and tooling has proven critical for incidents that nearly brought the IPFS network to its knees. Around January 2023, a software misconfiguration resulted in more than 50% of IPFS DHT network nodes becoming unresponsive. Through rigorous measurement and analysis of the measurement results, the engineering teams have chosen the right next steps to resolve the situation in record time, something that would have been significantly more difficult without the numbers that the ProbeLab team has provided. You can read all of the details regarding the incident, the response, and the measurements that our team carried out in [this previous blog post](https://blog.ipfs.tech/2023-ipfs-unresponsive-nodes/).
|
||||
|
||||
## ProbeLab Tooling
|
||||
|
||||
Our primary tooling is open-source and linked from the same website under: [https://probelab.io/tools/](https://probelab.io/tools/). There are detailed “how to” guides for each tool so that community members can get familiar and start using them for their own studies. The tools we have used so far include:
|
||||
|
||||
- [`Nebula`](https://probelab.io/tools/nebula/): a libp2p DHT crawler and monitor that is designed to track the liveliness and availability of peers.
|
||||
- [`Parsec`](https://github.com/plprobelab/parsec): a DHT and IPNI performance measurement tool that is used to gather accurate data on the performance of DHT and IPNI lookups and publications.
|
||||
- [`Tiros`](https://github.com/plprobelab/tiros): a retrieval and rendering metrics measurement tool of websites loaded over IPFS. It is designed to help developers monitor and optimize the performance of their IPFS-hosted websites. It also measures and compares the IPFS metrics with their HTTPS counterparts.
|
||||
|
||||
## What we know now that we didn’t know before
|
||||
|
||||
The plots and experiments at [https://probelab.io](https://probelab.io) offer visibility into lots of aspects that were not visible at all beforehand, or at least were not widely available. Our monitoring and observation of IPFS’s primary content routing components’ performance over the last couple of quarters reveals that at the time of writing:
|
||||
|
||||
- More than 25k DHT Server peers stay online for more than 80% of the time of a given week [[link to plot](https://probelab.io/ipfskpi/#dht-availability-classified-overall-plot)]
|
||||
|
||||

|
||||
|
||||
- Despite the above fact, the churn rate in the network is rather high with 80% of DHT Server peers leaving the network in 3hrs or less after they appeared online [[link to plot](https://probelab.io/ipfsdht/#dht-peers-churn-cdf-overall-plot)]
|
||||
|
||||

|
||||
|
||||
- The Median DHT Lookup Performance (i.e., the time to first provider record) is at 600ms as measured from 7 different geographical regions. It is worth highlighting that the lookup performance from the EU and North America, where most DHT nodes reside, is significantly better than other regions and stands at 200-250ms [[link to plot](https://probelab.io/ipfsdht/#dht-lookup-performance-cdf-region-plot)].
|
||||
|
||||

|
||||
|
||||
- Websites hosted on IPFS are served faster over kubo than HTTP for those well-performing regions (EU and North America) [[link to plot](https://probelab.io/websites/#websites-http-comparison-ttfb-p90)].
|
||||
|
||||

|
||||
|
||||
- The [cid.contact](http://cid.contact) IPNI maintains a stable lookup performance below the 300ms mark at the P90 for uncached content and across all 7 regions [[link to plot](https://probelab.io/ipni/cid.contact/#ipni-snapshot-uncached-latencies-cdf-cidcontact-plot)].
|
||||
|
||||

|
||||
|
||||
## Where to find more
|
||||
|
||||
Head over to [https://probelab.io](https://probelab.io) to dive into all the results and explanation of the experiments.
|
||||
|
||||
It is worth noting that we do not provide commentary on the results presented on the website itself. Instead, discussion around results reported at [https://probelab.io](https://probelab.io) is taking place at the [IPFS Discussion Forum](https://discuss.ipfs.tech/c/testing-and-experiments/measurements/39).
|
||||
|
||||
You can reach out to the ProbeLab team (e.g., if you’re interested contributing to the measurement effort, or have a request) through:
|
||||
|
||||
- the `#probe-lab` channel in IPFS Discord [[invite link](https://discord.gg/ipfs)], or Filecoin Slack [[invite link](https://filecoin.io/slack)] (bridged channel).
|
||||
- The team’s email: [probelab@protocol.ai](mailto:probelab@protocol.ai)
|
||||
|
||||
We also hold bi-weekly Office Hours, where we invite the community and our collaborators to join and bring up questions, challenges they face and topics for discussion. You can sign up through [this lu.ma page](https://lu.ma/ipfs-network-measurements).
|
||||
|
||||
<!-- ## A guide for website owners hosting with IPFS
|
||||
|
||||
Last, but not least, we have developed an in-depth methodology to monitor performance of websites hosted on IPFS. We are currently monitoring most of PL’s websites and provide a breakdown of web access performance metrics (primarily using [Web Vitals](https://web.dev/vitals/)). This is very helpful for monitoring overall performance, but especially for debugging in case of poor performance, or errors while fetching website content.
|
||||
|
||||
++ linking to the howto guide as well as how to use it, if we finalise and decide to include. -->
|
||||
110
src/_blog/2023-09-amino-refactoring.md
Normal file
110
src/_blog/2023-09-amino-refactoring.md
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
title: Amino (the Public IPFS DHT) is getting a facelift
|
||||
description: 'The ProbeLab team is working on a major refactoring of the Public IPFS DHT (henceforth called Amino) and a new feature which will accelerate the provide operation by several orders of magnitude. Read through to find out the details and how to get involved.'
|
||||
author: ProbeLab
|
||||
date: 2023-09-26
|
||||
permalink: '/2023-09-amino-refactoring/'
|
||||
header_image: '/2023-09-amino-refactoring.png'
|
||||
tags:
|
||||
- 'Amino'
|
||||
- 'IPFS DHT'
|
||||
- 'Reprovide Sweep'
|
||||
---
|
||||
|
||||
Two major items are being announced in this blogpost, both of which are equally exciting and relate to “the Public IPFS DHT” (the [public Kademlia-based DHT](https://docs.ipfs.tech/concepts/dht/#dual-dht) that [Kubo (and other implementations) default to bootstrapping into](https://docs.ipfs.tech/how-to/modify-bootstrap-list/) with the libp2p protocol `/ipfs/kad/1.0.0`), which is henceforth going to be called **“Amino”**. The first relates to a major refactoring of the Amino codebase and the second is an optimization of the publish operation of the protocol, so that providing content to Amino is made much faster and resource-efficient.
|
||||
|
||||
## Why Amino?
|
||||
|
||||
The “Public IPFS DHT” is henceforth going to be called **“Amino”**. This follows along with the trend from 2022 in the IPFS ecosystem to use more precise language to create space for alternative options (i.e., other DHTs). Just as there isn’t one IPFS implementation, there isn’t one content routing system or DHT. “Amino” was chosen from Amino acids - the building block for larger, stronger structures, which is what we believe will happen with this network. There can be several IPFS DHT networks, and they can choose to borrow functionality from the “Amino” network. More context on the naming can be found [here](https://github.com/ipfs/ipfs/discussions/473).
|
||||
|
||||
## Refactoring of `go-libp2p-kad-dht` codebase
|
||||
|
||||
It has long been realized that the current go implementation of libp2p’s Distributed Hash Table (DHT), which is used by IPFS implementations like Kubo and other projects/platforms, is in need of a major revision. The problems that have been identified by core maintainers and community contributors alike can be summarised in the following:
|
||||
|
||||
1. Several years of adding extra features to the codebase and iterations of core functionality have made the DHT faster and more efficient, but have also added substantially to its complexity. It has now become more **difficult to understand and make changes to the code**, which indirectly is pushing developers away from contributing to it.
|
||||
2. **Flaky tests due to concurrency issues**. Unit tests, which evaluate if the implementation is working as expected, are difficult to implement due to extensive parallelization of several parts of the code.
|
||||
3. Lack of unit tests in turn make it **hard to carry out performance evaluation tests**. This has recently resulted in performance evaluation results that are hard to understand or act upon - Bitswap’s `Provider Search` delay is a good example here [[link](https://github.com/ipfs/kubo/pull/9530)].
|
||||
4. The current implementation is carrying a **non-negligible amount of technical debt** that was acquired over the years. For instance, Kademlia should only handle Kademlia identifiers (256-bits bitstrings) internally, but it is currently using strings [[source](https://github.com/libp2p/go-libp2p-kad-dht/blob/b63ad6096833d36b365f1361edab871f6cdc283c/query.go#L83)].
|
||||
|
||||
The [PL EngRes IPFS Stewards team](https://www.notion.so/IPFS-f3c309cecfd844e788d8b9e13472a97b?pvs=21) has been working on a **major refactoring of `go-libp2p-kad-dht`**. In this context, a new library, `go-libdht` defines the basic building blocks for implementing DHTs, and will be used by the refactored `go-libp2p-kad-dht`. The goal of the refactoring project is to address the above challenges. In particular,
|
||||
|
||||
- make the code base easy to modify and improve by making it single-threaded.
|
||||
- allow for sequential, deterministic code execution, making debugging easier, testing more reliable and simulation/reproducibility possible and,
|
||||
- get rid of unnecessary code and complexity.
|
||||
|
||||
### Expected Changes & Timeline
|
||||
|
||||
The refactored codebase is being worked on in the [v2-develop branch of go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht/tree/v2-develop). The current progress, next tasks and open issues can be found at this project board: [https://github.com/orgs/plprobelab/projects/1](https://github.com/orgs/plprobelab/projects/1). The refactored code is expected to be completed, tested and ready for integration into Kubo for further testing during the first half of October.
|
||||
|
||||
Where possible, we aim to remain compatible with version 1. There are no breaking protocol changes planned, and we expect to be able to adhere to the standard Routing interface used by Kubo. The libp2p Kademlia implementation has been battle tested through many years of use, and we want to take advantage of the learnings from that real-world usage while improving the ergonomics and clarity of the code. However, we will be taking this opportunity to look closely at the current code interfaces and to propose improved or new ones.
|
||||
|
||||
Most of the changes being made are internal to the operation of the DHT. We’re creating a new state machine oriented execution model that is very different to the existing implementation. This allows us to bound work and resources more cleanly and prioritize work performed more appropriately. Performance will also be different and, for the initial release, our goal is for this to be similar to the current codebase. However, we expect the new execution model will give us more scope for optimization in the future. Having better control over the scheduling of work will also allow the new implementation to continue to perform well under resource pressure and high load.
|
||||
|
||||
## Making Reprovides to Amino lightning fast
|
||||
|
||||
Content providers with a large number of CIDs to provide to the DHT have traditionally been facing difficulties. The current PUT operation in `go-libp2p-kad-dht` lacks resource efficiency. For every CID being reprovided, the provider performs a lookup and initiates a connection with the top 20 nearest peers *sequentially*. In practice, this means that if a peer needs to be contacted twice for two CIDs, the providing peer needs to open two connections to the same peer at different points in time within the same reprovide task.
|
||||
|
||||
In turn, this results in significant bandwidth requirements and deters large content providers from advertising their content on Amino (the IPFS DHT) due to cost constraints. The sequential manner in which reprovides take place can result in content providers failing to refresh all content within the 48h provider record expiration interval [[link to source](https://github.com/libp2p/go-libp2p-kad-dht/blob/b63ad6096833d36b365f1361edab871f6cdc283c/providers/providers_manager.go#L38)][[link to spec](https://github.com/libp2p/specs/tree/master/kad-dht#content-provider-advertisement-and-discovery)], rendering the content inaccessible.
|
||||
|
||||
Our approach is to optimize the provide process, making it much less resource intensive. This will pave the way for a significantly larger throughput in the number of "provides".
|
||||
|
||||
### High level design of `ReprovideSweep`
|
||||
|
||||
The base premise of `ReprovideSweep` is that **all keys located in the *same keyspace region* are reprovided *all at once,** instead of sequentially,* which is currently the case. This is in contrast to the status quo of re-providing in the current IPFS DHT, where the provider record of each CID is sent out separately, though a new connection.
|
||||
|
||||
Given that some large Content Providers are publishing way more CIDs than there are DHT Servers, by the [pigeonhole principle](https://en.wikipedia.org/wiki/Pigeonhole_principle) there must be DHT Servers that are allocated more than one Provider Record, by a particular Content Provider. The primary rationale is to send/re-provide all Provider Records allocated to the same DHT Server *******at once, instead of having to revisit the same server later on, re-establish a connection, and store the provider record*******.
|
||||
|
||||
However, because sending multiple Provider Records requires a new RPC causing a breaking change, it isn’t trivial to send all Provider Records exactly *at once.* That said, the most expensive part in a (Re)Provide operation is the DHT walk to discover the right DHT Servers to store the Provider Records on, as well as opening new connections to these peers. Once these peers are known, and a connection is already open, the Content Provider can simply reuse the same connection to send multiple individual `Provide` requests, thereby avoiding breaking changes while still reaping performance gains.
|
||||
|
||||
The `go-libp2p-kad-dht` DHT implementation must keep track of the CIDs that must be republished every `Interval` (let’s assume that all Provider Records are republished at the same frequency). The Kademlia identifiers of the CIDs to republish must be arranged in a [binary trie](https://github.com/guillaumemichel/py-binary-trie) to allow for faster access. As each Provider Record is replicated on 20 different DHT Servers, 20 DHT Servers in a close locality are expected to store the same Provider Records (this is not 100% accurate, but suffices for our high-level description here - we’ll publish all the details in a subsequent post, when the solution is in production).
|
||||
|
||||
In a nutshell, the Content Provider will continuously lookup keys across the entire keyspace, hence “sweeping” the keyspace. For each key that is to be published, the Content Provider will find the 20 closest peers, and lookup in its “CIDs Republish Binary Trie” all Provider Records that would belong to those specific 20 remote peers. Doing this match-making exercise, content providers will be able to reprovide all provider records that correspond to a particular peer at once. Based on this logic, Content Providers are only limited by network throughput.
|
||||
|
||||
You can watch a recording from [IPFS Thing 2023](https://2023.ipfs-thing.io/) explaining the concept in more detail [here](https://youtu.be/bXaL64fp55c?si=1LuukjErCG_bz02N).
|
||||
|
||||
### `ReprovideSweep` Performance
|
||||
|
||||
`ReprovideSweep` is not implemented yet, hence, we can only approximate its performance analytically. In the tables below we see that `ReprovideSweep` is improving performance significantly on all fronts and important metrics, assuming that the number of CIDs (`#CIDs`) that a provider wishes to publish is much larger than the number of DHT Server nodes in the network (`#DHT_SERVERs`), i.e. `#CIDs >> #DHT_SERVERs`:
|
||||
|
||||
- The number of DHT Lookups is reduced from being equal to the number of CIDs to be published, down to 1/20th of the number of DHT Server nodes in the network.
|
||||
- The number of connections that need to be opened is also reduced and is equal to the number of DHT Server nodes (if the number of CIDs to be provided is much larger than the number of server nodes in the network).
|
||||
- As we see in the second table, assuming a network size of ~25k DHT Server nodes, the overall improvement in terms of ‘number of connections open’ and ‘number of DHT Lookups’ is significant reaching an improvement of ~800x for 1M CIDs.
|
||||
|
||||
| | Current Reprovide | Reprovide Sweep |
|
||||
| --- | --- | --- |
|
||||
| Number of DHT lookups | #CIDs | ~1/20 * #DHT_SERVERs |
|
||||
| Number of connections to open | 20 * #CIDs | #DHT_SERVERs |
|
||||
|
||||
| #CIDs published | Improvement (#connections, #DHT Lookups) |
|
||||
| --- | --- |
|
||||
| > 1K | - |
|
||||
| 25K | 20x |
|
||||
| 100K | 80x |
|
||||
| 500K | 400x |
|
||||
| 1M | 800x |
|
||||
| 10M | 8’000x |
|
||||
|
||||
### Expected Changes & Timeline
|
||||
|
||||
We are very excited about this change because it will enable large content providers to start using the most resilient and decentralized component of the IPFS network.
|
||||
|
||||
**This change is a client side optmization and doesn’t involve any protocol alteration.** As such, it allows users to immediately benefit from the feature. The interface between `go-libp2p-kad-dht` and [`boxo`](https://github.com/ipfs/boxo), which Kubo uses, must be updated to enable the DHT client to take on the responsibility of managing the reprovide operation.
|
||||
|
||||
The PL EngRes IPFS Stewards team is currently working to define the spec for `ReprovideSweep`, which we hope to have ready in the beginning of October, and we anticipate rolling out this enhancement during Q4’23. We will update the community with a new blogpost or discussion forum post closer to the time. Until then, you can follow developments on this front through this GH issue: [https://github.com/libp2p/go-libp2p-kad-dht/issues/824](https://github.com/libp2p/go-libp2p-kad-dht/issues/824).
|
||||
|
||||
## What’s next
|
||||
|
||||
We believe the above lays the groundwork for more exciting DHT innovation ahead. We have some ideas that we’d love to be talking about and working with the community. We’re still figuring out the best place for this conversation, but subscribe [here](https://discuss.ipfs.tech/t/dht-discussion-and-contribution-opportunities-in-2023q4/16937) if you’re interested in learning about upcoming DHT discussion areas (e.g., at [LabWeek](https://labweek.plnetwork.io/)/[DevConnect](https://devconnect.org/), DHT working group). You can also join the team's Office Hours by subscribing at: [https://lu.ma/ipfs-network-measurements](https://lu.ma/ipfs-network-measurements).
|
||||
|
||||
## How to get involved
|
||||
|
||||
As always, help is more than welcome to accelerate development and make the design more robust through feedback. Here are ways you can get involved:
|
||||
|
||||
- Github repository:
|
||||
- DHT Refactoring: [https://github.com/plprobelab/go-kademlia/](https://github.com/plprobelab/go-kademlia/)
|
||||
- Reprovide Sweep: [https://github.com/libp2p/go-libp2p-kad-dht/issues/824](https://github.com/libp2p/go-libp2p-kad-dht/issues/824)
|
||||
- Slack channel:
|
||||
- `#probe-lab` in [FIL Slack](https://filecoin.io/slack) or [IPFS Discord](https://discord.gg/vj7qWuAyHY) (bridged channel), or
|
||||
- `#kubo-boxo-dev` in FIL Slack
|
||||
- IPFS Discussion forum:
|
||||
- DHT Refactoring and future planning: [https://discuss.ipfs.tech/t/dht-discussion-and-contribution-opportunities-in-2023q4/16937](https://discuss.ipfs.tech/t/dht-discussion-and-contribution-opportunities-in-2023q4/16937)
|
||||
130
src/_blog/2023-11-introducing-nabu.md
Normal file
130
src/_blog/2023-11-introducing-nabu.md
Normal file
@@ -0,0 +1,130 @@
|
||||
---
|
||||
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.
|
||||
42
src/_blog/2023-11_connect-with-us-in-istanbul-and-prague.md
Normal file
42
src/_blog/2023-11_connect-with-us-in-istanbul-and-prague.md
Normal file
@@ -0,0 +1,42 @@
|
||||
---
|
||||
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!
|
||||
95
src/_blog/2023-12-introducing-dappling.md
Normal file
95
src/_blog/2023-12-introducing-dappling.md
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
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.
|
||||
|
||||
🙏
|
||||
72
src/_blog/2023-3-29-ipfs-thing-content-tracks.md
Normal file
72
src/_blog/2023-3-29-ipfs-thing-content-tracks.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: Announcing the Content Tracks for IPFS Thing 2023
|
||||
description: 'An overview of the content tracks that the community will convene around during IPFS Thing 2023.'
|
||||
author:
|
||||
date: 2023-3-29
|
||||
permalink: '/2023-ipfs-thing-content-tracks/'
|
||||
header_image: '/2023-3-29-ipfs-thing-content-tracks.jpg'
|
||||
tags:
|
||||
- 'ipfs thing'
|
||||
- 'event'
|
||||
---
|
||||
|
||||
The IPFS implementers community will be gathering together in Brussels, Belgium in just a few weeks for [IPFS Thing 2023](https://2023.ipfs-thing.io/submit/).
|
||||
|
||||
Today we’re excited to finally share the final list of the content tracks so you can know what to expect! Each track will have a variety of talks and discussions from members of the community.
|
||||
|
||||
If you haven’t registered yet, head on over to [the event website](https://2023.ipfs-thing.io/) to grab your tickets today! [IPFS Thing 2023](https://2023.ipfs-thing.io/) is happening from **April 15-19 in Brussels, Belgium** and will include everything from talks, workshops, discussion circles, hacking time, and more.
|
||||
|
||||
## Opening Keynotes
|
||||
|
||||
During this opening session, we'll hear an overview of the latest implementations, tools, and advancements across the world of IPFS, and celebrate the winners of the IPFS Impact Grants Round 2. (Track lead: [Mosh Lee](https://twitter.com/mishmosh))
|
||||
|
||||
## Standards, Governance, and DWeb Policy
|
||||
|
||||
This track sits at the intersection of IPFS standards, governance, and dweb and regulation. What's the latest on the IPFS protocol and governance? What specific problems do we face regarding existing regulation? What new regulation or changes could be helpful? Are there interesting policy angles that we can surface, develop, and advocate for? How do we make the dweb a robust, sustainable commons? (Track lead: [Robin Berjon](https://mastodon.social/@robin
|
||||
))
|
||||
|
||||
## IPFS Deployments + Operators
|
||||
|
||||
From best practices to the mistakes made along the way, this track is a chance to highlight how members of the community are running IPFS nodes at scale. Let's share what's working well and what implementations can do to make things even better! (Track lead: [James Walker](https://twitter.com/walkah))
|
||||
|
||||
## Interplanetary Databases
|
||||
|
||||
There’s a new class of distributed database technologies building atop steady advances in IPLD & hash linked data structures in general. In this track we’ll gather those brave enough to take on CAP theorem in a decentralized context, share notes on what’s working, and hear presentations from teams pushing the envelope on what databases can do and where they can exist. (Track lead: [J Chris](twitter.com/jchris))
|
||||
|
||||
## Data Transfer
|
||||
|
||||
Come join the Protocol Thunderdome as we battle to determine the best way to move content addressed bytes! We'll review recent progress in data transfer, including work coming out of the Move The Bytes Working Group, and explore how we can make IPFS 10x faster at getting your stuff than Web2! (Track lead: Hannah Howard)
|
||||
|
||||
## Measuring IPFS
|
||||
|
||||
A data-driven approach to the design and operation of IPFS and libp2p through rigorous network measurements, performance evaluation, and recommendations for builders and operators. (Track lead: Yiannis Psaras)
|
||||
|
||||
## IPFS on the Web
|
||||
|
||||
The world wide web is both the biggest deployment vector and least tractable surface for IPFS. There are opportunities and major challenges to bringing IPFS support in web rendering engines and browsers, to web content served through gateways, to IPFS network access from HTTP web apps and browser extensions. This track will have talks on: current and future browser implementations, approaches to managing and publishing IPFS content on the web, building apps that connect to the IPFS from within HTTP contexts, culminating in planning for group working sessions around on specific IPFS+Web challenges on day 4 & 5 of IPFS Thing. (Track lead: [Dietrich Ayala](https://twitter.com/dietrich/))
|
||||
|
||||
## Integrating IPFS
|
||||
|
||||
IPFS is not an island - it exists in diverse environments, manifesting in different ways depending on the use-case, ranging from mobile devices to blockchains to naming systems, even soon in space. These integration points provide interesting opportunities to explore the capabilities of IPFS and muse on what IPFS even is. We’ll hear from folks on what they’re doing, what’s working, and ponder how far we can flex IPFS to fit the multitude of places it needs to be. (Track lead: Ryan Plauche)
|
||||
|
||||
## Decentralized Compute & AI
|
||||
|
||||
We believe computing and AI can become more powerful and useful by embracing content addressing and a “merkle-native” way of doing things. In this track, we'll discuss various projects in this area, sharing R&D experiences, future directions, use cases, and benefits. (Track lead: [Iryna Tsimashenka](https://twitter.com/iryna_it09))
|
||||
|
||||
## Content Routing
|
||||
|
||||
Approaches and protocols to content routing in IPFS, what we've learned so far, and directions for the future. Join this track to explore herding CIDs, bringing content providers closer to the seekers of content, new advances across content routing systems, and a fresh look at the horizon of what's to come. (Track lead: Masih Derkani)
|
||||
|
||||
## HTTP Gateways
|
||||
|
||||
How do we deliver IPFS content to the masses? In this track, we'll dive into the magical and maddening topic of HTTP Gateways. Topics include the evolving semantics of /ipfs/cid, .car blocks and rendered flat files, and large-scale efforts to improve gateway architectures such as Project Saturn and Project Rhea. (Track lead: [Will Scott](https://twitter.com/willscott/))
|
||||
|
||||
## Roadmapping Next Steps out of the IPFS þing
|
||||
|
||||
A discussion / breakout-oriented workshop for defining and committing to next steps out of the week's conversations, which we can land and celebrate at upcoming IPFS events in Q3 / Q4 2023. (Track lead: [Molly Mackinlay](https://twitter.com/momack28))
|
||||
|
||||
---
|
||||
|
||||
We're looking forward to seeing you all soon and exploring these exciting content tracks together in-person!
|
||||
|
||||
Have a talk or workshop to share? You can also [submit a talk](https://2023.ipfs-thing.io/submit/) though April 5.
|
||||
26
src/_blog/2023-brave-infobar.md
Normal file
26
src/_blog/2023-brave-infobar.md
Normal file
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: Brave Browser's New IPFS Infobar
|
||||
description: 'We’re excited to share a new IPFS-related feature that appears in the most recent version of Brave.'
|
||||
date: 2023-09-25
|
||||
header_image: '/braveinfobar2.png'
|
||||
tags:
|
||||
- brave
|
||||
- browsers
|
||||
---
|
||||
|
||||
We’re excited to share a new IPFS-related feature that appears in the most recent version of [Brave’s web browser](https://brave.com/). 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](https://docs.ipfs.tech/how-to/address-ipfs-on-web/#http-gateways) or a website with a [DNSLink](https://docs.ipfs.tech/concepts/dnslink/).
|
||||
|
||||
By using the IPFS Infobar, you can choose whether you would like to switch to loading the IPFS version of the content. Selections can be made to always load via IPFS or only load it in a specific instance.
|
||||
|
||||

|
||||

|
||||
|
||||
This new feature will increase visibility of IPFS content when it exists and contribute to greater awareness for the benefits that can be had from utilizing content addressing.
|
||||
|
||||
Brave’s IPFS Infobar is a small but mighty new feature that we are excited to see in the wild!
|
||||
|
||||
In addition to the Infobar, there are more tools currently being developed for [Brave](https://brave.com/) by others such as [David Justice](https://github.com/JusticeEngineering) that are worth noting. Some of the prototypes include: Markdown/Wysiwyg webpage creator, Link In Bio/Link List site creator, and the ability to password protect webpages with many more ideas in the works.
|
||||
|
||||
[https://github.com/JusticeEngineering/markdown-publish](https://github.com/JusticeEngineering/markdown-publish)
|
||||
|
||||
[https://github.com/JusticeEngineering/link-list](https://github.com/JusticeEngineering/link-list)
|
||||
30
src/_blog/2023-content-blocking-for-the-ipfs-stack.md
Normal file
30
src/_blog/2023-content-blocking-for-the-ipfs-stack.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Content Blocking for the IPFS stack is finally here!
|
||||
description: 'We’re excited to share that content blocking can now be enabled in Kubo and other tools in the IPFS stack.'
|
||||
author: The Bifrost Team
|
||||
date: 2023-04-26
|
||||
permalink: '/2023-content-blocking-for-the-ipfs-stack/'
|
||||
header_image: '/release-notes-placeholder.png'
|
||||
tags:
|
||||
- 'go-ipfs'
|
||||
- 'kubo'
|
||||
- 'badbits'
|
||||
- 'content-blocking'
|
||||
- 'content-moderation'
|
||||
---
|
||||
|
||||
Bifrost (the Protocol Labs NetOps team responsible for the IPFS.io HTTP gateways) is happy to announce that content blocking can now be enabled in Kubo and other tools in the IPFS stack.
|
||||
|
||||
Traditionally, content blocking has been performed only at the IPFS gateway level and directly in Nginx, using the original [Badbits denylist](https://badbits.dwebops.pub/denylist.json). This had a few issues: content on the denylist was not blocked on Kubo and was still available via Bitswap. Additionally, blocking affected concrete CID strings, but not equivalent ones (i.e. those with a different base encoding).
|
||||
|
||||
In order to resolve these issues and to make a long term commitment to improving how we do content moderation in IPFS, we have taken the following steps:
|
||||
- [Submitted IPIP-383](https://github.com/ipfs/specs/pull/383), which defines a much more flexible and efficient compact denylist format. This new format supports different block types and sets a foundation for future work on denylist transparency, sharing, and distribution. For example, every blocked item can now have tags attached to provide metadata such as the reason for the blocking. IPFS implementations can then choose whether to expose that information or not.
|
||||
- [Implemented NOpfs](https://github.com/ipfs-shipyard/nopfs), a Blocker that understands the new compact denylist format and decides whether any CID or IPFS Path should be blocked or not. This Blocker implementation also provides a Kubo plugin which gives Kubo the ability to never download blocked content. NOpfs can also be used separately from Kubo by setting a Web service that returns whether an IPFS path or URL should be blocked or not (upcoming work from our side). This can also be useful for Filecoin Storage providers and anyone who wants to make sure their CIDs have not been included in a denylist.
|
||||
|
||||
In the meantime, we have converted our existing denylist to the new format so that everyone can take advantage of these changes right away: [https://badbits.dwebops.pub/badbits.deny](https://badbits.dwebops.pub/badbits.deny)
|
||||
|
||||
This work is the framing for a larger endeavour to improve content moderation on the IPFS public networks. If you have any questions, need help, or would like to collaborate, then please [reach out via GitHub on IPIP-383](https://github.com/ipfs/specs/pull/383) or [NOpfs](https://github.com/ipfs-shipyard/nopfs)! If you’d like to help further this initiative, you can start by sharing this news with your community and by letting the Kubo maintainers know that you’d like to see this functionality integrated into Kubo as a first class citizen.
|
||||
|
||||
And last of all, it would be remiss of us if we didn’t thank [Hector](https://twitter.com/hecturchi) for all the hard work he put into this. Thank you for all your efforts... they are greatly appreciated!
|
||||
|
||||
The Bifrost Team.
|
||||
505
src/_blog/2023-how-to-hose-dynamic-content-on-ipfs.md
Normal file
505
src/_blog/2023-how-to-hose-dynamic-content-on-ipfs.md
Normal file
@@ -0,0 +1,505 @@
|
||||
---
|
||||
title: 'How to Host Dynamic Content on IPFS'
|
||||
description: 'This article presents a design for hosting dynamic content on IPFS using IPLD, IPNS, and DHT Provider Records.'
|
||||
author: tabcat
|
||||
date: 2023-05-17
|
||||
permalink: '/2023-how-to-host-dynamic-content-on-ipfs/'
|
||||
header_image: '/hosting-dynamic-content.png'
|
||||
tags:
|
||||
- 'dynamic-content'
|
||||
- 'hosting'
|
||||
- 'ipld'
|
||||
- 'ipns'
|
||||
- 'dht'
|
||||
---
|
||||
|
||||
The InterPlanetary File System (IPFS) is a distributed, peer-to-peer file system designed to make the web faster, safer, and more resilient. Although IPFS excels at hosting static content, hosting dynamic content remains a challenge. This article presents a design for hosting dynamic content on IPFS using InterPlanetary Linked Data (IPLD), InterPlanetary Name Service (IPNS), and DHT Provider Records.
|
||||
|
||||
## Table of Contents
|
||||
<!-- TOC start -->
|
||||
|
||||
- [Understanding Key Components](#understanding-key-components)
|
||||
* [IPLD](#ipld)
|
||||
* [IPNS](#ipns)
|
||||
* [PeerID](#peerid)
|
||||
* [Provider Records](#provider-records)
|
||||
- [Defining the Problem](#defining-the-problem)
|
||||
- [Achieving Dynamicity](#achieving-dynamicity)
|
||||
* [Read and Write Steps](#read-and-write-steps)
|
||||
+ [Writing](#writing)
|
||||
+ [Reading](#reading)
|
||||
* [Dynamic-Content IDs](#dynamic-content-ids)
|
||||
* [Manifest Document](#manifest-document)
|
||||
- [Use-case: Edge-computed Applications](#use-case-edge-computed-applications)
|
||||
* [Edge Devices](#edge-devices)
|
||||
* [Pinning Servers](#pinning-servers)
|
||||
* [Replication](#replication)
|
||||
- [Roadblocks and Workarounds](#roadblocks-and-workarounds)
|
||||
* [No 3rd Party Publishing to DHT](#no-3rd-party-publishing-to-dht)
|
||||
* [No Delegated Refreshing of IPNS OR Provider Records](#no-delegated-refreshing-of-ipns-or-provider-records)
|
||||
- [Example](#example)
|
||||
* [Usage](#usage)
|
||||
+ [Clone the Repo](#clone-the-repo)
|
||||
+ [Install Packages](#install-packages)
|
||||
+ [Run Examples](#run-examples)
|
||||
* [What's Happening?](#whats-happening)
|
||||
* [Sample Outputs](#sample-outputs)
|
||||
- [Credits](#credits)
|
||||
- [Get Involved](#get-involved)
|
||||
- [FAQ](#faq)
|
||||
|
||||
<!-- TOC end -->
|
||||
|
||||
|
||||
<br/>
|
||||
|
||||
## Understanding Key Components
|
||||
|
||||
### IPLD
|
||||
|
||||
[IPLD](https://ipld.io/) is a data model for linking and addressing data across distributed systems. In IPFS, IPLD stores immutable data, providing [content-addressed storage](https://en.wikipedia.org/wiki/Content-addressable_storage). Data stored in IPLD has a unique [Content Identifier](https://docs.ipfs.tech/concepts/content-addressing/) (CID) derived from its content, ensuring data integrity.
|
||||
|
||||
### IPNS
|
||||
|
||||
[IPNS](https://docs.ipfs.tech/concepts/ipns/) is a decentralized naming system that allows you to create a mutable reference to an immutable CID. With IPNS, you can create a persistent address that always points to the latest version of your content, even as it changes over time.
|
||||
|
||||
### PeerID
|
||||
|
||||
A [Libp2p PeerID](https://docs.libp2p.io/concepts/fundamentals/peers/#peer-id) is a unique identifier for each node in the network, derived from a [public key](https://en.wikipedia.org/wiki/Public-key_cryptography). PeerIDs help find, identify, and communicate with other nodes.
|
||||
|
||||
### Provider Records
|
||||
|
||||
[Provider Records](https://docs.ipfs.tech/concepts/dht/) are a fundamental part of IPFS's Distributed Hash Table (DHT). When requesting IPFS content, a node queries the DHT for Provider Records associated with the requested CID. These records contain the PeerID of peers with the content, enabling the user to establish a connection and retrieve the data.
|
||||
|
||||
---
|
||||
> **It's important to note that IPNS names and PeerIDs use the same [key structures](https://specs.ipfs.tech/ipns/ipns-record/#ipns-keys).**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
## Defining the Problem
|
||||
|
||||
Databases on IPFS have been gaining more attention recently. In essence, these database protocols use IPLD to store replica data.
|
||||
And they commonly use a real-time protocol like [Gossipsub](https://docs.libp2p.io/concepts/pubsub/overview/) with IPLD to sync database changes peer-to-peer.
|
||||
Using this design to create [local-first](https://www.inkandswitch.com/local-first/) databases looks quite promising.
|
||||
However, local-first databases are often highly [sharded](https://en.wikipedia.org/wiki/Partition_(database)) and run on end-user devices.
|
||||
|
||||
This presents the problem of peers being few and unreliable to sync with.
|
||||
One solution is to add reliable database peers to the mix, either self-hosted or hosted by a service.
|
||||
There are two disadvantages to this approach:
|
||||
|
||||
- Each project must build infra tooling
|
||||
- Users need a live instance of each database protocol used
|
||||
|
||||
It would benefit all related protocols to have a general solution for asynchronous replication of dynamic content.<br/>
|
||||
*Think pinning layer for dynamic content.*
|
||||
|
||||
This standardized layer would complement the app-specific protocols used for real-time replication.
|
||||
|
||||
<br/>
|
||||
|
||||
## Achieving Dynamicity
|
||||
|
||||
Let's look at a replication algorithm for one of the first databases on IPFS, [OrbitDB](https://github.com/orbitdb). The algorithm is roughly as follows:
|
||||
|
||||
1. Join a shared pubsub channel for the database.
|
||||
2. On seeing a new pubsub peer in the shared channel, attempt to join a direct pubsub channel ([ipfs-pubsub-1on1](https://github.com/ipfs-shipyard/ipfs-pubsub-1on1)).
|
||||
3. On committing an update to the local replica, advertise replica root CIDs on each direct pubsub channel.
|
||||
4. On receiving a replica root CIDs advertisement on a direct pubsub, traverse the remote replica for changes to merge.
|
||||
|
||||
The design presented in this article works similarly but replaces pubsub with Provider Records and IPNS. Essentially, all parts of replication get encoded into ~persistent IPFS components.
|
||||
|
||||
- Provider Records to find collaborators
|
||||
- IPNS to point to the latest version of a device's replica
|
||||
|
||||
---
|
||||
> **Swapping pubsub for ~persistent components makes building on history without any collaborators online possible.**
|
||||
---
|
||||
|
||||
The main contribution is the novel use of Provider Records.
|
||||
Instead of tying a CID to PeerIDs of nodes hosting that content, the records tie a "Dynamic-Content ID" to IPNS names.
|
||||
Each IPNS name resolves to the latest CID of a device's local replica.
|
||||
|
||||
*Collaborating on dynamic content is possible without knowing any previous collaborators or needing them to be online as long as their replica data is kept available via a pinner.*
|
||||
|
||||
If you are familiar with publishing Provider Records to the DHT, *you may have spotted a problem here*.
|
||||
The source of the problem is a check DHT servers do when receiving an `ADD_PROVIDER` query, addressed in [Roadblocks and Workarounds](#roadblocks-and-workarounds).
|
||||
|
||||
<img src="https://raw.githubusercontent.com/tabcat/dynamic-content/master/.assets/dynamic-content-diagram.png" width="333">
|
||||
|
||||
---
|
||||
> **The Merkle-DAGs built with IPLD provide a persistent and efficient layer for collaborators to sync.**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
### Read and Write Steps
|
||||
|
||||
Describes the process of reading/writing dynamic content to IPFS:
|
||||
|
||||
#### Writing
|
||||
|
||||
1. Make changes to the local replica
|
||||
2. Push replica data to the IPLD pinner
|
||||
3. Republish IPNS to point to new CID root
|
||||
4. Add IPNS key as a provider of the Dynamic Content's ID
|
||||
|
||||
#### Reading
|
||||
|
||||
1. Query the DHT for Providers of the Dynamic Content's ID
|
||||
2. Resolve providers' IPNS keys to CIDs
|
||||
3. Resolve CIDs to IPLD data
|
||||
4. Merge changes with the local replica
|
||||
|
||||
---
|
||||
> **Titling this article 'Replication on IPFS' might have been more accurate, but 'Hosting Dynamic Content on IPFS' sounded waaay better.**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
### Dynamic-Content IDs
|
||||
|
||||
A Dynamic-Content ID (DCID) looks like a CID. Also, both DCIDs and CIDs reference and identify content on the DHT.
|
||||
|
||||
*Where the two IDs differ is in their creation.*
|
||||
|
||||
While CIDs come from the hash of some static content, DCIDs are a permutation of the CID of a manifest document.
|
||||
This immutable manifest document "describes" the dynamic content.
|
||||
|
||||
As stated in the previous section, DCIDs identify unique dynamic content.
|
||||
They point to IPNS names by using Provider Records on the DHT.
|
||||
|
||||
---
|
||||
> **Disclaimer: Dynamic-Content IDs, or DCIDs, only exist for the purpose of this article. It is not an official spec or part of IPFS. (expect a name change because I also hate "DCIDs" 🤢🤮)**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
### Manifest Document
|
||||
|
||||
Manifest documents, a term from OrbitDB, describe some unique dynamic content.
|
||||
Manifests are immutable and contain information like the protocol and parameter used.
|
||||
|
||||
This document format is not formally specified, but included below is a specification for this article:
|
||||
|
||||
**dag-cbor**
|
||||
```js
|
||||
// cbor type reference: https://www.rfc-editor.org/rfc/rfc8949.html#section-3.1
|
||||
{
|
||||
protocol: type 3
|
||||
param: type 5
|
||||
}
|
||||
```
|
||||
|
||||
`protocol`: a text string field containing a protocol id
|
||||
|
||||
`param`: a key value map for exclusive use by the `protocol`
|
||||
|
||||
```js
|
||||
// takes description of the dynamic content (protocol + params)
|
||||
// returns manifest (Block) and dynamic-content id (CID)
|
||||
export async function DynamicContent (
|
||||
{ protocol, param }: { protocol: string, param: any }
|
||||
):
|
||||
Promise<{ id: CID, manifest: BlockView }>
|
||||
{
|
||||
|
||||
// create manifest
|
||||
const manifest = await Block.encode({ value: { protocol, param }, codec, hasher })
|
||||
|
||||
// create dcid
|
||||
const dynamic = new TextEncoder().encode('dynamic')
|
||||
const bytes = new Uint8Array(dynamic.length + manifest.cid.multihash.digest.length)
|
||||
bytes.set(dynamic)
|
||||
bytes.set(manifest.cid.multihash.digest, dynamic.length)
|
||||
const dcid = CID.create(
|
||||
manifest.cid.version,
|
||||
manifest.cid.code,
|
||||
await hasher.digest(bytes)
|
||||
)
|
||||
|
||||
return { id: dcid, manifest }
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Above is a code block from the example attached to this article.
|
||||
It shows a manifest document "describing" the dynamic content using the `protocol` and `param` properties.
|
||||
It also shows the DCID derived from the manifest's CID.
|
||||
|
||||
<br/>
|
||||
|
||||
## Use-case: Edge-computed Applications
|
||||
|
||||
This design is particularly useful when paired with local-first databases.
|
||||
These databases are partitioned (a.k.a. sharded) to only the interested parties.
|
||||
It's common for only a few collaborators to be a part of a database, and there may be long periods without any of them online.
|
||||
This context makes it challenging to build upon the history of collaborators, a challenge this design can potentially solve.
|
||||
|
||||
### Edge Devices
|
||||
|
||||
- Handle application logic and merging of replicas from other collaborators.
|
||||
- Consist of a network of potentially unreliable peers that may come online and go offline at various times.
|
||||
- Ensure the application history is available by commanding pinning servers.
|
||||
|
||||
### Pinning Servers
|
||||
|
||||
- Reliable storage servers that keep dynamic content available on IPFS.
|
||||
- Pin IPLD replicas, and refresh IPNS and Provider Records for clients.
|
||||
- Execute no app-specific code
|
||||
|
||||
### Replication
|
||||
|
||||
The design presented in this article is a replication protocol.
|
||||
However, it is not a real-time replication protocol.
|
||||
Applications with real-time features should include an app-specific replication protocol for use with other online collaborators.
|
||||
Combining two replication protocols with these properties results in preserved and real-time P2P applications.
|
||||
|
||||
---
|
||||
> **Pinning servers, in this context, provide a general and reliable replication layer to fall back on when no other collaborators are online.**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
## Roadblocks and Workarounds
|
||||
|
||||
It should be clear now that using Provider Records this way was not intended.
|
||||
This brings us to the roadblock...
|
||||
|
||||
### No 3rd Party Publishing to DHT
|
||||
|
||||
[DHT servers validate that the PeerIDs inside received Provider Records match the PeerID of the node adding them.](https://github.com/libp2p/specs/tree/master/kad-dht#rpc-messages)
|
||||
|
||||
This check makes adding Provider Records for multiple PeerIDs to the DHT difficult.
|
||||
Not great if you want to participate in multiple pieces of dynamic content as each will require its own IPNS name.
|
||||
A Libp2p node may only add its own PeerId as a provider. This PeerId is also known as the "self" key.
|
||||
|
||||
There are two workarounds for now:
|
||||
|
||||
1. Use the "self" key for IPNS, and have it point to a CID for a map(DCID -> root replica CID) for all relevant dynamic content.
|
||||
2. Spin up *ephemeral* libp2p nodes to refresh each IPNS name as a provider every [22hours](https://github.com/libp2p/specs/tree/master/kad-dht#content-provider-advertisement-and-discovery).
|
||||
|
||||
### No Delegated Refreshing of IPNS OR Provider Records
|
||||
|
||||
Delegated publishing of IPNS and Provider Records is necessary to realize the edge-computed applications use case.
|
||||
Unfortunately, there are no official plans to add this feature.
|
||||
|
||||
<br/>
|
||||
|
||||
## Example
|
||||
|
||||
---
|
||||
> **USES HELIA 😲🤩 !!!! DHT IN 😵💫 JAVASCRIPT 😵💫 😵 !! DYNAMIC CONTENT ON IPFS!?🧐!?**
|
||||
---
|
||||
|
||||
This example shows dynamic-content replication using IPLD, IPNS, and Provider Records. There are 3 [helia](https://github.com/ipfs/helia) (IPFS) nodes running in a single script, named `client1`, `client2`, and `server`. `client1` and `client2` dial `server` and use the `/ipfs/kad/1.0.0` protocol. After dialing, clients can add IPNS and Provider records to the DHT server. Clients also add IPLD data to `server` programmatically.
|
||||
|
||||

|
||||
|
||||
---
|
||||
> **`client1`, `client2`, and `server ` are all in memory Helia nodes created by a single script.**
|
||||
|
||||
> **IPLD data is added to the server by clients by accessing `server.blockstore.put` from within the script (programmatically). As opposed to using an HTTP API like in any real use-case.**
|
||||
---
|
||||
|
||||
### Usage
|
||||
|
||||
- Requires [npm and Node v18](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
|
||||
|
||||
#### Clone the Repo
|
||||
|
||||
`git clone https://github.com/tabcat/dynamic-content.git`
|
||||
|
||||
#### Install Packages
|
||||
|
||||
`npm install`
|
||||
|
||||
#### Run Examples
|
||||
|
||||
There are two example scripts. One is interactive, meaning after the example runs, a REPL starts with global variables available to operate the replication manually.
|
||||
|
||||
The scripts are `npm run example` and `npm run interactive`.
|
||||
|
||||
**If something is broken please open an [issue](https://github.com/tabcat/dynamic-content/issues)!**
|
||||
|
||||
<br/>
|
||||
|
||||
### What's Happening?
|
||||
|
||||
The example consists of 3 [Helia](https://github.com/ipfs/helia) nodes, named `client1`, `client2`, and `server`.
|
||||
The `server` represents a reliable machine used as a
|
||||
|
||||
1. IPLD pinning server
|
||||
2. DHT server
|
||||
|
||||
---
|
||||
> **IPNS and Provider records are both stored in the DHT.**
|
||||
---
|
||||
|
||||
The clients are unreliable machines used to read and write dynamic content.
|
||||
In the example, `client1` does all the writing, and `client2` does all the reading.
|
||||
|
||||

|
||||
|
||||
<br/>
|
||||
|
||||
This is a very high overview of what's going on.
|
||||
Remember, this design uses only IPLD/IPNS/Provider Records.
|
||||
It may be helpful to read [index.ts](./src/index.ts) (~200 LOC) for clarity.
|
||||
|
||||
### Sample Outputs
|
||||
|
||||
In case you are unable to run the example, below shows all the output that would occur:
|
||||
|
||||
<details>
|
||||
<summary>`npm run example`</summary>
|
||||
|
||||
```sh
|
||||
$ npm run example
|
||||
|
||||
> dynamic-content@1.0.0 example
|
||||
> npm run build && node dist/index.js
|
||||
|
||||
|
||||
> dynamic-content@1.0.0 build
|
||||
> tsc
|
||||
|
||||
server is pinning ipld and serving dht ipns and provider records
|
||||
client1: online
|
||||
client1: added new values to set { nerf this }
|
||||
client1: set state: { nerf this }
|
||||
client1: encoded to raw data
|
||||
client1: pushed data to pinner
|
||||
client1: published ipns:12D3KooWRzE1FNCRXuz1C8Z3G8Q5oBg3C5nhKANSsFq377P1mWVn with value cid:bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq
|
||||
client1: advertised ipns:12D3KooWRzE1FNCRXuz1C8Z3G8Q5oBg3C5nhKANSsFq377P1mWVn as set provider
|
||||
client1: offline
|
||||
|
||||
--- no peers online, Zzzzz ---
|
||||
|
||||
client2: online
|
||||
dht query returned empty response
|
||||
client2: found ipns:12D3KooWRzE1FNCRXuz1C8Z3G8Q5oBg3C5nhKANSsFq377P1mWVn as set provider
|
||||
client2: resolved ipns:12D3KooWRzE1FNCRXuz1C8Z3G8Q5oBg3C5nhKANSsFq377P1mWVn to bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq
|
||||
client2: resolved ipfs:bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq to raw data
|
||||
client2: decoded raw data
|
||||
client2: added new values to set { nerf this }
|
||||
client2: set state: { nerf this }
|
||||
client2: offline
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>`npm run interactive`</summary>
|
||||
<br/>
|
||||
|
||||
The interactive example starts a REPL after the example has run.
|
||||
|
||||
```sh
|
||||
$ npm run interactive
|
||||
|
||||
> dynamic-content@1.0.0 interactive
|
||||
> npm run build && node dist/interactive.js
|
||||
|
||||
|
||||
> dynamic-content@1.0.0 build
|
||||
> tsc
|
||||
|
||||
server is pinning ipld and serving dht ipns and provider records
|
||||
client1: online
|
||||
client1: added new values to set { nerf this }
|
||||
client1: set state: { nerf this }
|
||||
client1: encoded to raw data
|
||||
client1: pushed data to pinner
|
||||
client1: published ipns:12D3KooWQXCo6Wzw7NmJRLC2peAX7fU6gHSydEKNAJfyfXCEwHFL with value cid:bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq
|
||||
client1: advertised ipns:12D3KooWQXCo6Wzw7NmJRLC2peAX7fU6gHSydEKNAJfyfXCEwHFL as set provider
|
||||
client1: offline
|
||||
|
||||
--- no peers online, Zzzzz ---
|
||||
|
||||
client2: online
|
||||
dht query returned empty response
|
||||
client2: found ipns:12D3KooWQXCo6Wzw7NmJRLC2peAX7fU6gHSydEKNAJfyfXCEwHFL as set provider
|
||||
client2: resolved ipns:12D3KooWQXCo6Wzw7NmJRLC2peAX7fU6gHSydEKNAJfyfXCEwHFL to bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq
|
||||
client2: resolved ipfs:bafyreihypffwyzhujryetatiy5imqq3p4mokuz36xmgp7wfegnhnjhwrsq to raw data
|
||||
client2: decoded raw data
|
||||
client2: added new values to set { nerf this }
|
||||
client2: set state: { nerf this }
|
||||
client2: offline
|
||||
|
||||
--- interactive example ---
|
||||
|
||||
client1: online
|
||||
client2: online
|
||||
|
||||
Usage:
|
||||
|
||||
globals
|
||||
|
||||
help: this message
|
||||
|
||||
client1: helia client node (sender)
|
||||
client2: helia client node (receiver)
|
||||
server: helia ipld/ipns pinner and dht server
|
||||
|
||||
// compare the 2 clients sets
|
||||
set1: client1's set variable
|
||||
set2: client2's set variable
|
||||
|
||||
await connect(<client>) // connects client to server
|
||||
await disconnect(<client>) // disconnects client from server
|
||||
|
||||
await update(...<string[]>) // create and publish changes from client1 - requires client1 to be connected
|
||||
await sync() // syncs changes to client2 - requires client2 to be connected
|
||||
|
||||
>
|
||||
```
|
||||
</details>
|
||||
|
||||
---
|
||||
> **Note: in practice, the DHT queries related to the Dynamic Content's ID only need to be run initially. Afterward, a protocol meant for real-time replication with online collaborators can be used.**
|
||||
---
|
||||
|
||||
<br/>
|
||||
|
||||
## Credits
|
||||
|
||||
Big thanks to [@autonome](https://github.com/autonome), [@SgtPooki](https://github.com/sgtpooki), and [@lidel](https://github.com/lidel) for help writing this article!
|
||||
|
||||
Also thanks to [@willscott](https://github.com/willscott) for answering all my DHT questions in [#libp2p-implementers](https://app.element.io/#/room/#libp2p-implementers:ipfs.io)!
|
||||
|
||||
<br/>
|
||||
|
||||
## Get Involved
|
||||
|
||||
Sound interesting? Get involved! Come [chat](https://matrix.to/#/#hldb:matrix.org)
|
||||
|
||||
Have a question? Create an [issue](https://github.com/tabcat/dynamic-content/issues)
|
||||
|
||||
[I](https://github.com/tabcat)'m implementing this in [tabcat/zzzync](https://github.com/tabcat/zzzync)
|
||||
|
||||
<br/>
|
||||
|
||||
## FAQ
|
||||
|
||||
**Q**: Why not just share an IPNS name between devices to update?
|
||||
|
||||
**A**: IPNS names are not built to handle concurrent writes and should not be extended to do so. They are signed, versioned documents that one device should be able to update. As shown here, they are essential for creating a system that can handle concurrent writes.
|
||||
|
||||
<br/>
|
||||
|
||||
**Q**: Isn't this going to be slow?
|
||||
|
||||
**A**: This design complements real-time replication by providing a general and reliable layer to fall back to. It adds two steps on top of resolving a CID: 1) the DHT provider query and 2) the IPNS name resolutions.
|
||||
Developers must reason how to design replicas for efficient storage and replication over IPLD.
|
||||
|
||||
<br/>
|
||||
|
||||
**Q**: Provider Records do not support this use case. Could this affect DHT measurements?
|
||||
|
||||
**A**: If this use case became prevalent, it could affect DHT measurements. Using Provider Records this way would make it look like the content providers are offline because the PeerIDs are used only for IPNS.
|
||||
|
||||
<br/>
|
||||
|
||||
**Q**: Could IPNS and Provider Records be swapped out for alternatives and achieve the same goal?
|
||||
|
||||
**A**: Absolutely. The goal is to provide a general and reliable replication layer. Additionally, the more widespread the building blocks used, the more existing infrastructure can be leveraged.
|
||||
72
src/_blog/2023-http-gateways-recap.md
Normal file
72
src/_blog/2023-http-gateways-recap.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
title: 'Recap: HTTP Gateways (þing 2023)'
|
||||
description: 'A recap of the new HTTP Gateways track including summaries, links, and videos.'
|
||||
author: Will Scott
|
||||
date: 2023-05-30
|
||||
permalink: '/2023-http-gateways-recap/'
|
||||
header_image: '/http-gateways-recap.jpg'
|
||||
tags:
|
||||
- 'thing'
|
||||
- 'þing'
|
||||
- 'event'
|
||||
- 'recap'
|
||||
- 'track'
|
||||
- 'http'
|
||||
- 'gateways'
|
||||
---
|
||||
|
||||
We had a new track at IPFS Thing last month: a forum focused on HTTP Gateways. As IPFS has scaled, the interactions between IFPS and the surrounding web has also increased. IPFS lives within the web, and as the [browser track](https://blog.ipfs.tech/2023-ipfs-thing-web-track/) noted, HTTP is deeply integrated with IPFS.
|
||||
|
||||
The Gateway track looked at the specific HTTP interface that IFPS as a server provides to web clients, and how the web clients make use of that interface. There are continuing pushes to evolve the interface `/ipfs/<cid>`, but we need to understand both how these primitives should be used by higher level APIs, and how to implement them.
|
||||
|
||||
A specific focus in this track was [Project Rhea](https://pl-strflt.notion.site/Project-Rhea-decentralized-IPFS-gateway-3d5906e7a0d84bea800d5920005dfea6), a cross-cutting project in Protocol Labs to decentralize the current gateways running at [ipfs.io](https://ipfs.io) to be hosted on decentralized infrastructure. This project has led to re-evaluation of the trust relationship between clients and gateways, and the hope that we can reduce the trust and increase the decentralization of gateways even further.
|
||||
|
||||
The talks in the track presented both different models for gateways, as well as implementation details for how components of Project Rhea are built.
|
||||
|
||||
In the rest of this post I'll provide links and brief color to the sessions in the track.
|
||||
|
||||
## What is Rhea?
|
||||
|
||||
[Will](https://wills.co.tt) kicked off the day with an overview of the architecture and goals of project Rhea.
|
||||
|
||||
@[youtube](0eJd2aqqSy8)
|
||||
|
||||
## IPFS Service Worker Gateways
|
||||
|
||||
[Adin](https://github.com/aschmahmann) demonstrated how web clients can reach origin IPFS hosts directly through protocols like webtransport and webRTC. The increasingly complete libp2p stack along with HTTP-compatible services like IPNI are bringing us to a reality where the HTTP gateways become less critical in bridging IPFS support directly to end web users.
|
||||
|
||||
@[youtube](MRIyWXy0ZRc)
|
||||
|
||||
## Web3 CDN Saturn accelerates IPFS & Filecoin retrievals
|
||||
|
||||
Alex Kinstler provided an overview of Saturn as a decentralized CDN and described the service it can provide as a basis for Rhea and as a platform that can host the ipfs.io IPFS gateway.
|
||||
|
||||
@[youtube](f9iUTLtPtKY)
|
||||
|
||||
## Self-hosting IPFS Gateway with bifrost-gateway
|
||||
|
||||
[Lidel](https://github.com/lidel) walked through the architecture of `bifrost-gateway`, a new IPFS implementation that acts as a 'trust gateway'. This component, built for Rhea, provides an HTTP gateway interface compatible with the current gateways which can fetch data from remote nodes via self-verifying car files.
|
||||
|
||||
@[youtube](xhJPz_efAQE)
|
||||
|
||||
## Introduction to Caboose
|
||||
|
||||
[Aarsh](https://github.com/aarshkshah1992/) dove into a 'thick client' for Saturn called Caboose that allows Saturn clients to make requests to close nodes in order to optimize performance of the CDN. In the Rhea use case, Caboose both allows for and improves fraud detection, as well as enabling faster switch-over in the case of a node going down.
|
||||
|
||||
@[youtube](z7a9E735l3Y)
|
||||
|
||||
## Testing Your IPFS Gateway Implementation: A Step-by-Step Guide
|
||||
|
||||
[Piotr](https://github.com/galargh) offered a framework for testing whether an IPFS gateway implementation works as expected. This conformance testing can improve our confidence that new implementations will be compatible with existing applications, and it is much less implementation-specific than previous testing frameworks.
|
||||
|
||||
@[youtube](PmIf77thO_c_)
|
||||
|
||||
## Live CDN Incentives and its Future
|
||||
|
||||
[Claudia](http://w.laudiacay.cool/) sent us off with a great dive into how incentives can be built for a retrieval market CDN. She described how existing primitives can be linked together to support a high performance decentralized CDN that is incentive-aligned with serving content well and quickly.
|
||||
|
||||
@[youtube](yrrAjR03TsU)
|
||||
|
||||
## Conclusion
|
||||
|
||||
I hope this overview of the HTTP Gateways track was helpful for those who couldn't attend IPFS Thing 2023 or for those who did attend but need a refresher. Next year we hope to take this new content track to the next level!
|
||||
32
src/_blog/2023-introducing-lassie.md
Normal file
32
src/_blog/2023-introducing-lassie.md
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
title: Introducing Lassie - a retrieval client for IPFS and Filecoin
|
||||
description: 'An overview of the content tracks that the community will convene around during IPFS Thing 2023.'
|
||||
author: Brenda Lee
|
||||
date: 2023-4-6
|
||||
permalink: '/2023-introducing-lassie/'
|
||||
header_image: '/Lassie.png'
|
||||
tags:
|
||||
- 'filecoin'
|
||||
- 'retrieval'
|
||||
---
|
||||
|
||||
We’re excited to share that you can now use a simple retrieval client, named [Lassie](https://github.com/filecoin-project/lassie), to get your data from IPFS and Filecoin. Lassie makes it easy to fetch your data from both the IPFS and Filecoin Network - it will find and fetch content over the best retrieval protocols available.
|
||||
|
||||
For end users and clients, this means you can easily retrieve your content addressed data (using CIDs) from IPFS or Filecoin using the Lassie client, without having to run your own IPFS node or Filecoin node. Simply download the Lassie binary and start retrieving your data with the simple command -
|
||||
|
||||
```jsx
|
||||
lassie fetch <your CID here>
|
||||
```
|
||||
|
||||
In addition to using Lassie directly to retrieve end user content, application developers can leverage Lassie as a library to fetch content from IPFS and Filecoin directly from within an application. Currently, the Saturn Network (a Web3 CDN in Filecoin’s retrieval market) is using Lassie to retrieve data from IPFS and Filecoin.
|
||||
|
||||
Learn more about Lassie with these resources:
|
||||
|
||||
- Github: [https://github.com/filecoin-project/lassie](https://github.com/filecoin-project/lassie)
|
||||
- Overview: [Basic Retrieval](https://docs.filecoin.io/basics/how-retrieval-works/basic-retrieval/)
|
||||
- Technical documentation: [https://github.com/filecoin-project/lassie/tree/main/docs](https://github.com/filecoin-project/lassie/tree/main/docs)
|
||||
- Ask questions: #retrieval-help in [Filecoin slack](https://www.notion.so/54fffa1b90ff4f6180586e79ff11ae17).
|
||||
|
||||
Special thanks to all who have paved the way building out prior retrieval clients ([w3rc](https://github.com/ipfs-shipyard/w3rc), [filclient](https://github.com/application-research/filclient)).
|
||||
|
||||
We encourage you to try this out and share with others who want to retrieve content from Filecoin or IPFS, and look forward to hearing your feedback. You can find us on [Github](https://github.com/filecoin-project/lassie) or #retrieval-help in [Filecoin slack](https://www.notion.so/54fffa1b90ff4f6180586e79ff11ae17).
|
||||
30
src/_blog/2023-introducing-the-ecosystem-working-group.md
Normal file
30
src/_blog/2023-introducing-the-ecosystem-working-group.md
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Introducing the IPFS Ecosystem Working Group
|
||||
description: 'Nurturing a vibrant and sustainable IPFS ecosystem.'
|
||||
author: The Ecosystem Working Group
|
||||
date: 2023-09-05
|
||||
permalink: '/2023-introducing-the-ecosystem-working-group/'
|
||||
header_image: ''
|
||||
tags:
|
||||
- 'Ecosystem'
|
||||
- 'Working Group'
|
||||
---
|
||||
|
||||
Since its initial release over 9 years ago, IPFS has been stewarded by a variety of teams and individual contributors, both within and outside of Protocol Labs. More recently though, it has lacked a dedicated team focused on nothing other than the success of the IPFS ecosystem. It is with this reality in mind that we are excited to announce the formation of **the brand new IPFS Ecosystem Working Group!**
|
||||
|
||||
At launch, the IPFS Ecosystem WG consists of Protocol Labs contributors, but we are forming with the explicit purpose of spinning out into our own independent entity over the coming months. We believe that this working group and its autonomy will be critical in helping propel IPFS toward a better and even brighter future.
|
||||
|
||||
Initially, we have four core goals:
|
||||
|
||||
1. Foster a thriving ecosystem by advocating for IPFS,
|
||||
2. Build bridges between IPFS and other ecosystems that could benefit from content addressing,
|
||||
3. Grow the community and develop strong and durable community ownership of the IPFS project as a public good, and
|
||||
4. Spin out from Protocol Labs into a self-sustaining organization that can support the IPFS community and build robust, effective governance for the protocol.
|
||||
|
||||
The future of IPFS requires greater degrees of decentralization, so you can expect other IPFS-focused teams to begin spinning out from Protocol Labs in the future as well.
|
||||
|
||||
As we continue to make progress towards these goals, we will provide updates and work in the open so as to keep the entire community in-the-loop with what we’re doing. A thriving ecosystem requires care and attention, and we believe that this new initiative and nimble team will be able to deliver on exactly that. But our work is only part of the story: community ownership means that your voice as IPFS users, operators, or contributors needs to be heard just as much as ours.
|
||||
|
||||
So if you have comments, questions, or concerns, then please join the discussion in the comments section below, via the [Ecosystem section of the IPFS Forums](https://discuss.ipfs.tech/c/communities/ecosystem/15), or the various chat links that follow – together let’s work on making IPFS thrive!
|
||||
|
||||
[Forums](https://discuss.ipfs.tech/c/communities/ecosystem/15) | [Discord](https://discord.com/channels/806902334369824788/1146489977174233098) | [Slack](https://filecoinproject.slack.com/archives/C05PGBP697E) | [Matrix](https://app.element.io/#/room/#ipfs-ecosystem:ipfs.io)
|
||||
85
src/_blog/2023-ipfs-companion-MV3-update.md
Normal file
85
src/_blog/2023-ipfs-companion-MV3-update.md
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
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).
|
||||
46
src/_blog/2023-ipfs-connect-istanbul.md
Normal file
46
src/_blog/2023-ipfs-connect-istanbul.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
title: Announcing IPFS Connect Istanbul 2023
|
||||
description: 'Join the IPFS Community for a full day of workshops, lightning talks, and demos showcasing technology, tools, and innovative projects in the IPFS ecosystem.'
|
||||
date: 2023-09-20
|
||||
header_image: '/ipfsconnect2023.jpg'
|
||||
tags:
|
||||
- events
|
||||
---
|
||||
|
||||
**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.
|
||||
|
||||
## Present to a large community of builders at IPFS Connect
|
||||
|
||||
We're planning a full day of talks & workshops to prepare and inspire builders from around the globe that are attending Devconnect. This includes large ecosystems and communities that rely on and integrate with IPFS, as well as individual builders joining to hack at ETHGlobal Hackathon that starts the day after IPFS Connect.
|
||||
|
||||
### Presentation & Workshop Types
|
||||
- Lightning talks & demos: short talks presenting your service, code, or app, designed to inspire, get signups, or talk about how you built it using IPFS.
|
||||
- Workshops: we have 2 dedicated workshop spaces that will be running all day. Run a workshop session with attendees walking through your -solution so they're ready to hack the next day.
|
||||
- Discussion: run a collaborative discussion on topics of interest - privacy, self hosting, devops best practices, decentralized data compliance, etc.
|
||||
- Full talks: present in one of two theater spaces, with professional video recording. We want to hear about your technical how-to, user stories, and other talks that inspire and educate.
|
||||
|
||||
Speakers receive a free ticket to the event, as well as discount codes to invite their community
|
||||
|
||||
<a href="https://cfp.ipfsconnect.org/ipfsconnect-istanbul/cfp" class="cta-button">Submit a presentation or proposal</a>
|
||||
|
||||
## Attend and connect with other community members
|
||||
|
||||
Tickets for IPFS Connect are on sale now, so you can register and buy early bird tickets to get full access to the day's events and opportunities: [https://istanbul2023.ipfsconnect.org](https://istanbul2023.ipfsconnect.org)
|
||||
|
||||
<a href="https://istanbul2023.ipfsconnect.org" class="cta-button">Register today</a>
|
||||
|
||||
## Sponsor the event to reach your target audience
|
||||
|
||||
You can learn more about multiple sponsorship opportuntities [via the sponsor deck here.](https://docs.google.com/presentation/d/1UMbRP5pYHDL5TluzBWUuqlo6DB6F1G8bgUZhMa_w_Pc/view#slide=id.p)
|
||||
|
||||
**Developers:**
|
||||
- Beginners to experts in IPFS
|
||||
- Interested in adding IPFS to their Web3 stacks so that dapp front ends are decentralized and want to use off-chain files and data to build more usable apps
|
||||
|
||||
**Startups, DAOs, Sovereign Chains:**
|
||||
- Select technology and service providers building on the IPFS tech stack combined with other Web3 components
|
||||
- Exploring novel use cases for IPFS including provenance, computation, identity, and more
|
||||
|
||||
<a href="https://docs.google.com/presentation/d/1UMbRP5pYHDL5TluzBWUuqlo6DB6F1G8bgUZhMa_w_Pc/view#slide=id.p" class="cta-button">Learn more about sponsoring</a>
|
||||
20
src/_blog/2023-ipfs-on-bluesky.md
Normal file
20
src/_blog/2023-ipfs-on-bluesky.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: IPFS is now on Bluesky!
|
||||
description: 'We’re excited to share that IPFS now has an official presence on Bluesky, a new decentralized social network that recently spun out of Twitter.'
|
||||
author:
|
||||
date: 2023-04-17
|
||||
permalink: '/2023-ipfs-on-bluesky/'
|
||||
header_image: '/2023-ipfs-on-bluesky.png'
|
||||
tags:
|
||||
- 'social media'
|
||||
---
|
||||
|
||||
We’re excited to share that [IPFS now has an official presence on Bluesky](https://staging.bsky.app/profile/ipfs.tech), a new decentralized social network that recently spun out of Twitter. Powered by the in-development [AT Protocol](https://atproto.com/), Bluesky aims to be a Twitter-like social media client that provides the benefits of interoperation, account portability, and algorithmic choice.
|
||||
|
||||
Up until now, IPFS has only had an official social media presence on Twitter. As the landscape of social media continues to change dramatically, we believe having a presence in more than just one place will be beneficial to the IPFS community, ecosystem, and brand.
|
||||
|
||||
We chose to join Bluesky because it shares many of the [same values and goals](https://specs.ipfs.tech/architecture/principles/) that the IPFS ecosystem has. Additionally, the [AT Protocol](https://atproto.com/) actively utilizes [IPLD](https://ipld.io/) and [content addressing](https://docs.ipfs.tech/concepts/how-ipfs-works/#subsystems-overview). The CEO of Bluesky, Jay Graber, even [gave a talk at IPFS Camp 2022 about Bluesky](https://www.youtube.com/watch?v=jGbBZbl-V8Y) that can be watched below, and her blog post about self-certifying protocols is referenced on the [IPFS Principles](https://specs.ipfs.tech/architecture/principles/#self-certifying-addressability) web page.
|
||||
|
||||
@[youtube](jGbBZbl-V8Y)
|
||||
|
||||
It’s still very early days at Bluesky (and it’s still in private beta), but it has shown early promise in solving some of the critical problems the social web has been plagued with. If you’re on Bluesky and want to keep up with IPFS there, [then give the new profile a follow @ipfs.tech](https://staging.bsky.app/profile/ipfs.tech)!
|
||||
88
src/_blog/2023-ipfs-thing-community-governance.md
Normal file
88
src/_blog/2023-ipfs-thing-community-governance.md
Normal file
@@ -0,0 +1,88 @@
|
||||
---
|
||||
title: 'Recap: Community & Governance (þing 2023)'
|
||||
description: 'A recap of the Community & Governance track including summaries, links, and videos.'
|
||||
author: Boris Mann and Robin Berjon
|
||||
date: 2023-05-23
|
||||
permalink: '/2023-ipfs-community-governance/'
|
||||
header_image: '/community-governance-recap.jpg'
|
||||
tags:
|
||||
- 'thing'
|
||||
- 'þing'
|
||||
- 'event'
|
||||
- 'recap'
|
||||
- 'track'
|
||||
- 'community'
|
||||
- 'governance'
|
||||
---
|
||||
|
||||
Governance and community are two ideas that vibe like they wouldn't live in the same part of town if their lives dependended on it. Community is warm, fun, and fuzzy if probably chaotic and occasionally infuriating, whereas governance sounds a lot more like flossing, something dry and painful that you pretend your project does to make the Serious People go away. But much like the predictable transition from misunderstanding to mutual respect in a buddy movie, these two were destined to form just the dynamic duo we need to take on insuperable odds. Community is the for and by of governance, and, quite frankly, the exercize of governance is messy, chaotic, and a crucible from which new, more resilient communities emerge.
|
||||
|
||||
The full-day Community & Governance track that brought us together at IPFS Þhing 2023 (which you can [watch in its entirety](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTIFbOVO5YfXkoFg6wIGbBN)) had all of that energy and then some. We spent the time bouncing back and forth between how to prevent capture by lumbering megacorporations and how to gather friends for a nice community café, what's a data protection officer and better ways to herd cats, ways of protecting people from some of the worst content on the Internet while supporting censorship-resistance and how to support commons and community ownership. It was a ride and a delightful one too.
|
||||
|
||||
Perhaps the core issue that brought us together across the diverse presentations was that we want to learn from the mistakes of the past and organize the community so that we can bring about a better world. It's not the worst plan.
|
||||
|
||||
## Memory in Uncertainty
|
||||
|
||||
"*Is that an elaborate way of saying everything's fucked?*" That might not be your typical audience question but then this wasn't your typical presentation either (or your typical audience, for that matter).
|
||||
|
||||
Cade Diehm is one of the brains behind [*The New Design Congress*](https://newdesigncongress.org/) (NDC), a research organization that practices "*ethical red teaming*" to identify issues with sociotechnical systems. [WebRecorder](https://webrecorder.net/) and [the Filecoin Foundation](https://fil.org/) hired NDC to take an in-depth look at web archiving (on IPFS) to help identify problems. Cade came to IPFS þing to udpate the community on his findings, which are captured in the [Memory in Uncertainty: Web Preservation in the Polycrisis](https://members.newdesigncongress.org/memory-in-uncertainty-web-preservation-in-the-polycrisis/) report.
|
||||
|
||||
"*The answer,*" Cade told us, "*is: 'kind of.'*" He gave a wide-ranging presentation ranging over the dangers of decentralized technology, the complexity of archives, the challenges presented by the potential weaponization of data, and much more. It provided a powerful call to take the impact of our tech seriously and to keep in mind that tech can only be ethical if it is governed by the people it impacts. Cade concluded with a set of tools to help avoid bad outcomes, because "*not everything is screwed.*"
|
||||
|
||||
@[youtube](TdiQGXSZmCk)
|
||||
|
||||
## Community Organizing
|
||||
|
||||
For all that remote work and online collaboration have improved, it's hard to have a strong and durable sense of community without meeting people in the flesh now and then. Thankfully, we have many gatherings to look forward to this year!
|
||||
|
||||
[Vukasin Vukoje](https://twitter.com/wukoje) made a surprise announcement of a new event series: Compute Camp. Details will be released more fully soon, but the first edition of this series dedicated specifically to distributed compute will take place later this year in Belgrade, Serbia. If you care more about doing things to data and less about where it's stored, this might just be the place for you.
|
||||
|
||||
Yuni Graham and Niki Gokani walked us through the organization of IPFS Camp, which will take place in November in Bangalore. We worked together to figure out what the best structure and content for the event would be. They're looking for volunteers to be part of the content planning work — please consider reaching out if you're interted!
|
||||
|
||||
@[youtube](U5u54jwOg6k)
|
||||
|
||||
And if what you're looking for is a more local IPFS-focused event, why not run your own? Yuni Graham and Nicole Schafer presented IPFS + Friends Café, a collection of local community gatherings to help develop an IPFS community on the ground, around the world. If you're iunterested, they might be able to sponsor such an event as well as assist with logistics and finding some speakers. It would be wonderful to see more local evangelism!
|
||||
|
||||
@[youtube](FII_9VTgDy8)
|
||||
|
||||
## Cat Herding
|
||||
|
||||
A growing community is a blessing, but keeping up with everything that is happening can become overwhelming. Several sessions provided us with both updates and tools to stay on top of future updates.
|
||||
|
||||
Henrique Dias (aka [@hacdias](https://twitter.com/hacdias)) walked us through [specs.ipfs.tech](https://specs.ipfs.tech/), the hot new place to get IPFS specifications. Not all of the IFPS specs have been moved there yet, but they're in the process of being ported over and everything new will be on the specs site from the get-go. This site is intended to grow into the one-stop-shop reference for IPFS implementations, ideally reaching the point at which one could produce an IPFS implementation from scratch using those documents alone (along with the emerging test suite, of course).
|
||||
|
||||
@[youtube](vQVnjEIPuCE)
|
||||
|
||||
At last year's þing in Iceland, the IPIP (IPFS Improvement Process) process was announced. The indefatigable @lidel walked us through all of the IPIP work that has happened since, and it's a lot! Initially announced as a lightning talk, this was more of a twenty minute presentation at lightning speed.
|
||||
|
||||
Keep in mind that this process is open to anyone in the community (and if you're reading this that means *you*). There is an [IPIP Pipeline GitHub project](https://github.com/orgs/ipfs/projects/19) that maintains an up-to-date status of all IPIPs, and the IPIPs get discussed on the [IPFS Implementers Working Group](https://lu.ma/ipfs-implementers). More generally, the [IPFS Community Calendar](https://lu.ma/ipfs) keeps track of the various meetings and events in which the evolution of the IPFS stack gets discussed.
|
||||
|
||||
@[youtube](WcHlV6sQuDI)
|
||||
|
||||
But then again, specs are only one corner of IPFS, and IPFS one corner of a bigger family of technologies. Staying on top of everything that is happening in *\[gestures vaguely around]* this space remains daunting. One novel tool that is already helping people get a clearer sense of what's happening (and that you can use as well) is [Starmap](https://starmap.site/). The core principle of Starmap is very simple: by structuring your GitHub issues according to very simple conventions, you can create a nested tree of issues that spans any arbitrary set of repositories and see all of those organized in a single Starmap.
|
||||
|
||||
The idea is that people should be organizing and coordinating code whichever way they see fit, but it should be possible to obtain an overview of the status of a progress across all of its components nevertheless. One example is the [Kubo/Boxo 2023Q2/Q3 items](https://starmap.site/roadmap/github.com/ipfs/kubo/issues/9817#list).
|
||||
|
||||
Bastien Dehaynin from Fission provided us with a clear and exciting overview and demo of the system. Several people in the room were already users, and there was definite interest in getting a Starmap for specs.
|
||||
|
||||
@[youtube](_HoLDQreF28)
|
||||
|
||||
## Governance
|
||||
|
||||
In order to keep IPFS and its broader ecosystem pushing in a direction that benefits all people, to support impactful collective action and ownership, and to avoid it being captured by larger players, we need to deploy matching governance capabilities. Your friendly here authors, Boris Mann and Robin Berjon, ran a workshop on "What Should We Governance?" with the goal of surfacing risks and pain points regarding governance of the IPFS ecosystem. This produced a lot of very valuable input, yet we feel like we have barely scratched the surface.
|
||||
|
||||
@[youtube](svqlHO3K_RQ)
|
||||
|
||||
Our dynamic duo then split their color-coordinated purple outfits, first with Boris discussing the allocation of funding for code and other community work, and suggesting that it would be great to use Starmap to find which parts of a project are most in need of funding.
|
||||
|
||||
@[youtube](PysiACKo1dI)
|
||||
|
||||
And then Robin talked about the ongoing work in the [Decent Data Compliance WG](https://github.com/DDC-WG) where parties from across the decentralized world are working together to figure out how to manage "[bad bits](https://badbits.dwebops.pub/)", how to protect operators from serving some of the worst content on the Internet (or simply things they don't want to host), and how to make sure that people's privacy rights are respected. There's a lot of work to be done, but it's heartening to see that people are taking these issues seriously.
|
||||
|
||||
@[youtube](bIlji91KEFQ)
|
||||
|
||||
## Where Next?
|
||||
|
||||
The day made it clear that there is strong interest in community and governance in the IPFS universe, and you can expect to hear a lot more on this side of things. While different aspects of these concerns have places where people can gather to discuss them (as seen in the links sprinkled above), overall coordination and cooperation around governance in the decent(ralized) world remains limited. We joked that we might need a "Working Group Working Group" to provide lightweight support for all the community working groups that keep emerging and help them work together. But the feedback was that it might not actually be such a joke of an idea.
|
||||
|
||||
Stay tuned!
|
||||
92
src/_blog/2023-ipfs-thing-recap-content-routing.md
Normal file
92
src/_blog/2023-ipfs-thing-recap-content-routing.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
title: 'Recap: Content Routing (þing 2023)'
|
||||
description: 'A recap of the Content Routing track including summaries, links, and videos.'
|
||||
author: Masih Derkani
|
||||
date: 2023-05-15
|
||||
permalink: '/2023-ipfs-thing-content-routing-track/'
|
||||
header_image: '/ipfs-thing-2023-recap/content-routing/content-routing-recap-slides.png'
|
||||
tags:
|
||||
- 'thing'
|
||||
- 'þing'
|
||||
- 'event'
|
||||
- 'recap'
|
||||
- 'track'
|
||||
- 'content'
|
||||
- 'routing'
|
||||
---
|
||||
|
||||
The term "content" is ubiquitous in discussions about knowledge sharing, regardless of the platform used. IPFS takes this term to a new level by defining content as an immutable piece of information, identified by a cryptographic hash that defines its identity. Any change in the information results in a different identity, making the content immutable. This property has a subtle yet powerful advantage: a receiver of a piece of information can verify its authenticity based on its identifier. This simple concept leads to an important question: how can one locate shared content using its identity? 🤔 This is where "Content Routing" comes in.
|
||||
|
||||
Content Routing is the crucial first step in exchanging content within the IPFS network. Once a Content Identifier (CID) is generated from a piece of information, Content Routing enables the information to be both discoverable and discovered. In other words, it involves telling the network, "Hey, I have content, and here is its CID," as well as answering peer questions such as "Who has this CID?".
|
||||
|
||||
This seemingly simple yet paramount functionality enables the network to share immutable and verifiable pieces of information. Since the inception of IPFS as a protocol, Content Routing has taken various forms and utilized several techniques to fulfill its promise of sharing knowledge. It remains an essential component of the IPFS ecosystem, as evidenced by its dedicated track at IPFS þing 2023 in Brussels, Belgium, last month.
|
||||
|
||||
At IPFS þing 2022 a year ago, Content Routing was divided into two tracks: [Privacy](https://www.youtube.com/watch?v=VLU44qtXypE&list=PLuhRWgmPaHtTegfLTVFYtTtqTKQEtDvxW) and [Performance](https://www.youtube.com/watch?v=AWbobt9oHZ0&list=PLuhRWgmPaHtSF3oIY3TzrM-Nq5IU_RTXb). This year, both tracks were combined into one glorious Content Routing track that covered both areas. We had the privilege of hosting talks from community leaders who discussed the impressive improvements in performance and scalability of content routing systems, the privacy preservation techniques that cut across different systems, as well as community call-outs and discussions on how to get involved and build a better decentralized web together.
|
||||
|
||||
The track offered a comprehensive view of the content routing evolution since the inception of IPFS and showcased the latest advancements in the IPFS ecosystem. It provided an overview of the [InterPlanetary Network Indexer (IPNI)](https://github.com/ipni) and explained how it enables the mass publication and lookup of content across hundreds of billions of CIDs. The latest developments in reader privacy preservation, a mechanism that allows private lookups of content on both the IPFS DHT and IPNI, were also presented.
|
||||
|
||||
The rest of this blog post offers highlights, links, and a brief commentary on the talks.
|
||||
|
||||
The full playlist of talks at the IPFS þing 2023 Content Routing track can be found [here](https://www.youtube.com/watch?v=oe7fjOl-q0s&list=PLuhRWgmPaHtRBWV3SvInC5ATS8aKV3lsW). To learn more about Content Routing, check out the previous tracks at [IPFS Camp 2022](https://www.youtube.com/watch?v=7nb5oEpURCU&list=PLuhRWgmPaHtRqhFZ-CAstJ0RIq7Vs-4eO) and the [IPFS YouTube channel](https://www.youtube.com/@IPFSbot/playlists).
|
||||
|
||||
## Content Routing Track Introduction by Masih Derkani
|
||||
|
||||
[Masih](https://derkani.org/) presented an overview of Content Routing as a concept, its evolution over time, along with the evolutionary trends of content routing in the IPFS ecosystem. The talk illustrated what routing content in the IPFS network looks like today and explained how the mesh of content providers of different sizes interconnects. It also showcased the sub-systems that enable content routing to "just work", regardless of where the data resides.
|
||||
|
||||
@[youtube](oe7fjOl-q0s)
|
||||
|
||||
## Opening the DHT to large content providers by Guillaume Michel
|
||||
|
||||
How does a 1M x reduction in opened connections sound? That's right, providing data via the DHT is becoming much more efficient for large content providers thanks to "regions". [Gui](https://github.com/guillaumemichel) presented the latest research on how the DHT key space can be divided across regions to reduce the number of connections as well as messages sent to make content discoverable via the IPFS DHT.
|
||||
|
||||
@[youtube](bXaL64fp55c)
|
||||
|
||||
## IPNI: the InterPlanetary Network Indexer by Masih Derkani
|
||||
|
||||
Talking of large content providers, IPNI, the InterPlanetary Network Indexer, is an alternative routing system designed from scratch to provide content by the bucket load. [Masih](https://derkani.org/) presented how IPNI achieves this by betting on storage becoming cheaper and using replicas to reduce the need for trust to provide single hop lookup for trillions of CIDs. He explained how IPNI handles changes in the subset of CIDs advertised by content providers in a super-efficient protocol. IPNI as a concept has been around for about a year; it is the same protocol that makes FileCoin content discoverable over the IPFS network. As a protocol, it has now grown large enough to deserve its own "InterPlanetary" acronym and a growing set of [specifications](https://github.com/ipni/specs).
|
||||
|
||||
@[youtube](_EDJXeDtcX4)
|
||||
|
||||
## cid.contact: one year on by Masih Derkani
|
||||
|
||||
Having made the distinction between "protocol" and "implementation", [Masih](https://derkani.org/) presented a second talk on [`cid.contact`](https://cid.contact), the largest most mature IPNI cluster. `cid.contact` is built into [Kubo](https://github.com/ipfs/kubo) as a default routing system since version [`0.18.0`](https://github.com/ipfs/kubo/releases/tag/v0.18.0) and is the content router of choice for [Lassie](https://youtu.be/d5SzSm8NkUU) used by [Rhea](https://youtu.be/p89i9_AskIw). The talk covered the latest architecture of `cid.contact` and the newest features, such as cascading lookup over IPFS DHT and BitSwap, that make it a one-stop content router, tuned to find content no matter where it might be. `cid.contact` has ingested over 1.3 trillion CIDs from hundreds of providers, and just turned one this April. Happy 1st birthday! 🎂
|
||||
|
||||
@[youtube](CPlOdNqJ8og)
|
||||
|
||||
## IPFS Content Routing Workgroup, an introduction by Torfinn Olsen
|
||||
|
||||
Ever wondered where the content routers meet? 🧙 Look no further; the Content Routing Workgroup is it! [Torfinn](https://github.com/TorfinnOlsen) provided an overview of what the workgroup aims for, how community decisions are made, and how things get prioritized in the pipeline. He presented the roadmap ahead for the workgroup and invited the community to join. The workgroup meetings are public and open to all. You can find recordings of the previous meetups [here](https://www.youtube.com/watch?v=LsCH8xw3__c&list=PLuhRWgmPaHtRP5lVouK_eqhC98xaej6Px). Whether it's the next big idea you'd like to propose or just to observe what content routers get up to all day, you are most welcome.
|
||||
|
||||
@[youtube](MagS8ly_YXE)
|
||||
|
||||
## DHT ~~Double Hashing~~ Reader Privacy Updates & Migration Plan by Yiannis Psaras
|
||||
|
||||
It was at the first IPFS þing in Reykjavík where [Gui](https://github.com/guillaumemichel) presented the idea of [Double Hashing](https://www.youtube.com/watch?v=ZPIDU1-JnVc) in the context of Content Routing. Yep; we love hashes so much we're gonna do it twice! In this technique, rather than looking up a CID straight up, it is hashed again and its "double-hashed" value is the key that's used for lookup. In turn, the lookup results are then returned in encrypted form using the original CID as the encryption key. Pretty nifty, right?! Gui presented two follow-up talks on this at IPFS Camp 2022 further [explaining the core idea](https://youtu.be/VBlx-VvIZqU) and what [transitioning to it would mean for content routing](https://youtu.be/m-6_VZ8e1tk). At Brussels, [Yiannis](https://github.com/yiannisbot) walked us through the latest updates in the rollout of ~~Double Hashing~~ Reader Privacy to the IPFS DHT, one of the routing systems in use today. The initial phase of privacy preservation focuses on the "reader" side, where an external observer cannot know what a user is looking up without knowing the original CID. Later work will build on this to expand the privacy benefits to the "writer" side, i.e., content providers.
|
||||
|
||||
@[youtube](FP4kKemco4w)
|
||||
|
||||
## Double Hashing in IPNI: Reader Privacy at scale by Ivan Schasny
|
||||
|
||||
Privacy preservation is a quality that cuts right across routing systems. ✂️ This means no matter how the content is advertised or found we _want to_ preserve the user's privacy. In this talk [Ivan](https://github.com/ischasny) walked us through what this means for IPNI and how it is changing the architecture of `cid.contact` to incorporate reader privacy at its very core: `cid.contact` is moving to _only_ store encrypted provider records which means even the servers do not know what CIDs are being looked up. He expanded on how this big change is being rolled out garcefully, in stages and what's to come in the near future. Watch the [`#ipni` channel on FileCoin Slack](https://filecoinproject.slack.com/archives/C02T827T9N0) for the latest updates.
|
||||
|
||||
@[youtube](Q46zJ_mai2c)
|
||||
|
||||
## Private data: state of the art by Ian Preston
|
||||
|
||||
Taking things one step further on the privacy front, [Ian](https://peergos.org/about#ian_) and his team have been busy building privacy deep at the heart of [Peergos](https://peergos.org/). How does it work? The talk takes a deep dive into the Peergos architecture and how it utilizes `cryptree+`, BATs, and Capabilities to enable post-quantum ciphertext-level access control with improved metadata preservation and better performance. Ian walked us through the challenges they faced, such as garbage collection, and how the team overcame them to make application sandboxing a piece of cake. 🍰 As for the icing, check out Ian's slides shared right from Peergos [here](https://peergos.net/public/demo/talks/2023/ipfs-thing/private-data/web/index.html?open=true).
|
||||
|
||||
@[youtube](HVyrVUI2-RA)
|
||||
|
||||
## Content Advertisement Mirroring by Andrew Gillis
|
||||
|
||||
As the adoption of IPNI as an alternative content routing protocol continues to grow, so does the need for scaling. 🚀 At IPFS Camp 2022, [Andrew](https://github.com/gammazero) presented how IPNI is [scaling the content routing](https://youtu.be/qaCB0UKqwAk). Building on top of previous work, this talk covered how the replication of content advertisements from providers is making ingestion (and re-ingestion) 5X faster. This means new IPNI instances can use alternative sources to build up their index records with much higher velocity, moving us closer to a federated mesh of IPNI instances that continue to maintain lookup latency in orders of a few milliseconds at 10^15 scale!
|
||||
|
||||
The talk was followed by a discussion on a set of open questions as we scale the IPNI network. Take a look and get involved right from where we left off at the next Content Routing Workgroup meeting!
|
||||
|
||||
@[youtube](6l0i8DjhpLg)
|
||||
|
||||
## A Massive Shout-out
|
||||
|
||||
It's great to see the IPFS community coming together and celebrating the latest advancements in the field. A big thank you to all who attended the track at Brussels and to the speakers who presented and helped generate questions. Last but not least, a massive shout-out to the community that tirelessly drives the vision (a better web for all) forward. 🙇
|
||||
|
||||
See you on the decentralised web! ✊
|
||||
58
src/_blog/2023-ipfs-thing-recap.md
Normal file
58
src/_blog/2023-ipfs-thing-recap.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: IPFS þing 2023 Recap
|
||||
description: 'Highlights, photos, and videos from the annual gathering of the IPFS implementers community.'
|
||||
author:
|
||||
date: 2023-05-04
|
||||
permalink: '/2023-ipfs-thing-recap/'
|
||||
header_image: '/ipfs-thing-2023-recap/ipfs-2023-recap-featured-image.jpg'
|
||||
tags:
|
||||
- 'thing'
|
||||
- 'þing'
|
||||
- 'event'
|
||||
- 'recap'
|
||||
---
|
||||
|
||||
The IPFS implementers community recently came together in Brussels, Belgium for the second year of IPFS þing, an annual gathering dedicated to advancing IPFS implementation. With 12 tracks and over 75 talks, demos, and sessions, the 5-day summit that occurred in April 2023 was a showcase of recent advances across IPFS, a forum for sharing needs from the protocol, and an opportunity to chart new directions for the future of IPFS.
|
||||
|
||||

|
||||
|
||||
Over 130 participants joined for a collection of talks, workshops, discussion circles, hacking time, and many many many hallway conversations. Here are a few memorable highlights:
|
||||
|
||||
* **Operators and Deployments:** In this track, the people putting IPFS into production gathered to share their architectures, best practices, and war stories. We laughed. We cried. We looked at a LOT of graphs. Also, this track had some crazy performance numbers – we learned that IPFS can be _really_ fast. ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTYOY5l8nehP_Vt6Ek-svrp))
|
||||
* **Data Transfer:** Since the last IPFS þing, a few different teams that needed faster transfer speeds came together to form the [Move The Bytes Working Group](https://mtngs.io/ipfs/move-the-bytes-wg/). This track included an update on how things are going with the initiative and showed how IPFS can be 10x faster at getting your stuff than Web2! ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtS6WBDGK8oxcBHA6ILKatVk))
|
||||
* **Community and Governance:** IPFS is a public good. It's important that it stays that way, that it resists capture, and that it has great governance by (and for) its community. This track charted a course to broad community participation in everything from core protocol standards to planning the next IPFS Camp (no spoilers – you’ll have to watch the talks to know when and where it’s going to be!). ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTIFbOVO5YfXkoFg6wIGbBN))
|
||||
* **IPFS Gateways:** Gateways (servers that translate between HTTP and IPFS) are the biggest onramp to the IPFS network,but they’re also the biggest single point of centralization. Huge changes are happening in this area, so if you’re a gateway user or if your service links to it, then be sure to watch these videos. ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTapMgLW7rRh92Tk8u7wip5))
|
||||
* **Integrating IPFS:** IPFS is used in environments ranging from tiny IoT sensor platforms to mobile devices to satellites in space. In this track, participants learned how IPFS is being implemented in space, on mobile devices running iOS or Android, and in higher level application constructs like “accounts”! We even learned what an “ipfs run” command would look like for distributed functions. ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTI0MS6ZjSJjBxZp7rcjSS_))
|
||||
* **Content Routing:** The first step to exchange “content” over the IPFS network is to either 1) find the given content by using a Content ID (CID), or 2) publish the given content by making its CID known. The Content Routing track covered a holistic view of the content routing evolution since the inception of IPFS and showcased the latest advancements in this simple yet paramount operation in the IPFS ecosystem. This track provided an overview of the InterPlanetary Network Indexer (IPNI), and expanded on how it enables mass publication and lookup of content across hundreds of billions of CIDs. The latest developments in reader privacy preservation, a mechanism that enables private lookups of content both on the IPFS DHT and IPNI, was also presented. ([YouTube playlist](https://www.youtube.com/playlist?list=PLuhRWgmPaHtRBWV3SvInC5ATS8aKV3lsW))
|
||||
|
||||

|
||||
|
||||
IPFS þing isn’t just about getting things done though… it’s also about doing things together. Because we were in the beating bureaucratic heart of the European Union, we had to ~~flaunt the rules~~ pay respect to the culture and history of the region by visiting the [Atomium](https://atomium.be/home/Index) for dinner on one night and the [Comics Art Museum](https://www.comicscenter.net/en/home) on another. We also held a game night featuring IPFS trivia that you will never be able to guess the answers to, but you may get a chance soon by following IPFS on [Twitter (@ipfs)](https://twitter.com/ipfs) or [Bluesky (@ipfs.tech)](https://staging.bsky.app/profile/ipfs.tech)
|
||||
|
||||

|
||||
|
||||
The closing session of IPFS þing was kicked off by a rousing call to action from [Danny O’Brien](https://twitter.com/mala) highlighting the importance of daily use of IPFS software within the community. This was followed by a group retrospective on the event itself run by IPFS inventor Juan Benet, collecting feedback in real time from all attendees as input into the next one.
|
||||
|
||||

|
||||
|
||||
The event would not have been possible without the dedication of our awesome track leaders, the 75+ speakers and sessions, the 5 IPFS þing Scholars who brought their unique perspectives and experiences to the event, and of course, everyone who traveled from over 30 countries to participate. Thank you to our incredible community for making IPFS þing 2023 an amazing experience, and see you next time!
|
||||
|
||||
Check out the full list of talks on the [IPFS YouTube channel](https://www.youtube.com/@IPFSbot/playlists). You can also head directly to each track’s video playlist:
|
||||
|
||||
* [Opening Keynotes](https://www.youtube.com/watch?v=G2hlQqvjE-Y&list=PLuhRWgmPaHtRnO5G2EF0RxYebcQzLDf5F)
|
||||
* [Measuring IPFS](https://www.youtube.com/watch?v=O8Nk1FN04Q8&list=PLuhRWgmPaHtQkkbiq-PbIkt9_S2NjJz6x)
|
||||
* [IPFS Deployments & Operators](https://www.youtube.com/watch?v=bILa9sPpBMs&list=PLuhRWgmPaHtTYOY5l8nehP_Vt6Ek-svrp)
|
||||
* [Data Transfer](https://www.youtube.com/watch?v=13_zr--akhs&list=PLuhRWgmPaHtS6WBDGK8oxcBHA6ILKatVk)
|
||||
* [IPFS on the Web](https://www.youtube.com/watch?v=dn8PssXkRbY&list=PLuhRWgmPaHtQ-TO65P62tqfUM85HCIqSj)
|
||||
* [Interplanetary Databases](https://www.youtube.com/watch?v=tjSuNmCTnyU&list=PLuhRWgmPaHtTO8hr2CYiJPTSe7wybW_op)
|
||||
* [Content Routing](https://www.youtube.com/watch?v=oe7fjOl-q0s&list=PLuhRWgmPaHtRBWV3SvInC5ATS8aKV3lsW)
|
||||
* [HTTP Gateways](https://www.youtube.com/watch?v=p89i9_AskIw&list=PLuhRWgmPaHtTapMgLW7rRh92Tk8u7wip5)
|
||||
* [Decentralized Compute & AI](https://www.youtube.com/watch?v=LK9QjOJIPkQ&list=PLuhRWgmPaHtQ_lKtbTR-vIW1LYuTjcaPw)
|
||||
* [Integrating IPFS](https://www.youtube.com/watch?v=drvFcbykHYY&list=PLuhRWgmPaHtTI0MS6ZjSJjBxZp7rcjSS_)
|
||||
* [Community & Governance](https://www.youtube.com/watch?v=U2qvvQxIdws&list=PLuhRWgmPaHtTIFbOVO5YfXkoFg6wIGbBN)
|
||||
|
||||
Subscribe to the [IPFS Community Calendar](https://lu.ma/ipfs) to be the first to know about both online and in-person events, including pre-registration for our community-wide [IPFS Camp](https://lu.ma/ipfscamp23-prereg) in autumn 2023!
|
||||
|
||||

|
||||
|
||||
See you there! 🚀
|
||||
122
src/_blog/2023-thing-web-track.md
Normal file
122
src/_blog/2023-thing-web-track.md
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: 'Recap: IPFS on the Web (þing 2023)'
|
||||
description: 'Track recap with links and serious analysis for the IPFS on the Web track at IPFS þing 2023'
|
||||
author: Dietrich Ayala
|
||||
date: 2023-05-10
|
||||
permalink: '/2023-ipfs-thing-web-track/'
|
||||
header_image: '/ipfs-thing-2023-recap/ipfs-on-the-web-featured-image-2.jpg'
|
||||
tags:
|
||||
- 'thing'
|
||||
- 'þing'
|
||||
- 'event'
|
||||
- 'recap'
|
||||
- 'track'
|
||||
- 'web'
|
||||
---
|
||||
|
||||
The world wide web is both the biggest deployment vector and least controllable surface for IPFS. There are opportunities and challenges with bringing IPFS support to rendering engines, browsers, gateway-served content, web apps, and browser extensions. It is these unique dynamics that motivated us to organize a dedicated content track for them at the annual gathering of IPFS implementers known as IPFS Thing.
|
||||
|
||||
To catch you up to speed, the [*Browsers and the Web Platform* track at IPFS Thing 2022](https://2022.ipfs-thing.io/schedule/#Browsers-and-The-Web-Platform) was only a half day long with a small group of people. It had browser and gateway progress updates, some alternate visions of how a content-addressed web could work on desktop and mobile, and also some straight-up "stuff is hard still" talks. You can listen to [all of these talks](https://www.youtube.com/watch?v=_DGVa2CJjIc&list=PLuhRWgmPaHtTsL76nt_A6CPDe6lW7l6Sz) on YouTube.
|
||||
|
||||
A few months later at [IPFS *Camp* 2022](https://2022.ipfs.camp/#Browsers-Platforms) we had a similar track with many more people and the tone changed a bit — we saw more working code, and even features shipped in products that were represented, and we covered platforms outside of web, like native mobile and space. You can watch the [full playlist of videos](https://www.youtube.com/watch?v=HhCHvuP5IJo&list=PLuhRWgmPaHtQohNbRjFJDS70WoElZ8ep5) on YouTube as well.
|
||||
|
||||
This brings us to IPFS *Thing* 2023 that occurred last month. I had the privilege of broadening the lens even further than we experienced at the previous two gatherings. We examined the opportunities, challenges, products, protocols, and experiments in the intersection of these two distinct paradigms of HTTP and IPFS. This area of the IPFS ecosystem is changing so rapidly that [HTTP Gateways to the IPFS network](https://www.youtube.com/watch?v=p89i9_AskIw&list=PLuhRWgmPaHtTapMgLW7rRh92Tk8u7wip5) had a whole track to itself this year. This gave the Web track more room to move, so we were able to cover everything from naming systems to publishing pipelines and JS toolkits and more.
|
||||
|
||||
In the rest of this blog post you'll find highlights, links, and commentary from the track lead (that's me, Dietrich) on why these talks were selected and why I think they're helping make a better web for us all.
|
||||
|
||||
You can find the full video playlist for the IPFS on the Web track [here](https://www.youtube.com/watch?v=dn8PssXkRbY&list=PLuhRWgmPaHtQ-TO65P62tqfUM85HCIqSj), and I'll link each below as well.
|
||||
|
||||
## IPFS on the Web in 2023 (so far) - Dietrich Ayala
|
||||
|
||||
[Dietrich](https://metafluff.com/) gave a short overview of various initiatives and collaboration projects of the Browsers, Platforms & Standards team at Protocol Labs. It was a peek into the latest IPFS features in Brave Browser, early work into Chromium native support for IPFS, and various other work those weirdos are pushing forward.
|
||||
|
||||
@[youtube](dn8PssXkRbY)
|
||||
|
||||
## What Is The Web? - Robin Berjon
|
||||
|
||||
Good morning. Have you had a coffee yet? Ok great because you're going to need it for this talk. [Robin](https://berjon.com/) sets the perspective for the day by asking us one of the most difficult questions: "What is the web, actually?" It's big. It's special. We complain about it. But we need to have language to describe what it is in order to talk about how it could grow and change. Warning: This talk begins at a point in history over 100 years ago!
|
||||
|
||||
@[youtube](s878bm15mrk)
|
||||
|
||||
## A better web: secure, private, p2p apps with user-owned data and identity - Ian Preston
|
||||
|
||||
[Peergos](https://peergos.org/) has been building *your* private space online for half a decade, and it shows: [Ian](https://peergos.org/about#ian_) and team have built a mostly exilfiltration-proof application platform on IPFS which works in the browsers of today. The idea of web content that can't phone home might make you say "hmmm", but it could just be the antidote to the surveillance-is-required-to-pay-the-bills version of the web we have today.
|
||||
|
||||
@[youtube](mSElk2jcFqY)
|
||||
|
||||
## WNFS: Versioned and Encrypted Data on IPFS - Philipp Krüger
|
||||
|
||||
It's the web. It's p2p. It's files. It's private. It's WNFS! [Philipp](https://irreactive.com/) walks us through how the WebNative Filesystem works, and how it works in browsers specifically. It's not easy, but none of us signed up for easy. That being said, you *can* sign up to join the [WNFS Working Group](https://github.com/wnfs-wg) today after watching this talk.
|
||||
|
||||
@[youtube](LBMyRp4Ywew)
|
||||
|
||||
## Content Based Addressing and the Web Security Model - Fabrice Desré
|
||||
|
||||
Speaking of hard... have you ever decided that the problem you'd like to fix in the world is Google and Apple's stranglehold on our daily digital lives? That's what [Fabrice](https://github.com/fabricedesre) does with [Capyloon](https://capyloon.org/), a complete web-based mobile operating system. When you control the OS, you ~~control the world~~ can do veeeerrrry interesting things. Fabrice gave us a deep dive into the [origin security model](https://www.rfc-editor.org/rfc/rfc6454) today and how radically different it can be in a content-addressed world.
|
||||
|
||||
@[youtube](H_1JVGDnctI)
|
||||
|
||||
## Hello Helia - achingbrain
|
||||
|
||||
Bye Felicia. Hello Helia. Thanks [achingbrain](https://github.com/achingbrain). Welcome to a new way to IPFS in JavaScript, on the web, or on the server... finally with nice things like DHT support. It should've been called banana. But we like it anyway.
|
||||
|
||||
@[youtube](T_FlhkLSgH8)
|
||||
|
||||
## JavaScript performance - how to wring the most out of your Helia deployment - achingbrain
|
||||
|
||||
Hey it's [achingbrain](https://github.com/achingbrain) again, this time with a deep dive into Helia performance and optimizing for the environment you're deploying to. JavaScript is the *fastest* language for the environments it lives in which other languages can't even exist, so take that.
|
||||
|
||||
@[youtube](zPeLYosZ3Ak)
|
||||
|
||||
## Connecting everything, everywhere, all at once with libp2p - Prithvi Shahi
|
||||
|
||||
First, the person who gives this talk is not Prithvi, it's Max. Second, Prithvi is a genius for thinking up a talk like this. Please enjoy all the transports everywhere all of the time.
|
||||
|
||||
@[youtube](zPeLYosZ3Ak)
|
||||
|
||||
## The Incredible Benefits of libp2p + HTTP - Marten Seemann & Marco Munizaga
|
||||
|
||||
In the ageless words of Gandalf, the headmaster of Hogwarts: "be like water". Or something like that. Anyways, if you're familiar with the challenge of writing code for the web that has to pretend that it's not actually stuck in a web browser tab, but instead is actually connected to a global transport-agnostic peer-to-peer network, then you'll understand how important it is to make friends with your environment and use the *!#? out of what it gives you. This talk from Marten and Marco shows you how the changing landscape of the network layer of the web platform is allowing libp2p to operate unfettered while still stuck in a tab in a window in a browser on your computer on earth.
|
||||
|
||||
@[youtube](Ixyo1G2tJZE)
|
||||
|
||||
## The Name Name Service - Blaine Cook
|
||||
|
||||
NNS.. NNS.. NNS... goes the beat. Now that you're bouncing your head, follow along as Blaine Cook shares his vision of how we solve one of the three hardest problems in computer science: how to make the perfect Hollandaise. Er, no that wasn't it. NAMING! Yes, that was it. The Name Name Service is a breathtakingly simple approach to flexible, veriable, integrate-able, old-world-compatible, and human-readable names for our digital things. Thank you Blaine.
|
||||
|
||||
@[youtube](CHiCEd36KtI)
|
||||
|
||||
## Building decentralized websites on IPFS - Ryan Shahine
|
||||
|
||||
Decentralization is cool but it's so hard and you have to be super technical to even... wait, what? I can just... drag and drop? What I see is what I get?! With Portrait, yes. Ryan Shahine shares Portrait's slick and simple site builder for publishing your sites to IPFS. No-code sites for non-technical creators is such a wonderful thing to behold.
|
||||
|
||||
@[youtube](TeFAHmzvIdg)
|
||||
|
||||
## ODD.js, a technical overview - icidasset
|
||||
|
||||
Oddly enough, DID you know UCAN build decentralized applications with that WNFS stuff we heard about earlier? In this preview of the final emergent form of a bunch of Fission's tools coming together like Voltron, you'll meet Odd.js - a toolkit for building applications that has all of the core bits you need, from identity to naming to storage to security. The only odd thing is that we didn't have this yet.
|
||||
|
||||
@[youtube](ByQbY3lNAck)
|
||||
|
||||
## IPFS native frontend development using Importmaps - Dilip Shukla
|
||||
|
||||
Imagine if your CDN was a massive cooperative global distributed network that 1) wasn't a single company, and 2) pushed alllll the way up into your client-side build tooling, making your pages immediately available. WHAT YOUR DOM WAS ACTUALLY A DAG... ok maybe that's too far, but what Lagom is doing is finding exactly what the right balance is. In the future we'll look back and wonder why we didn't do this from the begining...
|
||||
|
||||
@[youtube](4HY_7DxScMo)
|
||||
|
||||
## Explorations into Decentralized Publishing - David Justice
|
||||
|
||||
The Browsers, Platforms and Standards team wants to share our thoughts early and often. And we want to do it on IPFS. There are all kinds of ways to do it, but each have their trade-offs... but it's not clear what those are until you go make a bunch of mistakes. So we're going to make them for you. David Justice is working on approaches for building our team blog with some friends at Trigram and shares what the first stab at it looks like.
|
||||
|
||||
@[youtube](fn5QNvRXMIo)
|
||||
|
||||
## Thank you!
|
||||
|
||||
Thanks to all the speakers for the day and also to the rad people who joined and asked great questions.
|
||||
|
||||
Until our next event, come hang out in our superbridged megachannel:
|
||||
|
||||
* #browsers-and-platforms on Filecoin Slack ([join](https://filecoin.io/slack))
|
||||
* #browsers-and-standards on Element/Matrix ([join](https://matrix.to/#/#browsers-and-standards:ipfs.io))
|
||||
* #browsers-and-standards on IPFS Discord ([join](https://discord.gg/ipfs))
|
||||
|
||||
174
src/_blog/2024-brave-migration-guide.md
Normal file
174
src/_blog/2024-brave-migration-guide.md
Normal file
@@ -0,0 +1,174 @@
|
||||
---
|
||||
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.
|
||||
57
src/_blog/2025-03-static-web-manifesto.md
Normal file
57
src/_blog/2025-03-static-web-manifesto.md
Normal file
@@ -0,0 +1,57 @@
|
||||
---
|
||||
title: The Static Website Manifesto
|
||||
description: 'Building websites used to be fun. Let’s bring back the joy of putting your work online by using open protocols like IPFS.'
|
||||
author: Justin Hunter
|
||||
date: 2025-03-06
|
||||
permalink: '/2025-03-static-web-manifesto/'
|
||||
header_image: '/static-website-manifesto-header.png'
|
||||
canonicalUrl: https://orbiter.host/blog/the-static-website-manifesto
|
||||
tags:
|
||||
- 'community'
|
||||
---
|
||||
_This article originally appeared on [Orbiter's blog](https://orbiter.host/blog/the-static-website-manifesto)_
|
||||
|
||||
Building websites used to be fun. Let’s bring back the joy of putting your work online. This is our manifesto. Orbiter is built on IPFS using [IPCM](https://ipcm.dev) to map sites to Base smart contracts.
|
||||
|
||||
## Why IPFS
|
||||
|
||||
Websites are open and accessible for anyone. They are the perfect match for IPFS. IPFS is a peer-to-peer storage protocol that allows anyone to access a piece of content as long as they know the content identifier (CID) and there's an online node providing the data. This is a perfect match for the open web. It creates a level of availability not possible with traditional website file storage.
|
||||
|
||||
Additionally, because IPFS is content-addressed, that means each cid references a specific _version_ of a site. This created a built-in versioning system, similar to what you get when you explore the Wayback Machine.
|
||||
|
||||
Orbiter uses IPFS behind the scenes and integrates these concepts seamlessly for people hosting websites on the platform. But beyond that, Orbiter uses these concepts to make the web fun again.
|
||||
|
||||
## Bringing Back the Fun of the Web
|
||||
|
||||
Remember when putting a website online was as simple as uploading some files? The web used to be a playground for everyone to explore. Sure, there were technical hurdles - services like Geocities and Angelfire or uploading HTML using FTP. While FTP had its problems, it offered a straightforward path to launching a site you owned and controlled.
|
||||
|
||||

|
||||
|
||||
## How We Lost Our Way
|
||||
|
||||
Today's web is increasingly locked behind walled gardens. Social media has replaced the individual blogs and personal websites that flourished a decade ago. While changing preferences play a role, convenience is the real culprit. It's far easier to post on Facebook or Twitter than to wrangle with modern web development tools, complex deployment processes, and the challenge of finding an audience.
|
||||
|
||||
## The Problem with Modern Web Development
|
||||
|
||||
Launching a website today isn't fun anymore. While we have powerful tools at our disposal with incredible capabilities, they come at the cost of simplicity. The basic web stack - HTML for structure, CSS for style, and a sprinkle of JavaScript for interactivity - still works perfectly well. Yet much of web development has shifted toward complex frameworks that can make building even simple sites feel like a chore.
|
||||
|
||||
Who wants to wait 80 seconds for their code to build into a deployable package? The modern expectation is that you'll use source control, host your code on GitHub, and implement a full deployment pipeline. These tools are valuable for many projects, but they're overkill for many websites. Sometimes, you just want to take your folder of HTML files, upload them, and call it a day.
|
||||
|
||||
## A Return to Simplicity
|
||||
|
||||
This philosophy doesn't just apply to personal websites. Static web applications could benefit from returning to the web's simpler roots. A static web app is just a website with more JavaScript - we don't need to complicate it further. While larger projects might benefit from source control and automated deployments, the process should be flexible. Want to use CI/CD and other modern tools? Great! Prefer to simply upload files? That works too.
|
||||
|
||||
## Introducing Orbiter
|
||||
|
||||
As server-side rendering gains popularity, we're taking a stand for static sites. Orbiter is here for:
|
||||
|
||||
* The people building websites that don't need servers
|
||||
* The developers tired of waiting minutes for builds when they could have a working site in seconds
|
||||
* The web designers writing their first HTML
|
||||
* The marketers moving from WordPress to simple static HTML
|
||||
* The developers creating their own static site generators
|
||||
* Anyone who wants to share their work on the web
|
||||
|
||||
Don't feel like learning complex deployment processes? No problem. Orbiter gives you the freedom to work the way you want. We've built the simplest static site hosting platform on the web because we believe in making the web flexible, fun, and fast again.
|
||||
|
||||
Ready to make web hosting fun again? [Join us at Orbiter and put your website online in seconds](https://app.orbiter.host?ref=blog).
|
||||
38
src/_blog/2025-05-grants.md
Normal file
38
src/_blog/2025-05-grants.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: Spring 2025 IPFS Utility Grantees
|
||||
description: "We're delighted to announce the grantees for the Spring 2025 round of IPFS Utility Grants."
|
||||
author: Robin Berjon
|
||||
date: 2025-05-12
|
||||
permalink: '/2025-05-grants/'
|
||||
header_image: '/utility-grants.png'
|
||||
tags:
|
||||
- grants
|
||||
- funding
|
||||
- ecosystem
|
||||
---
|
||||
|
||||
The IPFS Implementations Grants program exists to advance the development, growth, and impact of the IPFS project through a focus on developer choice and availability. We provide financial support to projects and teams working to make IPFS accessible to more developer communities.
|
||||
|
||||
We recently ran [the Spring 2025 grant cycle for utilities](https://ipfsgrants.io/utility-grants/), which supports developers creating essential utilities, libraries, and tooling for the IPFS ecosystem. It was a tight competition with strong contenders and we're delighted with the grantees who came out of this round.
|
||||
|
||||
## rsky-satnav CAR Explorer from Rudy Fraser, BlackSky
|
||||
|
||||
If you're anywhere near work on the [AT Protocol](https://atproto.com/) then you surely know Rudy Fraser, among other things for his work on [BlackSky](https://www.blackskyweb.xyz/) and the [rsky](https://github.com/blacksky-algorithms/rsky) (say "risky") projects.
|
||||
|
||||
The grant will go to [rsky-satnav](https://github.com/blacksky-algorithms/rsky/tree/main/rsky-satnav) (Structured Archive Traversal, Navigation And Verification — we do appreciate a quality acronym), a local-first and user-friendly [CAR](https://dasl.ing/car.html) explorer for AT Protocol.
|
||||
|
||||
CAR archives are a very convenient part of the IFPS ecosystem, used to package up multiple CID-addressed resources in one bundle, and AT Protocol PDSs rely on them for data exports. But end users, even technical ones, have found dealing with CAR files challenging due to a lack of tooling. We really look forward to playing with rsky-satnav ourselves!
|
||||
|
||||
## CAR Indexing from Ben Lau, Basile Simon, and Yurko Jaremko, Starling Lab
|
||||
|
||||
Another issue with CAR files is that they are as diverse as the data usecases and ergonomics of the IPFS ecosystem: while Filecoin uploading returns a CAR file, it sidesteps the UnixFS and thus most CAR tooling cannot reconstruct or navigate its contents. As these big-data archive files are not introspectable with UnixFS tools, the [Starling Lab](https://starlinglab.org/) team is open-sourcing some indexing tools they created internally which create a _private index_ of Filecoin uploads, rounding out a historic tooling/interop gap in the ecosystem.
|
||||
|
||||
Ben, Basile, and Yurko are developing a browser-based tool to help locate contents within [Filecoin CAR archives](https://spec.filecoin.io/systems/filecoin_files/piece/), without relying on public indexing services. This is a stepping stone to more general solutions for CAR indexing. It's definitely going to boost that part of the ecosystem!
|
||||
|
||||
## DASL Testing from Cole Anthony Capilongo, Hypha Worker Co-operative
|
||||
|
||||
Not all heroes wear capes, many of the cooler ones write tests. Tests are important in development, but they are particularly important when you're creating interoperable standards. The difference between a standard and a random piece of paper isn't that the standard was blessed by a special standards organization — there are plenty of worthlessly blessed pieces of paper out there — but rather that the standard has a comprehensive test suite passed by multiple independent production-quality implementations.
|
||||
|
||||
With this in mind, we're excited to also support [Cole Anthony Capilongo](https://hypha.coop/people/#Cole%20Anthony%20Capilongo) (from the mighty [Hypha](https://hypha.coop/) working on a test suite for [DASL](https://dasl.ing/)'s [dCBOR42](https://dasl.ing/dcbor42.html) (an interoperable subset of IPLD for deterministic data encoding) and [CIDs](https://dasl.ing/cid.html) (a usable subset of IPFS CIDs). Cole will exercise the tests against multiple implementations and help us fix bugs in the specifications too. It's going to be fan<em>test</em>ic.
|
||||
|
||||
And beyond that, stay tuned: we will have more annoucements coming.
|
||||
84
src/_blog/2025-08-ed25519.md
Normal file
84
src/_blog/2025-08-ed25519.md
Normal file
@@ -0,0 +1,84 @@
|
||||
---
|
||||
title: "Ed25519 Support in Chrome: Making the Web Faster and Safer"
|
||||
description: "Ed25519 is now supported in Chrome, finally joining the other browsers after much effort."
|
||||
author: Bumblefudge
|
||||
date: 2025-08-13
|
||||
permalink: '/2025-08-ed25519/'
|
||||
header_image: '/ed25519.jpg'
|
||||
tags:
|
||||
- funding
|
||||
- ecosystem
|
||||
- browsers
|
||||
---
|
||||
|
||||
We're happy to share that Ed25519 is now supported in Chrome (version). Following Ed25519 support in [Firefox 129](https://developer.mozilla.org/en-US/docs/Mozilla/Firefox/Releases/129) in August 2024 and [Safari 17.0](https://developer.apple.com/documentation/safari-release-notes/safari-17-release-notes), Chrome finally following suit in 137 in May of this year. Ed25519 is now supported in every major browser engine, reaching [79% and counting](https://caniuse.com/?search=ed25519) of web users.
|
||||
|
||||
Ed25519 is a type of key, most known because it is the smallest and fastest commonly-available key for generating and verifying [elliptic curve cryptography](https://en.wikipedia.org/wiki/Elliptic-curve_cryptography) signatures. Digital signature algorithms let you prove that a piece of data was created by someone with a specific private key, without needing to reveal that key. They're essential for authenticating software updates, Git commits, cryptocurrency transactions, and, in distributed networks like IPFS, for authenticating peer identities and quickly establishing trust among peers.
|
||||
|
||||
## What Ed25519 in WebCrypto API means for developers
|
||||
|
||||
Why is Ed25519 support in browsers valuable? If you’re coming from traditional web development, you’re probably familiar with the common hashes (SHA-256) and key types (RSA) already there, which are “table stakes” (often even available through standard libraries) unless you have very niche cryptographic needs. Built-in support for Ed25519 represents a significant upgrade across the board, bringing Ed25519 into that category of “table stakes” which developers can stop worrying about and just take for granted.
|
||||
|
||||
**The key advantages**:
|
||||
|
||||
* **Smaller footprint**: Ed25519 keys are just 32 bytes (256 bits), compared to 256+ bytes for equivalent RSA security. Signatures are 64 bytes versus 256+ for RSA.
|
||||
|
||||
* **Faster operations**: Signature verification is roughly 10x faster than RSA and consistently faster than ECDSA. Signature generation is also faster.
|
||||
|
||||
* **Security by design**: Ed25519 was built from the ground up to resist timing attacks, uses deterministic signatures (no random number generation that can go wrong), and provides roughly 128-bit security level — equivalent to a 3072-bit RSA key.
|
||||
|
||||
* **Simpler implementation**: Unlike ECDSA, Ed25519 doesn't require developers to handle tricky parameters or worry about malleability attacks.
|
||||
|
||||
Ed25519 signatures keys have long been one of the top key types and signatures everywhere except the browser, used to power everyday connection protocols like SSH (remote terminal) and sFTP (file transfer) and PGP (encrypted email) and all kinds of things. But until now, if your web app needed to verify an Ed25519 signature (say, to validate a Git commit or authenticate with an SSH-based service), you had to bundle your own cryptography libraries, which can often be half the “weight” (download size) of your web app that uses Ed25519 signatures today!
|
||||
|
||||
Of course, Ed25519 signatures don’t just make it easier to support long-standing protocols, they also power lots of cutting-edge and forward-looking identity systems as well. For example, Radicle, an open-world/decentralized git community, uses EdDSA keys as usernames and requires all repositories to be signed by them (since almost all git tooling across languages defaults to an EdDSA key manager at the OS level).
|
||||
|
||||
Identity systems like Radicle aren’t the only beneficiaries of being able to produce or check signatures in the browser; most “local-first” software, and of course all software based on content-addressable data benefit as well. For example, many web3 applications and distributed systems generally use content-addressed envelopes and documents rather than flat, traditional authorization tokens. Two of these, UCANs and BeeHive (the local-first/CRDT variant of UCANs), both scale up CRDTs and distributed workflows by giving every process, container, and resource an EdDSA key, so that all these authorization documents can be quickly and cheaply checked at any trust-boundary, including in the end-user’s browser. Making a safe verifier or web-view on any of these systems just got days, maybe weeks faster to build, which results in smaller binaries so much smaller they can go more places as a result.
|
||||
|
||||
With Ed25519 now in WebCrypto, these operations become a simple browser API call — no external dependencies, no bundle bloat, and better performance.
|
||||
|
||||
|
||||
That qualifier “lightweight” is the main contribution here (and a counterintuitively very consequential one) to the commons of an increasingly cryptographic web. Tomorrow’s web is increasingly going to accrue ambient verifiability (even for publishers that don’t pay the CDN tax!), and many other downstream efficiencies fall out from being able to link up EdDSA keys which are already ubiquitous everywhere else in the average end-user’s operating systems and platforms.
|
||||
|
||||
## The Journey from Wanting to Having
|
||||
|
||||
Most of the updates you’ll see on this blog are about making IPFS work better with today’s web. Recently, we wrote about enabling true peer-to-peer connections through the HTTPS-only web with [AutoTLS](https://blog.libp2p.io/autotls/), and before that there was a [steady stream](https://blog.ipfs.tech/2024-shipyard-improving-ipfs-on-the-web/) of improvements from the IPFS Shipyard team, which make it easier to discover and distribute IPFS data smoothly over the web.
|
||||
|
||||
But sometimes, if you dream big enough and invest on a long enough time horizon, you can actually make the web work a little more like IPFS. In recent years, there’s been a broader movement towards a more hash-based, trustless web in the form of cryptography creeping into web standards as the reactive, edge-cached, CDN-enabled web shifts user expectations towards better and better UX. Intervening in this trend and putting up the funding to do the slow, relentless pushing in web standards plants the seeds of a web more aligned to [IPFS Principles](https://specs.ipfs.tech/architecture/principles/).
|
||||
|
||||
### How the web standards are governed, practically
|
||||
|
||||
The web has, in fact, been worldwide since most of us can remember, and even those of us old enough to remember its pre-ubiquitous phase have trouble remember the chaos of web development in those days when each browser took a blasé approach to HTML interoperability and how the details of HTTPS and TCP/IP were to be configured stably. Standardizing the web was almost as long and complex a technosocial process as making it worldwide or making it profitable, and it involved a lot of snarking on mailing lists, long before GitHub threads and Slack servers opened up new snarking surfaces.
|
||||
|
||||
The iterating and fine-tuning of software standards to a point where multiple completely-independent browsers could provably be uniform in how they render a given chaotic markup language (to say nothing of JavaScript!) is an ongoing and massive infrastructural accomplishment that battles on to this day. The janitorial work is led by a global-ish community, with lots of volunteers, underpaid experts, and tired academics providing extra patience and human-power. Their devotion keeps the web a durable and open platform for information, which could revert to mere plumbing for commerce if left entirely to large commercial players.
|
||||
|
||||
When you think about web standards, people naturally think about the Big Decisions and governance quagmires around specific technologies: how JavaScript can be sandboxed and policy-bound to safely run across domains, how CSS can get inherited and nuanced and last-mile exceptioned as it cascades over those same domains, etc. Smaller languages, thin protocols that run over the web (federated identity, social web, payments), accessibility and localization standards, and Big Semantics round out the rest of what we call “web standards,” mostly standardized at the World Wide Web Consortium (W3C) with the regular collaboration from adjacent standards development organizations.
|
||||
|
||||
Historically, most debate and standardization around cryptography happened one level below the web at [IETF](http://ietf.org/): as a rule of thumb, you could say “the web” is for humans and their messy semantics, while “the internet” is a superset powered by machines who can standardize on the stuff that vanishingly few humans even understand. But increasingly, to make the web more secure (think: passkeys, FIDO, wallets) web standards increasingly need cryptographical ground-truths in common web-wide as well. These have made one of the most closely-watched groups at the W3C the “WebCrypto API”-- where browser developers agree to interfaces that build basic cryptographic building blocks into the browser itself, incentivizing reuse and transparency by offloading crypto complexity onto the “web platform” itself (the ground assumptions about how the whole web will work in any browser).
|
||||
|
||||
The WebCrypto interface gives all web developers a powerful take-out window to order reliable and determinic signatures and hashes from, which enables all kinds of powerful building blocks in a few lines of code. For instance, the increasingly generalized [SubResource Integrity](https://w3c.github.io/webappsec-subresource-integrity/) pattern allows many of the heaviest parts of web development (big media files, JavaScript bundles that change often due to security and dependency trees) to be “checksummed”, i.e. integrity-protected by a hash. This dovetails nicely with the generalized integrity-protection that IPFS brings to web development; speeding up the browsers’ support for more sub-resource integrity mechanisms also makes the web much more IPFS-ready and makes IPFS more intuitive to tomorrow’s web developers.
|
||||
|
||||
## Igalia, Standards Work and Actual Adoption
|
||||
|
||||
So how exactly did IPFS support directly bring about Ed25519 becoming a browser default? The answer involves a three-year collaboration with [Igalia](https://www.igalia.com/), a worker-owned open source consultancy and co-operative that has become a major contributor to browser development since 2001.
|
||||
|
||||
It’s hard to overstate just how much work goes into even a comparatively simple web platform feature such as this one. If you want a peek at what happens behind the curtain, I strongly recommend [Javi’ blog post from February 2025 summarizing the progress to date](https://blogs.igalia.com/jfernandez/2025/02/28/can-i-use-secure-curves-in-the-web-platform/).
|
||||
|
||||
The specific focus of this collaboration was getting Ed25519 “into the browser” by default, with an eye to tools like [Verified Fetch](https://blog.ipfs.tech/verified-fetch/). Verified Fetch not only fetches content from IPFS by CID like any other client, but crucially it also verifies that each block matches its CID. Since Verified Fetch needs to be able to install as close to “invisibly” as possible, it is a huge UX improvement to reduce its download size by a two-digit percentage, which is achieved by outsourcing the math and the logic to the browser’s built-in library.
|
||||
|
||||
A PR on a browser engine is significantly more complex than a typical open source contribution. It requires extensive coordination across implementations, specifications, security review processes, performance review processes, quality assurance, and more. Javier (“Javi”) Fernandez at Igalia drove [PRs](https://github.com/whatwg/html/issues/9158) against all three of the major independent browser engines in parallel, juggling change requests and nits and corner-cases to make sure all three would handle any inputs the exact same way under any configuration or combination of extensions.
|
||||
|
||||
The work began with identifying and [fixing a bug](https://github.com/w3c/webcrypto/pull/345) in the W3C specification governing the WebCrypto interface. Over three years, Javi systematically addressed technical challenges in 3 browsers’ codebases, from low-level C implementations to API surface design.
|
||||
|
||||
## What’s Next
|
||||
|
||||
Ed25519 support went live in May 2025 [Chrome 137](https://developer.chrome.com/blog/chrome-137-beta#ed25519_in_web_cryptography), joining every other major browser before it.
|
||||
|
||||
Typically, it takes 2-3 years for new browser versions to proliferate across the user landscape. We anticipate that around 2027, developers can confidently start relying on simple and stable support for Ed25519 in most users’ browsers.
|
||||
|
||||
As this transition happens, developers can drop weight from our software packages, complexity from testing and maintenance, and load-time and bandwidth. In aggregate, that makes the web a lot more powerful for everyone, and more aligned with the IPFS principles: simple, modular, and verifiable. It’s a rare case of everybody winning, and the entire web getting a little more stable and good.
|
||||
|
||||
|
||||
Thanks to Protocol Labs (who initiated the collaboration with Igalia), the [IPFS Foundation](???), [Open Impact Foundation](https://openimpact.foundation/), and [WebTransitions.org](https://webtransitions.org/) for continuing to shepherd this initiative.
|
||||
|
||||
More IPFS initiatives and collaborations to make the web more simple, modular, and verifiable are in progress. They include [ElectronJS build variants](https://github.com/electron/electron/issues/42455) (to support better protocol handling), more useful [protocol handling in browser extensions](https://github.com/ipfs/in-web-browsers/issues/212) ([webtransitions theme](https://github.com/webtransitions/initiatives/issues/10)), as well (we hope) streaming support in browser cryptography APIs!
|
||||
74
src/_blog/2025-js-libp2p-devtools.md
Normal file
74
src/_blog/2025-js-libp2p-devtools.md
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
date: 2025-07-25
|
||||
permalink: /2025-js-libp2p-helia-devtools/
|
||||
title: 'Debugging Superpowers With the New js-libp2p Developer Tools'
|
||||
description: 'Discover the new js-libp2p developer tools from Shipyard that provide real-time debugging capabilities for js-libp2p and Helia nodes in both browsers and Node.js.'
|
||||
canonicalUrl: https://ipshipyard.com/blog/2025-js-libp2p-devtools/
|
||||
author: Daniel Norman
|
||||
header_image: /dev-tools.jpg
|
||||
tags:
|
||||
- ipfs
|
||||
- devtools
|
||||
- js-libp2p
|
||||
- browsers
|
||||
- node.js
|
||||
- extension
|
||||
- Interplanetary Shipyard
|
||||
---
|
||||
|
||||
_This blog post [originally appeared on the Interplanetary Shipyard blog](https://ipshipyard.com/blog/2025-js-libp2p-devtools/)_
|
||||
|
||||
[Interplanetary Shipyard](https://ipshipyard.com/) is thrilled to share [js-libp2p inspector](https://github.com/ipshipyard/js-libp2p-inspector/), the new developer tools for debugging and inspecting js-libp2p and Helia, for use both in browsers and Node.js.
|
||||
|
||||
Debugging is an essential part of software development, and having the right tools can make all the difference. The new developer tools provide a user-friendly interface to inspect your libp2p nodes in real-time, tightening the feedback loop and making it easier to diagnose issues.
|
||||
|
||||
## Inspecting and monitoring throughout the development lifecycle
|
||||
|
||||
These new developer tools expand the existing set of metrics implementations for js-libp2p, which include [metrics-prometheus](https://github.com/libp2p/js-libp2p/tree/main/packages/metrics-prometheus) and [metrics-opentelemetry](https://github.com/libp2p/js-libp2p/tree/main/packages/metrics-opentelemetry).
|
||||
|
||||
While Prometheus and OpenTelemetry are for monitoring and tracing in production (though not exclusively), the inspector is intended for use during development. Together, these tools provide a comprehensive solution for monitoring and debugging js-libp2p and Helia nodes throughout the development lifecycle.
|
||||
|
||||
## Getting started
|
||||
|
||||
To inspect a js-libp2p or Helia node, you need to pass the metrics implementation from the [`@ipshipyard/libp2p-inspector-metrics`](https://www.npmjs.com/package/@ipshipyard/libp2p-inspector-metrics) package to your js-libp2p or Helia factory:
|
||||
|
||||
### js-libp2p example
|
||||
|
||||
```js
|
||||
import { createLibp2p } from 'libp2p'
|
||||
import { inspectorMetrics } from '@ipshipyard/libp2p-inspector-metrics'
|
||||
|
||||
const node = await createLibp2p({
|
||||
metrics: inspectorMetrics()
|
||||
})
|
||||
```
|
||||
|
||||
### Helia example
|
||||
|
||||
```js
|
||||
import { createHelia } from 'helia'
|
||||
import { inspectorMetrics } from '@ipshipyard/libp2p-inspector-metrics'
|
||||
|
||||
const node = await createHelia({
|
||||
libp2p: {
|
||||
metrics: inspectorMetrics()
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Once you have your node running with the inspector metrics enabled, you can start inspecting it using the browser extension or the Electron app.
|
||||
|
||||
The following video walks through setup and usage with both Node.js and browser environments:
|
||||
|
||||
@[youtube](AKNGtn7EZxI)
|
||||
|
||||
## Try the new developer tools
|
||||
|
||||
The new developer tools consist of several npm packages that work together:
|
||||
|
||||
- [`@ipshipyard/libp2p-devtools`:](https://github.com/ipshipyard/js-libp2p-inspector/tree/main/packages/libp2p-devtools) Browser DevTools extension to inspect a libp2p node running in a web page.
|
||||
- [`@ipshipyard/libp2p-inspector`:](https://github.com/ipshipyard/js-libp2p-inspector/tree/main/packages/libp2p-inspector) Electron based app to inspect a running libp2p node in Node.js.
|
||||
- [`@ipshipyard/libp2p-inspector-metrics`:](https://github.com/ipshipyard/js-libp2p-inspector/tree/main/packages/libp2p-inspector-metrics) Metrics implementation that instruments the libp2p node such that it can be inspected by the inspector or the browser extension. This package needs to be imported in your js-libp2p based application to enable inspection.
|
||||
- [`@ipshipyard/libp2p-inspector-ui`:](https://github.com/ipshipyard/js-libp2p-inspector/tree/main/packages/libp2p-inspector-ui) The user interface shared by both the Electron inspector and the browser extension.
|
||||
|
||||
We encourage you to try out the new developer tools and provide feedback. You can find the source code on [GitHub](https://github.com/ipshipyard/js-libp2p-inspector).
|
||||
228
src/_blog/2025-someguy-cached-router.md
Normal file
228
src/_blog/2025-someguy-cached-router.md
Normal file
@@ -0,0 +1,228 @@
|
||||
---
|
||||
title: 'Faster Peer-to-Peer Retrieval in Browsers With Caching in the Delegated Routing HTTP Server'
|
||||
description: 'How caching and active peer probing in the Someguy, the Delegated Routing server accelerates peer-to-peer content retrieval in browsers and mobile applications.'
|
||||
author: Daniel Norman
|
||||
date: 2025-09-05
|
||||
permalink: /2025-delegated-routing-caching/
|
||||
header_image: /someguy-cache/cover.png
|
||||
tags:
|
||||
- ipfs
|
||||
- someguy
|
||||
- delegated routing
|
||||
- performance
|
||||
- mobile
|
||||
- browsers
|
||||
- caching
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
Last year we shipped a major improvement to [Someguy](https://github.com/ipfs/someguy/pull/90), the HTTP Delegated Routing API for the Amino DHT and IPNI. The update introduced a cached address book and active peer probing for DHT peers. This change considerably increases the ratio of providers with addresses returned, which in turn accelerates peer-to-peer content retrieval in browsers and mobile applications. It's included in the [v0.7.0 release](https://github.com/ipfs/someguy/releases/tag/v0.7.0) of Someguy. Follow along for the full story.
|
||||
|
||||
## What is Someguy and why it matters
|
||||
|
||||
[Someguy](https://github.com/ipfs/someguy) is a [Delegated Routing HTTP API](https://specs.ipfs.tech/routing/http-routing-v1/) for proxying IPFS routing requests to the Amino DHT, IPNI or any other routing system that implements the same API.
|
||||
|
||||
Its main purpose is to help IPFS clients find provider peers for CIDs and their network addresses, and expose that as an HTTP API. This is crucial for browsers and mobile applications that need to fetch IPFS content without running a full DHT client, which is often impractical on resource-constrained devices, like mobile phones and web browsers.
|
||||
|
||||
An Amino DHT client is stateful, and typically opens hundreds of connections to maintain its routing table and find provider and peer records. The problem is that browsers and mobiles are limited in their networking capabilities — both in terms of the **transports** they can use and the **number of connections** they can open. Mobiles also have limited battery and bandwidth, making it impractical to run a full DHT client.
|
||||
|
||||
Delegated routing allows these devices to query the DHT for content providers in a single HTTP request, rather than requiring them to maintain complex DHT connections themselves.
|
||||
|
||||
To make decentralised retrieval possible for content provided to the DHT, Someguy serves as a helper, allowing these devices to query the DHT in a single HTTP request and get back a list of provider peers that have the data for a CID. This is done over HTTP, which is universally supported by browsers and mobile apps.
|
||||
|
||||
The IPFS Foundation provides a public delegated routing endpoint backed by Someguy with the URL `https://delegated-ipfs.dev/routing/v1` that is used by [Helia](https://github.com/ipfs/helia/blob/a0cac72e5b440bf7ea7356571b0f244e05c896e0/packages/http/src/utils/libp2p-defaults.ts#L31) by default to accelerate peer-to-peer content retrieval in browsers and mobile applications.
|
||||
|
||||
## The role of Someguy in IPFS content retrieval
|
||||
|
||||
When Helia or [`@helia/verified-fetch`](https://www.npmjs.com/package/@helia/verified-fetch) fetches content from the IPFS network, it goes through the following process:
|
||||
|
||||
1. Helia requests providers for a CID from Someguy using `Accept: application/x-ndjson` header for streaming responses: `GET https://delegated-ipfs.dev/routing/v1/providers/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi`
|
||||
2. Someguy traverses the Amino DHT and responds with the providers that have the content, _typically_ along with their network addresses.
|
||||
- Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"Addrs": [
|
||||
"/ip4/12.144.75.172/tcp/4001",
|
||||
"/ip4/12.144.75.172/udp/4001/quic-v1",
|
||||
"/dns4/12-144-75-172.k51qzi5uqu5digdd4g1rmh3ircn34nxsehlp9ep60q96fqubc1t2604u88gin4.libp2p.direct/tcp/4001/tls/ws",
|
||||
"/ip4/12.144.75.172/udp/4001/webrtc-direct/certhash/uEiCcNkDjuquRDqyq3hvbp80GeS3joyomKoMjddVSLKdYUw",
|
||||
"/ip4/12.144.75.172/udp/4001/quic-v1/webtransport/certhash/uEiAUslaNVe83tW3hkVALwQUiKieQjzs77YXb4mLpo2yfJA/certhash/uEiAr6d8yeHt21X9jvRoHGwdtuLm_hDFHra0atSSCK-79HQ"
|
||||
],
|
||||
"ID": "12D3KooWFxAMbz588VcN4Ae69nMiGvVscWEyEoA6A3fcJxhSzBFM",
|
||||
"Schema": "peer"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
3. Browser/mobile app connects directly to those peers as soon as each provider record arrives in the stream, enabling parallel connection attempts and faster content retrieval
|
||||
|
||||
**The performance equation is straightforward**: the faster Someguy can respond with working peer addresses, the quicker browsers and mobile apps can start fetching content peer-to-peer. Every millisecond saved in routing queries directly translates to faster content delivery.
|
||||
|
||||
## The problem: provider records without peer addresses
|
||||
|
||||
Before [v0.7](https://github.com/ipfs/someguy/releases/tag/v0.7.0), Someguy would often respond with provider records that included peer IDs but **not** their network addresses. This meant that clients had to make an additional requests to `/routing/v1/peers/{peerid}` to get the actual addresses of each peer.
|
||||
|
||||
For example, unlike the response above, Someguy would return a response like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"Providers": [
|
||||
{
|
||||
"Addrs": [],
|
||||
"ID": "12D3KooWFxAMbz588VcN4Ae69nMiGvVscWEyEoA6A3fcJxhSzBFM",
|
||||
"Schema": "peer"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### But why are providers returned without peer addresses?
|
||||
|
||||
The widely-used [go-libp2p](https://github.com/libp2p/go-libp2p) and [go-libp2p-kad-dht](https://github.com/libp2p/go-libp2p-kad-dht/) libraries have a couple of important constants that control how long provider and peer addresses are cached in memory:
|
||||
|
||||
- `DefaultProvideValidity = 48 * time.Hour`: TTL for provider records mapping between a multihash (from the CID) and peer IDs.
|
||||
- `DefaultProviderAddrTTL = 24 * time.Hour`: TTL for the **addresses** of those providers. These addresses are returned in DHT RPC requests alongside the provider record. After the addresses expires, clients require an extra lookup, to find the multiaddress associated with the returned peer ID.
|
||||
- `RecentlyConnectedAddrTTL = time.Minute * 15`: Time during which a peer's address is kept in memory after a peer disconnects. Applies to any libp2p peer that has been recently connected to.
|
||||
|
||||
In other words, DHT servers can return provider records without peer addresses. This happens in the time window 24 hours after the provider record is published until it expires. This was designed to ensure that provider records are not returned with stale addresses. Since reproviding typically happens every 24 hours, DHT servers should always have fresh addresses for providers, but reality is messier.
|
||||
|
||||
## The solution: caching peer addresses
|
||||
|
||||
[PR #90](https://github.com/ipfs/someguy/pull/90) introduces several mechanisms that ensures Someguy always returns provider records with fresh peer addresses or doesn't return the provider record at all, thereby saving clients additional peer routing requests for unroutable peers.
|
||||
|
||||
This is achieved through a combination of: a cached address book, active peer probing, and a cached router which augments results with addresses and filters out undialable peers.
|
||||
|
||||
As it turns out, caching peer addresses is pretty cheap, especially if you consider that the work to discover them will be done anyway in subsequent requests. So we end up reducing the total request rates at the cost of increasing memory consumption slightly.
|
||||
|
||||
### Cached address book
|
||||
|
||||
The [new cached address book](https://github.com/ipfs/someguy/blob/6cb37a4da3ea3379a89a184335c51370b8abb48b/cached_addr_book.go) wraps the go-libp2p [memoryAddrBook](https://github.com/libp2p/go-libp2p/blob/master/p2p/host/peerstore/pstoremem/addr_book.go) and has the following properties:
|
||||
|
||||
- **48-hour cache**: Stores peer addresses for 48 hours, matching the DHT provider record expiration.
|
||||
- **1M peer capacity**: This sets an upper limit on memory usage, allowing Someguy to handle a large number of peers without excessive memory consumption.
|
||||
- **Memory-efficient**: Uses LRU eviction to keep the most relevant peers readily available
|
||||
- **Event driven cache maintenance**: Caches peers by subscribing to the libp2p event bus and caches after successful libp2p identify events, rather than actively polling the DHT for peer addresses, thereby only caching peers based on actual delegated routing requests.
|
||||
|
||||
### Active peer probing in the background
|
||||
|
||||
Rather than serving stale addresses, Someguy now tests peer connectivity in the background:
|
||||
|
||||
- **Background verification**: Every 15 minutes, tests whether cached peer addresses still work
|
||||
- **Exponential backoff**: Stops wasting time on persistently offline peers
|
||||
- **Concurrent testing**: Tests up to 20 peer connections simultaneously
|
||||
- **Selective probing**: Only tests peers that haven't been verified recently
|
||||
|
||||
### Cached router: better responses for HTTP clients
|
||||
|
||||
The `cachedRouter` (`server_cached_router.go`) uses the cached address book to augment the routing results for both peer and provider requests with a non-blocking iterator:
|
||||
|
||||
1. **Cache-first responses**: Returns verified peer addresses immediately when available
|
||||
2. **Background resolution**: If no cached addresses exist, looks up fresh ones without blocking the response
|
||||
3. **Streaming results**: Sends working peer addresses as soon as they're found
|
||||
4. **Fallback handling**: Omits peers that can't be reached rather than sending bad addresses
|
||||
|
||||
All these improvements are enabled by default in Someguy v0.7.0 and later (see the [`SOMEGUY_CACHED_ADDR_BOOK`](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md#someguy_cached_addr_book) env variable for how to disable it).
|
||||
|
||||
## Measuring impact
|
||||
|
||||
To measure the impact of these changes, we deployed two instances of someguy, one with the cached address book and active probing enabled, and the other with it disabled.
|
||||
|
||||
For the instance with the cached address book enabled, we realised that it took some time for the cached address book to warm up, as peers are only cached [following mutual authentication and running the identify protocol](https://github.com/ipfs/someguy/blob/316dbc27f3cfc4df1276a7afcff33f5b4f05688d/cached_addr_book.go#L176-L195) that would be initiated as a downstream effect of incoming content and peer routing requests, unless running with the accelerated DHT client, which performs a DHT crawl on startup.
|
||||
|
||||
To determine when the cache was sufficiently warm, we observed the cached address book size [metric](https://github.com/ipfs/someguy/blob/316dbc27f3cfc4df1276a7afcff33f5b4f05688d/cached_addr_book.go#L80-L85) and waited until it stabilised, which takes around 12 hours, at which point the cache had about 30k peers. This metric continues growing gradually —at a much slower rate— eventually stagnating at ~60k peers, which correlates with the number of DHT servers [measured by ProbeLab](https://probelab.io/ipfs/kpi/#client-vs-server-node-estimate) (measured in Q3 2025).
|
||||
|
||||

|
||||
|
||||
We then piped the last 500k CID that were requested from the public ipfs.io gateway through each instance's `/routing/v1/providers/[CID]` endpoint at a rate of 100 req/second concurrently, and examined the _cache hit rate_, which is the most important metric to measure the impact of this work.
|
||||
|
||||
We also looked at HTTP request latency, and HTTP success rates to get a fuller picture of the impact of this change, and to see if there were any unexpected side effects.
|
||||
|
||||
Note that the list of 500k CIDs was not deduplicated, this was to reflect real-world usage patterns, where popular CIDs are requested more frequently.
|
||||
|
||||
### Peer Address Cache effectiveness
|
||||
|
||||
| | Lookups | Percentage |
|
||||
| ------------------------ | --------- | ---------- |
|
||||
| **Address Cache Used** | 1,287,619 | 34.4% |
|
||||
| **Address Cache Unused** | 2,455,120 | 65.6% |
|
||||
| **Total** | 3,742,739 | 100.0% |
|
||||
|
||||
We measured two key metrics to assess the cache impact:
|
||||
|
||||
**(1) How often is the cache needed?**
|
||||
In ~66% of requests, the DHT returned provider records with addresses already included. The remaining ~34% returned providers without addresses, requiring either cache lookup or additional peer routing.
|
||||
|
||||
**(2) When needed, how effective is the cache?**
|
||||
For the 34.4% of requests that needed address resolution:
|
||||
|
||||
- Cache hit: **~83%** (addresses found in cache)
|
||||
- Cache miss: ~17% (required fresh peer lookup)
|
||||
|
||||
**Bottom line:** The cache eliminates ~83% of scenarios where clients would otherwise need to make additional peer routing requests 🎉
|
||||
|
||||
### HTTP request latency and success rate
|
||||
|
||||
Here we examine the P95 (95th percentile) latency for HTTP requests to `/routing/v1/providers/[CID]` grouped by response code (200 vs 404) and the success rates measured by the ratio of 200 to 404 responses.
|
||||
|
||||
It's worth noting that we didn't expect significant reduction in latency or error rates as a result of the cache, because the cached address book is only used to augment results from the DHT, and doesn't change the underlying DHT query process.
|
||||
|
||||
| Scenario | 200s P95 | 404s P95 | Success Rate | Latency Improvement |
|
||||
| ---------------------------- | -------- | -------- | ------------ | ------------------- |
|
||||
| **Cache Disabled** | 1.91s R | 7.35s | 52.0% | baseline |
|
||||
| **Cache Enabled and Warmed** | 1.35s | 7.46s | 57.2% | -560ms (29% faster) |
|
||||
|
||||
### Key insights
|
||||
|
||||
With peer address caching enabled, we observed unexpected improvements beyond just address availability:
|
||||
|
||||
- P95 latency for successful responses improved from 1.91s to 1.35s (29% faster)
|
||||
- Success rate increased from 52.0% to 57.2%
|
||||
|
||||
These improvements likely stem from the active background probing, which pre-validates peer connectivity. When duplicate CIDs are requested, Someguy can immediately return known-good peers from cache, accelerating the routing and avoiding DHT traversal for subsequent lookups of the same content.
|
||||
|
||||
The results demonstrate that the cached address book and active probing have no negative impact on latency or success rates, and actually improve both metrics.
|
||||
|
||||
## Configuration
|
||||
|
||||
The cached address book and active probing can be configured through the following environment variables:
|
||||
|
||||
- [SOMEGUY_CACHED_ADDR_BOOK](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md#someguy_cached_addr_book)
|
||||
- [SOMEGUY_CACHED_ADDR_BOOK_ACTIVE_PROBING](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md#someguy_cached_addr_book_active_probing)
|
||||
- [SOMEGUY_CACHED_ADDR_BOOK_RECENT_TTL](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md#someguy_cached_addr_book_recent_ttl)
|
||||
|
||||
See the [docs](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md) for more details.
|
||||
|
||||
## Metrics
|
||||
|
||||
When the cached address book and active probing are enabled, Prometheus metrics to monitor the cache and active probing, which can be found in the [metrics docs](https://github.com/ipfs/someguy/blob/main/docs/metrics.md#someguy-caches)
|
||||
|
||||
## Additional optimization: HTTP-level caching
|
||||
|
||||
Beyond the peer address caching discussed above, Someguy also implements HTTP-level caching through `Cache-Control` headers. This provides a complementary layer of caching that benefits all clients, even those that don't make repeated requests themselves:
|
||||
|
||||
**Cache durations:**
|
||||
|
||||
- Provider responses with results: **5 minutes** - fresh enough to catch new providers while reducing duplicate DHT lookups
|
||||
- Empty responses (no providers found): **15 seconds** - short duration allows quick discovery if content becomes available
|
||||
- `stale-while-revalidate`: **48 hours** - clients can use stale data while fetching updates in the background
|
||||
|
||||
This HTTP caching layer works together with the peer address cache:
|
||||
|
||||
- The address cache ensures provider records include dialable addresses
|
||||
- HTTP caching prevents redundant requests for the same CID across different clients
|
||||
- CDNs and proxies can serve popular content routing responses without hitting Someguy
|
||||
|
||||
Together, these caching layers significantly reduce latency and server load while maintaining data freshness.
|
||||
|
||||
## Conclusion
|
||||
|
||||
The addition of peer address caching and active probing to Someguy represents a significant step forward for decentralized content retrieval in constrained environments. By **eliminating ~83% of additional peer lookups** and **reducing P95 latency by ~30%** (~560ms), these improvements make direct peer-to-peer content retrieval noticeably faster for millions of users accessing IPFS through browsers and mobile apps.
|
||||
|
||||
This work is available now in [Someguy releases](https://github.com/ipfs/someguy/releases) starting from v0.7.0 and is already serving production traffic at [public good](https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing-endpoint) `https://delegated-ipfs.dev/routing/v1/providers`. Anyone can [run their own Someguy instance](https://github.com/ipfs/someguy?tab=readme-ov-file#install) to provide delegated routing for their users or applications. For operators, the caching feature is enabled by default and can be configured via [environment variables](https://github.com/ipfs/someguy/blob/main/docs/environment-variables.md).
|
||||
|
||||
Looking ahead, we continue to explore ways to make IPFS more accessible and performant for all users, regardless of their device capabilities.
|
||||
82
src/_blog/2026-01-fleek-migration.md
Normal file
82
src/_blog/2026-01-fleek-migration.md
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: "How to Migrate IPFS Websites from Fleek to Modular Infrastructure"
|
||||
description: "A how-to guide for future-proofing your content-addressed website hosting."
|
||||
author: Marcin Rataj
|
||||
date: 2026-01-06
|
||||
permalink: '/2026-fleek-migration/'
|
||||
canonicalUrl: https://ipshipyard.com/blog/2026-ipfs-self-hosting-migration/
|
||||
header_image: '/2022-ipfs-gateways-1.png'
|
||||
tags:
|
||||
- kubo
|
||||
- gateways
|
||||
- fleek
|
||||
- websites
|
||||
---
|
||||
|
||||
_Cross-posted from the [Shipyard blog](https://ipshipyard.com/blog/2026-ipfs-self-hosting-migration/)._
|
||||
|
||||
This is a practical guide to hosting websites on both HTTP and IPFS using modular, swappable components. When Fleek announced it was discontinuing hosting, we migrated 15+ IPFS Project websites to a setup designed to survive any single provider shutting down. Whether you're moving off Fleek or just want more resilient hosting, this guide covers the approach and the tools we used.
|
||||
|
||||
## What Changed
|
||||
|
||||
Sites including [ipfs.tech](https://ipfs.tech), [docs.ipfs.tech](https://docs.ipfs.tech), [blog.ipfs.tech](https://blog.ipfs.tech), and [specs.ipfs.tech](https://specs.ipfs.tech) now use:
|
||||
|
||||
- **[GitHub Pages](https://docs.github.com/en/pages)** for Web2 HTTPS hosting (we already use GitHub for code, so no new third-party dependencies)
|
||||
- **[Kubo](https://github.com/ipfs/kubo)** for CID and CAR creation (we control [content-addressing](https://docs.ipfs.tech/concepts/content-addressing/), making content portable across any provider)
|
||||
- **[IPFS Cluster](https://ipfscluster.io/)** for long-term pinning and serving content to IPFS network (self-hosted by Shipyard; [pinning services](https://docs.ipfs.tech/how-to/work-with-pinning-services/) work equally well)
|
||||
- **[DNSLink](https://docs.ipfs.tech/concepts/dnslink/)** for mapping CIDs to human-readable URLs (decouples naming from content location; automated via [dnslink-action](https://github.com/ipshipyard/dnslink-action))
|
||||
|
||||
All sites now have redundant hosting: traditional HTTP via GitHub Pages and content-addressed access via [IPFS Desktop](https://docs.ipfs.tech/install/ipfs-desktop/) with [IPFS Companion](https://docs.ipfs.tech/install/ipfs-companion/) and third-party [public IPFS gateways](https://ipfs.github.io/public-gateway-checker/).
|
||||
|
||||
## Third-Party Services Come and Go
|
||||
|
||||
Fleek Hosting was a turn-key solution that combined HTTP CDN with TLS, IPFS pinning, IPFS gateway, DNSLink, IPNS, ENS, and GitHub Actions CI integration in one platform. [Fleek is pivoting to AI](https://web.archive.org/web/20260108212232/https://www.fleek.sh/blog/2026-outlook) and [discontinuing its hosting services on January 31, 2026](https://github.com/ipshipyard/waterworks-community/issues/23).
|
||||
|
||||
The IPFS service landscape is always evolving. Some providers have shut down or changed focus: [nft.storage transitioned operations](https://web.archive.org/web/20250915005638/https://nft.storage/blog/nft-storage-operation-transitions-in-2025), [Infura deprecated its IPFS public API and gateway](https://web.archive.org/web/20230206190257/blog.infura.io/post/ipfs-public-api-and-gateway-deprecation), and [Scaleway shut down IPFS pinning](https://web.archive.org/web/20251130221548/https://labs.scaleway.com/en/ipfs-pinning/). At the same time, new options have emerged: [Storacha](https://storacha.network/) launched as a successor to web3.storage, Shipyard [took over Cloudflare's public IPFS gateways](https://web.archive.org/web/20251112005234/https://blog.cloudflare.com/cloudflares-public-ipfs-gateways-and-supporting-interplanetary-shipyard/), and pinning services like [Pinata](https://pinata.cloud/) and [Filebase](https://filebase.com/) continue to grow. This isn't a criticism of any particular service. Commercial offerings evolve based on business realities. The lesson: design your setup so that no single provider change requires starting over.
|
||||
|
||||
## Modularity as the Future-Proof Approach
|
||||
|
||||
IPFS is [built for robustness](https://specs.ipfs.tech/architecture/principles/#robustness): strict about verification outcomes, tolerant about methods. A hosting strategy should follow the same principle.
|
||||
|
||||
Decouple Web2 hosting from IPFS content-addressing. Keep each component independent:
|
||||
|
||||
- **HTTP**: GitHub Pages, Cloudflare Pages, or a self-hosted server
|
||||
- **IPFS**: pinning/storage service, self-hosted Kubo/IPFS Cluster, or both
|
||||
- **DNS**: Cloudflare, Gandi, DNSimple, Route53, or any provider with a management API
|
||||
|
||||
DNS serves both layers: HTTP needs A/AAAA records and TLS certificates, IPFS needs TXT records for DNSLink to map domains to CIDs.
|
||||
|
||||
The key: control CID and CAR creation. Creating the CAR locally means no lock-in to any provider. Pick content providers that accept the CAR. If one shuts down, upload the same CAR elsewhere. HTTP hosting and DNS stay untouched.
|
||||
|
||||
Compare this to an all-in-one platform. When it shuts down, everything needs rebuilding.
|
||||
|
||||
Two standards make this work: [CAR files](https://docs.ipfs.tech/concepts/glossary/#car) for portable content and [DNSLink](https://docs.ipfs.tech/concepts/dnslink/) for human-readable addressing. Switching providers requires no pipeline changes.
|
||||
|
||||
## Our Setup
|
||||
|
||||
We use our own [IPFS Cluster](https://ipfscluster.io/) instance since Shipyard already runs IPFS infrastructure. For most projects, a [third-party pinning service](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service) works just as well with less operational overhead.
|
||||
|
||||
Our CI/CD uses two GitHub Actions:
|
||||
|
||||
- [ipshipyard/ipfs-deploy-action](https://github.com/ipshipyard/ipfs-deploy-action) creates a CID, exports the website DAG as a CAR file, uploads to IPFS Cluster or other pinning services, and provides PR preview links
|
||||
- [ipshipyard/dnslink-action](https://github.com/ipshipyard/dnslink-action) automatically updates DNSLink TXT records when the CID changes
|
||||
|
||||

|
||||
|
||||
For security, we use a sandboxed DNS zone pattern: CI credentials can only modify DNSLink TXT records, not other DNS entries. If credentials leak, the blast radius is limited to the `_dnslink` subdomain. See the [dnslink-action security documentation](https://github.com/ipshipyard/dnslink-action?tab=readme-ov-file#security-sandboxed-dnslink-domain) for details.
|
||||
|
||||
## Getting Started
|
||||
|
||||
Already have HTTP hosting? Just add IPFS and DNSLink. Migrating from Fleek? Pick all three.
|
||||
|
||||
1. **HTTP**: [GitHub Pages](https://docs.github.com/en/pages) and [Cloudflare Pages](https://pages.cloudflare.com/) are simple and maintenance free. For all-in-one self-hosted HTTP+IPFS, see [Setup a DNSLink Gateway with Kubo and Caddy](https://docs.ipfs.tech/how-to/websites-on-ipfs/dnslink-gateway/)
|
||||
2. **IPFS**: Choose a [pinning service](https://docs.ipfs.tech/how-to/work-with-pinning-services/#use-a-third-party-pinning-service) or run your own node. Follow [Deploy static apps to IPFS with GitHub Actions](https://docs.ipfs.tech/how-to/websites-on-ipfs/deploy-github-action/)
|
||||
3. **DNS**: See [Automate DNSLink updates with GitHub Actions](https://docs.ipfs.tech/how-to/websites-on-ipfs/dnslink-action/) for TXT record automation, or use [OctoDNS](https://github.com/octodns/octodns) for more providers
|
||||
|
||||
The [ipfs-deploy-action](https://github.com/marketplace/actions/deploy-to-ipfs) creates the CID and exports the site as a CAR file. This makes content portable across any provider that accepts CARs. The [dnslink-action](https://github.com/marketplace/actions/dnslink-action) links CID to DNS, allowing [IPFS-enabled browsers](https://docs.ipfs.tech/install/ipfs-companion/) to load content over IPFS.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Third-party services will continue to come and go. The takeaway: separate your concerns and use standards-based tooling. Keep HTTP hosting independent from IPFS content-addressing, create CARs in your own CI rather than someone else's cloud service so you can switch providers, and automate DNSLink updates so they're not tied to any particular service. When one component needs replacing, swap it out without rebuilding everything. This modularity is the robustness that IPFS enables.
|
||||
|
||||
All the tools we used are open source and documented. If you have questions, open an issue in the respective repositories or reach out in the [IPFS community forums](https://discuss.ipfs.tech/).
|
||||
66
src/_blog/2026-01-ipld-2025-review.md
Normal file
66
src/_blog/2026-01-ipld-2025-review.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "IPLD 2025 Review: From Monoliths to Modules"
|
||||
description: "The year that brought us modular Rust libraries, faster DAG-CBOR, stable multiformats, and a simpler on-ramp with DASL."
|
||||
author: Volker Mische
|
||||
canonicalUrl: https://ipfsfoundation.org/ipld-2025-in-review/
|
||||
date: 2026-01-19
|
||||
permalink: '/2026-01-ipld-2025-review/'
|
||||
header_image: '/2026-01-rusted-facade.jpg'
|
||||
tags:
|
||||
- ipld
|
||||
- dasl
|
||||
---
|
||||
|
||||
# IPLD 2025 Review: From Monoliths to Modules
|
||||
|
||||
_Cross-posted from the [IPFS Foundation blog](https://ipfsfoundation.org/ipld-2025-in-review/)._
|
||||
|
||||
Whether you're building on [IPFS](https://ipfs.tech/), [Filecoin](https://filecoin.io/), or [ATProto](https://atproto.com/), [IPLD](https://ipld.io/) (InterPlanetary Linked Data) — a shared data model for the self-certifying, content-addressable web — ensures your data is portable and verifiable across platforms. This post covers the past year's progress in the IPLD ecosystem and a preview of what to expect in 2026, with a focus on Rust IPLD.
|
||||
|
||||
## Rust IPLD: From Monolith to Modules
|
||||
|
||||
Following the [JavaScript implementation's](https://ipld.io/libraries/javascript/) lead, we recognized that most projects only need specific IPLD components rather than the full stack. Earlier this year, we successfully migrated the `libipld` functionality into separate, focused crates and [officially deprecated](https://github.com/ipld/libipld/commit/6f0028519d60078f062b1fad403e2c783ce3fb2c) the Rust implementation [`libipld`](https://crates.io/crates/libipld). This modular architecture is now the standard across all IPLD implementations.
|
||||
|
||||
Over the past few months, we helped migrate all actively maintained projects that had updates in the past two years. Many projects had already made the switch on their own.
|
||||
|
||||
**Performance win:** Moving the Python [DAG-CBOR](https://ipld.io/docs/codecs/known/dag-cbor/) library [`python-libipld`](https://github.com/MarshalX/python-libipld) to [`cbor4ii`](https://crates.io/crates/cbor4ii) and the latest [Rust `cid`](https://crates.io/crates/cid) version made [Bluesky custom feeds in Python ~2x faster](https://bsky.app/profile/marshal.dev/post/3m6wqrij2es2v).
|
||||
|
||||
## Migration Guide: What Replaces What
|
||||
|
||||
If you're a Rust developer still using `libipld`, here's your upgrade path:
|
||||
|
||||
### For IPLD Data Model work
|
||||
|
||||
**Use:** [`ipld-core`](https://crates.io/crates/ipld-core), which is similar to the deprecated [`libipld-core`](https://crates.io/crates/libipld-core).
|
||||
|
||||
### For encoding/decoding
|
||||
|
||||
**Old way:** Custom `libipld` traits for [DAG-CBOR](https://ipld.io/docs/codecs/known/dag-cbor/), [DAG-JSON](https://ipld.io/docs/codecs/known/dag-json/), and [DAG-PB](https://ipld.io/docs/codecs/known/dag-pb/). [`libipld-cbor-derive`](https://crates.io/crates/libipld-cbor-derive) for IPLD Schema-like transformations.
|
||||
|
||||
**New way:** Serde-based crates that go directly from serialization to native Rust types without the IPLD Data Model conversion in between:
|
||||
|
||||
- [`serde_ipld_dagcbor`](https://crates.io/crates/serde_ipld_dagcbor/) for DAG-CBOR
|
||||
- [`serde_ipld_dagjson`](https://crates.io/crates/serde_ipld_dagjson/) for DAG-JSON
|
||||
- [`ipld-dagpb`](https://crates.io/crates/ipld-dagpb) for DAG-PB (not Serde-based since DAG-PB doesn't support the full IPLD Data Model)
|
||||
|
||||
[IPLD Schema-like transformations](https://ipld.io/docs/schemas/features/representation-strategies/) can now be done directly with [Serde attributes](https://serde.rs/attributes.html).
|
||||
|
||||
**Adoption in the wild:** `serde_ipld_dagcbor` is now widely used in the Rust ATProto community, including [rsky](https://github.com/blacksky-algorithms/rsky) (AT Protocol implementation in Rust), [ATrium](https://github.com/atrium-rs/atrium), and [jacquard](https://tangled.org/nonbinary.computer/jacquard) (ATProto/Bluesky libraries).
|
||||
|
||||
## IPLD Schemas
|
||||
|
||||
[@rvagg](https://github.com/rvagg/) made a [big upgrade to the code generation of IPLD Schemas](https://github.com/ipld/js-ipld-schema/pull/135). When you define a schema, you can now generate code for Go, Rust, and TypeScript.
|
||||
|
||||
## Multiformats
|
||||
|
||||
The Rust [multiformats](https://multiformats.io/) implementations are under active maintenance and all actionable items on [`cid`](https://crates.io/crates/cid), [`multihash`](https://github.com/multiformats/rust-multihash), and [`multibase`](https://crates.io/crates/multibase) have been resolved.
|
||||
|
||||
Rust multiformats now joins Go and JS in being stable and production-ready, and you can expect mostly minor dependency updates in 2026.
|
||||
|
||||
## DASL: Starting Simple, Staying Compatible
|
||||
|
||||
Not every project needs IPLD's full flexibility. [DASL (Data Addressable Structures and Links)](https://dasl.ing/) offers a streamlined subset: fewer decisions, fewer dependencies, easier to implement. We worked to ensure the DASL specifications remained a strict subset of IPLD, so data created with DASL tools remain seamlessly compatible with the broader IPLD ecosystem.
|
||||
|
||||
## Thank You
|
||||
|
||||
Special thanks to [@Stebalien](https://github.com/Stebalien/) and [@rvagg](https://github.com/rvagg/) for their countless hours helping maintain various IPLD and multiformats libraries.
|
||||
81
src/_blog/2026-01-year-in-review.md
Normal file
81
src/_blog/2026-01-year-in-review.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: "Content-Addressing: A Year In Review"
|
||||
description: "Let's take a look at what happened in content addressing in 2025 — it's a lot!"
|
||||
author: Robin Berjon
|
||||
canonicalUrl: https://ipfsfoundation.org/content-addressing-2025-in-review/
|
||||
date: 2026-01-15
|
||||
permalink: '/2026-01-year-in-review/'
|
||||
header_image: '/2026-01-sunrise-sea01.jpg'
|
||||
tags:
|
||||
- ecosystem
|
||||
---
|
||||
|
||||
It's hard to believe that it was 2025 only two weeks ago, but all the same we'd like to wrap the year up tidily and look back at what happened in content addressing leading up to 2026\!
|
||||
|
||||
"Content addressing?" you say. "Is there enough going on around content addressing to write a year in review post?" Content addressing has many uses, but two salient ones include trusting that you're getting the data you really want and ensuring that data can be independently verified without relying on the power of a centralized authority. It's easy to see how those two features are key to facing today's challenges. Over the past decade, the IPFS community has been at the forefront of making content addressing practical and accessible. Today, thousands of projects build on it, from decentralized websites and scientific data repositories to verifiable archives and supply chains.
|
||||
|
||||
The IPFS project began as an integrated full stack—content addressing, data formats, and peer-to-peer networking bundled together. Over time, it has evolved into a suite of technologies that work well together but also make sense independently.
|
||||
|
||||
This post focuses on one pillar: **content addressing** — the building blocks that let you identify, verify, and link data by what it contains. These tools (IPLD, multiformats, CIDs) are network-agnostic: you can use them with peer-to-peer systems, client-server architectures, or anything in between. The other historic pillar of IPFS, peer-to-peer networking, is a story for a future post.
|
||||
|
||||
## Modularity
|
||||
|
||||
Closer to home, about a year ago we said that we wanted to focus on making the IPFS technology suite more modular, adopting the principle that it should operate more in line with the good old-fashioned tenets of Unix philosophy: small tools strung together to assemble great power (if not always with great responsibility). For all that it may be accepted wisdom that the best-laid plans of mice and men often go awry, looking back over 2025 we're delighted to see that this one panned out.
|
||||
|
||||
In truth, the community was already ahead of us here, quietly shipping tight, purpose-built libraries for CAR, IPLD, and other primitives in the IPFS family. Together, over the past year, we’ve made real progress on modularity through community-wide efforts – spanning standards work, new specifications, and rethinking how our core libraries are structured.
|
||||
|
||||
And dawg, how best to show off modularity by giving you [a year-in-review post (about Rust IPLD)](https://blog.ipfs.tech/2026-01-ipld-2025-review/) in this year-in-review post? Check out how we got [a 50% speed improvement](https://bsky.app/profile/marshal.dev/post/3m6wqrij2es2v) in the Python wrapper around the Rust lib and other great boosts from migrating off of the old libipld and to more modular implementations.
|
||||
|
||||
This year also saw lots of action in the [DASL](https://dasl.ing/) space. If you don't know DASL, it's the part of the IPFS family that's laser-focused on adoption, interoperability, and web-style systems that need to be resilient in the face of dubious code, open-ended systems, and — *gasp* — potentially high volumes of users. DASL is all about modularity and tiny specs that mesh together like small Unix tools. (Read [our introduction to DASL](https://ipfsfoundation.org/dasl-a-simple-way-to-reference-digital-content/) from earlier this year.) In addition to simple subsets of [CIDs](https://dasl.ing/cid.html), [CAR](https://dasl.ing/car.html), and DAG-CBOR (aka [DRISL](https://dasl.ing/drisl.html)), DASL also supports HTTP retrieval ([RASL](https://dasl.ing/rasl.html)), packaging metadata ([MASL](https://dasl.ing/masl.html)), and bigger data ([BDASL](https://dasl.ing/bdasl.html)). And before you ask: yes, we do have a resident acronym expert on staff.
|
||||
|
||||
We're driving interoperability between implementations thanks to the [amazing test suite](https://hyphacoop.github.io/dasl-testing/) that the [Hypha Worker Co-Operative](https://hypha.coop/) built based on an IPFS Foundation grant. (They [wrote about the testing work](https://ipfsfoundation.org/hypha-dasl-the-test-suite/) on this very blog.) Looking at test suites over the weeks has been cause for celebration: where initially there had been red everywhere — because *no one* writes perfectly interoperable code without a test suite — we can see green growing fast with increasing alignment across the board. And this very interoperability has made it possible for us to submit an Internet Draft lovingly titled [*The tag-42 profile of CBOR*](https://ipfs-tech.github.io/cbor42/draft-caballero-cbor-cbor42.html) (after the CBOR tag for CIDs) to the IETF. This draft covers DASL CIDs and DRISL, and is particularly interesting in the context of ongoing discussions to standardize higher-level parts of the AT protocol at the IETF, like the “repository sync” operated over (DRISL-encoded) personal data servers by relays polling them for recent changes.
|
||||
|
||||
We hold monthly virtual meetings for the content addressing community, alternating between CID Congresses (presentations and discussions) and DASLing groups (hands-on working sessions). They’re always on the 3rd Thursday of each month – subscribe to the [CID Congress Luma calendar](https://luma.com/cid-congress) to join.
|
||||
|
||||
## Ecosystem Tooling
|
||||
|
||||
One of the joys of working on a truly open ecosystem is that you get genuine surprises. In July a new IPFS client, identifying itself as P2Pd and written in Python, that none of us had ever heard about launched and within only a few days skyrocketed to power 15% of the IPFS public network (Amino), now stabilizing near 10%.
|
||||
|
||||
Also within the Python community, growing number of geospatial projects have been using IPFS and contributing new tooling. One example is the [ORCESTRA Campaign](https://orcestra-campaign.org/intro.html), an international field study of tropical convection over the Atlantic Ocean. It generated large volumes of observational data from aircraft, ships, and ground stations to study how tropical storms form and organize. ORCESTRA chose IPFS as their distributed storage layer to make datasets immediately accessible, verifiable, and resilient to single points of failure — addressing pain points from previous field campaigns where centralized systems were too slow for day-to-day scientific work. [ipfsspec](https://pypi.org/project/ipfsspec/) brings verified IPFS retrieval to the Python data science ecosystem by implementing the [fsspec](https://filesystem-spec.readthedocs.io/) interface, the same abstraction layer used by xarray, pandas, Dask, and Zarr for remote data access.
|
||||
|
||||
The University of Maryland’s EASIER (Efficient, Accessible, and Sustainable Infrastructure for Extracting Reliable) Data Initiative has also released [ipfs-stac](https://pypi.org/project/ipfs-stac/) v0.2.0, a pivotal tool for onboarding and interfacing with geospatial data via [STAC](https://stacspec.org/en) APIs on IPFS.
|
||||
|
||||
Of note is how they have a straightforward tooling reuse approach in which they prepare data to work with IPFS and integrate with Kubo, as can be observed in [their codebase](https://github.com/orcestra-campaign). We've been interested in IPFS tooling for geospatial work and for scientific data in general, and this is as good an example as they get.
|
||||
|
||||
One thing that content addressing is useful for is data management, notably data provenance and attaching verifiable attestations to data sets for governance or compliance purposes. Within that space, we've been impressed with [EQTYLab's product suite](https://www.eqtylab.io/) that uses IPFS primitives for precisely those purposes. It simply looks slick and eminently usable.
|
||||
|
||||
And lest we forget: Bluesky blew past 40 million users this year, the growing AT ecosystem has over 400 apps with daily activity, and the community has shipped many libraries for all major languages to work with AT data and protocol components. Not too shabby for a content-addressed social network. (See our write-up of [AT and the Eurosky event](https://ipfsfoundation.org/ipfs-at-eurosky-live-berlin-highlights-from-a-bright-future/) from November.)
|
||||
|
||||
## Performance and Usability
|
||||
|
||||
It's been a great year for Kubo, shipping seven major releases up to the latest and shiniest [v0.39](https://github.com/ipfs/kubo/releases/tag/v0.39.0). But the number of releases is less impressive than what was in them and if it feels like you're breathing dust right now it might be from Kubo's radical performance improvements. The DHT system was rebuilt from the ground up and [the new "sweep" provider](https://ipshipyard.com/blog/2025-dht-provide-sweep/) is able to efficiently provide hundreds of thousands of CIDs without tickling your memory or risking open warfare with your ISP. This joins Bitswap improvements that have demonstrated 50-95% bandwidth improvements and 80-98% message volume reduction in testing. Even better, those CIDs can now be served directly from your node to browsers using [AutoTLS](https://blog.libp2p.io/autotls/), automatically setting up the certificate needed to make Secure WebSocket connections work in many places they could not previously. Conversely, Kubo is now able to fetch from HTTP so that you can use battle-tested HTTP infrastructure to serve content to IPFS networks.
|
||||
|
||||
Helia scored a big win shipping [verified fetch](https://www.npmjs.com/package/@helia/verified-fetch), a drop-in replacement for the classic Fetch API that verifies data for you. In turn, verified fetch powers the mighty [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway) which is a key component that will allow us to phase out HTTP gateways entirely very soon. This makes IPFS all the more usable in the browser, without the end-user needing to manually install anything.
|
||||
|
||||
Iroh too had a rocking year with no fewer than 19 releases (and there I was thinking Rust made shipping hard…) and adding over 4,500 GitHub stars inside of 2025\. They added support for many protocols, including live audio/video (working with [Streamplace](https://stream.place/)\!) and many of those like gossip or blobs compile to WASM and run in the browser. The community growing around Iroh is nothing short of amazing, having brought us [Typescript bindings](https://github.com/rayhanadev/iroh-ts), [Alt-Sendme](https://github.com/tonyantony300/alt-sendme) (with 4,500 stars of its own in Q4 alone\!), high-performance end-to-end testing platform [Endform](https://endform.dev/), wallet [Fedi](https://www.fedi.xyz/), or [Strada](https://strada.tech/), a collaborative suite for creative teams that need high-speed access to massive media content.
|
||||
|
||||
And the standards appreciators among you have some meaty, perhaps even gamey from long maturation, specs to sink your teeth into: the [UnixFS](https://specs.ipfs.tech/unixfs/) format used by most IPFS systems that expose some form of file system abstraction and [Kademlia DHT](https://specs.ipfs.tech/routing/kad-dht/), which describes how DHT-based IPFS networks make it possible for nodes to find content from one another.
|
||||
|
||||
We also have the [CID Profiles](https://github.com/ipfs/specs/pull/499) specification almost, *almost* finished. CIDs have a lot of options, which is great whenever you need to take a Swiss Army chainsaw to your content identifiers but can make it challenging to get two people to generate the same CIDs (and therefore to verify content) as they need to be using exactly the same options. Profiles solve this by listing all the possible options so that they can be easily shared between parties that need to talk.
|
||||
|
||||
## Events With A Wide Community
|
||||
|
||||
One of our areas of focus this year (and we're not about to stop\!) was to find out more about how our stack or content addressing in general could be used to solve problems that people have across the board, from syncing data faster to helping save democracy with more governable protocols (which, yes, content addressing does *help* with). We do this by meeting people where they are, learning about the problems you have across many domains and walks of life.
|
||||
|
||||
This included our own [Hashberg](https://ipfs.fyi/hashberg) event in Berlin of course, but also so much more. We did attend a number of web3 events, such as the excellent [ProtocolBerg](https://protocol.berlin/), [LabWeek](https://labweek.io/), and [DevConnect](https://devconnect.org/), but we deployed more energy connecting with the wider world. This included hacking heavies like the [Local-First Conference](https://www.localfirstconf.com/), [FOSDEM](https://archive.fosdem.org/2025/), and [Web Engines HackFest](https://webengineshackfest.org/), as well as more ecosystem-like events like [Eurosky](https://www.eurosky.social/), [DecidimFest](https://meta.decidim.org/conferences/DecidimFest25), the [Cypherpunk Camp](https://cypherpunk.camp/), and classics like [Re:publica](https://re-publica.com/en) or [MozFest](https://www.mozillafestival.org/en/). We also hopped over to Japan to see how content addressing might work with the [Originator Profile](https://originator-profile.org/en-US/). We rubbed elbows with research and standards communities at the [Dagstuhl Seminar](https://www.dagstuhl.de/en/seminars/seminar-calendar/seminar-details/25112), the [Public AI Retreat](https://publicai.network/), and of course the [IETF](https://www.ietf.org/).
|
||||
|
||||
We also went well outside of tech and into the real world at [RightsCon](https://www.rightscon.org/), the French [AI Summit](https://www.elysee.fr/en/sommet-pour-l-action-sur-l-ia) and its [FreeOurFeeds](https://freeourfeeds.com/) side event, the [IGF](https://www.intgovforum.org/en) notably with its workshop on social media infrastructure, the [Summit on European Digital Sovereignty](https://bmds.bund.de/aktuelles/eu-summit), and the [UNDP](https://www.undp.org/)'s event on governance innovation. It's been a whirlwind of a year and we've learned a lot that continues to inform our work.
|
||||
|
||||
We'll be announcing more in 2026 but you can already catch us speaking at FOSDEM in early February (both [Mosh](https://fosdem.org/2026/schedule/event/TRQ9LV-decentralized-to-doorsteps/) and [Robin](https://fosdem.org/2026/schedule/event/W8CJXD-dasl/)), as well as at [the AT Proto meetup on the Friday prior](https://luma.com/jj7nths0), and [ATmosphereConf](https://ti.to/atmosphereconf/atmosphereconf2026) in March. And look for Volker speaking on An Open, Decentralized Network for Metadata (in German) at [FOSSGIS Göttingen](https://www.fossgis-konferenz.de/2026/)\!
|
||||
|
||||
## Looking Ahead
|
||||
|
||||
As we ride into the reddened sunrise of 2026, looking ominously stylish as four horsepeople are wont to, we already have a batch of goodies we've been preparing.
|
||||
|
||||
We want to extend the capabilities of our current content-addressing stack, especially for large data. Watch out for exciting announcements in the pipeline around geo data and verifiable range requests that work over vanilla HTTP. We're also continuing our partnership with the always-brilliant [Igalia](http://igalia.com/) and hope to bring a number of improvements to *ye aulde* browsers, notably for streaming verification.
|
||||
|
||||
We've also been talking with our friends at [Streamplace](https://stream.place/) about collaborating on specs for a usable subset of [C2PA](https://c2pa.org/) and deterministic MPEG-4 containers so that you can watch content-addressable videos about content addressing. Another potential collaboration with secure chat providers and others who'd like to align on web-app containers might happen. It's still early days, we'll be sure to keep you posted as soon as there's even just a public description of the problem that covers more than me being a tease about it.
|
||||
|
||||
Overall, we'll be bringing more of the same. We'll keep working on modularization, interoperability, and adoption. We'll keep investing in test suites and implementations as needed. We'll keep pushing the IPFS family of technologies forward until it's so consistently easy to use that you stop noticing it entirely, until it's so straightforward you need not think about anything other than the specific problem you wish to solve.
|
||||
|
||||
Finally, the most important thing that we look forward to in 2026 is your participation. Everything we did in 2025 was to make things better for you and was always informed by what we heard from people or observed in the wild. Next year will be no different — but for that to work we need to hear from you\! There's many ways you can reach out: you can post on [the forum](https://discuss.ipfs.tech/), you can hit [@ipfs.tech](https://bsky.app/profile/ipfs.tech) up on the Bluesky, you can open an issue on the relevant repo, come talk to us at an in-person event, or join any of the meetings on the [IPFS Calendar](https://luma.com/ipfs) that strikes your fancy. The rumors are true: we do bite; but we only bite the bad people, so come talk\!
|
||||
45
src/_blog/2026-03-reproducible-cids.md
Normal file
45
src/_blog/2026-03-reproducible-cids.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
title: "IPIP-0499: Updating IPFS Standards for Consistent, Reproducible CIDs"
|
||||
description: "IPIP-0499 makes IPFS CIDs deterministic and consistent across all implementations."
|
||||
author: Michelle Lee
|
||||
date: 2026-03-09
|
||||
permalink: '/2026-03-reproducible-cids/'
|
||||
canonicalUrl: https://ipfsfoundation.org/ipip-0499-updating-ipfs-standards-for-consistent-reproducible-cids/
|
||||
header_image: '/2026-03-muted-teal-grid.png'
|
||||
tags:
|
||||
- ipfs
|
||||
- cid
|
||||
- ipip
|
||||
---
|
||||
|
||||
# IPIP-0499: Updating IPFS Standards for Consistent, Reproducible CIDs
|
||||
|
||||
_Cross-posted from the [IPFS Foundation blog](https://ipfsfoundation.org/ipip-0499-updating-ipfs-standards-for-consistent-reproducible-cids/)._
|
||||
|
||||
If you've worked with IPFS, you know that a content identifier (CID) is supposed to be a fingerprint for your data: feed in the same data, get the same CID. In practice, that hasn't been true. The same file or directory uploaded with [Kubo](https://github.com/ipfs/kubo), [Helia](https://github.com/ipfs/helia), or [Singularity](https://github.com/data-preservation-programs/singularity) could produce three different CIDs, because each tool uses different settings for how to split files into chunks, how wide to build the internal DAG tree, and when to switch to a HAMT structure for large directories.
|
||||
|
||||
To fix this, [IPIP-0499](https://specs.ipfs.tech/ipips/ipip-0499) has been merged into the IPFS specification. It introduces two named configuration profiles — `unixfs-v1-2025` and `unixfs-v0-2015` — each defining a complete set of DAG construction parameters.
|
||||
|
||||
### Benefits: Predictable CIDs, Faster Verification
|
||||
|
||||
The most immediate benefit is that CIDs are now deterministic. Previously, comparing two CIDs for "the same file" could return a false negative simply because the tools that created them used different chunk sizes or DAG widths. With this update, identical input processed by any implementation conforming to the same profile will always produce the same CID. That's the behavior most developers intuitively expect, and it's what makes content-addressing useful as a verification primitive.
|
||||
|
||||
A second major gain is verification efficiency. Without profile guarantees, confirming that two CIDs represent the same content requires fetching the underlying data and computing and comparing their Merkle DAGs. With deterministic CIDs, you can compare the CIDs directly without fetching the data itself. This matters especially at scale.
|
||||
|
||||
Finally, `unixfs-v1-2025` is a more performant default. Switching from 256 KiB chunks to 1 MiB, and from 174 to 1024 links per DAG node, produces shallower trees: a 1 TiB file requires 3 levels of DAG traversal instead of 4, with roughly 4x fewer total nodes. That translates to faster random access and seeking in large files, and fewer CIDs being announced to public routing infrastructure like the Amino DHT.
|
||||
|
||||
### Guidance for Implementers
|
||||
|
||||
- Implementations *MUST* support the `unixfs-v1-2025` profile.
|
||||
- The legacy `unixfs-v0-2015` profile is provided for backward compatibility and *MAY* be supported by implementations that need to produce CIDs matching historical Kubo output.
|
||||
- Implementations *SHOULD* allow users to inspect default values and adjust configuration options related to CID generation.
|
||||
|
||||
You can read the full specification, including detailed parameter comparison tables, at [specs.ipfs.tech/ipips/ipip-0499](https://specs.ipfs.tech/ipips/ipip-0499/).
|
||||
|
||||
### Current Implementation Support
|
||||
|
||||
IPIP-499 is now supported across many implementations in Go ([kubo 0.40](https://github.com/ipfs/kubo/releases/tag/v0.40.0), [boxo 0.37](https://github.com/ipfs/boxo/releases/tag/v0.37.0), [go-ipfs-cmds 0.16](https://github.com/ipfs/go-ipfs-cmds/releases/tag/v0.16.0)) and JS ([helia/unixfs 7.0.3](https://www.npmjs.com/package/@helia/unixfs), [ipfs-unixfs-importer 16.1.1](https://github.com/ipfs/js-ipfs-unixfs/releases/tag/ipfs-unixfs-importer-16.1.1)).
|
||||
|
||||
### Acknowledgements
|
||||
|
||||
Special thanks to [@lidel](https://github.com/lidel/), [@2color](https://github.com/2color), and to everyone who contributed to the [forum discussion](https://discuss.ipfs.tech/t/should-we-profile-cids/18507/13) and [review](https://github.com/ipfs/specs/pull/499).
|
||||
@@ -8,6 +8,7 @@ permalink: brave-new-wallet
|
||||
translationKey: ''
|
||||
header_image: "/ipfs-blog-brave-2021-07-23.jpg"
|
||||
tags:
|
||||
- brave
|
||||
- browsers
|
||||
- API
|
||||
|
||||
@@ -72,4 +73,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!
|
||||
|
||||
146
src/_blog/bybit-hack.md
Normal file
146
src/_blog/bybit-hack.md
Normal file
@@ -0,0 +1,146 @@
|
||||
---
|
||||
date: 2025-02-28
|
||||
permalink: /2025-could-ipfs-prevent-bybit-hack/
|
||||
canonicalUrl: https://ipshipyard.com/blog/2025-could-ipfs-prevent-bybit-hack/
|
||||
title: 'Could IPFS Have Prevented the Bybit Hack?'
|
||||
description: 'The Bybit hack revealed several security failures, this post examines whether IPFS could have helped prevent the hack and practical solutions for dapp developers.'
|
||||
author: Daniel Norman, Marcin Rataj
|
||||
header_image: /2022-ipfs-gateways-1.png
|
||||
tags:
|
||||
- ipfs
|
||||
- dapps
|
||||
- security
|
||||
---
|
||||
|
||||
## The Bybit Hack and IPFS
|
||||
|
||||
Bybit's [recent hack](https://www.reuters.com/technology/cybersecurity/cryptos-biggest-hacks-heists-after-15-billion-theft-bybit-2025-02-24/), which resulted in the loss of $1.4 billion, is a reminder of the importance of verification for frontends, especially dapp frontends in the Web3 ecosystem.
|
||||
|
||||
Based on what we know at the time of writing, IPFS, through local verification, could have served as a preventive line of defense in this sophisticated hack, potentially preventing it altogether.
|
||||
|
||||
In this blog post, we will recap what we know about the hack and share our perspective IPFS' role. diving into some of the technical efforts we've been spearheading at [Interplanetary Shipyard](https://ipshipyard.com/) to improve the health of the ecosystem.
|
||||
|
||||
If you are a dapp developer, you can skip the final section where we provide concrete recommendations with links to tooling.
|
||||
|
||||
## So how did the hack happen?
|
||||
|
||||
The TL;DR is that hackers managed to gain access to the AWS S3 bucket that hosted the Safe frontend served from `app.safe.global` and uploaded a malicious version of the frontend days before the hack. The frontend specifically targeted the Bybit cold wallet, causing owners of the multisig to sign a malicious transaction while obscuring the malicious transaction in the frontend.
|
||||
|
||||
It's not exactly clear how the hackers managed to gain access to the AWS S3 bucket. Some reports suggest that one of the developers' credentials was compromised through social engineering.
|
||||
|
||||

|
||||
|
||||
> [Source](https://x.com/benbybit/status/1894768736084885929)
|
||||
|
||||
## Security is layered
|
||||
|
||||
Security in software systems is approached in layers, often referred to as ["defense in depth."](<https://en.wikipedia.org/wiki/Defense_in_depth_(computing)>) This strategy involves implementing multiple security measures rather than relying on a single protective mechanism. If one layer fails, additional layers provide backup protection. The modern web is a complex ecosystem and as the stakes increase considering the sums of money at play, so does the need for better security measures.
|
||||
|
||||
In the context of this hack, we've identified three failures that made the hack possible:
|
||||
|
||||
1. The Safe frontend was unverified (trust was based on _belief_ DNS, TLS PKI and HTTP server are returning valid data)
|
||||
2. The Safe multisig owners signed a malicious transaction
|
||||
3. There were no additional approval layers in the Safe smart contract to prevent the malicious transaction from going through.
|
||||
|
||||
Since IPFS is mainly concerned with the first point (ability to verify data by means of [content-addressing](https://docs.ipfs.tech/concepts/content-addressing/)), we'll focus on that. The other two points bring up broader ecosystem needs like clear signing (rather than the blind signing often seen across smart contract wallets), improved UX that strengthens security rather than working against it, and more effective tools for verifying transactions.
|
||||
|
||||
The Ethereum community responded quickly, addressing the second point and released [multiple](https://safeutils.openzeppelin.com/) [tools](https://koeppelmann.github.io/CirclesTools/SafeViewer.html) and [documentation](https://help.safe.global/en/articles/276344-how-to-verify-safe-wallet-transactions-on-a-hardware-wallet) to help users verify transactions before signing them.
|
||||
|
||||

|
||||
|
||||
## IPFS and frontend verification
|
||||
|
||||
The IPFS project has long advocated for wider adoption of client verification. Over a year ago, we published a [blog post](https://blog.ipfs.tech/dapps-ipfs/) discussing the importance of client verification and how IPFS can help.
|
||||
|
||||
> 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.
|
||||
> From [_The State of Dapps on IPFS: Trust vs. Verification (2024)_](https://blog.ipfs.tech/dapps-ipfs/)
|
||||
|
||||
End-to-end integrity through cryptographic hash verification is not new to many of us in the DWeb, Web3 and IPFS ecosystems.
|
||||
|
||||
In fact, we feel somewhat vindicated seeing the Gnosis founder share the CID of an open-source fork of the Safe frontend called [Eternal Safe](https://github.com/eternalsafe/wallet) shortly after the hack, while the Safe team conducted a forensic review of their services and frontend:
|
||||
|
||||

|
||||
|
||||
> [Source](https://x.com/koeppelmann/status/1893274676756881852)
|
||||
|
||||
### Native content addressing on the web
|
||||
|
||||
One of the longest standing goals we've had for the IPFS project is to make client-side verification integrated into browsers, making CIDs first-class citizens. In an ideal world, you should be able to use CIDs in browsers using `ipfs://` without necessrily installing a "full" IPFS node that runs as a separate process on your computer.
|
||||
|
||||
To this end, we've launched multiple projects with varying degrees of success. The main challenge we run into time and time again is browser contraints and the lack of extensibility APIs that would allow shifting trust away from a specific origin from which content is served to a self-certifying identifier like a CID, allowing content to be verified locally, regardless of the source.
|
||||
|
||||
Browser extensions distributed through extension stores are harder to compromise in comparison to HTTP servers, because rollout is staged rather than instant, and vetted code assets can be bundled within the extension itself. Moreover, publishing mandates signing by the author, ensuring that users are installing the extension from a trusted source. We are investigating how we could [package the Service Worker IPFS gateway as a browser extension](https://github.com/ipfs/in-web-browsers/issues/212) to improve the user experience.
|
||||
|
||||
The self-certifying approach with CIDs is in tension with the [Same-origin policy](https://developer.mozilla.org/en-US/docs/Web/Security#same-origin_policy_and_cors): the fundamental security mechanism of the web whereby trust is anchored to an origin using DNS and PKI. Yet, given that [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) allows for hash verification of subresources, we're hopeful that we can work with standard bodies and browser vendors to expand on this foundation and provide mechanisms to verify top-level resources like HTML, JS, CSS, etc.
|
||||
|
||||
Having said that, we have some concrete recommendations for dapp developers that can be implemented today, while we advance efforts to make CIDs first-class citizens in browsers.
|
||||
|
||||
## IPFS for dapp developers
|
||||
|
||||
As a dapp developer, there are three key things you need understand and streamline into your development workflows today:
|
||||
|
||||
- How to deploy your frontend to IPFS.
|
||||
- How to safely signal release CIDs to users.
|
||||
- How users can and safely retrieve the frontend and be confident it's the same as the one you published.
|
||||
|
||||
Let's take a quick look at the state of the art for each of these.
|
||||
|
||||
### Deploying frontend to IPFS
|
||||
|
||||
To make deployments to IPFS as seamless as possible, we recently released [ipfs-deploy-action](https://github.com/ipfs/ipfs-deploy-action), a GitHub action that makes it easy to deploy your frontend (or any other static assets for that matter) to IPFS as part of CI/CD pipelines. It encapsulates best practices we've established over the years, like local CID generation and pinning with [CAR files](https://docs.ipfs.tech/concepts/glossary/#car).
|
||||
|
||||

|
||||
|
||||
The action is built with open tooling makes no assumption on your build process, so it works with any static site generator. Moreover, it sets the status of the commit with the CID allowing for more visibility and auditability of your deployments.
|
||||
|
||||
<br />
|
||||
<a href="https://github.com/ipfs/ipfs-deploy-action" class="cta-button">
|
||||
Try ipfs-deploy-action
|
||||
</a>
|
||||
|
||||
### Signaling the CID to users
|
||||
|
||||
Once you've deployed your frontend to IPFS, you need to signal the CID to users. This can be done in a few ways:
|
||||
|
||||
- Publishing the CID in the GitHub release notes, like [Eternal Safe](https://github.com/eternalsafe/wallet/releases/tag/v1) and [Uniswap](https://github.com/Uniswap/interface/releases/).
|
||||
- Publishing the CID onchain with [ENS](https://ens.domains) or [IPCM](https://github.com/PinataCloud/ipcm)
|
||||
- Regularly publishing cryptographically-signed [IPNS](https://docs.ipfs.tech/concepts/ipns/) records
|
||||
- Leveraging [DNSLink](https://docs.ipfs.tech/concepts/dnslink/) with hardened resolver ([DNSSEC](https://www.cloudflare.com/learning/dns/dnssec/how-dnssec-works/)-only and/or non-ICANN resolver such as [this one for ENS](https://github.com/ethlimo/limo-web3-dns)).
|
||||
|
||||
Each of these has different security properties and tradeoffs, some of which have been evaluated in the [Dapps on IPFS](https://blog.ipfs.tech/dapps-ipfs/) blog post.
|
||||
|
||||
The quickest way to get up and running is with GitHub, which provides strong security and auditability. At a minimum, reuse GitHub Releases to publish both the original source code and CID. This provides your users with a means to load frontend in a verifiable way.
|
||||
|
||||
### Retrieving the frontend
|
||||
|
||||
With the CID in hand, users have a few ways to retrieve the frontend:
|
||||
|
||||
- Local IPFS node like [IPFS Desktop](https://docs.ipfs.tech/install/ipfs-desktop/) together with [IPFS Companion browser extension](https://docs.ipfs.tech/install/ipfs-companion/) provide `ipfs://cid` URI support with the highest level of security, including local CID verification and caching. Great solution for desktops, but doesn't work on mobile.
|
||||
- In-browser verification with the [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway#readme) is getting better, however, initial bootstrapping of the worker is still tied to an HTTP server which could serve malicious client code if successfully exploited. We are currently investigating how we could package the Service Worker IPFS gateway as a browser extension to close this gap and improve the user experience.
|
||||
- Public Good HTTP Gateways, e.g. `ipfs.io`, `dweb.link`, and `eth.limo`, return deserialized assets which can't verified by end users. As the [IPFS Principles](https://specs.ipfs.tech/architecture/principles/#verification-matters) document states, **verification matters**, if you are not verifying, it's not IPFS. This is a supply chain equivalent of "not your keys, not your cheese".
|
||||
|
||||
<br />
|
||||
<a href="https://docs.ipfs.tech/install/ipfs-desktop/#install-instructions" class="cta-button">
|
||||
Download IPFS Desktop
|
||||
</a>
|
||||
<br/><br/>
|
||||
<a href="https://docs.ipfs.tech/install/ipfs-companion/" class="cta-button">
|
||||
Install IPFS Companion
|
||||
</a>
|
||||
|
||||
## Collaboration Proposal: Let's work together
|
||||
|
||||
[Interplanetary Shipyard](https://ipshipyard.com/), is an independent collective of people maintaining many of the most popular implementations in the IPFS and libp2p ecosystem.
|
||||
|
||||
If you are looking to improve the security of your dapp, we'd love to hear from you at `contact [at] ipshipyard.com`.
|
||||
|
||||
- Curious to explore browser extensions for your dapp that enforce frontend security via the Service Worker Gateway and safelisted release CIDs?
|
||||
- Want to sponsor browser improvements to remove dependency on DNS and PKI as trust anchor?
|
||||
|
||||
[Let's chat](https://ipshipyard.com/contact-us)!
|
||||
|
||||
## Final words
|
||||
|
||||
Striking the right balance between security and usability is hard. If there's one takeaway from this post, it's that verification is important at multiple steps of users' interaction with blockchains.
|
||||
|
||||
IPFS is not a silver bullet, but there's a good chance that if the owners of the Bybit Safe multisig loaded the frontend from a local IPFS node, this could have been prevented.
|
||||
532
src/_blog/dapps-ipfs.md
Normal file
532
src/_blog/dapps-ipfs.md
Normal file
@@ -0,0 +1,532 @@
|
||||
---
|
||||
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.
|
||||
37
src/_blog/ecosystemcontent.md
Normal file
37
src/_blog/ecosystemcontent.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Ecosystem content
|
||||
type: Ecosystem content
|
||||
sitemap:
|
||||
exclude: true
|
||||
data:
|
||||
- title: 'Shipyard 2025: IPFS Year in Review'
|
||||
description: 'Seven Kubo releases made self-hosted IPFS practical. Highlights: DHT Provide Sweep, AutoTLS, HTTP retrieval, and Helia for trustless browser retrieval.'
|
||||
date: 2025-12-19
|
||||
publish_date:
|
||||
card_image: /blog-post-placeholder.png
|
||||
path: https://ipshipyard.com/blog/2025-shipyard-ipfs-year-in-review/
|
||||
tags:
|
||||
- kubo
|
||||
- boxo
|
||||
- helia
|
||||
- gateways
|
||||
- DHT
|
||||
- AutoTLS
|
||||
- delegated routing
|
||||
- browsers
|
||||
- title: 'Provide Sweep: Solving the DHT Bottleneck for Self-Hosting IPFS at Scale'
|
||||
date: 2025-11-26
|
||||
publish_date:
|
||||
card_image: /blog-post-placeholder.png
|
||||
path: https://ipshipyard.com/blog/2025-dht-provide-sweep/
|
||||
tags:
|
||||
- DHT
|
||||
- kubo
|
||||
- title: 'libp2p at IPFS þing 2023 Recap'
|
||||
date: 2023-05-11
|
||||
publish_date:
|
||||
card_image: /blog-post-placeholder.png
|
||||
path: https://blog.libp2p.io/2023-libp2p-IPFS-Thing-recap/
|
||||
tags:
|
||||
- libp2p
|
||||
---
|
||||
@@ -4,6 +4,7 @@ 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,6 +11,9 @@ 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.
|
||||
@@ -165,4 +168,6 @@ 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).
|
||||
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).
|
||||
|
||||
49
src/_blog/ipfs-camp-2024-track-list.md
Normal file
49
src/_blog/ipfs-camp-2024-track-list.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
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)
|
||||
71
src/_blog/ipfs-check.md
Normal file
71
src/_blog/ipfs-check.md
Normal file
@@ -0,0 +1,71 @@
|
||||
---
|
||||
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/).
|
||||
20
src/_blog/ipfs-events-2024-survey.md
Normal file
20
src/_blog/ipfs-events-2024-survey.md
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: Take the IPFS Events 2024 Survey Today!
|
||||
description: 'We need your help! Make your voice heard about upcoming IPFS Events.'
|
||||
date: 2023-09-18
|
||||
tags:
|
||||
- survey
|
||||
- events
|
||||
---
|
||||
|
||||
## **We need your help! Make your voice heard about upcoming IPFS Events 📆**
|
||||
|
||||
Each year, several different IPFS events and gatherings are held at different locations to make space for the community to socialize, learn, and grow together. Many of you have been eagerly awaiting more information about when the next events will be, and we’re excited to begin sharing some of those details with you starting today!
|
||||
|
||||
**IPFS Camp** will take place in **Spring 2024**! IPFS Camp is a large in-person gathering for the entire IPFS community: devs, operators, implementers, researchers – and you!
|
||||
|
||||
**IPFS Thing** is targeted for **Fall 2024**! IPFS Thing is a week-long gathering for the IPFS implementors community. Everything from talks, workshops, discussion circles, hacking time, and more — all focused on advancing IPFS implementations.
|
||||
|
||||
We are currently in the middle of sourcing venues for both events and would love to hear your feedback on where we should be looking and why. [Submit your feedback via the following survey](https://docs.google.com/forms/d/e/1FAIpQLScNP2NKgjVBu80IygfioeTH32aCMYASLBrlQ7q05ub3choHKQ/viewform) **by September 25 at 11:59pm PST** to make sure that you’re voice is heard!
|
||||
|
||||
<a href="https://docs.google.com/forms/d/e/1FAIpQLScNP2NKgjVBu80IygfioeTH32aCMYASLBrlQ7q05ub3choHKQ/viewform" class="cta-button">Fill out the survey</a>
|
||||
@@ -3,6 +3,7 @@ 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
|
||||
|
||||
87
src/_blog/ipfs-newsletter-194.md
Normal file
87
src/_blog/ipfs-newsletter-194.md
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Welcome to IPFS News 194!
|
||||
description: Featuring Durin, Helia advancements, recaps of IPFS Thing 2023 from individual track leads, and much more!
|
||||
author: ''
|
||||
date: 2023-06-06
|
||||
permalink: "/newsletter-194"
|
||||
translationKey: ''
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
The month of May was packed full of new blog posts, þing 2023 recaps, and exciting milestones in the continued growth of IPFS. This edition of the newsletter covers everything from the launch of a new mobile app called Durin to a blog post explaining how to host dynamic content on IPFS using Helia.
|
||||
|
||||
Let’s dive in…
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Announcing Durin: a New Mobile App for the IPFS Network](https://blog.ipfs.tech/announcing-durin/)
|
||||
|
||||
- Durin is a new experimental app designed to make IPFS more accessible on mobile devices. Whereas in the past interacting with IPFS on mobile was difficult, you can now read and share to IPFS from iPhones and Android devices. [Learn more and download here!](https://blog.ipfs.tech/announcing-durin/)
|
||||
|
||||
[How to Host Dynamic Content on IPFS](https://blog.ipfs.tech/2023-how-to-host-dynamic-content-on-ipfs/)
|
||||
|
||||
- The new JS implementation of IPFS called Helia is finally here and you can do lots of things with it (like connect to the DHT)! In a recent blog post, [@tabcat00](https://twitter.com/tabcat00) presented a way to host dynamic content on IPFS that utilizes Helia. [Check it out!](https://blog.ipfs.tech/2023-how-to-host-dynamic-content-on-ipfs/)
|
||||
|
||||
[IPFS Multi-Gateway Experiment in Chromium](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/)
|
||||
|
||||
- John Turpish of Little Bear Labs goes over a new approach to implementing ipfs:// and ipns:// support natively in the browser, using a client-only approach and fetching verifiable responses from multiple HTTP gateways. [Dive in here](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/)!
|
||||
|
||||
[js-IPFS deprecation / replaced by Helia](https://blog.ipfs.tech/202305-js-ipfs-deprecation-for-helia/)
|
||||
|
||||
- js-IPFS is in the process of being deprecated so you should port your apps to Helia to receive bug fixes, features, and performance improvements moving forwards. [Read more on the IPFS blog](https://blog.ipfs.tech/202305-js-ipfs-deprecation-for-helia/)!
|
||||
|
||||
[IPFS Network Measurement Reports](https://github.com/protocol/network-measurements/tree/master/reports/2023)
|
||||
|
||||
- If you're interested in IPFS Network performance metrics and network cartography, make sure to check out ProbeLab's Weekly reports! The reports are posted every Monday at the [network-measurements repository on Github](https://github.com/protocol/network-measurements/tree/master/reports/2023) with commentary and discussion happening on [the IPFS Discussion Forum](https://discuss.ipfs.tech/c/testing-and-experiments/35). Make sure to get involved in the discussion and reach out through the discussion forum, the network-measurements repository (by opening an issue), or at the #probe-lab channel in the IPFS Discord, or FIL slack.
|
||||
|
||||
[What happens when half the network is down?](https://blog.ipfs.tech/2023-ipfs-unresponsive-nodes/)
|
||||
|
||||
- In 90% of networks, or networked systems, this is a grand-scale disaster... but for IPFS it's a very different story. Find out what happens in [a recent incident report published on the blog](https://blog.ipfs.tech/2023-ipfs-unresponsive-nodes/)!
|
||||
|
||||
[Introducing Rusty Lassie, a Rust wrapper for Lassie](https://crates.io/crates/lassie)
|
||||
|
||||
- A thin library embedding Lassie via CGo and FFI. With Rusty-Lassie, you can easily embed Lassie in your Rust project, start a Lassie HTTP server in a background thread, and retrieve CAR content using any HTTP client. [Learn more about the project here](https://crates.io/crates/lassie)!
|
||||
|
||||
## **IPFS Thing Track Recaps 📝**
|
||||
|
||||
[Recap: Content Routing (þing 2023)](https://blog.ipfs.tech/2023-ipfs-thing-content-routing-track/)
|
||||
|
||||
[Recap: Community & Governance (þing 2023)](https://blog.ipfs.tech/2023-ipfs-community-governance/)
|
||||
|
||||
[Recap: HTTP Gateways (þing 2023)](https://blog.ipfs.tech/2023-http-gateways-recap/)
|
||||
|
||||
[Recap: IPFS on the Web (þing 2023)](https://blog.ipfs.tech/2023-ipfs-thing-web-track/)
|
||||
|
||||
[libp2p at IPFS þing 2023 Recap](https://blog.libp2p.io/2023-libp2p-IPFS-Thing-recap/)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Founders Series, Episode 11: Juan Benet of Protocol Labs [Video]](https://www.youtube.com/watch?v=r-nU_MI2lV4)
|
||||
|
||||
- In this talk from LabWeek22 last November in Lisbon, Juan explains the importance of R&D, the lack of funding it receives, and how he hopes to solve this problem with the Protocol Labs Network, an ecosystem of teams based on open source, working together bridge what he calls the innovation chasm — the separation between research and deployment of product. [Watch it on YouTube!](https://www.youtube.com/watch?v=r-nU_MI2lV4)
|
||||
|
||||
[Filecoin & IPFS Ecosystem Roundup [Video]](https://youtu.be/kXnSklUL5NE)
|
||||
|
||||
- In this revamped monthly public video we give builders and community members a platform to share how they’re making web3 work better for all of us. Please [fill out this form](https://airtable.com/shrcadO9WAnQ5nJvA) to nominate a Team/Project to be featured as a 'Win of the Month'! Join us live the first Thursday of every month, and [watch the May round up now!](https://www.youtube.com/watch?v=kXnSklUL5NE)
|
||||
|
||||
[IPNS on Lighthouse](https://twitter.com/nanditmehra/status/1664317411313733634?s=20)
|
||||
|
||||
- IPNS support is now live on Lighthouse. Now build creative dapps with the world's best p2p tech for mutable data. Edit and upload your data and build dynamic NFT collections, mutable file systems, and much more with this IPNS support. [See the announcement on Twitter!](https://twitter.com/nanditmehra/status/1664317411313733634?s=20)
|
||||
|
||||
[IPFS Open Metaverse Base Camp Accelerator](https://twitter.com/OVioHQ/status/1662062713550299136?s=20)
|
||||
|
||||
- We're thrilled to announce the teams making up the latest IPFS Open Metaverse Base Camp accelerator cohort. This 12-week program will accelerate teams leveraging IPFS, Filecoin & [@fvmdev](https://twitter.com/fvmdev), paving the way forwards in the open data economy. [Read all about in this Twitter thead!](https://twitter.com/OVioHQ/status/1662062713550299136?s=20)
|
||||
|
||||
[Filebase for Startups](https://filebase.com/startups/)
|
||||
|
||||
- Filebase now has a program that offers complimentary IPFS storage and dedicated gateways for startups to scale with. You can learn more about it [on their website](https://filebase.com/startups/).
|
||||
|
||||
[Protocol Labs Launch Pad](https://protocol.ai/blog/launchpad-summit-paris-2023/)
|
||||
|
||||
- Launchpad is a blend of two key components: a dynamic four-week virtual learning cohort, where residents actively participate in remote learning seminars, and an unforgettable one-week in-person “colo” Summit. [Learn more on the Protocol Labs blog](https://protocol.ai/blog/launchpad-summit-paris-2023/)!
|
||||
|
||||
[HackFS kicked off on June 2](https://ethglobal.com/events/hackfs2023)
|
||||
|
||||
- Late last week, EthGlobal and Protocol Labs kicked off HackFS 2023 with an incredible summit featuring fireside chats on FVM, presentations on the Protocol Labs builders funnel, and even a talk from a surprise guest. [Check out the event's website to catchup](https://ethglobal.com/events/hackfs2023)!
|
||||
195
src/_blog/ipfs-uri-support-in-curl.md
Normal file
195
src/_blog/ipfs-uri-support-in-curl.md
Normal file
@@ -0,0 +1,195 @@
|
||||
---
|
||||
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.
|
||||
|
||||
199
src/_blog/major-improvements-to-omnilingo.md
Normal file
199
src/_blog/major-improvements-to-omnilingo.md
Normal file
@@ -0,0 +1,199 @@
|
||||
---
|
||||
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,6 +4,39 @@ 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:
|
||||
path: https://brave.com/nft-pinning/
|
||||
tags:
|
||||
- NFTs
|
||||
- Brave
|
||||
- pinning
|
||||
- title: WebTransport in libp2p
|
||||
date: 2022-12-19
|
||||
publish_date:
|
||||
|
||||
96
src/_blog/newsletter-195.md
Normal file
96
src/_blog/newsletter-195.md
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: Welcome to IPFS News 195!
|
||||
description: Featuring a deep-dive into the challenges of measuring decentralized networks + more!
|
||||
author: ''
|
||||
date: 2023-07-06
|
||||
permalink: "/newsletter-195"
|
||||
translationKey: ''
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
As we enter into the summer months, things are slowing down just a bit as people go on holiday or get some much needed R&R, but that doesn’t mean we don’t have plenty of things to share with you! From a deep-dive into [the challenges of measuring decentralized networks](https://pulse.internetsociety.org/blog/the-challenges-of-measuring-decentralized-networks-the-case-of-the-interplanetary-file-system) to news about Fission adding redirect support of IPFS, this month’s newsletter will keep you in the loop whether this edition finds you in the office, at home, or on the beach. 🏖️
|
||||
|
||||
Let’s jump in!
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Kubo 0.21.0](https://github.com/ipfs/kubo/releases/tag/v0.21.0)
|
||||
|
||||
- Saving previously seen nodes for later bootstrapping
|
||||
- Gateway: `DeserializedResponses` config flag
|
||||
- `client/rpc` migration of `go-ipfs-http-client`
|
||||
- Gateway: DAG-CBOR/-JSON previews and improved error pages
|
||||
- Gateway: subdomain redirects are now `text/html`
|
||||
- Gateway: support for partial CAR export parameters (IPIP-402)
|
||||
- `ipfs dag stat` deduping statistics
|
||||
- Accelerated DHT Client is no longer experimental
|
||||
|
||||
[The Challenges of Measuring Decentralized Networks: The Case of the InterPlanetary File System](https://pulse.internetsociety.org/blog/the-challenges-of-measuring-decentralized-networks-the-case-of-the-interplanetary-file-system)
|
||||
|
||||
- In this new blog post from the Internet Society's (ISOC) Pulse project, Yiannis Psaras of ProbeLab shares their experience measuring the stability, performance, and cartography of InterPlanetary File System (IPFS), one of the largest decentralized, P2P networks in operation. [Read it here!](https://pulse.internetsociety.org/blog/the-challenges-of-measuring-decentralized-networks-the-case-of-the-interplanetary-file-system)
|
||||
|
||||
[June Protocol Labs EngRes All Hands [Video]](https://www.youtube.com/watch?v=7fbhniQJjDw)
|
||||
|
||||
- The PL Engineering and Research (EngRes) Workgroup is formed by teams of core protocol developers, network researchers, and experienced contributors in the Protocol Labs Network. The PL EngRes WG mission is to scale and unlock new opportunities for IPFS, Filecoin, libp2p + IPLD, drive breakthroughs in protocol utility & capability, and scale network-native research & development across the PL Network. The PL EngRes WG hosts monthly all hands meetings to check in on progress, and showcase the growth and new capabilities being unlocked by these research & development teams. [Watch it here!](https://www.youtube.com/watch?v=7fbhniQJjDw)
|
||||
|
||||
[js-IPFS Deprecation Reminder: Move to Helia!](https://blog.ipfs.tech/202305-js-ipfs-deprecation-for-helia/)
|
||||
|
||||
- **js-IPFS is in the process of being deprecated** so you should port your apps to Helia to receive bug fixes, features, and performance improvements moving forwards. [Read more about it here!](https://blog.ipfs.tech/202305-js-ipfs-deprecation-for-helia/)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Fission adds redirect support for IPFS](https://fission.codes/blog/introducing-redirect-support-for-ipfs/)
|
||||
|
||||
- Fission is dedicated to building and improving on decentralized web protocols. Redirect support is an officially accepted improvement for IPFS that makes it easier to host modern web applications. [Learn more about it here!](https://fission.codes/blog/introducing-redirect-support-for-ipfs/)
|
||||
|
||||
[IPFS data integrated directly into a blockchain explorer](https://twitter.com/al_koii/status/1665817302279880706?s=20)
|
||||
|
||||
- Koii's distributed computing platform uses [web3.storage](https://t.co/KyqdyMsAQy) as a convenient integration for IPFS. Thanks to the lightning-fast w3link gateway and easy to use SDK, developers building on Koii have an extra edge as they implement P2P apps, distributed AI, and more. [Check it out in this Twitter thread!](https://twitter.com/al_koii/status/1665817302279880706?s=20)
|
||||
|
||||
[Elevate by Outlier Ventures](https://outlierventures.io/elevate/)
|
||||
|
||||
- Elevate is a virtual event series focused on spotlighting Outlier Ventures’ Base Camp Teams. Featuring talks from the very people driving Web3 forward, ELEVATE gives their partners, mentors, program experts and founders themselves an opportunity to showcase the progress they’ve made through their 12-week program. At the virtual event on July 6 (today!) you’ll be able to meet the builders onboarding the next billion users into the Open Metaverse, using IPFS. [Join the event here!](https://outlierventures.io/elevate/)
|
||||
|
||||
[ProbeLab Office Hours: IPFS Network Measurements](https://lu.ma/ipfs-network-measurements)
|
||||
|
||||
- These open office hours are for anyone interested in network measurements in the IPFS network. The session is hosted by the [ProbeLab](https://blog.ipfs.io/2022-06-15-probelab/) team. During this session, they will discuss issues related to ongoing projects and IPFS network measurement topics more generally with the community. If you're working or are interested in contributing, [make sure to join!](https://lu.ma/ipfs-network-measurements)
|
||||
|
||||
[IPFS Multi-Gateway Experiment in Chromium](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/?utm_content=253765483&utm_medium=social&utm_source=twitter&hss_channel=tw-3030006159)
|
||||
|
||||
- Learn about a new approach to implementing ipfs:// and ipns:// support natively in the browser, using a client-only approach and fetching verifiable responses from multiple HTTP gateways. [Check out the blog post!](https://blog.ipfs.tech/2023-05-multigateway-chromium-client/?utm_content=253765483&utm_medium=social&utm_source=twitter&hss_channel=tw-3030006159)
|
||||
|
||||
[Secure Curves in the Web Cryptography API](https://blogs.igalia.com/jfernandez/2023/06/20/secure-curves-in-the-web-cryptography-api/)
|
||||
|
||||
- A new blog post about the collaboration between [@igalia](https://twitter.com/igalia) and [@protocollabs](https://twitter.com/protocollabs) on the implementation of secure curves based on Curve25519 for the Web Cryptography specification. [Read it now!](https://blogs.igalia.com/jfernandez/2023/06/20/secure-curves-in-the-web-cryptography-api/)
|
||||
|
||||
[Where to find the Filecoin Community at EthCC](https://fil-paris.io/)
|
||||
|
||||
- Looking for the Filecoin community during EthCC? Check out [Filecoin Unleashed](https://filecoinunleashed.io) and [Fil Paris](https://fil-paris.io).
|
||||
|
||||
[Accelerate your Web3 journey: Protocol Labs Launchpad Summit on July 16-21](https://protocol.ai/blog/launchpad-summit-paris-2023/)
|
||||
|
||||
- Launchpad is a blend of two key components: a dynamic four-week virtual learning cohort, where residents actively participate in remote learning seminars, and an unforgettable one-week in-person “colo” Summit. **[Learn more on the Protocol Labs blog](https://protocol.ai/blog/launchpad-summit-paris-2023/)**
|
||||
|
||||
## HackFS Winners 🏅
|
||||
|
||||
This year’s [HackFS hackathon](https://ethglobal.com/events/hackfs2023) has come to a close, and several projects were selected as winners for the IPFS category. If you missed it, [learn more about HackFS here](https://ethglobal.com/events/hackfs2023).
|
||||
|
||||
Introducing the HackFS 2023 winners for IPFS…
|
||||
|
||||
[Web3Stash](https://ethglobal.com/showcase/web3stash-mn6iu) by [@mbcse50](https://twitter.com/mbcse50)
|
||||
|
||||
- Web3Stash is a standard library to get a single API to connect to multiple decentralized storage service providers. [Check it out here!](https://ethglobal.com/showcase/web3stash-mn6iu)
|
||||
|
||||
[unid.store](https://t.co/xbh9zYbjm9) by [@_Difint_](https://twitter.com/_Difint_)and [@mr13tech](https://twitter.com/mr13tech)
|
||||
|
||||
- Super simple file sharing - decentralized, quick, and without registration. [Take a look here!](https://ethglobal.com/showcase/unid-store-2yukr)
|
||||
|
||||
[Fileblox](https://ethglobal.com/showcase/fileblox-y0rjm) by [@Lycaoncreatives](https://twitter.com/LycaonCreatives), [@raldblox](https://twitter.com/raldblox), and [@luckscientist](https://twitter.com/luckscientist)
|
||||
|
||||
- FileBlox enables the creation of encrypted NFTs. It solves the right-click-and-save problem for our content creators while letting them get all the benefits of tokenization. [Learn more here!](https://ethglobal.com/showcase/fileblox-y0rjm)
|
||||
|
||||
[Star Streamer](https://ethglobal.com/showcase/star-streamer-huakw) by [@msakiart](https://twitter.com/msakiart)
|
||||
|
||||
- P2P video streaming service for decentralized content sharing with libp2p, ipfs and hypercore. [Check it out here!](https://ethglobal.com/showcase/star-streamer-huakw)
|
||||
73
src/_blog/newsletter-196.md
Normal file
73
src/_blog/newsletter-196.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Welcome to IPFS News 196!
|
||||
description: Featuring news about a resilient and fully-automated infrastructure to monitor the performance of the IPFS network.
|
||||
author: ''
|
||||
date: 2023-08-09
|
||||
permalink: "/newsletter-196"
|
||||
translationKey: ''
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **An Observatory for the IPFS Network 🔭**
|
||||
|
||||
We're excited to share that the ProbeLab team has worked hard over the past year to build a resilient and fully-automated infrastructure to monitor the performance of core IPFS stack protocols. The debut of this new measurement platform is big news, and you can learn all about it in a new post on the IPFS blog.
|
||||
|
||||
<a href="https://blog.ipfs.tech/2023-ipfs-observatory/" class="cta-button">Read the blog post</a>
|
||||
|
||||

|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[A Rusty Bootstrapper](https://blog.ipfs.tech/2023-rust-libp2p-based-ipfs-bootstrap-node/)
|
||||
|
||||
- As of July 13, 2023, one of the four "public good" IPFS bootstrap nodes operated by Protocol Labs has been running rust-libp2p-server instead of Kubo, which uses go-libp2p. rust-libp2p-server is a thin wrapper around rust-libp2p. We run both Kubo and rust-libp2p-server on IPFS bootstrap nodes to increase resilience. [Read more about it on the IPFS blog!](https://blog.ipfs.tech/2023-rust-libp2p-based-ipfs-bootstrap-node/)
|
||||
|
||||
[Dogfooding Announcement: IPFS-Companion Manifest v3 Changes](https://discuss.ipfs.tech/t/announcing-ipfs-companion-mv3-rc-beta/16442/7)
|
||||
|
||||
- The PL EngRes Ignite team has achieved a significant milestone – the completion of IPFS-Companion Manifest v3 changes! IPFS-Companion is browser extension that makes browsing the IPFS web simpler. These changes promise to greatly enhance compatibility with browsers going forward and offer performance improvements. [Read about it and get involved here!](https://discuss.ipfs.tech/t/announcing-ipfs-companion-mv3-rc-beta/16442/7)
|
||||
|
||||
[IPFS Events Planning Meeting](https://lu.ma/ipfseventsplanning)
|
||||
|
||||
- The events team is kicking off a new Events Planning Call today. If you're interested in joining or participating, you can find these meetings on the [IPFS Community Calendar](lu.ma/ipfs), or you can register directly at [lu.ma/ipfseventsplanning](lu.ma/ipfseventsplanning). Today's agenda will be to discuss timing for IPFS Camp and Thing for 2024. Timing will affect the locations that make the shortlist. [Join us here!](https://lu.ma/ipfseventsplanning)
|
||||
|
||||
[Boxo v0.11.0](https://github.com/ipfs/boxo/blob/release-v0.11.0/CHANGELOG.md)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[Guide: Setting Up a Website on the Distributed Web using Distributed Press](https://medium.com/@lindsay_walker/setting-up-a-website-on-the-distributed-web-7eae22594303)
|
||||
|
||||
- Distributed Press is a tool used to easily host content on distributed, peer-to-peer protocols such as IPFS and Hypercore, using open source tools created by the Distributed Press project. Publishing a static site on distributed protocols means that your website is more resilient and likely to stand the test of time. [Learn how to do it here!](https://medium.com/@lindsay_walker/setting-up-a-website-on-the-distributed-web-7eae22594303)
|
||||
|
||||
[Anytype: A private hub for all your data](https://anytype.io/)
|
||||
|
||||
- Meet Anytype, a private hub for all your data: docs, tasks, files, bookmarks, contacts and more. It’s built on a new architecture that protects your privacy and data sovereignty, even when working across devices. Use it to create elegant dashboards, documents, and knowledge graphs. [Try it out here!](https://anytype.io/)
|
||||
|
||||
[Fleek Network announces new edge platform](https://twitter.com/fleek_net/status/1685997861907890176)
|
||||
|
||||
- Fleek Network's new platform utilizes IPFS/IPLD as the addressability and performance layer of data on the network. [Learn more here!](https://twitter.com/fleek_net/status/1685997861907890176)
|
||||
|
||||
[Admarus: A Peer-to-Peer Search Engine for IPFS](https://blog.admarus.net/blog/mvp-release/)
|
||||
|
||||
- A decentralized search engine for the decentralized web (specifically, IPFS). [Check it out here!](https://blog.admarus.net/blog/mvp-release/)
|
||||
|
||||
[Beloga: A Decentralized Blogging Platform](https://discuss.ipfs.tech/t/beloga-decentralized-blogging-platform-powered-by-ipfs/16727)
|
||||
|
||||
- This new blogging platform has IPFS at its core with posts being securely stored and decentralized, making them tamper-proof and censorship-resistant. [See it for yourself here!](https://discuss.ipfs.tech/t/beloga-decentralized-blogging-platform-powered-by-ipfs/16727)
|
||||
|
||||
[Filebase introduces custom comain support for dedicated IPFS gateways](https://filebase.com/blog/introducing-custom-domain-support-for-dedicated-ipfs-gateways/)
|
||||
|
||||
- With the introduction of custom domain support, users can now attach their domain names to their dedicated gateways, bolstering their brand consistency and accessibility. [Learn more about it in this blog post announcement!](https://filebase.com/blog/introducing-custom-domain-support-for-dedicated-ipfs-gateways/)
|
||||
|
||||
[IPFSnodes.com](https://ipfsnodes.com/)
|
||||
|
||||
- A community created dashboard with lots of data and information about the IPFS network and its nodes. [Take a look at it here!](https://ipfsnodes.com/)
|
||||
|
||||
[Open Data Hackathon](https://www.encode.club/open-data-hack)
|
||||
|
||||
- This upcoming hackathon features a $1,000 IPFS bounty. [Learn more and get involved here!](https://www.encode.club/open-data-hack)https://www.encode.club/open-data-hack
|
||||
|
||||
[The Evolution of Filecoin and IPFS: An Overview of Challenges and Future Opportunities](https://medium.com/filemarket-xyz/the-evolution-of-filecoin-and-ipfs-an-overview-of-challenges-and-future-opportunities-795ce237c4b6)
|
||||
|
||||
- A new article on FileMarket about the evolution of Filecoin and IPFS that is based on an AMA with Juan Benet during Filecoin Unleashed Paris 2023. Read through it here!
|
||||
52
src/_blog/newsletter-197.md
Normal file
52
src/_blog/newsletter-197.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
title: Welcome to IPFS News 197!
|
||||
description: Featuring an announcement about the new Ecosystem Working Group and Kubo v0.22.0
|
||||
author: ''
|
||||
date: 2023-09-12
|
||||
permalink: "/newsletter-197"
|
||||
translationKey: ''
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
## **Introducing the Ecosystem Working Group 🔭**
|
||||
|
||||
Since its initial release over 9 years ago, IPFS has been stewarded by a variety of teams and individual contributors, both within and outside of Protocol Labs. More recently though, it has lacked a dedicated team focused on nothing other than the success of the IPFS ecosystem. It is with this reality in mind that we are excited to announce the formation of **[the brand new IPFS Ecosystem Working Group](https://blog.ipfs.tech/2023-introducing-the-ecosystem-working-group/)**!
|
||||
|
||||
<a href="https://blog.ipfs.tech/2023-introducing-the-ecosystem-working-group/" class="cta-button">Read the blog post</a>
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
[Kubo v0.22.0](https://github.com/ipfs/kubo/releases/tag/v0.22.0)
|
||||
|
||||
- Gateway: support for order= and dups= parameters (IPIP-412)
|
||||
- ipfs name publish now supports V2 only IPNS records
|
||||
- IPNS name resolution has been fixed
|
||||
- go-libp2p v0.29.0 update with smart dialing
|
||||
|
||||
[IPFSConnect Istanbul](https://istanbul2023.ipfsconnect.org/)
|
||||
|
||||
- Have you checked out [IPFSConnect](https://twitter.com/IPFSConnect) yet? It's a community-run meetup of developers and designers building on top of IPFS. Join us in Istanbul on Nov 16th for a day of workshops + talks! [Learn more here!](https://istanbul2023.ipfsconnect.org/)
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
[LabWeek23 is happening November 13-17](https://23.labweek.io/)
|
||||
|
||||
- Have you booked your travel yet? [LabWeek23](https://23.labweek.io/) 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/)
|
||||
|
||||
[A Beginner's Guide to IPFS Content Addressing](https://filebase.com/blog/a-beginners-guide-to-ipfs-content-addressing/)
|
||||
|
||||
- Learn how to harness the power of the InterPlanetary File System for seamless content distribution by checking out this comprehensive guide to IPFS content addressing by Filebase. [Read it here!](https://filebase.com/blog/a-beginners-guide-to-ipfs-content-addressing/)
|
||||
|
||||
[Fleek's new app is in closed alpha](https://blog.fleek.xyz/post/fleekxyz-alpha-release/)
|
||||
|
||||
- "The day is finally here–the first step of the new Fleek, both app and brand ⚡ Let’s set the stage: This is not the full release of the new Fleek app. Today marks the start of our initial closed testing phase, leading up to an open testing period, and later in September, the full v1 release of the new app." [Learn more in this blog post!](https://blog.fleek.xyz/post/fleekxyz-alpha-release/)
|
||||
|
||||
[New git-ipfs remote bridge](https://twitter.com/momack28/status/1697072752266706979?s=20)
|
||||
|
||||
- "Love git and IPFS? There's a new git-ipfs remote bridge that lets you snapshot new git releases to IPFS for self-hosting, immutable versioning, and decentralized replication. Go InterPlanetary!" [Check it out here!](https://github.com/ElettraSciComp/Git-IPFS-Remote-Bridge)
|
||||
|
||||
[Encrypted file support will be added to Cedalio soon](https://medium.com/@cedalio/product-update-uploading-files-has-never-been-easier-7b328def728a)
|
||||
|
||||
- "Introducing the ability to define file types within your GraphQL schema, while we handle the rest. To stay in sync with our company core values, we store files in IPFS, a decentralized peer-to-peer protocol for storing and sharing files across a distributed network. As of now, files stored in IPFS are not encrypted; however, we’re excited to announce that support for encryption will be added in early October." [Learn more via their product update!](https://medium.com/@cedalio/product-update-uploading-files-has-never-been-easier-7b328def728a)
|
||||
78
src/_blog/newsletter-198.md
Normal file
78
src/_blog/newsletter-198.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
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.
|
||||
|
||||
91
src/_blog/newsletter-199.md
Normal file
91
src/_blog/newsletter-199.md
Normal file
@@ -0,0 +1,91 @@
|
||||
---
|
||||
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>
|
||||
85
src/_blog/newsletter-200.md
Normal file
85
src/_blog/newsletter-200.md
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
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>
|
||||
76
src/_blog/newsletter-201.md
Normal file
76
src/_blog/newsletter-201.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
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>
|
||||
73
src/_blog/newsletter-202.md
Normal file
73
src/_blog/newsletter-202.md
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
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>
|
||||
55
src/_blog/newsletter-203.md
Normal file
55
src/_blog/newsletter-203.md
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
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>
|
||||
76
src/_blog/newsletter-204.md
Normal file
76
src/_blog/newsletter-204.md
Normal file
@@ -0,0 +1,76 @@
|
||||
---
|
||||
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>
|
||||
112
src/_blog/newsletter-205.md
Normal file
112
src/_blog/newsletter-205.md
Normal file
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: "🌳 IPFS Newsletter 205: HTTP, P2P in browsers, Kubo speedup & more"
|
||||
description: "The IPFS Newsletter is back, with many exciting updates to share: HTTP support across the IPFS stack, P2P in browsers, Kubo speedup, and more."
|
||||
date: 2025-05-23
|
||||
permalink: "/newsletter-205"
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
Welcome back to the IPFS Newsletter! After a hiatus, we have many exciting updates to share.
|
||||
|
||||
### More HTTP Support Across the IPFS Stack
|
||||
|
||||
Multiple IPFS libraries are embracing or adding support for HTTP (usually in addition to Bitswap). Benefits include lower data provision costs, easier integration with existing HTTP libraries and services, and seamless web compatibility.
|
||||
|
||||
- [Kubo](https://github.com/ipfs/kubo) added support for trustless HTTP retrieval on an opt-in basis in [v0.35](https://github.com/ipfs/kubo/releases/tag/v0.35.0).
|
||||
- [Rainbow](https://github.com/ipfs/rainbow), the high performance HTTP Gateway implementation, added support for trustless HTTP retrieval in [v1.12](https://github.com/ipfs/rainbow/releases/tag/v1.12.0).
|
||||
- Helia, [@helia/verified-fetch](https://github.com/ipfs/helia-verified-fetch) and the [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway) already support trustless HTTP retrieval.
|
||||
- [RASL](https://dasl.ing/rasl.html) includes a simple HTTP-based retrieval method.
|
||||
|
||||
The next step is adding support for HTTP providing to the DHT ([issue #496](https://github.com/ipfs/specs/issues/496)). This would let nodes announce themselves as HTTP providers alongside or instead of Bitswap.
|
||||
|
||||
### Service Worker Gateway Provides P2P Capabilities in the Browser
|
||||
|
||||
The [Service Worker Gateway](https://github.com/ipfs/service-worker-gateway) is a browser-based IPFS gateway that uses Service Workers to handle p2p retrieval, hash verification, and other IPFS functionality. Try it out at [inbrowser.link](https://inbrowser.link).
|
||||
|
||||
The Service Worker Gateway has been getting a lot of love recently: [v1.12](https://github.com/ipfs/service-worker-gateway/releases/tag/v1.12.0) includes configurable timeouts, better error pages, and a signed binary for local deployment. For a deep dive, check out the [Service Workers for IPFS on the Web](https://youtu.be/qtIJXRgxjVA?feature=shared) video. ([Shipyard](https://ipshipyard.com/))
|
||||
|
||||
### Drop-in Service Worker Example for App Developers
|
||||
|
||||
Here's a [drop-in service worker example](https://github.com/ipshipyard/drop-in-service-worker). It intercepts hardcoded requests to centralized gateways, using [@helia/verified-fetch](https://github.com/ipfs/helia-verified-fetch) to retrieve and verify content directly from peers. ([Shipyard](https://ipshipyard.com/))
|
||||
|
||||
### IPNI Service Update
|
||||
|
||||
The [IPNI](https://docs.ipfs.tech/concepts/ipni/), a content routing index for large content providers, suffered service degradation in April, disrupting the ability to find providers for CIDs. The IPNI team has made hardware and software improvements to avoid future disruptions, and service is improving as the newly-upgraded indexers catch up.
|
||||
|
||||
In the interim, a [new feature](https://github.com/ipfs/someguy/pull/110) in [Someguy](https://github.com/ipfs/someguy) allows large content providers to run a self-hosted [HTTP delegated routing](https://specs.ipfs.tech/routing/http-routing-v1) endpoint, providing an immediate remedy until IPNI service was restored.
|
||||
|
||||
Join the `#ipni` channel on the [Filecoin Slack](https://filecoin.io/slack) to follow along. A Content Routing WG will be meeting biweekly. More: [background](https://hackmd.io/sRmr-vnPRH2THaPxMIoKjA) & [latest notes](https://hackmd.io/Zxem7bVBRB6ZVDnaqS_kmw).
|
||||
|
||||
### 20-40x Speedup for Data Onboarding in Kubo
|
||||
|
||||
In the past, adding data to Kubo with `ipfs add` while Kubo was running was slow due to inefficient provider queue handling. A [new optimization](https://github.com/ipfs/boxo/pull/888) in Boxo yields a 20-40x speedup (higher for larger datasets), making it easier to onboard large data sets while Kubo is running. Available in [Kubo v0.35](https://github.com/ipfs/kubo/blob/release-v0.35.0/docs/changelogs/v0.35.md). ([Shipyard](https://ipshipyard.com/))
|
||||
|
||||
## Protocol and Standards
|
||||
|
||||
### DASL and IETF Draft for CBOR/c-42
|
||||
|
||||
[DASL](https://dasl.ing) (Data-Addressed Structures & Links) is a small set of specs for working with content-addressed, linked data. First released in December 2024, DASL now includes sub-specs for encoding (CID and dCBOR42, which are strict subsets of IPFS CIDs and IPLD), metadata ([MASL](https://dasl.ing/masl.html)), and retrieval ([RASL](https://dasl.ing/rasl.html)) of content addressed data.
|
||||
|
||||
[The tag-42 profile of CBOR Core](https://datatracker.ietf.org/doc/draft-caballero-cbor-cborc42/) was submitted as an IETF Draft on 22 May, paving the way for web-wide standardization of CBOR/c-42 and CIDs. (IPFS Foundation)
|
||||
|
||||
### Practical Interoperability for CIDs
|
||||
|
||||
The original [CID specification](https://github.com/multiformats/cid) was designed for flexibility and future-proofing, supporting various encodings, graph widths, and optimizations. In practice, this flexibility yields multiple CIDs for the same input, making it challenging to establish CID equivalency for the same data across implementations.
|
||||
|
||||
Efforts are underway to increase practical interop without losing futureproofing: [IPIP-499: CID Profiles](https://github.com/ipfs/specs/pull/499) proposes a set of standard profiles for UnixFS, and [Kubo v0.35](https://github.com/ipfs/kubo/releases/tag/v0.35.0) adds [new config options](https://github.com/ipfs/boxo/pull/906) towards this goal. For more context, see the lively [forum thread](https://discuss.ipfs.tech/t/should-we-profile-cids/18507).
|
||||
|
||||
### Amino DHT Spec
|
||||
|
||||
The Amino DHT is a distributed key-value store used for peer and content routing records within IPFS Mainnet. It extends the libp2p Kademlia DHT with IPFS-specific features, such as CIDs and IPNS records. Until recently, it had no formal spec beyond the [libp2p Kademlia DHT spec](https://github.com/libp2p/specs/blob/master/kad-dht/README.md).
|
||||
|
||||
[PR #497](https://github.com/ipfs/specs/pull/497) addresses this gap with the goal of improving interoperability, security, and clarity across implementations. ([Shipyard](https://ipshipyard.com/))
|
||||
|
||||
## Code and Tools
|
||||
|
||||
### 🚢 Releases
|
||||
|
||||
- [kubo 0.35](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.35.md) & [0.34](https://github.com/ipfs/kubo/blob/master/docs/changelogs/v0.34.md) — Lots of new features, including opt-in HTTP retrieval, new data import options that help with CID equivalency, easi, [AutoTLS](https://blog.libp2p.io/autotls/), and performance improvements to bitswap, providing, and data onboarding commands. `ipfs add` is now 20-40x faster.
|
||||
- [helia 5.4.1](https://www.npmjs.com/package/helia) — New usability improvements to the [`unixfs.stat` command](https://github.com/ipfs/helia/pull/760), and a [new option allowing finer control](https://github.com/ipfs/helia/pull/772) in how gateways are picked for block retrieval. Additionally, a bug fix in js-libp2p ensures abort signals passed to network operations are properly handled.
|
||||
- [IPFS Cluster v1.1.4](https://github.com/ipfs-cluster/ipfs-cluster/releases/tag/v1.1.4) — A maintenance release fixes the IPFS Cluster Docker image for arm64 architectures.
|
||||
- [Rainbow v1.13](https://github.com/ipfs/rainbow/releases/tag/v1.13.0) & [v1.12](https://github.com/ipfs/rainbow/releases/tag/v1.13.0) — Support for HTTP retrieval and a new option to control http providers.
|
||||
- [Boxo v0.30.0](https://github.com/ipfs/boxo/releases/tag/v0.30.0) — The reference library shared by Kubo and Rainbow adds support for custom UnixFS DAG width and the ability to enable/disable the bitswap server.
|
||||
- [Someguy v0.9.1](https://github.com/ipfs/someguy/releases/tag/v0.9.0) — The Delegated Routing API server implementation adds support for probing HTTP gateway endpoints and returning those as providers.
|
||||
- [Service Worker Gateway v1.12](https://github.com/ipfs/service-worker-gateway/releases/tag/v1.12.0) — Configurable timeouts, useful debug info on error pages, and more.
|
||||
|
||||
|
||||
### Ecosystem Spotlights
|
||||
|
||||
- [Helia 101 examples for Node.js](https://github.com/ipfs-examples/helia-examples/tree/main/examples/helia-101) is overhauled with many new examples: getting started with Helia, pinning, IPNS, and more.
|
||||
- [iroh v0.35](https://www.iroh.computer/blog/iroh-0-35-prepping-for-1-0) — The last planned version before the 1.0 release candidate later this year.
|
||||
- [Seed Hypermedia](https://seed.hyper.media), an open protocol and app for authorship and collaboration, published [a new blog post](https://seed.hyper.media/blog/collaborating-on-the-web-with-seed-hypermedia-protocol-and-ipfs) describing core principles and new features in the [Seed Hypermedia App](https://seed.hyper.media/hm/download), which features a clean, thoughtfully designed interface.
|
||||
- [Peergos 1.3](https://github.com/Peergos/web-ui/releases/tag/v1.3.0) — the p2p, secure file storage, social network and application protocol releases a new sync gui and api for managing the sync client.
|
||||
- Good news for WebTransport: `serverCertificateHashes`, a feature in the [WebTransport](https://blog.ipfs.tech/2024-shipyard-improving-ipfs-on-the-web/#webtransport) spec, necessary for browsers to connect to IPFS nodes over WebTransport without CA-signed TLS certs, was considered for removal. After a [lengthy discussion, the WebKit team agreed to implement it](https://github.com/w3c/webtransport/issues/623#issuecomment-2895955428), which means Safari users will also benefit from direct WebTransport connections to IPFS nodes.
|
||||
- [TeaTime](https://github.com/bjesus/teatime) is a static distributed library system powered by IPFS, SQLite and GitHub.
|
||||
- [js-blockstore-opfs](https://github.com/dozyio/js-blockstore-opfs) is an [Origin Private File System (OSPF)](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system) TS/JS blockstore implementation for use with Helia and js-libp2p in the browser. ([@dozyio](https://github.com/dozyio))
|
||||
- [Distributed Press](https://distributed.press/), a publishing tool for the distributed web, is [migrating to Helia](https://github.com/hyphacoop/api.distributed.press/pull/101).
|
||||
|
||||
## Services and Providers
|
||||
|
||||
- [Filebase launches IPFS RPC API Support](https://filebase.com/blog/introducing-support-for-the-ipfs-rpc-api) with Kubo-compatible endpoints to simplify integration with existing tools -- no node management required. ([Docs](https://docs.filebase.com/api-documentation/ipfs-rpc-api)).
|
||||
- [Filebase launches Real-Time Gateway Activity Streams](https://filebase.com/blog/introducing-ipfs-gateway-activity-streams) (v0), providing real-time visibility into IPFS gateway traffic, including IPs and status codes.
|
||||
- [Bluesky Backups by Storacha](https://bsky.storage/): This beta webapp [saves regular snapshots](https://www.youtube.com/watch?v=CIym-b-DA5s) of your ATProto data and installs a recovery key into your [DID PLC profile](https://github.com/did-method-plc/did-method-plc), bringing true credible exit to Bluesky. [Github repo](https://github.com/storacha/bluesky-backup-webapp-server).
|
||||
|
||||
### Articles and Tutorials
|
||||
|
||||
- 🎥 [Deploy Static Apps and Websites to IPFS with Github Actions](https://www.youtube.com/watch?v=ZRrPBqqFKFU). Whether you're using React, Vuepress, Astro, Next.js, or any other static site generator, the [IPFS Deploy Action](https://github.com/marketplace/actions/deploy-to-ipfs) will help you get your web application deployed on IPFS. Here's the [docs page](https://docs.ipfs.tech/how-to/websites-on-ipfs/deploy-github-action/#what-is-the-ipfs-deploy-action) and [video](https://www.youtube.com/watch?v=ZRrPBqqFKFU). (Daniel Norman, Shipyard)
|
||||
- 🎥 [Service Workers for IPFS on the Web](https://youtu.be/qtIJXRgxjVA?feature=shared). Deep dive into Service Workers, how they help IPFS on the Web, and how to use Service Workers today for verified peer-to-peer retrieval on the Web. (Daniel Norman, Shipyard)
|
||||
- 📘 [Setup a DNSLink Gateway to serve static sites on IPFS with Kubo and Caddy](https://docs.ipfs.tech/how-to/websites-on-ipfs/dnslink-gateway/).
|
||||
- [Smaller Hash BTrees](https://piss.beauty/post/smaller-hash-btrees) — Insightful blog post delving into optimization techniques to reduce the size of BTree indices when storing CIDs (using a real dataset from [ATProto](https://atproto.com/guides/glossary#cid-content-id)) in a PostgreSQL database. ([Stellz](https://bsky.app/profile/piss.beauty))
|
||||
|
||||
## Community & Events
|
||||
|
||||
- [Grantees Announced for Spring 2025 IPFS Utility Grants](https://blog.ipfs.tech/2025-05-grants/) — 3 grantees were selected: `rsky-satnav` CAR Explorer (Rudy Fraser, Blacksky), CAR Indexing Tools (Ben Lau, Basile Simon, & Yurko Jaremko, Starling Lab), and DASL Interop Testing (Cole Anthony Capilongo, Hypha Co-op), who will be presenting their work at [CID Congress #3](https://lu.ma/ofjr7mgd).
|
||||
- [USER * AGENTS * BERLIN](https://lu.ma/v457jxp2?tk=8UZBKL) (May 29-30, Berlin) — Chat or cowork with people interested in maximizing user agency in everyday software, and meet long-time contributors to the IPFS ecosystem.
|
||||
- [Hashberg: A Content Addressing Architectures Summit](https://lu.ma/nbv106v5) (June 11, Berlin) — An intimate, 1-day event to collaborate on critical topics across the IPFS ecosystem.
|
||||
- [Protocol Berg v2](https://protocol.berlin/) (June 12-13, Berlin) — Several talks on IPFS.
|
||||
- [JS Nation 2025](https://jsnation.com/#person-daniel-norman) (June 16, Virtual) — "Demystifying IPFS: A Web Developer's Guide to Content Distribution"
|
||||
- [CID Congress #3](https://lu.ma/ofjr7mgd) (June 25, Virtual)
|
||||
|
||||
If you made it this far, thanks for reading!
|
||||
@@ -1,5 +1,225 @@
|
||||
---
|
||||
data:
|
||||
- title: 'Just released: Kubo 0.40.0!'
|
||||
date: "2026-02-25"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.40.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.39.0!'
|
||||
date: "2025-11-27"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.39.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.38.2!'
|
||||
date: "2025-10-30"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.38.2
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.38.1!'
|
||||
date: "2025-10-08"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.38.1
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.38.0!'
|
||||
date: "2025-10-02"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.38.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.37.0!'
|
||||
date: "2025-08-27"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.37.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- telemetry
|
||||
- autoconf
|
||||
- title: 'Just released: Kubo 0.36.0!'
|
||||
date: "2025-07-14"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.36.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.35.0!'
|
||||
date: "2025-05-21"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.35.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.34.1!'
|
||||
date: "2025-03-25"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.34.1
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- AutoTLS
|
||||
- title: 'Just released: Kubo 0.34.0!'
|
||||
date: "2025-03-20"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.34.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- AutoTLS
|
||||
- title: 'Announcing AutoTLS: Bridging IPFS and the Web'
|
||||
date: "2025-02-17"
|
||||
publish_date: null
|
||||
path: https://blog.libp2p.io/autotls/
|
||||
card_image: "/libp2p_WebTransport_Blog_Header.png"
|
||||
tags:
|
||||
- AutoTLS
|
||||
- IPFS
|
||||
- libp2p
|
||||
- libp2p.direct
|
||||
- Let's Encrypt
|
||||
- TLS
|
||||
- Interplanetary Shipyard
|
||||
- title: 'Just released: Kubo 0.33.2!'
|
||||
date: "2025-02-14"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.33.2
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.33.1!'
|
||||
date: "2025-02-04"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.33.1
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: IPFS Desktop 0.41.0 with AutoTLS!'
|
||||
date: "2025-01-31"
|
||||
path: https://github.com/ipfs/ipfs-desktop/releases/tag/v0.41.0
|
||||
tags:
|
||||
- IPFS Desktop
|
||||
- AutoTLS
|
||||
- title: 'Just released: Kubo 0.33.0!'
|
||||
date: "2025-01-29"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.33.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- AutoTLS
|
||||
- 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
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.22.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.21.0!'
|
||||
date: "2023-07-03"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.21.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.20.0!'
|
||||
date: "2023-05-09"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.20.0
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.19.2!'
|
||||
date: "2023-05-03"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.19.2
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.19.1!'
|
||||
date: "2023-04-05"
|
||||
publish_date: null
|
||||
path: https://github.com/ipfs/kubo/releases/tag/v0.19.1
|
||||
tags:
|
||||
- go-ipfs
|
||||
- kubo
|
||||
- title: 'Just released: Kubo 0.19.0!'
|
||||
date: "2023-03-20"
|
||||
publish_date: null
|
||||
|
||||
395
src/_blog/shipyard-2024.md
Normal file
395
src/_blog/shipyard-2024.md
Normal file
@@ -0,0 +1,395 @@
|
||||
---
|
||||
date: 2024-11-25
|
||||
permalink: /2024-shipyard-improving-ipfs-on-the-web/
|
||||
canonicalUrl: https://ipshipyard.com/blog/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
|
||||
- Interplanetary Shipyard
|
||||
---
|
||||
|
||||
## 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/master/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.
|
||||
117
src/_blog/shipyard-hello-world.md
Normal file
117
src/_blog/shipyard-hello-world.md
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
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/'
|
||||
canonicalUrl: https://ipshipyard.com/blog/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. [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.
|
||||
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.
|
||||
|
||||
### 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 [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.
|
||||
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.
|
||||
|
||||
### 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,6 +4,16 @@ 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:
|
||||
|
||||
234
src/_blog/verified-fetch.md
Normal file
234
src/_blog/verified-fetch.md
Normal file
@@ -0,0 +1,234 @@
|
||||
---
|
||||
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,11 +4,68 @@ type: Video
|
||||
sitemap:
|
||||
exclude: true
|
||||
data:
|
||||
- title: 'Service Workers for IPFS on the Web'
|
||||
date: 2025-05-21
|
||||
publish_date: 2025-05-21T10:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=qtIJXRgxjVA
|
||||
tags:
|
||||
- IPFS Deploy Action
|
||||
- tutorial
|
||||
- IPFS Gateway
|
||||
- Service Worker Gateway
|
||||
- dapps
|
||||
- title: 'Deploy Static Apps and Websites to IPFS with GitHub Actions'
|
||||
date: 2025-04-04
|
||||
publish_date: 2025-04-04T10:00:00+00:00
|
||||
path: https://www.youtube.com/watch?v=ZRrPBqqFKFU
|
||||
tags:
|
||||
- IPFS Deploy Action
|
||||
- tutorial
|
||||
- guide
|
||||
- dapps
|
||||
- GitHub Actions
|
||||
- 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) [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/).
|
||||
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/).
|
||||
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 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).
|
||||
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).
|
||||
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.
|
||||
|
||||
@@ -69,4 +69,4 @@ If you meet any of the above criteria, please [submit this eligibility form ](ht
|
||||
* [Learn how to throw your ebook library at IPFS](https://dustri.org/b/how-to-throw-your-ebook-library-at-ipfs.html) in this recently released tutorial.
|
||||
* [Academic research on implementing Swarm’s Alpha Entanglement in IPFS](https://twitter.com/IPFS/status/1633367698724798464?s=20) using IPFS Cluster to increase reliability.
|
||||
* [Fireproof](https://twitter.com/FireproofStorge) is a new dynamic database product created by [@jchris](https://twitter.com/jchris) that has IPFS at its core. Use it to quickly add dynamic data to any app or page.
|
||||
* [A new tool](https://nouns.build) from Zora called Nouns Builder enables anyone to create a Nouns-style DAO without any code. The best part? It utilizes the power of IPFS. The next generation of DAOs will have a solid data foundation.
|
||||
* [A new tool](https://nouns.build) from Zora called Nouns Builder enables anyone to create a Nouns-style DAO without any code. The best part? It utilizes the power of IPFS. The next generation of DAOs will have a solid data foundation.
|
||||
|
||||
78
src/_blog/welcome-to-ipfs-news-193.md
Normal file
78
src/_blog/welcome-to-ipfs-news-193.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Welcome to IPFS News 193!
|
||||
description: Featuring Bluesky, a recap of IPFS Thing 2023, Brave's enhanced IPFS support, content blocking in Kubo, and much more!
|
||||
author: ''
|
||||
date: 2023-05-09
|
||||
permalink: "/newsletter-193"
|
||||
translationKey: ''
|
||||
header_image: "/ipfsnews.png"
|
||||
tags:
|
||||
- newsletter
|
||||
---
|
||||
|
||||
A lot has happened since the previous newsletter over a month ago. [IPFS Thing took place in Brussels](https://blog.ipfs.tech/2023-ipfs-thing-recap/), we created a [Bluesky](https://blog.ipfs.tech/2023-ipfs-on-bluesky/) account, [Brave released automatic NFT backups to IPFS](https://brave.com/nft-pinning/), [content blocking can now be enabled in Kubo](https://blog.ipfs.tech/2023-content-blocking-for-the-ipfs-stack/), plus so much more! Read on to catch up with what’s happened in the ecosystem over the last few weeks.
|
||||
|
||||
## **Recap: IPFS Thing 2023 🔄**
|
||||
|
||||
The IPFS implementers community recently gathered in Brussels, Belgium for the second year of [IPFS þing](https://2023.ipfs-thing.io/), an annual gathering dedicated to advancing IPFS implementation. With 12 tracks and over 75 talks, demos, and sessions, the 5-day summit that occurred in April 2023 was a showcase of recent advances across IPFS, a forum for sharing needs from the protocol, and an opportunity to chart new directions for the future of IPFS.
|
||||
|
||||
[Read the recap on the blog for photos, videos, and summaries!](https://blog.ipfs.tech/2023-ipfs-thing-recap/)
|
||||
|
||||
## **Brand New on IPFS ✨**
|
||||
|
||||
**[IPFS is now on Bluesky!](https://blog.ipfs.tech/2023-ipfs-on-bluesky/)**
|
||||
|
||||
* We’re excited to share that IPFS now has an official presence on [Bluesky](https://blueskyweb.xyz/)! We chose[ ](https://twitter.com/bluesky)Bluesky because it shares many of the same values and goals that the IPFS ecosystem has. Additionally, they actively utilize IPLD and content addressing. [Read more about it](https://blog.ipfs.tech/2023-ipfs-on-bluesky/)!
|
||||
|
||||
**[Content Blocking for the IPFS stack is finally here!](https://blog.ipfs.tech/2023-content-blocking-for-the-ipfs-stack/)**
|
||||
|
||||
* Traditionally, content blocking within the IPFS ecosystem has been performed only at the IPFS gateway level and directly in Nginx, using something called the "Badbits denylist" — but now it can be enabled in Kubo & other tools in the IPFS stack too! [Check out the blog post for more info.](https://blog.ipfs.tech/2023-content-blocking-for-the-ipfs-stack/)
|
||||
|
||||
**[What happens when half of the network is down?](https://blog.ipfs.tech/2023-ipfs-unresponsive-nodes/)**
|
||||
|
||||
* The IPFS DHT experienced a serious incident in the beginning of 2023, but users hardly noticed thanks to the power of a decentralized network. [Read all about it in a new incident report!](https://blog.ipfs.tech/2023-ipfs-unresponsive-nodes/)
|
||||
|
||||
**[IPFS Principles](https://specs.ipfs.tech/architecture/principles/)**
|
||||
|
||||
* As mentioned above, IPFS recently joined a new social media network called [Bluesky](https://blueskyweb.xyz/) because it shares many of the same values that the IPFS ecosystem has. But what are those values exactly? You can [read all about IPFS Principles in a new specs doc](https://specs.ipfs.tech/architecture/principles/) edited by[ Robin Berjon](https://twitter.com/robinberjon).
|
||||
|
||||
**[Kubo 0.20.0](https://github.com/ipfs/kubo/releases/tag/v0.20.0)**
|
||||
|
||||
* This update includes:
|
||||
* Switch to `boxo/gateway` library
|
||||
* Improved testing
|
||||
* Trace Context support
|
||||
* Removed legacy features
|
||||
|
||||
**[Kubo 0.19.2](https://github.com/ipfs/kubo/releases/tag/v0.19.2)**
|
||||
|
||||
**[Kubo 0.19.1](https://github.com/ipfs/kubo/releases/tag/v0.19.1)**
|
||||
|
||||
|
||||
## **Around the Ecosystem 🌎**
|
||||
|
||||
* [Brave announces automatic NFT backups and enhanced Filecoin support in Brave Wallet](https://brave.com/nft-pinning/)
|
||||
* We're excited to share that the latest version of Brave’s web browser introduces automatic NFT backups to IPFS. Brave Wallet users can avoid the permanent loss of NFT metadata and gain peace of mind thanks to this new feature. [Check it out!](https://brave.com/nft-pinning/)
|
||||
* [Introducing Lassie - a retrieval client for IPFS and Filecoin](https://blog.ipfs.tech/2023-introducing-lassie/)
|
||||
* Lassie makes it easy to fetch your data from both the IPFS and Filecoin Network - it will find and fetch content over the best retrieval protocols available. [Read more about it on the IPFS blog](https://blog.ipfs.tech/2023-introducing-lassie/)!
|
||||
* [IPFS Implementations: It’s Definitely A Thing](https://blog.ipfs.tech/2023-03-implementation-principles/)
|
||||
* In a new blog post,[ Robin Berjon](https://twitter.com/robinberjon) talks about how the world of IPFS implementations has diversified greatly over the past 9 months: “Springtime in the distributed hemisphere and we are frolicking across fields of tantalizing IPFS flowers.” [Read the entire blog post](https://blog.ipfs.tech/2023-03-implementation-principles/)!
|
||||
* [IPFS Open Metaverse Base Camp Accelerator](https://outlierventures.io/ipfs-open-metaverse-base-camp/)
|
||||
* The latest cohort kicked-off on May 8, 2023. Co-delivered by Protocol Labs and Outlier Ventures, the program will run for 12 weeks and provide the teams in the cohort with the knowledge, networks, and capital they need to succeed as startups in Web3. Teams will pitch their products and services at Demo Day in August. [Visit the website to learn more!](https://outlierventures.io/ipfs-open-metaverse-base-camp/)
|
||||
|
||||
|
||||
## **IPFS Thing 2023 on YouTube 📺**
|
||||
|
||||
All of the talks and presentations from this year’s gathering of the IPFS implementers community are now available on YouTube. If you weren’t able to attend, now is the perfect chance to catch up! Below you will find links to playlists for each content track:
|
||||
|
||||
* [Opening & Keynotes](https://www.youtube.com/playlist?list=PLuhRWgmPaHtRnO5G2EF0RxYebcQzLDf5F)
|
||||
* [Community & Governance](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTIFbOVO5YfXkoFg6wIGbBN)
|
||||
* [Integrating IPFS](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTI0MS6ZjSJjBxZp7rcjSS_)
|
||||
* [Decentralized Compute & AI](https://www.youtube.com/playlist?list=PLuhRWgmPaHtQ_lKtbTR-vIW1LYuTjcaPw)
|
||||
* [HTTP Gateways](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTapMgLW7rRh92Tk8u7wip5)
|
||||
* [Content Routing](https://www.youtube.com/playlist?list=PLuhRWgmPaHtRBWV3SvInC5ATS8aKV3lsW)
|
||||
* [Interplanetary Databases](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTO8hr2CYiJPTSe7wybW_op)
|
||||
* [IPFS on the Web](https://www.youtube.com/playlist?list=PLuhRWgmPaHtQ-TO65P62tqfUM85HCIqSj)
|
||||
* [Data Transfer](https://www.youtube.com/playlist?list=PLuhRWgmPaHtS6WBDGK8oxcBHA6ILKatVk)
|
||||
* [IPFS Deployments & Operators](https://www.youtube.com/playlist?list=PLuhRWgmPaHtTYOY5l8nehP_Vt6Ek-svrp)
|
||||
* [Measuring IPFS](https://www.youtube.com/playlist?list=PLuhRWgmPaHtQkkbiq-PbIkt9_S2NjJz6x)
|
||||
BIN
src/assets/2023-03-implementations-flower.jpg
Normal file
BIN
src/assets/2023-03-implementations-flower.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
BIN
src/assets/2023-05-ipfs-unresponsive-nodes-incident.jpeg
Normal file
BIN
src/assets/2023-05-ipfs-unresponsive-nodes-incident.jpeg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 78 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 495 KiB |
BIN
src/assets/2023-05-multigateway-chromium-client-header.png
Normal file
BIN
src/assets/2023-05-multigateway-chromium-client-header.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 35 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user