@toon-protocol/connector 2.2.0 → 2.5.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 (73) hide show
  1. package/README.md +118 -46
  2. package/dist/btp/btp-client-manager.d.ts +3 -0
  3. package/dist/btp/btp-client-manager.d.ts.map +1 -1
  4. package/dist/btp/btp-client-manager.js +19 -4
  5. package/dist/btp/btp-client-manager.js.map +1 -1
  6. package/dist/btp/btp-client.d.ts +4 -1
  7. package/dist/btp/btp-client.d.ts.map +1 -1
  8. package/dist/btp/btp-client.js +24 -10
  9. package/dist/btp/btp-client.js.map +1 -1
  10. package/dist/config/config-loader.d.ts +4 -0
  11. package/dist/config/config-loader.d.ts.map +1 -1
  12. package/dist/config/config-loader.js +165 -1
  13. package/dist/config/config-loader.js.map +1 -1
  14. package/dist/config/index.d.ts +1 -0
  15. package/dist/config/index.d.ts.map +1 -1
  16. package/dist/config/types.d.ts +18 -15
  17. package/dist/config/types.d.ts.map +1 -1
  18. package/dist/config/types.js +2 -5
  19. package/dist/config/types.js.map +1 -1
  20. package/dist/core/connector-node.d.ts +12 -1
  21. package/dist/core/connector-node.d.ts.map +1 -1
  22. package/dist/core/connector-node.js +237 -21
  23. package/dist/core/connector-node.js.map +1 -1
  24. package/dist/http/types.d.ts +4 -0
  25. package/dist/http/types.d.ts.map +1 -1
  26. package/dist/lib.d.ts +1 -1
  27. package/dist/lib.d.ts.map +1 -1
  28. package/dist/settlement/account-manager.d.ts.map +1 -1
  29. package/dist/settlement/account-manager.js +1 -1
  30. package/dist/settlement/account-manager.js.map +1 -1
  31. package/dist/settlement/claim-receiver.d.ts +1 -0
  32. package/dist/settlement/claim-receiver.d.ts.map +1 -1
  33. package/dist/settlement/claim-receiver.js +23 -0
  34. package/dist/settlement/claim-receiver.js.map +1 -1
  35. package/dist/settlement/provider/payment-channel-provider.d.ts +9 -0
  36. package/dist/settlement/provider/payment-channel-provider.d.ts.map +1 -1
  37. package/dist/settlement/settlement-executor.d.ts +3 -0
  38. package/dist/settlement/settlement-executor.d.ts.map +1 -1
  39. package/dist/settlement/settlement-executor.js +10 -1
  40. package/dist/settlement/settlement-executor.js.map +1 -1
  41. package/dist/transport/direct-transport-provider.d.ts +12 -0
  42. package/dist/transport/direct-transport-provider.d.ts.map +1 -0
  43. package/dist/transport/direct-transport-provider.js +27 -0
  44. package/dist/transport/direct-transport-provider.js.map +1 -0
  45. package/dist/transport/index.d.ts +7 -0
  46. package/dist/transport/index.d.ts.map +1 -0
  47. package/dist/transport/index.js +16 -0
  48. package/dist/transport/index.js.map +1 -0
  49. package/dist/transport/managed-anon-client.d.ts +47 -0
  50. package/dist/transport/managed-anon-client.d.ts.map +1 -0
  51. package/dist/transport/managed-anon-client.js +265 -0
  52. package/dist/transport/managed-anon-client.js.map +1 -0
  53. package/dist/transport/probe-tcp-port.d.ts +3 -0
  54. package/dist/transport/probe-tcp-port.d.ts.map +1 -0
  55. package/dist/transport/probe-tcp-port.js +59 -0
  56. package/dist/transport/probe-tcp-port.js.map +1 -0
  57. package/dist/transport/socks-transport-provider.d.ts +29 -0
  58. package/dist/transport/socks-transport-provider.d.ts.map +1 -0
  59. package/dist/transport/socks-transport-provider.js +136 -0
  60. package/dist/transport/socks-transport-provider.js.map +1 -0
  61. package/dist/transport/socks-url.d.ts +6 -0
  62. package/dist/transport/socks-url.d.ts.map +1 -0
  63. package/dist/transport/socks-url.js +29 -0
  64. package/dist/transport/socks-url.js.map +1 -0
  65. package/dist/transport/transport-provider.d.ts +9 -0
  66. package/dist/transport/transport-provider.d.ts.map +1 -0
  67. package/dist/transport/transport-provider.js +3 -0
  68. package/dist/transport/transport-provider.js.map +1 -0
  69. package/dist/utils/redact.d.ts +3 -0
  70. package/dist/utils/redact.d.ts.map +1 -0
  71. package/dist/utils/redact.js +21 -0
  72. package/dist/utils/redact.js.map +1 -0
  73. package/package.json +9 -2
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ManagedAnonClient = void 0;
4
+ exports.createDefaultAnonFactory = createDefaultAnonFactory;
5
+ const tslib_1 = require("tslib");
6
+ const fs_1 = require("fs");
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const probe_tcp_port_1 = require("./probe-tcp-port");
9
+ const socks_url_1 = require("./socks-url");
10
+ const DEFAULT_STARTUP_TIMEOUT_MS = 60_000;
11
+ const DEFAULT_STOP_TIMEOUT_MS = 10_000;
12
+ class ManagedAnonClient {
13
+ _opts;
14
+ _logger;
15
+ _socksHost;
16
+ _socksPort;
17
+ _sdk;
18
+ _started = false;
19
+ _lastHealthyFlag = true;
20
+ _consecutiveProbeFailures = 0;
21
+ constructor(options) {
22
+ this._opts = options;
23
+ this._logger = options.logger.child({ component: 'managed-anon-client' });
24
+ const { host, port } = (0, socks_url_1.parseSocks5hUrl)(options.socksProxy);
25
+ this._socksHost = host;
26
+ this._socksPort = port;
27
+ }
28
+ async start() {
29
+ if (this._started && this._sdk) {
30
+ return;
31
+ }
32
+ const factoryOpts = await this._buildFactoryOptions();
33
+ let sdk;
34
+ try {
35
+ sdk = this._opts.anonFactory(factoryOpts);
36
+ }
37
+ catch (err) {
38
+ const cause = err;
39
+ if (cause?.code === 'MODULE_NOT_FOUND') {
40
+ throw new Error(`Managed ATOR transport requires the optional dependency ` +
41
+ `"@anyone-protocol/anyone-client" but it was not found. ` +
42
+ `Install it with: npm install @anyone-protocol/anyone-client`, { cause });
43
+ }
44
+ throw new Error(`Failed to construct @anyone-protocol/anyone-client SDK handle: ${cause?.message ?? String(err)}`, { cause });
45
+ }
46
+ try {
47
+ await sdk.start();
48
+ }
49
+ catch (err) {
50
+ const cause = err;
51
+ await this._bestEffortStop(sdk);
52
+ this._sdk = undefined;
53
+ this._started = false;
54
+ if (cause?.code === 'ENOENT' || /ENOENT/.test(cause?.message ?? '')) {
55
+ const hint = this._opts.binaryPath
56
+ ? ` at configured binaryPath="${this._opts.binaryPath}"`
57
+ : ' (the bundled binary shipped by @anyone-protocol/anyone-client could not be spawned)';
58
+ throw new Error(`anon binary not found${hint}. Install @anyone-protocol/anyone-client ` +
59
+ `and ensure a compatible binary is available for this platform ` +
60
+ `(npm install @anyone-protocol/anyone-client).`, { cause });
61
+ }
62
+ throw new Error(`Failed to start managed anon SDK: ${cause?.message ?? String(err)}`, {
63
+ cause,
64
+ });
65
+ }
66
+ const startupTimeoutMs = this._opts.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS;
67
+ const socksPort = sdk.getSOCKSPort?.() ?? this._socksPort;
68
+ try {
69
+ await (0, probe_tcp_port_1.waitForTcpPort)(this._socksHost, socksPort, startupTimeoutMs);
70
+ }
71
+ catch (err) {
72
+ const cause = err;
73
+ await this._bestEffortStop(sdk);
74
+ this._sdk = undefined;
75
+ this._started = false;
76
+ throw new Error(`Managed anon SOCKS port ${socksPort} did not bind within ${startupTimeoutMs}ms timeout ` +
77
+ `(awaiting TCP readiness on ${this._socksHost}:${socksPort})`, { cause });
78
+ }
79
+ this._sdk = sdk;
80
+ this._started = true;
81
+ this._lastHealthyFlag = true;
82
+ this._logger.info({ event: 'managed_anon_started', socksPort }, 'Managed anon client started');
83
+ }
84
+ async stop() {
85
+ const sdk = this._sdk;
86
+ if (!sdk || !this._started) {
87
+ this._sdk = undefined;
88
+ this._started = false;
89
+ return;
90
+ }
91
+ this._sdk = undefined;
92
+ this._started = false;
93
+ const stopTimeoutMs = this._opts.stopTimeoutMs ?? DEFAULT_STOP_TIMEOUT_MS;
94
+ let timer;
95
+ const timeoutPromise = new Promise((resolve) => {
96
+ timer = setTimeout(() => resolve('timeout'), stopTimeoutMs);
97
+ });
98
+ let raceSettled = false;
99
+ const sdkStopPromise = sdk.stop();
100
+ sdkStopPromise.catch((lateErr) => {
101
+ if (raceSettled) {
102
+ this._logger.warn({
103
+ event: 'managed_anon_stop_late_error',
104
+ errorMessage: lateErr?.message ?? String(lateErr),
105
+ }, 'Managed anon SDK stop() rejected after the stop race had already settled');
106
+ }
107
+ });
108
+ try {
109
+ const result = await Promise.race([sdkStopPromise.then(() => 'ok'), timeoutPromise]);
110
+ raceSettled = true;
111
+ if (result === 'timeout') {
112
+ const stillRunning = safeIsRunning(sdk);
113
+ this._logger.warn({
114
+ event: 'managed_anon_stop_timeout',
115
+ stopTimeoutMs,
116
+ sdkStillRunning: stillRunning,
117
+ }, 'Managed anon SDK stop() did not resolve within timeout; ' +
118
+ (stillRunning ? 'operator intervention may be required' : 'proceeding with shutdown'));
119
+ }
120
+ else {
121
+ this._logger.info({ event: 'managed_anon_stopped' }, 'Managed anon client stopped');
122
+ }
123
+ }
124
+ catch (err) {
125
+ raceSettled = true;
126
+ const cause = err;
127
+ this._logger.warn({
128
+ event: 'managed_anon_stop_error',
129
+ errorMessage: cause?.message ?? String(err),
130
+ }, 'Managed anon SDK stop() threw; continuing shutdown');
131
+ }
132
+ finally {
133
+ if (timer)
134
+ clearTimeout(timer);
135
+ }
136
+ }
137
+ isRunning() {
138
+ return this._started && safeIsRunning(this._sdk);
139
+ }
140
+ async healthCheck() {
141
+ if (!this._started || !this._sdk) {
142
+ return false;
143
+ }
144
+ const ok = safeIsRunning(this._sdk);
145
+ if (!ok && this._lastHealthyFlag) {
146
+ this._lastHealthyFlag = false;
147
+ this._logger.warn({ event: 'managed_anon_crash_detected' }, 'Managed anon SDK reports not running (binary may have crashed)');
148
+ }
149
+ else if (ok && !this._lastHealthyFlag) {
150
+ this._lastHealthyFlag = true;
151
+ }
152
+ if (ok) {
153
+ try {
154
+ await (0, probe_tcp_port_1.probeTcpPort)(this._socksHost, this._sdk.getSOCKSPort(), 250);
155
+ this._consecutiveProbeFailures = 0;
156
+ }
157
+ catch (err) {
158
+ this._consecutiveProbeFailures += 1;
159
+ if (this._consecutiveProbeFailures >= 2) {
160
+ this._logger.warn({
161
+ event: 'managed_anon_probe_failed',
162
+ consecutiveFailures: this._consecutiveProbeFailures,
163
+ errorMessage: err?.message ?? String(err),
164
+ }, 'Managed anon SOCKS port probe failed on 2+ consecutive health checks');
165
+ return false;
166
+ }
167
+ }
168
+ }
169
+ return ok;
170
+ }
171
+ async _buildFactoryOptions() {
172
+ const opts = {
173
+ displayLog: this._opts.logger.level === 'debug' || this._opts.logger.level === 'trace',
174
+ useExecFile: false,
175
+ socksPort: this._socksPort,
176
+ orPort: 0,
177
+ binaryPath: this._opts.binaryPath,
178
+ autoTermsAgreement: true,
179
+ };
180
+ if (this._opts.hiddenServiceDir) {
181
+ opts.hiddenServiceDir = this._opts.hiddenServiceDir;
182
+ if (this._opts.hiddenServicePort !== undefined) {
183
+ opts.hiddenServicePort = this._opts.hiddenServicePort;
184
+ }
185
+ try {
186
+ await fs_1.promises.mkdir(this._opts.hiddenServiceDir, { recursive: true });
187
+ const anonrcPath = path_1.default.join(this._opts.hiddenServiceDir, 'anonrc');
188
+ let anonrcExists = false;
189
+ try {
190
+ await fs_1.promises.access(anonrcPath);
191
+ anonrcExists = true;
192
+ }
193
+ catch {
194
+ anonrcExists = false;
195
+ }
196
+ if (!anonrcExists) {
197
+ const anonrc = `# Written by ManagedAnonClient (Epic 35 / Story 35.5) on first boot.\n` +
198
+ `# Edit freely — ManagedAnonClient will NOT overwrite this file on subsequent starts.\n` +
199
+ `AgreeToTerms 1\n` +
200
+ `SocksPort ${this._socksPort}\n` +
201
+ `HiddenServiceDir ${this._opts.hiddenServiceDir}\n` +
202
+ (this._opts.hiddenServicePort !== undefined
203
+ ? `HiddenServicePort ${this._opts.hiddenServicePort} 127.0.0.1:${this._opts.hiddenServicePort}\n`
204
+ : '');
205
+ await fs_1.promises.writeFile(anonrcPath, anonrc, { encoding: 'utf8', flag: 'wx' });
206
+ }
207
+ opts.configFilePath = anonrcPath;
208
+ opts.configFile = anonrcPath;
209
+ }
210
+ catch (err) {
211
+ this._logger.debug({ event: 'managed_anon_anonrc_write_failed', error: err.message }, 'Could not write anonrc; continuing with native options only');
212
+ }
213
+ }
214
+ return opts;
215
+ }
216
+ async _bestEffortStop(sdk) {
217
+ try {
218
+ await sdk.stop();
219
+ }
220
+ catch (err) {
221
+ this._logger.warn({
222
+ event: 'managed_anon_cleanup_stop_failed',
223
+ errorMessage: err.message,
224
+ }, 'Best-effort SDK stop() during failure cleanup threw; ignoring');
225
+ }
226
+ }
227
+ }
228
+ exports.ManagedAnonClient = ManagedAnonClient;
229
+ function safeIsRunning(sdk) {
230
+ if (!sdk)
231
+ return false;
232
+ try {
233
+ return sdk.isRunning() === true;
234
+ }
235
+ catch {
236
+ return false;
237
+ }
238
+ }
239
+ async function createDefaultAnonFactory() {
240
+ let mod;
241
+ const pkg = '@anyone-protocol/anyone-client';
242
+ try {
243
+ mod = require(pkg);
244
+ }
245
+ catch {
246
+ try {
247
+ mod = await new Function('p', 'return import(p)')(pkg);
248
+ }
249
+ catch (err) {
250
+ const cause = err;
251
+ const wrapped = new Error(`Managed ATOR transport requires the optional dependency ` +
252
+ `"@anyone-protocol/anyone-client" but it was not found. ` +
253
+ `Install it with: npm install @anyone-protocol/anyone-client`, { cause });
254
+ wrapped.code = 'MODULE_NOT_FOUND';
255
+ throw wrapped;
256
+ }
257
+ }
258
+ const AnonCtor = mod?.Process ?? mod?.Anon ?? mod?.default?.Process ?? mod?.default?.Anon ?? mod?.default;
259
+ if (typeof AnonCtor !== 'function') {
260
+ throw new Error('@anyone-protocol/anyone-client did not export a `Process` or `Anon` constructor; ' +
261
+ 'SDK surface may have changed.');
262
+ }
263
+ return (opts) => new AnonCtor(opts);
264
+ }
265
+ //# sourceMappingURL=managed-anon-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"managed-anon-client.js","sourceRoot":"","sources":["../../src/transport/managed-anon-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function probeTcpPort(host: string, port: number, timeoutMs: number): Promise<void>;
2
+ export declare function waitForTcpPort(host: string, port: number, overallTimeoutMs: number, perProbeTimeoutMs?: number, pollIntervalMs?: number): Promise<void>;
3
+ //# sourceMappingURL=probe-tcp-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe-tcp-port.d.ts","sourceRoot":"","sources":["../../src/transport/probe-tcp-port.ts"],"names":[],"mappings":"AAyBA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiCzF;AAeD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,SAAM,EACvB,cAAc,SAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.probeTcpPort = probeTcpPort;
4
+ exports.waitForTcpPort = waitForTcpPort;
5
+ const tslib_1 = require("tslib");
6
+ const net_1 = tslib_1.__importDefault(require("net"));
7
+ function probeTcpPort(host, port, timeoutMs) {
8
+ return new Promise((resolve, reject) => {
9
+ const socket = net_1.default.createConnection({ host, port });
10
+ let settled = false;
11
+ const cleanup = () => {
12
+ socket.removeAllListeners();
13
+ socket.destroy();
14
+ };
15
+ socket.setTimeout(timeoutMs);
16
+ socket.once('connect', () => {
17
+ if (settled)
18
+ return;
19
+ settled = true;
20
+ cleanup();
21
+ resolve();
22
+ });
23
+ socket.once('timeout', () => {
24
+ if (settled)
25
+ return;
26
+ settled = true;
27
+ cleanup();
28
+ reject(new Error(`probe timed out after ${timeoutMs}ms`));
29
+ });
30
+ socket.once('error', (err) => {
31
+ if (settled)
32
+ return;
33
+ settled = true;
34
+ cleanup();
35
+ reject(err);
36
+ });
37
+ });
38
+ }
39
+ async function waitForTcpPort(host, port, overallTimeoutMs, perProbeTimeoutMs = 250, pollIntervalMs = 100) {
40
+ const deadline = Date.now() + overallTimeoutMs;
41
+ let lastErr;
42
+ while (Date.now() < deadline) {
43
+ const remaining = deadline - Date.now();
44
+ const probeTimeout = Math.min(perProbeTimeoutMs, Math.max(1, remaining));
45
+ try {
46
+ await probeTcpPort(host, port, probeTimeout);
47
+ return;
48
+ }
49
+ catch (err) {
50
+ lastErr = err;
51
+ }
52
+ if (Date.now() + pollIntervalMs >= deadline)
53
+ break;
54
+ await new Promise((r) => setTimeout(r, pollIntervalMs));
55
+ }
56
+ throw new Error(`TCP port ${host}:${port} did not become ready within ${overallTimeoutMs}ms timeout` +
57
+ (lastErr ? ` (last error: ${lastErr.message})` : ''));
58
+ }
59
+ //# sourceMappingURL=probe-tcp-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe-tcp-port.js","sourceRoot":"","sources":["../../src/transport/probe-tcp-port.ts"],"names":[],"mappings":";;AAyBA,oCAiCC;AAeD,wCA4BC;;AAtFD,sDAAsB;AAUtB,SAAgB,YAAY,CAAC,IAAY,EAAE,IAAY,EAAE,SAAiB;IACxE,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,aAAG,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,MAAM,OAAO,GAAG,GAAS,EAAE;YACzB,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC5B,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,CAAC,CAAC;QAEF,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE7B,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;YAC1B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,CAAC;YACV,MAAM,CAAC,IAAI,KAAK,CAAC,yBAAyB,SAAS,IAAI,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YAClC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,OAAO,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAeM,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,IAAY,EACZ,gBAAwB,EACxB,iBAAiB,GAAG,GAAG,EACvB,cAAc,GAAG,GAAG;IAEpB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;IAC/C,IAAI,OAA0B,CAAC;IAE/B,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAG,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACzE,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,GAAG,GAAY,CAAC;QACzB,CAAC;QAED,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,IAAI,QAAQ;YAAE,MAAM;QACnD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,IAAI,IAAI,gCAAgC,gBAAgB,YAAY;QAClF,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACvD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type http from 'http';
2
+ import type pino from 'pino';
3
+ import type { ManagedAnonClient } from './managed-anon-client';
4
+ import type { TransportProvider } from './transport-provider';
5
+ export interface SocksTransportProviderOptions {
6
+ socksProxy: string;
7
+ externalUrl: string;
8
+ logger: pino.Logger;
9
+ managedClient?: ManagedAnonClient;
10
+ resolveExternalUrlOnStart?: () => Promise<string>;
11
+ }
12
+ export declare class SocksTransportProvider implements TransportProvider {
13
+ private readonly _socksProxy;
14
+ private _externalUrl;
15
+ private readonly _logger;
16
+ private readonly _proxyHost;
17
+ private readonly _proxyPort;
18
+ private readonly _managedClient;
19
+ private readonly _resolveExternalUrlOnStart;
20
+ private _managedHealthy;
21
+ constructor(options: SocksTransportProviderOptions);
22
+ createAgent(peerUrl: string): http.Agent;
23
+ getExternalUrl(): string;
24
+ start(): Promise<void>;
25
+ stop(): Promise<void>;
26
+ healthCheck(): Promise<boolean>;
27
+ private _probeProxy;
28
+ }
29
+ //# sourceMappingURL=socks-transport-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-transport-provider.d.ts","sourceRoot":"","sources":["../../src/transport/socks-transport-provider.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAK9D,MAAM,WAAW,6BAA6B;IAE5C,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IAOpB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAQlC,yBAAyB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACnD;AAcD,qBAAa,sBAAuB,YAAW,iBAAiB;IAC9D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgC;IAC/D,OAAO,CAAC,QAAQ,CAAC,0BAA0B,CAAsC;IACjF,OAAO,CAAC,eAAe,CAAQ;gBAOnB,OAAO,EAAE,6BAA6B;IA+ClD,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK;IAOxC,cAAc,IAAI,MAAM;IAalB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgDtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAerB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IA+DrC,OAAO,CAAC,WAAW;CAGpB"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SocksTransportProvider = void 0;
4
+ const socks_proxy_agent_1 = require("socks-proxy-agent");
5
+ const probe_tcp_port_1 = require("./probe-tcp-port");
6
+ const socks_url_1 = require("./socks-url");
7
+ const START_PROBE_TIMEOUT_MS = 2000;
8
+ const HEALTH_PROBE_TIMEOUT_MS = 1000;
9
+ class SocksTransportProvider {
10
+ _socksProxy;
11
+ _externalUrl;
12
+ _logger;
13
+ _proxyHost;
14
+ _proxyPort;
15
+ _managedClient;
16
+ _resolveExternalUrlOnStart;
17
+ _managedHealthy = true;
18
+ constructor(options) {
19
+ const { socksProxy, externalUrl, logger, managedClient, resolveExternalUrlOnStart } = options;
20
+ if (!socksProxy || typeof socksProxy !== 'string') {
21
+ throw new Error('SocksTransportProvider: socksProxy must be a non-empty string starting with "socks5h://" ' +
22
+ '(socks5h:// is required to prevent DNS leaks -- the proxy, not the local resolver, ' +
23
+ 'must resolve target hostnames)');
24
+ }
25
+ let host;
26
+ let port;
27
+ try {
28
+ const parsed = (0, socks_url_1.parseSocks5hUrl)(socksProxy);
29
+ host = parsed.host;
30
+ port = parsed.port;
31
+ }
32
+ catch (err) {
33
+ throw new Error(`SocksTransportProvider: ${err instanceof Error ? err.message : String(err)}`);
34
+ }
35
+ if (!externalUrl || typeof externalUrl !== 'string') {
36
+ throw new Error('SocksTransportProvider: externalUrl must be a non-empty string');
37
+ }
38
+ this._socksProxy = socksProxy;
39
+ this._externalUrl = externalUrl;
40
+ this._proxyHost = host;
41
+ this._proxyPort = port;
42
+ this._logger = logger.child({ component: 'socks-transport-provider' });
43
+ this._managedClient = managedClient;
44
+ this._resolveExternalUrlOnStart = resolveExternalUrlOnStart;
45
+ }
46
+ createAgent(peerUrl) {
47
+ this._logger.debug({ event: 'socks_create_agent', peerUrl }, 'Creating SOCKS5 agent for peer');
48
+ return new socks_proxy_agent_1.SocksProxyAgent(this._socksProxy);
49
+ }
50
+ getExternalUrl() {
51
+ return this._externalUrl;
52
+ }
53
+ async start() {
54
+ if (this._managedClient) {
55
+ await this._managedClient.start();
56
+ }
57
+ if (this._resolveExternalUrlOnStart) {
58
+ try {
59
+ const resolved = await this._resolveExternalUrlOnStart();
60
+ if (!resolved || typeof resolved !== 'string') {
61
+ throw new Error('resolver returned a non-string value');
62
+ }
63
+ if (!resolved.startsWith('ws://') && !resolved.startsWith('wss://')) {
64
+ throw new Error('resolved externalUrl must start with ws:// or wss://');
65
+ }
66
+ this._externalUrl = resolved;
67
+ }
68
+ catch (err) {
69
+ const reason = err instanceof Error ? err.message : String(err);
70
+ throw new Error(`SocksTransportProvider: failed to resolve externalUrl from managed hidden service (${reason})`);
71
+ }
72
+ }
73
+ try {
74
+ await this._probeProxy(START_PROBE_TIMEOUT_MS);
75
+ }
76
+ catch (err) {
77
+ const reason = err instanceof Error ? err.message : String(err);
78
+ throw new Error(`SocksTransportProvider: SOCKS5 proxy unreachable at ${this._proxyHost}:${this._proxyPort} (${reason})`);
79
+ }
80
+ this._managedHealthy = true;
81
+ this._logger.info({ event: 'socks_transport_started', proxyHost: this._proxyHost, proxyPort: this._proxyPort }, 'SOCKS5 transport started');
82
+ }
83
+ async stop() {
84
+ this._logger.info({ event: 'socks_transport_stopped' }, 'SOCKS5 transport stopped');
85
+ if (this._managedClient) {
86
+ await this._managedClient.stop();
87
+ }
88
+ }
89
+ async healthCheck() {
90
+ let managedOk = true;
91
+ if (this._managedClient) {
92
+ try {
93
+ managedOk = await this._managedClient.healthCheck();
94
+ }
95
+ catch {
96
+ managedOk = false;
97
+ }
98
+ if (!managedOk && this._managedHealthy) {
99
+ this._managedHealthy = false;
100
+ this._logger.warn({
101
+ event: 'managed_anon_crash_detected',
102
+ proxyHost: this._proxyHost,
103
+ proxyPort: this._proxyPort,
104
+ }, 'Managed anon client reports not running');
105
+ }
106
+ else if (managedOk) {
107
+ this._managedHealthy = true;
108
+ }
109
+ }
110
+ try {
111
+ await this._probeProxy(HEALTH_PROBE_TIMEOUT_MS);
112
+ if (!managedOk) {
113
+ return false;
114
+ }
115
+ this._logger.debug({
116
+ event: 'socks_transport_health_ok',
117
+ proxyHost: this._proxyHost,
118
+ proxyPort: this._proxyPort,
119
+ }, 'SOCKS5 proxy healthy');
120
+ return true;
121
+ }
122
+ catch {
123
+ this._logger.warn({
124
+ event: 'socks_transport_health_failed',
125
+ proxyHost: this._proxyHost,
126
+ proxyPort: this._proxyPort,
127
+ }, 'SOCKS5 proxy health check failed');
128
+ return false;
129
+ }
130
+ }
131
+ _probeProxy(timeoutMs) {
132
+ return (0, probe_tcp_port_1.probeTcpPort)(this._proxyHost, this._proxyPort, timeoutMs);
133
+ }
134
+ }
135
+ exports.SocksTransportProvider = SocksTransportProvider;
136
+ //# sourceMappingURL=socks-transport-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-transport-provider.js","sourceRoot":"","sources":["../../src/transport/socks-transport-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface ParsedSocks5Url {
2
+ host: string;
3
+ port: number;
4
+ }
5
+ export declare function parseSocks5hUrl(socksProxy: string): ParsedSocks5Url;
6
+ //# sourceMappingURL=socks-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-url.d.ts","sourceRoot":"","sources":["../../src/transport/socks-url.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,eAAe;IAE9B,IAAI,EAAE,MAAM,CAAC;IAEb,IAAI,EAAE,MAAM,CAAC;CACd;AAYD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAiCnE"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSocks5hUrl = parseSocks5hUrl;
4
+ function parseSocks5hUrl(socksProxy) {
5
+ if (!socksProxy || typeof socksProxy !== 'string') {
6
+ throw new Error('socksProxy must be a non-empty string starting with "socks5h://" ' +
7
+ '(socks5h:// is required to prevent DNS leaks -- the proxy, not the local resolver, ' +
8
+ 'must resolve target hostnames)');
9
+ }
10
+ if (!socksProxy.startsWith('socks5h://')) {
11
+ throw new Error(`socksProxy scheme must be "socks5h://" (got "${socksProxy.split('://')[0]}://"). ` +
12
+ 'The "h" suffix is required to prevent DNS leaks: with socks5h, hostname resolution ' +
13
+ 'happens at the proxy (Tor exit / ATOR), not on the local host.');
14
+ }
15
+ let parsed;
16
+ try {
17
+ parsed = new URL(socksProxy.replace(/^socks5h:\/\//, 'http://'));
18
+ }
19
+ catch {
20
+ throw new Error(`socksProxy is not a valid URL (expected socks5h://host:port)`);
21
+ }
22
+ const host = parsed.hostname;
23
+ const port = parsed.port ? Number.parseInt(parsed.port, 10) : NaN;
24
+ if (!host || !Number.isFinite(port) || port < 0 || port > 65535) {
25
+ throw new Error('socksProxy must include a valid host and port (e.g., socks5h://127.0.0.1:9050)');
26
+ }
27
+ return { host, port };
28
+ }
29
+ //# sourceMappingURL=socks-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socks-url.js","sourceRoot":"","sources":["../../src/transport/socks-url.ts"],"names":[],"mappings":";;AA8BA,0CAiCC;AAjCD,SAAgB,eAAe,CAAC,UAAkB;IAChD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,mEAAmE;YACjE,qFAAqF;YACrF,gCAAgC,CACnC,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,KAAK,CACb,gDAAgD,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;YACjF,qFAAqF;YACrF,gEAAgE,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAClF,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC7B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAClE,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,gFAAgF,CACjF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type http from 'http';
2
+ export interface TransportProvider {
3
+ createAgent(peerUrl: string): http.Agent | undefined;
4
+ getExternalUrl(): string;
5
+ start(): Promise<void>;
6
+ stop(): Promise<void>;
7
+ healthCheck(): Promise<boolean>;
8
+ }
9
+ //# sourceMappingURL=transport-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-provider.d.ts","sourceRoot":"","sources":["../../src/transport/transport-provider.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAY7B,MAAM,WAAW,iBAAiB;IAYhC,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;IASrD,cAAc,IAAI,MAAM,CAAC;IASzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IASvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAStB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=transport-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-provider.js","sourceRoot":"","sources":["../../src/transport/transport-provider.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ export declare function redactPeerUrl(url: string): string;
2
+ export declare function redactAnonInMessage(message: string): string;
3
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/utils/redact.ts"],"names":[],"mappings":"AA+BA,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMjD;AAuBD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAI3D"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.redactPeerUrl = redactPeerUrl;
4
+ exports.redactAnonInMessage = redactAnonInMessage;
5
+ const REDACTION_SENTINEL = '<redacted-anon>';
6
+ function redactPeerUrl(url) {
7
+ if (!url)
8
+ return url;
9
+ if (url.toLowerCase().includes('.anon')) {
10
+ return REDACTION_SENTINEL;
11
+ }
12
+ return url;
13
+ }
14
+ function redactAnonInMessage(message) {
15
+ if (!message)
16
+ return message;
17
+ if (!message.toLowerCase().includes('.anon'))
18
+ return message;
19
+ return message.replace(/\S*\.anon\S*/gi, REDACTION_SENTINEL);
20
+ }
21
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/utils/redact.ts"],"names":[],"mappings":";;AA+BA,sCAMC;AAuBD,kDAIC;AAjDD,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAgB7C,SAAgB,aAAa,CAAC,GAAW;IACvC,IAAI,CAAC,GAAG;QAAE,OAAO,GAAG,CAAC;IACrB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,kBAAkB,CAAC;IAC5B,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAuBD,SAAgB,mBAAmB,CAAC,OAAe;IACjD,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAC7B,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7D,OAAO,OAAO,CAAC,OAAO,CAAC,gBAAgB,EAAE,kBAAkB,CAAC,CAAC;AAC/D,CAAC"}