@ton/blueprint 0.29.0 → 0.31.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/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
+ ## [0.31.0] - 2025-04-24
9
+
10
+ ### Added
11
+
12
+ - Added Fift output for FunC and Tolk build command
13
+ - Added API reference in code
14
+
15
+ ### Changed
16
+
17
+ - Improved CLI appearance
18
+
19
+ ## [0.30.0] - 2025-04-08
20
+
21
+ ### Fixed
22
+
23
+ - Fixed Tact compilation
24
+
25
+ ### Changed
26
+
27
+ - Updated Tact templates and `@tact-lang/compiler` dependency to v1.6.5
28
+
8
29
  ## [0.29.0] - 2025-03-02
9
30
 
10
31
  ### Changed
@@ -199,18 +220,18 @@ This release contains a breaking change.
199
220
 
200
221
  ### Fixed
201
222
 
202
- - Fixed TACT imports
223
+ - Fixed Tact imports
203
224
  - Fixed missing newlines when printing error messages while building contracts
204
225
 
205
226
  ## [0.11.0] - 2023-07-03
206
227
 
207
228
  ### Added
208
229
 
209
- - Added an `options` field to the `tact` variant of `CompilerConfig`, which is of the same type as the `options` of the TACT compiler, and includes fields such as `debug`, `experimental`, etc
230
+ - Added an `options` field to the `tact` variant of `CompilerConfig`, which is of the same type as the `options` of the Tact compiler, and includes fields such as `debug`, `experimental`, etc
210
231
 
211
232
  ### Changed
212
233
 
213
- - Updated TACT to 1.1.3
234
+ - Updated Tact to 1.1.3
214
235
 
215
236
  ## [0.10.0] - 2023-06-06
216
237
 
@@ -226,7 +247,7 @@ This release contains a breaking change.
226
247
 
227
248
  ### Changed
228
249
 
229
- - Updated dependencies, of note: func-js to use func 0.4.3, TACT to 1.1.1
250
+ - Updated dependencies, of note: func-js to use func 0.4.3, Tact to 1.1.1
230
251
 
231
252
  ## [0.8.0] - 2023-04-07
232
253
 
@@ -255,7 +276,7 @@ This release contains a breaking change.
255
276
 
256
277
  ### Added
257
278
 
258
- - Added support for [TACT](https://github.com/tact-lang/tact), including TACT smart contract templates
279
+ - Added support for [Tact](https://github.com/tact-lang/tact), including Tact smart contract templates
259
280
  - Added `--all` option for `build` command
260
281
 
261
282
  ### Changed
package/README.md CHANGED
@@ -60,7 +60,7 @@ Blueprint is an all-in-one development environment designed to enhance the proce
60
60
 
61
61
  * [Node.js](https://nodejs.org) with a recent version like v18. Version can be verified with `node -v`
62
62
  * IDE with TON support:
63
- * [Visual Studio Code](https://code.visualstudio.com/) with the [FunC plugin](https://marketplace.visualstudio.com/items?itemName=tonwhales.func-vscode) or [Tolk plugin](https://marketplace.visualstudio.com/items?itemName=ton-core.tolk-vscode)
63
+ * [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)
64
64
  * [IntelliJ IDEA](https://www.jetbrains.com/idea/) with the [TON Development plugin](https://plugins.jetbrains.com/plugin/23382-ton)
65
65
 
66
66
  ## Features overview
@@ -89,6 +89,7 @@ Blueprint is an all-in-one development environment designed to enhance the proce
89
89
  * Example: `yarn blueprint build counter`
90
90
  4. Build results are generated in `build/<CONTRACT>.compiled.json`
91
91
  5. Tact generated files are located in `build/<CONTRACT>` directory
92
+ 6. Fift output is located in `build/<CONTRACT>/<CONTRACT>.fif`
92
93
 
93
94
  ### Running the test suites
94
95
 
package/dist/build.js CHANGED
@@ -46,6 +46,11 @@ async function buildOne(contract, ui) {
46
46
  ui?.write(JSON.stringify(res, null, 2));
47
47
  await promises_1.default.mkdir(paths_1.BUILD_DIR, { recursive: true });
48
48
  await promises_1.default.writeFile(buildArtifactPath, JSON.stringify(res));
49
+ if (result.lang === 'func' || result.lang === 'tolk') {
50
+ const fiftFilepath = path_1.default.join(paths_1.BUILD_DIR, contract, `${contract}.fif`);
51
+ await promises_1.default.mkdir(path_1.default.join(paths_1.BUILD_DIR, contract));
52
+ await promises_1.default.writeFile(fiftFilepath, result.fiftCode);
53
+ }
49
54
  ui?.write(`\n✅ Wrote compilation artifact to ${path_1.default.relative(process.cwd(), buildArtifactPath)}`);
50
55
  }
51
56
  catch (e) {
package/dist/cli/cli.js CHANGED
@@ -82,10 +82,14 @@ async function main() {
82
82
  ...effectiveRunners,
83
83
  ...runners,
84
84
  };
85
- const runner = effectiveRunners[args._[0]];
85
+ const command = args._[0];
86
+ const runner = effectiveRunners[command];
86
87
  if (!runner) {
87
- console.log(chalk_1.default.redBright(` Error: command not found.`) + ` Run 'blueprint help' to see available commands\n`);
88
+ console.log(chalk_1.default.redBright(`Error: command ${command} not found.`) + `\nRunning ${chalk_1.default.cyanBright('blueprint help')}...`);
89
+ const helpMessage = (0, help_1.buildHelpMessage)();
90
+ console.log(helpMessage);
88
91
  process.exit(1);
92
+ return;
89
93
  }
90
94
  const ui = new InquirerUIProvider_1.InquirerUIProvider();
91
95
  await runner(args, ui, runnerContext);
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.helpMessages = exports.helpArgs = exports.templateTypes = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
4
8
  exports.templateTypes = [
5
9
  {
6
10
  name: 'An empty contract (FunC)',
@@ -11,7 +15,7 @@ exports.templateTypes = [
11
15
  value: 'tolk-empty',
12
16
  },
13
17
  {
14
- name: 'An empty contract (TACT)',
18
+ name: 'An empty contract (Tact)',
15
19
  value: 'tact-empty',
16
20
  },
17
21
  {
@@ -23,75 +27,71 @@ exports.templateTypes = [
23
27
  value: 'tolk-counter',
24
28
  },
25
29
  {
26
- name: 'A simple counter contract (TACT)',
30
+ name: 'A simple counter contract (Tact)',
27
31
  value: 'tact-counter',
28
32
  },
29
33
  ];
30
34
  exports.helpArgs = { '--help': Boolean };
35
+ const availableCommands = ['create', 'run', 'build', 'set', 'help', 'test', 'verify', 'convert'];
31
36
  exports.helpMessages = {
32
- help: `Usage: blueprint help [command]
37
+ help: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('help')} [${chalk_1.default.yellow('command')}]
33
38
 
34
39
  Displays this message if no command is specified, or displays detailed help for the specified command.
35
40
 
36
- Blueprint is generally invoked as follows: blueprint [command] [command-args] [flags]
41
+ Blueprint is generally invoked as follows:
42
+ ${chalk_1.default.cyan('blueprint')} ${chalk_1.default.yellow('[command]')} ${chalk_1.default.gray('[command-args]')} ${chalk_1.default.gray('[flags]')}
37
43
 
38
- List of available commands:
39
- - create
40
- - run
41
- - build
42
- - set
43
- - help
44
- - test
45
- - verify
46
- - convert`,
47
- create: `Usage: blueprint create [contract name] [flags]
44
+ ${chalk_1.default.bold('List of available commands:')}
45
+ ${availableCommands.map(c => `- ${chalk_1.default.green(c)}`).join('\n')}`,
46
+ create: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('create')} ${chalk_1.default.yellow('[contract name]')} ${chalk_1.default.gray('[flags]')}
48
47
 
49
48
  Creates a new contract together with supporting files according to a template.
50
49
 
51
50
  Contract name must be specified in PascalCase and may only include characters a-z, A-Z, 0-9. If not specified on the command line, it will be asked interactively.
52
51
 
53
- Flags:
54
- --type <type> - specifies the template type to use when creating the contract. If not specified on the command line, it will be asked interactively.
55
- List of available types:
56
- ${exports.templateTypes.map((t) => `${t.value} - ${t.name}`).join('\n')}`,
57
- run: `Usage: blueprint run [script name] [flags]
52
+ ${chalk_1.default.bold('Flags:')}
53
+ ${chalk_1.default.cyan('--type')} <type> - specifies the template type to use when creating the contract. If not specified on the command line, it will be asked interactively.
54
+
55
+ ${chalk_1.default.bold('List of available types:')}
56
+ ${exports.templateTypes.map((t) => `${chalk_1.default.cyan(t.value)} - ${t.name}`).join('\n')}`,
57
+ run: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('run')} ${chalk_1.default.yellow('[script name]')} ${chalk_1.default.gray('[flags]')}
58
58
 
59
59
  Runs a script from the scripts directory.
60
60
 
61
61
  Script name is matched (ignoring case) to a file in the scripts directory. If not specified on the command line, the available scripts will be presented interactively.
62
62
 
63
- Flags:
64
- --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
65
- --custom [api-endpoint] - indicates that a custom API should be used when running the script, and the API URL optionally. (example: https://testnet.toncenter.com/api/v2/)
66
- --custom-version - specifies the API version to use with the custom API. Options: v2 (default), v4.
67
- --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
68
- --custom-type - specifies the network type to be indicated to scripts. Options: custom (default), mainnet, testnet.
69
- --tonconnect, --deeplink, --mnemonic - specifies the deployer to use when running the script. If not specified on the command line, it will be asked interactively.
70
- --tonscan, --tonviewer, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonviewer.`,
71
- build: `Usage: blueprint build [contract name] [flags]
72
-
73
- Builds the specified contract according to the respective .compile.ts file. If the contract is written in TACT, all TACT-generated files (wrapper class, etc) will be placed in the build/<contract name> folder.
74
-
75
- If contract name is not specified on the command line, the buildable contracts (that have the respective .compile.ts files under wrappers directory) will be presented interactively, unless --all flag is specified.
76
-
77
- Flags:
78
- --all - builds all buildable contracts instead of just one.`,
79
- set: `Usage: blueprint set <key> [value]
80
- Available keys:
81
- - func - overrides @ton-community/func-js-bin version, effectively setting the func version. The required version may be passed as the value, otherwise available versions will be displayed.`,
82
- test: `Usage: blueprint test [...args]
83
-
84
- Just runs \`npm test [...args]\`, which by default runs \`jest\`.`,
85
- verify: `Usage: blueprint verify [contract name] [flags]
86
-
87
- Builds a contract (similar to build command) and verifies it on https://verifier.ton.org. The contract must be already deployed on the network. If the contract's name is not specified on the command line, it will be asked interactively.
88
-
89
- Flags:
90
- --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
91
- --custom [api-endpoint] - indicates that a custom API should be used when running the script, and the API URL optionally. (example: https://testnet.toncenter.com/api/v2/) Requires --custom-type to be specified.
92
- --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), v4.
93
- --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
94
- --custom-type - specifies the network type to be indicated to scripts. Options: mainnet, testnet.`,
95
- convert: `Usage: blueprint convert [path to build script]
96
- Atempts to convert legacy bash build script to a blueprint compile wrapper.`,
63
+ ${chalk_1.default.bold('Flags:')}
64
+ ${chalk_1.default.cyan('--mainnet')}, ${chalk_1.default.cyan('--testnet')} - selects network
65
+ ${chalk_1.default.cyan('--custom')} [api-endpoint] - use a custom API
66
+ ${chalk_1.default.cyan('--custom-version')} - API version (v2, v4)
67
+ ${chalk_1.default.cyan('--custom-key')} - API key (v2 only)
68
+ ${chalk_1.default.cyan('--custom-type')} - network type (custom, mainnet, testnet)
69
+ ${chalk_1.default.cyan('--tonconnect')}, ${chalk_1.default.cyan('--deeplink')}, ${chalk_1.default.cyan('--mnemonic')} - deployer options
70
+ ${chalk_1.default.cyan('--tonscan')}, ${chalk_1.default.cyan('--tonviewer')}, ${chalk_1.default.cyan('--toncx')}, ${chalk_1.default.cyan('--dton')} - explorer (default: tonviewer)`,
71
+ build: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('build')} ${chalk_1.default.yellow('[contract name]')} ${chalk_1.default.gray('[flags]')}
72
+
73
+ Builds the specified contract according to the respective .compile.ts file. For Tact contracts, all generated files will be placed in the ${chalk_1.default.cyan('build/<contract name>')} folder.
74
+
75
+ ${chalk_1.default.bold('Flags:')}
76
+ ${chalk_1.default.cyan('--all')} - builds all available contracts.`,
77
+ set: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('set')} <${chalk_1.default.yellow('key')}> [${chalk_1.default.yellow('value')}]
78
+
79
+ ${chalk_1.default.bold('Available keys:')}
80
+ - ${chalk_1.default.cyan('func')} - overrides @ton-community/func-js-bin version.`,
81
+ test: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('test')} [...args]
82
+
83
+ Runs ${chalk_1.default.green('npm test [...args]')}, which by default executes ${chalk_1.default.green('jest')}.`,
84
+ verify: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('verify')} ${chalk_1.default.yellow('[contract name]')} ${chalk_1.default.gray('[flags]')}
85
+
86
+ Verifies a deployed contract on ${chalk_1.default.underline('https://verifier.ton.org')}.
87
+
88
+ ${chalk_1.default.bold('Flags:')}
89
+ ${chalk_1.default.cyan('--mainnet')}, ${chalk_1.default.cyan('--testnet')} - selects network
90
+ ${chalk_1.default.cyan('--custom')} [api-endpoint] - use custom API (requires --custom-type)
91
+ ${chalk_1.default.cyan('--custom-version')} - API version (v2 default)
92
+ ${chalk_1.default.cyan('--custom-key')} - API key (v2 only)
93
+ ${chalk_1.default.cyan('--custom-type')} - network type (mainnet, testnet)`,
94
+ convert: `${chalk_1.default.bold('Usage:')} blueprint ${chalk_1.default.cyan('convert')} ${chalk_1.default.yellow('[path to build script]')}
95
+
96
+ Attempts to convert a legacy bash build script to a Blueprint compile wrapper.`,
97
97
  };
@@ -1,3 +1,4 @@
1
1
  import { Runner } from './Runner';
2
2
  export declare let additionalHelpMessages: Record<string, string>;
3
+ export declare function buildHelpMessage(cmd?: string): string;
3
4
  export declare const help: Runner;
package/dist/cli/help.js CHANGED
@@ -1,10 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.help = exports.additionalHelpMessages = void 0;
3
+ exports.help = exports.buildHelpMessage = exports.additionalHelpMessages = void 0;
4
4
  const constants_1 = require("./constants");
5
5
  exports.additionalHelpMessages = {};
6
- const help = async (args, ui) => {
7
- const cmd = args._.length >= 2 ? args._[1].toLowerCase() : '';
6
+ function buildHelpMessage(cmd = '') {
8
7
  const effectiveHelpMessages = {
9
8
  ...exports.additionalHelpMessages,
10
9
  ...constants_1.helpMessages,
@@ -12,7 +11,12 @@ const help = async (args, ui) => {
12
11
  for (const k in exports.additionalHelpMessages) {
13
12
  effectiveHelpMessages.help += '\n- ' + k;
14
13
  }
15
- const helpMessage = cmd in effectiveHelpMessages ? effectiveHelpMessages[cmd] : effectiveHelpMessages['help'];
14
+ return cmd in effectiveHelpMessages ? effectiveHelpMessages[cmd] : effectiveHelpMessages['help'];
15
+ }
16
+ exports.buildHelpMessage = buildHelpMessage;
17
+ const help = async (args, ui) => {
18
+ const cmd = args._.length >= 2 ? args._[1].toLowerCase() : '';
19
+ const helpMessage = buildHelpMessage(cmd);
16
20
  ui.write(helpMessage);
17
21
  };
18
22
  exports.help = help;
@@ -1,17 +1,42 @@
1
1
  import { SourceResolver, SourcesMap, SourcesArray } from '@ton-community/func-js';
2
2
  import { Cell } from '@ton/core';
3
- import { ConfigProject } from '@tact-lang/compiler';
3
+ import { Options } from '@tact-lang/compiler';
4
4
  export type HookParams = {
5
5
  userData?: any;
6
6
  };
7
7
  export type CommonCompilerConfig = {
8
+ /**
9
+ * A hook that runs **before** the contract is compiled.
10
+ *
11
+ * @param {HookParams} params - Hook parameters including user-defined data.
12
+ *
13
+ * @example
14
+ * const config: CompilerConfig = {
15
+ * preCompileHook: async (params) => {
16
+ * console.log("Preparing to compile, user params:", params);
17
+ * }
18
+ * };
19
+ */
8
20
  preCompileHook?: (params: HookParams) => Promise<void>;
21
+ /**
22
+ * A hook that runs **after** the contract is compiled.
23
+ *
24
+ * @param {Cell} code - The compiled contract code as a TON `Cell`.
25
+ * @param {HookParams} params - Hook parameters including user-defined data.
26
+ *
27
+ * @example
28
+ * const config: CompilerConfig = {
29
+ * postCompileHook: async (code) => {
30
+ * console.log("Compiled BOC size:", code.toBoc().length);
31
+ * }
32
+ * };
33
+ */
9
34
  postCompileHook?: (code: Cell, params: HookParams) => Promise<void>;
10
35
  };
11
36
  export type TactCompilerConfig = {
12
37
  lang: 'tact';
13
38
  target: string;
14
- options?: ConfigProject['options'];
39
+ options?: Options;
15
40
  };
16
41
  export type FuncCompilerConfig = {
17
42
  lang?: 'func';
@@ -10,12 +10,14 @@ export type SourceSnapshot = {
10
10
  export type TolkCompileResult = {
11
11
  lang: 'tolk';
12
12
  stderr: string;
13
+ fiftCode: string;
13
14
  code: Cell;
14
15
  snapshot: SourceSnapshot[];
15
16
  version: string;
16
17
  };
17
18
  export type FuncCompileResult = {
18
19
  lang: 'func';
20
+ fiftCode: string;
19
21
  code: Cell;
20
22
  targets: string[];
21
23
  snapshot: SourceSnapshot[];
@@ -29,7 +31,36 @@ export type TactCompileResult = {
29
31
  };
30
32
  export type CompileResult = TactCompileResult | FuncCompileResult | TolkCompileResult;
31
33
  export declare function doCompile(name: string, opts?: CompileOpts): Promise<CompileResult>;
34
+ /**
35
+ * Optional compilation settings, including user data passed to hooks
36
+ */
32
37
  export type CompileOpts = {
38
+ /**
39
+ * Any user-defined data that will be passed to both `preCompileHook` and `postCompileHook`.
40
+ */
33
41
  hookUserData?: any;
34
42
  };
43
+ /**
44
+ * Compiles a contract using the specified configuration for `tact`, `func`, or `tolk` languages.
45
+ *
46
+ * This function resolves the appropriate compiler configuration for a given contract name,
47
+ * runs any defined pre-compile and post-compile hooks, and returns the resulting compiled code
48
+ * as a [Cell]{@link Cell}.
49
+ *
50
+ * @param {string} name - The name of the contract to compile. This should correspond to a
51
+ * file named `<name>.compile.ts` in the `compilables` or `wrappers` directory.
52
+ * @param {CompileOpts} [opts] - Optional compilation options, including user data passed to hooks.
53
+ *
54
+ * @returns {Promise<Cell>} A promise that resolves to the compiled contract code as a `Cell`.
55
+ *
56
+ * @example
57
+ * import { compile } from '@ton/blueprint';
58
+ *
59
+ * async function main() {
60
+ * const codeCell = await compile('Contract');
61
+ * console.log('Compiled code BOC:', codeCell.toBoc().toString('base64'));
62
+ * }
63
+ *
64
+ * main();
65
+ */
35
66
  export declare function compile(name: string, opts?: CompileOpts): Promise<Cell>;
@@ -62,6 +62,7 @@ async function doCompileTolk(config) {
62
62
  return {
63
63
  lang: 'tolk',
64
64
  stderr: res.stderr,
65
+ fiftCode: res.fiftCode,
65
66
  code: core_1.Cell.fromBase64(res.codeBoc64),
66
67
  snapshot: res.sourcesSnapshot.map((e) => ({
67
68
  filename: e.filename,
@@ -83,6 +84,7 @@ async function doCompileFunc(config) {
83
84
  }
84
85
  return {
85
86
  lang: 'func',
87
+ fiftCode: cr.fiftCode,
86
88
  code: core_1.Cell.fromBase64(cr.codeBoc),
87
89
  targets,
88
90
  snapshot: cr.snapshot,
@@ -124,11 +126,11 @@ async function doCompileTact(config, name) {
124
126
  output: path_1.default.join(paths_1.BUILD_DIR, name),
125
127
  options: { ...rootConfigOptions, ...config.options },
126
128
  },
127
- stdlib: '/stdlib',
129
+ stdlib: Tact.createVirtualFileSystem("@stdlib", Tact.stdLibFiles),
128
130
  project: fs,
129
131
  };
130
132
  const res = await Tact.build(buildConfig);
131
- if (!res) {
133
+ if (!res.ok) {
132
134
  throw new Error('Could not compile tact');
133
135
  }
134
136
  const code = findTactBoc(fs.overwrites);
@@ -174,6 +176,29 @@ async function doCompile(name, opts) {
174
176
  return res;
175
177
  }
176
178
  exports.doCompile = doCompile;
179
+ /**
180
+ * Compiles a contract using the specified configuration for `tact`, `func`, or `tolk` languages.
181
+ *
182
+ * This function resolves the appropriate compiler configuration for a given contract name,
183
+ * runs any defined pre-compile and post-compile hooks, and returns the resulting compiled code
184
+ * as a [Cell]{@link Cell}.
185
+ *
186
+ * @param {string} name - The name of the contract to compile. This should correspond to a
187
+ * file named `<name>.compile.ts` in the `compilables` or `wrappers` directory.
188
+ * @param {CompileOpts} [opts] - Optional compilation options, including user data passed to hooks.
189
+ *
190
+ * @returns {Promise<Cell>} A promise that resolves to the compiled contract code as a `Cell`.
191
+ *
192
+ * @example
193
+ * import { compile } from '@ton/blueprint';
194
+ *
195
+ * async function main() {
196
+ * const codeCell = await compile('Contract');
197
+ * console.log('Compiled code BOC:', codeCell.toBoc().toString('base64'));
198
+ * }
199
+ *
200
+ * main();
201
+ */
177
202
  async function compile(name, opts) {
178
203
  const result = await doCompile(name, opts);
179
204
  return result.code;
@@ -1,7 +1,40 @@
1
1
  import { CustomNetwork } from './CustomNetwork';
2
2
  import { Plugin } from './Plugin';
3
3
  export interface Config {
4
+ /**
5
+ * Optional array of plugins to extend or customize the behavior.
6
+ * Plugins can provide additional tooling.
7
+ *
8
+ * @example
9
+ * import { Config } from '@ton/blueprint';
10
+ * import { ScaffoldPlugin } from 'blueprint-scaffold';
11
+ *
12
+ * export const config: Config = {
13
+ * plugins: [new ScaffoldPlugin()],
14
+ * };
15
+ */
4
16
  plugins?: Plugin[];
17
+ /**
18
+ * Specifies the target network for deployment or interaction.
19
+ *
20
+ * @example Custom network
21
+ * import { Config } from '@ton/blueprint';
22
+ *
23
+ * export const config: Config = {
24
+ * network: {
25
+ * endpoint: 'https://toncenter.com/api/v2/jsonRPC',
26
+ * type: 'mainnet',
27
+ * version: 'v2',
28
+ * key: 'YOUR_API_KEY',
29
+ * },
30
+ * };
31
+ */
5
32
  network?: 'mainnet' | 'testnet' | CustomNetwork;
33
+ /**
34
+ * If true, keeps compilable files (`*.compile.ts`) in a separate directory `compilables`.
35
+ * When false or unset, compilables are stored in `wrappers` directory.
36
+ *
37
+ * @default false
38
+ */
6
39
  separateCompilables?: boolean;
7
40
  }
@@ -3,15 +3,71 @@ import { Address, Cell, Contract, ContractProvider, OpenedContract, Sender } fro
3
3
  import { ContractAdapter } from '@ton-api/ton-adapter';
4
4
  import { UIProvider } from '../ui/UIProvider';
5
5
  export type BlueprintTonClient = TonClient4 | TonClient | ContractAdapter;
6
+ /**
7
+ * Interface representing a network provider for interacting with TON blockchain.
8
+ */
6
9
  export interface NetworkProvider {
10
+ /**
11
+ * Returns the current network type.
12
+ * @returns {'mainnet' | 'testnet' | 'custom'} The type of network.
13
+ */
7
14
  network(): 'mainnet' | 'testnet' | 'custom';
15
+ /**
16
+ * Returns the sender used for transactions.
17
+ * @example
18
+ * export async function run(provider: NetworkProvider) {
19
+ * await provider.sender().send({
20
+ * to: randomAddress(),
21
+ * value: toNano('0.5'),
22
+ * })
23
+ * }
24
+ *
25
+ * @returns {Sender} The sender instance.
26
+ */
8
27
  sender(): Sender;
28
+ /**
29
+ * Returns the underlying TON client API. May be [TonClient4]{@link TonClient4}, [TonClient]{@link TonClient} or [ContractAdapter]{@link ContractAdapter} (TON API)
30
+ * @returns {BlueprintTonClient} The client API used to interact with the network.
31
+ */
9
32
  api(): BlueprintTonClient;
33
+ /**
34
+ * Returns a contract provider instance for a given address and optional init parameters.
35
+ * @param {Address} address - The address of the contract.
36
+ * @param {{ code?: Cell; data?: Cell }} [init] - Optional contact [StateInit]{@link StateInit}.
37
+ * @returns {ContractProvider} The contract provider - class to interact with contract
38
+ * @example
39
+ */
10
40
  provider(address: Address, init?: {
11
41
  code?: Cell;
12
42
  data?: Cell;
13
43
  }): ContractProvider;
44
+ /**
45
+ * Checks whether a contract is deployed.
46
+ * @param {Address} address - The address to check for deployment.
47
+ * @example
48
+ * export async function run(provider: NetworkProvider) {
49
+ * const address = Address.parse('some address');
50
+ * const isDeployed = await provider.isContractDeployed(address);
51
+ * if (isDeployed) {
52
+ * console.log('Contract deployed');
53
+ * } else {
54
+ * console.log('Contract not deployed');
55
+ * }
56
+ * }
57
+ * @returns {Promise<boolean>} A promise that resolves to true if the contract is deployed, otherwise false.
58
+ */
14
59
  isContractDeployed(address: Address): Promise<boolean>;
60
+ /**
61
+ * Waits for a contract to be deployed by polling the address.
62
+ * @param {Address} address - The address to wait for deployment.
63
+ * @param {number} [attempts=20] - Maximum number of attempts to check for deployment.
64
+ * @param {number} [sleepDuration=2000] - Duration to wait between attempts, in milliseconds.
65
+ * @example
66
+ * await contract.sendDeploy(provider.sender(), toNano('0.05'));
67
+ * await provider.waitForDeploy(tolkTest.address);
68
+ * // run methods on `contract`
69
+ * @returns {Promise<void>} A promise that resolves when the contract is deployed or the attempts are exhausted.
70
+ */
15
71
  waitForDeploy(address: Address, attempts?: number, sleepDuration?: number): Promise<void>;
16
72
  /**
17
73
  * @deprecated
@@ -19,6 +75,22 @@ export interface NetworkProvider {
19
75
  * Use your Contract's `sendDeploy` method (or similar) together with `waitForDeploy` instead.
20
76
  */
21
77
  deploy(contract: Contract, value: bigint, body?: Cell, waitAttempts?: number): Promise<void>;
78
+ /**
79
+ * Opens a contract instance for interaction.
80
+ * @param {T} contract - The contract instance to open.
81
+ * @example
82
+ * const address = Address.parse('some address');
83
+ * const contract = provider.open(Contract.createFromAddress(address));
84
+ * await contract.send(provider.sender(), ...)
85
+ * @returns {OpenedContract<T>} An opened contract wrapper for interaction.
86
+ */
22
87
  open<T extends Contract>(contract: T): OpenedContract<T>;
88
+ /**
89
+ * Returns the UI provider used for writing data to graphical source (console).
90
+ * @returns {UIProvider} The UI provider instance.
91
+ * @example
92
+ * const ui = provider.ui();
93
+ * ui.write('Hello World!');
94
+ */
23
95
  ui(): UIProvider;
24
96
  }
@@ -1,25 +1,30 @@
1
1
  {{snakeName}}.tact
2
- import "@stdlib/deploy";
3
-
4
2
  message Add {
5
- queryId: Int as uint64;
6
3
  amount: Int as uint32;
7
4
  }
8
5
 
9
- contract {{name}} with Deployable {
10
- id: Int as uint32;
11
- counter: Int as uint32;
12
-
13
- init(id: Int) {
14
- self.id = id;
15
- self.counter = 0;
6
+ contract {{name}}(
7
+ // Persistent state variables declared via the
8
+ // contract parameters syntax, which was introduced in v1.6.0
9
+ //
10
+ // See: https://docs.tact-lang.org/book/contracts/#parameters
11
+ id: Int as uint32,
12
+ counter: Int as uint32,
13
+ ) {
14
+ // Empty receiver for the deployment,
15
+ // which expects the `null` message body
16
+ receive() {
17
+ // Forward the remaining value in the
18
+ // incoming message back to the sender
19
+ cashback(sender());
16
20
  }
17
21
 
18
22
  receive(msg: Add) {
19
23
  self.counter += msg.amount;
20
24
 
21
- // Notify the caller that the receiver was executed and forward remaining value back
22
- self.notify("Cashback".asComment());
25
+ // Forward the remaining value in the
26
+ // incoming message back to the sender
27
+ cashback(sender());
23
28
  }
24
29
 
25
30
  get fun counter(): Int {
@@ -4,17 +4,14 @@ import { {{name}} } from '../wrappers/{{name}}';
4
4
  import { NetworkProvider } from '@ton/blueprint';
5
5
 
6
6
  export async function run(provider: NetworkProvider) {
7
- const {{loweredName}} = provider.open(await {{name}}.fromInit(BigInt(Math.floor(Math.random() * 10000))));
7
+ const {{loweredName}} = provider.open(await {{name}}.fromInit(BigInt(Math.floor(Math.random() * 10000))), 0n);
8
8
 
9
9
  await {{loweredName}}.send(
10
10
  provider.sender(),
11
11
  {
12
12
  value: toNano('0.05'),
13
13
  },
14
- {
15
- $$type: 'Deploy',
16
- queryId: 0n,
17
- }
14
+ null,
18
15
  );
19
16
 
20
17
  await provider.waitForDeploy({{loweredName}}.address);
@@ -24,7 +24,6 @@ export async function run(provider: NetworkProvider, args: string[]) {
24
24
  },
25
25
  {
26
26
  $$type: 'Add',
27
- queryId: 0n,
28
27
  amount: 1n,
29
28
  }
30
29
  );
@@ -12,7 +12,7 @@ describe('{{name}}', () => {
12
12
  beforeEach(async () => {
13
13
  blockchain = await Blockchain.create();
14
14
 
15
- {{loweredName}} = blockchain.openContract(await {{name}}.fromInit(0n));
15
+ {{loweredName}} = blockchain.openContract(await {{name}}.fromInit(0n, 0n));
16
16
 
17
17
  deployer = await blockchain.treasury('deployer');
18
18
 
@@ -21,10 +21,7 @@ describe('{{name}}', () => {
21
21
  {
22
22
  value: toNano('0.05'),
23
23
  },
24
- {
25
- $$type: 'Deploy',
26
- queryId: 0n,
27
- }
24
+ null,
28
25
  );
29
26
 
30
27
  expect(deployResult.transactions).toHaveTransaction({
@@ -62,7 +59,6 @@ describe('{{name}}', () => {
62
59
  },
63
60
  {
64
61
  $$type: 'Add',
65
- queryId: 0n,
66
62
  amount: increaseBy,
67
63
  }
68
64
  );
@@ -1,9 +1,19 @@
1
1
  {{snakeName}}.tact
2
- import "@stdlib/deploy";
3
-
4
- contract {{name}} with Deployable {
5
- // Empty init() function is present by default in all Tact contracts
6
- // since v1.3.0, so the following may be omitted:
7
- //
8
- // init() {}
2
+ // Since v1.6.0, Tact has a contract parameters syntax that can supersede
3
+ // lazy initialization by init() for all contracts that do not require specific on-chain
4
+ // deployment logic that must be run only once in the `init()` function.
5
+ //
6
+ // Note that the empty parameter list above is still a parameter list,
7
+ // meaning that the contract won't have an implicit or explicit `init(){:tact}` function
8
+ // and will enjoy storage write optimizations and use less gas overall.
9
+ //
10
+ // See: https://docs.tact-lang.org/book/contracts/#parameters
11
+ contract {{name}}() {
12
+ // Empty receiver for the deployment,
13
+ // which expects the `null` message body
14
+ receive() {
15
+ // Forward the remaining value in the
16
+ // incoming message back to the sender
17
+ cashback(sender());
18
+ }
9
19
  }
@@ -11,10 +11,7 @@ export async function run(provider: NetworkProvider) {
11
11
  {
12
12
  value: toNano('0.05'),
13
13
  },
14
- {
15
- $$type: 'Deploy',
16
- queryId: 0n,
17
- }
14
+ null,
18
15
  );
19
16
 
20
17
  await provider.waitForDeploy({{loweredName}}.address);
@@ -21,10 +21,7 @@ describe('{{name}}', () => {
21
21
  {
22
22
  value: toNano('0.05'),
23
23
  },
24
- {
25
- $$type: 'Deploy',
26
- queryId: 0n,
27
- }
24
+ null,
28
25
  );
29
26
 
30
27
  expect(deployResult.transactions).toHaveTransaction({
@@ -1,10 +1,68 @@
1
1
  import { Address } from '@ton/core';
2
+ /**
3
+ * Interface for handling user interactions, such as displaying messages,
4
+ * prompting for input, and managing action prompts.
5
+ */
2
6
  export interface UIProvider {
7
+ /**
8
+ * Writes a message to the user interface (e.g., console or UI panel).
9
+ * @param {string} message - The message to display.
10
+ * @example
11
+ * const ui: UIProvider = ...
12
+ * ui.write("Transaction sent successfully.");
13
+ */
3
14
  write(message: string): void;
15
+ /**
16
+ * Prompts the user with a yes/no confirmation.
17
+ * @param {string} message - The message to display in the prompt.
18
+ * @returns {Promise<boolean>} A promise that resolves to true if the user confirms, otherwise false.
19
+ * @example
20
+ * const ui: UIProvider = ...
21
+ * const confirmed = await ui.prompt("Do you want to proceed?");
22
+ */
4
23
  prompt(message: string): Promise<boolean>;
24
+ /**
25
+ * Prompts the user to input a TON address.
26
+ * @param {string} message - The prompt message.
27
+ * @param {Address} [fallback] - A default address to use if the user provides no input.
28
+ * @returns {Promise<Address>} A promise that resolves to the input address.
29
+ * @example
30
+ * const ui: UIProvider = ...
31
+ * const address = await ui.inputAddress("Enter destination address:", myWalletAddress);
32
+ */
5
33
  inputAddress(message: string, fallback?: Address): Promise<Address>;
34
+ /**
35
+ * Prompts the user to input a string value.
36
+ * @param {string} message - The message to display in the prompt.
37
+ * @returns {Promise<string>} A promise that resolves to the user's input.
38
+ * @example
39
+ * const ui: UIProvider = ...
40
+ * const nickname = await ui.input("Enter your nickname:");
41
+ */
6
42
  input(message: string): Promise<string>;
43
+ /**
44
+ * Prompts the user to choose from a list of options.
45
+ * @param {string} message - The prompt message.
46
+ * @param {T[]} choices - An array of choices to select from.
47
+ * @param {(v: T) => string} display - A function that returns a string to display for each choice.
48
+ * @returns {Promise<T>} A promise that resolves to the selected item.
49
+ * @example
50
+ * const ui: UIProvider = ...
51
+ * const network = await ui.choose("Select a network:", ["mainnet", "testnet"], n => n.toUpperCase());
52
+ */
7
53
  choose<T>(message: string, choices: T[], display: (v: T) => string): Promise<T>;
54
+ /**
55
+ * Sets a persistent action prompt (e.g., status indicator) in the UI. New call of `setActionPrompt` will replace
56
+ * the previous action prompt.
57
+ * @param {string} message - The action message to display.
58
+ * @example
59
+ * ui.setActionPrompt("Awaiting transaction confirmation...");
60
+ */
8
61
  setActionPrompt(message: string): void;
62
+ /**
63
+ * Clears the current action prompt from the UI.
64
+ * @example
65
+ * ui.clearActionPrompt();
66
+ */
9
67
  clearActionPrompt(): void;
10
68
  }
@@ -1,3 +1,31 @@
1
1
  import { Address, Cell } from '@ton/core';
2
+ /**
3
+ * Generates a TON deep link for transfer.
4
+ *
5
+ * @param {Address} address - The recipient's TON address.
6
+ * @param {bigint} amount - The amount of nanoTON to send.
7
+ * @param {Cell} [body] - Optional message body as a Cell.
8
+ * @param {Cell} [stateInit] - Optional state init cell for deploying a contract.
9
+ * @returns {string} A URL deep link that can be opened in TON wallets.
10
+ *
11
+ * @example
12
+ * const link = tonDeepLink(myAddress, 10_000_000n); // 0.01 TON
13
+ * // "ton://transfer/..."
14
+ */
2
15
  export declare const tonDeepLink: (address: Address, amount: bigint, body?: Cell, stateInit?: Cell) => string;
16
+ /**
17
+ * Generates a link to view a TON address in a selected blockchain explorer.
18
+ *
19
+ * Supports several TON explorers like TONSCan, Tonviewer, dton.io, etc., and
20
+ * dynamically adds the testnet prefix when needed.
21
+ *
22
+ * @param {string} address - The TON address to view in explorer.
23
+ * @param {string} network - The target network, either 'mainnet' or 'testnet'.
24
+ * @param {string} explorer - The desired explorer. Supported values: 'tonscan', 'tonviewer', 'toncx', 'dton'.
25
+ * @returns {string} A full URL pointing to the address in the selected explorer.
26
+ *
27
+ * @example
28
+ * const link = getExplorerLink("EQC...", "testnet", "tonscan");
29
+ * // "https://testnet.tonscan.org/address/EQC..."
30
+ */
3
31
  export declare function getExplorerLink(address: string, network: string, explorer: string): string;
@@ -1,11 +1,39 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getExplorerLink = exports.tonDeepLink = void 0;
4
+ /**
5
+ * Generates a TON deep link for transfer.
6
+ *
7
+ * @param {Address} address - The recipient's TON address.
8
+ * @param {bigint} amount - The amount of nanoTON to send.
9
+ * @param {Cell} [body] - Optional message body as a Cell.
10
+ * @param {Cell} [stateInit] - Optional state init cell for deploying a contract.
11
+ * @returns {string} A URL deep link that can be opened in TON wallets.
12
+ *
13
+ * @example
14
+ * const link = tonDeepLink(myAddress, 10_000_000n); // 0.01 TON
15
+ * // "ton://transfer/..."
16
+ */
4
17
  const tonDeepLink = (address, amount, body, stateInit) => `ton://transfer/${address.toString({
5
18
  urlSafe: true,
6
19
  bounceable: true,
7
20
  })}?amount=${amount.toString()}${body ? '&bin=' + body.toBoc().toString('base64url') : ''}${stateInit ? '&init=' + stateInit.toBoc().toString('base64url') : ''}`;
8
21
  exports.tonDeepLink = tonDeepLink;
22
+ /**
23
+ * Generates a link to view a TON address in a selected blockchain explorer.
24
+ *
25
+ * Supports several TON explorers like TONSCan, Tonviewer, dton.io, etc., and
26
+ * dynamically adds the testnet prefix when needed.
27
+ *
28
+ * @param {string} address - The TON address to view in explorer.
29
+ * @param {string} network - The target network, either 'mainnet' or 'testnet'.
30
+ * @param {string} explorer - The desired explorer. Supported values: 'tonscan', 'tonviewer', 'toncx', 'dton'.
31
+ * @returns {string} A full URL pointing to the address in the selected explorer.
32
+ *
33
+ * @example
34
+ * const link = getExplorerLink("EQC...", "testnet", "tonscan");
35
+ * // "https://testnet.tonscan.org/address/EQC..."
36
+ */
9
37
  function getExplorerLink(address, network, explorer) {
10
38
  const networkPrefix = network === 'testnet' ? 'testnet.' : '';
11
39
  switch (explorer) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ton/blueprint",
3
- "version": "0.29.0",
3
+ "version": "0.31.0",
4
4
  "description": "Framework for development of TON smart contracts",
5
5
  "main": "dist/index.js",
6
6
  "bin": "./dist/cli/cli.js",
@@ -19,7 +19,7 @@
19
19
  "format": "prettier --write src"
20
20
  },
21
21
  "devDependencies": {
22
- "@tact-lang/compiler": "^1.5.3",
22
+ "@tact-lang/compiler": "^1.6.5",
23
23
  "@ton-community/func-js": "^0.9.0",
24
24
  "@ton/core": "^0.59.0",
25
25
  "@ton/crypto": "^3.3.0",
@@ -32,7 +32,7 @@
32
32
  "typescript": "^4.9.5"
33
33
  },
34
34
  "peerDependencies": {
35
- "@tact-lang/compiler": ">=1.5.3",
35
+ "@tact-lang/compiler": ">=1.6.5",
36
36
  "@ton-community/func-js": ">=0.9.0",
37
37
  "@ton/core": ">=0.59.0",
38
38
  "@ton/crypto": ">=3.3.0",