@ton/blueprint 0.10.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 (70) hide show
  1. package/CHANGELOG.md +146 -0
  2. package/README.md +114 -0
  3. package/dist/cli/build.d.ts +4 -0
  4. package/dist/cli/build.js +68 -0
  5. package/dist/cli/cli.d.ts +7 -0
  6. package/dist/cli/cli.js +106 -0
  7. package/dist/cli/create.d.ts +6 -0
  8. package/dist/cli/create.js +96 -0
  9. package/dist/cli/help.d.ts +2 -0
  10. package/dist/cli/help.js +55 -0
  11. package/dist/cli/run.d.ts +2 -0
  12. package/dist/cli/run.js +18 -0
  13. package/dist/cli/test.d.ts +2 -0
  14. package/dist/cli/test.js +9 -0
  15. package/dist/compile/CompilerConfig.d.ts +21 -0
  16. package/dist/compile/CompilerConfig.js +2 -0
  17. package/dist/compile/OverwritableVirtualFileSystem.d.ts +10 -0
  18. package/dist/compile/OverwritableVirtualFileSystem.js +24 -0
  19. package/dist/compile/compile.d.ts +14 -0
  20. package/dist/compile/compile.js +115 -0
  21. package/dist/index.d.ts +6 -0
  22. package/dist/index.js +10 -0
  23. package/dist/network/NetworkProvider.d.ts +22 -0
  24. package/dist/network/NetworkProvider.js +2 -0
  25. package/dist/network/createNetworkProvider.d.ts +3 -0
  26. package/dist/network/createNetworkProvider.js +282 -0
  27. package/dist/network/send/DeeplinkProvider.d.ts +10 -0
  28. package/dist/network/send/DeeplinkProvider.js +44 -0
  29. package/dist/network/send/MnemonicProvider.d.ts +19 -0
  30. package/dist/network/send/MnemonicProvider.js +80 -0
  31. package/dist/network/send/SendProvider.d.ts +6 -0
  32. package/dist/network/send/SendProvider.js +2 -0
  33. package/dist/network/send/TonConnectProvider.d.ts +12 -0
  34. package/dist/network/send/TonConnectProvider.js +108 -0
  35. package/dist/network/send/TonHubProvider.d.ts +16 -0
  36. package/dist/network/send/TonHubProvider.js +110 -0
  37. package/dist/network/storage/FSStorage.d.ts +8 -0
  38. package/dist/network/storage/FSStorage.js +53 -0
  39. package/dist/network/storage/Storage.d.ts +18 -0
  40. package/dist/network/storage/Storage.js +2 -0
  41. package/dist/paths.d.ts +12 -0
  42. package/dist/paths.js +19 -0
  43. package/dist/template.d.ts +4 -0
  44. package/dist/template.js +15 -0
  45. package/dist/templates/func/common/wrappers/compile.ts.template +7 -0
  46. package/dist/templates/func/counter/contracts/contract.fc.template +72 -0
  47. package/dist/templates/func/counter/scripts/deploy.ts.template +22 -0
  48. package/dist/templates/func/counter/scripts/increment.ts.template +38 -0
  49. package/dist/templates/func/counter/tests/spec.ts.template +81 -0
  50. package/dist/templates/func/counter/wrappers/wrapper.ts.template +67 -0
  51. package/dist/templates/func/empty/contracts/contract.fc.template +6 -0
  52. package/dist/templates/func/empty/scripts/deploy.ts.template +14 -0
  53. package/dist/templates/func/empty/tests/spec.ts.template +39 -0
  54. package/dist/templates/func/empty/wrappers/wrapper.ts.template +30 -0
  55. package/dist/templates/tact/common/wrappers/compile.ts.template +7 -0
  56. package/dist/templates/tact/common/wrappers/wrapper.ts.template +2 -0
  57. package/dist/templates/tact/counter/contracts/contract.tact.template +29 -0
  58. package/dist/templates/tact/counter/scripts/deploy.ts.template +23 -0
  59. package/dist/templates/tact/counter/scripts/increment.ts.template +45 -0
  60. package/dist/templates/tact/counter/tests/spec.ts.template +82 -0
  61. package/dist/templates/tact/empty/contracts/contract.tact.template +8 -0
  62. package/dist/templates/tact/empty/scripts/deploy.ts.template +23 -0
  63. package/dist/templates/tact/empty/tests/spec.ts.template +41 -0
  64. package/dist/ui/InquirerUIProvider.d.ts +12 -0
  65. package/dist/ui/InquirerUIProvider.js +70 -0
  66. package/dist/ui/UIProvider.d.ts +8 -0
  67. package/dist/ui/UIProvider.js +2 -0
  68. package/dist/utils.d.ts +39 -0
  69. package/dist/utils.js +122 -0
  70. package/package.json +51 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,146 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.10.0] - 2023-06-06
9
+
10
+ ### Added
11
+
12
+ - Added two optional fields to the `CompilerConfig`: `preCompileHook?: () => Promise<void>` and `postCompileHook?: (code: Cell) => Promise<void>`. The former one gets called before any compilation of the respective contract happens, the latter one - after any compilation with the compiled code cell (they are called both during the `build` command and when calling the `compile` function for the respective contracts)
13
+
14
+ ### Changed
15
+
16
+ - Changed the `run` command to only show `.ts` scripts
17
+
18
+ ## [0.9.0] - 2023-04-21
19
+
20
+ ### Changed
21
+
22
+ - Updated dependencies, of note: func-js to use func 0.4.3, TACT to 1.1.1
23
+
24
+ ## [0.8.0] - 2023-04-07
25
+
26
+ ### Changed
27
+
28
+ - Changed the `help` command to contain significantly more detailed help for every command
29
+ - Added the `success: true` requirement to every template test
30
+ - Updated dependencies
31
+
32
+ ## [0.7.0] - 2023-04-03
33
+
34
+ This release contains a breaking change.
35
+
36
+ ### Changed
37
+
38
+ - Changed the return type of `networkProvider.api()` and the type used internally in `NetworkProvider` from `TonClient` to `TonClient4`. This is a breaking change
39
+ - Updated dependencies
40
+
41
+ ## [0.6.1] - 2023-03-27
42
+
43
+ ### Changed
44
+
45
+ - Changed `UIProvider.prompt` return type from `Promise<void>` to `Promise<boolean>`
46
+
47
+ ## [0.6.0] - 2023-03-21
48
+
49
+ ### Added
50
+
51
+ - Added support for [TACT](https://github.com/tact-lang/tact), including TACT smart contract templates
52
+ - Added `--all` option for `build` command
53
+
54
+ ### Changed
55
+
56
+ - Updated dependencies
57
+
58
+ ## [0.5.0] - 2023-03-13
59
+
60
+ ### Changed
61
+
62
+ - `SendProvider` now returns `Promise<any>` instead of `Promise<void>` from `sendTransaction`. This allows providers using TON Connect and TonHub to return the results from their backends to the end user
63
+
64
+ ## [0.4.1] - 2023-03-02
65
+
66
+ ### Changed
67
+
68
+ - Changed ton peer dependency version to `>=13.4.1`
69
+
70
+ ## [0.4.0] - 2023-03-01
71
+
72
+ This release contains a breaking change.
73
+
74
+ ### Changed
75
+
76
+ - Changed ton-core peer dependency version to `>=0.48.0`. This is a breaking change
77
+
78
+ ### Added
79
+
80
+ - Added a new mnemonic deployer. Environment variables `WALLET_MNEMONIC` and `WALLET_VERSION` must be set, or a .env file with them must be present in order for it to be usable. Tonkeeper's v4R2 wallet corresponds to v4 version in blueprint
81
+ - Added the ability to choose the explorer for the deployed contracts. Pass one of the CLI flags `--tonscan`, `--tonapi`, `--toncx`, `--dton` to choose. Tonscan is the default
82
+ - Added ton-crypto peer dependency of version `>=3.2.0`
83
+
84
+ ### Fixed
85
+
86
+ - Fixed TonHub deployer's `Sent transaction` message
87
+ - Fixed `SendMode.PAY_GAS_SEPARATLY` (missing E) typo in accordance with ton-core update
88
+ - Fixed a crash when using `blueprint run` with flags but no file name
89
+
90
+ ## [0.3.0] - 2023-02-27
91
+
92
+ ### Added
93
+
94
+ - Added an increment counter script for the counter template
95
+ - Added `isContractDeployed(address)` method to `NetworkProvider`
96
+ - Added `waitForDeploy(address, attempts?, sleepDuration?)` method to `NetworkProvider`
97
+
98
+ ### Fixed
99
+
100
+ - Fixed exit code 1 on Windows even in case of successful execution
101
+ - Fixed paths to `.fc` files in `.compile.ts` files on Windows
102
+ - Fixed `TonConnectProvider` output
103
+
104
+ ### Changed
105
+
106
+ - Converted ```Deployer sender does not support `bounce` ``` error into a warning
107
+ - Added an optional `init?: { code?: Cell; data?: Cell }` argument to `provider` method on `NetworkProvider`
108
+ - `createNetworkProvider` now requires a `UIProvider`
109
+ - Removed excessive comments from counter template contract
110
+ - Changed deploy script templates to use `sendDeploy` and `waitForDeploy` instead of `deploy`
111
+ - Refactored test templates to create `Blockchain` and deploy contract in `beforeEach`
112
+ - Disabled file choice menu when there is only 1 file
113
+
114
+ ### Deprecated
115
+
116
+ - Deprecated `deploy` method on `NetworkProvider`. Users are advised to use self-implemented `sendDeploy` (or similar) methods on their `Contract` instances together with `isContractDeployed` or `waitForDeploy` on `NetworkProvider`
117
+
118
+ ## [0.2.0] - 2023-02-09
119
+
120
+ ### Added
121
+
122
+ - Added `blueprint test` command
123
+ - Added a pretty help message
124
+ - Added a hint to indicate that contract names must be PascalCase, and a restriction that contract names must start with a capital letter
125
+ - Added a better error message on an unknown command
126
+
127
+ ### Fixed
128
+
129
+ - Fixed counter templates
130
+ - Fixed an issue where using `networkProvider.provider` and `networkProvider.open` would lead to `Deployer sender does not support "bounce"` message when trying to send internal messages
131
+
132
+ ### Changed
133
+
134
+ - `networkProvider.provider` and `networkProvider.open` now wrap `TonClient`'s `ContractProvider` instead of directly using it for better control over passed arguments
135
+ - Removed unnecessary `await` keywords from all templates
136
+
137
+ ## [0.1.0] - 2023-02-03
138
+
139
+ ### Added
140
+
141
+ - Added fully interactive and fully non-interactive modes for the `create` command
142
+ - Added `input(message)` method to `UIProvider` and `InquirerUIProvider`
143
+
144
+ ### Fixed
145
+
146
+ - File selection (compilation files in `build` and scripts in `run`) now accepts CLI argument hints in any case
package/README.md ADDED
@@ -0,0 +1,114 @@
1
+ <img src="https://raw.githubusercontent.com/ton-org/blueprint/main/logo.svg" width=400 >
2
+
3
+ # Blueprint
4
+
5
+ A development environment for TON blockchain for writing, testing, and deploying smart contracts.
6
+
7
+ ### Quick start 🚀
8
+
9
+ Run the following in terminal to create a new project and follow the on-screen instructions:
10
+
11
+ ```console
12
+ npm create ton@latest
13
+ ```
14
+
15
+ &nbsp;
16
+
17
+ ### Core features 🔥
18
+
19
+ * Create a development environment from template in one click - `npm create ton@latest`
20
+ * Streamlined workflow for building, testing and deploying smart contracts
21
+ * Dead simple deployment to mainnet/testnet using your favorite wallet (eg. Tonkeeper)
22
+ * Blazing fast testing of multiple smart contracts in an isolated blockchain running in-process
23
+
24
+ ### Tech stack
25
+
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
29
+
30
+ ### Requirements
31
+
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)
34
+
35
+ &nbsp;
36
+
37
+ ## Create a new project
38
+
39
+ 1. Run and follow the on-screen instructions: &nbsp; `npm create ton@latest` &nbsp; or &nbsp; `npx create-ton@latest`
40
+ 2. (Optional) Then from the project directory: &nbsp; `npm install` &nbsp; or &nbsp; `yarn install`
41
+
42
+ ### Directory structure
43
+
44
+ * `contracts/` - Source code in [FunC](https://ton.org/docs/develop/func/overview) for all smart contracts and their imports
45
+ * `wrappers/` - TypeScript interface classes for all contracts (implementing `Contract` from [ton-core](https://www.npmjs.com/package/ton-core))
46
+ * include message [de]serialization primitives, getter wrappers and compilation functions
47
+ * used by the test suite and client code to interact with the contracts from TypeScript
48
+ * `tests/` - TypeScript test suite for all contracts (relying on [Sandbox](https://github.com/ton-org/sandbox) for in-process tests)
49
+ * `scripts/` - Deployment scripts to mainnet/testnet and other scripts interacting with live contracts
50
+ * `build/` - Compilation artifacts created here after running a build command
51
+
52
+ ### Build one of the contracts
53
+
54
+ 1. You need a compilation script in `wrappers/<CONTRACT>.compile.ts` - [example](/example/wrappers/Counter.compile.ts)
55
+ 2. Run interactive: &nbsp;&nbsp; `npx blueprint build` &nbsp; or &nbsp; `yarn blueprint build`
56
+ 3. Non-interactive: &nbsp; `npx/yarn blueprint build <CONTRACT>`
57
+ * Example: `yarn blueprint build counter`
58
+ 4. Build results are generated in `build/<CONTRACT>.compiled.json`
59
+
60
+ ### Run the test suite
61
+
62
+ 1. Run in terminal: &nbsp; `npx blueprint test` &nbsp; or &nbsp; `yarn blueprint test`
63
+ 2. Alternative method: &nbsp; `npm test` &nbsp; or &nbsp; `yarn test`
64
+
65
+ ### Deploy one of the contracts
66
+
67
+ 1. You need a deploy script in `scripts/deploy<CONTRACT>.ts` - [example](/example/scripts/deployCounter.ts)
68
+ 2. Run interactive: &nbsp;&nbsp; `npx blueprint run` &nbsp; or &nbsp; `yarn blueprint run`
69
+ 3. Non-interactive: &nbsp; `npx/yarn blueprint run <CONTRACT> --<NETWORK> --<DEPLOY_METHOD>`
70
+ * Example: `yarn blueprint run deployCounter --mainnet --tonconnect`
71
+
72
+ ### Help and additional commands
73
+
74
+ Run in terminal: &nbsp; `npx blueprint help` &nbsp; or &nbsp; `yarn blueprint help`
75
+
76
+ &nbsp;
77
+
78
+ ## Develop a new contract
79
+
80
+ 1. Make sure you have a project to host the contract
81
+ 2. Run interactive: &nbsp;&nbsp; `npx blueprint create` &nbsp; or &nbsp; `yarn blueprint create`
82
+ 3. Non-interactive: &nbsp; `npx/yarn blueprint create <CONTRACT> --type <TYPE>` (type can be `func-empty`, `func-counter`, `tact-empty`, `tact-counter`)
83
+ * Example: `yarn blueprint create MyNewContract --type func-empty`
84
+
85
+ ### Contract code
86
+
87
+ 1. Implement the standalone FunC root contract in `contracts/<CONTRACT>.fc`
88
+ 2. Implement shared FunC imports (if breaking code to multiple files) in `contracts/imports/*.fc`
89
+ 3. Implement wrapper TypeScript class in `wrappers/<CONTRACT>.ts` to encode messages and decode getters
90
+
91
+ ### Test suite
92
+
93
+ 1. Implement TypeScript tests in `tests/<CONTRACT>.spec.ts`
94
+ 2. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to interact with the contract
95
+
96
+ ### Compilation and deployment
97
+
98
+ 1. Implement a compilation script in `wrappers/<CONTRACT>.compile.ts`
99
+ 2. Implement a deployment script in `scripts/deploy<CONTRACT>.ts`
100
+ 3. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to initialize the contract
101
+
102
+ &nbsp;
103
+
104
+ ## Contributors
105
+
106
+ Special thanks to [@qdevstudio](https://t.me/qdevstudio) for their logo for blueprint.
107
+
108
+ ## License
109
+
110
+ MIT
111
+
112
+ ## Donations
113
+
114
+ TON - `EQAQR1d1Q4NaE5EefwUMdrr1QvXg-8mDB0XI2-fwDBD0nYxC`
@@ -0,0 +1,4 @@
1
+ import { Runner } from './cli';
2
+ import { UIProvider } from '../ui/UIProvider';
3
+ export declare function buildOne(contract: string, ui: UIProvider): Promise<void>;
4
+ export declare const build: Runner;
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.build = exports.buildOne = void 0;
7
+ const path_1 = __importDefault(require("path"));
8
+ const paths_1 = require("../paths");
9
+ const utils_1 = require("../utils");
10
+ const promises_1 = __importDefault(require("fs/promises"));
11
+ const compile_1 = require("../compile/compile");
12
+ const arg_1 = __importDefault(require("arg"));
13
+ async function buildOne(contract, ui) {
14
+ ui.write(`Build script running, compiling ${contract}`);
15
+ const buildArtifactPath = path_1.default.join(paths_1.BUILD_DIR, `${contract}.compiled.json`);
16
+ try {
17
+ await promises_1.default.unlink(buildArtifactPath);
18
+ }
19
+ catch (e) { }
20
+ ui.setActionPrompt('⏳ Compiling...');
21
+ try {
22
+ const result = await (0, compile_1.doCompile)(contract);
23
+ if (result.lang === 'tact') {
24
+ for (const [k, v] of result.fs) {
25
+ await promises_1.default.mkdir(path_1.default.dirname(k), {
26
+ recursive: true,
27
+ });
28
+ await promises_1.default.writeFile(k, v);
29
+ }
30
+ }
31
+ const cell = result.code;
32
+ ui.clearActionPrompt();
33
+ ui.write('\n✅ Compiled successfully! Cell BOC hex result:\n\n');
34
+ ui.write(cell.toBoc().toString('hex'));
35
+ await promises_1.default.mkdir(paths_1.BUILD_DIR, { recursive: true });
36
+ await promises_1.default.writeFile(buildArtifactPath, JSON.stringify({
37
+ hex: cell.toBoc().toString('hex'),
38
+ }));
39
+ ui.write(`\n✅ Wrote compilation artifact to ${path_1.default.relative(process.cwd(), buildArtifactPath)}`);
40
+ }
41
+ catch (e) {
42
+ ui.clearActionPrompt();
43
+ ui.write(e.toString());
44
+ process.exit(1);
45
+ }
46
+ }
47
+ exports.buildOne = buildOne;
48
+ const build = async (args, ui) => {
49
+ require('ts-node/register');
50
+ const localArgs = (0, arg_1.default)({
51
+ '--all': Boolean,
52
+ });
53
+ const files = await (0, utils_1.findCompiles)();
54
+ if (localArgs['--all']) {
55
+ for (const file of files) {
56
+ await buildOne(file.name, ui);
57
+ }
58
+ }
59
+ else {
60
+ const sel = await (0, utils_1.selectFile)(files, {
61
+ ui,
62
+ hint: args._.length > 1 && args._[1].length > 0 ? args._[1] : undefined,
63
+ import: false,
64
+ });
65
+ await buildOne(sel.name, ui);
66
+ }
67
+ };
68
+ exports.build = build;
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import arg from 'arg';
3
+ import { UIProvider } from '../ui/UIProvider';
4
+ declare const argSpec: {};
5
+ export type Args = arg.Result<typeof argSpec>;
6
+ export type Runner = (args: Args, ui: UIProvider) => Promise<void>;
7
+ export {};
@@ -0,0 +1,106 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ var __importDefault = (this && this.__importDefault) || function (mod) {
27
+ return (mod && mod.__esModule) ? mod : { "default": mod };
28
+ };
29
+ Object.defineProperty(exports, "__esModule", { value: true });
30
+ const dotenv = __importStar(require("dotenv"));
31
+ dotenv.config();
32
+ const arg_1 = __importDefault(require("arg"));
33
+ const chalk_1 = __importDefault(require("chalk"));
34
+ const create_1 = require("./create");
35
+ const run_1 = require("./run");
36
+ const build_1 = require("./build");
37
+ const test_1 = require("./test");
38
+ const help_1 = require("./help");
39
+ const InquirerUIProvider_1 = require("../ui/InquirerUIProvider");
40
+ const argSpec = {};
41
+ const runners = {
42
+ create: create_1.create,
43
+ run: run_1.run,
44
+ build: build_1.build,
45
+ test: test_1.test,
46
+ help: help_1.help,
47
+ };
48
+ async function main() {
49
+ const args = (0, arg_1.default)(argSpec, {
50
+ permissive: true,
51
+ });
52
+ if (args._.length === 0) {
53
+ showHelp();
54
+ process.exit(0);
55
+ }
56
+ const runner = runners[args._[0]];
57
+ if (!runner) {
58
+ console.log(chalk_1.default.redBright(` Error: command not found.`) + ` Run 'blueprint help' to see available commands\n`);
59
+ process.exit(1);
60
+ }
61
+ const ui = new InquirerUIProvider_1.InquirerUIProvider();
62
+ await runner({
63
+ ...args,
64
+ _: args._.filter((a) => !(a.length > 1 && a[0] === '-')), // filter out the flags pushed by `permissive`
65
+ }, ui);
66
+ ui.close();
67
+ }
68
+ process.on('SIGINT', () => {
69
+ process.exit(130);
70
+ });
71
+ main()
72
+ .catch(console.error)
73
+ .then(() => process.exit(0));
74
+ function showHelp() {
75
+ console.log(chalk_1.default.blueBright(`
76
+ ____ _ _ _ _____ ____ ____ ___ _ _ _____
77
+ | __ )| | | | | | ____| _ \\| _ \\|_ _| \\ | |_ _|
78
+ | _ \\| | | | | | _| | |_) | |_) || || \\| | | |
79
+ | |_) | |__| |_| | |___| __/| _ < | || |\\ | | |
80
+ |____/|_____\\___/|_____|_| |_| \\_\\___|_| \\_| |_| `));
81
+ console.log(chalk_1.default.blue(` TON development for professionals`));
82
+ console.log(``);
83
+ console.log(` Usage: blueprint [OPTIONS] COMMAND [ARGS]`);
84
+ console.log(``);
85
+ console.log(chalk_1.default.cyanBright(` blueprint create`) +
86
+ `\t` +
87
+ chalk_1.default.whiteBright(`create a new contract with .fc source, .ts wrapper, .spec.ts test`));
88
+ console.log(`\t\t\t` + chalk_1.default.gray(`blueprint create ContractName`));
89
+ console.log(chalk_1.default.cyanBright(` blueprint build`) +
90
+ `\t` +
91
+ chalk_1.default.whiteBright(`builds a contract that has a .compile.ts file`));
92
+ console.log(`\t\t\t` + chalk_1.default.gray(`blueprint build ContractName`));
93
+ console.log(chalk_1.default.cyanBright(` blueprint test`) +
94
+ `\t` +
95
+ chalk_1.default.whiteBright(`run the full project test suite with all .spec.ts files`));
96
+ console.log(`\t\t\t` + chalk_1.default.gray(`blueprint test`));
97
+ console.log(chalk_1.default.cyanBright(` blueprint run `) +
98
+ `\t` +
99
+ chalk_1.default.whiteBright(`runs a script from 'scripts' directory (eg. a deploy script)`));
100
+ console.log(`\t\t\t` + chalk_1.default.gray(`blueprint run deployContractName`));
101
+ console.log(chalk_1.default.cyanBright(` blueprint help`) +
102
+ `\t` +
103
+ chalk_1.default.whiteBright(`shows more detailed help, also see https://github.com/ton-community/blueprint`));
104
+ console.log(`\t\t\t` + chalk_1.default.gray(`blueprint help`));
105
+ console.log(``);
106
+ }
@@ -0,0 +1,6 @@
1
+ import { Runner } from './cli';
2
+ export declare const templateTypes: {
3
+ name: string;
4
+ value: string;
5
+ }[];
6
+ export declare const create: Runner;
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.create = exports.templateTypes = void 0;
7
+ const promises_1 = require("fs/promises");
8
+ const path_1 = __importDefault(require("path"));
9
+ const template_1 = require("../template");
10
+ const utils_1 = require("../utils");
11
+ const arg_1 = __importDefault(require("arg"));
12
+ const build_1 = require("./build");
13
+ function toSnakeCase(v) {
14
+ const r = v.replace(/[A-Z]/g, (sub) => '_' + sub.toLowerCase());
15
+ return r[0] === '_' ? r.substring(1) : r;
16
+ }
17
+ async function createFile(templatePath, realPath, replaces) {
18
+ const template = (await (0, promises_1.readFile)(templatePath)).toString('utf-8');
19
+ const lines = template.split('\n');
20
+ const fileName = (0, template_1.executeTemplate)(lines.shift(), replaces);
21
+ const contents = (0, template_1.executeTemplate)(lines.join('\n'), replaces);
22
+ const p = path_1.default.join(realPath, fileName);
23
+ const file = await (0, promises_1.open)(p, 'a+');
24
+ if ((await file.stat()).size > 0) {
25
+ console.warn(`${p} already exists, not changing.`);
26
+ await file.close();
27
+ return;
28
+ }
29
+ await file.writeFile(contents);
30
+ await file.close();
31
+ }
32
+ async function createFiles(templatePath, realPath, replaces) {
33
+ const contents = await (0, promises_1.readdir)(templatePath);
34
+ for (const file of contents) {
35
+ const tp = path_1.default.join(templatePath, file);
36
+ const rp = path_1.default.join(realPath, file);
37
+ if ((await (0, promises_1.lstat)(tp)).isDirectory()) {
38
+ await createFiles(tp, rp, replaces);
39
+ }
40
+ else {
41
+ await (0, promises_1.mkdir)(path_1.default.dirname(rp), {
42
+ recursive: true,
43
+ });
44
+ await createFile(tp, realPath, replaces);
45
+ }
46
+ }
47
+ }
48
+ exports.templateTypes = [
49
+ {
50
+ name: 'An empty contract (FunC)',
51
+ value: 'func-empty',
52
+ },
53
+ {
54
+ name: 'A simple counter contract (FunC)',
55
+ value: 'func-counter',
56
+ },
57
+ {
58
+ name: 'An empty contract (TACT)',
59
+ value: 'tact-empty',
60
+ },
61
+ {
62
+ name: 'A simple counter contract (TACT)',
63
+ value: 'tact-counter',
64
+ },
65
+ ];
66
+ const create = async (args, ui) => {
67
+ const localArgs = (0, arg_1.default)({
68
+ '--type': String,
69
+ });
70
+ const name = args._.length > 1 && args._[1].trim().length > 0
71
+ ? args._[1].trim()
72
+ : await ui.input('Contract name (PascalCase)');
73
+ if (name.length === 0)
74
+ throw new Error(`Cannot create a contract with an empty name`);
75
+ if (name.toLowerCase() === 'contract' || !/^[A-Z][a-zA-Z0-9]*$/.test(name))
76
+ throw new Error(`Cannot create a contract with the name '${name}'`);
77
+ const which = (await (0, utils_1.selectOption)(exports.templateTypes, {
78
+ ui,
79
+ msg: 'What type of contract do you want to create?',
80
+ hint: localArgs['--type'],
81
+ })).value;
82
+ const [lang, template] = which.split('-');
83
+ const snakeName = toSnakeCase(name);
84
+ const replaces = {
85
+ name,
86
+ loweredName: name.substring(0, 1).toLowerCase() + name.substring(1),
87
+ snakeName,
88
+ contractPath: 'contracts/' + snakeName + '.' + (lang === 'func' ? 'fc' : 'tact'),
89
+ };
90
+ await createFiles(path_1.default.join(template_1.TEMPLATES_DIR, lang, 'common'), process.cwd(), replaces);
91
+ await createFiles(path_1.default.join(template_1.TEMPLATES_DIR, lang, template), process.cwd(), replaces);
92
+ if (lang === 'tact') {
93
+ await (0, build_1.buildOne)(name, ui);
94
+ }
95
+ };
96
+ exports.create = create;
@@ -0,0 +1,2 @@
1
+ import { Runner } from './cli';
2
+ export declare const help: Runner;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.help = 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
+ - help
17
+ - test`,
18
+ create: `Usage: blueprint create [contract name] [flags]
19
+
20
+ Creates a new contract together with supporting files according to a template.
21
+
22
+ 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.
23
+
24
+ Flags:
25
+ --type <type> - specifies the template type to use when creating the contract. If not specified on the command line, it will be asked interactively.
26
+ List of available types:
27
+ ${create_1.templateTypes.map((t) => `${t.value} - ${t.name}`).join('\n')}`,
28
+ run: `Usage: blueprint run [script name] [flags]
29
+
30
+ Runs a script from the scripts directory.
31
+
32
+ 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.
33
+
34
+ Flags:
35
+ --mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
36
+ --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.
37
+ --tonscan, --tonapi, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonscan.`,
38
+ build: `Usage: blueprint build [contract name] [flags]
39
+
40
+ 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.
41
+
42
+ 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.
43
+
44
+ Flags:
45
+ --all - builds all buildable contracts instead of just one.`,
46
+ test: `Usage: blueprint test
47
+
48
+ Just runs \`npm test\`, which by default runs \`jest\`.`,
49
+ };
50
+ const help = async (args, ui) => {
51
+ const cmd = args._.length >= 2 ? args._[1].toLowerCase() : '';
52
+ const helpMessage = cmd in helpMessages ? helpMessages[cmd] : helpMessages['help'];
53
+ ui.write(helpMessage);
54
+ };
55
+ exports.help = help;
@@ -0,0 +1,2 @@
1
+ import { Runner } from './cli';
2
+ export declare const run: Runner;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = void 0;
4
+ const createNetworkProvider_1 = require("../network/createNetworkProvider");
5
+ const utils_1 = require("../utils");
6
+ const run = async (args, ui) => {
7
+ require('ts-node/register');
8
+ const { module: mod } = await (0, utils_1.selectFile)(await (0, utils_1.findScripts)(), {
9
+ ui,
10
+ hint: args._.length > 1 && args._[1].length > 0 ? args._[1] : undefined,
11
+ });
12
+ if (typeof mod.run !== 'function') {
13
+ throw new Error('Function `run` is missing!');
14
+ }
15
+ const networkProvider = await (0, createNetworkProvider_1.createNetworkProvider)(ui);
16
+ await mod.run(networkProvider, args._.slice(2));
17
+ };
18
+ exports.run = run;
@@ -0,0 +1,2 @@
1
+ import { Runner } from './cli';
2
+ export declare const test: Runner;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.test = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const test = async () => {
6
+ require('ts-node/register');
7
+ (0, child_process_1.execSync)('npm test', { stdio: 'inherit' });
8
+ };
9
+ exports.test = test;
@@ -0,0 +1,21 @@
1
+ import { SourceResolver, SourcesMap, SourcesArray } from '@ton-community/func-js';
2
+ import { Cell } from 'ton-core';
3
+ export type CommonCompilerConfig = {
4
+ preCompileHook?: () => Promise<void>;
5
+ postCompileHook?: (code: Cell) => Promise<void>;
6
+ };
7
+ export type TactCompilerConfig = {
8
+ lang: 'tact';
9
+ target: string;
10
+ };
11
+ export type FuncCompilerConfig = {
12
+ lang?: 'func';
13
+ optLevel?: number;
14
+ } & ({
15
+ targets: string[];
16
+ sources?: SourceResolver | SourcesMap;
17
+ } | {
18
+ targets?: string[];
19
+ sources: SourcesArray;
20
+ });
21
+ export type CompilerConfig = (TactCompilerConfig | FuncCompilerConfig) & CommonCompilerConfig;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });