[#10974] ENS resolving for IPNS names.
Signed-off-by: andrey <motor4ik@gmail.com>
This commit is contained in:
parent
2be70cca9a
commit
be25ecd4ea
|
@ -24,9 +24,7 @@
|
||||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||||
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
[status-im.ui.components.bottom-sheet.core :as bottom-sheet]
|
||||||
[status-im.browser.webview-ref :as webview-ref]
|
[status-im.browser.webview-ref :as webview-ref]
|
||||||
[alphabase.base58 :as alphabase.base58]
|
["eth-phishing-detect" :as eth-phishing-detect]))
|
||||||
["eth-phishing-detect" :as eth-phishing-detect]
|
|
||||||
["hi-base32" :as hi-base32]))
|
|
||||||
|
|
||||||
(fx/defn update-browser-option
|
(fx/defn update-browser-option
|
||||||
[{:keys [db]} option-key option-value]
|
[{:keys [db]} option-key option-value]
|
||||||
|
@ -170,16 +168,17 @@
|
||||||
|
|
||||||
(defmulti storage-gateway :namespace)
|
(defmulti storage-gateway :namespace)
|
||||||
|
|
||||||
|
(defmethod storage-gateway :ipns
|
||||||
|
[{:keys [hash]}]
|
||||||
|
(str "https://" hash))
|
||||||
|
|
||||||
(defmethod storage-gateway :ipfs
|
(defmethod storage-gateway :ipfs
|
||||||
[{:keys [hash]}]
|
[{:keys [hash]}]
|
||||||
(let [base32hash (-> (.encode ^js hi-base32 (alphabase.base58/decode hash))
|
(contenthash/ipfs-url hash))
|
||||||
(string/replace #"=" "")
|
|
||||||
(string/lower-case))]
|
|
||||||
(str base32hash ".infura.status.im")))
|
|
||||||
|
|
||||||
(defmethod storage-gateway :swarm
|
(defmethod storage-gateway :swarm
|
||||||
[{:keys [hash]}]
|
[{:keys [hash]}]
|
||||||
(str "swarm-gateways.net/bzz:/" hash))
|
(str "https://swarm-gateways.net/bzz:/" hash))
|
||||||
|
|
||||||
(fx/defn resolve-ens-multihash-success
|
(fx/defn resolve-ens-multihash-success
|
||||||
[{:keys [db] :as cofx} m]
|
[{:keys [db] :as cofx} m]
|
||||||
|
@ -190,7 +189,7 @@
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
{:db (-> (update db :browser/options
|
{:db (-> (update db :browser/options
|
||||||
assoc
|
assoc
|
||||||
:url (str "https://" gateway path)
|
:url (str gateway path)
|
||||||
:resolving? false)
|
:resolving? false)
|
||||||
(assoc-in [:browser/options :resolved-ens host] gateway))})))
|
(assoc-in [:browser/options :resolved-ens host] gateway))})))
|
||||||
|
|
||||||
|
@ -223,9 +222,12 @@
|
||||||
options (get-in cofx [:db :browser/options])
|
options (get-in cofx [:db :browser/options])
|
||||||
current-url (:url options)]
|
current-url (:url options)]
|
||||||
(when (and (not= "about:blank" url) (not= current-url url) (not= (str current-url "/") url))
|
(when (and (not= "about:blank" url) (not= current-url url) (not= (str current-url "/") url))
|
||||||
|
(let [resolved-ens (first (filter (fn [v]
|
||||||
(let [resolved-ens (first (filter #(not= (.indexOf ^js url (second %)) -1) (:resolved-ens options)))
|
(not= (.indexOf ^js url (second v)) -1))
|
||||||
resolved-url (if resolved-ens (string/replace url (second resolved-ens) (first resolved-ens)) url)]
|
(:resolved-ens options)))
|
||||||
|
resolved-url (if resolved-ens
|
||||||
|
(http/normalize-url (string/replace url (second resolved-ens) (first resolved-ens)))
|
||||||
|
url)]
|
||||||
(fx/merge cofx
|
(fx/merge cofx
|
||||||
(update-browser-history browser resolved-url)
|
(update-browser-history browser resolved-url)
|
||||||
(handle-pdf url)
|
(handle-pdf url)
|
||||||
|
@ -399,9 +401,7 @@
|
||||||
(cond
|
(cond
|
||||||
(and (= type constants/history-state-changed)
|
(and (= type constants/history-state-changed)
|
||||||
(not= "about:blank" url))
|
(not= "about:blank" url))
|
||||||
(fx/merge cofx
|
(update-browser-on-nav-change cofx url nil)
|
||||||
(update-browser-history browser url)
|
|
||||||
(resolve-url nil))
|
|
||||||
|
|
||||||
(= type constants/web3-send-async-read-only)
|
(= type constants/web3-send-async-read-only)
|
||||||
(web3-send-async-read-only cofx dapp-name payload messageId)
|
(web3-send-async-read-only cofx dapp-name payload messageId)
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
dapp1-id
|
dapp1-id
|
||||||
{:browser-id dapp1-id
|
{:browser-id dapp1-id
|
||||||
:history-index 0
|
:history-index 0
|
||||||
:history ["http://cryptokitties.co"]
|
:history ["https://cryptokitties.co"]
|
||||||
:dapp? false
|
:dapp? false
|
||||||
:name "Browser"
|
:name "Browser"
|
||||||
:timestamp 1}))
|
:timestamp 1}))
|
||||||
|
@ -63,12 +63,12 @@
|
||||||
(let [result-open-existing (browser/open-existing-browser {:db (:db result-open)
|
(let [result-open-existing (browser/open-existing-browser {:db (:db result-open)
|
||||||
:now 2}
|
:now 2}
|
||||||
dapp1-id)
|
dapp1-id)
|
||||||
dapp1-url2 (str "http://" dapp1-url "/nav2")]
|
dapp1-url2 (str "https://" dapp1-url "/nav2")]
|
||||||
(is (not (has-wrong-properties? result-open-existing
|
(is (not (has-wrong-properties? result-open-existing
|
||||||
dapp1-id
|
dapp1-id
|
||||||
{:browser-id dapp1-id
|
{:browser-id dapp1-id
|
||||||
:history-index 0
|
:history-index 0
|
||||||
:history ["http://cryptokitties.co"]
|
:history ["https://cryptokitties.co"]
|
||||||
:dapp? false
|
:dapp? false
|
||||||
:name "Browser"
|
:name "Browser"
|
||||||
:timestamp 2}))
|
:timestamp 2}))
|
||||||
|
@ -89,7 +89,7 @@
|
||||||
dapp1-id
|
dapp1-id
|
||||||
{:browser-id dapp1-id
|
{:browser-id dapp1-id
|
||||||
:history-index 1
|
:history-index 1
|
||||||
:history ["http://cryptokitties.co" dapp1-url2]
|
:history ["https://cryptokitties.co" dapp1-url2]
|
||||||
:dapp? false
|
:dapp? false
|
||||||
:name "Browser"
|
:name "Browser"
|
||||||
:timestamp 4}))
|
:timestamp 4}))
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
dapp1-id
|
dapp1-id
|
||||||
{:browser-id dapp1-id
|
{:browser-id dapp1-id
|
||||||
:history-index 0
|
:history-index 0
|
||||||
:history ["http://cryptokitties.co" dapp1-url2]
|
:history ["https://cryptokitties.co" dapp1-url2]
|
||||||
:dapp? false
|
:dapp? false
|
||||||
:name "Browser"
|
:name "Browser"
|
||||||
:timestamp 5}))
|
:timestamp 5}))
|
||||||
|
@ -115,7 +115,7 @@
|
||||||
dapp1-id
|
dapp1-id
|
||||||
{:browser-id dapp1-id
|
{:browser-id dapp1-id
|
||||||
:history-index 1
|
:history-index 1
|
||||||
:history ["http://cryptokitties.co" dapp1-url2]
|
:history ["https://cryptokitties.co" dapp1-url2]
|
||||||
:dapp? false
|
:dapp? false
|
||||||
:name "Browser"
|
:name "Browser"
|
||||||
:timestamp 6}))
|
:timestamp 6}))
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
(ns status-im.ipfs.core
|
|
||||||
(:refer-clojure :exclude [cat])
|
|
||||||
(:require [re-frame.core :as re-frame]
|
|
||||||
[status-im.utils.fx :as fx]))
|
|
||||||
|
|
||||||
;; we currently use an ipfs gateway but this detail is not relevant
|
|
||||||
;; outside of this namespace
|
|
||||||
(def ipfs-add-url "https://ipfs.infura.io:5001/api/v0/add?cid-version=1")
|
|
||||||
(def ipfs-cat-url "https://ipfs.infura.io/ipfs/")
|
|
||||||
|
|
||||||
(fx/defn cat
|
|
||||||
[cofx {:keys [hash on-success on-failure]}]
|
|
||||||
{:http-get (cond-> {:url (str ipfs-cat-url hash)
|
|
||||||
:timeout-ms 5000
|
|
||||||
:on-success (fn [{:keys [status body]}]
|
|
||||||
(if (= 200 status)
|
|
||||||
(re-frame/dispatch (on-success body))
|
|
||||||
(when on-failure
|
|
||||||
(re-frame/dispatch (on-failure status)))))}
|
|
||||||
on-failure
|
|
||||||
(assoc :on-error
|
|
||||||
#(re-frame/dispatch (on-failure %))))})
|
|
|
@ -43,7 +43,7 @@
|
||||||
:style styles/url-input}]
|
:style styles/url-input}]
|
||||||
[react/touchable-highlight {:style styles/url-text-container
|
[react/touchable-highlight {:style styles/url-text-container
|
||||||
:on-press #(re-frame/dispatch [:browser.ui/url-input-pressed])}
|
:on-press #(re-frame/dispatch [:browser.ui/url-input-pressed])}
|
||||||
[react/text (http/url-host url-original)]])
|
[react/text {:number-of-lines 1} (http/url-host url-original)]])
|
||||||
(when-not unsafe?
|
(when-not unsafe?
|
||||||
[react/touchable-highlight {:on-press #(.reload ^js @webview-ref/webview-ref)
|
[react/touchable-highlight {:on-press #(.reload ^js @webview-ref/webview-ref)
|
||||||
:accessibility-label :refresh-page-button}
|
:accessibility-label :refresh-page-button}
|
||||||
|
|
|
@ -2,27 +2,10 @@
|
||||||
"TODO: currently we only support encoding/decoding ipfs contenthash
|
"TODO: currently we only support encoding/decoding ipfs contenthash
|
||||||
implementing swarm and other protocols will come later"
|
implementing swarm and other protocols will come later"
|
||||||
(:refer-clojure :exclude [cat])
|
(:refer-clojure :exclude [cat])
|
||||||
(:require [alphabase.base58 :as b58]
|
(:require ["hi-base32" :as hi-base32]
|
||||||
[alphabase.hex :as hex]
|
[alphabase.hex :as hex]
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[status-im.ethereum.core :as ethereum]
|
[status-im.ethereum.core :as ethereum]))
|
||||||
[status-im.ipfs.core :as ipfs]
|
|
||||||
[status-im.utils.fx :as fx]))
|
|
||||||
|
|
||||||
(defn encode [{:keys [hash namespace ipld]}]
|
|
||||||
(when (and hash
|
|
||||||
(= namespace :ipfs)
|
|
||||||
(nil? ipld))
|
|
||||||
(when-let [b58-hash (if (string/starts-with? hash "z")
|
|
||||||
(when (= (count hash) 49)
|
|
||||||
;; this is a CID multihash
|
|
||||||
;; the z is removed, it indicates that the
|
|
||||||
;; CID is b58 encoded
|
|
||||||
(subs hash 1))
|
|
||||||
(when (= (count hash) 46)
|
|
||||||
;; this is a deprecated simple ipfs hash
|
|
||||||
hash))]
|
|
||||||
(str "0xe301" (hex/encode (b58/decode b58-hash))))))
|
|
||||||
|
|
||||||
(defn decode
|
(defn decode
|
||||||
"TODO properly decode the CID
|
"TODO properly decode the CID
|
||||||
|
@ -39,34 +22,27 @@
|
||||||
:hash hash})
|
:hash hash})
|
||||||
(and (= 78 (count hex))
|
(and (= 78 (count hex))
|
||||||
(string/starts-with? hex "0xe3010170"))
|
(string/starts-with? hex "0xe3010170"))
|
||||||
;; for retrocompatibility with old CIDv0
|
|
||||||
{:namespace :ipfs
|
{:namespace :ipfs
|
||||||
|
:hash (str "b" (-> hex
|
||||||
|
(subs 6)
|
||||||
|
hex/decode
|
||||||
|
((fn [v] (.encode ^js hi-base32 v)))
|
||||||
|
(string/replace #"=" "")
|
||||||
|
string/lower-case))}
|
||||||
|
(and (string/starts-with? hex "0xe50101700"))
|
||||||
|
{:namespace :ipns
|
||||||
:hash (-> hex
|
:hash (-> hex
|
||||||
(subs 10)
|
(subs 14)
|
||||||
hex/decode
|
((fn [v] (str "0x" v)))
|
||||||
b58/encode)}
|
(ethereum/hex-to-utf8))})))
|
||||||
(and (= 78 (count hex))
|
|
||||||
(string/starts-with? hex "0xe30101"))
|
(defn ipfs-url [hash]
|
||||||
;; new CIDv1
|
(str "https://" hash ".ipfs.cf-ipfs.com"))
|
||||||
{:namespace :ipfs
|
|
||||||
:hash (str "z" (-> hex
|
|
||||||
(subs 6)
|
|
||||||
hex/decode
|
|
||||||
b58/encode))})))
|
|
||||||
|
|
||||||
(defn url-fn [hex]
|
(defn url-fn [hex]
|
||||||
(let [{:keys [namespace hash]} (decode (ethereum/normalized-hex hex))]
|
(let [{:keys [namespace hash]} (decode (ethereum/normalized-hex hex))]
|
||||||
(case namespace
|
(case namespace
|
||||||
:ipfs (str "https://ipfs.infura.io/ipfs/" hash)
|
:ipfs (ipfs-url hash)
|
||||||
"")))
|
"")))
|
||||||
|
|
||||||
(def url (memoize url-fn))
|
(def url (memoize url-fn))
|
||||||
|
|
||||||
(fx/defn cat
|
|
||||||
[cofx {:keys [contenthash on-success on-failure]}]
|
|
||||||
(let [{:keys [namespace hash]} (decode contenthash)]
|
|
||||||
(when (= namespace :ipfs)
|
|
||||||
(ipfs/cat cofx
|
|
||||||
{:hash hash
|
|
||||||
:on-success on-success
|
|
||||||
:on-failure on-failure}))))
|
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
(testing "decoding a valid ipfs hash"
|
(testing "decoding a valid ipfs hash"
|
||||||
(is (= (contenthash/decode "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f")
|
(is (= (contenthash/decode "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f")
|
||||||
{:namespace :ipfs
|
{:namespace :ipfs
|
||||||
:hash "QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4"})))
|
:hash "bafybeibj6lixxzqtsb45ysdjnupvqkufgdvzqbnvmhw2kf7cfkesy7r7d4"})))
|
||||||
|
(testing "decoding a valid ipns hash"
|
||||||
|
(is (= (contenthash/decode "0xe5010170000f6170702e756e69737761702e6f7267")
|
||||||
|
{:namespace :ipns
|
||||||
|
:hash "app.uniswap.org"})))
|
||||||
(testing "decoding a valid swarm hash"
|
(testing "decoding a valid swarm hash"
|
||||||
(is (= (contenthash/decode "0xe40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162")
|
(is (= (contenthash/decode "0xe40101fa011b20d1de9994b4d039f6548d191eb26786769f580809256b4685ef316805265ea162")
|
||||||
{:namespace :swarm
|
{:namespace :swarm
|
||||||
|
@ -19,24 +23,4 @@
|
||||||
(testing "decoding random garbage"
|
(testing "decoding random garbage"
|
||||||
(is (nil? (contenthash/decode "0xabcdef1234567890"))))
|
(is (nil? (contenthash/decode "0xabcdef1234567890"))))
|
||||||
(testing "decoding nil"
|
(testing "decoding nil"
|
||||||
(is (nil? (contenthash/decode nil)))))
|
(is (nil? (contenthash/decode nil)))))
|
||||||
|
|
||||||
(deftest contenthash-encode
|
|
||||||
(testing "encoding a valid ipfs hash"
|
|
||||||
(is (= (contenthash/encode
|
|
||||||
{:namespace :ipfs
|
|
||||||
:hash "QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4"})
|
|
||||||
"0xe301122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f")))
|
|
||||||
(testing "encoding a valid ipfs cid"
|
|
||||||
(is (= (contenthash/encode
|
|
||||||
{:namespace :ipfs
|
|
||||||
:hash "zb2rhZfjRh2FHHB2RkHVEvL2vJnCTcu7kwRqgVsf9gpkLgteo"})
|
|
||||||
"0xe301015512202cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824")))
|
|
||||||
(testing "encoding an invalid ipfs hash"
|
|
||||||
(is (nil? (contenthash/encode {:namespace :ipfs
|
|
||||||
:hash "0xe301122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e2"}))))
|
|
||||||
(testing "encoding random garbage"
|
|
||||||
(is (nil? (contenthash/encode {:namespace :ipfs
|
|
||||||
:hash "0xabcdef1234567890"}))))
|
|
||||||
(testing "encoding random garbage"
|
|
||||||
(is (nil? (contenthash/encode nil)))))
|
|
|
@ -112,7 +112,7 @@
|
||||||
(.catch (or on-error #())))))
|
(.catch (or on-error #())))))
|
||||||
|
|
||||||
(defn normalize-url [url]
|
(defn normalize-url [url]
|
||||||
(str (when (and (string? url) (not (re-find #"^[a-zA-Z-_]+:/" url))) "http://") url))
|
(str (when (and (string? url) (not (re-find #"^[a-zA-Z-_]+:/" url))) "https://") url))
|
||||||
|
|
||||||
(def normalize-and-decode-url (comp js/decodeURI normalize-url))
|
(def normalize-and-decode-url (comp js/decodeURI normalize-url))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue