forked from status-im/status-legacy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontenthash.cljs
More file actions
71 lines (67 loc) · 2.54 KB
/
contenthash.cljs
File metadata and controls
71 lines (67 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
(ns status-im.utils.contenthash
"TODO: currently we only support encoding/decoding ipfs contenthash
implementing swarm and other protocols will come later"
(:refer-clojure :exclude [cat])
(:require [alphabase.base58 :as b58]
[alphabase.hex :as hex]
[clojure.string :as string]
[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
"TODO properly decode the CID
extract the content-type using varint ns"
[hex]
(when (and hex (not= hex "0x"))
(cond
(and (string/starts-with? hex "0xe40101"))
;; content type can be 2 or 4 bytes
;; we expect 1b20 (hash algorithm and hash length 64)
;; before the hash so we split the contenthash there
(when-let [hash (second (string/split hex "1b20"))]
(when (= 0x20 (count hash)))
{:namespace :swarm
:hash hash})
(and (= 78 (count hex))
(string/starts-with? hex "0xe3010170"))
;; for retrocompatibility with old CIDv0
{:namespace :ipfs
:hash (-> hex
(subs 10)
hex/decode
b58/encode)}
(and (= 78 (count hex))
(string/starts-with? hex "0xe30101"))
;; new CIDv1
{:namespace :ipfs
:hash (str "z" (-> hex
(subs 6)
hex/decode
b58/encode))})))
(defn url [hex]
(let [{:keys [namespace hash]} (decode (ethereum/normalized-address hex))]
(case namespace
:ipfs (str "https://ipfs.infura.io/ipfs/" hash)
"")))
(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}))))