@ton/blueprint 0.34.0 → 0.36.0-dev.20250609174628.e67475d

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/CHANGELOG.md CHANGED
@@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## Unreleased
9
+
10
+ ### Added
11
+
12
+ - Added `getConfig` and `getContractState` methods to network provider
13
+
14
+ ## [0.35.0] - 2025-06-02
15
+
16
+ ### Added
17
+
18
+ - Added ton lite client network provider
19
+ - Added tolk verifier
20
+ - Wallet v4 extended support: added v4r1, v4 is treated as v4r2
21
+ - Added possibility to specify custom `manifestUrl` in blueprint configuration
22
+ - Added documentation about the [Tact plugin by TON Studio](https://plugins.jetbrains.com/plugin/27290-tact)
23
+ - Added tolk v0.13 support
24
+
25
+ ### Changed
26
+
27
+ - Updated documentation about Tact wrappers
28
+
8
29
  ## [0.34.0] - 2025-05-20
9
30
 
10
31
  ### Added
package/README.md CHANGED
@@ -55,6 +55,7 @@ Blueprint is an all-in-one development environment designed to enhance the proce
55
55
  1. Compiling FunC with https://github.com/ton-community/func-js
56
56
  2. Compiling Tolk with https://github.com/ton-blockchain/tolk-js
57
57
  3. Compiling Tact with https://github.com/tact-lang/tact
58
+ * Uses [`tact.config.json`](https://docs.tact-lang.org/book/config/) as the build configuration file
58
59
  4. Testing smart contracts with https://github.com/ton-org/sandbox
59
60
  5. Deploying smart contracts with [TON Connect 2](https://github.com/ton-connect) or a `ton://` deeplink
60
61
 
@@ -63,7 +64,9 @@ Blueprint is an all-in-one development environment designed to enhance the proce
63
64
  * [Node.js](https://nodejs.org) with a recent version like v18. Version can be verified with `node -v`
64
65
  * IDE with TON support:
65
66
  * [Visual Studio Code](https://code.visualstudio.com/) with the [FunC plugin](https://marketplace.visualstudio.com/items?itemName=tonwhales.func-vscode), [Tolk plugin](https://marketplace.visualstudio.com/items?itemName=ton-core.tolk-vscode) or [Tact plugin](https://marketplace.visualstudio.com/items?itemName=tonstudio.vscode-tact)
66
- * [IntelliJ IDEA](https://www.jetbrains.com/idea/) with the [TON Development plugin](https://plugins.jetbrains.com/plugin/23382-ton)
67
+ * [IntelliJ IDEA](https://www.jetbrains.com/idea/)
68
+ * [TON Development plugin](https://plugins.jetbrains.com/plugin/23382-ton) for FunC, Tolk and Fift
69
+ * [Tact plugin by TON Studio](https://plugins.jetbrains.com/plugin/27290-tact) for Tact
67
70
 
68
71
  ## Features overview
69
72
 
@@ -75,9 +78,11 @@ Blueprint is an all-in-one development environment designed to enhance the proce
75
78
  ### Directory structure
76
79
 
77
80
  * `contracts/` - Source code for all smart contracts and their imports
78
- * `wrappers/` - TypeScript interface classes for all contracts (implementing `Contract` from [@ton/core](https://www.npmjs.com/package/@ton/core))
79
- * include message [de]serialization primitives, getter wrappers and compilation functions
80
- * used by the test suite and client code to interact with the contracts from TypeScript
81
+ * `wrappers/` - TypeScript interface classes for all contracts **except Tact**.
82
+ * Tact-generated wrappers are located according to the build path defined in [`tact.config.json`](https://docs.tact-lang.org/book/config/)
83
+ * Each wrapper implements `Contract` interface from [@ton/core](https://www.npmjs.com/package/@ton/core)
84
+ * Includes message [de]serialization primitives, getter wrappers and compilation functions
85
+ * Used by the test suite and client code to interact with the contracts from TypeScript
81
86
  * `compilables/` - Compilations scripts for contracts
82
87
  * `tests/` - TypeScript test suite for all contracts (relying on [Sandbox](https://github.com/ton-org/sandbox) for in-process tests)
83
88
  * `scripts/` - Deployment scripts to mainnet/testnet and other scripts interacting with live contracts
@@ -126,7 +131,7 @@ To run scripts using a wallet by mnemonic authentication, you need to configure
126
131
 
127
132
  Start by adding the following environment variables to your `.env` file:
128
133
  * **`WALLET_MNEMONIC`**: Your wallet's mnemonic phrase (space-separated words).
129
- * **`WALLET_VERSION`**: The wallet contract version to use. Supported versions: `v1r1`, `v1r2`, `v1r3`, `v2r1`, `v2r2`, `v3r1`, `v3r2`, `v4`, `v5r1`.
134
+ * **`WALLET_VERSION`**: The wallet contract version to use. Supported versions: `v1r1`, `v1r2`, `v1r3`, `v2r1`, `v2r2`, `v3r1`, `v3r2`, `v4r1`, `v4r2` (or `v4`), `v5r1`.
130
135
 
131
136
  **Optional variables:**
132
137
  * **`WALLET_ID`**: The wallet ID (can be used with versions below `v5r1`).
@@ -292,6 +297,33 @@ npx blueprint run --custom https://toncenter.com/api/v2/jsonRPC --custom-version
292
297
 
293
298
  Properties of the `network` object have the same semantics as the `--custom` flags with respective names (see `blueprint help run`).
294
299
 
300
+ ### Liteclient Support
301
+
302
+ Lite client is supported through the following configuration:
303
+
304
+ ```ts
305
+ import { Config } from '@ton/blueprint';
306
+
307
+ export const config: Config = {
308
+ network: {
309
+ endpoint: 'https://ton.org/testnet-global.config.json', // Use https://ton.org/global.config.json for mainnet or any custom configuration
310
+ version: 'liteclient',
311
+ type: 'testnet',
312
+ }
313
+ };
314
+ ```
315
+
316
+ You can also provide these parameters via CLI:
317
+
318
+ ```bash
319
+ npx blueprint run \
320
+ --custom https://ton.org/testnet-global.config.json \
321
+ --custom-version liteclient \
322
+ --custom-type testnet
323
+ ```
324
+
325
+ #### Contract Verification Using Custom Network
326
+
295
327
  You can also use custom network to verify contracts, like so:
296
328
  ```bash
297
329
  npx blueprint verify --custom https://toncenter.com/api/v2/jsonRPC --custom-version v2 --custom-type mainnet --custom-key YOUR_API_KEY
@@ -310,6 +342,36 @@ export const config: Config = {
310
342
  };
311
343
  ```
312
344
 
345
+ ### Recursive wrappers
346
+
347
+ You can configure whether the `wrappers` or `compilables` directories should be searched recursively for contracts configs by setting the `recursiveWrappers` field.
348
+
349
+ ```typescript
350
+ import { Config } from '@ton/blueprint';
351
+
352
+ export const config: Config = {
353
+ recursiveWrappers: true,
354
+ };
355
+ ```
356
+
357
+ By default, this is set to `false`.
358
+
359
+ ### TonConnect manifest URL
360
+
361
+ If you're using a TonConnect provider, you can override the default manifest URL by specifying the `manifestUrl` field.
362
+ ```typescript
363
+ import { Config } from '@ton/blueprint';
364
+
365
+ export const config: Config = {
366
+ manifestUrl: 'https://yourdomain.com/custom-manifest.json',
367
+ };
368
+ ```
369
+
370
+ By default, the manifest URL is set to:
371
+ ```
372
+ https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json
373
+ ```
374
+
313
375
  ## Contributors
314
376
 
315
377
  Special thanks to [@qdevstudio](https://t.me/qdevstudio) for their logo for blueprint.
package/dist/build.js CHANGED
@@ -17,8 +17,9 @@ async function buildOne(contract, ui) {
17
17
  const buildArtifactPath = path_1.default.join(paths_1.BUILD_DIR, `${contract}.compiled.json`);
18
18
  try {
19
19
  await promises_1.default.unlink(buildArtifactPath);
20
+ // eslint-disable-next-line no-empty
20
21
  }
21
- catch (e) { }
22
+ catch (_) { }
22
23
  ui?.setActionPrompt('⏳ Compiling...');
23
24
  try {
24
25
  const config = await (0, compile_1.getCompilerConfigForContract)(contract);
@@ -83,9 +84,6 @@ async function buildAllTact(ui) {
83
84
  .filter((file) => (0, compile_1.extractCompilableConfig)(file.path).lang === 'tact')
84
85
  .map((file) => file.name);
85
86
  const tactConfig = (0, tact_config_1.getRootTactConfig)();
86
- const tactContracts = [
87
- ...legacyTactContract,
88
- ...tactConfig.projects.map((project) => project.name),
89
- ];
87
+ const tactContracts = [...legacyTactContract, ...tactConfig.projects.map((project) => project.name)];
90
88
  await buildContracts(tactContracts, ui);
91
89
  }
package/dist/cli/cli.js CHANGED
@@ -69,6 +69,7 @@ const runners = {
69
69
  snapshot: snapshot_1.snapshot,
70
70
  };
71
71
  async function main() {
72
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
72
73
  require('ts-node/register');
73
74
  const args = (0, arg_1.default)(Runner_1.argSpec, {
74
75
  permissive: true,
@@ -54,7 +54,7 @@ Blueprint is generally invoked as follows:
54
54
  ${chalk_1.default.cyan('blueprint')} ${chalk_1.default.yellow('[command]')} ${chalk_1.default.gray('[command-args]')} ${chalk_1.default.gray('[flags]')}
55
55
 
56
56
  ${chalk_1.default.bold('List of available commands:')}
57
- ${availableCommands.map(c => `- ${chalk_1.default.green(c)}`).join('\n')}`,
57
+ ${availableCommands.map((c) => `- ${chalk_1.default.green(c)}`).join('\n')}`,
58
58
  create: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('create')} ${chalk_1.default.yellow('[contract name]')} ${chalk_1.default.gray('[flags]')}
59
59
 
60
60
  Creates a new contract together with supporting files according to a template.
@@ -44,7 +44,7 @@ function findFile(dir, filename) {
44
44
  }
45
45
  return foundPath;
46
46
  }
47
- function parseCompileString(str, src_dir, ui) {
47
+ function parseCompileString(str, src_dir, _ui) {
48
48
  // Naive but does the job
49
49
  const tokens = str.split(/\\?\s+/).filter((t) => t != '\\');
50
50
  const outputIdx = tokens.indexOf('-o');
@@ -52,7 +52,7 @@ function parseCompileString(str, src_dir, ui) {
52
52
  throw new Error('No output flag (-o) found in command:' + str);
53
53
  }
54
54
  const outFile = tokens[outputIdx + 1];
55
- const outputName = outFile.match(/([A-Za-z0-9\-_\\\/]*)/);
55
+ const outputName = outFile.match(/([A-Za-z0-9\-_\\/]*)/);
56
56
  if (outputName === null) {
57
57
  throw new Error(`Something went wrong when parsing output from ${outFile}`);
58
58
  }
@@ -80,7 +80,7 @@ function parseCompileString(str, src_dir, ui) {
80
80
  targets: sourceFiles.join(','),
81
81
  };
82
82
  }
83
- const convert = async (args, ui) => {
83
+ const convert = async (_args, ui) => {
84
84
  const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
85
85
  if (localArgs['--help']) {
86
86
  ui.write(constants_1.helpMessages['convert']);
@@ -70,7 +70,7 @@ function addToTactConfig(contractName, contractPath) {
70
70
  };
71
71
  (0, tact_config_1.updateRootTactConfig)(newConfig);
72
72
  }
73
- const create = async (args, ui) => {
73
+ const create = async (_args, ui) => {
74
74
  const localArgs = (0, arg_1.default)({
75
75
  '--type': String,
76
76
  ...constants_1.helpArgs,
package/dist/cli/pack.js CHANGED
@@ -6,8 +6,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.pack = void 0;
7
7
  const child_process_1 = require("child_process");
8
8
  const path_1 = __importDefault(require("path"));
9
- const arg_1 = __importDefault(require("arg"));
10
9
  const fs_1 = require("fs");
10
+ const arg_1 = __importDefault(require("arg"));
11
11
  const constants_1 = require("./constants");
12
12
  const build_1 = require("../build");
13
13
  const paths_1 = require("../paths");
@@ -64,7 +64,7 @@ async function correctPackageJson() {
64
64
  };
65
65
  await fs_1.promises.writeFile(paths_1.PACKAGE_JSON, JSON.stringify(newPackageJson, null, 2));
66
66
  }
67
- const pack = async (args, ui, context) => {
67
+ const pack = async (_args, ui, _context) => {
68
68
  const localArgs = (0, arg_1.default)({
69
69
  '--no-warn': Boolean,
70
70
  '-n': '--no-warn',
@@ -89,7 +89,10 @@ const pack = async (args, ui, context) => {
89
89
  ui.write('🛠️ Updating tsconfig.json...');
90
90
  await correctTsConfig();
91
91
  ui.write('🏗️ Building package...');
92
- await fs_1.promises.rm(path_1.default.join(process.cwd(), 'dist'), { recursive: true, force: true });
92
+ await fs_1.promises.rm(path_1.default.join(process.cwd(), 'dist'), {
93
+ recursive: true,
94
+ force: true,
95
+ });
93
96
  (0, child_process_1.execSync)(`tsc`, { stdio: 'inherit' });
94
97
  ui.write('📝 Updating package.json...');
95
98
  await correctPackageJson();
@@ -5,9 +5,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.rename = void 0;
7
7
  exports.renameExactIfRequired = renameExactIfRequired;
8
- const arg_1 = __importDefault(require("arg"));
9
8
  const fs_1 = require("fs");
10
9
  const path_1 = __importDefault(require("path"));
10
+ const arg_1 = __importDefault(require("arg"));
11
11
  const paths_1 = require("../paths");
12
12
  const Runner_1 = require("./Runner");
13
13
  const utils_1 = require("../utils");
@@ -35,7 +35,10 @@ class RenameContext {
35
35
  if (!(0, fs_1.existsSync)(directory)) {
36
36
  return;
37
37
  }
38
- const dir = await fs_1.promises.readdir(directory, { recursive: true, withFileTypes: true });
38
+ const dir = await fs_1.promises.readdir(directory, {
39
+ recursive: true,
40
+ withFileTypes: true,
41
+ });
39
42
  await Promise.all(dir.map(async (dir) => {
40
43
  if (!dir.isFile()) {
41
44
  return;
@@ -61,7 +64,7 @@ class RenameContext {
61
64
  }
62
65
  }
63
66
  }
64
- const rename = async (args, ui, context) => {
67
+ const rename = async (_args, ui, _context) => {
65
68
  const localArgs = (0, arg_1.default)(constants_1.helpArgs);
66
69
  if (localArgs['--help']) {
67
70
  ui.write(constants_1.helpMessages['rename']);
package/dist/cli/run.js CHANGED
@@ -4,12 +4,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.run = void 0;
7
+ const arg_1 = __importDefault(require("arg"));
7
8
  const Runner_1 = require("./Runner");
8
9
  const createNetworkProvider_1 = require("../network/createNetworkProvider");
9
10
  const utils_1 = require("../utils");
10
- const arg_1 = __importDefault(require("arg"));
11
11
  const constants_1 = require("./constants");
12
- const run = async (args, ui, context) => {
12
+ const run = async (_args, ui, context) => {
13
13
  const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
14
14
  if (localArgs['--help']) {
15
15
  ui.write(constants_1.helpMessages['run']);
package/dist/cli/set.js CHANGED
@@ -23,7 +23,7 @@ const getVersions = (pkg, ui) => {
23
23
  resolve(resJson);
24
24
  }
25
25
  else {
26
- reject(new TypeError("Expect json array on stdout, but got:\n" + stdout));
26
+ reject(new TypeError('Expect json array on stdout, but got:\n' + stdout));
27
27
  }
28
28
  }
29
29
  catch (e) {
@@ -36,7 +36,7 @@ const getVersions = (pkg, ui) => {
36
36
  }
37
37
  }
38
38
  if (error) {
39
- ui.write("Failed to get func-js-bin package versions!");
39
+ ui.write('Failed to get func-js-bin package versions!');
40
40
  reject(error);
41
41
  }
42
42
  });
@@ -4,14 +4,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.verify = void 0;
7
+ const path_1 = __importDefault(require("path"));
7
8
  const core_1 = require("@ton/core");
9
+ const arg_1 = __importDefault(require("arg"));
8
10
  const compile_1 = require("../compile/compile");
9
11
  const Runner_1 = require("./Runner");
10
- const path_1 = __importDefault(require("path"));
11
12
  const createNetworkProvider_1 = require("../network/createNetworkProvider");
12
13
  const build_1 = require("./build");
13
14
  const utils_1 = require("../utils");
14
- const arg_1 = __importDefault(require("arg"));
15
15
  const constants_1 = require("./constants");
16
16
  const backends = {
17
17
  mainnet: {
@@ -121,7 +121,7 @@ async function lookupCodeHash(hash, ui, retryCount = 5) {
121
121
  } while (!done && retryCount > 0);
122
122
  return foundAddr;
123
123
  }
124
- const verify = async (args, ui, context) => {
124
+ const verify = async (_args, ui, context) => {
125
125
  const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
126
126
  if (localArgs['--help']) {
127
127
  ui.write(constants_1.helpMessages['verify']);
@@ -217,6 +217,27 @@ const verify = async (args, ui, context) => {
217
217
  senderAddress: senderAddress.toString(),
218
218
  };
219
219
  }
220
+ else if (result.lang === 'tolk') {
221
+ for (const f of result.snapshot) {
222
+ fd.append(f.filename, new Blob([f.content]), path_1.default.basename(f.filename));
223
+ }
224
+ src = {
225
+ compiler: 'tolk',
226
+ compilerSettings: {
227
+ tolkVersion: result.version,
228
+ },
229
+ knownContractAddress: addr,
230
+ knownContractHash: result.code.hash().toString('base64'),
231
+ sources: result.snapshot.map((s) => ({
232
+ includeInCommand: true,
233
+ isStdLib: false,
234
+ hasIncludeDirectives: true,
235
+ isEntrypoint: s === result.snapshot[0],
236
+ folder: path_1.default.dirname(s.filename),
237
+ })),
238
+ senderAddress: senderAddress.toString(),
239
+ };
240
+ }
220
241
  else {
221
242
  // future proofing
222
243
  throw new Error('Unsupported language ' + result.lang);
@@ -23,6 +23,7 @@ async function getCompilablesDirectory() {
23
23
  return paths_1.WRAPPERS_DIR;
24
24
  }
25
25
  function extractCompilableConfig(path) {
26
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
26
27
  const mod = require(path);
27
28
  if (typeof mod.compile !== 'object') {
28
29
  throw new Error(`Object 'compile' is missing`);
@@ -52,4 +52,10 @@ export interface Config {
52
52
  * @default false
53
53
  */
54
54
  recursiveWrappers?: boolean;
55
+ /**
56
+ * Manifest url passed to TonConnect provider.
57
+ *
58
+ * @default https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json
59
+ */
60
+ manifestUrl?: string;
55
61
  }
@@ -1,6 +1,6 @@
1
1
  export type CustomNetwork = {
2
2
  endpoint: string;
3
- version?: 'v2' | 'v4' | 'tonapi';
3
+ version?: 'v2' | 'v4' | 'tonapi' | 'liteclient';
4
4
  key?: string;
5
5
  type?: 'mainnet' | 'testnet' | 'custom';
6
6
  };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { tonDeepLink, sleep } from './utils';
2
2
  export { NetworkProvider } from './network/NetworkProvider';
3
3
  export { createNetworkProvider } from './network/createNetworkProvider';
4
- export { compile, CompileOpts, TolkCompileResult, FuncCompileResult, TactCompileResult, CompileResult } from './compile/compile';
4
+ export { compile, CompileOpts, TolkCompileResult, FuncCompileResult, TactCompileResult, CompileResult, } from './compile/compile';
5
5
  export { CompilerConfig, HookParams } from './compile/CompilerConfig';
6
6
  export { UIProvider } from './ui/UIProvider';
7
7
  export { Config } from './config/Config';
@@ -9,5 +9,5 @@ export { Args, Runner, RunnerContext } from './cli/Runner';
9
9
  export { PluginRunner, Plugin } from './config/Plugin';
10
10
  export { CustomNetwork } from './config/CustomNetwork';
11
11
  export { buildOne, buildAll, buildAllTact } from './build';
12
- export { SourceSnapshot } from "./compile/SourceSnapshot";
12
+ export { SourceSnapshot } from './compile/SourceSnapshot';
13
13
  export { getCompilerConfigForContract } from './compile/compile';
@@ -1,8 +1,10 @@
1
- import { TonClient, TonClient4 } from '@ton/ton';
2
- import { Address, Cell, Contract, ContractProvider, OpenedContract, Sender } from '@ton/core';
1
+ import { parseFullConfig, TonClient, TonClient4 } from '@ton/ton';
2
+ import { Address, Cell, Contract, ContractProvider, ContractState, OpenedContract, Sender } from '@ton/core';
3
3
  import { ContractAdapter } from '@ton-api/ton-adapter';
4
+ import { LiteClient } from 'ton-lite-client';
4
5
  import { UIProvider } from '../ui/UIProvider';
5
- export type BlueprintTonClient = TonClient4 | TonClient | ContractAdapter;
6
+ export type BlueprintTonClient = TonClient4 | TonClient | ContractAdapter | LiteClient;
7
+ type BlockchainConfig = ReturnType<typeof parseFullConfig>;
6
8
  /**
7
9
  * Interface representing a network provider for interacting with TON blockchain.
8
10
  */
@@ -69,6 +71,35 @@ export interface NetworkProvider {
69
71
  * @returns {Promise<void>} A promise that resolves when the contract is deployed or the attempts are exhausted.
70
72
  */
71
73
  waitForDeploy(address: Address, attempts?: number, sleepDuration?: number): Promise<void>;
74
+ /**
75
+ * Retrieves the state of a contract at the specified address.
76
+ *
77
+ * @param {Address} address - The address of the contract.
78
+ *
79
+ * @example
80
+ * const address = Address.parse('YOUR_CONTRACT_ADDRESS');
81
+ * const state = await provider.getContractState(address);
82
+ * console.log(`Contract balance: ${fromNano(state.balance)} TON`);
83
+ *
84
+ * @returns {Promise<ContractState>} A promise that resolves to the contract's state.
85
+ */
86
+ getContractState(address: Address): Promise<ContractState>;
87
+ /**
88
+ * Fetches the current blockchain configuration.
89
+ *
90
+ * This method retrieves the configuration from the masterchain. If no address is provided,
91
+ * it defaults to the standard config address:
92
+ * `-1:5555555555555555555555555555555555555555555555555555555555555555`.
93
+ *
94
+ * @param {Address} [configAddress] - Optional configuration address.
95
+ *
96
+ * @example
97
+ * const config = await provider.getConfig();
98
+ * console.log('Global config version:', config.globalVersion.version);
99
+ *
100
+ @returns {Promise<BlockchainConfig>} A promise that resolves to the blockchain configuration.
101
+ */
102
+ getConfig(configAddress?: Address): Promise<BlockchainConfig>;
72
103
  /**
73
104
  * @deprecated
74
105
  *
@@ -94,3 +125,4 @@ export interface NetworkProvider {
94
125
  */
95
126
  ui(): UIProvider;
96
127
  }
128
+ export {};
@@ -17,21 +17,23 @@ var _SendProviderSender_provider, _WrappedContractProvider_address, _WrappedCont
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.argSpec = void 0;
19
19
  exports.createNetworkProvider = createNetworkProvider;
20
- const utils_1 = require("../utils");
21
- const DeeplinkProvider_1 = require("./send/DeeplinkProvider");
22
- const TonConnectProvider_1 = require("./send/TonConnectProvider");
20
+ const path_1 = __importDefault(require("path"));
23
21
  const core_1 = require("@ton/core");
24
22
  const ton_1 = require("@ton/ton");
25
23
  const ton_adapter_1 = require("@ton-api/ton-adapter");
26
24
  const client_1 = require("@ton-api/client");
25
+ const crypto_1 = require("@ton/crypto");
26
+ const axios_1 = __importDefault(require("axios"));
27
+ const ton_lite_client_1 = require("ton-lite-client");
28
+ const utils_1 = require("../utils");
29
+ const DeeplinkProvider_1 = require("./send/DeeplinkProvider");
30
+ const TonConnectProvider_1 = require("./send/TonConnectProvider");
27
31
  const FSStorage_1 = require("./storage/FSStorage");
28
- const path_1 = __importDefault(require("path"));
29
32
  const paths_1 = require("../paths");
30
- const crypto_1 = require("@ton/crypto");
31
33
  const MnemonicProvider_1 = require("./send/MnemonicProvider");
32
- const axios_1 = __importDefault(require("axios"));
33
34
  const INITIAL_DELAY = 400;
34
35
  const MAX_ATTEMPTS = 4;
36
+ const CONFIG_ADDRESS = core_1.Address.parse('-1:5555555555555555555555555555555555555555555555555555555555555555');
35
37
  exports.argSpec = {
36
38
  '--mainnet': Boolean,
37
39
  '--testnet': Boolean,
@@ -140,6 +142,25 @@ class NetworkProviderImpl {
140
142
  async isContractDeployed(address) {
141
143
  return (await __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").provider(address).getState()).state.type === 'active';
142
144
  }
145
+ async getConfig(address = CONFIG_ADDRESS) {
146
+ const state = await this.getContractState(address);
147
+ if (state.state.type !== 'active' || !state.state.data) {
148
+ throw new Error('Configuration contract not active');
149
+ }
150
+ const paramsDict = core_1.Cell.fromBoc(state.state.data)[0]
151
+ .beginParse()
152
+ .loadRef()
153
+ .beginParse()
154
+ .loadDictDirect(core_1.Dictionary.Keys.Int(32), core_1.Dictionary.Values.Cell());
155
+ const params = new Map();
156
+ for (const [key, value] of paramsDict) {
157
+ params.set(key, value.beginParse());
158
+ }
159
+ return (0, ton_1.parseFullConfig)(params);
160
+ }
161
+ async getContractState(address) {
162
+ return await __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").provider(address).getState();
163
+ }
143
164
  async waitForDeploy(address, attempts = 20, sleepDuration = 2000) {
144
165
  if (attempts <= 0) {
145
166
  throw new Error('Attempt number must be positive');
@@ -216,6 +237,33 @@ async function createMnemonicProvider(client, network, ui) {
216
237
  network,
217
238
  });
218
239
  }
240
+ function intToIP(int) {
241
+ const part1 = int & 255;
242
+ const part2 = (int >> 8) & 255;
243
+ const part3 = (int >> 16) & 255;
244
+ const part4 = (int >> 24) & 255;
245
+ return `${(part4 + 256) % 256}.${(part3 + 256) % 256}.${(part2 + 256) % 256}.${(part1 + 256) % 256}`;
246
+ }
247
+ async function buildLiteClient(configEndpoint) {
248
+ const { data } = await axios_1.default.get(configEndpoint);
249
+ if (!Array.isArray(data.liteservers)) {
250
+ throw new Error(`Invalid liteclient configuration on ${configEndpoint}. Use https://ton.org/testnet-global.config.json for testnet or https://ton.org/global.config.json for mainnet.`);
251
+ }
252
+ const engines = data.liteservers.map((server) => {
253
+ if (typeof server?.ip !== 'number' ||
254
+ typeof server?.port !== 'number' ||
255
+ typeof server?.id !== 'object' ||
256
+ typeof server?.id?.key !== 'string') {
257
+ throw new Error(`Invalid liteclient configuration on ${configEndpoint}`);
258
+ }
259
+ return new ton_lite_client_1.LiteSingleEngine({
260
+ host: `tcp://${intToIP(server.ip)}:${server.port}`,
261
+ publicKey: Buffer.from(server.id.key, 'base64'),
262
+ });
263
+ });
264
+ const engine = new ton_lite_client_1.LiteRoundRobinEngine(engines);
265
+ return new ton_lite_client_1.LiteClient({ engine });
266
+ }
219
267
  class NetworkProviderBuilder {
220
268
  constructor(args, ui, config, allowCustom = true) {
221
269
  this.args = args;
@@ -283,7 +331,7 @@ class NetworkProviderBuilder {
283
331
  case 'tonconnect':
284
332
  if (network === 'custom')
285
333
  throw new Error('Tonkeeper cannot work with custom network.');
286
- provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui, network);
334
+ provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui, network, this.config?.manifestUrl);
287
335
  break;
288
336
  case 'mnemonic':
289
337
  provider = await createMnemonicProvider(client, network, this.ui);
@@ -349,6 +397,9 @@ class NetworkProviderBuilder {
349
397
  apiKey: configNetwork.key,
350
398
  }));
351
399
  }
400
+ else if (configNetwork.version === 'liteclient') {
401
+ tc = await buildLiteClient(configNetwork.endpoint);
402
+ }
352
403
  else {
353
404
  throw new Error('Unknown API version: ' + configNetwork.version);
354
405
  }
@@ -397,7 +448,7 @@ class NetworkProviderBuilder {
397
448
  try {
398
449
  await sendProvider.connect();
399
450
  }
400
- catch (e) {
451
+ catch (_) {
401
452
  console.error('Unable to connect to wallet.');
402
453
  process.exit(1);
403
454
  }
@@ -17,8 +17,8 @@ var _DeeplinkProvider_network, _DeeplinkProvider_ui;
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.DeeplinkProvider = void 0;
19
19
  const core_1 = require("@ton/core");
20
- const utils_1 = require("../../utils");
21
20
  const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
21
+ const utils_1 = require("../../utils");
22
22
  class DeeplinkProvider {
23
23
  constructor(network, ui) {
24
24
  _DeeplinkProvider_network.set(this, void 0);
@@ -1,9 +1,10 @@
1
+ import { Buffer } from 'buffer';
1
2
  import { Address, Cell, StateInit } from '@ton/core';
2
3
  import { SendProvider } from './SendProvider';
3
4
  import { UIProvider } from '../../ui/UIProvider';
4
5
  import { BlueprintTonClient } from '../NetworkProvider';
5
6
  import { Network } from '../Network';
6
- export type WalletVersion = 'v1r1' | 'v1r2' | 'v1r3' | 'v2r1' | 'v2r2' | 'v3r1' | 'v3r2' | 'v4' | 'v5r1';
7
+ import { WalletVersion } from './wallets';
7
8
  type MnemonicProviderParams = {
8
9
  version: WalletVersion;
9
10
  workchain?: number;
@@ -13,20 +13,9 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
13
13
  var _MnemonicProvider_wallet, _MnemonicProvider_secretKey, _MnemonicProvider_client, _MnemonicProvider_ui, _MnemonicProvider_network;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.MnemonicProvider = void 0;
16
- const ton_1 = require("@ton/ton");
17
16
  const core_1 = require("@ton/core");
18
17
  const crypto_1 = require("@ton/crypto");
19
- const wallets = {
20
- v1r1: ton_1.WalletContractV1R1,
21
- v1r2: ton_1.WalletContractV1R2,
22
- v1r3: ton_1.WalletContractV1R3,
23
- v2r1: ton_1.WalletContractV2R1,
24
- v2r2: ton_1.WalletContractV2R2,
25
- v3r1: ton_1.WalletContractV3R1,
26
- v3r2: ton_1.WalletContractV3R2,
27
- v4: ton_1.WalletContractV4,
28
- v5r1: ton_1.WalletContractV5R1,
29
- };
18
+ const wallets_1 = require("./wallets");
30
19
  class MnemonicProvider {
31
20
  constructor(params) {
32
21
  _MnemonicProvider_wallet.set(this, void 0);
@@ -34,8 +23,8 @@ class MnemonicProvider {
34
23
  _MnemonicProvider_client.set(this, void 0);
35
24
  _MnemonicProvider_ui.set(this, void 0);
36
25
  _MnemonicProvider_network.set(this, void 0);
37
- if (!(params.version in wallets)) {
38
- throw new Error(`Unknown wallet version ${params.version}`);
26
+ if (!(params.version in wallets_1.wallets)) {
27
+ throw new Error(`Unknown wallet version ${params.version}, expected one of ${Object.keys(wallets_1.wallets).join(', ')}`);
39
28
  }
40
29
  __classPrivateFieldSet(this, _MnemonicProvider_client, params.client, "f");
41
30
  __classPrivateFieldSet(this, _MnemonicProvider_network, params.network, "f");
@@ -50,7 +39,7 @@ class MnemonicProvider {
50
39
  }
51
40
  createWallet(params, kp) {
52
41
  if (params.version === 'v5r1') {
53
- return wallets[params.version].create({
42
+ return wallets_1.wallets[params.version].create({
54
43
  publicKey: kp.publicKey,
55
44
  walletId: {
56
45
  networkGlobalId: params.network === 'testnet' ? -3 : -239, // networkGlobalId: -3 for Testnet, -239 for Mainnet
@@ -62,14 +51,17 @@ class MnemonicProvider {
62
51
  },
63
52
  });
64
53
  }
65
- return wallets[params.version].create({
54
+ return wallets_1.wallets[params.version].create({
66
55
  workchain: params.workchain ?? 0,
67
56
  publicKey: kp.publicKey,
68
57
  walletId: params.walletId,
69
58
  });
70
59
  }
71
60
  async connect() {
72
- const formattedAddress = this.address().toString({ testOnly: __classPrivateFieldGet(this, _MnemonicProvider_network, "f") === 'testnet', bounceable: false });
61
+ const formattedAddress = this.address().toString({
62
+ testOnly: __classPrivateFieldGet(this, _MnemonicProvider_network, "f") === 'testnet',
63
+ bounceable: false,
64
+ });
73
65
  __classPrivateFieldGet(this, _MnemonicProvider_ui, "f").write(`Connected to wallet at address: ${formattedAddress}\n`);
74
66
  }
75
67
  async sendTransaction(address, amount, payload, stateInit) {
@@ -5,7 +5,7 @@ import { UIProvider } from '../../ui/UIProvider';
5
5
  import { Network } from '../Network';
6
6
  export declare class TonConnectProvider implements SendProvider {
7
7
  #private;
8
- constructor(storage: Storage, ui: UIProvider, network: Network);
8
+ constructor(storage: Storage, ui: UIProvider, network: Network, manifestUrl?: string);
9
9
  connect(): Promise<void>;
10
10
  address(): Address | undefined;
11
11
  private connectWallet;
@@ -39,13 +39,13 @@ function isRemote(walletInfo) {
39
39
  return 'universalLink' in walletInfo && 'bridgeUrl' in walletInfo;
40
40
  }
41
41
  class TonConnectProvider {
42
- constructor(storage, ui, network) {
42
+ constructor(storage, ui, network, manifestUrl = 'https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json') {
43
43
  _TonConnectProvider_connector.set(this, void 0);
44
44
  _TonConnectProvider_ui.set(this, void 0);
45
45
  _TonConnectProvider_network.set(this, void 0);
46
46
  __classPrivateFieldSet(this, _TonConnectProvider_connector, new sdk_1.default({
47
47
  storage: new TonConnectStorage(storage),
48
- manifestUrl: 'https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json',
48
+ manifestUrl,
49
49
  }), "f");
50
50
  __classPrivateFieldSet(this, _TonConnectProvider_ui, ui, "f");
51
51
  __classPrivateFieldSet(this, _TonConnectProvider_network, network, "f");
@@ -0,0 +1,25 @@
1
+ import { Buffer } from 'buffer';
2
+ import { WalletContractV4 as WalletContractV4R2 } from '@ton/ton/dist/wallets/WalletContractV4';
3
+ import { WalletContractV1R1, WalletContractV1R2, WalletContractV1R3, WalletContractV2R1, WalletContractV2R2, WalletContractV3R1, WalletContractV3R2, WalletContractV5R1 } from '@ton/ton';
4
+ export type WalletVersion = 'v1r1' | 'v1r2' | 'v1r3' | 'v2r1' | 'v2r2' | 'v3r1' | 'v3r2' | 'v4' | 'v4r1' | 'v4r2' | 'v5r1';
5
+ declare class WalletContractV4R1 {
6
+ static create(args: {
7
+ workchain: number;
8
+ publicKey: Buffer;
9
+ walletId?: number | null;
10
+ }): WalletContractV4R2;
11
+ }
12
+ export declare const wallets: {
13
+ v1r1: typeof WalletContractV1R1;
14
+ v1r2: typeof WalletContractV1R2;
15
+ v1r3: typeof WalletContractV1R3;
16
+ v2r1: typeof WalletContractV2R1;
17
+ v2r2: typeof WalletContractV2R2;
18
+ v3r1: typeof WalletContractV3R1;
19
+ v3r2: typeof WalletContractV3R2;
20
+ v4: typeof WalletContractV4R2;
21
+ v4r1: typeof WalletContractV4R1;
22
+ v4r2: typeof WalletContractV4R2;
23
+ v5r1: typeof WalletContractV5R1;
24
+ };
25
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wallets = void 0;
4
+ const buffer_1 = require("buffer");
5
+ const WalletContractV4_1 = require("@ton/ton/dist/wallets/WalletContractV4");
6
+ const core_1 = require("@ton/core");
7
+ const ton_1 = require("@ton/ton");
8
+ class WalletContractV4R1 {
9
+ static create(args) {
10
+ const wallet = WalletContractV4_1.WalletContractV4.create(args);
11
+ const { data } = wallet.init;
12
+ const code = core_1.Cell.fromBoc(buffer_1.Buffer.from('B5EE9C72410215010002F5000114FF00F4A413F4BCF2C80B010201200203020148040504F8F28308D71820D31FD31FD31F02F823BBF263ED44D0D31FD31FD3FFF404D15143BAF2A15151BAF2A205F901541064F910F2A3F80024A4C8CB1F5240CB1F5230CBFF5210F400C9ED54F80F01D30721C0009F6C519320D74A96D307D402FB00E830E021C001E30021C002E30001C0039130E30D03A4C8CB1F12CB1FCBFF1112131403EED001D0D3030171B0915BE021D749C120915BE001D31F218210706C7567BD228210626C6E63BDB022821064737472BDB0925F03E002FA403020FA4401C8CA07CBFFC9D0ED44D0810140D721F404305C810108F40A6FA131B3925F05E004D33FC8258210706C7567BA9131E30D248210626C6E63BAE30004060708020120090A005001FA00F404308210706C7567831EB17080185005CB0527CF165003FA02F40012CB69CB1F5210CB3F0052F8276F228210626C6E63831EB17080185005CB0527CF1624FA0214CB6A13CB1F5230CB3F01FA02F4000092821064737472BA8E3504810108F45930ED44D0810140D720C801CF16F400C9ED54821064737472831EB17080185004CB0558CF1622FA0212CB6ACB1FCB3F9410345F04E2C98040FB000201200B0C0059BD242B6F6A2684080A06B90FA0218470D4080847A4937D29910CE6903E9FF9837812801B7810148987159F31840201580D0E0011B8C97ED44D0D70B1F8003DB29DFB513420405035C87D010C00B23281F2FFF274006040423D029BE84C600201200F100019ADCE76A26840206B90EB85FFC00019AF1DF6A26840106B90EB858FC0006ED207FA00D4D422F90005C8CA0715CBFFC9D077748018C8CB05CB0222CF165005FA0214CB6B12CCCCC971FB00C84014810108F451F2A702006C810108D718C8542025810108F451F2A782106E6F746570748018C8CB05CB025004CF16821005F5E100FA0213CB6A12CB1FC971FB00020072810108D718305202810108F459F2A7F82582106473747270748018C8CB05CB025005CF16821005F5E100FA0214CB6A13CB1F12CB3FC973FB00000AF400C9ED5446A9F34F', 'hex'))[0];
13
+ wallet.init = { data, code };
14
+ wallet.address = (0, core_1.contractAddress)(args.workchain, wallet.init);
15
+ return wallet;
16
+ }
17
+ }
18
+ exports.wallets = {
19
+ v1r1: ton_1.WalletContractV1R1,
20
+ v1r2: ton_1.WalletContractV1R2,
21
+ v1r3: ton_1.WalletContractV1R3,
22
+ v2r1: ton_1.WalletContractV2R1,
23
+ v2r2: ton_1.WalletContractV2R2,
24
+ v3r1: ton_1.WalletContractV3R1,
25
+ v3r2: ton_1.WalletContractV3R2,
26
+ v4: WalletContractV4_1.WalletContractV4, // left for backward compatibility
27
+ v4r1: WalletContractV4R1,
28
+ v4r2: WalletContractV4_1.WalletContractV4,
29
+ v5r1: ton_1.WalletContractV5R1,
30
+ };
@@ -44,7 +44,7 @@ _FSStorage_path = new WeakMap(), _FSStorage_instances = new WeakSet(), _FSStorag
44
44
  try {
45
45
  return JSON.parse((await promises_1.default.readFile(__classPrivateFieldGet(this, _FSStorage_path, "f"))).toString('utf-8'));
46
46
  }
47
- catch (e) {
47
+ catch (_) {
48
48
  return {};
49
49
  }
50
50
  }, _FSStorage_writeObject = async function _FSStorage_writeObject(obj) {
@@ -1,33 +1,33 @@
1
1
  {{snakeName}}.tolk
2
2
  // simple counter contract in Tolk language
3
3
 
4
- const OP_INCREASE = 0x7e8764ef; // arbitrary 32-bit number, equal to OP_INCREASE in wrappers/CounterContract.ts
4
+ // using unions to represent contract messages
5
5
 
6
- // storage variables
7
-
8
- // id is required to be able to create different instances of counters
9
- // since addresses in TON depend on the initial state of the contract
10
- global ctxID: int;
11
- global ctxCounter: int;
6
+ // the struct uses a 32-bit opcode prefix for message identification
7
+ struct (0x7e8764ef) IncreaseMessage {
8
+ queryID: uint64; // query id, typically included in messages
9
+ increaseBy: uint32;
10
+ }
12
11
 
13
- // loadData populates storage variables from persistent storage
14
- fun loadData() {
15
- var ds = contract.getData().beginParse();
12
+ // incoming message definition using a union for extensibility
13
+ // this union could be extended like below to support more message types
14
+ // type IncomingMessage = IncreaseMessage | DecreaseMessage | ...;
15
+ type IncomingMessage = IncreaseMessage;
16
16
 
17
- ctxID = ds.loadUint(32);
18
- ctxCounter = ds.loadUint(32);
17
+ // contract storage, auto-serialized to/from cells.
18
+ struct Storage {
19
+ id: uint32; // required to allow multiple independent counter instances, since contract address depends on initial state
20
+ counter: uint32;
21
+ }
19
22
 
20
- ds.assertEnd();
23
+ // load contract data using auto-deserialization
24
+ fun loadData() {
25
+ return Storage.fromCell(contract.getData());
21
26
  }
22
27
 
23
- // saveData stores storage variables as a cell into persistent storage
24
- fun saveData() {
25
- contract.setData(
26
- beginCell()
27
- .storeUint(ctxID, 32)
28
- .storeUint(ctxCounter, 32)
29
- .endCell()
30
- );
28
+ // save contract data into persistent storage using auto-serialization
29
+ fun saveData(data: Storage) {
30
+ contract.setData(data.toCell());
31
31
  }
32
32
 
33
33
  // onInternalMessage is the main entrypoint; it's called when a contract receives an internal message from other contracts
@@ -36,36 +36,39 @@ fun onInternalMessage(myBalance: int, msgValue: int, msgFull: cell, msgBody: sli
36
36
  return;
37
37
  }
38
38
 
39
- var cs: slice = msgFull.beginParse();
39
+ var cs = msgFull.beginParse();
40
40
  val flags = cs.loadMessageFlags();
41
41
  if (isMessageBounced(flags)) { // ignore all bounced messages
42
42
  return;
43
43
  }
44
44
 
45
- loadData(); // here we populate the storage variables
46
-
47
- val op = msgBody.loadMessageOp(); // by convention, the first 32 bits of incoming message is the op
48
- val queryID = msgBody.loadMessageQueryId(); // also by convention, the next 64 bits contain the "query id", although this is not always the case
49
-
50
- if (op == OP_INCREASE) {
51
- val increaseBy = msgBody.loadUint(32);
52
- ctxCounter += increaseBy;
53
- saveData();
54
- return;
45
+ val msg = IncomingMessage.fromSlice(msgBody); // 63 error code is thrown if the message opcode is unknown
46
+
47
+ match (msg) {
48
+ IncreaseMessage => {
49
+ var storage = loadData(); // here we load contract data
50
+ storage.counter += msg.increaseBy;
51
+ saveData(storage); // here we updating contract data
52
+ }
53
+ /* other messages could be supported via extending this match block
54
+ DecreaseMessage => {
55
+ var storage = loadData();
56
+ storage.counter -= msg.decreaseBy;
57
+ saveData(storage);
58
+ }
59
+ */
55
60
  }
56
-
57
- throw 0xffff; // if the message contains an op that is not known to this contract, we throw
58
61
  }
59
62
 
60
63
  // get methods are a means to conveniently read contract data using, for example, HTTP APIs
61
64
  // note that unlike in many other smart contract VMs, get methods cannot be called by other contracts
62
65
 
63
66
  get currentCounter(): int {
64
- loadData();
65
- return ctxCounter;
67
+ val storage = loadData();
68
+ return storage.counter;
66
69
  }
67
70
 
68
71
  get initialId(): int {
69
- loadData();
70
- return ctxID;
72
+ val storage = loadData();
73
+ return storage.id;
71
74
  }
@@ -1,5 +1,5 @@
1
- import { UIProvider } from '../ui/UIProvider';
2
1
  import { Address } from '@ton/core';
2
+ import { UIProvider } from '../ui/UIProvider';
3
3
  export declare class InquirerUIProvider implements UIProvider {
4
4
  #private;
5
5
  constructor();
@@ -46,7 +46,7 @@ class InquirerUIProvider {
46
46
  try {
47
47
  return addr === '' && fallback !== undefined ? fallback : core_1.Address.parse(addr);
48
48
  }
49
- catch (e) {
49
+ catch (_) {
50
50
  this.write(addr + ' is not valid!\n');
51
51
  }
52
52
  }
@@ -52,7 +52,10 @@ const findCompiles = async (directory) => {
52
52
  if (!(0, fs_1.existsSync)(dir)) {
53
53
  return [];
54
54
  }
55
- const files = await promises_1.default.readdir(dir, { recursive: (await (0, utils_1.getConfig)())?.recursiveWrappers ?? false, withFileTypes: true });
55
+ const files = await promises_1.default.readdir(dir, {
56
+ recursive: (await (0, utils_1.getConfig)())?.recursiveWrappers ?? false,
57
+ withFileTypes: true,
58
+ });
56
59
  const compilables = files.filter((file) => file.isFile() && file.name.endsWith(compile_1.COMPILE_END));
57
60
  return compilables.map((file) => ({
58
61
  path: path_1.default.join(file.path, file.name),
@@ -70,7 +73,10 @@ const findContracts = async () => {
70
73
  };
71
74
  exports.findContracts = findContracts;
72
75
  const findScripts = async () => {
73
- const dirents = await promises_1.default.readdir(paths_1.SCRIPTS_DIR, { recursive: true, withFileTypes: true });
76
+ const dirents = await promises_1.default.readdir(paths_1.SCRIPTS_DIR, {
77
+ recursive: true,
78
+ withFileTypes: true,
79
+ });
74
80
  const scripts = dirents.filter((dirent) => dirent.isFile() && dirent.name.endsWith('.ts'));
75
81
  return scripts
76
82
  .map((script) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ton/blueprint",
3
- "version": "0.34.0",
3
+ "version": "0.36.0-dev.20250609174628.e67475d",
4
4
  "description": "Framework for development of TON smart contracts",
5
5
  "main": "dist/index.js",
6
6
  "bin": "./dist/cli/cli.js",
@@ -15,29 +15,33 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "rm -rf dist && tsc && cp -r src/templates dist/",
18
+ "test": "echo \"Error: no test specified\" && exit 0",
18
19
  "release": "yarn build && yarn publish --access public",
19
- "format": "prettier --write src"
20
+ "lint": "eslint . --max-warnings 0",
21
+ "lint:fix": "eslint . --max-warnings 0 --fix"
20
22
  },
23
+ "prettier": "@ton/toolchain/prettier",
21
24
  "devDependencies": {
22
25
  "@tact-lang/compiler": "^1.6.5",
23
26
  "@ton-community/func-js": "^0.9.0",
24
- "@ton/core": "^0.59.0",
27
+ "@ton/core": "^0.60.1",
25
28
  "@ton/crypto": "^3.3.0",
26
29
  "@ton/tolk-js": "^0.12.0",
27
- "@ton/ton": "^15.0.0",
30
+ "@ton/ton": "^15.2.1",
31
+ "@ton/toolchain": "the-ton-tech/toolchain#v1.4.0",
28
32
  "@types/inquirer": "^8.2.6",
29
33
  "@types/node": "^20.2.5",
30
34
  "@types/qrcode-terminal": "^0.12.0",
31
- "prettier": "^3.0.3",
35
+ "eslint": "^9.28.0",
32
36
  "typescript": "^5.8.3"
33
37
  },
34
38
  "peerDependencies": {
35
39
  "@tact-lang/compiler": ">=1.6.5",
36
40
  "@ton-community/func-js": ">=0.9.0",
37
- "@ton/core": ">=0.59.0",
41
+ "@ton/core": ">=0.60.1",
38
42
  "@ton/crypto": ">=3.3.0",
39
- "@ton/tolk-js": ">=0.12.0",
40
- "@ton/ton": ">=15.0.0"
43
+ "@ton/tolk-js": ">=0.13.0",
44
+ "@ton/ton": ">=15.2.1"
41
45
  },
42
46
  "dependencies": {
43
47
  "@ton-api/client": "^0.2.0",
@@ -49,7 +53,8 @@
49
53
  "dotenv": "^16.1.4",
50
54
  "inquirer": "^8.2.5",
51
55
  "qrcode-terminal": "^0.12.0",
56
+ "ton-lite-client": "^3.1.0",
52
57
  "ts-node": "^10.9.1"
53
58
  },
54
- "packageManager": "yarn@4.3.1"
59
+ "packageManager": "yarn@4.9.2"
55
60
  }