@novasamatech/host-chat 0.8.4 → 0.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,4 @@
1
+ export declare const MediaThumbnail: import("scale-ts").Codec<Uint8Array<ArrayBufferLike>>;
1
2
  export declare const GeneralFileMeta: import("scale-ts").Codec<{
2
3
  mimeType: string;
3
4
  fileSize: number;
@@ -9,6 +10,7 @@ export declare const ImageFileMeta: import("scale-ts").Codec<{
9
10
  };
10
11
  width: number;
11
12
  height: number;
13
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
12
14
  }>;
13
15
  export declare const VideoFileMeta: import("scale-ts").Codec<{
14
16
  general: {
@@ -16,6 +18,7 @@ export declare const VideoFileMeta: import("scale-ts").Codec<{
16
18
  fileSize: number;
17
19
  };
18
20
  duration: number;
21
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
19
22
  }>;
20
23
  export declare const FileMeta: import("scale-ts").Codec<{
21
24
  tag: "general";
@@ -32,6 +35,7 @@ export declare const FileMeta: import("scale-ts").Codec<{
32
35
  };
33
36
  width: number;
34
37
  height: number;
38
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
35
39
  };
36
40
  } | {
37
41
  tag: "video";
@@ -41,11 +45,24 @@ export declare const FileMeta: import("scale-ts").Codec<{
41
45
  fileSize: number;
42
46
  };
43
47
  duration: number;
48
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
49
+ };
50
+ }>;
51
+ export declare const NodeEndpoint: import("scale-ts").Codec<{
52
+ tag: "wssUrl";
53
+ value: {
54
+ url: string;
44
55
  };
45
56
  }>;
46
57
  export declare const P2PMixnetFile: import("scale-ts").Codec<{
47
58
  identifier: Uint8Array<ArrayBufferLike>;
48
59
  claimTicket: Uint8Array<ArrayBufferLike>;
60
+ nodeEndpoint: {
61
+ tag: "wssUrl";
62
+ value: {
63
+ url: string;
64
+ };
65
+ };
49
66
  meta: {
50
67
  tag: "general";
51
68
  value: {
@@ -61,6 +78,7 @@ export declare const P2PMixnetFile: import("scale-ts").Codec<{
61
78
  };
62
79
  width: number;
63
80
  height: number;
81
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
64
82
  };
65
83
  } | {
66
84
  tag: "video";
@@ -70,6 +88,7 @@ export declare const P2PMixnetFile: import("scale-ts").Codec<{
70
88
  fileSize: number;
71
89
  };
72
90
  duration: number;
91
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
73
92
  };
74
93
  };
75
94
  }>;
@@ -78,6 +97,12 @@ export declare const FileVariant: import("scale-ts").Codec<{
78
97
  value: {
79
98
  identifier: Uint8Array<ArrayBufferLike>;
80
99
  claimTicket: Uint8Array<ArrayBufferLike>;
100
+ nodeEndpoint: {
101
+ tag: "wssUrl";
102
+ value: {
103
+ url: string;
104
+ };
105
+ };
81
106
  meta: {
82
107
  tag: "general";
83
108
  value: {
@@ -93,6 +118,7 @@ export declare const FileVariant: import("scale-ts").Codec<{
93
118
  };
94
119
  width: number;
95
120
  height: number;
121
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
96
122
  };
97
123
  } | {
98
124
  tag: "video";
@@ -102,6 +128,7 @@ export declare const FileVariant: import("scale-ts").Codec<{
102
128
  fileSize: number;
103
129
  };
104
130
  duration: number;
131
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
105
132
  };
106
133
  };
107
134
  };
@@ -1,5 +1,8 @@
1
1
  import { Enum } from '@novasamatech/scale';
2
- import { Bytes, Struct, str, u32 } from 'scale-ts';
2
+ import { Bytes, Option, Struct, str, u32 } from 'scale-ts';
3
+ // UTF-8 bytes of a Wolt-spec blurhash string (componentX=4, componentY=3).
4
+ // Wire type is Vec<u8>; the bytes themselves are the ASCII blurhash.
5
+ export const MediaThumbnail = Bytes();
3
6
  export const GeneralFileMeta = Struct({
4
7
  mimeType: str,
5
8
  fileSize: u32,
@@ -8,19 +11,27 @@ export const ImageFileMeta = Struct({
8
11
  general: GeneralFileMeta,
9
12
  width: u32,
10
13
  height: u32,
14
+ thumbnail: Option(MediaThumbnail),
11
15
  });
12
16
  export const VideoFileMeta = Struct({
13
17
  general: GeneralFileMeta,
14
18
  duration: u32,
19
+ thumbnail: Option(MediaThumbnail),
15
20
  });
16
21
  export const FileMeta = Enum({
17
22
  general: GeneralFileMeta,
18
23
  image: ImageFileMeta,
19
24
  video: VideoFileMeta,
20
25
  });
26
+ // Hop node endpoint stamped onto outgoing attachments so the receiver can validate
27
+ // the URL against its bulletin-chain hop allowlist before opening a socket.
28
+ export const NodeEndpoint = Enum({
29
+ wssUrl: Struct({ url: str }),
30
+ });
21
31
  export const P2PMixnetFile = Struct({
22
32
  identifier: Bytes(),
23
33
  claimTicket: Bytes(),
34
+ nodeEndpoint: NodeEndpoint,
24
35
  meta: FileMeta,
25
36
  });
26
37
  export const FileVariant = Enum({
@@ -15,6 +15,7 @@ describe('attachment codecs', () => {
15
15
  general: { mimeType: 'image/jpeg', fileSize: 500_000 },
16
16
  width: 1920,
17
17
  height: 1080,
18
+ thumbnail: new TextEncoder().encode('LEHV6nWB2yk8pyo0adR*.7kCMdnj'),
18
19
  };
19
20
  const encoded = ImageFileMeta.enc(original);
20
21
  const decoded = ImageFileMeta.dec(encoded);
@@ -26,6 +27,7 @@ describe('attachment codecs', () => {
26
27
  const original = {
27
28
  general: { mimeType: 'video/mp4', fileSize: 10_000_000 },
28
29
  duration: 120,
30
+ thumbnail: undefined,
29
31
  };
30
32
  const encoded = VideoFileMeta.enc(original);
31
33
  const decoded = VideoFileMeta.dec(encoded);
@@ -38,11 +40,16 @@ describe('attachment codecs', () => {
38
40
  { tag: 'general', value: { mimeType: 'application/pdf', fileSize: 1024 } },
39
41
  {
40
42
  tag: 'image',
41
- value: { general: { mimeType: 'image/png', fileSize: 2048 }, width: 800, height: 600 },
43
+ value: {
44
+ general: { mimeType: 'image/png', fileSize: 2048 },
45
+ width: 800,
46
+ height: 600,
47
+ thumbnail: undefined,
48
+ },
42
49
  },
43
50
  {
44
51
  tag: 'video',
45
- value: { general: { mimeType: 'video/mp4', fileSize: 4096 }, duration: 60 },
52
+ value: { general: { mimeType: 'video/mp4', fileSize: 4096 }, duration: 60, thumbnail: undefined },
46
53
  },
47
54
  ];
48
55
  for (const original of variants) {
@@ -57,12 +64,14 @@ describe('attachment codecs', () => {
57
64
  const original = {
58
65
  identifier: new Uint8Array(32).fill(0xaa),
59
66
  claimTicket: new Uint8Array(32).fill(0xbb),
67
+ nodeEndpoint: { tag: 'wssUrl', value: { url: 'wss://hop.example/ws' } },
60
68
  meta: {
61
69
  tag: 'image',
62
70
  value: {
63
71
  general: { mimeType: 'image/jpeg', fileSize: 500_000 },
64
72
  width: 1920,
65
73
  height: 1080,
74
+ thumbnail: undefined,
66
75
  },
67
76
  },
68
77
  };
@@ -70,6 +79,7 @@ describe('attachment codecs', () => {
70
79
  const decoded = P2PMixnetFile.dec(encoded);
71
80
  expect(decoded.identifier).toEqual(original.identifier);
72
81
  expect(decoded.claimTicket).toEqual(original.claimTicket);
82
+ expect(decoded.nodeEndpoint).toEqual(original.nodeEndpoint);
73
83
  expect(decoded.meta).toEqual(original.meta);
74
84
  });
75
85
  });
@@ -80,6 +90,7 @@ describe('attachment codecs', () => {
80
90
  value: {
81
91
  identifier: new Uint8Array(32).fill(0x11),
82
92
  claimTicket: new Uint8Array(32).fill(0x22),
93
+ nodeEndpoint: { tag: 'wssUrl', value: { url: 'wss://hop.example/ws' } },
83
94
  meta: { tag: 'general', value: { mimeType: 'text/plain', fileSize: 10 } },
84
95
  },
85
96
  };
@@ -61,6 +61,12 @@ export declare const LocalMessage: import("scale-ts").Codec<{
61
61
  value: {
62
62
  identifier: Uint8Array<ArrayBufferLike>;
63
63
  claimTicket: Uint8Array<ArrayBufferLike>;
64
+ nodeEndpoint: {
65
+ tag: "wssUrl";
66
+ value: {
67
+ url: string;
68
+ };
69
+ };
64
70
  meta: {
65
71
  tag: "general";
66
72
  value: {
@@ -76,6 +82,7 @@ export declare const LocalMessage: import("scale-ts").Codec<{
76
82
  };
77
83
  width: number;
78
84
  height: number;
85
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
79
86
  };
80
87
  } | {
81
88
  tag: "video";
@@ -85,6 +92,7 @@ export declare const LocalMessage: import("scale-ts").Codec<{
85
92
  fileSize: number;
86
93
  };
87
94
  duration: number;
95
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
88
96
  };
89
97
  };
90
98
  };
@@ -93,16 +101,27 @@ export declare const LocalMessage: import("scale-ts").Codec<{
93
101
  };
94
102
  } | {
95
103
  tag: "dataChannelOffer";
96
- value: undefined;
104
+ value: {
105
+ sdp: Uint8Array<ArrayBufferLike>;
106
+ purpose: "AUDIO_CALL" | "VIDEO_CALL";
107
+ };
97
108
  } | {
98
109
  tag: "dataChannelAnswer";
99
- value: undefined;
110
+ value: {
111
+ offerMessageId: string;
112
+ sdp: Uint8Array<ArrayBufferLike>;
113
+ };
100
114
  } | {
101
- tag: "dataChannelCandidates";
102
- value: undefined;
115
+ tag: "dataChannelIceCandidate";
116
+ value: {
117
+ offerMessageId: string;
118
+ sdp: Uint8Array<ArrayBufferLike>;
119
+ };
103
120
  } | {
104
- tag: "_reserved11";
105
- value: undefined;
121
+ tag: "dataChannelClosed";
122
+ value: {
123
+ offerMessageId: string;
124
+ };
106
125
  } | {
107
126
  tag: "edit";
108
127
  value: {
@@ -114,6 +133,12 @@ export declare const LocalMessage: import("scale-ts").Codec<{
114
133
  value: {
115
134
  identifier: Uint8Array<ArrayBufferLike>;
116
135
  claimTicket: Uint8Array<ArrayBufferLike>;
136
+ nodeEndpoint: {
137
+ tag: "wssUrl";
138
+ value: {
139
+ url: string;
140
+ };
141
+ };
117
142
  meta: {
118
143
  tag: "general";
119
144
  value: {
@@ -129,6 +154,7 @@ export declare const LocalMessage: import("scale-ts").Codec<{
129
154
  };
130
155
  width: number;
131
156
  height: number;
157
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
132
158
  };
133
159
  } | {
134
160
  tag: "video";
@@ -138,6 +164,7 @@ export declare const LocalMessage: import("scale-ts").Codec<{
138
164
  fileSize: number;
139
165
  };
140
166
  duration: number;
167
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
141
168
  };
142
169
  };
143
170
  };
@@ -161,6 +188,12 @@ export declare const LocalMessage: import("scale-ts").Codec<{
161
188
  value: {
162
189
  identifier: Uint8Array<ArrayBufferLike>;
163
190
  claimTicket: Uint8Array<ArrayBufferLike>;
191
+ nodeEndpoint: {
192
+ tag: "wssUrl";
193
+ value: {
194
+ url: string;
195
+ };
196
+ };
164
197
  meta: {
165
198
  tag: "general";
166
199
  value: {
@@ -176,6 +209,7 @@ export declare const LocalMessage: import("scale-ts").Codec<{
176
209
  };
177
210
  width: number;
178
211
  height: number;
212
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
179
213
  };
180
214
  } | {
181
215
  tag: "video";
@@ -185,14 +219,18 @@ export declare const LocalMessage: import("scale-ts").Codec<{
185
219
  fileSize: number;
186
220
  };
187
221
  duration: number;
222
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
188
223
  };
189
224
  };
190
225
  };
191
226
  }[] | undefined;
192
227
  };
193
228
  } | {
194
- tag: "_reserved16";
195
- value: undefined;
229
+ tag: "coinagePayment";
230
+ value: {
231
+ totalValue: number | bigint;
232
+ coinKeys: Uint8Array<ArrayBufferLike>[];
233
+ };
196
234
  } | {
197
235
  tag: "deviceAdded";
198
236
  value: {
@@ -6,6 +6,12 @@ export declare const RichTextContent: import("scale-ts").Codec<{
6
6
  value: {
7
7
  identifier: Uint8Array<ArrayBufferLike>;
8
8
  claimTicket: Uint8Array<ArrayBufferLike>;
9
+ nodeEndpoint: {
10
+ tag: "wssUrl";
11
+ value: {
12
+ url: string;
13
+ };
14
+ };
9
15
  meta: {
10
16
  tag: "general";
11
17
  value: {
@@ -21,6 +27,7 @@ export declare const RichTextContent: import("scale-ts").Codec<{
21
27
  };
22
28
  width: number;
23
29
  height: number;
30
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
24
31
  };
25
32
  } | {
26
33
  tag: "video";
@@ -30,6 +37,7 @@ export declare const RichTextContent: import("scale-ts").Codec<{
30
37
  fileSize: number;
31
38
  };
32
39
  duration: number;
40
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
33
41
  };
34
42
  };
35
43
  };
@@ -59,6 +67,12 @@ export declare const ReplyContent: import("scale-ts").Codec<{
59
67
  value: {
60
68
  identifier: Uint8Array<ArrayBufferLike>;
61
69
  claimTicket: Uint8Array<ArrayBufferLike>;
70
+ nodeEndpoint: {
71
+ tag: "wssUrl";
72
+ value: {
73
+ url: string;
74
+ };
75
+ };
62
76
  meta: {
63
77
  tag: "general";
64
78
  value: {
@@ -74,6 +88,7 @@ export declare const ReplyContent: import("scale-ts").Codec<{
74
88
  };
75
89
  width: number;
76
90
  height: number;
91
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
77
92
  };
78
93
  } | {
79
94
  tag: "video";
@@ -83,6 +98,7 @@ export declare const ReplyContent: import("scale-ts").Codec<{
83
98
  fileSize: number;
84
99
  };
85
100
  duration: number;
101
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
86
102
  };
87
103
  };
88
104
  };
@@ -98,6 +114,12 @@ export declare const EditContent: import("scale-ts").Codec<{
98
114
  value: {
99
115
  identifier: Uint8Array<ArrayBufferLike>;
100
116
  claimTicket: Uint8Array<ArrayBufferLike>;
117
+ nodeEndpoint: {
118
+ tag: "wssUrl";
119
+ value: {
120
+ url: string;
121
+ };
122
+ };
101
123
  meta: {
102
124
  tag: "general";
103
125
  value: {
@@ -113,6 +135,7 @@ export declare const EditContent: import("scale-ts").Codec<{
113
135
  };
114
136
  width: number;
115
137
  height: number;
138
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
116
139
  };
117
140
  } | {
118
141
  tag: "video";
@@ -122,6 +145,7 @@ export declare const EditContent: import("scale-ts").Codec<{
122
145
  fileSize: number;
123
146
  };
124
147
  duration: number;
148
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
125
149
  };
126
150
  };
127
151
  };
@@ -149,6 +173,26 @@ export declare const DeviceChatAcceptedContent: import("scale-ts").Codec<{
149
173
  encryptionPublicKey: Uint8Array<ArrayBufferLike>;
150
174
  };
151
175
  }>;
176
+ export declare const DataChannelPurpose: import("scale-ts").Codec<"AUDIO_CALL" | "VIDEO_CALL">;
177
+ export declare const DataChannelOfferContent: import("scale-ts").Codec<{
178
+ sdp: Uint8Array<ArrayBufferLike>;
179
+ purpose: "AUDIO_CALL" | "VIDEO_CALL";
180
+ }>;
181
+ export declare const DataChannelAnswerContent: import("scale-ts").Codec<{
182
+ offerMessageId: string;
183
+ sdp: Uint8Array<ArrayBufferLike>;
184
+ }>;
185
+ export declare const DataChannelIceCandidateContent: import("scale-ts").Codec<{
186
+ offerMessageId: string;
187
+ sdp: Uint8Array<ArrayBufferLike>;
188
+ }>;
189
+ export declare const DataChannelClosedContent: import("scale-ts").Codec<{
190
+ offerMessageId: string;
191
+ }>;
192
+ export declare const CoinagePaymentContent: import("scale-ts").Codec<{
193
+ totalValue: number | bigint;
194
+ coinKeys: Uint8Array<ArrayBufferLike>[];
195
+ }>;
152
196
  export declare const MessageContent: import("scale-ts").Codec<{
153
197
  tag: "text";
154
198
  value: string;
@@ -195,6 +239,12 @@ export declare const MessageContent: import("scale-ts").Codec<{
195
239
  value: {
196
240
  identifier: Uint8Array<ArrayBufferLike>;
197
241
  claimTicket: Uint8Array<ArrayBufferLike>;
242
+ nodeEndpoint: {
243
+ tag: "wssUrl";
244
+ value: {
245
+ url: string;
246
+ };
247
+ };
198
248
  meta: {
199
249
  tag: "general";
200
250
  value: {
@@ -210,6 +260,7 @@ export declare const MessageContent: import("scale-ts").Codec<{
210
260
  };
211
261
  width: number;
212
262
  height: number;
263
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
213
264
  };
214
265
  } | {
215
266
  tag: "video";
@@ -219,6 +270,7 @@ export declare const MessageContent: import("scale-ts").Codec<{
219
270
  fileSize: number;
220
271
  };
221
272
  duration: number;
273
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
222
274
  };
223
275
  };
224
276
  };
@@ -227,16 +279,27 @@ export declare const MessageContent: import("scale-ts").Codec<{
227
279
  };
228
280
  } | {
229
281
  tag: "dataChannelOffer";
230
- value: undefined;
282
+ value: {
283
+ sdp: Uint8Array<ArrayBufferLike>;
284
+ purpose: "AUDIO_CALL" | "VIDEO_CALL";
285
+ };
231
286
  } | {
232
287
  tag: "dataChannelAnswer";
233
- value: undefined;
288
+ value: {
289
+ offerMessageId: string;
290
+ sdp: Uint8Array<ArrayBufferLike>;
291
+ };
234
292
  } | {
235
- tag: "dataChannelCandidates";
236
- value: undefined;
293
+ tag: "dataChannelIceCandidate";
294
+ value: {
295
+ offerMessageId: string;
296
+ sdp: Uint8Array<ArrayBufferLike>;
297
+ };
237
298
  } | {
238
- tag: "_reserved11";
239
- value: undefined;
299
+ tag: "dataChannelClosed";
300
+ value: {
301
+ offerMessageId: string;
302
+ };
240
303
  } | {
241
304
  tag: "edit";
242
305
  value: {
@@ -248,6 +311,12 @@ export declare const MessageContent: import("scale-ts").Codec<{
248
311
  value: {
249
312
  identifier: Uint8Array<ArrayBufferLike>;
250
313
  claimTicket: Uint8Array<ArrayBufferLike>;
314
+ nodeEndpoint: {
315
+ tag: "wssUrl";
316
+ value: {
317
+ url: string;
318
+ };
319
+ };
251
320
  meta: {
252
321
  tag: "general";
253
322
  value: {
@@ -263,6 +332,7 @@ export declare const MessageContent: import("scale-ts").Codec<{
263
332
  };
264
333
  width: number;
265
334
  height: number;
335
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
266
336
  };
267
337
  } | {
268
338
  tag: "video";
@@ -272,6 +342,7 @@ export declare const MessageContent: import("scale-ts").Codec<{
272
342
  fileSize: number;
273
343
  };
274
344
  duration: number;
345
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
275
346
  };
276
347
  };
277
348
  };
@@ -295,6 +366,12 @@ export declare const MessageContent: import("scale-ts").Codec<{
295
366
  value: {
296
367
  identifier: Uint8Array<ArrayBufferLike>;
297
368
  claimTicket: Uint8Array<ArrayBufferLike>;
369
+ nodeEndpoint: {
370
+ tag: "wssUrl";
371
+ value: {
372
+ url: string;
373
+ };
374
+ };
298
375
  meta: {
299
376
  tag: "general";
300
377
  value: {
@@ -310,6 +387,7 @@ export declare const MessageContent: import("scale-ts").Codec<{
310
387
  };
311
388
  width: number;
312
389
  height: number;
390
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
313
391
  };
314
392
  } | {
315
393
  tag: "video";
@@ -319,14 +397,18 @@ export declare const MessageContent: import("scale-ts").Codec<{
319
397
  fileSize: number;
320
398
  };
321
399
  duration: number;
400
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
322
401
  };
323
402
  };
324
403
  };
325
404
  }[] | undefined;
326
405
  };
327
406
  } | {
328
- tag: "_reserved16";
329
- value: undefined;
407
+ tag: "coinagePayment";
408
+ value: {
409
+ totalValue: number | bigint;
410
+ coinKeys: Uint8Array<ArrayBufferLike>[];
411
+ };
330
412
  } | {
331
413
  tag: "deviceAdded";
332
414
  value: {
@@ -399,6 +481,12 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
399
481
  value: {
400
482
  identifier: Uint8Array<ArrayBufferLike>;
401
483
  claimTicket: Uint8Array<ArrayBufferLike>;
484
+ nodeEndpoint: {
485
+ tag: "wssUrl";
486
+ value: {
487
+ url: string;
488
+ };
489
+ };
402
490
  meta: {
403
491
  tag: "general";
404
492
  value: {
@@ -414,6 +502,7 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
414
502
  };
415
503
  width: number;
416
504
  height: number;
505
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
417
506
  };
418
507
  } | {
419
508
  tag: "video";
@@ -423,6 +512,7 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
423
512
  fileSize: number;
424
513
  };
425
514
  duration: number;
515
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
426
516
  };
427
517
  };
428
518
  };
@@ -431,16 +521,27 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
431
521
  };
432
522
  } | {
433
523
  tag: "dataChannelOffer";
434
- value: undefined;
524
+ value: {
525
+ sdp: Uint8Array<ArrayBufferLike>;
526
+ purpose: "AUDIO_CALL" | "VIDEO_CALL";
527
+ };
435
528
  } | {
436
529
  tag: "dataChannelAnswer";
437
- value: undefined;
530
+ value: {
531
+ offerMessageId: string;
532
+ sdp: Uint8Array<ArrayBufferLike>;
533
+ };
438
534
  } | {
439
- tag: "dataChannelCandidates";
440
- value: undefined;
535
+ tag: "dataChannelIceCandidate";
536
+ value: {
537
+ offerMessageId: string;
538
+ sdp: Uint8Array<ArrayBufferLike>;
539
+ };
441
540
  } | {
442
- tag: "_reserved11";
443
- value: undefined;
541
+ tag: "dataChannelClosed";
542
+ value: {
543
+ offerMessageId: string;
544
+ };
444
545
  } | {
445
546
  tag: "edit";
446
547
  value: {
@@ -452,6 +553,12 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
452
553
  value: {
453
554
  identifier: Uint8Array<ArrayBufferLike>;
454
555
  claimTicket: Uint8Array<ArrayBufferLike>;
556
+ nodeEndpoint: {
557
+ tag: "wssUrl";
558
+ value: {
559
+ url: string;
560
+ };
561
+ };
455
562
  meta: {
456
563
  tag: "general";
457
564
  value: {
@@ -467,6 +574,7 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
467
574
  };
468
575
  width: number;
469
576
  height: number;
577
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
470
578
  };
471
579
  } | {
472
580
  tag: "video";
@@ -476,6 +584,7 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
476
584
  fileSize: number;
477
585
  };
478
586
  duration: number;
587
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
479
588
  };
480
589
  };
481
590
  };
@@ -499,6 +608,12 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
499
608
  value: {
500
609
  identifier: Uint8Array<ArrayBufferLike>;
501
610
  claimTicket: Uint8Array<ArrayBufferLike>;
611
+ nodeEndpoint: {
612
+ tag: "wssUrl";
613
+ value: {
614
+ url: string;
615
+ };
616
+ };
502
617
  meta: {
503
618
  tag: "general";
504
619
  value: {
@@ -514,6 +629,7 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
514
629
  };
515
630
  width: number;
516
631
  height: number;
632
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
517
633
  };
518
634
  } | {
519
635
  tag: "video";
@@ -523,14 +639,18 @@ export declare const VersionedMessageContent: import("scale-ts").Codec<{
523
639
  fileSize: number;
524
640
  };
525
641
  duration: number;
642
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
526
643
  };
527
644
  };
528
645
  };
529
646
  }[] | undefined;
530
647
  };
531
648
  } | {
532
- tag: "_reserved16";
533
- value: undefined;
649
+ tag: "coinagePayment";
650
+ value: {
651
+ totalValue: number | bigint;
652
+ coinKeys: Uint8Array<ArrayBufferLike>[];
653
+ };
534
654
  } | {
535
655
  tag: "deviceAdded";
536
656
  value: {
@@ -607,6 +727,12 @@ export declare const ChatMessage: import("scale-ts").Codec<{
607
727
  value: {
608
728
  identifier: Uint8Array<ArrayBufferLike>;
609
729
  claimTicket: Uint8Array<ArrayBufferLike>;
730
+ nodeEndpoint: {
731
+ tag: "wssUrl";
732
+ value: {
733
+ url: string;
734
+ };
735
+ };
610
736
  meta: {
611
737
  tag: "general";
612
738
  value: {
@@ -622,6 +748,7 @@ export declare const ChatMessage: import("scale-ts").Codec<{
622
748
  };
623
749
  width: number;
624
750
  height: number;
751
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
625
752
  };
626
753
  } | {
627
754
  tag: "video";
@@ -631,6 +758,7 @@ export declare const ChatMessage: import("scale-ts").Codec<{
631
758
  fileSize: number;
632
759
  };
633
760
  duration: number;
761
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
634
762
  };
635
763
  };
636
764
  };
@@ -639,16 +767,27 @@ export declare const ChatMessage: import("scale-ts").Codec<{
639
767
  };
640
768
  } | {
641
769
  tag: "dataChannelOffer";
642
- value: undefined;
770
+ value: {
771
+ sdp: Uint8Array<ArrayBufferLike>;
772
+ purpose: "AUDIO_CALL" | "VIDEO_CALL";
773
+ };
643
774
  } | {
644
775
  tag: "dataChannelAnswer";
645
- value: undefined;
776
+ value: {
777
+ offerMessageId: string;
778
+ sdp: Uint8Array<ArrayBufferLike>;
779
+ };
646
780
  } | {
647
- tag: "dataChannelCandidates";
648
- value: undefined;
781
+ tag: "dataChannelIceCandidate";
782
+ value: {
783
+ offerMessageId: string;
784
+ sdp: Uint8Array<ArrayBufferLike>;
785
+ };
649
786
  } | {
650
- tag: "_reserved11";
651
- value: undefined;
787
+ tag: "dataChannelClosed";
788
+ value: {
789
+ offerMessageId: string;
790
+ };
652
791
  } | {
653
792
  tag: "edit";
654
793
  value: {
@@ -660,6 +799,12 @@ export declare const ChatMessage: import("scale-ts").Codec<{
660
799
  value: {
661
800
  identifier: Uint8Array<ArrayBufferLike>;
662
801
  claimTicket: Uint8Array<ArrayBufferLike>;
802
+ nodeEndpoint: {
803
+ tag: "wssUrl";
804
+ value: {
805
+ url: string;
806
+ };
807
+ };
663
808
  meta: {
664
809
  tag: "general";
665
810
  value: {
@@ -675,6 +820,7 @@ export declare const ChatMessage: import("scale-ts").Codec<{
675
820
  };
676
821
  width: number;
677
822
  height: number;
823
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
678
824
  };
679
825
  } | {
680
826
  tag: "video";
@@ -684,6 +830,7 @@ export declare const ChatMessage: import("scale-ts").Codec<{
684
830
  fileSize: number;
685
831
  };
686
832
  duration: number;
833
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
687
834
  };
688
835
  };
689
836
  };
@@ -707,6 +854,12 @@ export declare const ChatMessage: import("scale-ts").Codec<{
707
854
  value: {
708
855
  identifier: Uint8Array<ArrayBufferLike>;
709
856
  claimTicket: Uint8Array<ArrayBufferLike>;
857
+ nodeEndpoint: {
858
+ tag: "wssUrl";
859
+ value: {
860
+ url: string;
861
+ };
862
+ };
710
863
  meta: {
711
864
  tag: "general";
712
865
  value: {
@@ -722,6 +875,7 @@ export declare const ChatMessage: import("scale-ts").Codec<{
722
875
  };
723
876
  width: number;
724
877
  height: number;
878
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
725
879
  };
726
880
  } | {
727
881
  tag: "video";
@@ -731,14 +885,18 @@ export declare const ChatMessage: import("scale-ts").Codec<{
731
885
  fileSize: number;
732
886
  };
733
887
  duration: number;
888
+ thumbnail: Uint8Array<ArrayBufferLike> | undefined;
734
889
  };
735
890
  };
736
891
  };
737
892
  }[] | undefined;
738
893
  };
739
894
  } | {
740
- tag: "_reserved16";
741
- value: undefined;
895
+ tag: "coinagePayment";
896
+ value: {
897
+ totalValue: number | bigint;
898
+ coinKeys: Uint8Array<ArrayBufferLike>[];
899
+ };
742
900
  } | {
743
901
  tag: "deviceAdded";
744
902
  value: {
@@ -68,6 +68,40 @@ export const DeviceChatAcceptedContent = Struct({
68
68
  requestId: str,
69
69
  device: DeviceInfoContent,
70
70
  });
71
+ // WebRTC data-channel signalling carried as chat-content variants. Android's
72
+ // `ChatMessageStatementContent.DataChannelOffer/Answer/IceCandidate/Closed`
73
+ // use plain `ByteArray` (no `@FixedLength`), which substrate-sdk-android
74
+ // encodes as length-prefixed `Vec<u8>`. None of these are interpreted by
75
+ // the host on desktop, but the codecs must consume the payload bytes so
76
+ // that any sync/chat envelope mixing them with other variants still decodes
77
+ // cleanly — leaving these as `_void` mis-advances the decoder by N bytes
78
+ // and corrupts every following entry in the envelope.
79
+ export const DataChannelPurpose = Status('AUDIO_CALL', 'VIDEO_CALL');
80
+ export const DataChannelOfferContent = Struct({
81
+ sdp: Bytes(),
82
+ purpose: DataChannelPurpose,
83
+ });
84
+ export const DataChannelAnswerContent = Struct({
85
+ offerMessageId: str,
86
+ sdp: Bytes(),
87
+ });
88
+ export const DataChannelIceCandidateContent = Struct({
89
+ offerMessageId: str,
90
+ sdp: Bytes(),
91
+ });
92
+ export const DataChannelClosedContent = Struct({
93
+ offerMessageId: str,
94
+ });
95
+ // Android `CoinagePayment` (index 16):
96
+ // { totalValue: Balance (compact-encoded), coinKeys: Vec<Vec<u8>> }
97
+ // Desktop doesn't act on coinage, but the codec must consume the payload
98
+ // for the same reason as the data-channel variants above — otherwise a
99
+ // sync `SyncEntity::Messages` carrying a coinage message wipes out every
100
+ // following message in the same envelope at decode time.
101
+ export const CoinagePaymentContent = Struct({
102
+ totalValue: compact,
103
+ coinKeys: Vector(Bytes()),
104
+ });
71
105
  // Note: enum indices MUST match iOS/Android SCALE codecs.
72
106
  // Indices are auto-assigned sequentially, so order matters.
73
107
  export const MessageContent = Enum({
@@ -79,15 +113,15 @@ export const MessageContent = Enum({
79
113
  reactionRemoved: ReactionContent, // 5
80
114
  _reserved6: _void, // 6 — reserved (unused)
81
115
  reply: ReplyContent, // 7
82
- dataChannelOffer: _void, // 8
83
- dataChannelAnswer: _void, // 9
84
- dataChannelCandidates: _void, // 10
85
- _reserved11: _void, // 11 reserved (unused)
116
+ dataChannelOffer: DataChannelOfferContent, // 8
117
+ dataChannelAnswer: DataChannelAnswerContent, // 9
118
+ dataChannelIceCandidate: DataChannelIceCandidateContent, // 10 (renamed from `dataChannelCandidates`; Android: `DataChannelIceCandidate`)
119
+ dataChannelClosed: DataChannelClosedContent, // 11 (Android: `DataChannelClosed`)
86
120
  edit: EditContent, // 12
87
121
  leftChat: _void, // 13
88
122
  chatAccepted: ChatAcceptedContent, // 14 (legacy single-device accept, iOS V1)
89
123
  richText: RichTextContent, // 15
90
- _reserved16: _void, // 16 reserved (android `coinagePayment`, unused on desktop)
124
+ coinagePayment: CoinagePaymentContent, // 16 (Android-only; consumed for cross-device sync wire-stability)
91
125
  deviceAdded: DeviceAddedContent, // 17
92
126
  deviceRemoved: DeviceRemovedContent, // 18
93
127
  _reserved19: _void, // 19 — reserved (placeholder so deviceChatAccepted lands on the spec'd index 20)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@novasamatech/host-chat",
3
3
  "type": "module",
4
- "version": "0.8.4",
4
+ "version": "0.8.6",
5
5
  "description": "Host statement store chat integration",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -40,9 +40,9 @@
40
40
  "README.md"
41
41
  ],
42
42
  "dependencies": {
43
- "@novasamatech/scale": "0.8.4",
44
- "@novasamatech/statement-store": "0.8.4",
45
- "@novasamatech/storage-adapter": "0.8.4",
43
+ "@novasamatech/scale": "0.8.6",
44
+ "@novasamatech/statement-store": "0.8.6",
45
+ "@novasamatech/storage-adapter": "0.8.6",
46
46
  "nanoid": "5.1.11",
47
47
  "neverthrow": "^8.2.0"
48
48
  },