@meshline/sdk 0.0.0-stage → 0.1.0-alpha.1

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.
Files changed (338) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +43 -2
  3. package/dist/channels/repository.d.ts +73 -0
  4. package/dist/channels/repository.d.ts.map +1 -0
  5. package/dist/channels/repository.js +367 -0
  6. package/dist/channels/repository.js.map +1 -0
  7. package/dist/client/account-operations.d.ts +41 -0
  8. package/dist/client/account-operations.d.ts.map +1 -0
  9. package/dist/client/account-operations.js +304 -0
  10. package/dist/client/account-operations.js.map +1 -0
  11. package/dist/client/conversations.d.ts +36 -0
  12. package/dist/client/conversations.d.ts.map +1 -0
  13. package/dist/client/conversations.js +144 -0
  14. package/dist/client/conversations.js.map +1 -0
  15. package/dist/client.d.ts +53 -0
  16. package/dist/client.d.ts.map +1 -0
  17. package/dist/client.js +162 -0
  18. package/dist/client.js.map +1 -0
  19. package/dist/components/account.d.ts +38 -0
  20. package/dist/components/account.d.ts.map +1 -0
  21. package/dist/components/account.js +243 -0
  22. package/dist/components/account.js.map +1 -0
  23. package/dist/components/channel.d.ts +78 -0
  24. package/dist/components/channel.d.ts.map +1 -0
  25. package/dist/components/channel.js +475 -0
  26. package/dist/components/channel.js.map +1 -0
  27. package/dist/components/component.d.ts +49 -0
  28. package/dist/components/component.d.ts.map +1 -0
  29. package/dist/components/component.js +194 -0
  30. package/dist/components/component.js.map +1 -0
  31. package/dist/components/device.d.ts +60 -0
  32. package/dist/components/device.d.ts.map +1 -0
  33. package/dist/components/device.js +648 -0
  34. package/dist/components/device.js.map +1 -0
  35. package/dist/components/group.d.ts +141 -0
  36. package/dist/components/group.d.ts.map +1 -0
  37. package/dist/components/group.js +933 -0
  38. package/dist/components/group.js.map +1 -0
  39. package/dist/components/message.d.ts +63 -0
  40. package/dist/components/message.d.ts.map +1 -0
  41. package/dist/components/message.js +439 -0
  42. package/dist/components/message.js.map +1 -0
  43. package/dist/components/profile.d.ts +37 -0
  44. package/dist/components/profile.d.ts.map +1 -0
  45. package/dist/components/profile.js +232 -0
  46. package/dist/components/profile.js.map +1 -0
  47. package/dist/crypto/groups.d.ts +56 -0
  48. package/dist/crypto/groups.d.ts.map +1 -0
  49. package/dist/crypto/groups.js +163 -0
  50. package/dist/crypto/groups.js.map +1 -0
  51. package/dist/crypto/messages.d.ts +52 -0
  52. package/dist/crypto/messages.d.ts.map +1 -0
  53. package/dist/crypto/messages.js +180 -0
  54. package/dist/crypto/messages.js.map +1 -0
  55. package/dist/crypto/primitives.d.ts +30 -0
  56. package/dist/crypto/primitives.d.ts.map +1 -0
  57. package/dist/crypto/primitives.js +102 -0
  58. package/dist/crypto/primitives.js.map +1 -0
  59. package/dist/errors.d.ts +11 -0
  60. package/dist/errors.d.ts.map +1 -0
  61. package/dist/errors.js +14 -0
  62. package/dist/errors.js.map +1 -0
  63. package/dist/groups/account-sync.d.ts +28 -0
  64. package/dist/groups/account-sync.d.ts.map +1 -0
  65. package/dist/groups/account-sync.js +235 -0
  66. package/dist/groups/account-sync.js.map +1 -0
  67. package/dist/groups/messages.d.ts +39 -0
  68. package/dist/groups/messages.d.ts.map +1 -0
  69. package/dist/groups/messages.js +141 -0
  70. package/dist/groups/messages.js.map +1 -0
  71. package/dist/groups/operations.d.ts +57 -0
  72. package/dist/groups/operations.d.ts.map +1 -0
  73. package/dist/groups/operations.js +225 -0
  74. package/dist/groups/operations.js.map +1 -0
  75. package/dist/groups/repository.d.ts +56 -0
  76. package/dist/groups/repository.d.ts.map +1 -0
  77. package/dist/groups/repository.js +254 -0
  78. package/dist/groups/repository.js.map +1 -0
  79. package/dist/groups/secrets.d.ts +67 -0
  80. package/dist/groups/secrets.d.ts.map +1 -0
  81. package/dist/groups/secrets.js +452 -0
  82. package/dist/groups/secrets.js.map +1 -0
  83. package/dist/groups/state.d.ts +39 -0
  84. package/dist/groups/state.d.ts.map +1 -0
  85. package/dist/groups/state.js +201 -0
  86. package/dist/groups/state.js.map +1 -0
  87. package/dist/identity/identifiers.d.ts +9 -0
  88. package/dist/identity/identifiers.d.ts.map +1 -0
  89. package/dist/identity/identifiers.js +37 -0
  90. package/dist/identity/identifiers.js.map +1 -0
  91. package/dist/identity/neo.d.ts +11 -0
  92. package/dist/identity/neo.d.ts.map +1 -0
  93. package/dist/identity/neo.js +77 -0
  94. package/dist/identity/neo.js.map +1 -0
  95. package/dist/index.d.ts +53 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +46 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/interactions.d.ts +31 -0
  100. package/dist/interactions.d.ts.map +1 -0
  101. package/dist/interactions.js +2 -0
  102. package/dist/interactions.js.map +1 -0
  103. package/dist/messages/account-sender.d.ts +9 -0
  104. package/dist/messages/account-sender.d.ts.map +1 -0
  105. package/dist/messages/account-sender.js +46 -0
  106. package/dist/messages/account-sender.js.map +1 -0
  107. package/dist/messages/contacts.d.ts +103 -0
  108. package/dist/messages/contacts.d.ts.map +1 -0
  109. package/dist/messages/contacts.js +525 -0
  110. package/dist/messages/contacts.js.map +1 -0
  111. package/dist/messages/outbox.d.ts +66 -0
  112. package/dist/messages/outbox.d.ts.map +1 -0
  113. package/dist/messages/outbox.js +167 -0
  114. package/dist/messages/outbox.js.map +1 -0
  115. package/dist/messages/receiver.d.ts +35 -0
  116. package/dist/messages/receiver.d.ts.map +1 -0
  117. package/dist/messages/receiver.js +113 -0
  118. package/dist/messages/receiver.js.map +1 -0
  119. package/dist/messages/repository.d.ts +89 -0
  120. package/dist/messages/repository.d.ts.map +1 -0
  121. package/dist/messages/repository.js +295 -0
  122. package/dist/messages/repository.js.map +1 -0
  123. package/dist/models/authentication.d.ts +37 -0
  124. package/dist/models/authentication.d.ts.map +1 -0
  125. package/dist/models/authentication.js +53 -0
  126. package/dist/models/authentication.js.map +1 -0
  127. package/dist/models/channels.d.ts +141 -0
  128. package/dist/models/channels.d.ts.map +1 -0
  129. package/dist/models/channels.js +258 -0
  130. package/dist/models/channels.js.map +1 -0
  131. package/dist/models/contacts.d.ts +68 -0
  132. package/dist/models/contacts.d.ts.map +1 -0
  133. package/dist/models/contacts.js +186 -0
  134. package/dist/models/contacts.js.map +1 -0
  135. package/dist/models/content.d.ts +37 -0
  136. package/dist/models/content.d.ts.map +1 -0
  137. package/dist/models/content.js +137 -0
  138. package/dist/models/content.js.map +1 -0
  139. package/dist/models/device-state.d.ts +8 -0
  140. package/dist/models/device-state.d.ts.map +1 -0
  141. package/dist/models/device-state.js +22 -0
  142. package/dist/models/device-state.js.map +1 -0
  143. package/dist/models/group-admission.d.ts +111 -0
  144. package/dist/models/group-admission.d.ts.map +1 -0
  145. package/dist/models/group-admission.js +153 -0
  146. package/dist/models/group-admission.js.map +1 -0
  147. package/dist/models/group-keys.d.ts +30 -0
  148. package/dist/models/group-keys.d.ts.map +1 -0
  149. package/dist/models/group-keys.js +52 -0
  150. package/dist/models/group-keys.js.map +1 -0
  151. package/dist/models/group-management.d.ts +190 -0
  152. package/dist/models/group-management.d.ts.map +1 -0
  153. package/dist/models/group-management.js +263 -0
  154. package/dist/models/group-management.js.map +1 -0
  155. package/dist/models/groups.d.ts +81 -0
  156. package/dist/models/groups.d.ts.map +1 -0
  157. package/dist/models/groups.js +127 -0
  158. package/dist/models/groups.js.map +1 -0
  159. package/dist/models/identity.d.ts +47 -0
  160. package/dist/models/identity.d.ts.map +1 -0
  161. package/dist/models/identity.js +136 -0
  162. package/dist/models/identity.js.map +1 -0
  163. package/dist/models/messages.d.ts +104 -0
  164. package/dist/models/messages.d.ts.map +1 -0
  165. package/dist/models/messages.js +168 -0
  166. package/dist/models/messages.js.map +1 -0
  167. package/dist/models/profile.d.ts +24 -0
  168. package/dist/models/profile.d.ts.map +1 -0
  169. package/dist/models/profile.js +47 -0
  170. package/dist/models/profile.js.map +1 -0
  171. package/dist/models/relay.d.ts +39 -0
  172. package/dist/models/relay.d.ts.map +1 -0
  173. package/dist/models/relay.js +160 -0
  174. package/dist/models/relay.js.map +1 -0
  175. package/dist/protocol/codec.d.ts +36 -0
  176. package/dist/protocol/codec.d.ts.map +1 -0
  177. package/dist/protocol/codec.js +144 -0
  178. package/dist/protocol/codec.js.map +1 -0
  179. package/dist/protocol/context.d.ts +14 -0
  180. package/dist/protocol/context.d.ts.map +1 -0
  181. package/dist/protocol/context.js +43 -0
  182. package/dist/protocol/context.js.map +1 -0
  183. package/dist/protocol/encoding.d.ts +15 -0
  184. package/dist/protocol/encoding.d.ts.map +1 -0
  185. package/dist/protocol/encoding.js +133 -0
  186. package/dist/protocol/encoding.js.map +1 -0
  187. package/dist/protocol/json.d.ts +16 -0
  188. package/dist/protocol/json.d.ts.map +1 -0
  189. package/dist/protocol/json.js +172 -0
  190. package/dist/protocol/json.js.map +1 -0
  191. package/dist/protocol/validation.d.ts +4 -0
  192. package/dist/protocol/validation.d.ts.map +1 -0
  193. package/dist/protocol/validation.js +18 -0
  194. package/dist/protocol/validation.js.map +1 -0
  195. package/dist/runtime/abort.d.ts +6 -0
  196. package/dist/runtime/abort.d.ts.map +1 -0
  197. package/dist/runtime/abort.js +32 -0
  198. package/dist/runtime/abort.js.map +1 -0
  199. package/dist/runtime/async-gate.d.ts +6 -0
  200. package/dist/runtime/async-gate.d.ts.map +1 -0
  201. package/dist/runtime/async-gate.js +15 -0
  202. package/dist/runtime/async-gate.js.map +1 -0
  203. package/dist/runtime/async-pulse.d.ts +7 -0
  204. package/dist/runtime/async-pulse.d.ts.map +1 -0
  205. package/dist/runtime/async-pulse.js +23 -0
  206. package/dist/runtime/async-pulse.js.map +1 -0
  207. package/dist/runtime/clock.d.ts +16 -0
  208. package/dist/runtime/clock.d.ts.map +1 -0
  209. package/dist/runtime/clock.js +62 -0
  210. package/dist/runtime/clock.js.map +1 -0
  211. package/dist/runtime/events.d.ts +11 -0
  212. package/dist/runtime/events.d.ts.map +1 -0
  213. package/dist/runtime/events.js +45 -0
  214. package/dist/runtime/events.js.map +1 -0
  215. package/dist/runtime/url.d.ts +3 -0
  216. package/dist/runtime/url.d.ts.map +1 -0
  217. package/dist/runtime/url.js +23 -0
  218. package/dist/runtime/url.js.map +1 -0
  219. package/dist/storage/signed-request.d.ts +14 -0
  220. package/dist/storage/signed-request.d.ts.map +1 -0
  221. package/dist/storage/signed-request.js +26 -0
  222. package/dist/storage/signed-request.js.map +1 -0
  223. package/dist/storage/store.d.ts +58 -0
  224. package/dist/storage/store.d.ts.map +1 -0
  225. package/dist/storage/store.js +52 -0
  226. package/dist/storage/store.js.map +1 -0
  227. package/dist/storage/transaction.d.ts +7 -0
  228. package/dist/storage/transaction.d.ts.map +1 -0
  229. package/dist/storage/transaction.js +22 -0
  230. package/dist/storage/transaction.js.map +1 -0
  231. package/dist/transport/client.d.ts +61 -0
  232. package/dist/transport/client.d.ts.map +1 -0
  233. package/dist/transport/client.js +392 -0
  234. package/dist/transport/client.js.map +1 -0
  235. package/dist/transport/discovery.d.ts +19 -0
  236. package/dist/transport/discovery.d.ts.map +1 -0
  237. package/dist/transport/discovery.js +75 -0
  238. package/dist/transport/discovery.js.map +1 -0
  239. package/dist/transport/endpoint.d.ts +6 -0
  240. package/dist/transport/endpoint.d.ts.map +1 -0
  241. package/dist/transport/endpoint.js +35 -0
  242. package/dist/transport/endpoint.js.map +1 -0
  243. package/dist/transport/http.d.ts +52 -0
  244. package/dist/transport/http.d.ts.map +1 -0
  245. package/dist/transport/http.js +128 -0
  246. package/dist/transport/http.js.map +1 -0
  247. package/dist/transport/pool.d.ts +31 -0
  248. package/dist/transport/pool.d.ts.map +1 -0
  249. package/dist/transport/pool.js +137 -0
  250. package/dist/transport/pool.js.map +1 -0
  251. package/dist/transport/relay-error.d.ts +23 -0
  252. package/dist/transport/relay-error.d.ts.map +1 -0
  253. package/dist/transport/relay-error.js +47 -0
  254. package/dist/transport/relay-error.js.map +1 -0
  255. package/dist/transport/rpc.d.ts +31 -0
  256. package/dist/transport/rpc.d.ts.map +1 -0
  257. package/dist/transport/rpc.js +56 -0
  258. package/dist/transport/rpc.js.map +1 -0
  259. package/dist/transport/session.d.ts +49 -0
  260. package/dist/transport/session.d.ts.map +1 -0
  261. package/dist/transport/session.js +169 -0
  262. package/dist/transport/session.js.map +1 -0
  263. package/dist/transport/socket.d.ts +55 -0
  264. package/dist/transport/socket.d.ts.map +1 -0
  265. package/dist/transport/socket.js +266 -0
  266. package/dist/transport/socket.js.map +1 -0
  267. package/dist/transport/subscription.d.ts +36 -0
  268. package/dist/transport/subscription.d.ts.map +1 -0
  269. package/dist/transport/subscription.js +169 -0
  270. package/dist/transport/subscription.js.map +1 -0
  271. package/package.json +35 -4
  272. package/src/channels/repository.ts +244 -0
  273. package/src/client/account-operations.ts +183 -0
  274. package/src/client/conversations.ts +95 -0
  275. package/src/client.ts +108 -0
  276. package/src/components/account.ts +206 -0
  277. package/src/components/channel.ts +253 -0
  278. package/src/components/component.ts +151 -0
  279. package/src/components/device.ts +455 -0
  280. package/src/components/group.ts +546 -0
  281. package/src/components/message.ts +253 -0
  282. package/src/components/profile.ts +179 -0
  283. package/src/crypto/groups.ts +107 -0
  284. package/src/crypto/messages.ts +129 -0
  285. package/src/crypto/primitives.ts +103 -0
  286. package/src/errors.ts +13 -0
  287. package/src/groups/account-sync.ts +144 -0
  288. package/src/groups/messages.ts +89 -0
  289. package/src/groups/operations.ts +145 -0
  290. package/src/groups/repository.ts +161 -0
  291. package/src/groups/secrets.ts +256 -0
  292. package/src/groups/state.ts +138 -0
  293. package/src/identity/identifiers.ts +41 -0
  294. package/src/identity/neo.ts +72 -0
  295. package/src/index.ts +52 -0
  296. package/src/interactions.ts +35 -0
  297. package/src/messages/account-sender.ts +33 -0
  298. package/src/messages/contacts.ts +379 -0
  299. package/src/messages/outbox.ts +152 -0
  300. package/src/messages/receiver.ts +86 -0
  301. package/src/messages/repository.ts +230 -0
  302. package/src/models/authentication.ts +63 -0
  303. package/src/models/channels.ts +155 -0
  304. package/src/models/contacts.ts +141 -0
  305. package/src/models/content.ts +105 -0
  306. package/src/models/device-state.ts +18 -0
  307. package/src/models/group-admission.ts +110 -0
  308. package/src/models/group-keys.ts +34 -0
  309. package/src/models/group-management.ts +182 -0
  310. package/src/models/groups.ts +100 -0
  311. package/src/models/identity.ts +164 -0
  312. package/src/models/messages.ts +139 -0
  313. package/src/models/profile.ts +46 -0
  314. package/src/models/relay.ts +151 -0
  315. package/src/protocol/codec.ts +144 -0
  316. package/src/protocol/context.ts +39 -0
  317. package/src/protocol/encoding.ts +106 -0
  318. package/src/protocol/json.ts +140 -0
  319. package/src/protocol/validation.ts +13 -0
  320. package/src/runtime/abort.ts +27 -0
  321. package/src/runtime/async-gate.ts +16 -0
  322. package/src/runtime/async-pulse.ts +20 -0
  323. package/src/runtime/clock.ts +63 -0
  324. package/src/runtime/events.ts +31 -0
  325. package/src/runtime/url.ts +17 -0
  326. package/src/storage/signed-request.ts +26 -0
  327. package/src/storage/store.ts +90 -0
  328. package/src/storage/transaction.ts +17 -0
  329. package/src/transport/client.ts +328 -0
  330. package/src/transport/discovery.ts +64 -0
  331. package/src/transport/endpoint.ts +32 -0
  332. package/src/transport/http.ts +129 -0
  333. package/src/transport/pool.ts +115 -0
  334. package/src/transport/relay-error.ts +46 -0
  335. package/src/transport/rpc.ts +56 -0
  336. package/src/transport/session.ts +154 -0
  337. package/src/transport/socket.ts +248 -0
  338. package/src/transport/subscription.ts +117 -0
@@ -0,0 +1,168 @@
1
+ import { requireLength, verifyDevice } from '../crypto/primitives.js';
2
+ import { ProtocolError } from '../errors.js';
3
+ import { validateIdentifier } from '../identity/identifiers.js';
4
+ import { validateAccountId } from '../identity/neo.js';
5
+ import { array, boolean, bytes, defineCodec, enumeration, integer, text } from '../protocol/codec.js';
6
+ import { signingInput } from '../protocol/context.js';
7
+ import { encodeUtf8 } from '../protocol/encoding.js';
8
+ import { canonicalJson, parseJson, requireObject, requireSafeInteger } from '../protocol/json.js';
9
+ import { validateCompleteObject } from '../protocol/validation.js';
10
+ import { relayFailureCodec } from '../transport/relay-error.js';
11
+ import { contentReferenceCodec, messageBodyCodec, validateAttachments, validateMessageBody } from './content.js';
12
+ import { contactAuthorizationCodec, validateContactGrant, validateContactInvite } from './contacts.js';
13
+ import { certificateId, deviceCertificateCodec, validateCertificate } from './identity.js';
14
+ /** Complete wire business object. Unknown types may be stored but cannot authorize protocol state changes. */
15
+ export const messagePayloadCodec = {
16
+ decode(value) {
17
+ const object = requireObject(value);
18
+ validateCompleteObject(object);
19
+ if (typeof object['$type'] !== 'string')
20
+ throw new ProtocolError('invalid_type', 'A message payload requires a string $type.');
21
+ return requireObject(parseJson(canonicalJson(object)));
22
+ },
23
+ encode(value) { return this.decode(value); },
24
+ };
25
+ export const encryptedPayloadCodec = defineCodec({ alg: { wire: 'alg', codec: text }, nonce: { wire: 'nonce', codec: bytes }, ciphertext: { wire: 'ciphertext', codec: bytes } });
26
+ export function validateEncryptedPayload(value) {
27
+ validateCompleteObject(encryptedPayloadCodec.encode(value));
28
+ if (value.alg !== 'AES-256-GCM')
29
+ throw new ProtocolError('unsupported_algorithm', 'Message payload encryption must use AES-256-GCM.');
30
+ requireLength(value.nonce, 12, 'Payload nonce');
31
+ if (value.ciphertext.length <= 16)
32
+ throw new ProtocolError('invalid_ciphertext', 'Encrypted payload requires nonempty ciphertext and a GCM tag.');
33
+ }
34
+ export const messageEnvelopeCodec = defineCodec({ messageId: { wire: 'message_id', codec: text }, createdAt: { wire: 'created_at', codec: integer },
35
+ from: { wire: 'from', codec: text }, fromDeviceId: { wire: 'from_device_id', codec: text }, to: { wire: 'to', codec: text },
36
+ payload: { wire: 'payload', codec: encryptedPayloadCodec }, deviceSignature: { wire: 'device_signature', codec: bytes } }, 'meshline.message.envelope');
37
+ export const messageEnvelopeInput = (value, context) => signingInput(messageEnvelopeCodec.encode(value), context, ['device_signature']);
38
+ export function validateMessageEnvelope(value) {
39
+ validateCompleteObject(messageEnvelopeCodec.encode(value));
40
+ validateIdentifier('message', value.messageId);
41
+ validateIdentifier('device', value.fromDeviceId);
42
+ requireSafeInteger(value.createdAt, 0);
43
+ validateAccountId(value.from);
44
+ validateAccountId(value.to);
45
+ requireLength(value.deviceSignature, 64, 'Envelope signature');
46
+ validateEncryptedPayload(value.payload);
47
+ if (encodeUtf8(messageEnvelopeCodec.stringify(value)).length > 262144)
48
+ throw new ProtocolError('invalid_size', 'Message envelope exceeds 262144 canonical UTF-8 bytes.');
49
+ }
50
+ /** Historical signature integrity only. Current device authority is checked separately by the receiver's business workflow. */
51
+ export function verifyMessageEnvelope(value, sender, context) {
52
+ validateMessageEnvelope(value);
53
+ validateCertificate(sender, context);
54
+ if (sender.account !== value.from || certificateId(sender, context) !== value.fromDeviceId)
55
+ throw new ProtocolError('invalid_identity', 'Envelope signing certificate belongs to another account or device.');
56
+ if (!verifyDevice(messageEnvelopeInput(value, context), value.deviceSignature, sender.signingPublicKey))
57
+ throw new ProtocolError('invalid_signature', 'Invalid message envelope signature.');
58
+ }
59
+ export const messageKeyBoxCodec = defineCodec({ deviceId: { wire: 'device_id', codec: text }, alg: { wire: 'alg', codec: text }, enc: { wire: 'enc', codec: bytes }, sealedKey: { wire: 'sealed_key', codec: bytes } });
60
+ export function validateMessageKeyBox(value) {
61
+ validateCompleteObject(messageKeyBoxCodec.encode(value));
62
+ validateIdentifier('device', value.deviceId);
63
+ if (value.alg !== 'X25519-HKDF-SHA256-AES256GCM')
64
+ throw new ProtocolError('unsupported_algorithm', 'Unsupported message key box algorithm.');
65
+ requireLength(value.enc, 32, 'Ephemeral public key');
66
+ requireLength(value.sealedKey, 60, 'Sealed content key');
67
+ }
68
+ export function validateMessageKeyBoxes(values) {
69
+ if (values.length < 1 || values.length > 8)
70
+ throw new ProtocolError('invalid_size', 'Key box sets require between one and eight devices.');
71
+ const ids = new Set();
72
+ for (const value of values) {
73
+ validateMessageKeyBox(value);
74
+ if (ids.has(value.deviceId))
75
+ throw new ProtocolError('duplicate_device', 'Key box set contains a duplicate device.');
76
+ ids.add(value.deviceId);
77
+ }
78
+ }
79
+ export const messageSendRequestCodec = defineCodec({ envelope: { wire: 'envelope', codec: messageEnvelopeCodec }, senderBoxes: { wire: 'sender_boxes', codec: array(messageKeyBoxCodec), optional: true },
80
+ recipientBoxes: { wire: 'recipient_boxes', codec: array(messageKeyBoxCodec) }, authorization: { wire: 'authorization', codec: contactAuthorizationCodec, optional: true } });
81
+ export function validateMessageSendRequest(value, now) {
82
+ validateCompleteObject(messageSendRequestCodec.encode(value));
83
+ requireSafeInteger(now, 0);
84
+ validateMessageEnvelope(value.envelope);
85
+ validateMessageKeyBoxes(value.recipientBoxes);
86
+ if (value.senderBoxes)
87
+ validateMessageKeyBoxes(value.senderBoxes);
88
+ if (value.envelope.from === value.envelope.to && (value.senderBoxes !== undefined || value.authorization !== undefined))
89
+ throw new ProtocolError('invalid_self_delivery', 'Self messages must omit sender boxes and contact authorization.');
90
+ if (value.authorization) {
91
+ if ('grantor' in value.authorization) {
92
+ validateContactGrant(value.authorization, now);
93
+ if (value.authorization.grantor !== value.envelope.to || value.authorization.grantee !== value.envelope.from)
94
+ throw new ProtocolError('invalid_authorization', 'Message grant has inconsistent account bindings.');
95
+ }
96
+ else {
97
+ validateContactInvite(value.authorization, now);
98
+ if (value.authorization.inviter !== value.envelope.to)
99
+ throw new ProtocolError('invalid_authorization', 'Message invitation belongs to another recipient.');
100
+ }
101
+ }
102
+ }
103
+ export const directMessageReferenceCodec = defineCodec({ from: { wire: 'from', codec: text }, messageId: { wire: 'message_id', codec: text } });
104
+ export const directMessageCodec = defineCodec({ body: { wire: 'body', codec: messageBodyCodec, optional: true }, attachments: { wire: 'attachments', codec: array(contentReferenceCodec), optional: true },
105
+ replyTo: { wire: 'reply_to', codec: directMessageReferenceCodec, optional: true } }, 'meshline.message.direct');
106
+ export function validateDirectMessage(value) {
107
+ validateCompleteObject(directMessageCodec.encode(value));
108
+ if (value.body)
109
+ validateMessageBody(value.body);
110
+ if (value.attachments)
111
+ validateAttachments(value.attachments);
112
+ if (!value.body && !value.attachments?.length)
113
+ throw new ProtocolError('invalid_message', 'A direct message requires a body or at least one attachment.');
114
+ if (value.replyTo) {
115
+ validateAccountId(value.replyTo.from);
116
+ validateIdentifier('message', value.replyTo.messageId);
117
+ }
118
+ }
119
+ export const messageTimelineEntryCodec = defineCodec({ sequence: { wire: 'sequence', codec: integer }, envelope: { wire: 'envelope', codec: messageEnvelopeCodec }, keyBox: { wire: 'key_box', codec: messageKeyBoxCodec }, acceptedAt: { wire: 'accepted_at', codec: integer } });
120
+ export const messageTimelinePageCodec = defineCodec({ items: { wire: 'items', codec: array(messageTimelineEntryCodec) }, certificates: { wire: 'certificates', codec: array(deviceCertificateCodec) },
121
+ hasMore: { wire: 'has_more', codec: boolean }, hasRetentionGap: { wire: 'has_retention_gap', codec: boolean, optional: true } });
122
+ /** Checks page ordering and certificate availability. Each entry still requires decryption and business validation before cursor commit. */
123
+ export function validateMessageTimelinePage(value, context, after = -1) {
124
+ requireSafeInteger(after, -1);
125
+ validateCompleteObject(messageTimelinePageCodec.encode(value));
126
+ if (value.hasMore && !value.items.length)
127
+ throw new ProtocolError('invalid_pagination', 'An empty timeline page cannot have more items.');
128
+ const ids = new Map();
129
+ for (const certificate of value.certificates) {
130
+ validateCertificate(certificate, context);
131
+ const id = certificateId(certificate, context);
132
+ if (ids.has(id))
133
+ throw new ProtocolError('duplicate_device', 'Timeline page has duplicate signing certificates.');
134
+ ids.set(id, certificate.account);
135
+ }
136
+ for (const item of value.items) {
137
+ requireSafeInteger(item.sequence, 0);
138
+ requireSafeInteger(item.acceptedAt, 0);
139
+ if (item.sequence <= after)
140
+ throw new ProtocolError('invalid_sequence', 'Timeline sequences must increase strictly after the requested cursor.');
141
+ if (!ids.has(item.envelope.fromDeviceId))
142
+ throw new ProtocolError('missing_certificate', 'Timeline message has no signing certificate.');
143
+ if (ids.get(item.envelope.fromDeviceId) !== item.envelope.from)
144
+ throw new ProtocolError('invalid_identity', 'Timeline signing certificate belongs to another account.');
145
+ after = item.sequence;
146
+ }
147
+ }
148
+ export const messageTimelineQueryCodec = defineCodec({ after: { wire: 'after', codec: integer, optional: true }, limit: { wire: 'limit', codec: integer, optional: true } });
149
+ export function validateMessageTimelineQuery(value) {
150
+ validateCompleteObject(messageTimelineQueryCodec.encode(value));
151
+ if (value.after !== undefined)
152
+ requireSafeInteger(value.after, -1);
153
+ if (value.limit !== undefined)
154
+ requireSafeInteger(value.limit, 1);
155
+ }
156
+ export const messageDeliveryQueryCodec = defineCodec({ messageId: { wire: 'message_id', codec: text } });
157
+ export const messageDeliveryStatusCodec = defineCodec({ status: { wire: 'status', codec: enumeration('delivering', 'target_accepted', 'failed') }, error: { wire: 'error', codec: relayFailureCodec, optional: true }, acceptedAt: { wire: 'accepted_at', codec: integer } });
158
+ export function validateMessageDeliveryStatus(value) {
159
+ validateCompleteObject(messageDeliveryStatusCodec.encode(value));
160
+ requireSafeInteger(value.acceptedAt, 0);
161
+ if ((value.status === 'failed') !== (value.error !== undefined))
162
+ throw new ProtocolError('invalid_delivery', 'Only failed delivery results must contain an error.');
163
+ }
164
+ export const deviceStateChangedCodec = defineCodec({ revision: { wire: 'revision', codec: integer } }, 'meshline.device.state.changed');
165
+ export function validateDeviceStateChanged(value) { validateCompleteObject(deviceStateChangedCodec.encode(value)); requireSafeInteger(value.revision, 0); }
166
+ export const messageTimelineChangedCodec = defineCodec({ head: { wire: 'head', codec: integer } });
167
+ export function validateMessageTimelineChanged(value) { validateCompleteObject(messageTimelineChangedCodec.encode(value)); requireSafeInteger(value.head, 0); }
168
+ //# sourceMappingURL=messages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.js","sourceRoot":"","sources":["../../src/models/messages.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { type ExtensibleModel } from '../protocol/codec.js';
2
+ import { type NetworkContext } from '../protocol/context.js';
3
+ import { type ContentReference } from './content.js';
4
+ import { type DeviceCertificate } from './identity.js';
5
+ export interface AccountProfile extends ExtensibleModel {
6
+ readonly account: string;
7
+ readonly nickname?: string;
8
+ readonly avatar?: ContentReference;
9
+ readonly bio?: string;
10
+ readonly publicDiscovery: boolean;
11
+ readonly updatedAt: number;
12
+ readonly deviceSignature: Uint8Array;
13
+ }
14
+ export declare const accountProfileCodec: import("../protocol/codec.js").ProtocolCodec<AccountProfile>;
15
+ export declare const profileInput: (value: AccountProfile, context: NetworkContext) => Uint8Array;
16
+ export declare function validateProfile(value: AccountProfile): void;
17
+ export interface ProfileResolveResult extends ExtensibleModel {
18
+ readonly profile: AccountProfile;
19
+ readonly signerCertificate: DeviceCertificate;
20
+ }
21
+ export declare const profileResolveResultCodec: import("../protocol/codec.js").ProtocolCodec<ProfileResolveResult>;
22
+ /** The certificate is evidence at publication acceptance, not a claim of current device authorization. */
23
+ export declare function validateProfileResult(value: ProfileResolveResult, context: NetworkContext, account?: string): void;
24
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/models/profile.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8C,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACxG,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI3E,OAAO,EAA0E,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7H,OAAO,EAA+C,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEpG,MAAM,WAAW,cAAe,SAAQ,eAAe;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAChH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC;CACvG;AACD,eAAO,MAAM,mBAAmB,8DAIV,CAAC;AACvB,eAAO,MAAM,YAAY,UAAW,cAAc,WAAW,cAAc,KAAG,UAA4F,CAAC;AAC3K,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAY3D;AACD,MAAM,WAAW,oBAAqB,SAAQ,eAAe;IAAG,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IAAC,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAA;CAAE;AACjJ,eAAO,MAAM,yBAAyB,oEAEpC,CAAC;AACH,0GAA0G;AAC1G,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,oBAAoB,EAAE,OAAO,EAAE,cAAc,EAAE,OAAO,SAAwB,GAAG,IAAI,CAMjI"}
@@ -0,0 +1,47 @@
1
+ import { requireLength, verifyDevice } from '../crypto/primitives.js';
2
+ import { ProtocolError } from '../errors.js';
3
+ import { validateAccountId } from '../identity/neo.js';
4
+ import { boolean, bytes, defineCodec, integer, text } from '../protocol/codec.js';
5
+ import { signingInput } from '../protocol/context.js';
6
+ import { encodeUtf8 } from '../protocol/encoding.js';
7
+ import { requireSafeInteger } from '../protocol/json.js';
8
+ import { validateCompleteObject } from '../protocol/validation.js';
9
+ import { containsNonWhitespace, contentReferenceCodec, validateContentReference } from './content.js';
10
+ import { deviceCertificateCodec, validateCertificate } from './identity.js';
11
+ export const accountProfileCodec = defineCodec({
12
+ account: { wire: 'account', codec: text }, nickname: { wire: 'nickname', codec: text, optional: true },
13
+ avatar: { wire: 'avatar', codec: contentReferenceCodec, optional: true }, bio: { wire: 'bio', codec: text, optional: true },
14
+ publicDiscovery: { wire: 'public_discovery', codec: boolean }, updatedAt: { wire: 'updated_at', codec: integer }, deviceSignature: { wire: 'device_signature', codec: bytes },
15
+ }, 'meshline.profile');
16
+ export const profileInput = (value, context) => signingInput(accountProfileCodec.encode(value), context, ['device_signature']);
17
+ export function validateProfile(value) {
18
+ validateCompleteObject(accountProfileCodec.encode(value));
19
+ validateAccountId(value.account);
20
+ requireSafeInteger(value.updatedAt, 0);
21
+ requireLength(value.deviceSignature, 64, 'Profile signature');
22
+ for (const [field, limit] of [[value.nickname, 256], [value.bio, 2048]]) {
23
+ if (field !== undefined && field !== '' && (!containsNonWhitespace(field) || encodeUtf8(field).length > limit))
24
+ throw new ProtocolError('invalid_profile_text', `Nonempty profile text must contain non-whitespace characters and fit ${limit} UTF-8 bytes.`);
25
+ }
26
+ if (value.avatar) {
27
+ validateContentReference(value.avatar);
28
+ if (!value.avatar.contentType.toLowerCase().startsWith('image/'))
29
+ throw new ProtocolError('invalid_avatar', 'An avatar requires an image media type.');
30
+ }
31
+ if (encodeUtf8(accountProfileCodec.stringify(value)).length > 8192)
32
+ throw new ProtocolError('invalid_size', 'Profile exceeds 8192 canonical JSON bytes.');
33
+ }
34
+ export const profileResolveResultCodec = defineCodec({
35
+ profile: { wire: 'profile', codec: accountProfileCodec }, signerCertificate: { wire: 'signer_certificate', codec: deviceCertificateCodec },
36
+ });
37
+ /** The certificate is evidence at publication acceptance, not a claim of current device authorization. */
38
+ export function validateProfileResult(value, context, account = value.profile.account) {
39
+ validateCompleteObject(profileResolveResultCodec.encode(value));
40
+ validateProfile(value.profile);
41
+ validateCertificate(value.signerCertificate, context);
42
+ if (value.profile.account !== account || value.signerCertificate.account !== account)
43
+ throw new ProtocolError('invalid_identity', 'Profile or signer certificate belongs to another account.');
44
+ if (!verifyDevice(profileInput(value.profile, context), value.profile.deviceSignature, value.signerCertificate.signingPublicKey))
45
+ throw new ProtocolError('invalid_signature', 'Invalid profile device signature.');
46
+ }
47
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/models/profile.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { type ExtensibleModel } from '../protocol/codec.js';
2
+ import { NetworkContext } from '../protocol/context.js';
3
+ export interface RelayDescriptor extends ExtensibleModel {
4
+ readonly relayId: string;
5
+ readonly publicKey: Uint8Array;
6
+ readonly endpoints: readonly string[];
7
+ readonly capabilities?: readonly string[];
8
+ readonly expiresAt: number;
9
+ readonly relaySignature: Uint8Array;
10
+ }
11
+ export declare const relayDescriptorCodec: import("../protocol/codec.js").ProtocolCodec<RelayDescriptor>;
12
+ export declare function relayDescriptorInput(descriptor: RelayDescriptor, context: NetworkContext): Uint8Array;
13
+ export type RelayEndpoint = {
14
+ readonly kind: 'https' | 'wss' | 'unknown';
15
+ } | {
16
+ readonly kind: 'libp2p-tcp';
17
+ readonly peerId: string;
18
+ };
19
+ export declare function validateRelayEndpoint(endpoint: string): RelayEndpoint;
20
+ export declare function validateRelayDescriptor(descriptor: RelayDescriptor, context: NetworkContext, now: number): void;
21
+ export interface RelayLimits extends ExtensibleModel {
22
+ readonly messageRetention: number;
23
+ readonly channelTimelineRetention?: number;
24
+ readonly maxChannelSubscriptions?: number;
25
+ readonly groupMessageRetention?: number;
26
+ readonly maxGroupMembers?: number;
27
+ readonly maxGroupSubscriptions?: number;
28
+ readonly maxGroupInviteTtl?: number;
29
+ }
30
+ export declare const relayLimitsCodec: import("../protocol/codec.js").ProtocolCodec<RelayLimits>;
31
+ export interface RelayInfo extends ExtensibleModel {
32
+ readonly relayId: string;
33
+ readonly name: string;
34
+ readonly serverTime: number;
35
+ readonly limits: RelayLimits;
36
+ }
37
+ export declare const relayInfoCodec: import("../protocol/codec.js").ProtocolCodec<RelayInfo>;
38
+ export declare function validateRelayInfo(info: RelayInfo, descriptor?: RelayDescriptor): void;
39
+ //# sourceMappingURL=relay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../../src/models/relay.ts"],"names":[],"mappings":"AAOA,OAAO,EAA4C,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACtG,OAAO,EAAE,cAAc,EAAgB,MAAM,wBAAwB,CAAC;AAKtE,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACpD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,cAAc,EAAE,UAAU,CAAC;CACvC;AACD,eAAO,MAAM,oBAAoB,+DAIF,CAAC;AAEhC,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,GAAG,UAAU,CAErG;AAoBD,MAAM,MAAM,aAAa,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AACtI,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CA4BrE;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA2B/G;AAED,MAAM,WAAW,WAAY,SAAQ,eAAe;IAChD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAC1C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACvC;AACD,eAAO,MAAM,gBAAgB,2DAQ3B,CAAC;AACH,MAAM,WAAW,SAAU,SAAQ,eAAe;IAAG,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAAE;AACjK,eAAO,MAAM,cAAc,yDAEzB,CAAC;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,eAAe,GAAG,IAAI,CAiBrF"}
@@ -0,0 +1,160 @@
1
+ import { multiaddr } from '@multiformats/multiaddr';
2
+ import { bases } from 'multiformats/basics';
3
+ import { base58btc } from 'multiformats/bases/base58';
4
+ import { create as createDigest, decode as decodeDigest } from 'multiformats/hashes/digest';
5
+ import { requireLength } from '../crypto/primitives.js';
6
+ import { ProtocolError } from '../errors.js';
7
+ import { validateRelayId, verifyRelay } from '../identity/neo.js';
8
+ import { array, bytes, defineCodec, integer, text } from '../protocol/codec.js';
9
+ import { NetworkContext, signingInput } from '../protocol/context.js';
10
+ import { encodeUtf8, equalBytes } from '../protocol/encoding.js';
11
+ import { requireSafeInteger } from '../protocol/json.js';
12
+ import { webEndpoint } from '../transport/endpoint.js';
13
+ export const relayDescriptorCodec = defineCodec({
14
+ relayId: { wire: 'relay_id', codec: text }, publicKey: { wire: 'public_key', codec: bytes },
15
+ endpoints: { wire: 'endpoints', codec: array(text) }, capabilities: { wire: 'capabilities', codec: array(text), optional: true },
16
+ expiresAt: { wire: 'expires_at', codec: integer }, relaySignature: { wire: 'relay_signature', codec: bytes },
17
+ }, 'meshline.relay.descriptor');
18
+ export function relayDescriptorInput(descriptor, context) {
19
+ return signingInput(relayDescriptorCodec.encode(descriptor), context, ['relay_signature']);
20
+ }
21
+ /** Normalized multihash identity, independent of a peer ID's allowed base/CID spelling. */
22
+ function peerIdentity(value) {
23
+ let hashBytes;
24
+ if (value.startsWith('Qm') || value.startsWith('1'))
25
+ hashBytes = base58btc.decode('z' + value);
26
+ else {
27
+ const base = Object.values(bases).find(base => value.startsWith(base.prefix));
28
+ if (!base)
29
+ throw new ProtocolError('invalid_peer', 'Unknown peer ID multibase.');
30
+ const cid = base.decode(value);
31
+ if (cid[0] !== 1 || cid[1] !== 0x72)
32
+ throw new ProtocolError('invalid_peer', 'Peer IDs require CIDv1 libp2p-key.');
33
+ hashBytes = cid.subarray(2);
34
+ }
35
+ const digest = decodeDigest(hashBytes);
36
+ if (!(digest.code === 0x12 && digest.size === 32 || digest.code === 0 && digest.size > 0 && digest.size <= 42)
37
+ || !equalBytes(hashBytes, createDigest(digest.code, digest.digest).bytes))
38
+ throw new ProtocolError('invalid_peer', 'Invalid or noncanonical peer multihash.');
39
+ return base58btc.encode(hashBytes).slice(1);
40
+ }
41
+ export function validateRelayEndpoint(endpoint) {
42
+ if (typeof endpoint !== 'string' || endpoint.length === 0)
43
+ throw new ProtocolError('invalid_endpoint', 'Relay endpoints must be nonempty strings.');
44
+ const candidate = endpoint.trimStart();
45
+ if (/^(https|wss):/i.test(candidate)) {
46
+ const url = webEndpoint(endpoint);
47
+ return { kind: url.protocol === 'https:' ? 'https' : 'wss' };
48
+ }
49
+ if (!candidate.startsWith('/') || !candidate.includes('/tcp/') && !candidate.endsWith('/tcp'))
50
+ return { kind: 'unknown' };
51
+ if (!endpoint.startsWith('/') || endpoint.endsWith('/') || endpoint.includes('//') || /[\s\p{Cc}]/u.test(endpoint))
52
+ throw new ProtocolError('invalid_endpoint', 'Malformed libp2p TCP endpoint.');
53
+ try {
54
+ const parts = endpoint.split('/');
55
+ if (parts.at(-2) !== 'p2p')
56
+ throw new Error('Endpoint must end with a peer ID.');
57
+ const peerId = peerIdentity(parts.at(-1));
58
+ for (let i = 0; i < parts.length; i++)
59
+ if (parts[i] === 'tcp' && !/^[0-9]+$/.test(parts[i + 1] ?? ''))
60
+ throw new Error('Invalid TCP port.');
61
+ const address = multiaddr(endpoint.slice(0, endpoint.lastIndexOf('/p2p/')) + '/p2p/' + peerId);
62
+ // Parsing textual components alone is lazy; encoding validates IP and port values.
63
+ void address.bytes;
64
+ const components = address.getComponents();
65
+ if (components.length < 3 || components[1].name !== 'tcp' || Number(components[1].value) <= 0
66
+ || components.filter(item => item.name === 'tcp').length !== 1 || components.filter(item => item.name === 'p2p').length !== 1
67
+ || components.at(-1).name !== 'p2p')
68
+ throw new Error('Expected host/TCP/.../peer endpoint.');
69
+ const host = components[0];
70
+ if (!['ip4', 'ip6', 'dns', 'dns4', 'dns6'].includes(host.name))
71
+ throw new Error('Invalid multiaddr host type.');
72
+ if (host.name.startsWith('dns')) {
73
+ const hostname = parseAbsoluteUrl(`https://${host.value}`).hostname;
74
+ if (hostname.startsWith('[') || /^[0-9.]+$/.test(hostname) || hostname.length > 255
75
+ || !hostname.replace(/\.$/, '').split('.').every(label => /^[a-z0-9_][a-z0-9_-]{0,62}$/i.test(label)))
76
+ throw new Error('Invalid DNS host.');
77
+ }
78
+ return { kind: 'libp2p-tcp', peerId };
79
+ }
80
+ catch (cause) {
81
+ throw new ProtocolError('invalid_endpoint', 'Invalid libp2p TCP relay endpoint.', { cause });
82
+ }
83
+ }
84
+ export function validateRelayDescriptor(descriptor, context, now) {
85
+ validateCompleteObject(relayDescriptorCodec.encode(descriptor));
86
+ requireSafeInteger(now, 0);
87
+ requireSafeInteger(descriptor.expiresAt, 0);
88
+ validateRelayId(descriptor.relayId);
89
+ requireLength(descriptor.publicKey, 33, 'Relay public key');
90
+ requireLength(descriptor.relaySignature, 64, 'Relay signature');
91
+ if (descriptor.expiresAt <= now)
92
+ throw new ProtocolError('expired_descriptor', 'The relay descriptor has expired.');
93
+ if (!Array.isArray(descriptor.endpoints) || descriptor.endpoints.length === 0)
94
+ throw new ProtocolError('invalid_endpoint', 'Relay endpoints must be a nonempty array.');
95
+ const endpoints = new Set();
96
+ let hasHttps = false;
97
+ let peer;
98
+ for (const endpoint of descriptor.endpoints) {
99
+ if (endpoints.has(endpoint))
100
+ throw new ProtocolError('duplicate_endpoint', 'Relay endpoints cannot contain duplicates.');
101
+ endpoints.add(endpoint);
102
+ const validated = validateRelayEndpoint(endpoint);
103
+ if (validated.kind === 'https')
104
+ hasHttps = true;
105
+ if (validated.kind === 'libp2p-tcp') {
106
+ if (peer !== undefined && peer !== validated.peerId)
107
+ throw new ProtocolError('invalid_peer', 'All libp2p TCP endpoints must identify the same peer.');
108
+ peer = validated.peerId;
109
+ }
110
+ }
111
+ if (!hasHttps || peer === undefined)
112
+ throw new ProtocolError('missing_endpoint', 'A relay must advertise HTTPS and libp2p TCP endpoints.');
113
+ const capabilities = descriptor.capabilities ?? [];
114
+ if (!Array.isArray(capabilities) || capabilities.length > 64 || new Set(capabilities).size !== capabilities.length)
115
+ throw new ProtocolError('invalid_capabilities', 'Capabilities must be distinct and contain at most 64 entries.');
116
+ for (const value of capabilities)
117
+ if (value.length === 0 || encodeUtf8(value).length > 128)
118
+ throw new ProtocolError('invalid_capabilities', 'Capabilities must contain 1 to 128 UTF-8 bytes.');
119
+ if (!verifyRelay(descriptor.relayId, descriptor.publicKey, relayDescriptorInput(descriptor, context), descriptor.relaySignature))
120
+ throw new ProtocolError('invalid_signature', 'The descriptor signature does not identify this relay.');
121
+ }
122
+ export const relayLimitsCodec = defineCodec({
123
+ messageRetention: { wire: 'message_retention', codec: integer },
124
+ channelTimelineRetention: { wire: 'channel_timeline_retention', codec: integer, optional: true },
125
+ maxChannelSubscriptions: { wire: 'max_channel_subscriptions', codec: integer, optional: true },
126
+ groupMessageRetention: { wire: 'group_message_retention', codec: integer, optional: true },
127
+ maxGroupMembers: { wire: 'max_group_members', codec: integer, optional: true },
128
+ maxGroupSubscriptions: { wire: 'max_group_subscriptions', codec: integer, optional: true },
129
+ maxGroupInviteTtl: { wire: 'max_group_invite_ttl', codec: integer, optional: true },
130
+ });
131
+ export const relayInfoCodec = defineCodec({
132
+ relayId: { wire: 'relay_id', codec: text }, name: { wire: 'name', codec: text }, serverTime: { wire: 'server_time', codec: integer }, limits: { wire: 'limits', codec: relayLimitsCodec },
133
+ });
134
+ export function validateRelayInfo(info, descriptor) {
135
+ validateCompleteObject(relayInfoCodec.encode(info));
136
+ validateRelayId(info.relayId);
137
+ requireSafeInteger(info.serverTime, 0);
138
+ if (info.name.trim().length === 0 || encodeUtf8(info.name).length > 256)
139
+ throw new ProtocolError('invalid_name', 'Relay name must be nonblank and at most 256 UTF-8 bytes.');
140
+ requireSafeInteger(info.limits.messageRetention, 1);
141
+ for (const value of [info.limits.channelTimelineRetention, info.limits.groupMessageRetention, info.limits.maxGroupMembers, info.limits.maxGroupInviteTtl])
142
+ if (value !== undefined)
143
+ requireSafeInteger(value, 1);
144
+ for (const value of [info.limits.maxChannelSubscriptions, info.limits.maxGroupSubscriptions])
145
+ if (value !== undefined)
146
+ requireSafeInteger(value, 0);
147
+ if (descriptor) {
148
+ if (info.relayId !== descriptor.relayId)
149
+ throw new ProtocolError('invalid_identity', 'Relay info belongs to a different relay.');
150
+ const sockets = descriptor.endpoints.some(endpoint => endpoint.startsWith('wss://'));
151
+ const limits = info.limits;
152
+ if (descriptor.capabilities?.includes('channel.host.v1') && (limits.channelTimelineRetention === undefined || sockets && limits.maxChannelSubscriptions === undefined)
153
+ || descriptor.capabilities?.includes('group.host.v1') && (limits.groupMessageRetention === undefined || limits.maxGroupMembers === undefined
154
+ || limits.maxGroupInviteTtl === undefined || sockets && limits.maxGroupSubscriptions === undefined))
155
+ throw new ProtocolError('missing_limits', 'Relay info omits limits required by its advertised capabilities.');
156
+ }
157
+ }
158
+ import { validateCompleteObject } from '../protocol/validation.js';
159
+ import { parseAbsoluteUrl } from '../runtime/url.js';
160
+ //# sourceMappingURL=relay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/models/relay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { type JsonObject, type JsonValue } from './json.js';
2
+ /** Unknown wire fields remain distinct from the application's camelCase members. */
3
+ export interface ExtensibleModel {
4
+ readonly additionalProperties?: JsonObject;
5
+ }
6
+ /** A model codec enforces wire representation; domain validators enforce authorization. */
7
+ export interface ProtocolCodec<T> {
8
+ decode(value: JsonValue): T;
9
+ encode(value: T): JsonObject;
10
+ parse(input: string | Uint8Array): T;
11
+ stringify(value: T): string;
12
+ }
13
+ export interface ValueCodec<T> {
14
+ decode(value: JsonValue): T;
15
+ encode(value: T): JsonValue;
16
+ }
17
+ export declare const text: ValueCodec<string>;
18
+ export declare const integer: ValueCodec<number>;
19
+ export declare const boolean: ValueCodec<boolean>;
20
+ export declare const bytes: ValueCodec<Uint8Array>;
21
+ export declare function array<T>(item: ValueCodec<T>): ValueCodec<readonly T[]>;
22
+ export declare function dictionary<T>(item: ValueCodec<T>): ValueCodec<Readonly<Record<string, T>>>;
23
+ export declare function enumeration<const T extends string>(...values: T[]): ValueCodec<T>;
24
+ export interface Field<T> {
25
+ readonly wire: string;
26
+ readonly codec: ValueCodec<T>;
27
+ readonly optional?: boolean;
28
+ readonly nullable?: boolean;
29
+ }
30
+ type Fields<T> = {
31
+ [K in Exclude<keyof T, 'additionalProperties'>]-?: Field<Exclude<T[K], null | undefined>>;
32
+ };
33
+ /** Creates an explicit mapping without guessing wire names or discarding signed extensions. */
34
+ export declare function defineCodec<T extends ExtensibleModel>(fields: Fields<T>, type?: string): ProtocolCodec<T>;
35
+ export {};
36
+ //# sourceMappingURL=codec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/protocol/codec.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+D,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAEzH,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAAG,QAAQ,CAAC,oBAAoB,CAAC,EAAE,UAAU,CAAA;CAAE;AAE/E,2FAA2F;AAC3F,MAAM,WAAW,aAAa,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,UAAU,CAAC;IAC7B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,CAAC,CAAC;IACrC,SAAS,CAAC,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,MAAM,CAAC,KAAK,EAAE,SAAS,GAAG,CAAC,CAAC;IAC5B,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;CAC/B;AAED,eAAO,MAAM,IAAI,EAAE,UAAU,CAAC,MAAM,CAMnC,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,UAAU,CAAC,MAAM,CAGtC,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,UAAU,CAAC,OAAO,CAMvC,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,UAAU,CAAC,UAAU,CAMxC,CAAC;AAEF,wBAAgB,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC,CAWtE;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAc1F;AAED,wBAAgB,WAAW,CAAC,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAQjF;AAED,MAAM,WAAW,KAAK,CAAC,CAAC;IAAI,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE;AAC5I,KAAK,MAAM,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC;CAAE,CAAC;AAE/G,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,CAAC,SAAS,eAAe,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,CAmDzG"}