Rudimentary reply is working.

This commit is contained in:
Robert C. Martin 2022-04-20 09:15:31 -05:00
parent 7afaa564c6
commit bc2b912cab
6 changed files with 101 additions and 26 deletions

View File

@ -1,6 +1,7 @@
(ns more-speech.nostr.events_spec
(:require [speclj.core :refer :all]
[more-speech.nostr.events :refer :all]))
[more-speech.nostr.events :refer :all]
[more-speech.nostr.elliptic-signature :as ecc]))
(declare now event state)
(describe "Processing Text events (Kind 1)"
@ -79,4 +80,41 @@
)
)
(describe "Composing outgoing events"
(it "composes an original message."
(let [private-key (ecc/num->bytes 64 42)
public-key (ecc/get-pub-key private-key)
text "message text"
event (compose-text-event private-key text)
{:keys [pubkey created_at kind tags content id sig]} (second event)
now (quot (System/currentTimeMillis) 1000)]
(should= "EVENT" (first event))
(should= (ecc/bytes->hex-string public-key) pubkey)
(should (<= 0 (- now created_at) 1 )) ;within one second.
(should= 1 kind)
(should= [] tags)
(should= text content)
(should (ecc/do-verify (ecc/hex-string->bytes id)
public-key
(ecc/hex-string->bytes sig)))))
(it "composes a reply."
(let [private-key (ecc/num->bytes 64 42)
public-key (ecc/get-pub-key private-key)
reply-to (ecc/num->bytes 32 7734)
text "message text"
event (compose-text-event private-key text reply-to)
{:keys [pubkey created_at kind tags content id sig]} (second event)
now (quot (System/currentTimeMillis) 1000)]
(should= "EVENT" (first event))
(should= (ecc/bytes->hex-string public-key) pubkey)
(should (<= 0 (- now created_at) 1)) ;within one second.
(should= 1 kind)
(should= [[:e (ecc/bytes->hex-string reply-to)]] tags)
(should= text content)
(should (ecc/do-verify (ecc/hex-string->bytes id)
public-key
(ecc/hex-string->bytes sig)))))
)

View File

@ -13,12 +13,13 @@
state (reply-to-article state)
edit-frame (get-in state [:application :edit-window :text-frame])]
(should= [""] (get edit-frame :text))
(should-be-nil (:reply-id edit-frame))
(should= [0 0] (get edit-frame :insertion-point))))
(it "will create a simple reply if a simple article is being displayed"
(let [state (assoc-in @state [:application :selected-header] 1)
event-map (get-in state [:application :text-event-map])
event-map (assoc event-map 1 {:id "1"
event-map (assoc event-map 1 {:id 0x1d
:pubkey 0xf00d
:created-at @now
:kind 1
@ -29,5 +30,8 @@
state (reply-to-article state)
edit-frame (get-in state [:application :edit-window :text-frame])]
(should= [">simple"] (get edit-frame :text))
(should= 0x1d (:reply-id edit-frame))
(should= [0 0] (get edit-frame :insertion-point))))
)

View File

@ -1,5 +1,9 @@
;;Stories
;; - Add author/date, etc. to replies.
;; - Start checking sdefs in update.
;; - Clean up java schnorr library.
;; - Messages with / don't work. Signature is wrong somehow?
;; - Messages with unicode (\u) don't work either.
;; - Threading does not work quite right. Do some diagnosis.
;; - Reply
;; - Mark read and highlight properly.

View File

@ -65,7 +65,9 @@
(defn do-verify [message public-key signature]
(Schnorr/verify message public-key signature))
(defn get-pub-key [private-key]
(defn get-pub-key
"private-key is byte array. Returns byte array."
[private-key]
(Schnorr/genPubKey private-key))

View File

@ -113,21 +113,34 @@
id)
)
(defn compose-text-event [private-key text]
(let [private-key (ecc/hex-string->bytes private-key)
pubkey (ecc/get-pub-key private-key)
tags []
content text
now (quot (System/currentTimeMillis) 1000)
body {:pubkey (ecc/bytes->hex-string pubkey)
:created_at now
:kind 1
:tags tags
:content content}
id (make-id body)
aux-rand (ecc/num->bytes 32 (biginteger (System/currentTimeMillis)))
signature (ecc/do-sign id private-key aux-rand)
event (assoc body :id (ecc/bytes->hex-string id)
:sig (ecc/bytes->hex-string signature))
]
["EVENT" event]))
(declare make-reply-tag)
(defn compose-text-event
([private-key text]
(compose-text-event private-key text nil))
([private-key text reply-to]
(let [pubkey (ecc/get-pub-key private-key)
tags (if (some? reply-to)
[(make-reply-tag reply-to)]
[])
content text
now (quot (System/currentTimeMillis) 1000)
body {:pubkey (ecc/bytes->hex-string pubkey)
:created_at now
:kind 1
:tags tags
:content content}
id (make-id body)
aux-rand (ecc/num->bytes 32 (biginteger (System/currentTimeMillis)))
signature (ecc/do-sign id private-key aux-rand)
event (assoc body :id (ecc/bytes->hex-string id)
:sig (ecc/bytes->hex-string signature))
]
["EVENT" event])))
(defn make-reply-tag [reply-to]
(let [reply-to (ecc/num->bytes 32 reply-to)
reply-to (ecc/bytes->hex-string reply-to)]
[:e reply-to])
)

View File

@ -7,12 +7,19 @@
[more-speech.nostr.events :as events]
[clojure.string :as string]
[clojure.core.async :as async]
[more-speech.ui.formatters :as formatters]))
[more-speech.ui.formatters :as formatters]
[more-speech.nostr.elliptic-signature :as ecc]))
;; edit-frame
;; - :text A vector containing the lines of the composed message
;; - :reply-id nil, or the numeric id of the article being replied to.
;; - :insertion-point the x,y coordinates of the insertion cursor.
(s/def ::text (and vector? (s/coll-of string?)))
(s/def ::reply-id (or nil? number?))
(s/def ::insertion-point (s/tuple [int? int?]))
(s/def ::edit-frame (s/keys :opt-un [::text
::insertion-point]))
::insertion-point
::reply-id]))
(declare draw-edit-frame
edit-window-key-pressed)
@ -141,8 +148,10 @@
(defn send-msg [state frame]
(let [private-key (get-in state [:keys :private-key])
private-key (ecc/hex-string->bytes private-key)
text (string/join \newline (:text frame))
event (events/compose-text-event private-key text)
reply-to (:reply-id frame)
event (events/compose-text-event private-key text reply-to)
send-chan (:send-chan state)
frame (assoc frame :text [""] :insertion-point [0 0])
state (assoc-in state (:path frame) frame)]
@ -151,15 +160,20 @@
(defn clear-edit-window [state]
(let [edit-frame (get-in state [:application :edit-window :text-frame])
edit-frame (assoc edit-frame :text [""] :insertion-point [0 0])]
edit-frame (assoc edit-frame :text [""]
:reply-id nil
:insertion-point [0 0])]
(assoc-in state (:path edit-frame) edit-frame)))
(declare text->edit-text)
(defn load-edit-window [state event]
(let [edit-frame (get-in state [:application :edit-window :text-frame])
id (:id event)
content (formatters/reformat-article (:content event)
(- (:width config/edit-window-dimensions) 10))
edit-frame (assoc edit-frame :text (text->edit-text content) :insertion-point [0 0])]
edit-frame (assoc edit-frame :text (text->edit-text content)
:insertion-point [0 0]
:reply-id id)]
(assoc-in state (:path edit-frame) edit-frame)))
(defn text->edit-text [text]