@tradelayerprotocol/tradelayer 1.9.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 (249) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/.claude/skills/tl-algo/SKILL.md +255 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/publish.yaml +26 -0
  5. package/4mm.js +163 -0
  6. package/LICENSE +21 -0
  7. package/NPMSwapRefactor.zip +0 -0
  8. package/README.md +217 -0
  9. package/address.sh +26 -0
  10. package/algoAPI.js +581 -0
  11. package/analyzepsbt.js +92 -0
  12. package/apiEx.js +99 -0
  13. package/bb_hyperscalper.js +290 -0
  14. package/bbo_demo.js +111 -0
  15. package/buyer.js +622 -0
  16. package/client.js +50 -0
  17. package/createTxTest.js +26 -0
  18. package/createWallet.js +75 -0
  19. package/daytrader.js +531 -0
  20. package/decodeTest.js +69 -0
  21. package/fundingManager.js +144 -0
  22. package/index.js +4 -0
  23. package/listener.js +27 -0
  24. package/litecoreTxBuilder.js +1128 -0
  25. package/mmEx.js +356 -0
  26. package/networks.js +51 -0
  27. package/orderbook.js +200 -0
  28. package/package.json +34 -0
  29. package/perTradeQueue.js +36 -0
  30. package/projectsTLNPMTLNPM/package-lock.json +162 -0
  31. package/projectsTLNPMTLNPM/package.json +5 -0
  32. package/quick.js +32 -0
  33. package/quickFut.js +37 -0
  34. package/quickSell.js +37 -0
  35. package/relayerClient.js +117 -0
  36. package/run4mm.js +80 -0
  37. package/run_bbo_tracker.js +241 -0
  38. package/seller.js +443 -0
  39. package/session.js +45 -0
  40. package/setup-lin-ltc.sh +139 -0
  41. package/setup-lin.sh +203 -0
  42. package/setup-win-ltc.bat +108 -0
  43. package/setup-win.bat +167 -0
  44. package/spam_screamer_futures.js +222 -0
  45. package/tradelayer.js/.gitattributes +2 -0
  46. package/tradelayer.js/README.md +2 -0
  47. package/tradelayer.js/oldTests/activationTest.js +6 -0
  48. package/tradelayer.js/oldTests/base58.test.js +23 -0
  49. package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
  50. package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
  51. package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
  52. package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
  53. package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
  54. package/tradelayer.js/oldTests/createPayload.js +0 -0
  55. package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
  56. package/tradelayer.js/oldTests/decode.js +205 -0
  57. package/tradelayer.js/oldTests/decodeTest.js +50 -0
  58. package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
  59. package/tradelayer.js/oldTests/encodeDecode.js +340 -0
  60. package/tradelayer.js/oldTests/expressTest.js +29 -0
  61. package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
  62. package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
  63. package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
  64. package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
  65. package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
  66. package/tradelayer.js/oldTests/indexTest.js +26 -0
  67. package/tradelayer.js/oldTests/initTokensTest.js +32 -0
  68. package/tradelayer.js/oldTests/interfaceChild.js +129 -0
  69. package/tradelayer.js/oldTests/listenerChild.js +112 -0
  70. package/tradelayer.js/oldTests/opdecode.js +26 -0
  71. package/tradelayer.js/oldTests/options.js +79 -0
  72. package/tradelayer.js/oldTests/optxtest.js +116 -0
  73. package/tradelayer.js/oldTests/optxtest1.js +64 -0
  74. package/tradelayer.js/oldTests/oracle.test.js +32 -0
  75. package/tradelayer.js/oldTests/orderbook.test.js +36 -0
  76. package/tradelayer.js/oldTests/parsing.js +93 -0
  77. package/tradelayer.js/oldTests/payload.js +13 -0
  78. package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
  79. package/tradelayer.js/oldTests/property.test.js +53 -0
  80. package/tradelayer.js/oldTests/propertyLevel.js +75 -0
  81. package/tradelayer.js/oldTests/propertyTest.js +32 -0
  82. package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
  83. package/tradelayer.js/oldTests/salter.js +14 -0
  84. package/tradelayer.js/oldTests/tally.js +81 -0
  85. package/tradelayer.js/oldTests/tally.test.js +48 -0
  86. package/tradelayer.js/oldTests/tally2.js +124 -0
  87. package/tradelayer.js/oldTests/tally3.js +142 -0
  88. package/tradelayer.js/oldTests/tallyDiag.js +38 -0
  89. package/tradelayer.js/oldTests/testGetRaw.js +40 -0
  90. package/tradelayer.js/oldTests/testHexConvert.js +47 -0
  91. package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
  92. package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
  93. package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
  94. package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
  95. package/tradelayer.js/oldTests/testOPReturn.js +102 -0
  96. package/tradelayer.js/oldTests/testPayload.js +23 -0
  97. package/tradelayer.js/oldTests/testRaw.js +50 -0
  98. package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
  99. package/tradelayer.js/oldTests/testTxBuild +28 -0
  100. package/tradelayer.js/oldTests/testTxBuild.js +42 -0
  101. package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
  102. package/tradelayer.js/oldTests/txUtilsA.js +515 -0
  103. package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
  104. package/tradelayer.js/oldTests/vaults.js +72 -0
  105. package/tradelayer.js/oldTests/volumeIndex.js +117 -0
  106. package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
  107. package/tradelayer.js/output_base64.txt +1 -0
  108. package/tradelayer.js/package-lock.json +9967 -0
  109. package/tradelayer.js/package.json +61 -0
  110. package/tradelayer.js/server/index.js +88 -0
  111. package/tradelayer.js/server/litecoind.exe +0 -0
  112. package/tradelayer.js/src/activation.js +303 -0
  113. package/tradelayer.js/src/adjuster.js +77 -0
  114. package/tradelayer.js/src/amm.js +400 -0
  115. package/tradelayer.js/src/base256.js +55 -0
  116. package/tradelayer.js/src/base94.js +79 -0
  117. package/tradelayer.js/src/channels.js +1163 -0
  118. package/tradelayer.js/src/clearing.js +3109 -0
  119. package/tradelayer.js/src/clearlist.js +364 -0
  120. package/tradelayer.js/src/client.js +295 -0
  121. package/tradelayer.js/src/consensus.js +613 -0
  122. package/tradelayer.js/src/contractRegistry.js +964 -0
  123. package/tradelayer.js/src/db.js +89 -0
  124. package/tradelayer.js/src/init.js +24 -0
  125. package/tradelayer.js/src/insurance.js +347 -0
  126. package/tradelayer.js/src/interface.js +218 -0
  127. package/tradelayer.js/src/interfaceExpress.js +178 -0
  128. package/tradelayer.js/src/iou.js +509 -0
  129. package/tradelayer.js/src/listener.js +226 -0
  130. package/tradelayer.js/src/logic.js +1702 -0
  131. package/tradelayer.js/src/main.js +927 -0
  132. package/tradelayer.js/src/marginMap.js +2165 -0
  133. package/tradelayer.js/src/options.js +126 -0
  134. package/tradelayer.js/src/oracle.js +394 -0
  135. package/tradelayer.js/src/orderbook.js +4123 -0
  136. package/tradelayer.js/src/persistence.js +554 -0
  137. package/tradelayer.js/src/property.js +411 -0
  138. package/tradelayer.js/src/reOrg.js +41 -0
  139. package/tradelayer.js/src/scaling.js +145 -0
  140. package/tradelayer.js/src/tally.js +1275 -0
  141. package/tradelayer.js/src/tradeHistoryManager.js +552 -0
  142. package/tradelayer.js/src/txDecoder.js +584 -0
  143. package/tradelayer.js/src/txEncoder.js +610 -0
  144. package/tradelayer.js/src/txIndex.js +502 -0
  145. package/tradelayer.js/src/txUtils.js +1392 -0
  146. package/tradelayer.js/src/types.js +429 -0
  147. package/tradelayer.js/src/validity.js +3077 -0
  148. package/tradelayer.js/src/vaults.js +430 -0
  149. package/tradelayer.js/src/vesting.js +491 -0
  150. package/tradelayer.js/src/volumeIndex.js +618 -0
  151. package/tradelayer.js/src/walletInterface.js +220 -0
  152. package/tradelayer.js/src/walletListener.js +665 -0
  153. package/tradelayer.js/tests/256decode.js +82 -0
  154. package/tradelayer.js/tests/UTXOracle.js +205 -0
  155. package/tradelayer.js/tests/base94test.js +23 -0
  156. package/tradelayer.js/tests/cancelTxTest.js +62 -0
  157. package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
  158. package/tradelayer.js/tests/decimalTest.js +65 -0
  159. package/tradelayer.js/tests/decoderTest.js +100 -0
  160. package/tradelayer.js/tests/deltaCount.js +47 -0
  161. package/tradelayer.js/tests/deltaCount2.js +60 -0
  162. package/tradelayer.js/tests/interfaceTest.js +37 -0
  163. package/tradelayer.js/tests/mainTest.js +53 -0
  164. package/tradelayer.js/tests/makeActivationTest.js +24 -0
  165. package/tradelayer.js/tests/maxHeightTest.js +49 -0
  166. package/tradelayer.js/tests/reverseHash.js +72 -0
  167. package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
  168. package/tradelayer.js/tests/tallyTest.js +40 -0
  169. package/tradelayer.js/tests/testBuybacks.js +46 -0
  170. package/tradelayer.js/tests/testCodeHash.js +49 -0
  171. package/tradelayer.js/tests/testConsensusHash.js +91 -0
  172. package/tradelayer.js/tests/testDecode.js +30 -0
  173. package/tradelayer.js/tests/testEncodingLengths.js +129 -0
  174. package/tradelayer.js/tests/testGetTx +32 -0
  175. package/tradelayer.js/tests/testGetTx.js +32 -0
  176. package/tradelayer.js/tests/testHexHash.js +32 -0
  177. package/tradelayer.js/tests/testIndexHash.js +35 -0
  178. package/tradelayer.js/tests/testInitContracts.js +38 -0
  179. package/tradelayer.js/tests/testMaxConsensus.js +12 -0
  180. package/tradelayer.js/tests/testMaxSynth.js +44 -0
  181. package/tradelayer.js/tests/testMint.js +21 -0
  182. package/tradelayer.js/tests/testNetwork.js +33 -0
  183. package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
  184. package/tradelayer.js/tests/testRebates.js +32 -0
  185. package/tradelayer.js/tests/testRedeem.js +22 -0
  186. package/tradelayer.js/tests/testTokenTrade.js +39 -0
  187. package/tradelayer.js/tests/testTxBuild.js +42 -0
  188. package/tradelayer.js/tests/testUTXOTrade.js +27 -0
  189. package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
  190. package/tradelayer.js/tests/tradeFutures.js +40 -0
  191. package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
  192. package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
  193. package/tradelayer.js/tests/txScanTest.js +134 -0
  194. package/tradelayer.js/tests/validateTest.js +136 -0
  195. package/tradelayer.js/tests/vestingTest.js +37 -0
  196. package/tradelayer.js/utils/activateMainnet.js +59 -0
  197. package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
  198. package/tradelayer.js/utils/autocompactdb.js +23 -0
  199. package/tradelayer.js/utils/base64toHex.js +32 -0
  200. package/tradelayer.js/utils/broadcastDoge.js +38 -0
  201. package/tradelayer.js/utils/calcRedeem.js +19 -0
  202. package/tradelayer.js/utils/checkNetwork.js +27 -0
  203. package/tradelayer.js/utils/createAddress.js +48 -0
  204. package/tradelayer.js/utils/createAttestation.js +133 -0
  205. package/tradelayer.js/utils/createContract.js +118 -0
  206. package/tradelayer.js/utils/createOracle.js +94 -0
  207. package/tradelayer.js/utils/createwallet.js +20 -0
  208. package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
  209. package/tradelayer.js/utils/crossTokenTrades.js +62 -0
  210. package/tradelayer.js/utils/dumpPriv.js +29 -0
  211. package/tradelayer.js/utils/generateChannel.js +34 -0
  212. package/tradelayer.js/utils/getInfo.js +21 -0
  213. package/tradelayer.js/utils/hardWipe.js +20 -0
  214. package/tradelayer.js/utils/hexTo64.js +16 -0
  215. package/tradelayer.js/utils/importAddress.js +28 -0
  216. package/tradelayer.js/utils/importpriv.js +20 -0
  217. package/tradelayer.js/utils/issueOracleContract.js +67 -0
  218. package/tradelayer.js/utils/issueTokens.js +41 -0
  219. package/tradelayer.js/utils/listunspent.js +66 -0
  220. package/tradelayer.js/utils/litecoinClient.js +30 -0
  221. package/tradelayer.js/utils/loadwallet.js +20 -0
  222. package/tradelayer.js/utils/publishOracle.js +113 -0
  223. package/tradelayer.js/utils/sendActivation.js +21 -0
  224. package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
  225. package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
  226. package/tradelayer.js/utils/sendCommit.js +24 -0
  227. package/tradelayer.js/utils/sendDoge.js +62 -0
  228. package/tradelayer.js/utils/sendDogeMain.js +67 -0
  229. package/tradelayer.js/utils/sendDogeTx.js +46 -0
  230. package/tradelayer.js/utils/sendLTC.js +63 -0
  231. package/tradelayer.js/utils/sendMainnet.js +62 -0
  232. package/tradelayer.js/utils/sendTransfer.js +19 -0
  233. package/tradelayer.js/utils/sendVestTest.js +88 -0
  234. package/tradelayer.js/utils/sendWithdrawal.js +26 -0
  235. package/tradelayer.js/utils/simpleStart.js +8 -0
  236. package/tradelayer.js/utils/startStop.js +27 -0
  237. package/tradelayer.js/utils/structuredTrades.js +136 -0
  238. package/tradelayer.js/utils/verifySignature.js +90 -0
  239. package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
  240. package/tradelayer.js/utils/walletCache.js +172 -0
  241. package/tradelayer.js/utils/walletContractInterface.js +48 -0
  242. package/tradelayer.js/utils/walletFetchTxs.js +66 -0
  243. package/tradelayer.js/utils/walletUtils.js +97 -0
  244. package/tradelayer.js/utils/wipeDB.js +55 -0
  245. package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
  246. package/txEncoder.js +529 -0
  247. package/utility.js +28 -0
  248. package/verifymessage.js +38 -0
  249. package/ws-transport.js +311 -0
@@ -0,0 +1,38 @@
1
+ const litecoinClient = require('./litecoinClient'); // Adjust path if necessary
2
+
3
+ /**
4
+ * Promisified version of the verifymessage RPC call
5
+ * @param {string} address - The address that signed the message.
6
+ * @param {string} signature - The signature to verify.
7
+ * @param {string} message - The original message that was signed.
8
+ * @returns {Promise<boolean>} - Resolves to `true` if signature is valid, `false` otherwise.
9
+ */
10
+ const verifyMessageAsync = util.promisify(client.cmd.bind(client,'verifymessage'));
11
+
12
+ const verifySignature = async (address, signature, message) => {
13
+ try {
14
+ // Making the RPC call using litecoinClient
15
+ const result = await verifymessageAsync([address, signature, message]);
16
+
17
+ // Check if the result is true (valid signature)
18
+ if (result === true) {
19
+ console.log(`Signature is valid for address: ${address}`);
20
+ return true;
21
+ } else {
22
+ console.log(`Signature is invalid for address: ${address}`);
23
+ return false;
24
+ }
25
+ } catch (error) {
26
+ console.error(`Error verifying signature: ${error}`);
27
+ return false;
28
+ }
29
+ };
30
+
31
+ // Example Usage
32
+ (async () => {
33
+ const address = 'tltc1ql9yqzpe0ce0ccdwmyd3lwkqr794fm22tmhe7mn';
34
+ const signature = 'H1t+P0w0u1kQOpS7LCUsTtT...'; // Example signature
35
+ const message = 'Hello, Litecoin!';
36
+
37
+ await verifySignature(address, signature, message);
38
+ })();
@@ -0,0 +1,311 @@
1
+ /* ws-transport.js — pure WS, spam-safe, parity-preserving */
2
+ 'use strict';
3
+
4
+ const { EventEmitter } = require('events');
5
+ const WS = (typeof WebSocket !== 'undefined') ? WebSocket : require('ws');
6
+
7
+ /* -------- OUTBOUND FILTERS ---------- */
8
+ /* Local-only events your app used to keep off the wire.
9
+ (Expanded minimally to match prior behavior and your notes.) */
10
+ const OUTBOUND_BLOCKLIST = new Set([
11
+ // lifecycle / diagnostics
12
+ 'connected', 'connect', 'disconnect', 'reconnect', 'message', 'error', 'ws-error',
13
+ // local bus/order lifecycle
14
+ 'order:saved', 'order:error', 'placed-orders', 'orders:placed',
15
+ // misc keepalives
16
+ 'ping', 'pong'
17
+ ]);
18
+
19
+ /* Only these go to server by default. */
20
+ const SERVER_EVENTS = new Set([
21
+ 'new-order',
22
+ 'update-orderbook',
23
+ 'close-order',
24
+ 'many-orders',
25
+ 'disconnect',
26
+ 'orderbook:join',
27
+ 'orderbook:leave'
28
+ ]);
29
+
30
+ /* Auto-once these inbound events to prevent per-request leaks (unless handler.persist=true) */
31
+ const AUTO_ONCE_EVENTS = new Set(['order:saved', 'order:error']);
32
+
33
+ /* ------------------------------------ */
34
+
35
+ function _emitLocal(em, ev, payload) {
36
+ try { EventEmitter.prototype.emit.call(em, ev, payload); } catch {}
37
+ }
38
+
39
+ function safeParse(s) { try { return JSON.parse(s); } catch { return null; } }
40
+
41
+ class WsTransport extends EventEmitter {
42
+ /**
43
+ * @param {string|object} arg url or { url, headers?, pingMs? }
44
+ * @param {object} [opts]
45
+ */
46
+ constructor(arg, opts = {}, network) {
47
+ super();
48
+ const cfg = (typeof arg === 'string') ? { url: arg, ...opts } : (arg || {});
49
+ this.url = cfg.url || null;
50
+ this.opts = { headers: cfg.headers, pingMs: cfg.pingMs || 0 };
51
+
52
+ /** @type {WebSocket|null} */
53
+ this.ws = null;
54
+
55
+ // Prevent duplicate inbound bridges and track listener identity
56
+ this._bridgeBound = false;
57
+ this._listenerSet = new Map(); // event -> Set<fn or fn.__orig>
58
+ this.network =network
59
+ this.setMaxListeners(0); // allow many, we’ll handle cleanup ourselves
60
+ }
61
+
62
+ /* ---- listener anti-spam layer ---- */
63
+ on(event, handler) { return this._dedupAdd(event, handler, false); }
64
+ addListener(event, handler) { return this._dedupAdd(event, handler, false); }
65
+ once(event, handler){ return this._dedupAdd(event, handler, true); }
66
+
67
+ // Replace existing off(...) in ws-transport.js with this:
68
+ off(event, handler) {
69
+ // If no event, nothing to do
70
+ if (!event || typeof event !== 'string') return this;
71
+
72
+ const set = this._listenerSet?.get?.(event);
73
+
74
+ // Case 1: remove all listeners for this event when no handler provided
75
+ if (handler == null) {
76
+ if (set && set.size) {
77
+ for (const fn of Array.from(set)) {
78
+ const orig = fn.__orig || fn;
79
+ if (typeof orig === 'function') {
80
+ try { this.removeListener?.(event, orig); } catch {}
81
+ }
82
+ }
83
+ set.clear();
84
+ }
85
+ this._listenerSet?.delete?.(event);
86
+ return this;
87
+ }
88
+
89
+ // Case 2: handler provided but not a function → no-op (avoid Node ERR_INVALID_ARG_TYPE)
90
+ const orig = handler.__orig || handler;
91
+ if (typeof orig !== 'function') {
92
+ // also clean bookkeeping if present
93
+ if (set) {
94
+ set.delete(handler);
95
+ set.delete(orig);
96
+ if (!set.size) this._listenerSet.delete(event);
97
+ }
98
+ return this;
99
+ }
100
+
101
+ // Normal path: remove the specific handler
102
+ try { this.removeListener?.(event, orig); } catch {}
103
+ if (set) {
104
+ set.delete(handler);
105
+ set.delete(orig);
106
+ if (!set.size) this._listenerSet.delete(event);
107
+ }
108
+ return this;
109
+ }
110
+
111
+ removeListener(event, handler) { return this.off(event, handler); }
112
+
113
+ _dedupAdd(event, handler, forceOnce) {
114
+ // If auto-once target and handler not marked persistent, wrap it
115
+ let fn = handler;
116
+ const shouldOnce = forceOnce || (AUTO_ONCE_EVENTS.has(event) && !handler?.persist);
117
+ if (shouldOnce) {
118
+ const wrapped = (...args) => { this.off(event, wrapped); handler(...args); };
119
+ Object.defineProperty(wrapped, '__orig', { value: handler });
120
+ fn = wrapped;
121
+ }
122
+
123
+ // De-duplicate by original function identity
124
+ const key = fn.__orig || fn;
125
+ const set = this._listenerSet.get(event) || new Set();
126
+ if (set.has(key)) return this; // already attached
127
+ set.add(key); this._listenerSet.set(event, set);
128
+
129
+ return EventEmitter.prototype.on.call(this, event, fn);
130
+ }
131
+
132
+ /* ---- connection ---- */
133
+
134
+ /**
135
+ * Connects to WebSocket. If url omitted, uses ctor url.
136
+ * Resolves on 'open', rejects on error/close before open.
137
+ */
138
+ connect(url) {
139
+ const target = url || this.url;
140
+ if (!target) return Promise.reject(new Error('WebSocket URL not provided'));
141
+
142
+ // Already open?
143
+ if (this.ws && this.ws.readyState === (WS.OPEN || 1)) return Promise.resolve();
144
+
145
+ return new Promise((resolve, reject) => {
146
+ let settled = false;
147
+ try {
148
+ const ws = (typeof window === 'undefined')
149
+ ? new WS(target, { headers: this.opts.headers })
150
+ : new WS(target);
151
+
152
+ this.ws = ws;
153
+ this._bridgeBound = false;
154
+
155
+ const handleMessage = (raw) => {
156
+ // --- normalize inbound raw/text ---
157
+ const txt =
158
+ typeof raw === 'string'
159
+ ? raw
160
+ : (raw?.data != null
161
+ ? (typeof raw.data === 'string' ? raw.data : raw.data.toString())
162
+ : raw?.toString?.());
163
+ if (!txt) return;
164
+
165
+ const frame = safeParse(txt);
166
+ if (!frame || typeof frame.event !== 'string') return;
167
+
168
+ const ev = frame.event;
169
+ let norm = (frame.data !== undefined ? frame.data : frame);
170
+
171
+ // --- flatten legacy <socketId>::swap frames ---
172
+ if (ev.endsWith('::swap')) {
173
+ if (
174
+ norm && typeof norm === 'object' &&
175
+ 'data' in norm && typeof norm.data === 'object' &&
176
+ norm.eventName === undefined && norm.socketId === undefined
177
+ ) {
178
+ const inner = norm.data;
179
+ norm = { ...norm, ...inner };
180
+ }
181
+ }
182
+
183
+ _emitLocal(this, ev, norm);
184
+ _emitLocal(this, 'message', { event: ev, data: norm });
185
+
186
+ // clear one-time listeners
187
+ if (AUTO_ONCE_EVENTS.has(ev)) {
188
+ const set = this._listenerSet.get(ev);
189
+ if (set && set.size) {
190
+ for (const fn of Array.from(set)) {
191
+ const orig = fn.__orig || fn;
192
+ if (!orig?.persist) this.off(ev, fn);
193
+ }
194
+ }
195
+ }
196
+ };
197
+
198
+ ws.onopen = () => {
199
+ this._bindBridgeOnce(ws, handleMessage);
200
+ console.log('[WS] connected to', target);
201
+ if (!settled) { settled = true; resolve(); }
202
+ _emitLocal(this, 'connected', { url: target });
203
+ _emitLocal(this, 'connect', { url: target });
204
+ };
205
+
206
+ this._bindBridgeOnce(ws, handleMessage);
207
+
208
+
209
+ ws.onerror = (e) => {
210
+ const err = e?.error instanceof Error ? e.error : new Error(e?.message || 'ws error');
211
+ console.error('[WS] error', err);
212
+ _emitLocal(this, 'ws-error', err);
213
+ if (!settled && ws.readyState !== (WS.OPEN || 1)) {
214
+ settled = true; reject(err);
215
+ }
216
+ };
217
+
218
+ ws.onclose = (ev) => {
219
+ console.warn('[WS] closed');
220
+ this._bridgeBound = false;
221
+ _emitLocal(this, 'disconnect', { code: ev?.code, reason: ev?.reason });
222
+ if (!settled) {
223
+ settled = true;
224
+ reject(new Error(`closed before open (${ev?.code || ''})`));
225
+ }
226
+ };
227
+ } catch (e) {
228
+ console.error('[WS] create error', e);
229
+ reject(e);
230
+ }
231
+ });
232
+ }
233
+
234
+
235
+ _bindBridgeOnce(ws, handleMessage) {
236
+ if (this._bridgeBound) return;
237
+ this._bridgeBound = true;
238
+
239
+ ws.on('message', handleMessage); // <—— RESTORE THIS LINE
240
+ }
241
+
242
+
243
+ close(code = 1000, reason = 'client-close') { try { this.ws?.close(code, reason); } catch {} return this; }
244
+ disconnect(code, reason) { return this.close(code, reason); }
245
+ get isOpen() { return !!this.ws && this.ws.readyState === (WS.OPEN || 1); }
246
+
247
+ /**
248
+ * Transport.emit:
249
+ * - keeps local-only events off the wire (OUTBOUND_BLOCKLIST)
250
+ * - only whitelisted server events are sent
251
+ * - everything else is local re-emit (no extra spam to server)
252
+ */
253
+ emit(event, payload = {}) {
254
+ // local-only events
255
+ if (OUTBOUND_BLOCKLIST.has(event)) {
256
+ _emitLocal(this, event, payload);
257
+ return this;
258
+ }
259
+
260
+ // allow dynamic namespaced swap events to go upstream
261
+ const isServerEvent =
262
+ SERVER_EVENTS.has(event) ||
263
+ (typeof event === 'string' && event.endsWith('::swap'));
264
+
265
+ if (!isServerEvent) {
266
+ _emitLocal(this, event, payload);
267
+ return this;
268
+ }
269
+
270
+ // send upstream
271
+ if (!this.ws || this.ws.readyState !== 1) {
272
+ _emitLocal(this, 'ws-drain', { event, payload });
273
+ return this;
274
+ }
275
+
276
+ // inject network
277
+ const frame = {
278
+ event,
279
+ ...(payload || {}),
280
+ network: this.network
281
+ };
282
+
283
+ try {
284
+ this.ws.send(JSON.stringify(frame));
285
+ } catch (e) {
286
+ _emitLocal(this, 'ws-error', e);
287
+ }
288
+
289
+ return this;
290
+ }
291
+ }
292
+
293
+ /* Factory kept for parity with your callers */
294
+ function createTransport(opts) {
295
+ // callers do createTransport({ type:'ws', url: 'ws://...' })
296
+ const url = (opts && typeof opts === 'object') ? opts.url : opts;
297
+ return new WsTransport(url || null, opts || {});
298
+ }
299
+
300
+ module.exports = {
301
+ WsTransport,
302
+ createTransport,
303
+ OUTBOUND_BLOCKLIST,
304
+ create: createTransport
305
+ };
306
+ module.exports.default = {
307
+ WsTransport,
308
+ createTransport,
309
+ OUTBOUND_BLOCKLIST,
310
+ create: createTransport
311
+ };