Verify ens names on messages and contact requests

This commits verifies ens names when new messages or contact requests
come through.
A batch of ens names is sent to status-go which will then verifying them
and the result will be passed back in a callback to status-react.

Also temporary skipped test_ens_in_public_chat until we merge the ENS
code (blocked currently by 1.9 upgrade)

Signed-off-by: Andrea Maria Piana <andrea.maria.piana@gmail.com>
This commit is contained in:
Andrea Maria Piana 2019-10-11 13:33:34 +02:00
parent 474ff00c7f
commit 57b1722863
No known key found for this signature in database
GPG Key ID: AA6CCA6DE0E06424
20 changed files with 224 additions and 99 deletions

View File

@ -101,11 +101,11 @@
{:db (assoc-in db [:contacts/new-identity] "")}
(upsert-contact contact)))))
(defn handle-contact-update
[public-key
(fx/defn handle-contact-update
[{{:contacts/keys [contacts] :as db} :db :as cofx}
public-key
timestamp
{:keys [name profile-image address fcm-token device-info] :as m}
{{:contacts/keys [contacts] :as db} :db :as cofx}]
{:keys [name profile-image address fcm-token device-info] :as m}]
;; We need to convert to timestamp ms as before we were using now in ms to
;; set last updated
;; Using whisper timestamp mostly works but breaks in a few scenarios:
@ -139,10 +139,6 @@
fcm-token (assoc :fcm-token fcm-token))]
(upsert-contact cofx contact-props)))))
(def receive-contact-request handle-contact-update)
(def receive-contact-request-confirmation handle-contact-update)
(def receive-contact-update handle-contact-update)
(fx/defn initialize-contacts [cofx]
(contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %])))
@ -161,3 +157,29 @@
(assoc :tribute-to-talk (or tribute-to-talk
{:disabled? true})))]
{:db (assoc-in db [:contacts/contacts public-key] contact)}))
(defn add-ens-names [contacts names]
(reduce-kv (fn [acc public-key-keyword result]
(let [verified (:verified result)
error (:error result)
ens-name (:name result)
ens-verified-at (:verifiedAt result)
public-key (str "0x" (name public-key-keyword))
contact (contact.db/public-key->contact contacts public-key)]
(if error
(assoc acc public-key contact)
(assoc acc public-key
(assoc contact
;; setting the name for now as ens-verification is not enabled because of geth 1.9 upgrade
:name ens-name
:ens-verified-at ens-verified-at
:ens-verified verified)))))
(or contacts {})
names))
(fx/defn names-verified
{:events [:contacts/ens-names-verified]}
[{:keys [db]} names]
{:db (update db :contacts/contacts add-ens-names names)})

View File

@ -15,6 +15,8 @@
(spec/def :contact/last-online (spec/nilable int?))
(spec/def :contact/last-updated (spec/nilable int?))
(spec/def :contact/name (spec/nilable string?))
(spec/def :contact/ens-verified (spec/nilable boolean?))
(spec/def :contact/ens-verified-at (spec/nilable int?))
(spec/def :contact/public-key :global/not-empty-string)
(spec/def :contact/photo-path (spec/nilable string?))
@ -63,11 +65,13 @@
(spec/def :ui/contact (spec/keys :opt [:contact/new-tag]))
(defn public-key->new-contact [public-key]
{:name (gfycat/generate-gfy public-key)
:address (ethereum/public-key->address public-key)
:identicon (identicon/identicon public-key)
:public-key public-key
:system-tags #{}})
(let [alias (gfycat/generate-gfy public-key)]
{:alias alias
:name alias
:address (ethereum/public-key->address public-key)
:identicon (identicon/identicon public-key)
:public-key public-key
:system-tags #{}}))
(defn public-key->contact
[contacts public-key]

View File

@ -33,6 +33,8 @@
:photoPath :photo-path
:deviceInfo :device-info
:tributeToTalk :tribute-to-talk
:ensVerifiedAt :ens-verified-at
:ensVerified :ens-verified
:systemTags :system-tags
:lastUpdated :last-updated})))
@ -42,6 +44,8 @@
(update :tribute-to-talk types/serialize)
(update :system-tags #(mapv str %))
(clojure.set/rename-keys {:public-key :id
:ens-verified :ensVerified
:ens-verified-at :ensVerifiedAt
:photo-path :photoPath
:device-info :deviceInfo
:tribute-to-talk :tributeToTalk

View File

@ -2,6 +2,9 @@
(:require [clojure.string :as string]
[re-frame.core :as re-frame]
[status-im.ens.db :as ens.db]
[taoensso.timbre :as log]
[status-im.multiaccounts.update.core :as multiaccounts.update]
[status-im.multiaccounts.model :as multiaccounts.model]
[status-im.ethereum.abi-spec :as abi-spec]
[status-im.ethereum.contracts :as contracts]
[status-im.ethereum.core :as ethereum]
@ -11,6 +14,7 @@
[status-im.ethereum.stateofus :as stateofus]
[status-im.ui.screens.navigation :as navigation]
[status-im.utils.fx :as fx]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.money :as money]
[status-im.signing.core :as signing]
[status-im.multiaccounts.update.core :as multiaccounts.update]
@ -252,3 +256,31 @@
(fx/merge cofx
(set-username-candidate (get-in db [:ens/registration :username] ""))
(navigation/navigate-to-cofx :ens-search {})))
(defn verify-names [names]
(json-rpc/call {:method "shhext_verifyENSNames"
:params [names]
:on-success #(re-frame/dispatch [:contacts/ens-names-verified %])
:on-failure #(log/error "failed to resolve ens names" % names)}))
(re-frame/reg-fx
::verify-names
(fn [names]
(verify-names (distinct names))))
(defn should-be-verified? [cofx ens-name signature]
(and ens-name
(not (get-in cofx [:contacts/contacts signature :ens-verified]))
(not= signature (multiaccounts.model/current-public-key cofx))
(or (valid-custom-domain? ens-name)
(stateofus/valid-username? ens-name))))
(fx/defn verify-names-from-message [cofx {:keys [content]} signature]
(when (should-be-verified? cofx (:name content) signature)
{::verify-names [{:name (:name content)
:publicKey (subs signature 2)}]}))
(fx/defn verify-names-from-contact-request [cofx {:keys [name]} signature]
(when (should-be-verified? cofx name signature)
{::verify-names [{:name name
:publicKey (subs signature 2)}]}))

View File

@ -55,6 +55,7 @@
;;TODO not used anywhere?
"shhext_deleteChat" {}
"shhext_saveContact" {}
"shhext_verifyENSNames" {}
"status_chats" {}
"wallet_getTransfers" {}
"wallet_getTokensBalances" {}

View File

@ -14,16 +14,23 @@
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]))
; Whether we should be strict about verifying ens, currently disabled as
; status-go can't be upgrade because of geth 1.9 incompatibility
(def only-verified-ens false)
(defn displayed-name
"Use preferred name, name or alias in that order"
[{:keys [name preferred-name alias public-key]}]
(let [name (or preferred-name
name
alias)]
(if (ens/is-valid-eth-name? name)
(let [username (stateofus/username name)]
(str "@" (or username name)))
(or name (gfycat/generate-gfy public-key)))))
[{:keys [name preferred-name alias public-key ens-verified]}]
(let [ens-name (or preferred-name
name)]
;; Preferred name is our own
;; otherwise we make sure is verified
(if (or preferred-name
(and only-verified-ens
ens-verified
name))
(let [username (stateofus/username ens-name)]
(str "@" (or username ens-name)))
(or alias (gfycat/generate-gfy public-key)))))
(defn displayed-photo
"If a photo-path is set use it, otherwise fallback on identicon or generate"

View File

@ -1583,11 +1583,12 @@
(fn [[contacts current-multiaccount] [_ identity]]
(let [me? (= (:public-key current-multiaccount) identity)]
(if me?
{:username (:name current-multiaccount)
{:ens-name (:name current-multiaccount)
:alias (gfycat/generate-gfy identity)}
(let [contact (or (contacts identity)
(contact.db/public-key->new-contact identity))]
{:username (:name contact)
{:ens-name (when (:ens-verified contact)
(:name contact))
:alias (or (:alias contact)
(gfycat/generate-gfy identity))})))))

View File

@ -1,10 +1,14 @@
(ns status-im.transport.impl.receive
(:require [status-im.group-chats.core :as group-chats]
[status-im.contact.core :as contact]
[status-im.utils.fx :as fx]
[status-im.ens.core :as ens]
[status-im.pairing.core :as pairing]
[status-im.transport.message.contact :as transport.contact]
[status-im.transport.message.group-chat :as transport.group-chat]
[status-im.transport.message.pairing :as transport.pairing]
[status-im.transport.message.core :as transport.message]
[status-im.transport.message.protocol :as protocol]))
(extend-type transport.group-chat/GroupMembershipUpdate
@ -16,17 +20,26 @@
(extend-type transport.contact/ContactRequest
protocol/StatusMessage
(receive [this _ signature timestamp cofx]
(contact/receive-contact-request signature timestamp this cofx)))
(fx/merge
cofx
(contact/handle-contact-update cofx signature timestamp this)
(ens/verify-names-from-contact-request this signature))))
(extend-type transport.contact/ContactRequestConfirmed
protocol/StatusMessage
(receive [this _ signature timestamp cofx]
(contact/receive-contact-request-confirmation signature timestamp this cofx)))
(fx/merge
cofx
(contact/handle-contact-update cofx signature timestamp this)
(ens/verify-names-from-contact-request this signature))))
(extend-type transport.contact/ContactUpdate
protocol/StatusMessage
(receive [this _ signature timestamp cofx]
(contact/receive-contact-update signature timestamp this cofx)))
(fx/merge
cofx
(contact/handle-contact-update cofx signature timestamp this)
(ens/verify-names-from-contact-request this signature))))
(extend-type transport.pairing/SyncInstallation
protocol/StatusMessage
@ -37,3 +50,10 @@
protocol/StatusMessage
(receive [this _ signature timestamp cofx]
(pairing/handle-pair-installation cofx this timestamp signature)))
(extend-type protocol/Message
protocol/StatusMessage
(receive [this chat-id signature timestamp cofx]
(fx/merge cofx
(transport.message/receive-transit-message this chat-id signature timestamp)
(ens/verify-names-from-message this signature))))

View File

@ -10,6 +10,7 @@
[status-im.transport.message.protocol :as protocol]
[status-im.transport.message.transit :as transit]
[status-im.transport.utils :as transport.utils]
[status-im.tribute-to-talk.whitelist :as whitelist]
[status-im.utils.config :as config]
[status-im.utils.fx :as fx]
[taoensso.timbre :as log]
@ -180,3 +181,21 @@
:params [confirmations]
:on-success #(log/debug "successfully confirmed messages")
:on-failure #(log/error "failed to confirm messages" %)}))))
(fx/defn receive-transit-message [cofx message chat-id signature timestamp]
(let [received-message-fx {:chat-received-message/add-fx
[(assoc (into {} message)
:message-id
(get-in cofx [:metadata :messageId])
:chat-id chat-id
:whisper-timestamp timestamp
:alias (get-in cofx [:metadata :author :alias])
:identicon (get-in cofx [:metadata :author :identicon])
:from signature
:metadata (:metadata cofx)
:js-obj (:js-obj cofx))]}]
(whitelist/filter-message cofx
received-message-fx
(:message-type message)
(get-in message [:content :tribute-transaction])
signature)))

View File

@ -70,28 +70,6 @@
(when (pairing.utils/has-paired-installations? cofx)
(send-direct-message current-public-key nil this))
(send-with-pubkey params)))))
(receive [this chat-id signature timestamp cofx]
(let [received-message-fx {:chat-received-message/add-fx
[(assoc (into {} this)
:message-id
(or (get-in cofx [:metadata :messageId])
(transport.utils/message-id
signature
(.-payload (:js-obj cofx))))
:chat-id chat-id
:whisper-timestamp timestamp
:raw-payload-hash (ethereum/sha3
(.-payload (:js-obj cofx)))
:alias (get-in cofx [:metadata :author :alias])
:identicon (get-in cofx [:metadata :author :identicon])
:from signature
:metadata (:metadata cofx)
:js-obj (:js-obj cofx))]}]
(whitelist/filter-message cofx
received-message-fx
message-type
(get-in this [:content :tribute-transaction])
signature)))
(validate [this]
(if (spec/valid? :message/message this)
this

View File

@ -154,14 +154,14 @@
:color colors/gray}]]])))
(defview reply-message [from alias message-text]
(letsubs [{:keys [username]} [:contacts/contact-name-by-identity from]
(letsubs [{:keys [ens-name]} [:contacts/contact-name-by-identity from]
current-public-key [:multiaccount/public-key]]
[react/scroll-view {:style style/reply-message-content}
[react/view {:style style/reply-message-to-container}
[vector-icons/tiny-icon :tiny-icons/tiny-reply {:container-style style/reply-icon
:width 20
:color colors/gray}]
(chat-utils/format-reply-author from alias username current-public-key style/reply-message-author)]
(chat-utils/format-reply-author from alias ens-name current-public-key style/reply-message-author)]
[react/text {:style (assoc (message-style/style-message-text false) :font-size 14) :number-of-lines 3} message-text]]))
(defview reply-message-view []

View File

@ -45,11 +45,11 @@
content content-type]])
(defview quoted-message [{:keys [from text]} outgoing current-public-key]
(letsubs [{:keys [username alias]} [:contacts/contact-name-by-identity from]]
(letsubs [{:keys [ens-name alias]} [:contacts/contact-name-by-identity from]]
[react/view {:style (style/quoted-message-container outgoing)}
[react/view {:style style/quoted-message-author-container}
[vector-icons/tiny-icon :tiny-icons/tiny-reply {:color (if outgoing colors/white-transparent colors/gray)}]
(chat.utils/format-reply-author from alias username current-public-key (partial style/quoted-message-author outgoing))]
(chat.utils/format-reply-author from alias ens-name current-public-key (partial style/quoted-message-author outgoing))]
[react/text {:style (style/quoted-message-text outgoing)
:number-of-lines 5}
@ -196,8 +196,9 @@
(:command content))
[command-status content]))))
(defview message-author-name [alias name]
(chat.utils/format-author alias style/message-author-name name))
(defview message-author-name [from alias]
(letsubs [{:keys [ens-name]} [:contacts/contact-name-by-identity from]]
(chat.utils/format-author alias style/message-author-name ens-name)))
(defn message-body
[{:keys [last-in-group?
@ -219,7 +220,7 @@
[react/view (style/group-message-view outgoing display-photo?)
(when display-username?
[react/touchable-opacity {:on-press #(re-frame/dispatch [:chat.ui/show-profile from])}
[message-author-name alias (:name content)]])
[message-author-name from alias]])
[react/view {:style (style/timestamp-content-wrapper outgoing)}
child]]]
[react/view (style/delivery-status outgoing)

View File

@ -13,7 +13,7 @@
(defn format-author [alias style name]
(let [additional-styles (style false)]
(if (ens/is-valid-eth-name? name)
(if name
[react/text {:style (merge {:color colors/blue :font-size 13 :font-weight "500"} additional-styles)}
(str "@" (or (stateofus/username name) name))]
[react/text {:style (merge {:color colors/gray :font-size 12 :font-weight "400"} additional-styles)}

View File

@ -64,12 +64,12 @@
:height 24}}]]]))
(views/defview message-author-name [{:keys [from]}]
(views/letsubs [{:keys [username]} [:contacts/contact-name-by-identity from]]
(views/letsubs [{:keys [ens-name alias]} [:contacts/contact-name-by-identity from]]
[react/view {:flex-direction :row}
(when username
[react/text {:style styles/author} username])
(when ens-name
[react/text {:style styles/author} ens-name])
[react/text {:style styles/author-generated}
(str (when username " • ") (gfycat/generate-gfy from))]]))
(str (when ens-name " • ") alias)]]))
(views/defview member-photo [from]
(views/letsubs [current-public-key [:multiaccount/public-key]
@ -85,14 +85,14 @@
:style styles/photo-style}]]]]]))
(views/defview quoted-message [{:keys [from text]} outgoing current-public-key]
(views/letsubs [{:keys [username alias]} [:contacts/contact-name-by-identity from]]
(views/letsubs [{:keys [ens-name alias]} [:contacts/contact-name-by-identity from]]
[react/view {:style styles/quoted-message-container}
[react/view {:style styles/quoted-message-author-container}
[vector-icons/tiny-icon :tiny-icons/tiny-reply {:style (styles/reply-icon outgoing)
:width 16
:height 16
:container-style (when outgoing {:opacity 0.4})}]
(chat-utils/format-reply-author from alias username current-public-key (partial message.style/quoted-message-author outgoing))]
(chat-utils/format-reply-author from alias ens-name current-public-key (partial message.style/quoted-message-author outgoing))]
[react/text {:style (message.style/quoted-message-text outgoing)
:number-of-lines 5}
(core-utils/truncate-str text constants/chars-collapse-threshold)]]))
@ -271,10 +271,10 @@
[vector-icons/icon :main-icons/arrow-left {:style (styles/send-icon-arrow inactive?)}]]])))
(views/defview reply-message [from alias message-text]
(views/letsubs [{:keys [username]} [:contacts/contact-name-by-identity from]
(views/letsubs [{:keys [ens-name]} [:contacts/contact-name-by-identity from]
current-public-key [:multiaccount/public-key]]
[react/view {:style styles/reply-content-container}
(chat-utils/format-reply-author from alias username current-public-key styles/reply-content-author)
(chat-utils/format-reply-author from alias ens-name current-public-key styles/reply-content-author)
[react/text {:style styles/reply-content-message} message-text]]))
(views/defview reply-member-photo [from]

View File

@ -31,7 +31,7 @@
(.blur password-text-input)
(re-frame/dispatch [:multiaccounts.login.ui/password-input-submitted]))
(defn multiaccount-login-badge [{:keys [public-key] :as multiaccount}]
(defn multiaccount-login-badge [{:keys [public-key name] :as multiaccount}]
[react/view styles/login-badge
[photos/photo
;;TODO this should be done in a subscription
@ -42,7 +42,7 @@
:ellipsize-mode :middle
:numberOfLines 1}
;;TODO this should be done in a subscription
(multiaccounts/displayed-name multiaccount)]
name]
[react/text {:style styles/login-badge-pubkey}
(utils/get-shortened-address public-key)]]])

View File

@ -16,6 +16,7 @@
:filters/load-filters
:pairing/set-installation-metadata
:status-im.data-store.messages/save-message
:status-im.ens.core/verify-names
:shh/send-direct-message
:shh/remove-filter
:shh/generate-sym-key-from-password

View File

@ -711,6 +711,8 @@ class TestProfileMultipleDevice(MultipleDeviceTestCase):
@marks.testrail_id(6226)
@marks.critical
@marks.skip
# TODO: skipped in PR 9178 - should be re-enabled once geth 1.9 upgrade will be merged
def test_ens_in_public_chat(self):
self.create_drivers(2)
device_1, device_2 = self.drivers[0], self.drivers[1]

View File

@ -37,6 +37,7 @@
current-multiaccount)
[{:name "generated"
:identicon "generated"
:alias "generated"
:admin? true
:address "71adb0644e2b590e37dafdfea8bd58f0c7668c7f"
:public-key "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"

View File

@ -1,6 +1,8 @@
(ns status-im.test.models.contact
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.ethereum.json-rpc :as json-rpc]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]
[status-im.contact.core :as model]))
(def public-key "0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917")
@ -10,6 +12,7 @@
(with-redefs [json-rpc/call (constantly nil)]
(testing "the contact is not in contacts"
(let [actual (model/handle-contact-update
{:db {}}
public-key
1
{:name "name"
@ -17,8 +20,7 @@
:address "address"
:device-info [{:id "1"
:fcm-token "token-1"}]
:fcm-token "token"}
{:db {}})
:fcm-token "token"})
contact (get-in actual [:db :contacts/contacts public-key])]
(testing "it adds a new contact"
(is (= {:public-key public-key
@ -35,16 +37,6 @@
(testing "the contact is already in contacts"
(testing "timestamp is greater than last-updated"
(let [actual (model/handle-contact-update
public-key
1
{:name "new-name"
:profile-image "new-image"
:device-info [{:id "2"
:fcm-token "token-2"}
{:id "3"
:fcm-token "token-3"}]
:address "new-address"
:fcm-token "new-token"}
{:db {:contacts/contacts
{public-key {:public-key public-key
:photo-path "old-image"
@ -58,7 +50,17 @@
:fcm-token "token-2"}}
:system-tags #{:contact/added}
:fcm-token "old-token"
:address "old-address"}}}})
:address "old-address"}}}}
public-key
1
{:name "new-name"
:profile-image "new-image"
:device-info [{:id "2"
:fcm-token "token-2"}
{:id "3"
:fcm-token "token-3"}]
:address "new-address"
:fcm-token "new-token"})
contact (get-in actual [:db :contacts/contacts public-key])]
(testing "it updates the contact and adds contact/request-received to system tags"
(is (= {:public-key public-key
@ -80,12 +82,6 @@
contact)))))
(testing "timestamp is equal to last-updated"
(let [actual (model/handle-contact-update
public-key
1
{:name "new-name"
:profile-image "new-image"
:address "new-address"
:fcm-token "new-token"}
{:db {:contacts/contacts
{public-key {:public-key public-key
:photo-path "old-image"
@ -93,18 +89,18 @@
:last-updated 1000
:system-tags #{:contact/added}
:fcm-token "old-token"
:address "old-address"}}}})
:address "old-address"}}}}
public-key
1
{:name "new-name"
:profile-image "new-image"
:address "new-address"
:fcm-token "new-token"})
contact (get-in actual [:db :contacts/contacts public-key])]
(testing "it does nothing"
(is (nil? actual)))))
(testing "timestamp is less than last-updated"
(let [actual (model/handle-contact-update
public-key
0
{:name "new-name"
:profile-image "new-image"
:address "new-address"
:fcm-token "new-token"}
{:db {:contacts/contacts
{public-key {:public-key public-key
:photo-path "old-image"
@ -112,16 +108,18 @@
:last-updated 1000
:system-tags #{:contact/added :contact/request-received}
:fcm-token "old-token"
:address "old-address"}}}})
:address "old-address"}}}}
public-key
0
{:name "new-name"
:profile-image "new-image"
:address "new-address"
:fcm-token "new-token"})
contact (get-in actual [:db :contacts/contacts public-key])]
(testing "it does nothing"
(is (nil? actual))))))
(testing "backward compatibility"
(let [actual (model/handle-contact-update
public-key
1
{:name "new-name"
:profile-image "new-image"}
{:db {:contacts/contacts
{public-key {:public-key public-key
:photo-path "old-image"
@ -129,7 +127,11 @@
:fcm-token "token-1"}}
:name "old-name"
:last-updated 0
:system-tags #{:contact/added}}}}})
:system-tags #{:contact/added}}}}}
public-key
1
{:name "new-name"
:profile-image "new-image"})
contact (get-in actual [:db :contacts/contacts public-key])]
(testing "it updates the contact"
(is (= {:public-key public-key
@ -142,4 +144,33 @@
:address address} contact)))))
(testing "the message is coming from us"
(testing "it does not update contacts"
(is (nil? (model/handle-contact-update "me" 1 {} {:db {:multiaccount {:public-key "me"}}})))))))
(is (nil? (model/handle-contact-update {:db {:multiaccount {:public-key "me"}}} "me" 1 {})))))))
(deftest add-ens-names-test
(with-redefs [gfycat/generate-gfy (constantly "generated")
identicon/identicon (constantly "generated")]
(testing "adding ens names"
(let [pk1 "048e57d37615380705cedf2eacc3543e7597eaed38c0bd0ff5b8c759406c657a29b4d6f4018ae323479dafa6bf1c821a422f2478a6759689afbca5e48fba720332"
pk2 "04318d20a2ca5fd0022579005ed24802e07d4ec610bede808dd13d3318af439e16d55be1a59af007a11120bd1c205861e5f53fe7b000a25e2b0d4eee7f0c5ebf7e"
expected {(str "0x" pk1) {:alias "generated"
:identicon "generated"
:name "name-1"
:address "6dd28d3d14c6ded091ed38a6735350ce92fe1956"
:ens-verified true
:ens-verified-at 1
:public-key (str "0x" pk1)
:system-tags #{}}
(str "0x" pk2) {:alias "generated"
:name "name-2"
:identicon "generated"
:address "7ab91a68f65c1365d8071302a71599273acb68a2"
:ens-verified false
:ens-verified-at 2
:public-key (str "0x" pk2)
:system-tags #{}}}]
(is (= expected (model/add-ens-names {} {pk1 {:verified true
:name "name-1"
:verifiedAt 1}
pk2 {:verified false
:name "name-2"
:verifiedAt 2}})))))))

View File

@ -1,6 +1,7 @@
(ns status-im.test.transport.core
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.utils.fx :as fx]
status-im.transport.impl.receive
[status-im.protocol.core :as protocol]
[status-im.transport.core :as transport]
[status-im.transport.message.core :as message]))