3737 ds: WakuClient
3838 sdsClient: ReliabilityManager
3939 owner: Identity
40- topic: string
4140 participant: PublicKey
4241 discriminator: string
4342 doubleratchet: naxolotl.Doubleratchet
4443
45- proc getTopic * (self: PrivateV1 ): string =
46- # # Returns the topic for the PrivateV1 conversation.
47- return self.topic
44+ proc derive_topic (participant: PublicKey ): string =
45+ # # Derives a topic from the participants' public keys.
46+ return " /convo/private/" & participant.get_addr ()
47+
48+ proc getTopicInbound * (self: PrivateV1 ): string =
49+ # # Returns the topic where the local client is listening for messages
50+ return derive_topic (self.owner.getPubkey ())
51+
52+ proc getTopicOutbound * (self: PrivateV1 ): string =
53+ # # Returns the topic where the remote recipient is listening for messages
54+ return derive_topic (self.participant)
4855
4956proc allParticipants (self: PrivateV1 ): seq [PublicKey ] =
5057 return @ [self.owner.getPubkey (), self.participant]
@@ -61,9 +68,6 @@ proc getConvoIdRaw(participants: seq[PublicKey],
6168proc getConvoId * (self: PrivateV1 ): string =
6269 return getConvoIdRaw (@ [self.owner.getPubkey (), self.participant], self.discriminator)
6370
64- proc derive_topic (participants: seq [PublicKey ], discriminator: string ): string =
65- # # Derives a topic from the participants' public keys.
66- return " /convo/private/" & getConvoIdRaw (participants, discriminator)
6771
6872proc calcMsgId (self: PrivateV1 , msgBytes: seq [byte ]): string =
6973 let s = fmt" { self.getConvoId ()} |{ msgBytes} "
@@ -93,6 +97,7 @@ proc decrypt*(convo: PrivateV1, enc: EncryptedPayload): Result[seq[byte], ChatEr
9397 prevChainLen: dr.prevChainLen
9498 )
9599 copyMem (addr header.dhPublic[0 ], unsafeAddr dr.dh[0 ], dr.dh.len) # TODO : Avoid this copy
100+ debug " DECR WRAP" , who= convo.owner.getName (), cipher = shrink (dr.ciphertext[0 .. 8 ])
96101
97102 convo.doubleratchet.decrypt (header, dr.ciphertext, @ []).mapErr (proc (e: NaxolotlError ): ChatError = ChatError (code: errWrapped, context: repr (e) ))
98103
@@ -110,7 +115,7 @@ proc wireCallbacks(convo: PrivateV1, deliveryAckCb: proc(
110115 let funcDeliveryAck = proc (messageId: SdsMessageID ,
111116 channelId: SdsChannelID ) {.gcsafe .} =
112117 debug " sds message ack" , messageId = messageId,
113- channelId = channelId, cb = repr (deliveryAckCb)
118+ channelId = channelId
114119
115120 if deliveryAckCb != nil :
116121 asyncSpawn deliveryAckCb (convo, messageId)
@@ -132,48 +137,43 @@ proc initPrivateV1*(owner: Identity, ds:WakuClient, participant: PublicKey, seed
132137 msgId: string ): Future [void ] {.async .} = nil ):
133138 PrivateV1 =
134139
135- var participants = @ [owner.getPubkey (), participant];
136-
137140 var rm = newReliabilityManager ().valueOr:
138141 raise newException (ValueError , fmt" sds initialization: { repr (error)} " )
139142
143+ let dr = if isSender:
144+ initDoubleratchetSender (seedKey, participant.bytes)
145+ else :
146+ initDoubleratchetRecipient (seedKey, owner.privateKey.bytes)
147+
140148 result = PrivateV1 (
141149 ds: ds,
142150 sdsClient: rm,
143151 owner: owner,
144- topic: derive_topic (participants, discriminator),
145152 participant: participant,
146153 discriminator: discriminator,
147- doubleratchet: initDoubleratchet (seedKey, owner.privateKey.bytes, participant.bytes, isSender)
154+ doubleratchet: dr
148155 )
149156
150157 result .wireCallbacks (deliveryAckCb)
151158
152159 result .sdsClient.ensureChannel (result .getConvoId ()).isOkOr:
153160 raise newException (ValueError , " bad sds channel" )
154161
155-
156- proc initPrivateV1Sender * (owner:Identity , ds: WakuClient , participant: PublicKey , seedKey: array [32 , byte ], deliveryAckCb: proc (
157- conversation: Conversation , msgId: string ): Future [void ] {.async .} = nil ): PrivateV1 =
158- initPrivateV1 (owner, ds, participant, seedKey, " default" , true , deliveryAckCb)
159-
160- proc initPrivateV1Recipient * (owner:Identity ,ds: WakuClient , participant: PublicKey , seedKey: array [32 , byte ], deliveryAckCb: proc (
161- conversation: Conversation , msgId: string ): Future [void ] {.async .} = nil ): PrivateV1 =
162- initPrivateV1 (owner,ds, participant, seedKey, " default" , false , deliveryAckCb)
163-
164-
165- proc sendFrame (self: PrivateV1 , ds: WakuClient ,
166- msg: PrivateV1Frame ): Future [MessageId ]{.async .} =
162+ proc encodeFrame * (self: PrivateV1 , msg: PrivateV1Frame ): (MessageId , EncryptedPayload ) =
167163
168164 let frameBytes = encode (msg)
169165 let msgId = self.calcMsgId (frameBytes)
170166 var sdsPayload = self.sdsClient.wrapOutgoingMessage (frameBytes, msgId,
171167 self.getConvoId ()).valueOr:
172168 raise newException (ValueError , fmt" sds wrapOutgoingMessage failed: { repr (error)} " )
173169
174- let encryptedPayload = self.encrypt (sdsPayload)
170+ result = (msgId, self.encrypt (sdsPayload))
171+
175172
176- discard ds.sendPayload (self.getTopic (), encryptedPayload.toEnvelope (
173+ proc sendFrame (self: PrivateV1 , ds: WakuClient ,
174+ msg: PrivateV1Frame ): Future [MessageId ]{.async .} =
175+ let (msgId, encryptedPayload) = self.encodeFrame (msg)
176+ discard ds.sendPayload (self.getTopicOutbound (), encryptedPayload.toEnvelope (
177177 self.getConvoId ()))
178178
179179 result = msgId
@@ -182,19 +182,19 @@ proc sendFrame(self: PrivateV1, ds: WakuClient,
182182method id * (self: PrivateV1 ): string =
183183 return getConvoIdRaw (self.allParticipants (), self.discriminator)
184184
185+
186+
187+
185188proc handleFrame * [T: ConversationStore ](convo: PrivateV1 , client: T,
186- bytes: seq [ byte ] ) =
189+ encPayload: EncryptedPayload ) =
187190 # # Dispatcher for Incoming `PrivateV1Frames`.
188191 # # Calls further processing depending on the kind of frame.
189192
190- let enc = decode (bytes, EncryptedPayload ).valueOr:
191- raise newException (ValueError , fmt" Failed to decode EncryptedPayload: { repr (error)} " )
192-
193- if convo.doubleratchet.dhSelfPublic () == enc.doubleratchet.dh:
193+ if convo.doubleratchet.dhSelfPublic () == encPayload.doubleratchet.dh:
194194 info " outgoing message, no need to handle" , convo = convo.id ()
195195 return
196196
197- let plaintext = convo.decrypt (enc ).valueOr:
197+ let plaintext = convo.decrypt (encPayload ).valueOr:
198198 error " decryption failed" , error = error
199199 return
200200
@@ -220,6 +220,15 @@ proc handleFrame*[T: ConversationStore](convo: PrivateV1, client: T,
220220 of typePlaceholder:
221221 notice " Got Placeholder" , text = frame.placeholder.counter
222222
223+ proc handleFrame * [T: ConversationStore ](convo: PrivateV1 , client: T,
224+ bytes: seq [byte ]) =
225+ # # Dispatcher for Incoming `PrivateV1Frames`.
226+ # # Calls further processing depending on the kind of frame.
227+ let encPayload = decode (bytes, EncryptedPayload ).valueOr:
228+ raise newException (ValueError , fmt" Failed to decode EncryptedPayload: { repr (error)} " )
229+
230+ convo.handleFrame (client,encPayload)
231+
223232
224233method sendMessage * (convo: PrivateV1 , content_frame: ContentFrame ) : Future [MessageId ] {.async .} =
225234
@@ -231,3 +240,36 @@ method sendMessage*(convo: PrivateV1, content_frame: ContentFrame) : Future[Mess
231240 except Exception as e:
232241 error " Unknown error in PrivateV1:SendMessage"
233242
243+
244+ # # Encrypts content without sending it.
245+ proc encryptMessage * (self: PrivateV1 , content_frame: ContentFrame ) : (MessageId , EncryptedPayload ) =
246+
247+ try :
248+ let frame = PrivateV1Frame (
249+ sender: @ (self.owner.getPubkey ().bytes ()),
250+ timestamp: getCurrentTimestamp (),
251+ content: content_frame
252+ )
253+
254+ result = self.encodeFrame (frame)
255+
256+ except Exception as e:
257+ error " Unknown error in PrivateV1:SendMessage"
258+
259+ proc initPrivateV1Sender * (sender:Identity ,
260+ ds: WakuClient ,
261+ participant: PublicKey ,
262+ seedKey: array [32 , byte ],
263+ content: ContentFrame ,
264+ deliveryAckCb: proc (conversation: Conversation , msgId: string ): Future [void ] {.async .} = nil ): (PrivateV1 , EncryptedPayload ) =
265+ let convo = initPrivateV1 (sender, ds, participant, seedKey, " default" , true , deliveryAckCb)
266+
267+ # Encrypt Content with Convo
268+ let contentFrame = PrivateV1Frame (sender: @ (sender.getPubkey ().bytes ()), timestamp: getCurrentTimestamp (), content: content)
269+ let (msg_id, encPayload) = convo.encryptMessage (content)
270+ result = (convo, encPayload)
271+
272+
273+ proc initPrivateV1Recipient * (owner:Identity ,ds: WakuClient , participant: PublicKey , seedKey: array [32 , byte ], deliveryAckCb: proc (
274+ conversation: Conversation , msgId: string ): Future [void ] {.async .} = nil ): PrivateV1 =
275+ initPrivateV1 (owner,ds, participant, seedKey, " default" , false , deliveryAckCb)
0 commit comments