@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.
- package/CHANGELOG.md +146 -0
- package/README.md +114 -0
- package/dist/cli/build.d.ts +4 -0
- package/dist/cli/build.js +68 -0
- package/dist/cli/cli.d.ts +7 -0
- package/dist/cli/cli.js +106 -0
- package/dist/cli/create.d.ts +6 -0
- package/dist/cli/create.js +96 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.js +55 -0
- package/dist/cli/run.d.ts +2 -0
- package/dist/cli/run.js +18 -0
- package/dist/cli/test.d.ts +2 -0
- package/dist/cli/test.js +9 -0
- package/dist/compile/CompilerConfig.d.ts +21 -0
- package/dist/compile/CompilerConfig.js +2 -0
- package/dist/compile/OverwritableVirtualFileSystem.d.ts +10 -0
- package/dist/compile/OverwritableVirtualFileSystem.js +24 -0
- package/dist/compile/compile.d.ts +14 -0
- package/dist/compile/compile.js +115 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +10 -0
- package/dist/network/NetworkProvider.d.ts +22 -0
- package/dist/network/NetworkProvider.js +2 -0
- package/dist/network/createNetworkProvider.d.ts +3 -0
- package/dist/network/createNetworkProvider.js +282 -0
- package/dist/network/send/DeeplinkProvider.d.ts +10 -0
- package/dist/network/send/DeeplinkProvider.js +44 -0
- package/dist/network/send/MnemonicProvider.d.ts +19 -0
- package/dist/network/send/MnemonicProvider.js +80 -0
- package/dist/network/send/SendProvider.d.ts +6 -0
- package/dist/network/send/SendProvider.js +2 -0
- package/dist/network/send/TonConnectProvider.d.ts +12 -0
- package/dist/network/send/TonConnectProvider.js +108 -0
- package/dist/network/send/TonHubProvider.d.ts +16 -0
- package/dist/network/send/TonHubProvider.js +110 -0
- package/dist/network/storage/FSStorage.d.ts +8 -0
- package/dist/network/storage/FSStorage.js +53 -0
- package/dist/network/storage/Storage.d.ts +18 -0
- package/dist/network/storage/Storage.js +2 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.js +19 -0
- package/dist/template.d.ts +4 -0
- package/dist/template.js +15 -0
- package/dist/templates/func/common/wrappers/compile.ts.template +7 -0
- package/dist/templates/func/counter/contracts/contract.fc.template +72 -0
- package/dist/templates/func/counter/scripts/deploy.ts.template +22 -0
- package/dist/templates/func/counter/scripts/increment.ts.template +38 -0
- package/dist/templates/func/counter/tests/spec.ts.template +81 -0
- package/dist/templates/func/counter/wrappers/wrapper.ts.template +67 -0
- package/dist/templates/func/empty/contracts/contract.fc.template +6 -0
- package/dist/templates/func/empty/scripts/deploy.ts.template +14 -0
- package/dist/templates/func/empty/tests/spec.ts.template +39 -0
- package/dist/templates/func/empty/wrappers/wrapper.ts.template +30 -0
- package/dist/templates/tact/common/wrappers/compile.ts.template +7 -0
- package/dist/templates/tact/common/wrappers/wrapper.ts.template +2 -0
- package/dist/templates/tact/counter/contracts/contract.tact.template +29 -0
- package/dist/templates/tact/counter/scripts/deploy.ts.template +23 -0
- package/dist/templates/tact/counter/scripts/increment.ts.template +45 -0
- package/dist/templates/tact/counter/tests/spec.ts.template +82 -0
- package/dist/templates/tact/empty/contracts/contract.tact.template +8 -0
- package/dist/templates/tact/empty/scripts/deploy.ts.template +23 -0
- package/dist/templates/tact/empty/tests/spec.ts.template +41 -0
- package/dist/ui/InquirerUIProvider.d.ts +12 -0
- package/dist/ui/InquirerUIProvider.js +70 -0
- package/dist/ui/UIProvider.d.ts +8 -0
- package/dist/ui/UIProvider.js +2 -0
- package/dist/utils.d.ts +39 -0
- package/dist/utils.js +122 -0
- 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
|
+
|
|
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
|
+
|
|
36
|
+
|
|
37
|
+
## Create a new project
|
|
38
|
+
|
|
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`
|
|
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: `npx blueprint build` or `yarn blueprint build`
|
|
56
|
+
3. Non-interactive: `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: `npx blueprint test` or `yarn blueprint test`
|
|
63
|
+
2. Alternative method: `npm test` or `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: `npx blueprint run` or `yarn blueprint run`
|
|
69
|
+
3. Non-interactive: `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: `npx blueprint help` or `yarn blueprint help`
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
## Develop a new contract
|
|
79
|
+
|
|
80
|
+
1. Make sure you have a project to host the contract
|
|
81
|
+
2. Run interactive: `npx blueprint create` or `yarn blueprint create`
|
|
82
|
+
3. Non-interactive: `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
|
+
|
|
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,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;
|
package/dist/cli/cli.js
ADDED
|
@@ -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,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;
|
package/dist/cli/help.js
ADDED
|
@@ -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;
|
package/dist/cli/run.js
ADDED
|
@@ -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;
|
package/dist/cli/test.js
ADDED
|
@@ -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;
|