@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.
- package/.claude/settings.local.json +13 -0
- package/.claude/skills/tl-algo/SKILL.md +255 -0
- package/.gitattributes +2 -0
- package/.github/workflows/publish.yaml +26 -0
- package/4mm.js +163 -0
- package/LICENSE +21 -0
- package/NPMSwapRefactor.zip +0 -0
- package/README.md +217 -0
- package/address.sh +26 -0
- package/algoAPI.js +581 -0
- package/analyzepsbt.js +92 -0
- package/apiEx.js +99 -0
- package/bb_hyperscalper.js +290 -0
- package/bbo_demo.js +111 -0
- package/buyer.js +622 -0
- package/client.js +50 -0
- package/createTxTest.js +26 -0
- package/createWallet.js +75 -0
- package/daytrader.js +531 -0
- package/decodeTest.js +69 -0
- package/fundingManager.js +144 -0
- package/index.js +4 -0
- package/listener.js +27 -0
- package/litecoreTxBuilder.js +1128 -0
- package/mmEx.js +356 -0
- package/networks.js +51 -0
- package/orderbook.js +200 -0
- package/package.json +34 -0
- package/perTradeQueue.js +36 -0
- package/projectsTLNPMTLNPM/package-lock.json +162 -0
- package/projectsTLNPMTLNPM/package.json +5 -0
- package/quick.js +32 -0
- package/quickFut.js +37 -0
- package/quickSell.js +37 -0
- package/relayerClient.js +117 -0
- package/run4mm.js +80 -0
- package/run_bbo_tracker.js +241 -0
- package/seller.js +443 -0
- package/session.js +45 -0
- package/setup-lin-ltc.sh +139 -0
- package/setup-lin.sh +203 -0
- package/setup-win-ltc.bat +108 -0
- package/setup-win.bat +167 -0
- package/spam_screamer_futures.js +222 -0
- package/tradelayer.js/.gitattributes +2 -0
- package/tradelayer.js/README.md +2 -0
- package/tradelayer.js/oldTests/activationTest.js +6 -0
- package/tradelayer.js/oldTests/base58.test.js +23 -0
- package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
- package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
- package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
- package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
- package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
- package/tradelayer.js/oldTests/createPayload.js +0 -0
- package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
- package/tradelayer.js/oldTests/decode.js +205 -0
- package/tradelayer.js/oldTests/decodeTest.js +50 -0
- package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
- package/tradelayer.js/oldTests/encodeDecode.js +340 -0
- package/tradelayer.js/oldTests/expressTest.js +29 -0
- package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
- package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
- package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
- package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
- package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
- package/tradelayer.js/oldTests/indexTest.js +26 -0
- package/tradelayer.js/oldTests/initTokensTest.js +32 -0
- package/tradelayer.js/oldTests/interfaceChild.js +129 -0
- package/tradelayer.js/oldTests/listenerChild.js +112 -0
- package/tradelayer.js/oldTests/opdecode.js +26 -0
- package/tradelayer.js/oldTests/options.js +79 -0
- package/tradelayer.js/oldTests/optxtest.js +116 -0
- package/tradelayer.js/oldTests/optxtest1.js +64 -0
- package/tradelayer.js/oldTests/oracle.test.js +32 -0
- package/tradelayer.js/oldTests/orderbook.test.js +36 -0
- package/tradelayer.js/oldTests/parsing.js +93 -0
- package/tradelayer.js/oldTests/payload.js +13 -0
- package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
- package/tradelayer.js/oldTests/property.test.js +53 -0
- package/tradelayer.js/oldTests/propertyLevel.js +75 -0
- package/tradelayer.js/oldTests/propertyTest.js +32 -0
- package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
- package/tradelayer.js/oldTests/salter.js +14 -0
- package/tradelayer.js/oldTests/tally.js +81 -0
- package/tradelayer.js/oldTests/tally.test.js +48 -0
- package/tradelayer.js/oldTests/tally2.js +124 -0
- package/tradelayer.js/oldTests/tally3.js +142 -0
- package/tradelayer.js/oldTests/tallyDiag.js +38 -0
- package/tradelayer.js/oldTests/testGetRaw.js +40 -0
- package/tradelayer.js/oldTests/testHexConvert.js +47 -0
- package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
- package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
- package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
- package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
- package/tradelayer.js/oldTests/testOPReturn.js +102 -0
- package/tradelayer.js/oldTests/testPayload.js +23 -0
- package/tradelayer.js/oldTests/testRaw.js +50 -0
- package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
- package/tradelayer.js/oldTests/testTxBuild +28 -0
- package/tradelayer.js/oldTests/testTxBuild.js +42 -0
- package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
- package/tradelayer.js/oldTests/txUtilsA.js +515 -0
- package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
- package/tradelayer.js/oldTests/vaults.js +72 -0
- package/tradelayer.js/oldTests/volumeIndex.js +117 -0
- package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
- package/tradelayer.js/output_base64.txt +1 -0
- package/tradelayer.js/package-lock.json +9967 -0
- package/tradelayer.js/package.json +61 -0
- package/tradelayer.js/server/index.js +88 -0
- package/tradelayer.js/server/litecoind.exe +0 -0
- package/tradelayer.js/src/activation.js +303 -0
- package/tradelayer.js/src/adjuster.js +77 -0
- package/tradelayer.js/src/amm.js +400 -0
- package/tradelayer.js/src/base256.js +55 -0
- package/tradelayer.js/src/base94.js +79 -0
- package/tradelayer.js/src/channels.js +1163 -0
- package/tradelayer.js/src/clearing.js +3109 -0
- package/tradelayer.js/src/clearlist.js +364 -0
- package/tradelayer.js/src/client.js +295 -0
- package/tradelayer.js/src/consensus.js +613 -0
- package/tradelayer.js/src/contractRegistry.js +964 -0
- package/tradelayer.js/src/db.js +89 -0
- package/tradelayer.js/src/init.js +24 -0
- package/tradelayer.js/src/insurance.js +347 -0
- package/tradelayer.js/src/interface.js +218 -0
- package/tradelayer.js/src/interfaceExpress.js +178 -0
- package/tradelayer.js/src/iou.js +509 -0
- package/tradelayer.js/src/listener.js +226 -0
- package/tradelayer.js/src/logic.js +1702 -0
- package/tradelayer.js/src/main.js +927 -0
- package/tradelayer.js/src/marginMap.js +2165 -0
- package/tradelayer.js/src/options.js +126 -0
- package/tradelayer.js/src/oracle.js +394 -0
- package/tradelayer.js/src/orderbook.js +4123 -0
- package/tradelayer.js/src/persistence.js +554 -0
- package/tradelayer.js/src/property.js +411 -0
- package/tradelayer.js/src/reOrg.js +41 -0
- package/tradelayer.js/src/scaling.js +145 -0
- package/tradelayer.js/src/tally.js +1275 -0
- package/tradelayer.js/src/tradeHistoryManager.js +552 -0
- package/tradelayer.js/src/txDecoder.js +584 -0
- package/tradelayer.js/src/txEncoder.js +610 -0
- package/tradelayer.js/src/txIndex.js +502 -0
- package/tradelayer.js/src/txUtils.js +1392 -0
- package/tradelayer.js/src/types.js +429 -0
- package/tradelayer.js/src/validity.js +3077 -0
- package/tradelayer.js/src/vaults.js +430 -0
- package/tradelayer.js/src/vesting.js +491 -0
- package/tradelayer.js/src/volumeIndex.js +618 -0
- package/tradelayer.js/src/walletInterface.js +220 -0
- package/tradelayer.js/src/walletListener.js +665 -0
- package/tradelayer.js/tests/256decode.js +82 -0
- package/tradelayer.js/tests/UTXOracle.js +205 -0
- package/tradelayer.js/tests/base94test.js +23 -0
- package/tradelayer.js/tests/cancelTxTest.js +62 -0
- package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
- package/tradelayer.js/tests/decimalTest.js +65 -0
- package/tradelayer.js/tests/decoderTest.js +100 -0
- package/tradelayer.js/tests/deltaCount.js +47 -0
- package/tradelayer.js/tests/deltaCount2.js +60 -0
- package/tradelayer.js/tests/interfaceTest.js +37 -0
- package/tradelayer.js/tests/mainTest.js +53 -0
- package/tradelayer.js/tests/makeActivationTest.js +24 -0
- package/tradelayer.js/tests/maxHeightTest.js +49 -0
- package/tradelayer.js/tests/reverseHash.js +72 -0
- package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
- package/tradelayer.js/tests/tallyTest.js +40 -0
- package/tradelayer.js/tests/testBuybacks.js +46 -0
- package/tradelayer.js/tests/testCodeHash.js +49 -0
- package/tradelayer.js/tests/testConsensusHash.js +91 -0
- package/tradelayer.js/tests/testDecode.js +30 -0
- package/tradelayer.js/tests/testEncodingLengths.js +129 -0
- package/tradelayer.js/tests/testGetTx +32 -0
- package/tradelayer.js/tests/testGetTx.js +32 -0
- package/tradelayer.js/tests/testHexHash.js +32 -0
- package/tradelayer.js/tests/testIndexHash.js +35 -0
- package/tradelayer.js/tests/testInitContracts.js +38 -0
- package/tradelayer.js/tests/testMaxConsensus.js +12 -0
- package/tradelayer.js/tests/testMaxSynth.js +44 -0
- package/tradelayer.js/tests/testMint.js +21 -0
- package/tradelayer.js/tests/testNetwork.js +33 -0
- package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
- package/tradelayer.js/tests/testRebates.js +32 -0
- package/tradelayer.js/tests/testRedeem.js +22 -0
- package/tradelayer.js/tests/testTokenTrade.js +39 -0
- package/tradelayer.js/tests/testTxBuild.js +42 -0
- package/tradelayer.js/tests/testUTXOTrade.js +27 -0
- package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
- package/tradelayer.js/tests/tradeFutures.js +40 -0
- package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
- package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
- package/tradelayer.js/tests/txScanTest.js +134 -0
- package/tradelayer.js/tests/validateTest.js +136 -0
- package/tradelayer.js/tests/vestingTest.js +37 -0
- package/tradelayer.js/utils/activateMainnet.js +59 -0
- package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
- package/tradelayer.js/utils/autocompactdb.js +23 -0
- package/tradelayer.js/utils/base64toHex.js +32 -0
- package/tradelayer.js/utils/broadcastDoge.js +38 -0
- package/tradelayer.js/utils/calcRedeem.js +19 -0
- package/tradelayer.js/utils/checkNetwork.js +27 -0
- package/tradelayer.js/utils/createAddress.js +48 -0
- package/tradelayer.js/utils/createAttestation.js +133 -0
- package/tradelayer.js/utils/createContract.js +118 -0
- package/tradelayer.js/utils/createOracle.js +94 -0
- package/tradelayer.js/utils/createwallet.js +20 -0
- package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
- package/tradelayer.js/utils/crossTokenTrades.js +62 -0
- package/tradelayer.js/utils/dumpPriv.js +29 -0
- package/tradelayer.js/utils/generateChannel.js +34 -0
- package/tradelayer.js/utils/getInfo.js +21 -0
- package/tradelayer.js/utils/hardWipe.js +20 -0
- package/tradelayer.js/utils/hexTo64.js +16 -0
- package/tradelayer.js/utils/importAddress.js +28 -0
- package/tradelayer.js/utils/importpriv.js +20 -0
- package/tradelayer.js/utils/issueOracleContract.js +67 -0
- package/tradelayer.js/utils/issueTokens.js +41 -0
- package/tradelayer.js/utils/listunspent.js +66 -0
- package/tradelayer.js/utils/litecoinClient.js +30 -0
- package/tradelayer.js/utils/loadwallet.js +20 -0
- package/tradelayer.js/utils/publishOracle.js +113 -0
- package/tradelayer.js/utils/sendActivation.js +21 -0
- package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
- package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
- package/tradelayer.js/utils/sendCommit.js +24 -0
- package/tradelayer.js/utils/sendDoge.js +62 -0
- package/tradelayer.js/utils/sendDogeMain.js +67 -0
- package/tradelayer.js/utils/sendDogeTx.js +46 -0
- package/tradelayer.js/utils/sendLTC.js +63 -0
- package/tradelayer.js/utils/sendMainnet.js +62 -0
- package/tradelayer.js/utils/sendTransfer.js +19 -0
- package/tradelayer.js/utils/sendVestTest.js +88 -0
- package/tradelayer.js/utils/sendWithdrawal.js +26 -0
- package/tradelayer.js/utils/simpleStart.js +8 -0
- package/tradelayer.js/utils/startStop.js +27 -0
- package/tradelayer.js/utils/structuredTrades.js +136 -0
- package/tradelayer.js/utils/verifySignature.js +90 -0
- package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
- package/tradelayer.js/utils/walletCache.js +172 -0
- package/tradelayer.js/utils/walletContractInterface.js +48 -0
- package/tradelayer.js/utils/walletFetchTxs.js +66 -0
- package/tradelayer.js/utils/walletUtils.js +97 -0
- package/tradelayer.js/utils/wipeDB.js +55 -0
- package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
- package/txEncoder.js +529 -0
- package/utility.js +28 -0
- package/verifymessage.js +38 -0
- package/ws-transport.js +311 -0
package/verifymessage.js
ADDED
|
@@ -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
|
+
})();
|
package/ws-transport.js
ADDED
|
@@ -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
|
+
};
|