@mt-tl/server 0.1.0

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 (293) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -0
  3. package/dist/auth/handshake.d.ts +35 -0
  4. package/dist/auth/handshake.d.ts.map +1 -0
  5. package/dist/auth/handshake.js +208 -0
  6. package/dist/auth/handshake.js.map +1 -0
  7. package/dist/auth/nonce-store.d.ts +22 -0
  8. package/dist/auth/nonce-store.d.ts.map +1 -0
  9. package/dist/auth/nonce-store.js +23 -0
  10. package/dist/auth/nonce-store.js.map +1 -0
  11. package/dist/bootstrap.d.ts +36 -0
  12. package/dist/bootstrap.d.ts.map +1 -0
  13. package/dist/bootstrap.js +82 -0
  14. package/dist/bootstrap.js.map +1 -0
  15. package/dist/config.d.ts +103 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +2 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/core/context.d.ts +57 -0
  20. package/dist/core/context.d.ts.map +1 -0
  21. package/dist/core/context.js +27 -0
  22. package/dist/core/context.js.map +1 -0
  23. package/dist/core/errors.d.ts +33 -0
  24. package/dist/core/errors.d.ts.map +1 -0
  25. package/dist/core/errors.js +47 -0
  26. package/dist/core/errors.js.map +1 -0
  27. package/dist/core/index.d.ts +5 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +5 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/rpc.d.ts +83 -0
  32. package/dist/core/rpc.d.ts.map +1 -0
  33. package/dist/core/rpc.js +102 -0
  34. package/dist/core/rpc.js.map +1 -0
  35. package/dist/core/updates.d.ts +56 -0
  36. package/dist/core/updates.d.ts.map +1 -0
  37. package/dist/core/updates.js +34 -0
  38. package/dist/core/updates.js.map +1 -0
  39. package/dist/create-server.d.ts +89 -0
  40. package/dist/create-server.d.ts.map +1 -0
  41. package/dist/create-server.js +109 -0
  42. package/dist/create-server.js.map +1 -0
  43. package/dist/crypto/aes-ige.d.ts +3 -0
  44. package/dist/crypto/aes-ige.d.ts.map +1 -0
  45. package/dist/crypto/aes-ige.js +55 -0
  46. package/dist/crypto/aes-ige.js.map +1 -0
  47. package/dist/crypto/dh.d.ts +21 -0
  48. package/dist/crypto/dh.d.ts.map +1 -0
  49. package/dist/crypto/dh.js +99 -0
  50. package/dist/crypto/dh.js.map +1 -0
  51. package/dist/crypto/hashes.d.ts +6 -0
  52. package/dist/crypto/hashes.d.ts.map +1 -0
  53. package/dist/crypto/hashes.js +14 -0
  54. package/dist/crypto/hashes.js.map +1 -0
  55. package/dist/crypto/msg-key.d.ts +15 -0
  56. package/dist/crypto/msg-key.d.ts.map +1 -0
  57. package/dist/crypto/msg-key.js +24 -0
  58. package/dist/crypto/msg-key.js.map +1 -0
  59. package/dist/crypto/rsa.d.ts +27 -0
  60. package/dist/crypto/rsa.d.ts.map +1 -0
  61. package/dist/crypto/rsa.js +50 -0
  62. package/dist/crypto/rsa.js.map +1 -0
  63. package/dist/dispatch/dispatcher.d.ts +72 -0
  64. package/dist/dispatch/dispatcher.d.ts.map +1 -0
  65. package/dist/dispatch/dispatcher.js +503 -0
  66. package/dist/dispatch/dispatcher.js.map +1 -0
  67. package/dist/dispatch/forwarders/in-process.d.ts +12 -0
  68. package/dist/dispatch/forwarders/in-process.d.ts.map +1 -0
  69. package/dist/dispatch/forwarders/in-process.js +15 -0
  70. package/dist/dispatch/forwarders/in-process.js.map +1 -0
  71. package/dist/dispatch/forwarders/print.d.ts +14 -0
  72. package/dist/dispatch/forwarders/print.d.ts.map +1 -0
  73. package/dist/dispatch/forwarders/print.js +23 -0
  74. package/dist/dispatch/forwarders/print.js.map +1 -0
  75. package/dist/dispatch/rpc-forwarder.d.ts +14 -0
  76. package/dist/dispatch/rpc-forwarder.d.ts.map +1 -0
  77. package/dist/dispatch/rpc-forwarder.js +2 -0
  78. package/dist/dispatch/rpc-forwarder.js.map +1 -0
  79. package/dist/dispatch/types.d.ts +32 -0
  80. package/dist/dispatch/types.d.ts.map +1 -0
  81. package/dist/dispatch/types.js +23 -0
  82. package/dist/dispatch/types.js.map +1 -0
  83. package/dist/gateway.d.ts +57 -0
  84. package/dist/gateway.d.ts.map +1 -0
  85. package/dist/gateway.js +150 -0
  86. package/dist/gateway.js.map +1 -0
  87. package/dist/index.d.ts +7 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +25 -0
  90. package/dist/index.js.map +1 -0
  91. package/dist/lib.d.ts +12 -0
  92. package/dist/lib.d.ts.map +1 -0
  93. package/dist/lib.js +13 -0
  94. package/dist/lib.js.map +1 -0
  95. package/dist/server/message-pipeline.d.ts +57 -0
  96. package/dist/server/message-pipeline.d.ts.map +1 -0
  97. package/dist/server/message-pipeline.js +199 -0
  98. package/dist/server/message-pipeline.js.map +1 -0
  99. package/dist/session/inbound-tracker.d.ts +118 -0
  100. package/dist/session/inbound-tracker.d.ts.map +1 -0
  101. package/dist/session/inbound-tracker.js +170 -0
  102. package/dist/session/inbound-tracker.js.map +1 -0
  103. package/dist/session/message-id.d.ts +19 -0
  104. package/dist/session/message-id.d.ts.map +1 -0
  105. package/dist/session/message-id.js +30 -0
  106. package/dist/session/message-id.js.map +1 -0
  107. package/dist/session/salts.d.ts +51 -0
  108. package/dist/session/salts.d.ts.map +1 -0
  109. package/dist/session/salts.js +132 -0
  110. package/dist/session/salts.js.map +1 -0
  111. package/dist/session/session-manager.d.ts +18 -0
  112. package/dist/session/session-manager.d.ts.map +1 -0
  113. package/dist/session/session-manager.js +43 -0
  114. package/dist/session/session-manager.js.map +1 -0
  115. package/dist/storage/index.d.ts +14 -0
  116. package/dist/storage/index.d.ts.map +1 -0
  117. package/dist/storage/index.js +16 -0
  118. package/dist/storage/index.js.map +1 -0
  119. package/dist/storage/memory.d.ts +3 -0
  120. package/dist/storage/memory.d.ts.map +1 -0
  121. package/dist/storage/memory.js +91 -0
  122. package/dist/storage/memory.js.map +1 -0
  123. package/dist/storage/mongo.d.ts +3 -0
  124. package/dist/storage/mongo.d.ts.map +1 -0
  125. package/dist/storage/mongo.js +175 -0
  126. package/dist/storage/mongo.js.map +1 -0
  127. package/dist/storage/types.d.ts +85 -0
  128. package/dist/storage/types.d.ts.map +1 -0
  129. package/dist/storage/types.js +3 -0
  130. package/dist/storage/types.js.map +1 -0
  131. package/dist/testkit.d.ts +11 -0
  132. package/dist/testkit.d.ts.map +1 -0
  133. package/dist/testkit.js +17 -0
  134. package/dist/testkit.js.map +1 -0
  135. package/dist/tl/codec.d.ts +37 -0
  136. package/dist/tl/codec.d.ts.map +1 -0
  137. package/dist/tl/codec.js +297 -0
  138. package/dist/tl/codec.js.map +1 -0
  139. package/dist/tl/layered-registry.d.ts +29 -0
  140. package/dist/tl/layered-registry.d.ts.map +1 -0
  141. package/dist/tl/layered-registry.js +118 -0
  142. package/dist/tl/layered-registry.js.map +1 -0
  143. package/dist/tl/protocol.d.ts +126 -0
  144. package/dist/tl/protocol.d.ts.map +1 -0
  145. package/dist/tl/protocol.js +22 -0
  146. package/dist/tl/protocol.js.map +1 -0
  147. package/dist/tl/reader.d.ts +30 -0
  148. package/dist/tl/reader.d.ts.map +1 -0
  149. package/dist/tl/reader.js +87 -0
  150. package/dist/tl/reader.js.map +1 -0
  151. package/dist/tl/registry.d.ts +39 -0
  152. package/dist/tl/registry.d.ts.map +1 -0
  153. package/dist/tl/registry.js +52 -0
  154. package/dist/tl/registry.js.map +1 -0
  155. package/dist/tl/writer.d.ts +24 -0
  156. package/dist/tl/writer.d.ts.map +1 -0
  157. package/dist/tl/writer.js +95 -0
  158. package/dist/tl/writer.js.map +1 -0
  159. package/dist/transport/connection-registry.d.ts +31 -0
  160. package/dist/transport/connection-registry.d.ts.map +1 -0
  161. package/dist/transport/connection-registry.js +84 -0
  162. package/dist/transport/connection-registry.js.map +1 -0
  163. package/dist/transport/connection.d.ts +62 -0
  164. package/dist/transport/connection.d.ts.map +1 -0
  165. package/dist/transport/connection.js +77 -0
  166. package/dist/transport/connection.js.map +1 -0
  167. package/dist/transport/framing.d.ts +39 -0
  168. package/dist/transport/framing.d.ts.map +1 -0
  169. package/dist/transport/framing.js +212 -0
  170. package/dist/transport/framing.js.map +1 -0
  171. package/dist/transport/proxy-protocol.d.ts +23 -0
  172. package/dist/transport/proxy-protocol.d.ts.map +1 -0
  173. package/dist/transport/proxy-protocol.js +108 -0
  174. package/dist/transport/proxy-protocol.js.map +1 -0
  175. package/dist/transport/server-common.d.ts +27 -0
  176. package/dist/transport/server-common.d.ts.map +1 -0
  177. package/dist/transport/server-common.js +27 -0
  178. package/dist/transport/server-common.js.map +1 -0
  179. package/dist/transport/tcp-server.d.ts +26 -0
  180. package/dist/transport/tcp-server.d.ts.map +1 -0
  181. package/dist/transport/tcp-server.js +91 -0
  182. package/dist/transport/tcp-server.js.map +1 -0
  183. package/dist/transport/ws-server.d.ts +19 -0
  184. package/dist/transport/ws-server.d.ts.map +1 -0
  185. package/dist/transport/ws-server.js +78 -0
  186. package/dist/transport/ws-server.js.map +1 -0
  187. package/dist/update-publisher.d.ts +34 -0
  188. package/dist/update-publisher.d.ts.map +1 -0
  189. package/dist/update-publisher.js +29 -0
  190. package/dist/update-publisher.js.map +1 -0
  191. package/dist/updates/mongo-update-log.d.ts +13 -0
  192. package/dist/updates/mongo-update-log.d.ts.map +1 -0
  193. package/dist/updates/mongo-update-log.js +39 -0
  194. package/dist/updates/mongo-update-log.js.map +1 -0
  195. package/dist/updates/presence-binder.d.ts +29 -0
  196. package/dist/updates/presence-binder.d.ts.map +1 -0
  197. package/dist/updates/presence-binder.js +36 -0
  198. package/dist/updates/presence-binder.js.map +1 -0
  199. package/dist/updates/presence.d.ts +31 -0
  200. package/dist/updates/presence.d.ts.map +1 -0
  201. package/dist/updates/presence.js +44 -0
  202. package/dist/updates/presence.js.map +1 -0
  203. package/dist/updates/push.d.ts +25 -0
  204. package/dist/updates/push.d.ts.map +1 -0
  205. package/dist/updates/push.js +72 -0
  206. package/dist/updates/push.js.map +1 -0
  207. package/dist/updates/redis-bus.d.ts +45 -0
  208. package/dist/updates/redis-bus.d.ts.map +1 -0
  209. package/dist/updates/redis-bus.js +59 -0
  210. package/dist/updates/redis-bus.js.map +1 -0
  211. package/dist/updates/redis-presence.d.ts +43 -0
  212. package/dist/updates/redis-presence.d.ts.map +1 -0
  213. package/dist/updates/redis-presence.js +65 -0
  214. package/dist/updates/redis-presence.js.map +1 -0
  215. package/dist/updates/render.d.ts +16 -0
  216. package/dist/updates/render.d.ts.map +1 -0
  217. package/dist/updates/render.js +46 -0
  218. package/dist/updates/render.js.map +1 -0
  219. package/dist/updates/router.d.ts +27 -0
  220. package/dist/updates/router.d.ts.map +1 -0
  221. package/dist/updates/router.js +36 -0
  222. package/dist/updates/router.js.map +1 -0
  223. package/dist/updates/types.d.ts +23 -0
  224. package/dist/updates/types.d.ts.map +1 -0
  225. package/dist/updates/types.js +2 -0
  226. package/dist/updates/types.js.map +1 -0
  227. package/dist/updates/update-bus.d.ts +29 -0
  228. package/dist/updates/update-bus.d.ts.map +1 -0
  229. package/dist/updates/update-bus.js +24 -0
  230. package/dist/updates/update-bus.js.map +1 -0
  231. package/dist/util/bytes.d.ts +12 -0
  232. package/dist/util/bytes.d.ts.map +1 -0
  233. package/dist/util/bytes.js +46 -0
  234. package/dist/util/bytes.js.map +1 -0
  235. package/package.json +84 -0
  236. package/src/auth/handshake.ts +262 -0
  237. package/src/auth/nonce-store.ts +39 -0
  238. package/src/bootstrap.ts +114 -0
  239. package/src/config.ts +103 -0
  240. package/src/core/context.ts +94 -0
  241. package/src/core/errors.ts +52 -0
  242. package/src/core/index.ts +4 -0
  243. package/src/core/rpc.ts +165 -0
  244. package/src/core/updates.ts +69 -0
  245. package/src/create-server.ts +181 -0
  246. package/src/crypto/aes-ige.ts +57 -0
  247. package/src/crypto/dh.ts +101 -0
  248. package/src/crypto/hashes.ts +17 -0
  249. package/src/crypto/msg-key.ts +29 -0
  250. package/src/crypto/rsa.ts +70 -0
  251. package/src/dispatch/dispatcher.ts +586 -0
  252. package/src/dispatch/forwarders/in-process.ts +14 -0
  253. package/src/dispatch/forwarders/print.ts +22 -0
  254. package/src/dispatch/rpc-forwarder.ts +15 -0
  255. package/src/dispatch/types.ts +60 -0
  256. package/src/gateway.ts +214 -0
  257. package/src/index.ts +53 -0
  258. package/src/lib.ts +24 -0
  259. package/src/server/message-pipeline.ts +256 -0
  260. package/src/session/inbound-tracker.ts +221 -0
  261. package/src/session/message-id.ts +43 -0
  262. package/src/session/salts.ts +162 -0
  263. package/src/session/session-manager.ts +66 -0
  264. package/src/storage/index.ts +26 -0
  265. package/src/storage/memory.ts +101 -0
  266. package/src/storage/mongo.ts +215 -0
  267. package/src/storage/types.ts +92 -0
  268. package/src/testkit.ts +19 -0
  269. package/src/tl/codec.ts +292 -0
  270. package/src/tl/layered-registry.ts +132 -0
  271. package/src/tl/protocol.ts +146 -0
  272. package/src/tl/reader.ts +99 -0
  273. package/src/tl/registry.ts +78 -0
  274. package/src/tl/writer.ts +104 -0
  275. package/src/transport/connection-registry.ts +91 -0
  276. package/src/transport/connection.ts +113 -0
  277. package/src/transport/framing.ts +223 -0
  278. package/src/transport/proxy-protocol.ts +109 -0
  279. package/src/transport/server-common.ts +49 -0
  280. package/src/transport/tcp-server.ts +102 -0
  281. package/src/transport/ws-server.ts +94 -0
  282. package/src/update-publisher.ts +47 -0
  283. package/src/updates/mongo-update-log.ts +49 -0
  284. package/src/updates/presence-binder.ts +51 -0
  285. package/src/updates/presence.ts +61 -0
  286. package/src/updates/push.ts +90 -0
  287. package/src/updates/redis-bus.ts +86 -0
  288. package/src/updates/redis-presence.ts +87 -0
  289. package/src/updates/render.ts +53 -0
  290. package/src/updates/router.ts +52 -0
  291. package/src/updates/types.ts +24 -0
  292. package/src/updates/update-bus.ts +49 -0
  293. package/src/util/bytes.ts +49 -0
@@ -0,0 +1,503 @@
1
+ import { gunzipSync } from 'node:zlib';
2
+ import { TlReader } from '../tl/reader.js';
3
+ import { fromJson, toJson, MigrationRegistry } from '@mt-tl/tl';
4
+ import { replyToBadAccept } from './types.js';
5
+ import { messageClass } from '../session/inbound-tracker.js';
6
+ import { NoopPresenceBinder } from '../updates/presence-binder.js';
7
+ import { noopLogger } from '@mt-tl/tl';
8
+ const ID_GZIP_PACKED = 0x3072cfa1;
9
+ const ID_MSG_CONTAINER = 0x73f1f8dc;
10
+ /** Spec cap: a container carries at most 1024 messages. */
11
+ const CONTAINER_MAX_MESSAGES = 1024;
12
+ /** Managed `updates.getDifference`: max updates per response before slicing. */
13
+ const DIFF_SLICE = 100;
14
+ /** Managed `updates.getDifference`: gap beyond which we force a full resync (differenceTooLong). */
15
+ const DIFF_TOO_LONG = 5000;
16
+ /** Methods the engine answers itself when `updates.managed` (else forwarded to the app). */
17
+ const MANAGED_UPDATES = new Set(['updates.getState', 'updates.getDifference']);
18
+ /** Protocol/service predicates handled inside the gateway (never forwarded). */
19
+ const SERVICE = new Set([
20
+ 'ping',
21
+ 'ping_delay_disconnect',
22
+ 'msgs_ack',
23
+ 'msgs_state_req',
24
+ 'msgs_all_info',
25
+ 'msg_resend_req',
26
+ 'destroy_session',
27
+ 'destroy_auth_key',
28
+ 'get_future_salts',
29
+ 'rpc_drop_answer',
30
+ 'http_wait',
31
+ ]);
32
+ const WRAPPERS = new Set([
33
+ 'invokeWithLayer',
34
+ 'initConnection',
35
+ 'invokeWithoutUpdates',
36
+ 'invokeAfterMsg',
37
+ 'invokeAfterMsgs',
38
+ 'invokeWithMessagesRange',
39
+ 'invokeWithTakeout',
40
+ ]);
41
+ export class Dispatcher {
42
+ deps;
43
+ binder;
44
+ migrations;
45
+ logger;
46
+ checkSeqNo;
47
+ managedUpdates;
48
+ /** Built once from `deps.allowedApiIds`; undefined = whitelist disabled. */
49
+ allowedApiIds;
50
+ constructor(deps) {
51
+ this.deps = deps;
52
+ this.binder = deps.binder ?? new NoopPresenceBinder();
53
+ this.migrations = deps.migrations ?? new MigrationRegistry();
54
+ this.logger = deps.logger ?? noopLogger;
55
+ this.checkSeqNo = !deps.disableSeqNoCheck;
56
+ this.managedUpdates = !!deps.managedUpdates && !!deps.updateLog;
57
+ this.allowedApiIds = deps.allowedApiIds ? new Set(deps.allowedApiIds) : undefined;
58
+ }
59
+ /** Entry point: a raw message body (after the encrypted envelope). */
60
+ async dispatchPayload(payload, ctx, conn) {
61
+ if (payload.length < 4)
62
+ return;
63
+ const id = payload.readUInt32LE(0);
64
+ if (id === ID_GZIP_PACKED) {
65
+ const r = new TlReader(payload);
66
+ r.readUInt32();
67
+ const inflated = gunzipSync(r.readBytes());
68
+ return this.dispatchPayload(inflated, ctx, conn);
69
+ }
70
+ if (id === ID_MSG_CONTAINER) {
71
+ // Parse the whole container before dispatching anything: a malformed one
72
+ // (bad count / inner length overflow) is rejected atomically with
73
+ // bad_msg_notification code 64 ("invalid container"), nothing processed.
74
+ let inners;
75
+ try {
76
+ inners = parseContainer(payload);
77
+ }
78
+ catch {
79
+ this.logger.warn('container.invalid', {
80
+ authKeyId: conn.ctx.authKeyId,
81
+ layer: conn.ctx.apiLayer,
82
+ bytes: payload.length,
83
+ });
84
+ this.deps.responder.sendEncrypted(conn, {
85
+ _: 'bad_msg_notification',
86
+ bad_msg_id: ctx.msgId,
87
+ bad_msg_seqno: ctx.seqNo,
88
+ error_code: 64,
89
+ }, { contentRelated: false });
90
+ return;
91
+ }
92
+ for (const { msgId, seqNo, inner } of inners) {
93
+ // Validate each inner message like the outer envelope, EXCEPT ordering
94
+ // (code 32): a resend container legitimately carries old seqnos. A bad
95
+ // inner gets its own bad_msg_notification / msg_detailed_info and is
96
+ // skipped; the others still run.
97
+ const check = conn.tracker.accept(msgId, seqNo, {
98
+ ...messageClass(inner),
99
+ checkSeqNo: this.checkSeqNo,
100
+ checkOrder: false,
101
+ });
102
+ if (!check.ok) {
103
+ replyToBadAccept(this.deps.responder, conn, check, msgId, seqNo);
104
+ continue;
105
+ }
106
+ await this.dispatchPayload(inner, { ...ctx, msgId, seqNo }, conn);
107
+ }
108
+ return;
109
+ }
110
+ let body;
111
+ try {
112
+ body = this.deps.codec.decode(payload);
113
+ }
114
+ catch {
115
+ // Unknown/undecodable type — ack-by-silence, but log so it's visible.
116
+ this.logger.warn('decode.fail', {
117
+ id: '0x' + id.toString(16).padStart(8, '0'),
118
+ authKeyId: conn.ctx.authKeyId,
119
+ sessionId: conn.ctx.sessionId,
120
+ layer: conn.ctx.apiLayer,
121
+ bytes: payload.length,
122
+ });
123
+ return;
124
+ }
125
+ await this.dispatchObject(body, ctx, conn);
126
+ }
127
+ async dispatchObject(body, ctx, conn) {
128
+ const name = body._;
129
+ this.logger.debug('msg', {
130
+ method: name,
131
+ authKeyId: conn.ctx.authKeyId,
132
+ sessionId: conn.ctx.sessionId,
133
+ layer: conn.ctx.apiLayer,
134
+ });
135
+ if (WRAPPERS.has(name)) {
136
+ if (name === 'invokeWithLayer' && typeof body.layer === 'number') {
137
+ conn.ctx.apiLayer = body.layer;
138
+ if (conn.ctx.sessionId !== undefined) {
139
+ await this.deps.storage.sessions.update(conn.ctx.sessionId, { apiLayer: body.layer });
140
+ }
141
+ }
142
+ else if (name === 'initConnection') {
143
+ const rejected = await this.handleInitConnection(body, ctx, conn);
144
+ if (rejected)
145
+ return;
146
+ }
147
+ else if (name === 'invokeWithoutUpdates') {
148
+ // Client opts this connection out of server-push (PushService skips it).
149
+ conn.ctx.noUpdates = true;
150
+ }
151
+ const query = body.query;
152
+ if (query && typeof query === 'object' && '_' in query) {
153
+ return this.dispatchObject(query, ctx, conn);
154
+ }
155
+ return;
156
+ }
157
+ if (SERVICE.has(name))
158
+ return this.handleService(body, ctx, conn);
159
+ if (this.managedUpdates && MANAGED_UPDATES.has(name)) {
160
+ return this.handleManagedUpdate(body, ctx, conn);
161
+ }
162
+ return this.forwardBusiness(body, ctx, conn);
163
+ }
164
+ /**
165
+ * Process an `initConnection` envelope: optionally enforce the `api_id`
166
+ * whitelist, then capture the device/app fields onto the connection and
167
+ * persist them to the auth key's meta (the per-device source of truth; an
168
+ * auth key is one app install, so this is stable per key, not per session).
169
+ * Returns `true` when the connection was rejected (caller must not dispatch
170
+ * the wrapped query).
171
+ */
172
+ async handleInitConnection(body, ctx, conn) {
173
+ const apiId = typeof body.api_id === 'number' ? body.api_id : undefined;
174
+ if (this.allowedApiIds && (apiId === undefined || !this.allowedApiIds.has(apiId))) {
175
+ this.logger.warn('initConnection.rejected', {
176
+ authKeyId: conn.ctx.authKeyId,
177
+ sessionId: conn.ctx.sessionId,
178
+ apiId,
179
+ });
180
+ this.sendRpcError(conn, ctx.msgId, 400, 'API_ID_INVALID');
181
+ return true;
182
+ }
183
+ const meta = {
184
+ apiId,
185
+ deviceModel: asString(body.device_model),
186
+ systemVersion: asString(body.system_version),
187
+ appVersion: asString(body.app_version),
188
+ systemLangCode: asString(body.system_lang_code),
189
+ langCode: asString(body.lang_code),
190
+ };
191
+ conn.ctx.apiId = meta.apiId;
192
+ conn.ctx.deviceModel = meta.deviceModel;
193
+ conn.ctx.systemVersion = meta.systemVersion;
194
+ conn.ctx.appVersion = meta.appVersion;
195
+ conn.ctx.systemLangCode = meta.systemLangCode;
196
+ conn.ctx.langCode = meta.langCode;
197
+ if (conn.ctx.authKeyId !== undefined) {
198
+ await this.deps.storage.authKeys.updateMeta(conn.ctx.authKeyId, meta);
199
+ }
200
+ return false;
201
+ }
202
+ /**
203
+ * Engine-owned `updates.getState` / `updates.getDifference` (when
204
+ * `config.updates.managed`). Common pts sequence only — qts/seq/channels are 0.
205
+ * Updates are returned in `other_updates`; the durable {@link UpdateLog}
206
+ * supplies pts. Auth-gated like a normal `auth: true` method.
207
+ */
208
+ async handleManagedUpdate(body, ctx, conn) {
209
+ const log = this.deps.updateLog;
210
+ const subject = conn.ctx.subject;
211
+ if (subject === undefined)
212
+ return this.sendRpcError(conn, ctx.msgId, 401, 'AUTH_KEY_UNREGISTERED');
213
+ const date = Math.floor(Date.now() / 1000);
214
+ const state = (pts) => ({
215
+ _: 'updates.state',
216
+ pts,
217
+ qts: 0,
218
+ date,
219
+ seq: 0,
220
+ unread_count: 0,
221
+ });
222
+ if (body._ === 'updates.getState') {
223
+ return this.sendRpcResult(conn, ctx.msgId, state(await log.currentPts(subject)));
224
+ }
225
+ // updates.getDifference
226
+ const sincePts = Number(body.pts ?? 0);
227
+ const current = await log.currentPts(subject);
228
+ if (sincePts >= current) {
229
+ return this.sendRpcResult(conn, ctx.msgId, { _: 'updates.differenceEmpty', date, seq: 0 });
230
+ }
231
+ if (current - sincePts > DIFF_TOO_LONG) {
232
+ return this.sendRpcResult(conn, ctx.msgId, { _: 'updates.differenceTooLong', pts: current });
233
+ }
234
+ const all = await log.since(subject, sincePts);
235
+ const sliced = all.length > DIFF_SLICE;
236
+ const page = sliced ? all.slice(0, DIFF_SLICE) : all;
237
+ const lastPts = page.at(-1)?.pts ?? current;
238
+ const common = {
239
+ new_messages: [],
240
+ new_encrypted_messages: [],
241
+ other_updates: page.map(u => u.update),
242
+ chats: [],
243
+ users: [],
244
+ };
245
+ return this.sendRpcResult(conn, ctx.msgId, sliced
246
+ ? { _: 'updates.differenceSlice', ...common, intermediate_state: state(lastPts) }
247
+ : { _: 'updates.difference', ...common, state: state(lastPts) });
248
+ }
249
+ async handleService(body, ctx, conn) {
250
+ const { responder } = this.deps;
251
+ switch (body._) {
252
+ case 'ping_delay_disconnect':
253
+ // Close the connection after `disconnect_delay`s of inactivity unless
254
+ // reset; then respond like a normal ping.
255
+ conn.armDisconnect(Number(body.disconnect_delay ?? 0));
256
+ // falls through
257
+ case 'ping':
258
+ responder.sendEncrypted(conn, { _: 'pong', msg_id: ctx.msgId, ping_id: body.ping_id }, { contentRelated: false });
259
+ return;
260
+ case 'msgs_state_req':
261
+ case 'msg_resend_req': {
262
+ // We keep no sent-message store to re-send, so per spec a msg_resend_req
263
+ // is answered like a msgs_state_req: report each requested id's state.
264
+ const ids = body.msg_ids ?? [];
265
+ responder.sendEncrypted(conn, { _: 'msgs_state_info', req_msg_id: ctx.msgId, info: conn.tracker.stateOf(ids) }, { contentRelated: false });
266
+ return;
267
+ }
268
+ case 'destroy_auth_key': {
269
+ // Permanent key destruction (logout). Block the key so any further use
270
+ // is rejected; the response is sent before this message's key is dropped.
271
+ await this.deps.storage.authKeys.setBlocked(ctx.authKeyId, true);
272
+ responder.sendEncrypted(conn, { _: 'destroy_auth_key_ok' }, { contentRelated: false });
273
+ return;
274
+ }
275
+ case 'destroy_session': {
276
+ // Tear down the stored session if it belongs to this auth key; the
277
+ // client uses this to forget another session under the same key.
278
+ const sessionId = body.session_id;
279
+ const existing = await this.deps.storage.sessions.get(sessionId);
280
+ const owned = !!existing && existing.authKeyId === ctx.authKeyId;
281
+ if (owned)
282
+ await this.deps.storage.sessions.delete(sessionId);
283
+ responder.sendEncrypted(conn, { _: owned ? 'destroy_session_ok' : 'destroy_session_none', session_id: sessionId }, { contentRelated: false });
284
+ return;
285
+ }
286
+ case 'get_future_salts': {
287
+ // Return the next `num` scheduled salts (clamped) with true windows,
288
+ // minting more if the schedule is short.
289
+ const num = Math.min(64, Math.max(1, Number(body.num ?? 1)));
290
+ const authKeyId = conn.ctx.authKeyId;
291
+ const scheduled = authKeyId !== undefined ? await this.deps.saltService.future(authKeyId, num) : [];
292
+ responder.sendEncrypted(conn, {
293
+ _: 'future_salts',
294
+ req_msg_id: ctx.msgId,
295
+ now: Math.floor(Date.now() / 1000),
296
+ salts: scheduled.map(s => ({
297
+ _: 'future_salt',
298
+ valid_since: s.validSince,
299
+ valid_until: s.validUntil,
300
+ salt: s.salt,
301
+ })),
302
+ }, { contentRelated: false });
303
+ return;
304
+ }
305
+ case 'rpc_drop_answer':
306
+ // Packets are processed serially per connection (see transport `pump`)
307
+ // and answers are sent immediately (no outgoing queue to drop from), so
308
+ // by the time a drop arrives its target RPC has already been answered.
309
+ // `rpc_answer_unknown` ("no memory of req_msg_id / already responded")
310
+ // is the spec-correct reply here. The RpcDropAnswer is wrapped in an
311
+ // rpc_result (and acknowledged) like any RPC response — see
312
+ // docs/internals/protocol-compliance.md.
313
+ responder.sendEncrypted(conn, {
314
+ _: 'rpc_result',
315
+ req_msg_id: ctx.msgId,
316
+ result: { _: 'rpc_answer_unknown' },
317
+ });
318
+ return;
319
+ case 'msgs_ack':
320
+ // Client acknowledgments of server→client messages. We never retransmit,
321
+ // so there is no resend queue for an ack to clear — nothing to do.
322
+ return;
323
+ case 'msgs_all_info':
324
+ // Voluntary status of our messages from the client; informational and
325
+ // not requiring acknowledgment — nothing to do (we don't retransmit).
326
+ return;
327
+ case 'http_wait':
328
+ default:
329
+ return;
330
+ }
331
+ }
332
+ async forwardBusiness(body, ctx, conn) {
333
+ // Identity carried on every line for this request: reqId (the client's
334
+ // msg_id) + authKeyId/sessionId/subject/layer. Matches the per-request
335
+ // `ctx.log` child the handler layer binds, so engine ⇄ handler lines join.
336
+ // device/ip are added only once known (deviceModel after initConnection) so
337
+ // they don't noise pre-init lines.
338
+ const logBase = {
339
+ reqId: ctx.msgId,
340
+ method: body._,
341
+ subject: conn.ctx.subject,
342
+ authKeyId: ctx.authKeyId,
343
+ sessionId: ctx.sessionId,
344
+ layer: conn.ctx.apiLayer,
345
+ ...(conn.ctx.deviceModel ? { deviceModel: conn.ctx.deviceModel } : {}),
346
+ ...(conn.ctx.remoteAddress ? { ip: conn.ctx.remoteAddress } : {}),
347
+ };
348
+ const def = this.deps.registry.getByName(body._);
349
+ if (!def || def.kind !== 'method') {
350
+ // Not a known business method — surface as an rpc_error.
351
+ this.logger.warn('rpc.unknown', logBase);
352
+ return this.sendRpcError(conn, ctx.msgId, 400, 'METHOD_NOT_FOUND');
353
+ }
354
+ // Normalize older-layer input up to the canonical shape before forwarding.
355
+ const canonical = this.migrations.up(body, conn.ctx.apiLayer);
356
+ const params = paramsToJson(canonical, this.deps.registry);
357
+ // Full incoming payload at debug — "what came in" (structured in JSON mode).
358
+ this.logger.debug('rpc.params', { ...logBase, params });
359
+ const rpcCtx = {
360
+ sessionId: ctx.sessionId.toString(),
361
+ authKeyId: ctx.authKeyId.toString(),
362
+ subject: conn.ctx.subject,
363
+ apiLayer: conn.ctx.apiLayer,
364
+ apiId: conn.ctx.apiId,
365
+ deviceModel: conn.ctx.deviceModel,
366
+ systemVersion: conn.ctx.systemVersion,
367
+ appVersion: conn.ctx.appVersion,
368
+ langCode: conn.ctx.langCode,
369
+ ip: conn.ctx.remoteAddress,
370
+ };
371
+ const startedAt = Date.now();
372
+ let res;
373
+ try {
374
+ res = await this.deps.forwarder.forward({
375
+ id: ctx.msgId.toString(),
376
+ method: body._,
377
+ params,
378
+ context: rpcCtx,
379
+ });
380
+ }
381
+ catch (err) {
382
+ this.logger.error('rpc.fail', { ...logBase, ms: Date.now() - startedAt, err });
383
+ return this.sendRpcError(conn, ctx.msgId, 500, 'INTERNAL');
384
+ }
385
+ const ms = Date.now() - startedAt;
386
+ if (res.effects?.length)
387
+ await this.applyEffects(conn, ctx, res.effects);
388
+ if (res.error) {
389
+ this.logger.info('rpc', {
390
+ ...logBase,
391
+ ms,
392
+ status: 'error',
393
+ code: res.error.code,
394
+ error: res.error.message,
395
+ });
396
+ return this.sendRpcError(conn, ctx.msgId, res.error.code, res.error.message);
397
+ }
398
+ if (res.result !== undefined) {
399
+ this.logger.info('rpc', { ...logBase, ms, status: 'ok' });
400
+ // Full outgoing payload at debug — "what went out".
401
+ this.logger.debug('rpc.result', { ...logBase, result: res.result });
402
+ return this.sendRpcResult(conn, ctx.msgId, res.result);
403
+ }
404
+ // Neither result nor error — malformed envelope.
405
+ this.logger.error('rpc.malformed', { ...logBase, ms });
406
+ return this.sendRpcError(conn, ctx.msgId, 500, 'INTERNAL');
407
+ }
408
+ /** Apply backend-requested mutations to gateway-owned auth/session state. */
409
+ async applyEffects(conn, ctx, effects) {
410
+ for (const effect of effects) {
411
+ switch (effect.type) {
412
+ case 'bindUser':
413
+ await this.deps.storage.authKeys.bindUser(ctx.authKeyId, effect.subject);
414
+ conn.ctx.subject = effect.subject;
415
+ await this.patchSession(conn, { subject: effect.subject });
416
+ this.binder.bind(conn, effect.subject);
417
+ // A user logged in on this auth key (device login).
418
+ this.logger.info('user.bind', { subject: effect.subject, authKeyId: ctx.authKeyId });
419
+ break;
420
+ case 'unbindUser':
421
+ await this.deps.storage.authKeys.bindUser(ctx.authKeyId, null);
422
+ conn.ctx.subject = undefined;
423
+ this.binder.unbind(conn);
424
+ this.logger.info('user.unbind', { authKeyId: ctx.authKeyId });
425
+ break;
426
+ case 'revokeKey':
427
+ await this.deps.storage.authKeys.setBlocked(ctx.authKeyId, true);
428
+ this.logger.info('authkey.revoke', { authKeyId: ctx.authKeyId });
429
+ break;
430
+ }
431
+ }
432
+ }
433
+ async patchSession(conn, patch) {
434
+ if (conn.ctx.sessionId !== undefined) {
435
+ await this.deps.storage.sessions.update(conn.ctx.sessionId, patch);
436
+ }
437
+ }
438
+ sendRpcResult(conn, reqMsgId, result) {
439
+ // Render the canonical result down to the client's layer before encoding.
440
+ const tl = this.migrations.down(fromJson(result), conn.ctx.apiLayer);
441
+ // rpc_result.result must be a boxed object, Bool, or Vector.
442
+ if (typeof tl !== 'boolean' && !Array.isArray(tl) && !(tl && typeof tl === 'object' && '_' in tl)) {
443
+ return this.sendRpcError(conn, reqMsgId, 500, 'INVALID_RESULT');
444
+ }
445
+ this.deps.responder.sendEncrypted(conn, {
446
+ _: 'rpc_result',
447
+ req_msg_id: reqMsgId,
448
+ result: tl,
449
+ });
450
+ }
451
+ sendRpcError(conn, reqMsgId, code, message) {
452
+ this.deps.responder.sendEncrypted(conn, {
453
+ _: 'rpc_result',
454
+ req_msg_id: reqMsgId,
455
+ result: { _: 'rpc_error', error_code: code, error_message: message },
456
+ });
457
+ }
458
+ }
459
+ /** Build JSON-RPC params from a decoded method: drop `_` and bitmask fields. */
460
+ function paramsToJson(body, registry) {
461
+ const def = registry.getByName(body._);
462
+ const omit = new Set(['_']);
463
+ if (def) {
464
+ for (const p of def.params) {
465
+ if (p.type.kind === 'flags')
466
+ omit.add(p.name);
467
+ else if (p.type.kind === 'flag')
468
+ omit.add(p.type.flagsField);
469
+ }
470
+ }
471
+ const out = {};
472
+ for (const [k, v] of Object.entries(body)) {
473
+ if (!omit.has(k))
474
+ out[k] = toJson(v);
475
+ }
476
+ return out;
477
+ }
478
+ function asString(v) {
479
+ return typeof v === 'string' ? v : undefined;
480
+ }
481
+ /**
482
+ * Parse a `msg_container` body into its inner messages, validating structure.
483
+ * Throws on a malformed container (too many messages, or an inner length that
484
+ * overruns the buffer) — the caller maps that to `bad_msg_notification` code 64.
485
+ */
486
+ function parseContainer(payload) {
487
+ const r = new TlReader(payload);
488
+ r.readUInt32(); // container constructor id
489
+ const count = r.readUInt32();
490
+ if (count > CONTAINER_MAX_MESSAGES) {
491
+ throw new Error(`container: ${count} messages exceeds ${CONTAINER_MAX_MESSAGES}`);
492
+ }
493
+ const out = [];
494
+ for (let i = 0; i < count; i++) {
495
+ const msgId = r.readLong();
496
+ const seqNo = r.readUInt32();
497
+ const bytes = r.readUInt32();
498
+ const inner = r.read(bytes); // throws if `bytes` overruns the buffer
499
+ out.push({ msgId, seqNo, inner });
500
+ }
501
+ return out;
502
+ }
503
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/dispatch/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { RpcForwarder, RpcRequest, RpcResponse } from '../rpc-forwarder.js';
2
+ /**
3
+ * Forwarder that calls a handler in the same process — for co-locating the
4
+ * gateway and a worker (no broker), and for end-to-end tests. The handler is
5
+ * typically the worker's `dispatchRpc`.
6
+ */
7
+ export declare class InProcessForwarder implements RpcForwarder {
8
+ private readonly handler;
9
+ constructor(handler: (req: RpcRequest) => Promise<RpcResponse>);
10
+ forward(req: RpcRequest): Promise<RpcResponse>;
11
+ }
12
+ //# sourceMappingURL=in-process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-process.d.ts","sourceRoot":"","sources":["../../../src/dispatch/forwarders/in-process.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEhF;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,YAAY;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,CAAC;IAE/E,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CAGjD"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Forwarder that calls a handler in the same process — for co-locating the
3
+ * gateway and a worker (no broker), and for end-to-end tests. The handler is
4
+ * typically the worker's `dispatchRpc`.
5
+ */
6
+ export class InProcessForwarder {
7
+ handler;
8
+ constructor(handler) {
9
+ this.handler = handler;
10
+ }
11
+ forward(req) {
12
+ return this.handler(req);
13
+ }
14
+ }
15
+ //# sourceMappingURL=in-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"in-process.js","sourceRoot":"","sources":["../../../src/dispatch/forwarders/in-process.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,OAAO,kBAAkB;IACE;IAA7B,YAA6B,OAAkD;QAAlD,YAAO,GAAP,OAAO,CAA2C;IAAG,CAAC;IAEnF,OAAO,CAAC,GAAe;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;CACJ"}
@@ -0,0 +1,14 @@
1
+ import { type Logger } from '@mt-tl/tl';
2
+ import type { RpcForwarder, RpcRequest, RpcResponse } from '../rpc-forwarder.js';
3
+ /**
4
+ * Dev fallback forwarder, used when no app is registered: logs the JSON-RPC 2.0
5
+ * envelope the handler *would* receive (info level), then returns NOT_IMPLEMENTED.
6
+ * Wire a real app via `createServer(...).register(app)` to get an
7
+ * {@link InProcessForwarder}.
8
+ */
9
+ export declare class PrintForwarder implements RpcForwarder {
10
+ private readonly logger;
11
+ constructor(logger?: Logger);
12
+ forward(req: RpcRequest): Promise<RpcResponse>;
13
+ }
14
+ //# sourceMappingURL=print.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.d.ts","sourceRoot":"","sources":["../../../src/dispatch/forwarders/print.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,WAAW,CAAA;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEhF;;;;;GAKG;AACH,qBAAa,cAAe,YAAW,YAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,GAAE,MAAmB;IAElD,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;CASvD"}
@@ -0,0 +1,23 @@
1
+ import { noopLogger } from '@mt-tl/tl';
2
+ /**
3
+ * Dev fallback forwarder, used when no app is registered: logs the JSON-RPC 2.0
4
+ * envelope the handler *would* receive (info level), then returns NOT_IMPLEMENTED.
5
+ * Wire a real app via `createServer(...).register(app)` to get an
6
+ * {@link InProcessForwarder}.
7
+ */
8
+ export class PrintForwarder {
9
+ logger;
10
+ constructor(logger = noopLogger) {
11
+ this.logger = logger;
12
+ }
13
+ async forward(req) {
14
+ this.logger.info('rpc.print', {
15
+ id: req.id,
16
+ method: req.method,
17
+ params: req.params,
18
+ context: req.context,
19
+ });
20
+ return { error: { code: 501, message: 'NOT_IMPLEMENTED' } };
21
+ }
22
+ }
23
+ //# sourceMappingURL=print.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"print.js","sourceRoot":"","sources":["../../../src/dispatch/forwarders/print.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAe,MAAM,WAAW,CAAA;AAGnD;;;;;GAKG;AACH,MAAM,OAAO,cAAc;IACM;IAA7B,YAA6B,SAAiB,UAAU;QAA3B,WAAM,GAAN,MAAM,CAAqB;IAAG,CAAC;IAE5D,KAAK,CAAC,OAAO,CAAC,GAAe;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE;YAC1B,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,OAAO,EAAE,GAAG,CAAC,OAAO;SACvB,CAAC,CAAA;QACF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,iBAAiB,EAAE,EAAE,CAAA;IAC/D,CAAC;CACJ"}
@@ -0,0 +1,14 @@
1
+ export type { RpcContext, RpcRequest, RpcResponse, SessionEffect } from '@mt-tl/tl';
2
+ import type { RpcRequest, RpcResponse } from '@mt-tl/tl';
3
+ /**
4
+ * Bridge from a decoded business TL method to its handler. The framework is
5
+ * in-process, so there are two implementations:
6
+ * - {@link InProcessForwarder} — calls the app's `dispatchRpc` directly (prod
7
+ * and tests); what `createServer(...).listen()` wires.
8
+ * - `PrintForwarder` — the dev fallback when no app is registered; logs the
9
+ * decoded request envelope and returns NOT_IMPLEMENTED.
10
+ */
11
+ export interface RpcForwarder {
12
+ forward(req: RpcRequest): Promise<RpcResponse>;
13
+ }
14
+ //# sourceMappingURL=rpc-forwarder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-forwarder.d.ts","sourceRoot":"","sources":["../../src/dispatch/rpc-forwarder.ts"],"names":[],"mappings":"AACA,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAExD;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;CACjD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rpc-forwarder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpc-forwarder.js","sourceRoot":"","sources":["../../src/dispatch/rpc-forwarder.ts"],"names":[],"mappings":""}