@ton/blueprint 0.21.0 → 0.23.0-debugger.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +85 -36
  3. package/dist/cli/build.js +6 -0
  4. package/dist/cli/cli.js +10 -19
  5. package/dist/cli/constants.d.ts +17 -0
  6. package/dist/cli/constants.js +89 -0
  7. package/dist/cli/convert.js +6 -1
  8. package/dist/cli/create.js +10 -1
  9. package/dist/cli/help.js +2 -69
  10. package/dist/cli/run.js +6 -1
  11. package/dist/cli/set.js +7 -0
  12. package/dist/cli/test.js +13 -2
  13. package/dist/cli/verify.js +6 -1
  14. package/dist/compile/CompilerConfig.d.ts +1 -0
  15. package/dist/compile/compile.d.ts +5 -1
  16. package/dist/compile/compile.js +18 -2
  17. package/dist/config/Config.d.ts +1 -0
  18. package/dist/config/utils.d.ts +2 -0
  19. package/dist/config/utils.js +46 -0
  20. package/dist/index.d.ts +1 -1
  21. package/dist/index.js +2 -1
  22. package/dist/network/send/DeeplinkProvider.js +17 -6
  23. package/dist/paths.d.ts +3 -0
  24. package/dist/paths.js +4 -1
  25. package/dist/templates/func/not-separated-common/wrappers/compile.ts.template +7 -0
  26. package/dist/templates/tact/not-separated-common/wrappers/compile.ts.template +10 -0
  27. package/dist/templates/tact/not-separated-common/wrappers/wrapper.ts.template +2 -0
  28. package/dist/types/file.d.ts +4 -0
  29. package/dist/types/file.js +2 -0
  30. package/dist/utils/index.d.ts +4 -0
  31. package/dist/utils/index.js +20 -0
  32. package/dist/utils/object.utils.d.ts +3 -0
  33. package/dist/utils/object.utils.js +18 -0
  34. package/dist/utils/selection.utils.d.ts +24 -0
  35. package/dist/{utils.js → utils/selection.utils.js} +22 -51
  36. package/dist/utils/timer.utils.d.ts +1 -0
  37. package/dist/utils/timer.utils.js +9 -0
  38. package/dist/utils/ton.utils.d.ts +3 -0
  39. package/dist/utils/ton.utils.js +24 -0
  40. package/package.json +4 -4
  41. package/dist/utils.d.ts +0 -39
  42. /package/dist/templates/func/common/{wrappers → compilables}/compile.ts.template +0 -0
  43. /package/dist/templates/tact/common/{wrappers → compilables}/compile.ts.template +0 -0
package/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ 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.22.0] - 2024-07-08
9
+
10
+ ### Added
11
+
12
+ - Added support for scripts in subdirectories, for example `scripts/counter/deploy.ts`
13
+ - Added the ability to specify test files in `blueprint test` command, for example `blueprint test Counter`
14
+
15
+ ### Changed
16
+
17
+ - Separated compilables and wrappers
18
+
19
+ ### Fixed
20
+
21
+ - Fixed `code overflow` error when generating QR code for ton:// link
22
+
8
23
  ## [0.21.0] - 2024-05-27
9
24
 
10
25
  ### Changed
package/README.md CHANGED
@@ -4,106 +4,155 @@
4
4
 
5
5
  A development environment for TON blockchain for writing, testing, and deploying smart contracts.
6
6
 
7
- ### Quick start 🚀
8
-
9
- Run the following in terminal to create a new project and follow the on-screen instructions:
7
+ ## Table of Contents
8
+
9
+ * [Quick start](#quick-start-)
10
+ * [Overview](#overview)
11
+ * [Core features](#core-features)
12
+ * [Tech stack](#tech-stack)
13
+ * [Requirements](#requirements)
14
+ * [Features overview](#features-overview)
15
+ * [Project creation](#project-creation)
16
+ * [Directory structure](#directory-structure)
17
+ * [Building contracts](#building-contracts)
18
+ * [Running the test suites](#running-the-test-suites)
19
+ * [Deploying contracts](#deploying-contracts)
20
+ * [Custom scripts](#custom-scripts)
21
+ * [Contract development](#contract-development)
22
+ * [Creating contracts](#creating-contracts)
23
+ * [Writing contract code](#writing-contract-code)
24
+ * [Testing contracts](#testing-contracts)
25
+ * [Configuration](#configuration)
26
+ * [Plugins](#plugins)
27
+ * [Custom network](#custom-network)
28
+ * [Contributors](#contributors)
29
+ * [License](#license)
30
+ * [Donations](#donations)
31
+
32
+ ## Quick start 🚀
33
+
34
+ Run the command in terminal to create a new project and follow the on-screen instructions:
10
35
 
11
36
  ```console
12
37
  npm create ton@latest
13
38
  ```
14
39
 
15
-  
40
+ ## Overview
41
+
42
+ Blueprint is an all-in-one development environment designed to enhance the process of creating, testing, and deploying smart contracts on TON blockchain using [FunC](https://docs.ton.org/develop/func/overview) and [Tact](https://docs.tact-lang.org/) languages
16
43
 
17
- ### Core features 🔥
44
+ ### Core features
18
45
 
19
- * Create a development environment from template in one click - `npm create ton@latest`
46
+ * Create a development environment from template - `npm create ton@latest`
20
47
  * Streamlined workflow for building, testing and deploying smart contracts
21
48
  * Dead simple deployment to mainnet/testnet using your favorite wallet (eg. Tonkeeper)
22
49
  * Blazing fast testing of multiple smart contracts in an isolated blockchain running in-process
23
50
 
24
51
  ### Tech stack
25
52
 
26
- 1. Compiling FunC with https://github.com/ton-community/func-js (no CLI)
27
- 2. Testing smart contracts with https://github.com/ton-org/sandbox
28
- 3. Deploying smart contracts with [TON Connect 2](https://github.com/ton-connect), [Tonhub wallet](https://tonhub.com/) or a `ton://` deeplink
53
+ 1. Compiling FunC with https://github.com/ton-community/func-js
54
+ 2. Compiling Tact with https://github.com/tact-lang/tact
55
+ 3. Testing smart contracts with https://github.com/ton-org/sandbox
56
+ 4. Deploying smart contracts with [TON Connect 2](https://github.com/ton-connect), [Tonhub wallet](https://tonhub.com/) or a `ton://` deeplink
29
57
 
30
58
  ### Requirements
31
59
 
32
- * [Node.js](https://nodejs.org) with a recent version like v18, verify version with `node -v`
33
- * IDE with TypeScript and FunC support like [Visual Studio Code](https://code.visualstudio.com/) with the [FunC plugin](https://marketplace.visualstudio.com/items?itemName=tonwhales.func-vscode) or [IntelliJ IDEA](https://www.jetbrains.com/idea/) with the [TON Development plugin](https://plugins.jetbrains.com/plugin/23382-ton)
60
+ * [Node.js](https://nodejs.org) with a recent version like v18. Version can be verified with `node -v`
61
+ * IDE with TON support:
62
+ * [Visual Studio Code](https://code.visualstudio.com/) with the [FunC plugin](https://marketplace.visualstudio.com/items?itemName=tonwhales.func-vscode)
63
+ * [IntelliJ IDEA](https://www.jetbrains.com/idea/) with the [TON Development plugin](https://plugins.jetbrains.com/plugin/23382-ton)
34
64
 
35
-  
65
+ ## Features overview
36
66
 
37
- ## Create a new project
67
+ ### Project creation
38
68
 
39
- 1. Run and follow the on-screen instructions:   `npm create ton@latest`   or   `npx create-ton@latest`
40
- 2. (Optional) Then from the project directory:   `npm install`   or   `yarn install`
69
+ 1. Run and follow the on-screen instructions:   `npm create ton@latest`   or   `npx create-ton@latest`
70
+ 2. From the project directory run   `npm/yarn install`   to install dependencies
41
71
 
42
72
  ### Directory structure
43
73
 
44
- * `contracts/` - Source code in [FunC](https://ton.org/docs/develop/func/overview) for all smart contracts and their imports
74
+ * `contracts/` - Source code in [FunC](https://docs.ton.org/develop/func/overview) or [Tact](https://tact-lang.org/) for all smart contracts and their imports
45
75
  * `wrappers/` - TypeScript interface classes for all contracts (implementing `Contract` from [@ton/core](https://www.npmjs.com/package/@ton/core))
46
76
  * include message [de]serialization primitives, getter wrappers and compilation functions
47
77
  * used by the test suite and client code to interact with the contracts from TypeScript
78
+ * `compilables/` - Compilations scripts for contracts
48
79
  * `tests/` - TypeScript test suite for all contracts (relying on [Sandbox](https://github.com/ton-org/sandbox) for in-process tests)
49
80
  * `scripts/` - Deployment scripts to mainnet/testnet and other scripts interacting with live contracts
50
81
  * `build/` - Compilation artifacts created here after running a build command
51
82
 
52
- ### Build contracts
83
+ ### Building contracts
53
84
 
54
- 1. You need a compilation script in `wrappers/<CONTRACT>.compile.ts` - [example](/example/wrappers/Counter.compile.ts)
85
+ 1. You need a compilation script in `compilables/<CONTRACT>.compile.ts` - [example](/example/compilables/Counter.compile.ts)
55
86
  2. Run interactive: &nbsp;&nbsp; `npx blueprint build` &nbsp; or &nbsp; `yarn blueprint build`
56
87
  3. Non-interactive: &nbsp; `npx/yarn blueprint build <CONTRACT>` &nbsp; OR build all contracts &nbsp; `yarn blueprint build --all`
57
88
  * Example: `yarn blueprint build counter`
58
89
  4. Build results are generated in `build/<CONTRACT>.compiled.json`
90
+ 5. Tact generated files are located in `build/<CONTRACT>` directory
59
91
 
60
- ### Run the test suite
92
+ ### Running the test suites
61
93
 
62
94
  1. Run in terminal: &nbsp; `npx blueprint test` &nbsp; or &nbsp; `yarn blueprint test`
63
95
  2. Alternative method: &nbsp; `npm test` &nbsp; or &nbsp; `yarn test`
96
+ 3. You can specify test file to run: &nbsp; `npm/yarn test <CONTRACT>`
97
+ * Example: `yarn test counter`
64
98
 
65
99
  > Learn more about writing tests from the Sandbox's documentation - [here](https://github.com/ton-org/sandbox#writing-tests).
66
100
 
67
- ### Deploy one of the contracts
101
+ ### Deploying contracts
68
102
 
69
- 1. You need a deploy script in `scripts/deploy<CONTRACT>.ts` - [example](/example/scripts/deployCounter.ts)
103
+ 1. You need a deployment script in `scripts/deploy<CONTRACT>.ts` - [example](/example/scripts/deployCounter.ts)
70
104
  2. Run interactive: &nbsp;&nbsp; `npx blueprint run` &nbsp; or &nbsp; `yarn blueprint run`
71
- 3. Non-interactive: &nbsp; `npx/yarn blueprint run <CONTRACT> --<NETWORK> --<DEPLOY_METHOD>`
105
+ 3. Non-interactive: &nbsp; `npx/yarn blueprint run deploy<CONTRACT> --<NETWORK> --<DEPLOY_METHOD>`
72
106
  * Example: `yarn blueprint run deployCounter --mainnet --tonconnect`
73
107
 
108
+ ### Custom scripts
109
+
110
+ 1. Custom scripts should be located in `scripts` folder
111
+ 2. Script file must have exported function `run`
112
+ ```ts
113
+ export async function run(provider: NetworkProvider) {
114
+ //
115
+ }
116
+ ```
117
+ 3. Script can be run using `npx/yarn blueprint run <SCRIPT>` command
118
+
119
+ ### Updating FunC version
120
+
121
+ FunC version can be updated using `npx/yarn blueprint set func` command
122
+
74
123
  ### Help and additional commands
75
124
 
76
125
  Run in terminal: &nbsp; `npx blueprint help` &nbsp; or &nbsp; `yarn blueprint help`
77
126
 
78
- &nbsp;
127
+ ## Contract development
128
+
129
+ Before developing, make sure that your current working directory is located in the root of the project created using `npm create ton@latest`
79
130
 
80
- ## Develop a new contract
131
+ ### Creating contracts
81
132
 
82
- 1. Make sure you have a project to host the contract
83
- 2. Run interactive: &nbsp;&nbsp; `npx blueprint create` &nbsp; or &nbsp; `yarn blueprint create`
84
- 3. Non-interactive: &nbsp; `npx/yarn blueprint create <CONTRACT> --type <TYPE>` (type can be `func-empty`, `func-counter`, `tact-empty`, `tact-counter`)
133
+ 1. Run interactive: &nbsp;&nbsp; `npx blueprint create` &nbsp; or &nbsp; `yarn blueprint create`
134
+ 2. Non-interactive: &nbsp; `npx/yarn blueprint create <CONTRACT> --type <TYPE>` (type can be `func-empty`, `func-counter`, `tact-empty`, `tact-counter`)
85
135
  * Example: `yarn blueprint create MyNewContract --type func-empty`
86
136
 
87
- ### Contract code
137
+ ### Writing contract code
88
138
 
139
+ #### FunC
89
140
  1. Implement the standalone FunC root contract in `contracts/<CONTRACT>.fc`
90
141
  2. Implement shared FunC imports (if breaking code to multiple files) in `contracts/imports/*.fc`
91
142
  3. Implement wrapper TypeScript class in `wrappers/<CONTRACT>.ts` to encode messages and decode getters
92
143
 
93
- ### Test suite
144
+ #### Tact
145
+ 1. Implement tact contract in `contracts/<CONTRACT>.tact`
146
+ 2. Wrappers will be automatically generated in `build/<CONTRACT>/tact_<CONTRACT>.ts`
147
+
148
+ ### Testing contracts
94
149
 
95
150
  1. Implement TypeScript tests in `tests/<CONTRACT>.spec.ts`
96
151
  2. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to interact with the contract
97
152
 
98
153
  > Learn more about writing tests from the Sandbox's documentation - [here](https://github.com/ton-org/sandbox#writing-tests).
99
154
 
100
- ### Compilation and deployment
101
-
102
- 1. Implement a compilation script in `wrappers/<CONTRACT>.compile.ts`
103
- 2. Implement a deployment script in `scripts/deploy<CONTRACT>.ts`
104
- 3. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to initialize the contract
105
-
106
- ## Config
155
+ ## Configuration
107
156
 
108
157
  A config may be created in order to control some of blueprint's features. If a config is needed, create a `blueprint.config.ts` file in the root of your project with something like this:
109
158
  ```typescript
package/dist/cli/build.js CHANGED
@@ -7,6 +7,7 @@ exports.build = exports.selectCompile = void 0;
7
7
  const utils_1 = require("../utils");
8
8
  const arg_1 = __importDefault(require("arg"));
9
9
  const build_1 = require("../build");
10
+ const constants_1 = require("./constants");
10
11
  async function selectCompile(ui, args) {
11
12
  return await (0, utils_1.selectFile)(await (0, utils_1.findCompiles)(), {
12
13
  ui,
@@ -18,7 +19,12 @@ exports.selectCompile = selectCompile;
18
19
  const build = async (args, ui) => {
19
20
  const localArgs = (0, arg_1.default)({
20
21
  '--all': Boolean,
22
+ ...constants_1.helpArgs,
21
23
  });
24
+ if (localArgs['--help']) {
25
+ ui.write(constants_1.helpMessages['build']);
26
+ return;
27
+ }
22
28
  if (localArgs['--all']) {
23
29
  await (0, build_1.buildAll)();
24
30
  }
package/dist/cli/cli.js CHANGED
@@ -41,7 +41,7 @@ const convert_1 = require("./convert");
41
41
  const help_1 = require("./help");
42
42
  const InquirerUIProvider_1 = require("../ui/InquirerUIProvider");
43
43
  const Runner_1 = require("./Runner");
44
- const path_1 = __importDefault(require("path"));
44
+ const utils_1 = require("../config/utils");
45
45
  const runners = {
46
46
  create: create_1.create,
47
47
  run: run_1.run,
@@ -53,7 +53,6 @@ const runners = {
53
53
  convert: convert_1.convert,
54
54
  };
55
55
  async function main() {
56
- var _a;
57
56
  require('ts-node/register');
58
57
  const args = (0, arg_1.default)(Runner_1.argSpec, {
59
58
  permissive: true,
@@ -64,28 +63,20 @@ async function main() {
64
63
  }
65
64
  let effectiveRunners = {};
66
65
  const runnerContext = {};
66
+ const config = await (0, utils_1.getConfig)();
67
67
  try {
68
- const configModule = await (_a = path_1.default.join(process.cwd(), 'blueprint.config.ts'), Promise.resolve().then(() => __importStar(require(_a))));
69
- try {
70
- if ('config' in configModule && typeof configModule.config === 'object') {
71
- const config = configModule.config;
72
- runnerContext.config = config;
73
- for (const plugin of config.plugins ?? []) {
74
- for (const runner of plugin.runners()) {
75
- effectiveRunners[runner.name] = runner.runner;
76
- help_1.additionalHelpMessages[runner.name] = runner.help;
77
- }
78
- }
68
+ runnerContext.config = config;
69
+ for (const plugin of config?.plugins ?? []) {
70
+ for (const runner of plugin.runners()) {
71
+ effectiveRunners[runner.name] = runner.runner;
72
+ help_1.additionalHelpMessages[runner.name] = runner.help;
79
73
  }
80
74
  }
81
- catch (e) {
82
- // if plugin.runners() throws
83
- console.error('Could not load one or more plugins');
84
- console.error(e);
85
- }
86
75
  }
87
76
  catch (e) {
88
- // no config
77
+ // if plugin.runners() throws
78
+ console.error('Could not load one or more plugins');
79
+ console.error(e);
89
80
  }
90
81
  effectiveRunners = {
91
82
  ...effectiveRunners,
@@ -0,0 +1,17 @@
1
+ export declare const templateTypes: {
2
+ name: string;
3
+ value: string;
4
+ }[];
5
+ export declare const helpArgs: {
6
+ '--help': BooleanConstructor;
7
+ };
8
+ export declare const helpMessages: {
9
+ help: string;
10
+ create: string;
11
+ run: string;
12
+ build: string;
13
+ set: string;
14
+ test: string;
15
+ verify: string;
16
+ convert: string;
17
+ };
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.helpMessages = exports.helpArgs = exports.templateTypes = void 0;
4
+ exports.templateTypes = [
5
+ {
6
+ name: 'An empty contract (FunC)',
7
+ value: 'func-empty',
8
+ },
9
+ {
10
+ name: 'A simple counter contract (FunC)',
11
+ value: 'func-counter',
12
+ },
13
+ {
14
+ name: 'An empty contract (TACT)',
15
+ value: 'tact-empty',
16
+ },
17
+ {
18
+ name: 'A simple counter contract (TACT)',
19
+ value: 'tact-counter',
20
+ },
21
+ ];
22
+ exports.helpArgs = { '--help': Boolean };
23
+ exports.helpMessages = {
24
+ help: `Usage: blueprint help [command]
25
+
26
+ Displays this message if no command is specified, or displays detailed help for the specified command.
27
+
28
+ Blueprint is generally invoked as follows: blueprint [command] [command-args] [flags]
29
+
30
+ List of available commands:
31
+ - create
32
+ - run
33
+ - build
34
+ - set
35
+ - help
36
+ - test
37
+ - verify
38
+ - convert`,
39
+ create: `Usage: blueprint create [contract name] [flags]
40
+
41
+ Creates a new contract together with supporting files according to a template.
42
+
43
+ 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.
44
+
45
+ Flags:
46
+ --type <type> - specifies the template type to use when creating the contract. If not specified on the command line, it will be asked interactively.
47
+ List of available types:
48
+ ${exports.templateTypes.map((t) => `${t.value} - ${t.name}`).join('\n')}`,
49
+ run: `Usage: blueprint run [script name] [flags]
50
+
51
+ Runs a script from the scripts directory.
52
+
53
+ 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.
54
+
55
+ Flags:
56
+ --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
57
+ --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/)
58
+ --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), v4.
59
+ --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
60
+ --custom-type - specifies the network type to be indicated to scripts. Options: custom (default), mainnet, testnet.
61
+ --tonconnect, --tonhub, --deeplink, --mnemonic - specifies the deployer to use when running the script. If not specified on the command line, it will be asked interactively.
62
+ --tonscan, --tonviewer, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonscan.`,
63
+ build: `Usage: blueprint build [contract name] [flags]
64
+
65
+ 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.
66
+
67
+ 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.
68
+
69
+ Flags:
70
+ --all - builds all buildable contracts instead of just one.`,
71
+ set: `Usage: blueprint set <key> [value]
72
+ Available keys:
73
+ - 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.`,
74
+ test: `Usage: blueprint test [...args]
75
+
76
+ Just runs \`npm test [...args]\`, which by default runs \`jest\`.`,
77
+ verify: `Usage: blueprint verify [contract name] [flags]
78
+
79
+ 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.
80
+
81
+ Flags:
82
+ --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
83
+ --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.
84
+ --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), v4.
85
+ --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
86
+ --custom-type - specifies the network type to be indicated to scripts. Options: mainnet, testnet.`,
87
+ convert: `Usage: blueprint convert [path to build script]
88
+ Atempts to convert legacy bash build script to a blueprint compile wrapper.`,
89
+ };
@@ -10,6 +10,7 @@ const arg_1 = __importDefault(require("arg"));
10
10
  const createNetworkProvider_1 = require("../network/createNetworkProvider");
11
11
  const template_1 = require("../template");
12
12
  const paths_1 = require("../paths");
13
+ const constants_1 = require("./constants");
13
14
  function createWrapperName(old) {
14
15
  return old
15
16
  .split(/[-_]/)
@@ -80,7 +81,11 @@ function parseCompileString(str, src_dir, ui) {
80
81
  };
81
82
  }
82
83
  const convert = async (args, ui) => {
83
- const localArgs = (0, arg_1.default)(createNetworkProvider_1.argSpec);
84
+ const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
85
+ if (localArgs['--help']) {
86
+ ui.write(constants_1.helpMessages['convert']);
87
+ return;
88
+ }
84
89
  let filePath;
85
90
  if (localArgs._.length < 2) {
86
91
  filePath = await ui.input('Please specify path to convert from:');
@@ -10,6 +10,8 @@ const template_1 = require("../template");
10
10
  const utils_1 = require("../utils");
11
11
  const arg_1 = __importDefault(require("arg"));
12
12
  const build_1 = require("../build");
13
+ const utils_2 = require("../config/utils");
14
+ const constants_1 = require("./constants");
13
15
  function toSnakeCase(v) {
14
16
  const r = v.replace(/[A-Z]/g, (sub) => '_' + sub.toLowerCase());
15
17
  return r[0] === '_' ? r.substring(1) : r;
@@ -66,7 +68,12 @@ exports.templateTypes = [
66
68
  const create = async (args, ui) => {
67
69
  const localArgs = (0, arg_1.default)({
68
70
  '--type': String,
71
+ ...constants_1.helpArgs,
69
72
  });
73
+ if (localArgs['--help']) {
74
+ ui.write(constants_1.helpMessages['create']);
75
+ return;
76
+ }
70
77
  const name = localArgs._.length > 1 && localArgs._[1].trim().length > 0
71
78
  ? localArgs._[1].trim()
72
79
  : await ui.input('Contract name (PascalCase)');
@@ -87,7 +94,9 @@ const create = async (args, ui) => {
87
94
  snakeName,
88
95
  contractPath: 'contracts/' + snakeName + '.' + (lang === 'func' ? 'fc' : 'tact'),
89
96
  };
90
- await createFiles(path_1.default.join(template_1.TEMPLATES_DIR, lang, 'common'), process.cwd(), replaces);
97
+ const config = await (0, utils_2.getConfig)();
98
+ const commonPath = config?.separateCompilables ? 'common' : 'not-separated-common';
99
+ await createFiles(path_1.default.join(template_1.TEMPLATES_DIR, lang, commonPath), process.cwd(), replaces);
91
100
  await createFiles(path_1.default.join(template_1.TEMPLATES_DIR, lang, template), process.cwd(), replaces);
92
101
  if (lang === 'tact') {
93
102
  await (0, build_1.buildOne)(name, ui);
package/dist/cli/help.js CHANGED
@@ -1,80 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.help = exports.additionalHelpMessages = void 0;
4
- const create_1 = require("./create");
5
- const helpMessages = {
6
- help: `Usage: blueprint help [command]
7
-
8
- Displays this message if no command is specified, or displays detailed help for the specified command.
9
-
10
- Blueprint is generally invoked as follows: blueprint [command] [command-args] [flags]
11
-
12
- List of available commands:
13
- - create
14
- - run
15
- - build
16
- - custom
17
- - help
18
- - test
19
- - verify
20
- - convert`,
21
- create: `Usage: blueprint create [contract name] [flags]
22
-
23
- Creates a new contract together with supporting files according to a template.
24
-
25
- 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.
26
-
27
- Flags:
28
- --type <type> - specifies the template type to use when creating the contract. If not specified on the command line, it will be asked interactively.
29
- List of available types:
30
- ${create_1.templateTypes.map((t) => `${t.value} - ${t.name}`).join('\n')}`,
31
- run: `Usage: blueprint run [script name] [flags]
32
-
33
- Runs a script from the scripts directory.
34
-
35
- 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.
36
-
37
- Flags:
38
- --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
39
- --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/)
40
- --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), v4.
41
- --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
42
- --custom-type - specifies the network type to be indicated to scripts. Options: custom (default), mainnet, testnet.
43
- --tonconnect, --tonhub, --deeplink, --mnemonic - specifies the deployer to use when running the script. If not specified on the command line, it will be asked interactively.
44
- --tonscan, --tonviewer, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonscan.`,
45
- build: `Usage: blueprint build [contract name] [flags]
46
-
47
- 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.
48
-
49
- 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.
50
-
51
- Flags:
52
- --all - builds all buildable contracts instead of just one.`,
53
- set: `Usage: blueprint set <key> [value]
54
- Available keys:
55
- - 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.`,
56
- test: `Usage: blueprint test
57
-
58
- Just runs \`npm test\`, which by default runs \`jest\`.`,
59
- verify: `Usage: blueprint verify [contract name] [flags]
60
-
61
- 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.
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/) Requires --custom-type to be specified.
66
- --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), 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: mainnet, testnet.`,
69
- convert: `Usage: blueprint convert [path to build script]
70
- Atempts to convert legacy bash build script to a blueprint compile wrapper.`,
71
- };
4
+ const constants_1 = require("./constants");
72
5
  exports.additionalHelpMessages = {};
73
6
  const help = async (args, ui) => {
74
7
  const cmd = args._.length >= 2 ? args._[1].toLowerCase() : '';
75
8
  const effectiveHelpMessages = {
76
9
  ...exports.additionalHelpMessages,
77
- ...helpMessages,
10
+ ...constants_1.helpMessages,
78
11
  };
79
12
  for (const k in exports.additionalHelpMessages) {
80
13
  effectiveHelpMessages.help += '\n- ' + k;
package/dist/cli/run.js CHANGED
@@ -7,8 +7,13 @@ exports.run = void 0;
7
7
  const createNetworkProvider_1 = require("../network/createNetworkProvider");
8
8
  const utils_1 = require("../utils");
9
9
  const arg_1 = __importDefault(require("arg"));
10
+ const constants_1 = require("./constants");
10
11
  const run = async (args, ui, context) => {
11
- const localArgs = (0, arg_1.default)(createNetworkProvider_1.argSpec);
12
+ const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
13
+ if (localArgs['--help']) {
14
+ ui.write(constants_1.helpMessages['run']);
15
+ return;
16
+ }
12
17
  const { module: mod } = await (0, utils_1.selectFile)(await (0, utils_1.findScripts)(), {
13
18
  ui,
14
19
  hint: localArgs._.length > 1 && localArgs._[1].length > 0 ? localArgs._[1] : undefined,
package/dist/cli/set.js CHANGED
@@ -7,6 +7,8 @@ exports.set = void 0;
7
7
  const promises_1 = require("fs/promises");
8
8
  const node_child_process_1 = require("node:child_process");
9
9
  const path_1 = __importDefault(require("path"));
10
+ const arg_1 = __importDefault(require("arg"));
11
+ const constants_1 = require("./constants");
10
12
  const getVersions = (pkg, ui) => {
11
13
  return new Promise((resolve, reject) => {
12
14
  (0, node_child_process_1.exec)(`npm view ${pkg} versions --json`, (error, stdout, stderr) => {
@@ -58,6 +60,11 @@ const install = (cmd, ui) => {
58
60
  });
59
61
  };
60
62
  const set = async (args, ui) => {
63
+ const localArgs = (0, arg_1.default)(constants_1.helpArgs);
64
+ if (localArgs['--help']) {
65
+ ui.write(constants_1.helpMessages['set']);
66
+ return;
67
+ }
61
68
  if (args._.length < 2) {
62
69
  throw new Error('Please pass a key');
63
70
  }
package/dist/cli/test.js CHANGED
@@ -1,8 +1,19 @@
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.test = void 0;
4
7
  const child_process_1 = require("child_process");
5
- const test = async () => {
6
- (0, child_process_1.execSync)('npm test', { stdio: 'inherit' });
8
+ const arg_1 = __importDefault(require("arg"));
9
+ const constants_1 = require("./constants");
10
+ const test = async (args, ui) => {
11
+ const localArgs = (0, arg_1.default)(constants_1.helpArgs);
12
+ if (localArgs['--help']) {
13
+ ui.write(constants_1.helpMessages['test']);
14
+ return;
15
+ }
16
+ const testArgs = args._.slice(1); // first argument is `test`, need to get rid of it
17
+ (0, child_process_1.execSync)(`npm test ${testArgs.join(' ')}`, { stdio: 'inherit' });
7
18
  };
8
19
  exports.test = test;
@@ -11,6 +11,7 @@ const createNetworkProvider_1 = require("../network/createNetworkProvider");
11
11
  const build_1 = require("./build");
12
12
  const utils_1 = require("../utils");
13
13
  const arg_1 = __importDefault(require("arg"));
14
+ const constants_1 = require("./constants");
14
15
  const backends = {
15
16
  mainnet: {
16
17
  sourceRegistry: core_1.Address.parse('EQD-BJSVUJviud_Qv7Ymfd3qzXdrmV525e3YDzWQoHIAiInL'),
@@ -120,7 +121,11 @@ async function lookupCodeHash(hash, ui, retryCount = 5) {
120
121
  return foundAddr;
121
122
  }
122
123
  const verify = async (args, ui, context) => {
123
- const localArgs = (0, arg_1.default)(createNetworkProvider_1.argSpec);
124
+ const localArgs = (0, arg_1.default)({ ...createNetworkProvider_1.argSpec, ...constants_1.helpArgs });
125
+ if (localArgs['--help']) {
126
+ ui.write(constants_1.helpMessages['verify']);
127
+ return;
128
+ }
124
129
  const sel = await (0, build_1.selectCompile)(ui, localArgs);
125
130
  const networkProvider = await (0, createNetworkProvider_1.createNetworkProvider)(ui, localArgs, context.config, false);
126
131
  const sender = networkProvider.sender();
@@ -16,6 +16,7 @@ export type TactCompilerConfig = {
16
16
  export type FuncCompilerConfig = {
17
17
  lang?: 'func';
18
18
  optLevel?: number;
19
+ debugInfo?: boolean;
19
20
  } & ({
20
21
  targets: string[];
21
22
  sources?: SourceResolver | SourcesMap;
@@ -1,13 +1,16 @@
1
1
  /// <reference types="node" />
2
- import { SourcesArray } from '@ton-community/func-js';
2
+ import { SourcesArray, DebugInfoEntry } from '@ton-community/func-js';
3
3
  import { Cell } from '@ton/core';
4
4
  import { TactCompilerConfig } from './CompilerConfig';
5
+ export declare function getCompilablesDirectory(): Promise<string>;
6
+ export declare const COMPILE_END = ".compile.ts";
5
7
  export type FuncCompileResult = {
6
8
  lang: 'func';
7
9
  code: Cell;
8
10
  targets: string[];
9
11
  snapshot: SourcesArray;
10
12
  version: string;
13
+ debugInfo?: DebugInfoEntry[];
11
14
  };
12
15
  export type TactCompileResult = {
13
16
  lang: 'tact';
@@ -19,5 +22,6 @@ export type CompileResult = TactCompileResult | FuncCompileResult;
19
22
  export declare function doCompile(name: string, opts?: CompileOpts): Promise<CompileResult>;
20
23
  export type CompileOpts = {
21
24
  hookUserData?: any;
25
+ debugInfo?: boolean;
22
26
  };
23
27
  export declare function compile(name: string, opts?: CompileOpts): Promise<Cell>;
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.compile = exports.doCompile = void 0;
29
+ exports.compile = exports.doCompile = exports.COMPILE_END = exports.getCompilablesDirectory = void 0;
30
30
  const func_js_1 = require("@ton-community/func-js");
31
31
  const fs_1 = require("fs");
32
32
  const path_1 = __importDefault(require("path"));
@@ -34,9 +34,20 @@ const core_1 = require("@ton/core");
34
34
  const paths_1 = require("../paths");
35
35
  const Tact = __importStar(require("@tact-lang/compiler"));
36
36
  const OverwritableVirtualFileSystem_1 = require("./OverwritableVirtualFileSystem");
37
+ const utils_1 = require("../config/utils");
38
+ async function getCompilablesDirectory() {
39
+ const config = await (0, utils_1.getConfig)();
40
+ if (config?.separateCompilables) {
41
+ return paths_1.COMPILABLES_DIR;
42
+ }
43
+ return paths_1.WRAPPERS_DIR;
44
+ }
45
+ exports.getCompilablesDirectory = getCompilablesDirectory;
46
+ exports.COMPILE_END = '.compile.ts';
37
47
  async function getCompilerConfigForContract(name) {
38
48
  var _a;
39
- const mod = await (_a = path_1.default.join(paths_1.WRAPPERS_DIR, name + '.compile.ts'), Promise.resolve().then(() => __importStar(require(_a))));
49
+ const compilablesDirectory = await getCompilablesDirectory();
50
+ const mod = await (_a = path_1.default.join(compilablesDirectory, name + exports.COMPILE_END), Promise.resolve().then(() => __importStar(require(_a))));
40
51
  if (typeof mod.compile !== 'object') {
41
52
  throw new Error(`Object 'compile' is missing`);
42
53
  }
@@ -59,6 +70,7 @@ async function doCompileFunc(config) {
59
70
  targets,
60
71
  snapshot: cr.snapshot,
61
72
  version: (await (0, func_js_1.compilerVersion)()).funcVersion,
73
+ debugInfo: cr.debugInfo,
62
74
  };
63
75
  }
64
76
  function findTactBoc(fs) {
@@ -119,10 +131,14 @@ async function doCompileInner(name, config) {
119
131
  targets: config.targets,
120
132
  sources: config.sources ?? ((path) => (0, fs_1.readFileSync)(path).toString()),
121
133
  optLevel: config.optLevel,
134
+ debugInfo: config.debugInfo,
122
135
  });
123
136
  }
124
137
  async function doCompile(name, opts) {
125
138
  const config = await getCompilerConfigForContract(name);
139
+ if (opts?.debugInfo && config.lang === 'func') {
140
+ config.debugInfo = true;
141
+ }
126
142
  if (config.preCompileHook !== undefined) {
127
143
  await config.preCompileHook({
128
144
  userData: opts?.hookUserData,
@@ -3,4 +3,5 @@ import { Plugin } from './Plugin';
3
3
  export interface Config {
4
4
  plugins?: Plugin[];
5
5
  network?: 'mainnet' | 'testnet' | CustomNetwork;
6
+ separateCompilables?: boolean;
6
7
  }
@@ -0,0 +1,2 @@
1
+ import { Config } from './Config';
2
+ export declare function getConfig(): Promise<Config | undefined>;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var _a;
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.getConfig = void 0;
28
+ const paths_1 = require("../paths");
29
+ let config;
30
+ async function getConfig() {
31
+ if (config) {
32
+ return config;
33
+ }
34
+ try {
35
+ const configModule = await (_a = paths_1.BLUEPRINT_CONFIG, Promise.resolve().then(() => __importStar(require(_a))));
36
+ if (!('config' in configModule) || typeof configModule.config !== 'object') {
37
+ return undefined;
38
+ }
39
+ config = configModule.config;
40
+ return config;
41
+ }
42
+ catch {
43
+ return undefined;
44
+ }
45
+ }
46
+ exports.getConfig = getConfig;
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 } from './compile/compile';
4
+ export { compile, CompileOpts, CompileResult, FuncCompileResult, TactCompileResult, doCompile } 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';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildAll = exports.buildOne = exports.compile = exports.createNetworkProvider = exports.sleep = exports.tonDeepLink = void 0;
3
+ exports.buildAll = exports.buildOne = exports.doCompile = exports.compile = exports.createNetworkProvider = exports.sleep = exports.tonDeepLink = void 0;
4
4
  var utils_1 = require("./utils");
5
5
  Object.defineProperty(exports, "tonDeepLink", { enumerable: true, get: function () { return utils_1.tonDeepLink; } });
6
6
  Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
@@ -8,6 +8,7 @@ var createNetworkProvider_1 = require("./network/createNetworkProvider");
8
8
  Object.defineProperty(exports, "createNetworkProvider", { enumerable: true, get: function () { return createNetworkProvider_1.createNetworkProvider; } });
9
9
  var compile_1 = require("./compile/compile");
10
10
  Object.defineProperty(exports, "compile", { enumerable: true, get: function () { return compile_1.compile; } });
11
+ Object.defineProperty(exports, "doCompile", { enumerable: true, get: function () { return compile_1.doCompile; } });
11
12
  var build_1 = require("./build");
12
13
  Object.defineProperty(exports, "buildOne", { enumerable: true, get: function () { return build_1.buildOne; } });
13
14
  Object.defineProperty(exports, "buildAll", { enumerable: true, get: function () { return build_1.buildAll; } });
@@ -29,12 +29,23 @@ class DeeplinkProvider {
29
29
  }
30
30
  async sendTransaction(address, amount, payload, stateInit) {
31
31
  const deepLink = (0, utils_1.tonDeepLink)(address, amount, payload, stateInit ? (0, core_1.beginCell)().storeWritable((0, core_1.storeStateInit)(stateInit)).endCell() : undefined);
32
- __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\n');
33
- qrcode_terminal_1.default.generate(deepLink, { small: true }, (qr) => __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write(qr));
34
- __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\n');
35
- __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write(deepLink);
36
- __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\nScan the QR code above, or open the ton:// link to send this transaction');
37
- await __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").prompt('Press enter when transaction was issued');
32
+ try {
33
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\n');
34
+ qrcode_terminal_1.default.generate(deepLink, { small: true }, (qr) => __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write(qr));
35
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\n');
36
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write(deepLink);
37
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\nScan the QR code above, or open the ton:// link to send this transaction');
38
+ await __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").prompt('Press enter when transaction was issued');
39
+ }
40
+ catch (err) {
41
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write(deepLink);
42
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('\n');
43
+ if (err instanceof Error && err.message.includes('code length overflow')) {
44
+ __classPrivateFieldGet(this, _DeeplinkProvider_ui, "f").write('Message is too large to be sent via QR code. Please use the ton:// link or another method.');
45
+ process.exit(1);
46
+ }
47
+ throw err;
48
+ }
38
49
  }
39
50
  address() {
40
51
  return undefined;
package/dist/paths.d.ts CHANGED
@@ -1,13 +1,16 @@
1
1
  export declare const CONTRACTS = "contracts";
2
2
  export declare const TESTS = "tests";
3
+ export declare const COMPILABLES = "compilables";
3
4
  export declare const WRAPPERS = "wrappers";
4
5
  export declare const SCRIPTS = "scripts";
5
6
  export declare const TEMP = "temp";
6
7
  export declare const BUILD = "build";
8
+ export declare const COMPILABLES_DIR: string;
7
9
  export declare const WRAPPERS_DIR: string;
8
10
  export declare const SCRIPTS_DIR: string;
9
11
  export declare const BUILD_DIR: string;
10
12
  export declare const TEMP_DIR: string;
11
13
  export declare const CONTRACTS_DIR: string;
12
14
  export declare const TESTS_DIR: string;
15
+ export declare const BLUEPRINT_CONFIG: string;
13
16
  export declare const TACT_ROOT_CONFIG: string;
package/dist/paths.js CHANGED
@@ -3,18 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TACT_ROOT_CONFIG = exports.TESTS_DIR = exports.CONTRACTS_DIR = exports.TEMP_DIR = exports.BUILD_DIR = exports.SCRIPTS_DIR = exports.WRAPPERS_DIR = exports.BUILD = exports.TEMP = exports.SCRIPTS = exports.WRAPPERS = exports.TESTS = exports.CONTRACTS = void 0;
6
+ exports.TACT_ROOT_CONFIG = exports.BLUEPRINT_CONFIG = exports.TESTS_DIR = exports.CONTRACTS_DIR = exports.TEMP_DIR = exports.BUILD_DIR = exports.SCRIPTS_DIR = exports.WRAPPERS_DIR = exports.COMPILABLES_DIR = exports.BUILD = exports.TEMP = exports.SCRIPTS = exports.WRAPPERS = exports.COMPILABLES = exports.TESTS = exports.CONTRACTS = void 0;
7
7
  const path_1 = __importDefault(require("path"));
8
8
  exports.CONTRACTS = 'contracts';
9
9
  exports.TESTS = 'tests';
10
+ exports.COMPILABLES = 'compilables';
10
11
  exports.WRAPPERS = 'wrappers';
11
12
  exports.SCRIPTS = 'scripts';
12
13
  exports.TEMP = 'temp';
13
14
  exports.BUILD = 'build';
15
+ exports.COMPILABLES_DIR = path_1.default.join(process.cwd(), exports.COMPILABLES);
14
16
  exports.WRAPPERS_DIR = path_1.default.join(process.cwd(), exports.WRAPPERS);
15
17
  exports.SCRIPTS_DIR = path_1.default.join(process.cwd(), exports.SCRIPTS);
16
18
  exports.BUILD_DIR = path_1.default.join(process.cwd(), exports.BUILD);
17
19
  exports.TEMP_DIR = path_1.default.join(process.cwd(), exports.TEMP);
18
20
  exports.CONTRACTS_DIR = path_1.default.join(process.cwd(), exports.CONTRACTS);
19
21
  exports.TESTS_DIR = path_1.default.join(process.cwd(), exports.TESTS);
22
+ exports.BLUEPRINT_CONFIG = path_1.default.join(process.cwd(), 'blueprint.config.ts');
20
23
  exports.TACT_ROOT_CONFIG = path_1.default.join(process.cwd(), 'tact.config.json');
@@ -0,0 +1,7 @@
1
+ {{name}}.compile.ts
2
+ import { CompilerConfig } from '@ton/blueprint';
3
+
4
+ export const compile: CompilerConfig = {
5
+ lang: 'func',
6
+ targets: ['{{contractPath}}'],
7
+ };
@@ -0,0 +1,10 @@
1
+ {{name}}.compile.ts
2
+ import { CompilerConfig } from '@ton/blueprint';
3
+
4
+ export const compile: CompilerConfig = {
5
+ lang: 'tact',
6
+ target: '{{contractPath}}',
7
+ options: {
8
+ debug: true,
9
+ },
10
+ };
@@ -0,0 +1,2 @@
1
+ {{name}}.ts
2
+ export * from '../build/{{name}}/tact_{{name}}';
@@ -0,0 +1,4 @@
1
+ export type File = {
2
+ name: string;
3
+ path: string;
4
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export * from './object.utils';
2
+ export * from './timer.utils';
3
+ export * from './ton.utils';
4
+ export * from './selection.utils';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./object.utils"), exports);
18
+ __exportStar(require("./timer.utils"), exports);
19
+ __exportStar(require("./ton.utils"), exports);
20
+ __exportStar(require("./selection.utils"), exports);
@@ -0,0 +1,3 @@
1
+ export declare function oneOrZeroOf<T extends {
2
+ [k: string]: boolean | undefined;
3
+ }>(options: T): keyof T | undefined;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.oneOrZeroOf = void 0;
4
+ function oneOrZeroOf(options) {
5
+ let opt = undefined;
6
+ for (const k in options) {
7
+ if (options[k]) {
8
+ if (opt === undefined) {
9
+ opt = k;
10
+ }
11
+ else {
12
+ throw new Error(`Please pick only one of the options: ${Object.keys(options).join(', ')}`);
13
+ }
14
+ }
15
+ }
16
+ return opt;
17
+ }
18
+ exports.oneOrZeroOf = oneOrZeroOf;
@@ -0,0 +1,24 @@
1
+ import { UIProvider } from '../ui/UIProvider';
2
+ import { File } from '../types/file';
3
+ export declare const findCompiles: (directory?: string) => Promise<File[]>;
4
+ export declare const findScripts: () => Promise<File[]>;
5
+ export declare function selectOption(options: {
6
+ name: string;
7
+ value: string;
8
+ }[], opts: {
9
+ ui: UIProvider;
10
+ msg: string;
11
+ hint?: string;
12
+ }): Promise<{
13
+ name: string;
14
+ value: string;
15
+ }>;
16
+ export declare function selectFile(files: File[], opts: {
17
+ ui: UIProvider;
18
+ hint?: string;
19
+ import?: boolean;
20
+ }): Promise<{
21
+ module: any;
22
+ name: string;
23
+ path: string;
24
+ }>;
@@ -27,44 +27,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  var _a;
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.getExplorerLink = exports.selectFile = exports.selectOption = exports.findScripts = exports.findCompiles = exports.oneOrZeroOf = exports.sleep = exports.tonDeepLink = void 0;
30
+ exports.selectFile = exports.selectOption = exports.findScripts = exports.findCompiles = void 0;
31
31
  const path_1 = __importDefault(require("path"));
32
32
  const promises_1 = __importDefault(require("fs/promises"));
33
- const paths_1 = require("./paths");
34
- const tonDeepLink = (address, amount, body, stateInit) => `ton://transfer/${address.toString({
35
- urlSafe: true,
36
- bounceable: true,
37
- })}?amount=${amount.toString()}${body ? '&bin=' + body.toBoc().toString('base64url') : ''}${stateInit ? '&init=' + stateInit.toBoc().toString('base64url') : ''}`;
38
- exports.tonDeepLink = tonDeepLink;
39
- function sleep(ms) {
40
- return new Promise((resolve) => {
41
- setTimeout(resolve, ms);
42
- });
43
- }
44
- exports.sleep = sleep;
45
- function oneOrZeroOf(options) {
46
- let opt = undefined;
47
- for (const k in options) {
48
- if (options[k]) {
49
- if (opt === undefined) {
50
- opt = k;
51
- }
52
- else {
53
- throw new Error(`Please pick only one of the options: ${Object.keys(options).join(', ')}`);
54
- }
55
- }
56
- }
57
- return opt;
58
- }
59
- exports.oneOrZeroOf = oneOrZeroOf;
60
- const compileEnd = '.compile.ts';
61
- const findCompiles = async () => (await promises_1.default.readdir(paths_1.WRAPPERS_DIR))
62
- .filter((f) => f.endsWith(compileEnd))
63
- .map((f) => ({ path: path_1.default.join(paths_1.WRAPPERS_DIR, f), name: f.slice(0, f.length - compileEnd.length) }));
33
+ const paths_1 = require("../paths");
34
+ const compile_1 = require("../compile/compile");
35
+ const findCompiles = async (directory) => {
36
+ const dir = directory ?? await (0, compile_1.getCompilablesDirectory)();
37
+ const files = await promises_1.default.readdir(dir);
38
+ const compilables = files.filter((file) => file.endsWith(compile_1.COMPILE_END));
39
+ return compilables.map((file) => ({
40
+ path: path_1.default.join(dir, file),
41
+ name: file.slice(0, file.length - compile_1.COMPILE_END.length),
42
+ }));
43
+ };
64
44
  exports.findCompiles = findCompiles;
65
- const findScripts = async () => (await promises_1.default.readdir(paths_1.SCRIPTS_DIR))
66
- .filter((f) => f.endsWith('.ts'))
67
- .map((f) => ({ path: path_1.default.join(paths_1.SCRIPTS_DIR, f), name: path_1.default.parse(f).name }));
45
+ const findScripts = async () => {
46
+ const dirents = await promises_1.default.readdir(paths_1.SCRIPTS_DIR, { recursive: true, withFileTypes: true });
47
+ const scripts = dirents.filter((dirent) => dirent.isFile() && dirent.name.endsWith('.ts'));
48
+ return scripts
49
+ .map((script) => ({
50
+ name: path_1.default.join(script.path.slice(paths_1.SCRIPTS_DIR.length + 1), path_1.default.parse(script.name).name),
51
+ path: path_1.default.join(script.path, script.name),
52
+ }))
53
+ .sort((a, b) => (a.name >= b.name ? 1 : -1));
54
+ };
68
55
  exports.findScripts = findScripts;
69
56
  async function selectOption(options, opts) {
70
57
  if (opts.hint) {
@@ -104,19 +91,3 @@ async function selectFile(files, opts) {
104
91
  };
105
92
  }
106
93
  exports.selectFile = selectFile;
107
- function getExplorerLink(address, network, explorer) {
108
- const networkPrefix = network === 'testnet' ? 'testnet.' : '';
109
- switch (explorer) {
110
- case 'tonscan':
111
- return `https://${networkPrefix}tonscan.org/address/${address}`;
112
- case 'tonviewer':
113
- return `https://${networkPrefix}tonviewer.com/${address}`;
114
- case 'toncx':
115
- return `https://${networkPrefix}ton.cx/address/${address}`;
116
- case 'dton':
117
- return `https://${networkPrefix}dton.io/a/${address}`;
118
- default:
119
- return `https://${networkPrefix}tonscan.org/address/${address}`;
120
- }
121
- }
122
- exports.getExplorerLink = getExplorerLink;
@@ -0,0 +1 @@
1
+ export declare function sleep(ms: number): Promise<unknown>;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleep = void 0;
4
+ function sleep(ms) {
5
+ return new Promise((resolve) => {
6
+ setTimeout(resolve, ms);
7
+ });
8
+ }
9
+ exports.sleep = sleep;
@@ -0,0 +1,3 @@
1
+ import { Address, Cell } from '@ton/core';
2
+ export declare const tonDeepLink: (address: Address, amount: bigint, body?: Cell, stateInit?: Cell) => string;
3
+ export declare function getExplorerLink(address: string, network: string, explorer: string): string;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getExplorerLink = exports.tonDeepLink = void 0;
4
+ const tonDeepLink = (address, amount, body, stateInit) => `ton://transfer/${address.toString({
5
+ urlSafe: true,
6
+ bounceable: true,
7
+ })}?amount=${amount.toString()}${body ? '&bin=' + body.toBoc().toString('base64url') : ''}${stateInit ? '&init=' + stateInit.toBoc().toString('base64url') : ''}`;
8
+ exports.tonDeepLink = tonDeepLink;
9
+ function getExplorerLink(address, network, explorer) {
10
+ const networkPrefix = network === 'testnet' ? 'testnet.' : '';
11
+ switch (explorer) {
12
+ case 'tonscan':
13
+ return `https://${networkPrefix}tonscan.org/address/${address}`;
14
+ case 'tonviewer':
15
+ return `https://${networkPrefix}tonviewer.com/${address}`;
16
+ case 'toncx':
17
+ return `https://${networkPrefix}ton.cx/address/${address}`;
18
+ case 'dton':
19
+ return `https://${networkPrefix}dton.io/a/${address}`;
20
+ default:
21
+ return `https://${networkPrefix}tonscan.org/address/${address}`;
22
+ }
23
+ }
24
+ exports.getExplorerLink = getExplorerLink;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ton/blueprint",
3
- "version": "0.21.0",
3
+ "version": "0.23.0-debugger.0",
4
4
  "description": "Framework for development of TON smart contracts",
5
5
  "main": "dist/index.js",
6
6
  "bin": "./dist/cli/cli.js",
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@orbs-network/ton-access": "^2.3.3",
38
- "@tact-lang/compiler": "^1.3.0",
39
- "@ton-community/func-js": "^0.7.0",
38
+ "@tact-lang/compiler": "^1.4.0",
39
+ "@ton-community/func-js": "^0.8.0-debuginfo.0",
40
40
  "@tonconnect/sdk": "^2.2.0",
41
41
  "arg": "^5.0.2",
42
42
  "chalk": "^4.1.0",
@@ -46,5 +46,5 @@
46
46
  "ton-x": "^2.1.0",
47
47
  "ts-node": "^10.9.1"
48
48
  },
49
- "packageManager": "yarn@3.6.1"
49
+ "packageManager": "yarn@4.3.1"
50
50
  }
package/dist/utils.d.ts DELETED
@@ -1,39 +0,0 @@
1
- import { Address, Cell } from '@ton/core';
2
- import { UIProvider } from './ui/UIProvider';
3
- export declare const tonDeepLink: (address: Address, amount: bigint, body?: Cell, stateInit?: Cell) => string;
4
- export declare function sleep(ms: number): Promise<unknown>;
5
- export declare function oneOrZeroOf<T extends {
6
- [k: string]: boolean | undefined;
7
- }>(options: T): keyof T | undefined;
8
- export declare const findCompiles: () => Promise<{
9
- path: string;
10
- name: string;
11
- }[]>;
12
- export declare const findScripts: () => Promise<{
13
- path: string;
14
- name: string;
15
- }[]>;
16
- export declare function selectOption(options: {
17
- name: string;
18
- value: string;
19
- }[], opts: {
20
- ui: UIProvider;
21
- msg: string;
22
- hint?: string;
23
- }): Promise<{
24
- name: string;
25
- value: string;
26
- }>;
27
- export declare function selectFile(files: {
28
- name: string;
29
- path: string;
30
- }[], opts: {
31
- ui: UIProvider;
32
- hint?: string;
33
- import?: boolean;
34
- }): Promise<{
35
- module: any;
36
- name: string;
37
- path: string;
38
- }>;
39
- export declare function getExplorerLink(address: string, network: string, explorer: string): string;