@mtkruto/node 0.0.6
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 +165 -0
- package/README.md +1 -0
- package/esm/_dnt.shims.js +68 -0
- package/esm/client/client.js +169 -0
- package/esm/client/client_abstract.js +51 -0
- package/esm/client/client_plain.js +112 -0
- package/esm/connection/connection.js +2 -0
- package/esm/connection/connection_web_socket.js +90 -0
- package/esm/constants.js +60 -0
- package/esm/deps/deno.land/std@0.186.0/fmt/colors.js +474 -0
- package/esm/deps/deno.land/std@0.186.0/testing/_diff.js +311 -0
- package/esm/deps/deno.land/std@0.186.0/testing/_format.js +23 -0
- package/esm/deps/deno.land/std@0.186.0/testing/asserts.js +633 -0
- package/esm/deps/deno.land/x/crc32@v0.2.0/mod.js +105 -0
- package/esm/deps/deno.land/x/tgcrypto@0.1.1/mod.js +68 -0
- package/esm/deps/deno.land/x/tgcrypto@0.1.1/tgcrypto.js +1127 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/gzip/gzip.js +239 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/utils/uint8.js +10 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/deflate.js +139 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/inflate.js +176 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/mod.js +2 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/adler32.js +19 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/crc32.js +25 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/deflate.js +1941 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/gzheader.js +85 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inffast.js +321 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inflate.js +1658 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inftrees.js +355 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/messages.js +11 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/status.js +42 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/trees.js +1107 -0
- package/esm/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/zstream.js +86 -0
- package/esm/deps.js +4 -0
- package/esm/mod.js +4 -0
- package/esm/package.json +3 -0
- package/esm/tl/0_tl_raw_reader.js +62 -0
- package/esm/tl/0_tl_raw_writer.js +60 -0
- package/esm/tl/1_tl_object.js +149 -0
- package/esm/tl/2_types.js +48220 -0
- package/esm/tl/3_functions.js +19856 -0
- package/esm/tl/3_tl_object_deserializer.js +72 -0
- package/esm/tl/3_tl_reader.js +16 -0
- package/esm/tl/3_tl_writer.js +7 -0
- package/esm/tl/4_rpc_result.js +27 -0
- package/esm/tl/5_message.js +54 -0
- package/esm/tl/6_message_container.js +35 -0
- package/esm/transport/transport.js +32 -0
- package/esm/transport/transport_intermediate.js +56 -0
- package/esm/transport/transport_provider.js +23 -0
- package/esm/types.js +1 -0
- package/esm/utilities/0_bigint.js +37 -0
- package/esm/utilities/0_buffer.js +33 -0
- package/esm/utilities/0_crypto.js +35 -0
- package/esm/utilities/0_hash.js +7 -0
- package/esm/utilities/1_auth.js +29 -0
- package/esm/utilities/1_message.js +94 -0
- package/esm/utilities/1_obfuscation.js +33 -0
- package/package.json +40 -0
- package/script/_dnt.shims.js +77 -0
- package/script/client/client.js +173 -0
- package/script/client/client_abstract.js +55 -0
- package/script/client/client_plain.js +116 -0
- package/script/connection/connection.js +6 -0
- package/script/connection/connection_web_socket.js +117 -0
- package/script/constants.js +63 -0
- package/script/deps/deno.land/std@0.186.0/fmt/colors.js +548 -0
- package/script/deps/deno.land/std@0.186.0/testing/_diff.js +317 -0
- package/script/deps/deno.land/std@0.186.0/testing/_format.js +50 -0
- package/script/deps/deno.land/std@0.186.0/testing/asserts.js +659 -0
- package/script/deps/deno.land/x/crc32@v0.2.0/mod.js +113 -0
- package/script/deps/deno.land/x/tgcrypto@0.1.1/mod.js +82 -0
- package/script/deps/deno.land/x/tgcrypto@0.1.1/tgcrypto.js +1152 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/gzip/gzip.js +271 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/utils/uint8.js +14 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/deflate.js +172 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/inflate.js +208 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/mod.js +18 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/adler32.js +22 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/crc32.js +30 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/deflate.js +1976 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/gzheader.js +88 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inffast.js +324 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inflate.js +1674 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inftrees.js +358 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/messages.js +14 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/status.js +44 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/trees.js +1115 -0
- package/script/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/zstream.js +89 -0
- package/script/deps.js +30 -0
- package/script/mod.js +32 -0
- package/script/package.json +3 -0
- package/script/tl/0_tl_raw_reader.js +66 -0
- package/script/tl/0_tl_raw_writer.js +64 -0
- package/script/tl/1_tl_object.js +156 -0
- package/script/tl/2_types.js +49824 -0
- package/script/tl/3_functions.js +20413 -0
- package/script/tl/3_tl_object_deserializer.js +76 -0
- package/script/tl/3_tl_reader.js +20 -0
- package/script/tl/3_tl_writer.js +11 -0
- package/script/tl/4_rpc_result.js +31 -0
- package/script/tl/5_message.js +58 -0
- package/script/tl/6_message_container.js +39 -0
- package/script/transport/transport.js +36 -0
- package/script/transport/transport_intermediate.js +60 -0
- package/script/transport/transport_provider.js +27 -0
- package/script/types.js +2 -0
- package/script/utilities/0_bigint.js +67 -0
- package/script/utilities/0_buffer.js +38 -0
- package/script/utilities/0_crypto.js +39 -0
- package/script/utilities/0_hash.js +35 -0
- package/script/utilities/1_auth.js +56 -0
- package/script/utilities/1_message.js +102 -0
- package/script/utilities/1_obfuscation.js +60 -0
- package/types/_dnt.shims.d.ts +10 -0
- package/types/client/client.d.ts +19 -0
- package/types/client/client_abstract.d.ts +20 -0
- package/types/client/client_plain.d.ts +10 -0
- package/types/connection/connection.d.ts +7 -0
- package/types/connection/connection_web_socket.d.ts +13 -0
- package/types/constants.d.ts +2 -0
- package/types/deps/deno.land/std@0.186.0/fmt/colors.d.ts +270 -0
- package/types/deps/deno.land/std@0.186.0/testing/_diff.d.ts +26 -0
- package/types/deps/deno.land/std@0.186.0/testing/_format.d.ts +1 -0
- package/types/deps/deno.land/std@0.186.0/testing/asserts.d.ts +284 -0
- package/types/deps/deno.land/x/crc32@v0.2.0/mod.d.ts +15 -0
- package/types/deps/deno.land/x/tgcrypto@0.1.1/mod.d.ts +47 -0
- package/types/deps/deno.land/x/tgcrypto@0.1.1/tgcrypto.d.ts +2 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/gzip/gzip.d.ts +16 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/utils/uint8.d.ts +1 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/deflate.d.ts +29 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/inflate.d.ts +23 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/mod.d.ts +2 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/adler32.d.ts +1 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/crc32.d.ts +2 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/deflate.d.ts +78 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/gzheader.d.ts +12 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inffast.d.ts +1 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inflate.d.ts +47 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/inftrees.d.ts +1 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/messages.d.ts +12 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/status.d.ts +30 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/trees.d.ts +5 -0
- package/types/deps/raw.githubusercontent.com/MTKruto/compress/master/zlib/zlib/zstream.d.ts +14 -0
- package/types/deps.d.ts +4 -0
- package/types/mod.d.ts +4 -0
- package/types/tl/0_tl_raw_reader.d.ts +13 -0
- package/types/tl/0_tl_raw_writer.d.ts +13 -0
- package/types/tl/1_tl_object.d.ts +36 -0
- package/types/tl/2_types.d.ts +14815 -0
- package/types/tl/3_functions.d.ts +6122 -0
- package/types/tl/3_tl_object_deserializer.d.ts +3 -0
- package/types/tl/3_tl_reader.d.ts +4 -0
- package/types/tl/3_tl_writer.d.ts +5 -0
- package/types/tl/4_rpc_result.d.ts +8 -0
- package/types/tl/5_message.d.ts +11 -0
- package/types/tl/6_message_container.d.ts +9 -0
- package/types/transport/transport.d.ts +15 -0
- package/types/transport/transport_intermediate.d.ts +11 -0
- package/types/transport/transport_provider.d.ts +12 -0
- package/types/types.d.ts +1 -0
- package/types/utilities/0_bigint.d.ts +4 -0
- package/types/utilities/0_buffer.d.ts +2 -0
- package/types/utilities/0_crypto.d.ts +8 -0
- package/types/utilities/0_hash.d.ts +2 -0
- package/types/utilities/1_auth.d.ts +1 -0
- package/types/utilities/1_message.d.ts +10 -0
- package/types/utilities/1_obfuscation.d.ts +6 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { assertEquals } from "../deps.js";
|
|
2
|
+
import { analyzeOptionalParam, flags, isOptionalParam, isTLObjectConstructor, paramDesc } from "./1_tl_object.js";
|
|
3
|
+
import { map } from "./2_types.js";
|
|
4
|
+
function deserializeSingleParam(reader, type, ntype) {
|
|
5
|
+
if (isTLObjectConstructor(type)) {
|
|
6
|
+
const cid = reader.readInt32(false);
|
|
7
|
+
const constructor = map.get(cid);
|
|
8
|
+
if (!constructor) {
|
|
9
|
+
throw new Error(`Constructor with ID ${cid} not found`);
|
|
10
|
+
}
|
|
11
|
+
return deserialize(reader, constructor[paramDesc], constructor);
|
|
12
|
+
}
|
|
13
|
+
if (type == Uint8Array) {
|
|
14
|
+
return reader.readBytes();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
switch (type) {
|
|
18
|
+
case "bigint":
|
|
19
|
+
if (ntype == "int128") {
|
|
20
|
+
return reader.readInt128();
|
|
21
|
+
}
|
|
22
|
+
else if (ntype === "int256") {
|
|
23
|
+
return reader.readInt256();
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
return reader.readInt64();
|
|
27
|
+
}
|
|
28
|
+
case "boolean":
|
|
29
|
+
return reader.readInt32(false) == 0x997275B5;
|
|
30
|
+
case "number":
|
|
31
|
+
return reader.readInt32();
|
|
32
|
+
case "string":
|
|
33
|
+
return reader.readString();
|
|
34
|
+
case "true":
|
|
35
|
+
return true;
|
|
36
|
+
default:
|
|
37
|
+
throw new Error(`Unexpected type ${type}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
export function deserialize(reader, paramDesc, constructor) {
|
|
42
|
+
const params = {};
|
|
43
|
+
const flagFields = {};
|
|
44
|
+
for (const [name, type, ntype] of paramDesc) {
|
|
45
|
+
if (isOptionalParam(ntype)) {
|
|
46
|
+
const { flagField, bitIndex } = analyzeOptionalParam(ntype);
|
|
47
|
+
const bits = flagFields[flagField];
|
|
48
|
+
if ((bits & (1 << bitIndex)) == 0) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (type == flags && ntype == "#") {
|
|
53
|
+
flagFields[name] = reader.readInt32();
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (type instanceof Array) {
|
|
57
|
+
assertEquals(reader.readInt32(false), 0x1CB5C415);
|
|
58
|
+
const count = reader.readInt32();
|
|
59
|
+
const items = new Array();
|
|
60
|
+
for (let i = 0; i < count; i++) {
|
|
61
|
+
items.push(deserializeSingleParam(reader, type[0], ntype));
|
|
62
|
+
}
|
|
63
|
+
params[name] = items;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const value = deserializeSingleParam(reader, type, ntype);
|
|
67
|
+
if (value) {
|
|
68
|
+
params[name] = value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return new constructor(params);
|
|
72
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { TLRawReader } from "./0_tl_raw_reader.js";
|
|
2
|
+
import { paramDesc } from "./1_tl_object.js";
|
|
3
|
+
import { map } from "./2_types.js";
|
|
4
|
+
import { deserialize } from "./3_tl_object_deserializer.js";
|
|
5
|
+
export class TLReader extends TLRawReader {
|
|
6
|
+
readObject(id) {
|
|
7
|
+
if (!id) {
|
|
8
|
+
id = this.readInt32(false);
|
|
9
|
+
}
|
|
10
|
+
const constructor = map.get(id);
|
|
11
|
+
if (constructor) {
|
|
12
|
+
return deserialize(this, constructor[paramDesc], constructor);
|
|
13
|
+
}
|
|
14
|
+
throw new Error(`Unknown constructor ${id.toString(16)}`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { id } from "./1_tl_object.js";
|
|
2
|
+
import { TLReader } from "./3_tl_reader.js";
|
|
3
|
+
export class RPCResult {
|
|
4
|
+
static get [id]() {
|
|
5
|
+
return 0xF35C6D01;
|
|
6
|
+
}
|
|
7
|
+
constructor(messageId, result) {
|
|
8
|
+
Object.defineProperty(this, "messageId", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: messageId
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "result", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: result
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
static deserialize(buffer) {
|
|
22
|
+
const reader = new TLReader(buffer);
|
|
23
|
+
const messageId = reader.readInt64();
|
|
24
|
+
const result = reader.readObject();
|
|
25
|
+
return new RPCResult(messageId, result);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { id, length } from "./1_tl_object.js";
|
|
2
|
+
import { TLReader } from "./3_tl_reader.js";
|
|
3
|
+
import { TLWriter } from "./3_tl_writer.js";
|
|
4
|
+
import { RPCResult } from "./4_rpc_result.js";
|
|
5
|
+
export class Message {
|
|
6
|
+
constructor(id, seqNo, body) {
|
|
7
|
+
Object.defineProperty(this, "id", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: id
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "seqNo", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: seqNo
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(this, "body", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
configurable: true,
|
|
22
|
+
writable: true,
|
|
23
|
+
value: body
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
serialize() {
|
|
27
|
+
if (this.body instanceof RPCResult) {
|
|
28
|
+
throw new Error("Not applicable");
|
|
29
|
+
}
|
|
30
|
+
return new TLWriter()
|
|
31
|
+
.writeInt64(this.id)
|
|
32
|
+
.writeInt32(this.seqNo)
|
|
33
|
+
.writeInt32(this.body[length])
|
|
34
|
+
.writeObject(this.body)
|
|
35
|
+
.buffer;
|
|
36
|
+
}
|
|
37
|
+
static deserialize(reader) {
|
|
38
|
+
const id_ = reader.readInt64();
|
|
39
|
+
const seqNo = reader.readInt32();
|
|
40
|
+
const length = reader.readInt32();
|
|
41
|
+
reader = new TLReader(reader.read(length));
|
|
42
|
+
const cid = reader.readInt32(false);
|
|
43
|
+
let body;
|
|
44
|
+
{
|
|
45
|
+
if (cid == RPCResult[id]) {
|
|
46
|
+
body = RPCResult.deserialize(reader.buffer);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
body = reader.readObject(cid);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return new Message(id_, seqNo, body);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { id } from "./1_tl_object.js";
|
|
2
|
+
import { TLReader } from "./3_tl_reader.js";
|
|
3
|
+
import { TLWriter } from "./3_tl_writer.js";
|
|
4
|
+
import { Message } from "./5_message.js";
|
|
5
|
+
export class MessageContainer {
|
|
6
|
+
static get [id]() {
|
|
7
|
+
return 0x73F1F8DC;
|
|
8
|
+
}
|
|
9
|
+
constructor(messages) {
|
|
10
|
+
Object.defineProperty(this, "messages", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true,
|
|
14
|
+
value: messages
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
serialize() {
|
|
18
|
+
const writer = new TLWriter();
|
|
19
|
+
writer.writeInt32(MessageContainer[id]);
|
|
20
|
+
writer.writeInt32(this.messages.length);
|
|
21
|
+
for (const message of this.messages) {
|
|
22
|
+
writer.write(message.serialize());
|
|
23
|
+
}
|
|
24
|
+
return writer.buffer;
|
|
25
|
+
}
|
|
26
|
+
static deserialize(buffer) {
|
|
27
|
+
const reader = new TLReader(buffer);
|
|
28
|
+
const length = reader.readInt32();
|
|
29
|
+
const messages = new Array();
|
|
30
|
+
for (let i = 0; i < length; i++) {
|
|
31
|
+
messages.push(Message.deserialize(reader));
|
|
32
|
+
}
|
|
33
|
+
return new MessageContainer(messages);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export class Transport {
|
|
2
|
+
constructor() {
|
|
3
|
+
Object.defineProperty(this, "initialized", {
|
|
4
|
+
enumerable: true,
|
|
5
|
+
configurable: true,
|
|
6
|
+
writable: true,
|
|
7
|
+
value: false
|
|
8
|
+
});
|
|
9
|
+
Object.defineProperty(this, "obfuscationParameters", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: null
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
encrypt(buffer) {
|
|
17
|
+
if (this.obfuscationParameters) {
|
|
18
|
+
return this.obfuscationParameters.encryptionCTR.encrypt(buffer);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return buffer;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
decrypt(buffer) {
|
|
25
|
+
if (this.obfuscationParameters) {
|
|
26
|
+
return this.obfuscationParameters.decryptionCTR.decrypt(buffer);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return buffer;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { bufferFromBigInt, concat } from "../utilities/0_buffer.js";
|
|
2
|
+
import { getObfuscationParameters } from "../utilities/1_obfuscation.js";
|
|
3
|
+
import { Transport } from "./transport.js";
|
|
4
|
+
export class TransportIntermediate extends Transport {
|
|
5
|
+
constructor(connection, obfuscated = false) {
|
|
6
|
+
super();
|
|
7
|
+
Object.defineProperty(this, "connection", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: connection
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(this, "obfuscated", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
configurable: true,
|
|
16
|
+
writable: true,
|
|
17
|
+
value: obfuscated
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
async initialize() {
|
|
21
|
+
if (!this.initialized) {
|
|
22
|
+
if (this.obfuscated) {
|
|
23
|
+
this.obfuscationParameters = await getObfuscationParameters(0xEEEEEEEE, this.connection);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
await this.connection.write(new Uint8Array([0xEE, 0xEE, 0xEE, 0xEE]));
|
|
27
|
+
}
|
|
28
|
+
this.initialized = true;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new Error("Transport already initialized");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async receive() {
|
|
35
|
+
let length;
|
|
36
|
+
{
|
|
37
|
+
const buffer = new Uint8Array(4);
|
|
38
|
+
await this.connection.read(buffer);
|
|
39
|
+
const dataView = new DataView(this.decrypt(buffer).buffer);
|
|
40
|
+
length = dataView.getUint32(0, true);
|
|
41
|
+
}
|
|
42
|
+
const buffer = new Uint8Array(length);
|
|
43
|
+
await this.connection.read(buffer);
|
|
44
|
+
return this.decrypt(buffer);
|
|
45
|
+
}
|
|
46
|
+
async send(buffer) {
|
|
47
|
+
if (!this.initialized) {
|
|
48
|
+
throw new Error("Transport not initialized");
|
|
49
|
+
}
|
|
50
|
+
const length = bufferFromBigInt(buffer.length, 4);
|
|
51
|
+
await this.connection.write(this.encrypt(concat(length, buffer)));
|
|
52
|
+
}
|
|
53
|
+
deinitialize() {
|
|
54
|
+
this.initialized = false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ConnectionWebSocket } from "../connection/connection_web_socket.js";
|
|
2
|
+
import { TransportIntermediate } from "./transport_intermediate.js";
|
|
3
|
+
export const defaultDc = "2-test";
|
|
4
|
+
const dcToNameMap = {
|
|
5
|
+
"1": "pluto",
|
|
6
|
+
"1-test": "pluto",
|
|
7
|
+
"2": "venus",
|
|
8
|
+
"2-test": "venus",
|
|
9
|
+
"3": "aurora",
|
|
10
|
+
"3-test": "aurora",
|
|
11
|
+
"4": "vesta",
|
|
12
|
+
"5": "flora",
|
|
13
|
+
};
|
|
14
|
+
export const defaultTransportProvider = (params) => {
|
|
15
|
+
return (cdn) => {
|
|
16
|
+
const { dc, wss = typeof location !== "undefined" && location.protocol == "http:" ? false : true } = params ?? { dc: defaultDc };
|
|
17
|
+
const url = `${wss ? "wss" : "ws"}://${dcToNameMap[dc]}${cdn ? "-1" : ""}.telegram.org/apiws${dc.endsWith("-test") ? "apiws_test" : "apiws"}`;
|
|
18
|
+
const connection = new ConnectionWebSocket(url);
|
|
19
|
+
const transport = new TransportIntermediate(connection, true);
|
|
20
|
+
const dcId = Number(dc[0]) + (dc.endsWith("-test") ? 10000 : 0) * (cdn ? -1 : 1);
|
|
21
|
+
return { connection, transport, dcId };
|
|
22
|
+
};
|
|
23
|
+
};
|
package/esm/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
2
|
+
export function modExp(a, b, n) {
|
|
3
|
+
a %= n;
|
|
4
|
+
let result = 1n;
|
|
5
|
+
let x = a;
|
|
6
|
+
while (b > 0n) {
|
|
7
|
+
const leastSignificantBit = b % 2n;
|
|
8
|
+
b /= 2n;
|
|
9
|
+
if (leastSignificantBit == 1n) {
|
|
10
|
+
result *= x;
|
|
11
|
+
result %= n;
|
|
12
|
+
}
|
|
13
|
+
x *= x;
|
|
14
|
+
x %= n;
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
export function mod(n, m) {
|
|
19
|
+
return ((n % m) + m) % m;
|
|
20
|
+
}
|
|
21
|
+
export function bigIntFromBuffer(buffer, little = true, signed = false) {
|
|
22
|
+
let randomBuffer = buffer;
|
|
23
|
+
const bytesLength = randomBuffer.length;
|
|
24
|
+
if (little) {
|
|
25
|
+
randomBuffer = randomBuffer.reverse();
|
|
26
|
+
}
|
|
27
|
+
let bigIntVar = BigInt("0x" + [...randomBuffer].map((v) => v.toString(16).padStart(2, "0")).join(""));
|
|
28
|
+
if (signed && Math.floor(bigIntVar.toString(2).length / 8) >= bytesLength) {
|
|
29
|
+
bigIntVar = bigIntVar - (2n ** (BigInt(bytesLength * 8)));
|
|
30
|
+
}
|
|
31
|
+
return bigIntVar;
|
|
32
|
+
}
|
|
33
|
+
export function getRandomBigInt(byteLength, little, signed) {
|
|
34
|
+
const randomBytes = new Uint8Array(byteLength);
|
|
35
|
+
dntShim.crypto.getRandomValues(randomBytes);
|
|
36
|
+
return bigIntFromBuffer(randomBytes, little, signed);
|
|
37
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export function concat(...buffers) {
|
|
2
|
+
return new Uint8Array(buffers.map((v) => Array.from(v)).flat());
|
|
3
|
+
}
|
|
4
|
+
const bufferFromHexString = (hexString) => Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
|
5
|
+
export function bufferFromBigInt(bigIntVar, bytesNumber, little = true, signed = false) {
|
|
6
|
+
bigIntVar = BigInt(typeof bigIntVar === "number" ? Math.ceil(bigIntVar) : bigIntVar);
|
|
7
|
+
const bitLength = bigIntVar.toString(2).length;
|
|
8
|
+
const bytes = Math.ceil(bitLength / 8);
|
|
9
|
+
if (bytesNumber < bytes) {
|
|
10
|
+
throw new Error("OverflowError: int too big to convert");
|
|
11
|
+
}
|
|
12
|
+
if (!signed && bigIntVar < 0n) {
|
|
13
|
+
throw new Error("Cannot convert to unsigned");
|
|
14
|
+
}
|
|
15
|
+
let below = false;
|
|
16
|
+
if (bigIntVar < 0n) {
|
|
17
|
+
below = true;
|
|
18
|
+
bigIntVar = bigIntVar < 0 ? bigIntVar * -1n : bigIntVar;
|
|
19
|
+
}
|
|
20
|
+
const hex = bigIntVar.toString(16).padStart(bytesNumber * 2, "0");
|
|
21
|
+
const buffer = bufferFromHexString(hex);
|
|
22
|
+
if (signed && below) {
|
|
23
|
+
buffer[buffer.length - 1] = 256 -
|
|
24
|
+
buffer[buffer.length - 1];
|
|
25
|
+
for (let i = 0; i < buffer.length - 1; i++) {
|
|
26
|
+
buffer[i] = 255 - buffer[i];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (little) {
|
|
30
|
+
buffer.reverse();
|
|
31
|
+
}
|
|
32
|
+
return buffer;
|
|
33
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ctr256Decrypt, ctr256Encrypt } from "../deps.js";
|
|
2
|
+
export class CTR {
|
|
3
|
+
constructor(key, iv) {
|
|
4
|
+
Object.defineProperty(this, "key", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: key
|
|
9
|
+
});
|
|
10
|
+
Object.defineProperty(this, "iv", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
configurable: true,
|
|
13
|
+
writable: true,
|
|
14
|
+
value: iv
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(this, "state", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
configurable: true,
|
|
19
|
+
writable: true,
|
|
20
|
+
value: new Uint8Array(1)
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
encrypt(data) {
|
|
24
|
+
const [encrypted, iv, state] = ctr256Encrypt(data, this.key, this.iv, this.state);
|
|
25
|
+
this.iv = iv;
|
|
26
|
+
this.state = state;
|
|
27
|
+
return new Uint8Array(encrypted);
|
|
28
|
+
}
|
|
29
|
+
decrypt(data) {
|
|
30
|
+
const [decrypted, iv, state] = ctr256Decrypt(data, this.key, this.iv, this.state);
|
|
31
|
+
this.iv = iv;
|
|
32
|
+
this.state = state;
|
|
33
|
+
return new Uint8Array(decrypted);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
2
|
+
export async function sha256(payload) {
|
|
3
|
+
return new Uint8Array(await dntShim.crypto.subtle.digest("SHA-256", payload));
|
|
4
|
+
}
|
|
5
|
+
export async function sha1(payload) {
|
|
6
|
+
return new Uint8Array(await dntShim.crypto.subtle.digest("SHA-1", payload));
|
|
7
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
2
|
+
import { assert, assertEquals, ige256Encrypt } from "../deps.js";
|
|
3
|
+
import { bigIntFromBuffer, modExp } from "./0_bigint.js";
|
|
4
|
+
import { bufferFromBigInt, concat } from "./0_buffer.js";
|
|
5
|
+
import { sha256 } from "./0_hash.js";
|
|
6
|
+
export async function rsaPad(data, [serverKey, exponent]) {
|
|
7
|
+
assert(data.length <= 144);
|
|
8
|
+
let keyAesEncryptedInt;
|
|
9
|
+
let tries = 0;
|
|
10
|
+
do {
|
|
11
|
+
if (++tries == 10) {
|
|
12
|
+
throw new Error("Out of tries");
|
|
13
|
+
}
|
|
14
|
+
const dataWithPadding = concat(data, new Uint8Array(192 - data.length));
|
|
15
|
+
const dataPadReversed = new Uint8Array(dataWithPadding).reverse();
|
|
16
|
+
const tempKey = dntShim.crypto.getRandomValues(new Uint8Array(32));
|
|
17
|
+
const dataWithHash = concat(dataPadReversed, await sha256(concat(tempKey, dataWithPadding)));
|
|
18
|
+
const aesEncrypted = ige256Encrypt(dataWithHash, tempKey, new Uint8Array(32));
|
|
19
|
+
const aesEncryptedSha256 = await sha256(aesEncrypted);
|
|
20
|
+
const tempKeyXor = tempKey.map((v, i) => v ^ aesEncryptedSha256[i]);
|
|
21
|
+
const keyAesEncrypted = concat(tempKeyXor, aesEncrypted);
|
|
22
|
+
assertEquals(keyAesEncrypted.length, 256);
|
|
23
|
+
keyAesEncryptedInt = bigIntFromBuffer(keyAesEncrypted, false, false);
|
|
24
|
+
} while (keyAesEncryptedInt >= serverKey);
|
|
25
|
+
const encryptedDataInt = modExp(keyAesEncryptedInt, exponent, serverKey);
|
|
26
|
+
const encryptedData = bufferFromBigInt(encryptedDataInt, 256, false, false);
|
|
27
|
+
assertEquals(encryptedData.length, 256);
|
|
28
|
+
return encryptedData;
|
|
29
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { assertEquals, ige256Decrypt, ige256Encrypt } from "../deps.js";
|
|
2
|
+
import { TLRawReader } from "../tl/0_tl_raw_reader.js";
|
|
3
|
+
import { TLRawWriter } from "../tl/0_tl_raw_writer.js";
|
|
4
|
+
import { id } from "../tl/1_tl_object.js";
|
|
5
|
+
import { TLReader } from "../tl/3_tl_reader.js";
|
|
6
|
+
import { RPCResult } from "../tl/4_rpc_result.js";
|
|
7
|
+
import { Message } from "../tl/5_message.js";
|
|
8
|
+
import { MessageContainer } from "../tl/6_message_container.js";
|
|
9
|
+
import { bufferFromBigInt, concat } from "./0_buffer.js";
|
|
10
|
+
import { sha256 } from "./0_hash.js";
|
|
11
|
+
let lastMsgId = 0n;
|
|
12
|
+
export function getMessageId() {
|
|
13
|
+
const now = new Date().getTime() / 1000 + 0;
|
|
14
|
+
const nanoseconds = Math.floor((now - Math.floor(now)) * 1e9);
|
|
15
|
+
let newMsgId = (BigInt(Math.floor(now)) <<
|
|
16
|
+
32n) ||
|
|
17
|
+
(BigInt(nanoseconds) << 2n);
|
|
18
|
+
if (lastMsgId >= (newMsgId)) {
|
|
19
|
+
newMsgId = lastMsgId + 4n;
|
|
20
|
+
}
|
|
21
|
+
lastMsgId = newMsgId;
|
|
22
|
+
return newMsgId;
|
|
23
|
+
}
|
|
24
|
+
export function packUnencryptedMessage(data) {
|
|
25
|
+
const message = concat(bufferFromBigInt(0x00, 8), bufferFromBigInt(getMessageId(), 8), bufferFromBigInt(data.length, 4), data);
|
|
26
|
+
return message;
|
|
27
|
+
}
|
|
28
|
+
export function unpackUnencryptedMessage(buffer) {
|
|
29
|
+
const reader = new TLRawReader(buffer);
|
|
30
|
+
const _authKeyId = reader.readInt64();
|
|
31
|
+
const messageId = reader.readInt64();
|
|
32
|
+
const messageLength = reader.readInt32();
|
|
33
|
+
const message = reader.read(messageLength);
|
|
34
|
+
return { messageId, message };
|
|
35
|
+
}
|
|
36
|
+
export async function encryptMessage(message, authKey, authKeyId, salt, sessionId) {
|
|
37
|
+
const encoded = message.body.serialize();
|
|
38
|
+
const payloadWriter = new TLRawWriter();
|
|
39
|
+
payloadWriter.writeInt64(salt);
|
|
40
|
+
payloadWriter.writeInt64(sessionId);
|
|
41
|
+
payloadWriter.writeInt64(message.id);
|
|
42
|
+
payloadWriter.writeInt32(message.seqNo);
|
|
43
|
+
payloadWriter.writeInt32(encoded.length);
|
|
44
|
+
payloadWriter.write(encoded);
|
|
45
|
+
payloadWriter.write(new Uint8Array(payloadWriter.buffer.length + 12 % 16 + 12));
|
|
46
|
+
let payload = payloadWriter.buffer;
|
|
47
|
+
while (true) {
|
|
48
|
+
if (payload.length % 16 == 0 && (payload.length) % 4 == 0) {
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
payload = concat(payload, new Uint8Array(1));
|
|
52
|
+
}
|
|
53
|
+
const messageKey = (await sha256(concat(authKey.slice(88, 120), payload))).slice(8, 24);
|
|
54
|
+
const a = await sha256(concat(messageKey, authKey.slice(0, 36)));
|
|
55
|
+
const b = await sha256(concat(authKey.slice(40, 76), messageKey));
|
|
56
|
+
const aesKey = concat(a.slice(0, 8), b.slice(8, 24), a.slice(24, 32));
|
|
57
|
+
const aesIV = concat(b.slice(0, 8), a.slice(8, 24), b.slice(24, 32));
|
|
58
|
+
const messageWriter = new TLRawWriter();
|
|
59
|
+
messageWriter.writeInt64(authKeyId);
|
|
60
|
+
messageWriter.write(messageKey);
|
|
61
|
+
messageWriter.write(ige256Encrypt(payload, aesKey, aesIV));
|
|
62
|
+
return messageWriter.buffer;
|
|
63
|
+
}
|
|
64
|
+
export async function decryptMessage(buffer, authKey, authKeyId, _sessionId) {
|
|
65
|
+
const reader = new TLReader(buffer);
|
|
66
|
+
assertEquals(reader.readInt64(false), authKeyId);
|
|
67
|
+
const messageKey_ = reader.readInt128();
|
|
68
|
+
const messageKey = bufferFromBigInt(messageKey_, 16, true, true);
|
|
69
|
+
const a = await sha256(concat(messageKey, authKey.slice(8, 44)));
|
|
70
|
+
const b = await sha256(concat(authKey.slice(48, 84), messageKey));
|
|
71
|
+
const aesKey = concat(a.slice(0, 8), b.slice(8, 24), a.slice(24, 32));
|
|
72
|
+
const aesIv = concat(b.slice(0, 8), a.slice(8, 24), b.slice(24, 32));
|
|
73
|
+
const plaintext = ige256Decrypt(reader.buffer, aesKey, aesIv);
|
|
74
|
+
assertEquals(plaintext.buffer.byteLength % 4, 0);
|
|
75
|
+
let plainReader = new TLReader(plaintext);
|
|
76
|
+
const _salt = plainReader.readInt64();
|
|
77
|
+
const _sessionId_ = plainReader.readInt64(false);
|
|
78
|
+
const mid = plainReader.readInt64();
|
|
79
|
+
const seqno = plainReader.readInt32();
|
|
80
|
+
const length = plainReader.readInt32();
|
|
81
|
+
plainReader = new TLReader(plainReader.read(length));
|
|
82
|
+
const cid = plainReader.readInt32(false);
|
|
83
|
+
if (cid == MessageContainer[id]) {
|
|
84
|
+
return MessageContainer.deserialize(plainReader.buffer);
|
|
85
|
+
}
|
|
86
|
+
else if (cid == RPCResult[id]) {
|
|
87
|
+
const body = RPCResult.deserialize(plainReader.buffer);
|
|
88
|
+
return new Message(mid, seqno, body);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const body = plainReader.readObject(cid);
|
|
92
|
+
return new Message(mid, seqno, body);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as dntShim from "../_dnt.shims.js";
|
|
2
|
+
import { bufferFromBigInt, concat } from "./0_buffer.js";
|
|
3
|
+
import { CTR } from "./0_crypto.js";
|
|
4
|
+
export async function getObfuscationParameters(protocol, connection) {
|
|
5
|
+
const dc = 0xFCFF;
|
|
6
|
+
let init;
|
|
7
|
+
while (true) {
|
|
8
|
+
init = concat(dntShim.crypto.getRandomValues(new Uint8Array(56)), bufferFromBigInt(protocol, 4, false), bufferFromBigInt(dc, 2, false), dntShim.crypto.getRandomValues(new Uint8Array(2)));
|
|
9
|
+
if (init[0] == 0xEF) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const dataView = new DataView(init.buffer);
|
|
13
|
+
const firstInt = dataView.getInt32(0);
|
|
14
|
+
if ([0x44414548, 0x54534F50, 0x20544547, 0x4954504F, 0x02010316, 0xDDDDDDDD, 0xEEEEEEEE].includes(firstInt)) {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const secondInt = dataView.getInt32(4);
|
|
18
|
+
if (secondInt == 0x00000000) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
const encryptKey = init.slice(8, 8 + 32);
|
|
24
|
+
const encryptIv = init.slice(40, 40 + 16);
|
|
25
|
+
const encryptionCTR = new CTR(encryptKey, encryptIv);
|
|
26
|
+
const encryptedInit = encryptionCTR.encrypt(init);
|
|
27
|
+
const initRev = new Uint8Array(init).reverse();
|
|
28
|
+
const decryptKey = initRev.slice(8, 8 + 32);
|
|
29
|
+
const decryptIv = initRev.slice(40, 40 + 16);
|
|
30
|
+
const decryptionCTR = new CTR(decryptKey, decryptIv);
|
|
31
|
+
await connection.write(concat(init.slice(0, 56), encryptedInit.slice(56, 56 + 8)));
|
|
32
|
+
return { encryptionCTR, decryptionCTR };
|
|
33
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"module": "./esm/mod.js",
|
|
3
|
+
"main": "./script/mod.js",
|
|
4
|
+
"types": "./types/mod.d.ts",
|
|
5
|
+
"name": "@mtkruto/node",
|
|
6
|
+
"version": "0.0.6",
|
|
7
|
+
"description": "MTKruto for Node.js",
|
|
8
|
+
"author": "Roj <rojvv@icloud.com>",
|
|
9
|
+
"license": "LGPL-3.0-or-later",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/MTKruto/MTKruto.git"
|
|
13
|
+
},
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./types/mod.d.ts",
|
|
18
|
+
"default": "./esm/mod.js"
|
|
19
|
+
},
|
|
20
|
+
"require": {
|
|
21
|
+
"types": "./types/mod.d.ts",
|
|
22
|
+
"default": "./script/mod.js"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"test": "node test_runner.js"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"async-mutex": "0.4.0",
|
|
31
|
+
"@deno/shim-deno": "~0.15.0",
|
|
32
|
+
"@deno/shim-crypto": "~0.3.1",
|
|
33
|
+
"ws": "^8.13.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/node": "^18.11.9",
|
|
37
|
+
"chalk": "^4.1.2",
|
|
38
|
+
"@types/ws": "^8.5.4"
|
|
39
|
+
}
|
|
40
|
+
}
|