From 5ae9064b7d29e7ec9351f24f2dc6678f653de74b Mon Sep 17 00:00:00 2001
From: Marcin Rataj <lidel@lidel.org>
Date: Thu, 25 Jul 2019 13:50:32 +0200
Subject: [PATCH 1/2] feat(brave): delegated peers and content routing

This enables delegated routers in embedded js-ipfs running in Brave.
Coupled with preload, this gives us basic file sharing functionality
back, until we have real p2p transport, native DHT etc.
---
 add-on/src/lib/options.js | 20 +++++++++++++-------
 package.json              |  2 ++
 yarn.lock                 | 34 +++++++++++++++++-----------------
 3 files changed, 32 insertions(+), 24 deletions(-)

diff --git a/add-on/src/lib/options.js b/add-on/src/lib/options.js
index b2dd54b22..491e1fac6 100644
--- a/add-on/src/lib/options.js
+++ b/add-on/src/lib/options.js
@@ -24,7 +24,7 @@ exports.optionDefaults = Object.freeze({
   ipfsApiUrl: buildIpfsApiUrl(),
   ipfsApiPollMs: 3000,
   ipfsProxy: true, // window.ipfs
-  logNamespaces: 'jsipfs*,ipfs*,-*:ipns*,-ipfs:preload*,-ipfs-http-client:request*'
+  logNamespaces: 'jsipfs*,ipfs*,libp2p-delegated*,-*:ipns*,-ipfs:preload*,-ipfs-http-client:request*'
 })
 
 function buildCustomGatewayUrl () {
@@ -62,15 +62,21 @@ function buildDefaultIpfsNodeConfig () {
     // Until we have MulticastDNS+DNS, peer discovery is done over ws-star
     config.config.Addresses.Swarm = ['/dns4/ws-star1.par.dwebops.pub/tcp/443/wss/p2p-websocket-star']
     // Until DHT and p2p transport are ready, delegate + preload
+    // Note: we use .preload.ipfs.io and .delegate.ipfs.io as means of http sharding (12 instead of 6 concurrent requests)
     const delegates = [
-      '/dns4/node0.preload.ipfs.io/tcp/443/https',
-      '/dns4/node1.preload.ipfs.io/tcp/443/https'
+      '/dns4/node1.delegate.ipfs.io/tcp/443/https',
+      '/dns4/node0.delegate.ipfs.io/tcp/443/https'
     ]
     // Delegated Content and Peer Routing: https://github.com/ipfs/js-ipfs/pull/2195
-    // TODO: delegated routing blocked by https://github.com/libp2p/js-libp2p-delegated-content-routing/issues/12
-    // config.config.Addresses.Delegates = delegates
-    // TODO: are preloads needed? should Brave have own nodes?
-    config.preload = { enabled: true, addresses: delegates }
+    config.config.Addresses.Delegates = delegates
+    // TODO: when we have p2p transport, are preloads still needed? should Brave have own nodes?
+    config.preload = {
+      enabled: true,
+      addresses: [
+        '/dns4/node1.preload.ipfs.io/tcp/443/https',
+        '/dns4/node0.preload.ipfs.io/tcp/443/https'
+      ]
+    }
     /*
       (Sidenote on why we need API for Web UI)
       Gateway can run without API port,
diff --git a/package.json b/package.json
index c43307387..fa512cd5f 100644
--- a/package.json
+++ b/package.json
@@ -66,6 +66,8 @@
   "private": true,
   "preferGlobal": false,
   "resolutions": {
+    "libp2p-delegated-content-routing": "0.3.1",
+    "libp2p-delegated-peer-routing": "0.3.1",
     "@hapi/hapi": "https://github.com/lidel/hapi/tarball/ccbf84ba5edc9b24564fdd166e3ee6d81c4c02d8/hapi.tar.gz",
     "pino": "5.12.3",
     "hapi-pino": "https://github.com/pinojs/hapi-pino/tarball/3767ed6b67601831e176e084ed82ba4ed9f726e6/hapi-pino.tar.gz",
diff --git a/yarn.lock b/yarn.lock
index 315203e7b..f7fa6ddb6 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -6798,7 +6798,7 @@ ipfs-css@0.12.0:
   resolved "https://registry.yarnpkg.com/ipfs-css/-/ipfs-css-0.12.0.tgz#becf48dbdfb1c913006ff0c6dc6c56752a2cb6b3"
   integrity sha512-bU72aEG1LR1MVUnHIXsCxdZqJwKpQrh0Wod2aI1o940hVxobZqHEVw5PISdhVdtK42IaHhtq25wAl0zZlUwyiA==
 
-ipfs-http-client@33.1.0, ipfs-http-client@^33.0.1, ipfs-http-client@^33.0.2, ipfs-http-client@^33.1.0:
+ipfs-http-client@33.1.0, ipfs-http-client@^33.1.0:
   version "33.1.0"
   resolved "https://registry.yarnpkg.com/ipfs-http-client/-/ipfs-http-client-33.1.0.tgz#4d3beceba27fcef26cf1940375a5f8c9d609f0dd"
   integrity sha512-hkS8nXay3DGKb/KXU1RDvTyxnvkAdhS5enlXxNXaS7yKvADlf5SEuQGYjW+VknkPPQ4FNbY3JttQ3YW+LTuoRA==
@@ -8550,25 +8550,25 @@ libp2p-crypto@~0.16.0, libp2p-crypto@~0.16.1:
     tweetnacl "^1.0.0"
     ursa-optional "~0.9.10"
 
-libp2p-delegated-content-routing@^0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/libp2p-delegated-content-routing/-/libp2p-delegated-content-routing-0.2.3.tgz#de3e923e70cbcfbbc2de679a84ad1c1c342a8129"
-  integrity sha512-WbHunAEJj5HzhbHKEep9myfoGa7/g4rWytyHLuC3syxbVpc9Tv4oQK0dD8G09YofGpIr/I4yUPaJY1GM7skGQQ==
+libp2p-delegated-content-routing@0.3.1, libp2p-delegated-content-routing@^0.2.3:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/libp2p-delegated-content-routing/-/libp2p-delegated-content-routing-0.3.1.tgz#45e1711074a68d457c9b4bd92682ad06fb8857c8"
+  integrity sha512-GgEj1FHzNFH6nL0fQ5sFZWcskfWkwVLL+GtY5wZbe9izXftyg5QDVdoKSlYWQUrEjaaAJE+T4KjvtK83T/C7Yg==
   dependencies:
-    async "^2.6.2"
-    ipfs-http-client "^33.0.2"
+    debug "^4.1.1"
+    ipfs-http-client "^33.1.0"
     multiaddr "^6.1.0"
-    peer-id "^0.12.2"
-    peer-info "^0.15.1"
+    p-queue "^6.1.0"
 
-libp2p-delegated-peer-routing@^0.2.3:
-  version "0.2.3"
-  resolved "https://registry.yarnpkg.com/libp2p-delegated-peer-routing/-/libp2p-delegated-peer-routing-0.2.3.tgz#b2c27bee2bd6a9f0147fc2ec12b5e1c9c6c982eb"
-  integrity sha512-yr5NRgAnVmsvhIC5COyEda+ZdD42JVfBeShsHj7FaRdYay4kdEpUXqLXiC7bC6PMbYSh2d/TheO3ITTj4Kp1Fw==
+libp2p-delegated-peer-routing@0.3.1, libp2p-delegated-peer-routing@^0.2.3:
+  version "0.3.1"
+  resolved "https://registry.yarnpkg.com/libp2p-delegated-peer-routing/-/libp2p-delegated-peer-routing-0.3.1.tgz#331d129559b2b257cef5e13260d7ac50d4731768"
+  integrity sha512-WAN2rBsuiS1xqrAaZthKX9vVtXar0nH7ACAWoTNsk2BaAhhds0Shri48NB5jN//kxLo+vC7+WVn4Rgdg3Dp2sA==
   dependencies:
-    ipfs-http-client "^33.0.1"
-    peer-id "^0.12.2"
-    peer-info "^0.15.1"
+    debug "^4.1.1"
+    ipfs-http-client "^33.1.0"
+    p-queue "^6.1.0"
+    peer-id "~0.12.2"
 
 libp2p-floodsub@^0.16.1:
   version "0.16.1"
@@ -10737,7 +10737,7 @@ p-map@^2.0.0:
   resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175"
   integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==
 
-p-queue@6.1.0:
+p-queue@6.1.0, p-queue@^6.1.0:
   version "6.1.0"
   resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.1.0.tgz#3f546275073b41e4af460e41459524b15c2753f3"
   integrity sha512-907vNz/cY+JEsqGglo7o/Ia9E/wisahJGOp9HPfbAyCVGERQVmFGA4IyknxY1v+QRBiMKedL3ToOBXNEy9MKQA==

From 8fcfa7a066aa6f0566c2de022d15988c63d2efeb Mon Sep 17 00:00:00 2001
From: Marcin Rataj <lidel@lidel.org>
Date: Fri, 26 Jul 2019 23:53:18 +0200
Subject: [PATCH 2/2] fix: callback-based delgates + DNS caching

This switches to 0.2.x versions of delegate modules which work correctly
with js-libp2p + wip [1] fix for js-ipfs that caches DNS records for 1
minute, greatly reducing the HTTP request overhead to remote APIs.

[1]: https://github.com/ipfs/js-ipfs/pull/2304
---
 add-on/src/lib/options.js |   5 +-
 package.json              |   6 +-
 yarn.lock                 | 245 +++++++++++++++++++++++++++++++-------
 3 files changed, 208 insertions(+), 48 deletions(-)

diff --git a/add-on/src/lib/options.js b/add-on/src/lib/options.js
index 491e1fac6..32a242b46 100644
--- a/add-on/src/lib/options.js
+++ b/add-on/src/lib/options.js
@@ -60,7 +60,10 @@ function buildDefaultIpfsNodeConfig () {
     config.config.Addresses.Gateway = '/ip4/127.0.0.1/tcp/9091'
 
     // Until we have MulticastDNS+DNS, peer discovery is done over ws-star
-    config.config.Addresses.Swarm = ['/dns4/ws-star1.par.dwebops.pub/tcp/443/wss/p2p-websocket-star']
+    config.config.Addresses.Swarm = [
+      '/dns4/ws-star1.par.dwebops.pub/tcp/443/wss/p2p-websocket-star',
+      '/dns4/ws-star.discovery.libp2p.io/tcp/443/wss/p2p-websocket-star'
+    ]
     // Until DHT and p2p transport are ready, delegate + preload
     // Note: we use .preload.ipfs.io and .delegate.ipfs.io as means of http sharding (12 instead of 6 concurrent requests)
     const delegates = [
diff --git a/package.json b/package.json
index fa512cd5f..b37df2a43 100644
--- a/package.json
+++ b/package.json
@@ -66,8 +66,8 @@
   "private": true,
   "preferGlobal": false,
   "resolutions": {
-    "libp2p-delegated-content-routing": "0.3.1",
-    "libp2p-delegated-peer-routing": "0.3.1",
+    "libp2p-delegated-content-routing": "0.2.4",
+    "libp2p-delegated-peer-routing": "0.2.4",
     "@hapi/hapi": "https://github.com/lidel/hapi/tarball/ccbf84ba5edc9b24564fdd166e3ee6d81c4c02d8/hapi.tar.gz",
     "pino": "5.12.3",
     "hapi-pino": "https://github.com/pinojs/hapi-pino/tarball/3767ed6b67601831e176e084ed82ba4ed9f726e6/hapi-pino.tar.gz",
@@ -126,7 +126,7 @@
     "get-port": "5.0.0",
     "http-dns": "3.0.1",
     "http-node": "1.2.0",
-    "ipfs": "https://github.com/ipfs/js-ipfs/tarball/2ae6b672c222555b1a068141f2acfe4b5f39b709/js-ipfs.tar.gz",
+    "ipfs": "https://github.com/ipfs/js-ipfs/tarball/6fa8f88310a4f7f451f0f6846e435134376703e6/js-ipfs.tar.gz",
     "ipfs-css": "0.12.0",
     "ipfs-http-client": "33.1.0",
     "ipfs-http-response": "0.3.1",
diff --git a/yarn.lock b/yarn.lock
index f7fa6ddb6..fbf698ca9 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1845,6 +1845,13 @@ async@^2.0.0, async@^2.0.1, async@^2.6.0, async@^2.6.1, async@^2.6.2:
   dependencies:
     lodash "^4.17.11"
 
+async@^2.6.3:
+  version "2.6.3"
+  resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
+  integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==
+  dependencies:
+    lodash "^4.17.14"
+
 async@^3.0.1, async@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/async/-/async-3.1.0.tgz#42b3b12ae1b74927b5217d8c0016baaf62463772"
@@ -4422,6 +4429,11 @@ err-code@^1.1.2:
   resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960"
   integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=
 
+err-code@^2.0.0:
+  version "2.0.0"
+  resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.0.tgz#452dadddde12356b1dd5a85f33b28ddda377ef2a"
+  integrity sha512-MsMOijQ4v0xlmrz1fc7lyPEy7jFhoNF7EVaRSP7mPzs20LaFOwG6qNjGRy3Ie85n9DARlcUnB1zbsBv5sJrIvw==
+
 errno@^0.1.3, errno@~0.1.1, errno@~0.1.7:
   version "0.1.7"
   resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618"
@@ -6120,7 +6132,7 @@ handlebars@^4.1.2:
   optionalDependencies:
     uglify-js "^3.1.4"
 
-hapi-pino@^6.0.0, "hapi-pino@https://github.com/pinojs/hapi-pino/tarball/3767ed6b67601831e176e084ed82ba4ed9f726e6/hapi-pino.tar.gz":
+hapi-pino@^6.0.2, "hapi-pino@https://github.com/pinojs/hapi-pino/tarball/3767ed6b67601831e176e084ed82ba4ed9f726e6/hapi-pino.tar.gz":
   version "5.4.0"
   resolved "https://github.com/pinojs/hapi-pino/tarball/3767ed6b67601831e176e084ed82ba4ed9f726e6/hapi-pino.tar.gz#3a8f286bdb50b8dc3a6c949be22df2cd192dc317"
   dependencies:
@@ -6849,6 +6861,57 @@ ipfs-http-client@33.1.0, ipfs-http-client@^33.1.0:
     tar-stream "^2.0.1"
     through2 "^3.0.1"
 
+ipfs-http-client@^33.0.1, ipfs-http-client@^33.0.2:
+  version "33.1.1"
+  resolved "https://registry.yarnpkg.com/ipfs-http-client/-/ipfs-http-client-33.1.1.tgz#6ddc13e86f8db768093290b19537d2388c74dd45"
+  integrity sha512-iwtLL3lOIzxXJFwLnOEtFUv1cYTuWJ0NauD7rpMEd/y4C7z6fuN6TSF4h547lxMh7sJWv+6Z0PmOA5N8FzUHJw==
+  dependencies:
+    async "^2.6.1"
+    bignumber.js "^9.0.0"
+    bl "^3.0.0"
+    bs58 "^4.0.1"
+    buffer "^5.2.1"
+    cids "~0.7.1"
+    concat-stream "github:hugomrdias/concat-stream#feat/smaller"
+    debug "^4.1.0"
+    detect-node "^2.0.4"
+    end-of-stream "^1.4.1"
+    err-code "^1.1.2"
+    flatmap "0.0.3"
+    glob "^7.1.3"
+    ipfs-block "~0.8.1"
+    ipfs-utils "~0.0.3"
+    ipld-dag-cbor "~0.15.0"
+    ipld-dag-pb "~0.17.3"
+    ipld-raw "^4.0.0"
+    is-ipfs "~0.6.1"
+    is-pull-stream "0.0.0"
+    is-stream "^2.0.0"
+    iso-stream-http "~0.1.2"
+    iso-url "~0.4.6"
+    just-kebab-case "^1.1.0"
+    just-map-keys "^1.1.0"
+    kind-of "^6.0.2"
+    lru-cache "^5.1.1"
+    multiaddr "^6.0.6"
+    multibase "~0.6.0"
+    multicodec "~0.5.1"
+    multihashes "~0.4.14"
+    ndjson "github:hugomrdias/ndjson#feat/readable-stream3"
+    once "^1.4.0"
+    peer-id "~0.12.2"
+    peer-info "~0.15.1"
+    promisify-es6 "^1.0.3"
+    pull-defer "~0.2.3"
+    pull-stream "^3.6.9"
+    pull-to-stream "~0.1.1"
+    pump "^3.0.0"
+    qs "^6.5.2"
+    readable-stream "^3.1.1"
+    stream-to-pull-stream "^1.7.2"
+    tar-stream "^2.0.1"
+    through2 "^3.0.1"
+
 ipfs-http-response@0.3.1, ipfs-http-response@~0.3.1:
   version "0.3.1"
   resolved "https://registry.yarnpkg.com/ipfs-http-response/-/ipfs-http-response-0.3.1.tgz#5cc351f8abf5f77dae47a41781fd7bc0c88fcaf8"
@@ -6866,10 +6929,10 @@ ipfs-http-response@0.3.1, ipfs-http-response@~0.3.1:
     promisify-es6 "^1.0.3"
     stream-to-blob "^1.0.1"
 
-ipfs-mfs@~0.11.6:
-  version "0.11.7"
-  resolved "https://registry.yarnpkg.com/ipfs-mfs/-/ipfs-mfs-0.11.7.tgz#068452a0972e718fb0f31607c4d1aac68431c496"
-  integrity sha512-OA48yd+j9qAhRph5GfCRaLRjbZxIZ3QOAPSIHwndhWo1QLzFucgaCR+eWkn15tNPQGXL/sguExK2PEfGW1fSnA==
+ipfs-mfs@~0.12.0:
+  version "0.12.0"
+  resolved "https://registry.yarnpkg.com/ipfs-mfs/-/ipfs-mfs-0.12.0.tgz#fa1efbd24a74d8340762716cb5d43eb1fe00683e"
+  integrity sha512-EY+At/kw2Lsyfd/AFInmvR2O6MQvQ87RWhAnN3GXSy/tXaopaS5CqT9SSUVAx3we87/pAUbusxQ1pK7HYtrXSw==
   dependencies:
     "@hapi/boom" "^7.4.2"
     "@hapi/joi" "^15.1.0"
@@ -6892,7 +6955,7 @@ ipfs-mfs@~0.11.6:
     promisify-es6 "^1.0.3"
     pull-stream "^3.6.9"
 
-ipfs-multipart@~0.1.0:
+ipfs-multipart@~0.1.0, ipfs-multipart@~0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/ipfs-multipart/-/ipfs-multipart-0.1.1.tgz#a8c2ad93c3732c00558f50f254ba88a6aeaac6ae"
   integrity sha512-NAmCxgBkZ0usWXf8lMwYYEXvyzrqa65uy/1caVKm5yOKFoqXNrNOt4Ev99Pb+B0RMRqGSdfSvtnZM1cfhSSk2A==
@@ -6999,9 +7062,22 @@ ipfs-utils@~0.0.3:
     kind-of "^6.0.2"
     readable-stream "^3.3.0"
 
-"ipfs@https://github.com/ipfs/js-ipfs/tarball/2ae6b672c222555b1a068141f2acfe4b5f39b709/js-ipfs.tar.gz":
-  version "0.36.4"
-  resolved "https://github.com/ipfs/js-ipfs/tarball/2ae6b672c222555b1a068141f2acfe4b5f39b709/js-ipfs.tar.gz#f5dae17aaaf63f945c9fa20534e0e21121a45233"
+ipfs-utils@~0.0.4:
+  version "0.0.4"
+  resolved "https://registry.yarnpkg.com/ipfs-utils/-/ipfs-utils-0.0.4.tgz#946114cfeb6afb4454b4ccb10d2327cd323b0cce"
+  integrity sha512-7cZf6aGj2FG3XJWhCNwn4mS93Q0GEWjtBZvEHqzgI43U2qzNDCyzfS1pei1Y5F+tw/zDJ5U4XG0G9reJxR53Ig==
+  dependencies:
+    buffer "^5.2.1"
+    is-buffer "^2.0.3"
+    is-electron "^2.2.0"
+    is-pull-stream "0.0.0"
+    is-stream "^2.0.0"
+    kind-of "^6.0.2"
+    readable-stream "^3.4.0"
+
+"ipfs@https://github.com/ipfs/js-ipfs/tarball/6fa8f88310a4f7f451f0f6846e435134376703e6/js-ipfs.tar.gz":
+  version "0.37.0"
+  resolved "https://github.com/ipfs/js-ipfs/tarball/6fa8f88310a4f7f451f0f6846e435134376703e6/js-ipfs.tar.gz#5d1582a899ccefd265e0b93e848e9a76619a0888"
   dependencies:
     "@hapi/ammo" "^3.1.0"
     "@hapi/boom" "^7.4.2"
@@ -7027,13 +7103,13 @@ ipfs-utils@~0.0.3:
     datastore-pubsub "~0.1.1"
     debug "^4.1.0"
     dlv "^1.1.3"
-    err-code "^1.1.2"
+    err-code "^2.0.0"
     file-type "^12.0.1"
     fnv1a "^1.0.1"
     fsm-event "^2.1.0"
     get-folder-size "^2.0.0"
     glob "^7.1.3"
-    hapi-pino "^6.0.0"
+    hapi-pino "^6.0.2"
     hashlru "^2.3.0"
     human-to-milliseconds "^2.0.0"
     interface-datastore "~0.6.0"
@@ -7042,13 +7118,13 @@ ipfs-utils@~0.0.3:
     ipfs-block-service "~0.15.2"
     ipfs-http-client "^33.1.0"
     ipfs-http-response "~0.3.1"
-    ipfs-mfs "~0.11.6"
-    ipfs-multipart "~0.1.0"
+    ipfs-mfs "~0.12.0"
+    ipfs-multipart "~0.1.1"
     ipfs-repo "~0.26.6"
     ipfs-unixfs "~0.1.16"
     ipfs-unixfs-exporter "~0.37.7"
     ipfs-unixfs-importer "~0.39.11"
-    ipfs-utils "~0.0.3"
+    ipfs-utils "~0.0.4"
     ipld "~0.24.1"
     ipld-bitcoin "~0.3.0"
     ipld-dag-cbor "~0.15.0"
@@ -7066,12 +7142,14 @@ ipfs-utils@~0.0.3:
     just-flatten-it "^2.1.0"
     just-safe-set "^2.1.0"
     kind-of "^6.0.2"
+    ky "~0.11.2"
+    ky-universal "~0.2.2"
     libp2p "~0.25.4"
     libp2p-bootstrap "~0.9.3"
     libp2p-crypto "~0.16.0"
-    libp2p-delegated-content-routing "^0.2.3"
-    libp2p-delegated-peer-routing "^0.2.3"
-    libp2p-kad-dht "~0.15.2"
+    libp2p-delegated-content-routing "^0.2.4"
+    libp2p-delegated-peer-routing "^0.2.4"
+    libp2p-kad-dht "~0.15.3"
     libp2p-keychain "~0.4.2"
     libp2p-mdns "~0.12.0"
     libp2p-record "~0.6.3"
@@ -7080,7 +7158,7 @@ ipfs-utils@~0.0.3:
     libp2p-webrtc-star "~0.16.0"
     libp2p-websocket-star-multi "~0.4.3"
     libp2p-websockets "~0.12.2"
-    lodash "^4.17.11"
+    lodash "^4.17.15"
     mafmt "^6.0.2"
     merge-options "^1.0.1"
     mime-types "^2.1.21"
@@ -7088,14 +7166,15 @@ ipfs-utils@~0.0.3:
     multiaddr "^6.1.0"
     multiaddr-to-uri "^4.0.1"
     multibase "~0.6.0"
-    multicodec "~0.5.1"
+    multicodec "~0.5.5"
     multihashes "~0.4.14"
     multihashing-async "~0.6.0"
-    node-fetch "^2.3.0"
+    p-queue "^6.1.0"
     peer-book "~0.9.0"
-    peer-id "~0.12.0"
+    peer-id "~0.12.3"
     peer-info "~0.15.0"
     progress "^2.0.1"
+    promise-nodeify "3.0.1"
     promisify-es6 "^1.0.3"
     protons "^1.0.1"
     pull-abortable "^4.1.1"
@@ -7106,13 +7185,13 @@ ipfs-utils@~0.0.3:
     pull-ndjson "~0.1.1"
     pull-pushable "^2.2.0"
     pull-sort "^1.0.1"
-    pull-stream "^3.6.13"
+    pull-stream "^3.6.14"
     pull-stream-to-async-iterator "^1.0.2"
     pull-stream-to-stream "^1.3.4"
     pull-traverse "^1.0.3"
     readable-stream "^3.4.0"
     receptacle "^1.3.2"
-    semver "^6.2.0"
+    semver "^6.3.0"
     stream-to-pull-stream "^1.7.3"
     superstruct "~0.6.0"
     tar-stream "^2.0.0"
@@ -7120,7 +7199,7 @@ ipfs-utils@~0.0.3:
     update-notifier "^3.0.1"
     uri-to-multiaddr "^3.0.1"
     varint "^5.0.0"
-    yargs "^13.2.4"
+    yargs "^13.3.0"
     yargs-promise "^1.1.0"
   optionalDependencies:
     prom-client "^11.5.3"
@@ -8202,6 +8281,19 @@ klaw@^1.0.0:
   optionalDependencies:
     graceful-fs "^4.1.9"
 
+ky-universal@~0.2.2:
+  version "0.2.2"
+  resolved "https://registry.yarnpkg.com/ky-universal/-/ky-universal-0.2.2.tgz#7a36e1a75641a98f878157463513965f799f5bfe"
+  integrity sha512-fb32o/fKy/ux2ALWa9HU2hvGtfOq7/vn2nH0FpVE+jwNzyTeORlAbj3Fiw+WLMbUlmVqZIWupnLZ2USHvqwZHw==
+  dependencies:
+    abort-controller "^3.0.0"
+    node-fetch "^2.3.0"
+
+ky@~0.11.2:
+  version "0.11.2"
+  resolved "https://registry.yarnpkg.com/ky/-/ky-0.11.2.tgz#4ffe6621d9d9ab61bf0f5500542e3a96d1ba0815"
+  integrity sha512-5Aou5BWue5/mkPqIRqzSWW+0Hkl403pr/2AIrCKYw7cVl/Xoe8Xe4KLBO0PRjbz7GnRe1/8wW1KhqQNFFE7/GQ==
+
 labeled-stream-splicer@^2.0.0:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/labeled-stream-splicer/-/labeled-stream-splicer-2.0.2.tgz#42a41a16abcd46fd046306cf4f2c3576fffb1c21"
@@ -8550,25 +8642,27 @@ libp2p-crypto@~0.16.0, libp2p-crypto@~0.16.1:
     tweetnacl "^1.0.0"
     ursa-optional "~0.9.10"
 
-libp2p-delegated-content-routing@0.3.1, libp2p-delegated-content-routing@^0.2.3:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/libp2p-delegated-content-routing/-/libp2p-delegated-content-routing-0.3.1.tgz#45e1711074a68d457c9b4bd92682ad06fb8857c8"
-  integrity sha512-GgEj1FHzNFH6nL0fQ5sFZWcskfWkwVLL+GtY5wZbe9izXftyg5QDVdoKSlYWQUrEjaaAJE+T4KjvtK83T/C7Yg==
+libp2p-delegated-content-routing@0.2.4, libp2p-delegated-content-routing@^0.2.4:
+  version "0.2.4"
+  resolved "https://registry.yarnpkg.com/libp2p-delegated-content-routing/-/libp2p-delegated-content-routing-0.2.4.tgz#2627f09f59a38829eef291693482dd9e15c815bd"
+  integrity sha512-VgupHN9DhoNIJmnoe5H1Qb+AeG+Z7A4Yc8p/8jNNuRq61Jn7uzs03k1WWFRt/+Xnb9FlnHrBo1vrp8NqXdq9NQ==
   dependencies:
-    debug "^4.1.1"
-    ipfs-http-client "^33.1.0"
+    async "^2.6.2"
+    ipfs-http-client "^33.0.2"
     multiaddr "^6.1.0"
     p-queue "^6.1.0"
+    peer-id "^0.12.2"
+    peer-info "^0.15.1"
 
-libp2p-delegated-peer-routing@0.3.1, libp2p-delegated-peer-routing@^0.2.3:
-  version "0.3.1"
-  resolved "https://registry.yarnpkg.com/libp2p-delegated-peer-routing/-/libp2p-delegated-peer-routing-0.3.1.tgz#331d129559b2b257cef5e13260d7ac50d4731768"
-  integrity sha512-WAN2rBsuiS1xqrAaZthKX9vVtXar0nH7ACAWoTNsk2BaAhhds0Shri48NB5jN//kxLo+vC7+WVn4Rgdg3Dp2sA==
+libp2p-delegated-peer-routing@0.2.4, libp2p-delegated-peer-routing@^0.2.4:
+  version "0.2.4"
+  resolved "https://registry.yarnpkg.com/libp2p-delegated-peer-routing/-/libp2p-delegated-peer-routing-0.2.4.tgz#18ee245585e2737a4f875cd6bc5e106d8ad1e95b"
+  integrity sha512-uL6QumPoXG5LhFPQaDtcW4k83LlTJEDNqqv3DnM9RG3/d+N6/yHBNqQpRmvgR4gBeaDOEpdAyK3FSa9IWNpEFA==
   dependencies:
-    debug "^4.1.1"
-    ipfs-http-client "^33.1.0"
+    ipfs-http-client "^33.0.1"
     p-queue "^6.1.0"
-    peer-id "~0.12.2"
+    peer-id "^0.12.2"
+    peer-info "^0.15.1"
 
 libp2p-floodsub@^0.16.1:
   version "0.16.1"
@@ -8598,10 +8692,10 @@ libp2p-identify@~0.7.6:
     pull-length-prefixed "^1.3.1"
     pull-stream "^3.6.9"
 
-libp2p-kad-dht@~0.15.2:
-  version "0.15.2"
-  resolved "https://registry.yarnpkg.com/libp2p-kad-dht/-/libp2p-kad-dht-0.15.2.tgz#4230a1778f90ecb32e1c63d59b8573e44b930951"
-  integrity sha512-1lTIHOzaDy6BssCiWo9SIoJoLk4OSaJwJ6gqt8xySsqgLLB8jZ9tmtjIQmA9IffFRZ20nMQRZ/aWW0uR6N9B/w==
+libp2p-kad-dht@~0.15.3:
+  version "0.15.3"
+  resolved "https://registry.yarnpkg.com/libp2p-kad-dht/-/libp2p-kad-dht-0.15.3.tgz#3d7057c5c17742747cd3139cf3b4395f4a64f405"
+  integrity sha512-CasmSH+/zwlsk6q4wigmVioa3l2H1q2QZCwHPJ85ox2KKQS58mbVgXuBL2I300G2lMg0RPQRojvY43yynHhn4A==
   dependencies:
     abort-controller "^3.0.0"
     async "^2.6.2"
@@ -8620,6 +8714,8 @@ libp2p-kad-dht@~0.15.2:
     merge-options "^1.0.1"
     multihashes "~0.4.14"
     multihashing-async "~0.5.2"
+    p-queue "^5.0.0"
+    p-times "^2.1.0"
     peer-id "~0.12.2"
     peer-info "~0.15.1"
     priorityqueue "~0.2.1"
@@ -8628,6 +8724,7 @@ libp2p-kad-dht@~0.15.2:
     protons "^1.0.1"
     pull-length-prefixed "^1.3.2"
     pull-stream "^3.6.9"
+    pull-stream-to-async-iterator "^1.0.1"
     varint "^5.0.0"
     xor-distance "^2.0.0"
 
@@ -9100,6 +9197,11 @@ lodash@^4, lodash@^4.0.0, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.3, lodash
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba"
   integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==
 
+lodash@^4.17.14, lodash@^4.17.15:
+  version "4.17.15"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
+  integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
+
 log-symbols@2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
@@ -9756,6 +9858,13 @@ multicodec@~0.5.0, multicodec@~0.5.1, multicodec@~0.5.3:
   dependencies:
     varint "^5.0.0"
 
+multicodec@~0.5.5:
+  version "0.5.5"
+  resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.5.tgz#55c2535b44eca9ea40a13771420153fe075bb36d"
+  integrity sha512-1kOifvwAqp9IdiiTKmpK2tS+LY6GHZdKpk3S2EvW4T32vlwDyA3hJoZtGauzqdedUPVNGChnTksEotVOCVlC+Q==
+  dependencies:
+    varint "^5.0.0"
+
 multihashes@~0.4.12, multihashes@~0.4.13, multihashes@~0.4.14, multihashes@~0.4.15:
   version "0.4.15"
   resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.15.tgz#6dbc55f7f312c6782f5367c03c9783681589d8a6"
@@ -10766,6 +10875,13 @@ p-timeout@^3.1.0:
   dependencies:
     p-finally "^1.0.0"
 
+p-times@^2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/p-times/-/p-times-2.1.0.tgz#b3e7f9159f916cacb6aae06d67c79451b0076c6c"
+  integrity sha512-y23lF7HegeUyBTAxHNl6qYvwTy6S4d+BQcs+4CwgxXzc1v1Hsf7pyAqbDHMiYnjdL5Vcmr/oHc9l+nAu0Q+Hhg==
+  dependencies:
+    p-map "^2.0.0"
+
 p-try@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3"
@@ -11077,7 +11193,7 @@ peer-id@^0.11.0:
     lodash "^4.17.10"
     multihashes "~0.4.13"
 
-peer-id@^0.12.2, peer-id@~0.12.0, peer-id@~0.12.2:
+peer-id@^0.12.2, peer-id@~0.12.2:
   version "0.12.3"
   resolved "https://registry.yarnpkg.com/peer-id/-/peer-id-0.12.3.tgz#8256888a33331efdabdda9b439eb5e50ab09cb14"
   integrity sha512-rSpKw1lL0jL2hu0FO1IywmMTHLchiUO8/jkxe14d/TWSKLjlqhymzl9W6oMfmTZT5cLy99Tq3dRIBjdSaR4Flg==
@@ -11097,6 +11213,16 @@ peer-id@~0.10.7:
     lodash "^4.17.5"
     multihashes "~0.4.13"
 
+peer-id@~0.12.3:
+  version "0.12.4"
+  resolved "https://registry.yarnpkg.com/peer-id/-/peer-id-0.12.4.tgz#25708b0676ee0a8b0ce32d73fe9c68163ed747c2"
+  integrity sha512-AIAwL/6CmVc/VKbUhpA1rY3A/VJ3Z9ELvtvDQfl5cIi0A74L7lvsJ6LxQn5JSJVHM5Us2Ng9zMO523dO3FFnnw==
+  dependencies:
+    async "^2.6.3"
+    class-is "^1.1.0"
+    libp2p-crypto "~0.16.1"
+    multihashes "~0.4.15"
+
 peer-info@^0.14.1:
   version "0.14.1"
   resolved "https://registry.yarnpkg.com/peer-info/-/peer-info-0.14.1.tgz#ac5aec421e9965f7b0e7576d717941bb25676134"
@@ -11403,6 +11529,11 @@ promise-inflight@^1.0.1:
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
   integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
 
+promise-nodeify@3.0.1:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/promise-nodeify/-/promise-nodeify-3.0.1.tgz#f0f5d9720ee9ec71dd2bfa92667be504c10229c2"
+  integrity sha512-ghsSuzZXJX8iO7WVec2z7GI+Xk/EyiD+JZK7AZKhUqYfpLa/Zs4ylUD+CwwnKlG6G3HnkUPMAi6PO7zeqGKssg==
+
 promise-timeout@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/promise-timeout/-/promise-timeout-1.3.0.tgz#d1c78dd50a607d5f0a5207410252a3a0914e1014"
@@ -11684,6 +11815,11 @@ pull-stream@^3.2.3, pull-stream@^3.4.5, pull-stream@^3.5.0, pull-stream@^3.6.13,
   resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.13.tgz#181435322841b0397c7ed44ee5a3fae32662ac1b"
   integrity sha512-enbnbnO+czsPuCq9s9HTTzDzzVQD5TSe60aO3nBioeJ9mevh8RzE4Hxbujo9TReg1fJlmNEL8uyQTUgn8+rSHg==
 
+pull-stream@^3.6.14:
+  version "3.6.14"
+  resolved "https://registry.yarnpkg.com/pull-stream/-/pull-stream-3.6.14.tgz#529dbd5b86131f4a5ed636fdf7f6af00781357ee"
+  integrity sha512-KIqdvpqHHaTUA2mCYcLG1ibEbu/LCKoJZsBWyv9lSYtPkJPBq8m3Hxa103xHi6D2thj5YXa0TqK3L3GUkwgnew==
+
 pull-stringify@^1.2.2:
   version "1.2.2"
   resolved "https://registry.yarnpkg.com/pull-stringify/-/pull-stringify-1.2.2.tgz#5a1c34e0075faf2f2f6d46004e36dccd33bd7c7c"
@@ -12585,6 +12721,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0:
   resolved "https://registry.yarnpkg.com/semver/-/semver-6.2.0.tgz#4d813d9590aaf8a9192693d6c85b9344de5901db"
   integrity sha512-jdFC1VdUGT/2Scgbimf7FSx9iJLXoqfglSF+gJeuNWVpiE37OIbc1jywR/GJyFdz3mnkz2/id0L0J/cr0izR5A==
 
+semver@^6.3.0:
+  version "6.3.0"
+  resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
+  integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+
 semver@~5.4.1:
   version "5.4.1"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
@@ -15160,7 +15301,7 @@ yargs-parser@^11.1.1:
     camelcase "^5.0.0"
     decamelize "^1.2.0"
 
-yargs-parser@^13.0.0, yargs-parser@^13.1.0:
+yargs-parser@^13.0.0, yargs-parser@^13.1.0, yargs-parser@^13.1.1:
   version "13.1.1"
   resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"
   integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==
@@ -15199,7 +15340,7 @@ yargs@13.2.2:
     y18n "^4.0.0"
     yargs-parser "^13.0.0"
 
-yargs@13.2.4, yargs@^13.2.2, yargs@^13.2.4, yargs@~13.2.0:
+yargs@13.2.4, yargs@^13.2.2, yargs@~13.2.0:
   version "13.2.4"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
   integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
@@ -15234,6 +15375,22 @@ yargs@^12.0.5:
     y18n "^3.2.1 || ^4.0.0"
     yargs-parser "^11.1.1"
 
+yargs@^13.3.0:
+  version "13.3.0"
+  resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"
+  integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==
+  dependencies:
+    cliui "^5.0.0"
+    find-up "^3.0.0"
+    get-caller-file "^2.0.1"
+    require-directory "^2.1.1"
+    require-main-filename "^2.0.0"
+    set-blocking "^2.0.0"
+    string-width "^3.0.0"
+    which-module "^2.0.0"
+    y18n "^4.0.0"
+    yargs-parser "^13.1.1"
+
 yargs@^3.19.0:
   version "3.32.0"
   resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995"