@meow-laika/ton-lite-client 3.2.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 +22 -0
- package/README.md +80 -0
- package/dist/client.d.ts +121 -0
- package/dist/client.js +548 -0
- package/dist/engines/engine.d.ts +31 -0
- package/dist/engines/engine.js +12 -0
- package/dist/engines/roundRobin.d.ts +27 -0
- package/dist/engines/roundRobin.js +115 -0
- package/dist/engines/single.d.ts +37 -0
- package/dist/engines/single.js +186 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +16 -0
- package/dist/liteClientProvider.d.ts +12 -0
- package/dist/liteClientProvider.js +211 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.js +80 -0
- package/dist/parser/parseShards.d.ts +11 -0
- package/dist/parser/parseShards.js +46 -0
- package/dist/schema.d.ts +554 -0
- package/dist/schema.gen.d.ts +8 -0
- package/dist/schema.gen.js +17 -0
- package/dist/schema.js +1595 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +2 -0
- package/dist/utils/arrays.d.ts +2 -0
- package/dist/utils/arrays.js +11 -0
- package/dist/utils/bigint.d.ts +3 -0
- package/dist/utils/bigint.js +28 -0
- package/dist/utils/crc16.d.ts +9 -0
- package/dist/utils/crc16.js +56 -0
- package/package.json +36 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright
|
|
4
|
+
* (c) 2022 Whales Corp.
|
|
5
|
+
* (c) 2023 TrueCarry <truecarry@gmail.com>
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* This source code is licensed under the MIT license found in the
|
|
9
|
+
* LICENSE file in the root directory of this source tree.
|
|
10
|
+
*/
|
|
11
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
12
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
13
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
14
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
15
|
+
};
|
|
16
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
17
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
18
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
19
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
20
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
var _LiteRoundRobinEngine_closed, _LiteRoundRobinEngine_counter;
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.LiteRoundRobinEngine = void 0;
|
|
28
|
+
const events_1 = __importDefault(require("events"));
|
|
29
|
+
class LiteRoundRobinEngine extends events_1.default {
|
|
30
|
+
constructor(engines) {
|
|
31
|
+
super();
|
|
32
|
+
this.allEngines = [];
|
|
33
|
+
this.readyEngines = [];
|
|
34
|
+
_LiteRoundRobinEngine_closed.set(this, false);
|
|
35
|
+
_LiteRoundRobinEngine_counter.set(this, 0);
|
|
36
|
+
for (const engine of engines) {
|
|
37
|
+
this.addSingleEngine(engine);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
addSingleEngine(engine) {
|
|
41
|
+
const existing = this.allEngines.find(e => e === engine);
|
|
42
|
+
if (existing) {
|
|
43
|
+
throw new Error('Engine already exists');
|
|
44
|
+
}
|
|
45
|
+
this.allEngines.push(engine);
|
|
46
|
+
engine.on('ready', () => {
|
|
47
|
+
this.readyEngines.push(engine);
|
|
48
|
+
});
|
|
49
|
+
engine.on('close', () => {
|
|
50
|
+
this.readyEngines = this.readyEngines.filter(e => e !== engine);
|
|
51
|
+
});
|
|
52
|
+
engine.on('error', () => {
|
|
53
|
+
this.readyEngines = this.readyEngines.filter(e => e !== engine);
|
|
54
|
+
});
|
|
55
|
+
if (engine.isReady()) {
|
|
56
|
+
this.readyEngines.push(engine);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async query(f, req, args) {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
if (__classPrivateFieldGet(this, _LiteRoundRobinEngine_closed, "f")) {
|
|
62
|
+
throw new Error('Engine is closed');
|
|
63
|
+
}
|
|
64
|
+
let attempts = 0;
|
|
65
|
+
let id = ((__classPrivateFieldSet(this, _LiteRoundRobinEngine_counter, (_b = __classPrivateFieldGet(this, _LiteRoundRobinEngine_counter, "f"), _a = _b++, _b), "f"), _a) % this.readyEngines.length) || 0;
|
|
66
|
+
let errorsCount = 0;
|
|
67
|
+
while (true) {
|
|
68
|
+
if (!this.readyEngines[id]?.isReady()) {
|
|
69
|
+
id = ((id + 1) % this.readyEngines.length) || 0;
|
|
70
|
+
attempts++;
|
|
71
|
+
if (attempts >= this.readyEngines.length) {
|
|
72
|
+
await delay(100);
|
|
73
|
+
}
|
|
74
|
+
if (attempts > 200) {
|
|
75
|
+
throw new Error('No engines are available');
|
|
76
|
+
}
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const res = await this.readyEngines[id].query(f, req, args);
|
|
81
|
+
return res;
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
id = ((id + 1) % this.readyEngines.length) || 0;
|
|
85
|
+
if (e instanceof Error && e.message === 'Timeout') {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
errorsCount++;
|
|
89
|
+
if (errorsCount > 20) {
|
|
90
|
+
throw e;
|
|
91
|
+
}
|
|
92
|
+
await delay(100);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
close() {
|
|
97
|
+
for (let q of this.allEngines) {
|
|
98
|
+
q.close();
|
|
99
|
+
}
|
|
100
|
+
__classPrivateFieldSet(this, _LiteRoundRobinEngine_closed, true, "f");
|
|
101
|
+
}
|
|
102
|
+
isClosed() {
|
|
103
|
+
return __classPrivateFieldGet(this, _LiteRoundRobinEngine_closed, "f");
|
|
104
|
+
}
|
|
105
|
+
isReady() {
|
|
106
|
+
return !__classPrivateFieldGet(this, _LiteRoundRobinEngine_closed, "f");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.LiteRoundRobinEngine = LiteRoundRobinEngine;
|
|
110
|
+
_LiteRoundRobinEngine_closed = new WeakMap(), _LiteRoundRobinEngine_counter = new WeakMap();
|
|
111
|
+
function delay(ms) {
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
setTimeout(resolve, ms);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright
|
|
3
|
+
* (c) 2022 Whales Corp.
|
|
4
|
+
* (c) 2023 TrueCarry <truecarry@gmail.com>
|
|
5
|
+
* All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
/// <reference types="node" />
|
|
11
|
+
/// <reference types="node" />
|
|
12
|
+
import { TLFunction } from "ton-tl";
|
|
13
|
+
import { LiteEngine } from "./engine";
|
|
14
|
+
import EventEmitter from "events";
|
|
15
|
+
export declare class LiteSingleEngine extends EventEmitter implements LiteEngine {
|
|
16
|
+
#private;
|
|
17
|
+
readonly host: string;
|
|
18
|
+
readonly publicKey: Buffer;
|
|
19
|
+
constructor(args: {
|
|
20
|
+
host: string;
|
|
21
|
+
publicKey: Buffer;
|
|
22
|
+
client?: 'tcp' | 'ws';
|
|
23
|
+
reconnectTimeout?: number;
|
|
24
|
+
});
|
|
25
|
+
isClosed(): boolean;
|
|
26
|
+
isReady(): boolean;
|
|
27
|
+
query<REQ, RES>(f: TLFunction<REQ, RES>, req: REQ, queryArgs?: {
|
|
28
|
+
timeout?: number;
|
|
29
|
+
awaitSeqno?: number;
|
|
30
|
+
}): Promise<RES>;
|
|
31
|
+
close(): void;
|
|
32
|
+
private connect;
|
|
33
|
+
private onConencted;
|
|
34
|
+
private onReady;
|
|
35
|
+
private onData;
|
|
36
|
+
private onClosed;
|
|
37
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright
|
|
4
|
+
* (c) 2022 Whales Corp.
|
|
5
|
+
* (c) 2023 TrueCarry <truecarry@gmail.com>
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* This source code is licensed under the MIT license found in the
|
|
9
|
+
* LICENSE file in the root directory of this source tree.
|
|
10
|
+
*/
|
|
11
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
12
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
13
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
14
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
15
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
16
|
+
};
|
|
17
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
18
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
19
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
20
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
21
|
+
};
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
var _LiteSingleEngine_currentClient, _LiteSingleEngine_ready, _LiteSingleEngine_closed, _LiteSingleEngine_queries, _LiteSingleEngine_clientType, _LiteSingleEngine_reconnectTimeout;
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.LiteSingleEngine = void 0;
|
|
28
|
+
const tweetnacl_1 = require("tweetnacl");
|
|
29
|
+
const ton_tl_1 = require("ton-tl");
|
|
30
|
+
const adnl_1 = require("adnl");
|
|
31
|
+
const schema_1 = require("../schema");
|
|
32
|
+
const events_1 = __importDefault(require("events"));
|
|
33
|
+
const defaultArgs = { timeout: 5000 };
|
|
34
|
+
class LiteSingleEngine extends events_1.default {
|
|
35
|
+
constructor(args) {
|
|
36
|
+
super();
|
|
37
|
+
_LiteSingleEngine_currentClient.set(this, null);
|
|
38
|
+
_LiteSingleEngine_ready.set(this, false);
|
|
39
|
+
_LiteSingleEngine_closed.set(this, true);
|
|
40
|
+
_LiteSingleEngine_queries.set(this, new Map());
|
|
41
|
+
_LiteSingleEngine_clientType.set(this, void 0);
|
|
42
|
+
_LiteSingleEngine_reconnectTimeout.set(this, void 0);
|
|
43
|
+
this.onConencted = () => {
|
|
44
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_closed, false, "f");
|
|
45
|
+
};
|
|
46
|
+
this.onReady = () => {
|
|
47
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_ready, true, "f");
|
|
48
|
+
// Write all pendings
|
|
49
|
+
for (let q of __classPrivateFieldGet(this, _LiteSingleEngine_queries, "f")) {
|
|
50
|
+
__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f").write(q[1].packet);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
this.onData = (data) => {
|
|
54
|
+
let answer = schema_1.Codecs.adnl_Message.decode(new ton_tl_1.TLReadBuffer(data));
|
|
55
|
+
if (answer.kind === 'adnl.message.answer') {
|
|
56
|
+
let id = answer.queryId.toString('hex');
|
|
57
|
+
let q = __classPrivateFieldGet(this, _LiteSingleEngine_queries, "f").get(id);
|
|
58
|
+
if (q) {
|
|
59
|
+
__classPrivateFieldGet(this, _LiteSingleEngine_queries, "f").delete(id);
|
|
60
|
+
// Decode response
|
|
61
|
+
if (answer.answer.readInt32LE(0) === -1146494648) {
|
|
62
|
+
q.reject(new Error(schema_1.Codecs.liteServer_Error.decode(new ton_tl_1.TLReadBuffer(answer.answer)).message));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
try {
|
|
66
|
+
let decoded = q.f.decodeResponse(new ton_tl_1.TLReadBuffer(answer.answer));
|
|
67
|
+
// Resolve
|
|
68
|
+
q.resolver(decoded);
|
|
69
|
+
}
|
|
70
|
+
catch (e) {
|
|
71
|
+
// Reject
|
|
72
|
+
q.reject(e);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
this.onClosed = () => {
|
|
79
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_currentClient, null, "f");
|
|
80
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_ready, false, "f");
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
if (!__classPrivateFieldGet(this, _LiteSingleEngine_closed, "f")) {
|
|
83
|
+
this.connect();
|
|
84
|
+
}
|
|
85
|
+
}, __classPrivateFieldGet(this, _LiteSingleEngine_reconnectTimeout, "f"));
|
|
86
|
+
};
|
|
87
|
+
this.host = args.host;
|
|
88
|
+
this.publicKey = args.publicKey;
|
|
89
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_clientType, args.client || 'tcp', "f");
|
|
90
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_reconnectTimeout, args.reconnectTimeout || 10000, "f");
|
|
91
|
+
this.connect();
|
|
92
|
+
}
|
|
93
|
+
isClosed() {
|
|
94
|
+
return __classPrivateFieldGet(this, _LiteSingleEngine_closed, "f");
|
|
95
|
+
}
|
|
96
|
+
isReady() {
|
|
97
|
+
return __classPrivateFieldGet(this, _LiteSingleEngine_ready, "f");
|
|
98
|
+
}
|
|
99
|
+
async query(f, req, queryArgs) {
|
|
100
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_closed, "f")) {
|
|
101
|
+
throw new Error('Engine is closed');
|
|
102
|
+
}
|
|
103
|
+
const args = { ...defaultArgs, ...queryArgs };
|
|
104
|
+
let id = Buffer.from((0, tweetnacl_1.randomBytes)(32));
|
|
105
|
+
// Request
|
|
106
|
+
let writer = new ton_tl_1.TLWriteBuffer();
|
|
107
|
+
if (args.awaitSeqno !== undefined) {
|
|
108
|
+
schema_1.Functions.liteServer_waitMasterchainSeqno.encodeRequest({ kind: 'liteServer.waitMasterchainSeqno', seqno: args.awaitSeqno, timeoutMs: args.timeout }, writer);
|
|
109
|
+
}
|
|
110
|
+
f.encodeRequest(req, writer);
|
|
111
|
+
let body = writer.build();
|
|
112
|
+
// Lite server query
|
|
113
|
+
let lsQuery = new ton_tl_1.TLWriteBuffer();
|
|
114
|
+
schema_1.Functions.liteServer_query.encodeRequest({ kind: 'liteServer.query', data: body }, lsQuery);
|
|
115
|
+
let lsbody = lsQuery.build();
|
|
116
|
+
// ADNL body
|
|
117
|
+
let adnlWriter = new ton_tl_1.TLWriteBuffer();
|
|
118
|
+
schema_1.Codecs.adnl_Message.encode({ kind: 'adnl.message.query', queryId: id, query: lsbody }, adnlWriter);
|
|
119
|
+
const packet = adnlWriter.build();
|
|
120
|
+
return new Promise((resolve, reject) => {
|
|
121
|
+
// Send
|
|
122
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_ready, "f")) {
|
|
123
|
+
__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f").write(packet);
|
|
124
|
+
}
|
|
125
|
+
// Register query
|
|
126
|
+
__classPrivateFieldGet(this, _LiteSingleEngine_queries, "f").set(id.toString('hex'), { resolver: resolve, reject, f, packet, timeout: args.timeout });
|
|
127
|
+
// Query timeout
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
let ex = __classPrivateFieldGet(this, _LiteSingleEngine_queries, "f").get(id.toString('hex'));
|
|
130
|
+
if (ex) {
|
|
131
|
+
__classPrivateFieldGet(this, _LiteSingleEngine_queries, "f").delete(id.toString('hex'));
|
|
132
|
+
ex.reject(new Error('Timeout'));
|
|
133
|
+
}
|
|
134
|
+
}, args.timeout);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
close() {
|
|
138
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_closed, true, "f");
|
|
139
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f")) {
|
|
140
|
+
let c = __classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f");
|
|
141
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_ready, false, "f");
|
|
142
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_currentClient, null, "f");
|
|
143
|
+
c.end();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
connect() {
|
|
147
|
+
// Configure new client
|
|
148
|
+
const client = __classPrivateFieldGet(this, _LiteSingleEngine_clientType, "f") === 'ws' ? new adnl_1.ADNLClientWS(this.host, this.publicKey) : new adnl_1.ADNLClientTCP(this.host, this.publicKey);
|
|
149
|
+
client.connect();
|
|
150
|
+
client.on('connect', () => {
|
|
151
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f") === client) {
|
|
152
|
+
this.onConencted();
|
|
153
|
+
this.emit('connect');
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
client.on('close', () => {
|
|
157
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f") === client) {
|
|
158
|
+
this.onClosed();
|
|
159
|
+
this.emit('close');
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
client.on('data', (data) => {
|
|
163
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f") === client) {
|
|
164
|
+
this.onData(data);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
client.on('ready', async () => {
|
|
168
|
+
if (__classPrivateFieldGet(this, _LiteSingleEngine_currentClient, "f") === client) {
|
|
169
|
+
this.onReady();
|
|
170
|
+
this.emit('ready');
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
client.on('error', (err) => {
|
|
174
|
+
this.close();
|
|
175
|
+
this.emit('error');
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_closed, false, "f");
|
|
178
|
+
this.connect();
|
|
179
|
+
}, 30000);
|
|
180
|
+
});
|
|
181
|
+
// Persist client
|
|
182
|
+
__classPrivateFieldSet(this, _LiteSingleEngine_currentClient, client, "f");
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.LiteSingleEngine = LiteSingleEngine;
|
|
186
|
+
_LiteSingleEngine_currentClient = new WeakMap(), _LiteSingleEngine_ready = new WeakMap(), _LiteSingleEngine_closed = new WeakMap(), _LiteSingleEngine_queries = new WeakMap(), _LiteSingleEngine_clientType = new WeakMap(), _LiteSingleEngine_reconnectTimeout = new WeakMap();
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Whales Corp.
|
|
3
|
+
* All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
export { LiteClient } from './client';
|
|
9
|
+
export { LiteEngine } from './engines/engine';
|
|
10
|
+
export { LiteSingleEngine } from './engines/single';
|
|
11
|
+
export { LiteRoundRobinEngine } from './engines/roundRobin';
|
|
12
|
+
export type { AccountsDataLoaderKey, BlockID, BlockLookupIDRequest, BlockLookupUtimeRequest, CacheMap, AllShardsResponse, ClientAccountState, QueryArgs } from './types';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) Whales Corp.
|
|
4
|
+
* All Rights Reserved.
|
|
5
|
+
*
|
|
6
|
+
* This source code is licensed under the MIT license found in the
|
|
7
|
+
* LICENSE file in the root directory of this source tree.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LiteRoundRobinEngine = exports.LiteSingleEngine = exports.LiteClient = void 0;
|
|
11
|
+
var client_1 = require("./client");
|
|
12
|
+
Object.defineProperty(exports, "LiteClient", { enumerable: true, get: function () { return client_1.LiteClient; } });
|
|
13
|
+
var single_1 = require("./engines/single");
|
|
14
|
+
Object.defineProperty(exports, "LiteSingleEngine", { enumerable: true, get: function () { return single_1.LiteSingleEngine; } });
|
|
15
|
+
var roundRobin_1 = require("./engines/roundRobin");
|
|
16
|
+
Object.defineProperty(exports, "LiteRoundRobinEngine", { enumerable: true, get: function () { return roundRobin_1.LiteRoundRobinEngine; } });
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright
|
|
3
|
+
* (c) 2022 Whales Corp.
|
|
4
|
+
* (c) 2023 TrueCarry <truecarry@gmail.com>
|
|
5
|
+
* All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
import { Address, ContractProvider, StateInit } from '@ton/core';
|
|
11
|
+
import { LiteClient } from './';
|
|
12
|
+
export declare function createLiteClientProvider(client: LiteClient, block: number | null, address: Address, init: StateInit | null): ContractProvider;
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright
|
|
4
|
+
* (c) 2022 Whales Corp.
|
|
5
|
+
* (c) 2023 TrueCarry <truecarry@gmail.com>
|
|
6
|
+
* All Rights Reserved.
|
|
7
|
+
*
|
|
8
|
+
* This source code is licensed under the MIT license found in the
|
|
9
|
+
* LICENSE file in the root directory of this source tree.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.createLiteClientProvider = void 0;
|
|
13
|
+
/* eslint-disable camelcase */
|
|
14
|
+
const core_1 = require("@ton/core");
|
|
15
|
+
const buffer_1 = require("buffer");
|
|
16
|
+
const bigint_1 = require("./utils/bigint");
|
|
17
|
+
function createLiteClientProvider(client, block, address, init) {
|
|
18
|
+
return {
|
|
19
|
+
async getState() {
|
|
20
|
+
// Resolve block
|
|
21
|
+
let sq; // = block
|
|
22
|
+
if (block === null) {
|
|
23
|
+
const res = await client.getMasterchainInfo();
|
|
24
|
+
sq = res.last;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const res = await client.getFullBlock(block);
|
|
28
|
+
const shard = res.shards.find((s) => s.workchain === -1);
|
|
29
|
+
sq = {
|
|
30
|
+
...shard,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Load state
|
|
34
|
+
// const state = await client.getAccount(sq, address)
|
|
35
|
+
const state = await client.getAccountState(address, sq);
|
|
36
|
+
// Convert state
|
|
37
|
+
const last = state.lastTx // .account.last
|
|
38
|
+
? {
|
|
39
|
+
lt: BigInt(state.lastTx.lt),
|
|
40
|
+
hash: (0, bigint_1.txHashToBuffer)(state.lastTx.hash),
|
|
41
|
+
}
|
|
42
|
+
: null;
|
|
43
|
+
let storage;
|
|
44
|
+
if (state.state?.storage.state.type === 'active') {
|
|
45
|
+
storage = {
|
|
46
|
+
type: 'active',
|
|
47
|
+
code: state.state?.storage.state.state.code?.toBoc(),
|
|
48
|
+
data: state.state?.storage.state.state.data?.toBoc(),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
else if (state.state?.storage.state.type === 'uninit') {
|
|
52
|
+
storage = {
|
|
53
|
+
type: 'uninit',
|
|
54
|
+
};
|
|
55
|
+
//
|
|
56
|
+
}
|
|
57
|
+
else if (state.state?.storage.state.type === 'frozen') {
|
|
58
|
+
storage = {
|
|
59
|
+
type: 'frozen',
|
|
60
|
+
stateHash: (0, bigint_1.txHashToBuffer)(state.state.storage.state.stateHash),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
throw Error('Unsupported state');
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
balance: BigInt(state.state.storage.balance.coins),
|
|
68
|
+
last,
|
|
69
|
+
state: storage,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
async get(name, args) {
|
|
73
|
+
let sq; // = block
|
|
74
|
+
if (block === null) {
|
|
75
|
+
const res = await client.getMasterchainInfo();
|
|
76
|
+
sq = res.last;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const res = await client.getFullBlock(block);
|
|
80
|
+
const shard = res.shards.find((s) => s.workchain === -1);
|
|
81
|
+
sq = {
|
|
82
|
+
...shard,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// const method = await client.runMethod(address, name, args, sq)c
|
|
86
|
+
const method = await runMethod(client, sq, address, name, args);
|
|
87
|
+
if (method.exitCode !== 0 && method.exitCode !== 1) {
|
|
88
|
+
throw Error('Exit code: ' + method.exitCode);
|
|
89
|
+
}
|
|
90
|
+
return {
|
|
91
|
+
stack: new core_1.TupleReader(method.result),
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
async external(message) {
|
|
95
|
+
const res = await client.getMasterchainInfo();
|
|
96
|
+
const sq = res.last;
|
|
97
|
+
// Resolve init
|
|
98
|
+
let neededInit = null;
|
|
99
|
+
if (init &&
|
|
100
|
+
(await client.getAccountState(address, sq)).state?.storage.state.type !== 'active') {
|
|
101
|
+
neededInit = init;
|
|
102
|
+
}
|
|
103
|
+
const ext = (0, core_1.external)({
|
|
104
|
+
to: address,
|
|
105
|
+
init: neededInit ?? null,
|
|
106
|
+
body: message,
|
|
107
|
+
});
|
|
108
|
+
const pkg = (0, core_1.beginCell)().store((0, core_1.storeMessage)(ext)).endCell().toBoc();
|
|
109
|
+
await client.sendMessage(pkg);
|
|
110
|
+
},
|
|
111
|
+
async internal(via, message) {
|
|
112
|
+
const res = await client.getMasterchainInfo();
|
|
113
|
+
const sq = res.last;
|
|
114
|
+
// Resolve init
|
|
115
|
+
let neededInit = null;
|
|
116
|
+
if (init &&
|
|
117
|
+
(await client.getAccountState(address, sq)).state?.storage.state.type !== 'active') {
|
|
118
|
+
neededInit = init;
|
|
119
|
+
}
|
|
120
|
+
// Resolve bounce
|
|
121
|
+
let bounce = true;
|
|
122
|
+
if (message.bounce !== null && message.bounce !== undefined) {
|
|
123
|
+
bounce = message.bounce;
|
|
124
|
+
}
|
|
125
|
+
// Resolve value
|
|
126
|
+
let value;
|
|
127
|
+
if (typeof message.value === 'string') {
|
|
128
|
+
value = (0, core_1.toNano)(message.value);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
value = message.value;
|
|
132
|
+
}
|
|
133
|
+
// Resolve body
|
|
134
|
+
let body = null;
|
|
135
|
+
if (typeof message.body === 'string') {
|
|
136
|
+
body = (0, core_1.comment)(message.body);
|
|
137
|
+
}
|
|
138
|
+
else if (message.body) {
|
|
139
|
+
body = message.body;
|
|
140
|
+
}
|
|
141
|
+
// Send internal message
|
|
142
|
+
await via.send({
|
|
143
|
+
to: address,
|
|
144
|
+
value,
|
|
145
|
+
bounce,
|
|
146
|
+
sendMode: message.sendMode,
|
|
147
|
+
init: neededInit,
|
|
148
|
+
body,
|
|
149
|
+
});
|
|
150
|
+
},
|
|
151
|
+
open(contract) {
|
|
152
|
+
return (0, core_1.openContract)(contract, (args) => createLiteClientProvider(client, block, args.address, args.init));
|
|
153
|
+
},
|
|
154
|
+
async getTransactions(address, lt, hash, limit) {
|
|
155
|
+
// Resolve last
|
|
156
|
+
const useLimit = typeof limit === 'number';
|
|
157
|
+
if (useLimit && limit <= 0) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
// Load transactions
|
|
161
|
+
let transactions = [];
|
|
162
|
+
do {
|
|
163
|
+
const result = await client.getAccountTransactions(address, lt.toString(), hash, limit ?? 100);
|
|
164
|
+
const txs = core_1.Cell.fromBoc(result.transactions).map((tx) => (0, core_1.loadTransaction)(tx.beginParse()));
|
|
165
|
+
const firstTx = txs[0];
|
|
166
|
+
const [firstLt, firstHash] = [firstTx.lt, firstTx.hash()];
|
|
167
|
+
const needSkipFirst = transactions.length > 0 && firstLt === lt && firstHash.equals(hash);
|
|
168
|
+
if (needSkipFirst) {
|
|
169
|
+
txs.shift();
|
|
170
|
+
}
|
|
171
|
+
if (txs.length === 0) {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
const lastTx = txs[txs.length - 1];
|
|
175
|
+
const [lastLt, lastHash] = [lastTx.lt, lastTx.hash()];
|
|
176
|
+
if (lastLt === lt && lastHash.equals(hash)) {
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
transactions.push(...txs);
|
|
180
|
+
lt = lastLt;
|
|
181
|
+
hash = lastHash;
|
|
182
|
+
} while (useLimit && transactions.length < limit);
|
|
183
|
+
// Apply limit
|
|
184
|
+
if (useLimit) {
|
|
185
|
+
transactions = transactions.slice(0, limit);
|
|
186
|
+
}
|
|
187
|
+
// Return transactions
|
|
188
|
+
return transactions;
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
exports.createLiteClientProvider = createLiteClientProvider;
|
|
193
|
+
/**
|
|
194
|
+
* Execute run method
|
|
195
|
+
* @param seqno block sequence number
|
|
196
|
+
* @param address account address
|
|
197
|
+
* @param name method name
|
|
198
|
+
* @param args method arguments
|
|
199
|
+
* @returns method result
|
|
200
|
+
*/
|
|
201
|
+
async function runMethod(clinet, seqno, address, name, args) {
|
|
202
|
+
const tail = args ? (0, core_1.serializeTuple)(args).toBoc({ idx: false, crc32: false }) : buffer_1.Buffer.alloc(0);
|
|
203
|
+
const res = await clinet.runMethod(address, name, tail, seqno);
|
|
204
|
+
return {
|
|
205
|
+
exitCode: res.exitCode,
|
|
206
|
+
result: res.result ? (0, core_1.parseTuple)(core_1.Cell.fromBoc(buffer_1.Buffer.from(res.result, 'base64'))[0]) : [],
|
|
207
|
+
resultRaw: res.result,
|
|
208
|
+
block: res.block,
|
|
209
|
+
shardBlock: res.shardBlock,
|
|
210
|
+
};
|
|
211
|
+
}
|