wip
This commit is contained in:
parent
d1f00320a1
commit
14df49232b
|
@ -1,5 +1,6 @@
|
|||
(ns cljs-tests.core
|
||||
(:require [cljs-tests.whisper-protocol :as p]))
|
||||
(:require [cljs-tests.protocol.api :as p]
|
||||
[cljs-tests.utils.logging :as log]))
|
||||
|
||||
(enable-console-print!)
|
||||
|
||||
|
@ -10,20 +11,34 @@
|
|||
)
|
||||
|
||||
|
||||
(comment
|
||||
|
||||
(p/init-protocol {:ethereum-rpc-url "http://localhost:4546"
|
||||
:handler (fn [{:keys [event-type] :as event}]
|
||||
(log/info "Event:" (clj->js event)))})
|
||||
|
||||
(p/send-user-msg {:to "0x04a877ae4dcd6005c8f4a576f8c11df56889f5252360cbf7e274bfcfc13f4028f10a3e29ebbb4af12c751d989fbaba09c570a78bc2c5e55773f0ee8579355a1358"
|
||||
:content "Hello World!"})
|
||||
|
||||
(p/my-identity)
|
||||
|
||||
)
|
||||
|
||||
|
||||
(comment
|
||||
|
||||
|
||||
|
||||
;;;;;;;;;;;; CHAT USER 1
|
||||
(def web3 (p/make-web3 "http://localhost:8545"))
|
||||
(def user1-ident (p/new-identity web3))
|
||||
(def listener (p/whisper-listen web3 (fn [err]
|
||||
(println "Whisper listener caught an error: " (js->clj err)))))
|
||||
|
||||
|
||||
(def web3-2 (p/make-web3 "http://localhost:8546"))
|
||||
(def user2-ident (p/new-identity web3-2))
|
||||
(p/send-message web3-2 user2-ident user1-ident "Hello World!")
|
||||
|
||||
;(def web3 (p/make-web3 "http://localhost:4546"))
|
||||
;(def user1-ident (p/new-identity web3))
|
||||
;(def listener (p/whisper-listen web3 (fn [err]
|
||||
; (println "Whisper listener caught an error: " (js->clj err)))))
|
||||
;
|
||||
;
|
||||
;(def web3-2 (p/make-web3 "http://localhost:4547"))
|
||||
;(def user2-ident (p/new-identity web3-2))
|
||||
;(p/make-whisper-msg web3-2 user2-ident user1-ident "Hello World!")
|
||||
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
(ns cljs-tests.protocol.api
|
||||
(:require [cljs-tests.protocol.state :as state]
|
||||
[cljs-tests.protocol.whisper :as whisper]))
|
||||
|
||||
(def default-content-type "text/plain")
|
||||
|
||||
(defn create-connection [ethereum-rpc-url]
|
||||
(whisper/make-web3 ethereum-rpc-url))
|
||||
|
||||
(defn create-identity [connection]
|
||||
(whisper/new-identity connection))
|
||||
|
||||
(defn init-protocol
|
||||
"Required [handler ethereum-rpc-url]
|
||||
Optional [whisper-identity] - if not passed a new identity is created automatically
|
||||
|
||||
(fn handler [{:keys [event-type...}])
|
||||
|
||||
:event-type can be:
|
||||
|
||||
:new-msg - [from payload]
|
||||
:error - [error-msg]
|
||||
:msg-acked [msg-id]
|
||||
"
|
||||
[{:keys [handler ethereum-rpc-url identity]}]
|
||||
(state/set-handler handler)
|
||||
(let [connection (create-connection ethereum-rpc-url)
|
||||
identity (or identity
|
||||
(create-identity connection))]
|
||||
(state/set-connection connection)
|
||||
(state/set-identity identity)
|
||||
(whisper/listen connection)
|
||||
{:identity identity}))
|
||||
|
||||
(defn send-user-msg [{:keys [to content]}]
|
||||
(let [[msg-id msg] (whisper/make-msg {:from (state/my-identity)
|
||||
:to to
|
||||
:payload {:content content
|
||||
:content-type default-content-type
|
||||
:type :user-msg}})]
|
||||
(state/add-pending-message msg-id msg)
|
||||
(whisper/post-msg (state/connection) msg)))
|
||||
|
||||
(defn my-identity []
|
||||
(state/my-identity))
|
||||
|
||||
(defn current-connection []
|
||||
(state/connection))
|
|
@ -0,0 +1,34 @@
|
|||
(ns cljs-tests.protocol.state)
|
||||
|
||||
(def state (atom {:pending-messages {}
|
||||
:filters {}
|
||||
:handler nil
|
||||
:identity nil
|
||||
:connection nil}))
|
||||
|
||||
(defn add-pending-message [msg-id msg]
|
||||
(swap! state assoc-in [:pending-messages msg-id] msg))
|
||||
|
||||
(defn add-filter [topics filter]
|
||||
(swap! state assoc-in [:filters topics] filter))
|
||||
|
||||
(defn remove-pending-message [msg-id]
|
||||
(swap! state update-in [:pending-messages] dissoc msg-id))
|
||||
|
||||
(defn set-handler [handler]
|
||||
(swap! state assoc :handler handler))
|
||||
|
||||
(defn set-identity [identity]
|
||||
(swap! state assoc :identity identity))
|
||||
|
||||
(defn set-connection [connection]
|
||||
(swap! state assoc :connection connection))
|
||||
|
||||
(defn connection []
|
||||
(:connection @state))
|
||||
|
||||
(defn my-identity []
|
||||
(:identity @state))
|
||||
|
||||
(defn handler []
|
||||
(:handler @state))
|
|
@ -0,0 +1,104 @@
|
|||
(ns cljs-tests.protocol.whisper
|
||||
(:require [cljsjs.web3]
|
||||
[cljsjs.chance]
|
||||
[cljs-tests.utils.logging :as log]
|
||||
[cljs-tests.protocol.state :as state]
|
||||
[cljs.reader :refer [read-string]]))
|
||||
|
||||
(def syng-app-topic "SYNG-APP-CHAT-TOPIC")
|
||||
(def syng-msg-ttl 100)
|
||||
|
||||
(defn from-ascii [s]
|
||||
(.fromAscii js/Web3.prototype s))
|
||||
|
||||
(defn whisper [web3]
|
||||
(.-shh web3))
|
||||
|
||||
(defn make-topics [topics]
|
||||
(->> {:topics (mapv from-ascii topics)}
|
||||
(clj->js)))
|
||||
|
||||
(defn make-web3 [rpc-url]
|
||||
(->> (js/Web3.providers.HttpProvider. rpc-url)
|
||||
(js/Web3.)))
|
||||
|
||||
(defn new-identity [web3]
|
||||
(.newIdentity (.-shh web3)))
|
||||
|
||||
(defn invoke-handler [event-type params]
|
||||
((state/handler) (assoc params :event-type event-type)))
|
||||
|
||||
(defn handle-ack [msg-id]
|
||||
(log/info "Got ack for message:" msg-id)
|
||||
(state/remove-pending-message msg-id)
|
||||
(invoke-handler :msg-acked {:msg-id msg-id}))
|
||||
|
||||
(defn post-msg [web3 msg]
|
||||
(let [js-msg (clj->js msg)]
|
||||
(log/info "Sending whisper message:" js-msg)
|
||||
(-> (whisper web3)
|
||||
(.post js-msg))))
|
||||
|
||||
(defn make-msg
|
||||
"Returns [msg-id msg], `msg` is formed for Web3.shh.post()"
|
||||
[{:keys [from to ttl topics payload]
|
||||
:or {ttl syng-msg-ttl
|
||||
topics []}}]
|
||||
(let [msg-id (.guid js/chance)]
|
||||
[msg-id (cond-> {:ttl ttl
|
||||
:topics (->> (conj topics syng-app-topic)
|
||||
(mapv from-ascii))
|
||||
:payload (->> (merge payload {:msg-id msg-id})
|
||||
(str)
|
||||
(from-ascii))}
|
||||
from (assoc :from from)
|
||||
to (assoc :to to))]))
|
||||
|
||||
(defn send-ack [web3 to msg-id]
|
||||
(log/info "Acking message:" msg-id "To:" to)
|
||||
(->> (make-msg {:from (state/my-identity)
|
||||
:to to
|
||||
:payload {:type :ack
|
||||
:msg-id msg-id}})
|
||||
(post-msg web3)))
|
||||
|
||||
(defn handle-user-msg [web3 from {:keys [msg-id] :as payload}]
|
||||
(send-ack web3 from msg-id)
|
||||
(invoke-handler :new-msg {:from from
|
||||
:payload payload}))
|
||||
|
||||
(defn handle-arriving-whisper-msg [web3 msg]
|
||||
(log/info "Got whisper message:" msg)
|
||||
(let [{from :from
|
||||
to :to
|
||||
topics :topics ;; always empty (bug in go-ethereum?)
|
||||
payload :payload
|
||||
:as msg} (js->clj msg :keywordize-keys true)]
|
||||
(if (= to (state/my-identity))
|
||||
(let [{msg-type :type
|
||||
msg-id :msg-id
|
||||
:as payload} (->> (from-ascii payload)
|
||||
(read-string))]
|
||||
(case msg-type
|
||||
:ack (handle-ack msg-id)
|
||||
:user-msg (handle-user-msg web3 from payload)))
|
||||
(log/warn "My identity:" (state/my-identity) "Message To:" to "Message is encrypted for someone else, ignoring"))))
|
||||
|
||||
(defn listen
|
||||
"Returns a filter which can be stopped with (stop-whisper-listener)"
|
||||
[web3]
|
||||
(let [topics [syng-app-topic]
|
||||
shh (whisper web3)
|
||||
filter (.filter shh (make-topics topics))
|
||||
watch (.watch filter (fn [error msg]
|
||||
(if error
|
||||
(invoke-handler :error {:error-msg error})
|
||||
(handle-arriving-whisper-msg web3 msg))))]
|
||||
(state/add-filter topics filter)))
|
||||
|
||||
(defn stop-listener [filter]
|
||||
(.stopWatching filter))
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(ns cljs-tests.utils.logging)
|
||||
|
||||
(defn info [& args]
|
||||
(.apply (.-log js/console) js/console (into-array args)))
|
||||
|
||||
(defn warn [& args]
|
||||
(.apply (.-warn js/console) js/console (into-array args)))
|
||||
|
||||
(defn error [& args]
|
||||
(.apply (.-error js/console) js/console (into-array args)))
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
(ns cljs-tests.whisper-protocol
|
||||
(:require [cljsjs.web3]
|
||||
[cljsjs.chance]))
|
||||
|
||||
|
||||
(def pending-messages (atom {}))
|
||||
(def syng-app-topic "SYNG-APP-CHAT-TOPIC")
|
||||
(def syng-msg-ttl 100)
|
||||
(def default-content-type "text/plain")
|
||||
|
||||
(defn from-ascii [s]
|
||||
(.fromAscii js/Web3.prototype s))
|
||||
|
||||
(defn whisper [web3]
|
||||
(.-shh web3))
|
||||
|
||||
(defn make-web3 [rpc-url]
|
||||
(->> (js/Web3.providers.HttpProvider. rpc-url)
|
||||
(js/Web3.)))
|
||||
|
||||
(defn make-topics [topics]
|
||||
(->> {:topics (mapv from-ascii topics)}
|
||||
(clj->js)))
|
||||
|
||||
(defn new-identity [web3]
|
||||
(.newIdentity (.-shh web3)))
|
||||
|
||||
(defn whisper-listen
|
||||
"Returns a filter which can be used with (stop-whisper-listener)"
|
||||
[web3 on-error]
|
||||
(let [shh (whisper web3)
|
||||
filter (.filter shh (make-topics [syng-app-topic]))
|
||||
watch (.watch filter (fn [error result]
|
||||
(if error
|
||||
(on-error error)
|
||||
(println "got whisper msg:" (js->clj result)))))]
|
||||
filter))
|
||||
|
||||
(defn stop-whisper-listener [filter]
|
||||
(.stopWatching filter))
|
||||
|
||||
(defn send-message
|
||||
([web3 from to content]
|
||||
(let [msg-id (.guid js/chance)
|
||||
msg (cond-> {:ttl syng-msg-ttl
|
||||
:topics [(from-ascii syng-app-topic)]
|
||||
:payload (from-ascii content)
|
||||
;(->> (str {:msg-id msg-id
|
||||
; :msg-num 122
|
||||
; :type :user-message
|
||||
; :content encoded-msg
|
||||
; :content-type default-content-type})
|
||||
; (from-ascii))
|
||||
:from from}
|
||||
to (assoc :to to))]
|
||||
(println "sending:" msg)
|
||||
(.log js/console (clj->js msg))
|
||||
(swap! pending-messages assoc msg-id msg)
|
||||
(.post (.-shh web3)
|
||||
(clj->js
|
||||
(dissoc msg :from :to)))
|
||||
))
|
||||
([web3 from content]
|
||||
(send-message web3 from nil content)))
|
Loading…
Reference in New Issue