@erfan_bahramali/tping 1.0.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.
- package/LICENSE +21 -0
- package/README.md +118 -0
- package/dist/crypto/aes-ctr.d.ts +18 -0
- package/dist/crypto/aes-ctr.d.ts.map +1 -0
- package/dist/crypto/aes-ctr.js +30 -0
- package/dist/crypto/aes-ctr.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/checker.d.ts +6 -0
- package/dist/lib/checker.d.ts.map +1 -0
- package/dist/lib/checker.js +72 -0
- package/dist/lib/checker.js.map +1 -0
- package/dist/lib/parser.d.ts +7 -0
- package/dist/lib/parser.d.ts.map +1 -0
- package/dist/lib/parser.js +96 -0
- package/dist/lib/parser.js.map +1 -0
- package/dist/lib/ping.d.ts +10 -0
- package/dist/lib/ping.d.ts.map +1 -0
- package/dist/lib/ping.js +59 -0
- package/dist/lib/ping.js.map +1 -0
- package/dist/mtproto/connection.d.ts +59 -0
- package/dist/mtproto/connection.d.ts.map +1 -0
- package/dist/mtproto/connection.js +198 -0
- package/dist/mtproto/connection.js.map +1 -0
- package/dist/mtproto/fake-tls.d.ts +56 -0
- package/dist/mtproto/fake-tls.d.ts.map +1 -0
- package/dist/mtproto/fake-tls.js +175 -0
- package/dist/mtproto/fake-tls.js.map +1 -0
- package/dist/mtproto/messages.d.ts +48 -0
- package/dist/mtproto/messages.d.ts.map +1 -0
- package/dist/mtproto/messages.js +104 -0
- package/dist/mtproto/messages.js.map +1 -0
- package/dist/mtproto/obfuscation.d.ts +26 -0
- package/dist/mtproto/obfuscation.d.ts.map +1 -0
- package/dist/mtproto/obfuscation.js +78 -0
- package/dist/mtproto/obfuscation.js.map +1 -0
- package/dist/mtproto/socks5.d.ts +36 -0
- package/dist/mtproto/socks5.d.ts.map +1 -0
- package/dist/mtproto/socks5.js +148 -0
- package/dist/mtproto/socks5.js.map +1 -0
- package/dist/types/index.d.ts +49 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/format.d.ts +22 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +131 -0
- package/dist/utils/format.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Erfan Bahramali
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# 🏓 tping
|
|
2
|
+
|
|
3
|
+
**Ping for Telegram Proxies** - Test connectivity to Telegram Proxies, just like `ping` for IP addresses.
|
|
4
|
+
|
|
5
|
+
A simple and clean CLI tool to continuously ping Telegram proxies (MTProto and SOCKS5) and measure latency in real-time using official Telegram API.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## ✨ Features
|
|
10
|
+
|
|
11
|
+
- 🏓 **Continuous ping mode** - Like standard `ping` command
|
|
12
|
+
- 🔄 **Multiple proxies** - Ping simultaneously
|
|
13
|
+
- ⚙️ **Configurable** - Custom count and interval
|
|
14
|
+
- 📊 **Statistics** - min/avg/max latency, packet loss
|
|
15
|
+
- 🚀 **Simple & clean** - Easy to use
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g @erfan_bahramali/tping
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Or use directly with npx:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npx @erfan_bahramali/tping <proxy>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 🚀 Usage
|
|
34
|
+
|
|
35
|
+
You can pass proxy as text or file path. For multiple proxies, separate by newlines (in text or file).
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Single proxy
|
|
39
|
+
tping "https://t.me/proxy?server=proxy.example.com&port=443&secret=0123456789abcdef"
|
|
40
|
+
|
|
41
|
+
# Multiple proxies
|
|
42
|
+
tping "https://t.me/proxy?server=proxy1.com&port=443&secret=abc
|
|
43
|
+
https://t.me/socks?server=proxy2.com&port=1080"
|
|
44
|
+
|
|
45
|
+
# From file (single or multiple proxies)
|
|
46
|
+
tping proxies.txt
|
|
47
|
+
|
|
48
|
+
# Ping 5 times
|
|
49
|
+
tping -c 5 "https://t.me/socks?server=proxy.example.com&port=1080"
|
|
50
|
+
|
|
51
|
+
# Ping unlimited times with custom interval (500ms)
|
|
52
|
+
tping -i 500 "https://t.me/socks?server=proxy.example.com&port=1080"
|
|
53
|
+
|
|
54
|
+
# Ping 10 times with custom interval (500ms)
|
|
55
|
+
tping -c 10 -i 500 proxies.txt
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## ⚙️ Options
|
|
61
|
+
|
|
62
|
+
| Option | Description |
|
|
63
|
+
|--------|-------------|
|
|
64
|
+
| `-c, --count <n>` | Number of pings to send (default: unlimited) |
|
|
65
|
+
| `-i, --interval <ms>` | Interval between pings in milliseconds (default: 1000) |
|
|
66
|
+
| `-t, --timeout <ms>` | Timeout for each ping in milliseconds (default: 10000) |
|
|
67
|
+
| `-v, --version` | Show version number |
|
|
68
|
+
| `-h, --help` | Show help |
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 📊 Example Output
|
|
73
|
+
|
|
74
|
+
```
|
|
75
|
+
🏓 PING proxy.example.com:443 (MTProto)
|
|
76
|
+
Sending pings with 1000ms interval... (Press Ctrl+C to stop)
|
|
77
|
+
|
|
78
|
+
✓ proxy.example.com:443 │ MTProto │ seq=1 │ 45ms
|
|
79
|
+
✓ proxy.example.com:443 │ MTProto │ seq=2 │ 48ms
|
|
80
|
+
✓ proxy.example.com:443 │ MTProto │ seq=3 │ 43ms
|
|
81
|
+
^C
|
|
82
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
83
|
+
📊 Statistics for proxy.example.com:443
|
|
84
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
85
|
+
Packets: 3 sent │ 3 received │ 0% loss
|
|
86
|
+
Latency: 43ms min │ 45ms avg │ 48ms max
|
|
87
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 🔍 How it Works
|
|
93
|
+
|
|
94
|
+
tping performs a **real MTProto handshake** through the proxy — the same first
|
|
95
|
+
step every official Telegram client does:
|
|
96
|
+
|
|
97
|
+
1. **Transport obfuscation** — a 64-byte header is generated with AES-256-CTR
|
|
98
|
+
keys derived from the proxy secret (per the official
|
|
99
|
+
[MTProto transport obfuscation](https://core.telegram.org/mtproto/mtproto-transports#transport-obfuscation)).
|
|
100
|
+
2. **Fake TLS** (secrets with `ee` prefix) — a TLS 1.3 ClientHello with a valid
|
|
101
|
+
HMAC digest is sent; the proxy's signed ServerHello is verified before any
|
|
102
|
+
data is trusted. Wrong secrets are detected immediately.
|
|
103
|
+
3. **MTProto ping** — a `req_pq_multi` request is sent through the proxy to the
|
|
104
|
+
Telegram datacenter. The measured latency is the round trip of receiving a
|
|
105
|
+
valid `resPQ` reply with our echoed nonce. A proxy only passes if the
|
|
106
|
+
datacenter actually answers — dead or fake proxies are reported as failures,
|
|
107
|
+
never as successes.
|
|
108
|
+
|
|
109
|
+
SOCKS5 proxies are checked by negotiating a connection to a Telegram datacenter
|
|
110
|
+
through them.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 📋 License
|
|
115
|
+
|
|
116
|
+
MIT © 2026 [ErfanBahramali](https://github.com/ErfanBahramali)
|
|
117
|
+
|
|
118
|
+
---
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-CTR cipher with continuous counter mode.
|
|
3
|
+
* Used for MTProto obfuscation layer encryption.
|
|
4
|
+
*/
|
|
5
|
+
export declare class AESCTR {
|
|
6
|
+
private cipher;
|
|
7
|
+
/**
|
|
8
|
+
* @param key - 32 bytes encryption key
|
|
9
|
+
* @param iv - 16 bytes initialization vector (counter)
|
|
10
|
+
*/
|
|
11
|
+
constructor(key: Buffer, iv: Buffer);
|
|
12
|
+
/**
|
|
13
|
+
* Encrypt/decrypt data (CTR mode is symmetric).
|
|
14
|
+
* Maintains internal counter state across multiple calls.
|
|
15
|
+
*/
|
|
16
|
+
encrypt(data: Buffer): Buffer;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=aes-ctr.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-ctr.d.ts","sourceRoot":"","sources":["../../src/crypto/aes-ctr.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAoC;IAElD;;;OAGG;gBACS,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;IAYnC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAG9B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createCipheriv } from 'crypto';
|
|
2
|
+
/**
|
|
3
|
+
* AES-256-CTR cipher with continuous counter mode.
|
|
4
|
+
* Used for MTProto obfuscation layer encryption.
|
|
5
|
+
*/
|
|
6
|
+
export class AESCTR {
|
|
7
|
+
cipher;
|
|
8
|
+
/**
|
|
9
|
+
* @param key - 32 bytes encryption key
|
|
10
|
+
* @param iv - 16 bytes initialization vector (counter)
|
|
11
|
+
*/
|
|
12
|
+
constructor(key, iv) {
|
|
13
|
+
if (key.length !== 32) {
|
|
14
|
+
throw new Error('AES-256 key must be 32 bytes');
|
|
15
|
+
}
|
|
16
|
+
if (iv.length !== 16) {
|
|
17
|
+
throw new Error('IV must be 16 bytes');
|
|
18
|
+
}
|
|
19
|
+
// CTR mode doesn't distinguish between encrypt/decrypt
|
|
20
|
+
this.cipher = createCipheriv('aes-256-ctr', key, iv);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Encrypt/decrypt data (CTR mode is symmetric).
|
|
24
|
+
* Maintains internal counter state across multiple calls.
|
|
25
|
+
*/
|
|
26
|
+
encrypt(data) {
|
|
27
|
+
return this.cipher.update(data);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=aes-ctr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes-ctr.js","sourceRoot":"","sources":["../../src/crypto/aes-ctr.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAExC;;;GAGG;AACH,MAAM,OAAO,MAAM;IACT,MAAM,CAAoC;IAElD;;;OAGG;IACH,YAAY,GAAW,EAAE,EAAU;QACjC,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QACD,IAAI,EAAE,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC;QAED,uDAAuD;QACvD,IAAI,CAAC,MAAM,GAAG,cAAc,CAAC,aAAa,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;;OAGG;IACH,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;CACF"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { program } from 'commander';
|
|
4
|
+
import { parseProxies } from './lib/parser.js';
|
|
5
|
+
import { pingProxy } from './lib/ping.js';
|
|
6
|
+
program
|
|
7
|
+
.name('tping')
|
|
8
|
+
.description('Ping for Telegram Proxies')
|
|
9
|
+
.version('1.0.0', '-v, --version')
|
|
10
|
+
.argument('[proxy]', 'Proxy URL or file path (supports MTProto, SOCKS5)')
|
|
11
|
+
.option('-c, --count <n>', 'Number of pings to send (default: unlimited)', parseInt)
|
|
12
|
+
.option('-i, --interval <ms>', 'Interval between pings in milliseconds (default: 1000)', parseInt)
|
|
13
|
+
.option('-t, --timeout <ms>', 'Timeout for each ping in milliseconds (default: 10000)', parseInt)
|
|
14
|
+
.showHelpAfterError('(add --help for additional information)')
|
|
15
|
+
.addHelpText('after', `
|
|
16
|
+
Supported proxy formats:
|
|
17
|
+
MTProto: "https://t.me/proxy?server=...&port=...&secret=..."
|
|
18
|
+
MTProto: "tg://proxy?server=...&port=...&secret=..."
|
|
19
|
+
SOCKS5: "https://t.me/socks?server=...&port=...&user=...&pass=..."
|
|
20
|
+
SOCKS5: "tg://socks?server=...&port=...&user=...&pass=..."
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
$ tping "https://t.me/proxy?server=proxy.example.com&port=443&secret=0123456789abcdef"
|
|
24
|
+
$ tping -c 5 "https://t.me/socks?server=proxy.example.com&port=1080"
|
|
25
|
+
$ tping -c 10 -i 500 "tg://socks?server=proxy.example.com&port=1080&user=admin&pass=secret"
|
|
26
|
+
$ tping proxies.txt
|
|
27
|
+
`)
|
|
28
|
+
.action(async (proxyInput, options) => {
|
|
29
|
+
if (!proxyInput) {
|
|
30
|
+
program.help();
|
|
31
|
+
}
|
|
32
|
+
// Parse proxies
|
|
33
|
+
const proxies = parseProxies(proxyInput);
|
|
34
|
+
if (proxies.length === 0) {
|
|
35
|
+
console.log(chalk.red('Error: Invalid proxy format'));
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
options.interval = options.interval || 1000;
|
|
39
|
+
options.timeout = options.timeout || 10000;
|
|
40
|
+
// Print header
|
|
41
|
+
console.log();
|
|
42
|
+
console.log(chalk.bold.cyan('🏓 TPing'));
|
|
43
|
+
console.log(chalk.gray('━'.repeat(50)));
|
|
44
|
+
console.log(chalk.cyan(`📡 Proxies: ${chalk.white(proxies.length)}`));
|
|
45
|
+
console.log(chalk.cyan(`🎯 Count: ${chalk.white(options.count || 'unlimited')}`));
|
|
46
|
+
console.log(chalk.cyan(`⏰ Interval: ${chalk.white(options.interval + 'ms')}`));
|
|
47
|
+
console.log(chalk.cyan(`⏳ Timeout: ${chalk.white(options.timeout + 'ms')}`));
|
|
48
|
+
console.log(chalk.gray('━'.repeat(50)));
|
|
49
|
+
console.log();
|
|
50
|
+
// Setup abort controller for Ctrl+C
|
|
51
|
+
const abortController = new AbortController();
|
|
52
|
+
let isAborting = false;
|
|
53
|
+
const handleAbort = async () => {
|
|
54
|
+
if (isAborting) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
isAborting = true;
|
|
58
|
+
abortController.abort();
|
|
59
|
+
console.log(chalk.yellow('\n⏸️ Stopping... (Press Ctrl+C again to force quit)'));
|
|
60
|
+
};
|
|
61
|
+
process.on('SIGINT', handleAbort);
|
|
62
|
+
process.on('SIGTERM', handleAbort);
|
|
63
|
+
await pingProxy(proxies, options, abortController.signal);
|
|
64
|
+
process.exit(0);
|
|
65
|
+
}).parse();
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../../src/lib/checker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA0EpE;;GAEG;AACH,eAAO,MAAM,UAAU,GACrB,OAAO,aAAa,EACpB,UAAS,MAAc,KACtB,OAAO,CAAC,WAAW,CAQrB,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { MTProtoConnection } from '../mtproto/connection.js';
|
|
2
|
+
import { SOCKS5Client } from '../mtproto/socks5.js';
|
|
3
|
+
/**
|
|
4
|
+
* Ping an MTProto proxy with a real MTProto handshake (req_pq -> ResPQ).
|
|
5
|
+
* Latency includes TCP + obfuscation (+ fake TLS) handshake + the MTProto round trip.
|
|
6
|
+
*/
|
|
7
|
+
const pingMTProtoProxy = async (proxy, timeout) => {
|
|
8
|
+
if (proxy.type !== 'mtproto' || !proxy.secret) {
|
|
9
|
+
return { proxy, success: false, error: 'Invalid MTProto configuration' };
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const latency = await MTProtoConnection.pingOnce({
|
|
13
|
+
host: proxy.server,
|
|
14
|
+
port: proxy.port,
|
|
15
|
+
secret: proxy.secret,
|
|
16
|
+
timeout,
|
|
17
|
+
}, timeout);
|
|
18
|
+
return { proxy, success: true, latency };
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
return {
|
|
22
|
+
proxy,
|
|
23
|
+
success: false,
|
|
24
|
+
error: err instanceof Error ? err.message : 'Connection failed',
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Ping a SOCKS5 proxy by connecting through it to a Telegram datacenter.
|
|
30
|
+
*/
|
|
31
|
+
const pingSOCKS5Proxy = async (proxy, timeout) => {
|
|
32
|
+
if (proxy.type !== 'socks5') {
|
|
33
|
+
return { proxy, success: false, error: 'Invalid SOCKS5 configuration' };
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const client = new SOCKS5Client({
|
|
37
|
+
host: proxy.server,
|
|
38
|
+
port: proxy.port,
|
|
39
|
+
username: proxy.username,
|
|
40
|
+
password: proxy.password,
|
|
41
|
+
timeout,
|
|
42
|
+
});
|
|
43
|
+
const start = Date.now();
|
|
44
|
+
await client.connect();
|
|
45
|
+
const ok = await client.testConnection();
|
|
46
|
+
client.close();
|
|
47
|
+
if (!ok) {
|
|
48
|
+
return { proxy, success: false, error: 'Connection test failed' };
|
|
49
|
+
}
|
|
50
|
+
return { proxy, success: true, latency: Date.now() - start };
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
return {
|
|
54
|
+
proxy,
|
|
55
|
+
success: false,
|
|
56
|
+
error: err instanceof Error ? err.message : 'Connection failed',
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Ping any proxy type.
|
|
62
|
+
*/
|
|
63
|
+
export const checkProxy = async (proxy, timeout = 10000) => {
|
|
64
|
+
if (proxy.type === 'mtproto') {
|
|
65
|
+
return pingMTProtoProxy(proxy, timeout);
|
|
66
|
+
}
|
|
67
|
+
if (proxy.type === 'socks5') {
|
|
68
|
+
return pingSOCKS5Proxy(proxy, timeout);
|
|
69
|
+
}
|
|
70
|
+
return { proxy, success: false, error: 'Unsupported proxy type' };
|
|
71
|
+
};
|
|
72
|
+
//# sourceMappingURL=checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checker.js","sourceRoot":"","sources":["../../src/lib/checker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { TelegramProxy } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse proxies from input string or file.
|
|
4
|
+
* Automatically detects if input is a file path or proxy text.
|
|
5
|
+
*/
|
|
6
|
+
export declare const parseProxies: (input: string) => readonly TelegramProxy[];
|
|
7
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA4EvD;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,OAAO,MAAM,KAAG,SAAS,aAAa,EA0BlE,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'fs';
|
|
2
|
+
/**
|
|
3
|
+
* Valid Telegram proxy URL prefixes
|
|
4
|
+
*/
|
|
5
|
+
const TELEGRAM_PROXY_PREFIXES = [
|
|
6
|
+
'https://t.me/proxy?',
|
|
7
|
+
'https://telegram.me/proxy?',
|
|
8
|
+
'https://telegram.dog/proxy?',
|
|
9
|
+
'tg://proxy?',
|
|
10
|
+
];
|
|
11
|
+
const TELEGRAM_SOCKS_PREFIXES = [
|
|
12
|
+
'https://t.me/socks?',
|
|
13
|
+
'https://telegram.me/socks?',
|
|
14
|
+
'https://telegram.dog/socks?',
|
|
15
|
+
'tg://socks?',
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Parse proxy string in Telegram URL format.
|
|
19
|
+
*/
|
|
20
|
+
const parseProxyString = (line) => {
|
|
21
|
+
// Strip shell-escape backslashes before URL punctuation (e.g. t.me/proxy\?...\&...)
|
|
22
|
+
const trimmed = line
|
|
23
|
+
.replace(/\\([?=&#])/g, '$1')
|
|
24
|
+
.replace(/\+/g, '%2B')
|
|
25
|
+
.trim();
|
|
26
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const url = new URL(trimmed);
|
|
31
|
+
// Check if it's MTProto proxy
|
|
32
|
+
if (TELEGRAM_PROXY_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
|
|
33
|
+
const server = url.searchParams.get('server');
|
|
34
|
+
const port = url.searchParams.get('port');
|
|
35
|
+
const secret = url.searchParams.get('secret');
|
|
36
|
+
if (server && port && secret) {
|
|
37
|
+
return {
|
|
38
|
+
type: 'mtproto',
|
|
39
|
+
server,
|
|
40
|
+
port: parseInt(port, 10),
|
|
41
|
+
secret,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Check if it's SOCKS5 proxy
|
|
46
|
+
if (TELEGRAM_SOCKS_PREFIXES.some((prefix) => trimmed.startsWith(prefix))) {
|
|
47
|
+
const server = url.searchParams.get('server');
|
|
48
|
+
const port = url.searchParams.get('port');
|
|
49
|
+
const user = url.searchParams.get('user');
|
|
50
|
+
const pass = url.searchParams.get('pass');
|
|
51
|
+
if (server && port) {
|
|
52
|
+
return {
|
|
53
|
+
type: 'socks5',
|
|
54
|
+
server,
|
|
55
|
+
port: parseInt(port, 10),
|
|
56
|
+
username: user || undefined,
|
|
57
|
+
password: pass || undefined,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Parse proxies from input string or file.
|
|
69
|
+
* Automatically detects if input is a file path or proxy text.
|
|
70
|
+
*/
|
|
71
|
+
export const parseProxies = (input) => {
|
|
72
|
+
let content;
|
|
73
|
+
// Check if input is a file path
|
|
74
|
+
if (existsSync(input)) {
|
|
75
|
+
try {
|
|
76
|
+
content = readFileSync(input, 'utf-8');
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
content = input;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
content = input;
|
|
84
|
+
}
|
|
85
|
+
// Parse each line
|
|
86
|
+
const proxies = [];
|
|
87
|
+
const lines = content.split(/\r?\n/);
|
|
88
|
+
for (const line of lines) {
|
|
89
|
+
const proxy = parseProxyString(line);
|
|
90
|
+
if (proxy) {
|
|
91
|
+
proxies.push(proxy);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return proxies;
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/lib/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TelegramProxy, CheckResult } from '../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Ping proxies continuously.
|
|
4
|
+
*/
|
|
5
|
+
export declare const pingProxy: (proxies: readonly TelegramProxy[], options: {
|
|
6
|
+
count?: number;
|
|
7
|
+
interval?: number;
|
|
8
|
+
timeout?: number;
|
|
9
|
+
}, signal?: AbortSignal) => Promise<readonly CheckResult[][]>;
|
|
10
|
+
//# sourceMappingURL=ping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ping.d.ts","sourceRoot":"","sources":["../../src/lib/ping.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIpE;;GAEG;AACH,eAAO,MAAM,SAAS,GAClB,SAAS,SAAS,aAAa,EAAE,EACjC,SAAS;IACL,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB,EACD,SAAS,WAAW,KACrB,OAAO,CAAC,SAAS,WAAW,EAAE,EAAE,CAmElC,CAAC"}
|
package/dist/lib/ping.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { checkProxy } from './checker.js';
|
|
2
|
+
import { printPingResult, printPingStatistics } from '../utils/format.js';
|
|
3
|
+
/**
|
|
4
|
+
* Ping proxies continuously.
|
|
5
|
+
*/
|
|
6
|
+
export const pingProxy = async (proxies, options, signal) => {
|
|
7
|
+
const { count, interval = 1000, timeout = 10000 } = options;
|
|
8
|
+
let shouldStop = false;
|
|
9
|
+
// Handle abort signal
|
|
10
|
+
if (signal) {
|
|
11
|
+
signal.addEventListener('abort', () => {
|
|
12
|
+
shouldStop = true;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
const sleep = (ms) => {
|
|
16
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
17
|
+
};
|
|
18
|
+
// Initialize results array for each proxy
|
|
19
|
+
const allResults = proxies.map(() => []);
|
|
20
|
+
let sequence = 1;
|
|
21
|
+
// Main ping loop - all proxies tested together
|
|
22
|
+
while (!shouldStop) {
|
|
23
|
+
// Check if we've reached the count limit
|
|
24
|
+
if (count !== undefined && sequence > count) {
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
// Show testing status for all proxies
|
|
28
|
+
for (let i = 0; i < proxies.length; i++) {
|
|
29
|
+
printPingResult(i, proxies, sequence, 'testing');
|
|
30
|
+
process.stdout.write('\n');
|
|
31
|
+
}
|
|
32
|
+
// Ping all proxies in parallel with real-time updates
|
|
33
|
+
await Promise.all(proxies.map(async (proxy, i) => {
|
|
34
|
+
const result = await checkProxy(proxy, timeout);
|
|
35
|
+
allResults[i].push(result);
|
|
36
|
+
// Move cursor to the correct line and update
|
|
37
|
+
const lineOffset = proxies.length - i;
|
|
38
|
+
process.stdout.write(`\x1b[${lineOffset}A`); // Move up
|
|
39
|
+
printPingResult(i, proxies, sequence, 'done', result);
|
|
40
|
+
process.stdout.write(`\x1b[${lineOffset}B`); // Move back down
|
|
41
|
+
}));
|
|
42
|
+
// Move to position after all lines
|
|
43
|
+
process.stdout.write('\n');
|
|
44
|
+
sequence++;
|
|
45
|
+
// Check if aborted or should stop
|
|
46
|
+
if (shouldStop) {
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
// Wait for interval before next ping (unless it's the last one)
|
|
50
|
+
if (count === undefined || sequence <= count) {
|
|
51
|
+
if (!shouldStop) {
|
|
52
|
+
await sleep(interval);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
printPingStatistics(proxies, allResults);
|
|
57
|
+
return allResults;
|
|
58
|
+
};
|
|
59
|
+
//# sourceMappingURL=ping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ping.js","sourceRoot":"","sources":["../../src/lib/ping.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE1E;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAC1B,OAAiC,EACjC,OAIC,EACD,MAAoB,EACa,EAAE;IACnC,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAC5D,IAAI,UAAU,GAAG,KAAK,CAAC;IAEvB,sBAAsB;IACtB,IAAI,MAAM,EAAE,CAAC;QACT,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YAClC,UAAU,GAAG,IAAI,CAAC;QACtB,CAAC,CAAC,CAAC;IACP,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,EAAU,EAAiB,EAAE;QACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,0CAA0C;IAC1C,MAAM,UAAU,GAAoB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1D,IAAI,QAAQ,GAAG,CAAC,CAAC;IAEjB,+CAA+C;IAC/C,OAAO,CAAC,UAAU,EAAE,CAAC;QACjB,yCAAyC;QACzC,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,GAAG,KAAK,EAAE,CAAC;YAC1C,MAAM;QACV,CAAC;QAED,sCAAsC;QACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;YACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;QAED,sDAAsD;QACtD,MAAM,OAAO,CAAC,GAAG,CACb,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YAC3B,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAChD,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE3B,6CAA6C;YAC7C,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,UAAU,GAAG,CAAC,CAAC,CAAC,UAAU;YACvD,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;YACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,UAAU,GAAG,CAAC,CAAC,CAAC,iBAAiB;QAClE,CAAC,CAAC,CACL,CAAC;QAEF,mCAAmC;QACnC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE3B,QAAQ,EAAE,CAAC;QAEX,kCAAkC;QAClC,IAAI,UAAU,EAAE,CAAC;YACb,MAAM;QACV,CAAC;QAED,gEAAgE;QAChE,IAAI,KAAK,KAAK,SAAS,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,MAAM,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1B,CAAC;QACL,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;IAEzC,OAAO,UAAU,CAAC;AACtB,CAAC,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export interface MTProtoConnectionOptions {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
secret: string;
|
|
5
|
+
dcId?: number;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* MTProto proxy connection supporting both simple (dd) and fake TLS (ee) modes.
|
|
10
|
+
*
|
|
11
|
+
* A ping is a real MTProto handshake: req_pq_multi is sent and a valid ResPQ
|
|
12
|
+
* must come back from the Telegram datacenter. In fake TLS mode the proxy's
|
|
13
|
+
* ServerHello is also verified against an HMAC of the proxy secret, so a wrong
|
|
14
|
+
* secret is detected immediately.
|
|
15
|
+
*/
|
|
16
|
+
export declare class MTProtoConnection {
|
|
17
|
+
private options;
|
|
18
|
+
private socket;
|
|
19
|
+
private encryptor?;
|
|
20
|
+
private decryptor?;
|
|
21
|
+
private isFakeTLS;
|
|
22
|
+
private receiveBuffer;
|
|
23
|
+
private pending;
|
|
24
|
+
private phase;
|
|
25
|
+
private clientRandom?;
|
|
26
|
+
constructor(options: MTProtoConnectionOptions);
|
|
27
|
+
/**
|
|
28
|
+
* Connect to the MTProto proxy and perform the obfuscation (+ fake TLS) handshake.
|
|
29
|
+
* Resolves only after the proxy's ServerHello is HMAC-verified (fake TLS mode).
|
|
30
|
+
*/
|
|
31
|
+
connect(): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Send a real MTProto ping: req_pq_multi and wait for a valid ResPQ.
|
|
34
|
+
*
|
|
35
|
+
* @returns Round-trip time in ms
|
|
36
|
+
*/
|
|
37
|
+
ping(timeout?: number): Promise<number>;
|
|
38
|
+
/**
|
|
39
|
+
* Connect + single real ping in one call. Closes the connection afterwards.
|
|
40
|
+
*/
|
|
41
|
+
static pingOnce(options: MTProtoConnectionOptions, timeout?: number): Promise<number>;
|
|
42
|
+
/**
|
|
43
|
+
* Handle incoming socket data depending on the current phase.
|
|
44
|
+
*/
|
|
45
|
+
private onData;
|
|
46
|
+
/**
|
|
47
|
+
* Wait until the FakeTLS ServerHello can be verified.
|
|
48
|
+
*/
|
|
49
|
+
private awaitVerdict;
|
|
50
|
+
/**
|
|
51
|
+
* Reject any pending waiters (socket closed mid-handshake/ping).
|
|
52
|
+
*/
|
|
53
|
+
private failPending;
|
|
54
|
+
/**
|
|
55
|
+
* Close the connection.
|
|
56
|
+
*/
|
|
57
|
+
close(): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../src/mtproto/connection.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID;;;;;;;GAOG;AACH,qBAAa,iBAAiB;IAUhB,OAAO,CAAC,OAAO;IAT3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,OAAO,CAAyC;IACxD,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAS;gBAEV,OAAO,EAAE,wBAAwB;IAOrD;;;OAGG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6C9B;;;;OAIG;IACG,IAAI,CAAC,OAAO,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IA2C5C;;OAEG;WACU,QAAQ,CAAC,OAAO,EAAE,wBAAwB,EAAE,OAAO,SAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;IAU1F;;OAEG;IACH,OAAO,CAAC,MAAM;IA4Bd;;OAEG;YACW,YAAY;IAyB1B;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}
|