@ton/blueprint 0.12.1 → 0.14.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 +18 -0
- package/README.md +26 -4
- package/dist/build.d.ts +3 -0
- package/dist/build.js +57 -0
- package/dist/cli/Runner.d.ts +5 -0
- package/dist/cli/Runner.js +4 -0
- package/dist/cli/build.d.ts +6 -2
- package/dist/cli/build.js +12 -48
- package/dist/cli/cli.d.ts +0 -5
- package/dist/cli/cli.js +48 -4
- package/dist/cli/create.d.ts +1 -1
- package/dist/cli/create.js +1 -1
- package/dist/cli/help.d.ts +2 -1
- package/dist/cli/help.js +20 -4
- package/dist/cli/run.d.ts +1 -1
- package/dist/cli/run.js +0 -1
- package/dist/cli/test.d.ts +1 -1
- package/dist/cli/test.js +0 -1
- package/dist/cli/verify.d.ts +2 -0
- package/dist/cli/verify.js +179 -0
- package/dist/compile/compile.d.ts +4 -0
- package/dist/compile/compile.js +10 -1
- package/dist/config/Config.d.ts +4 -0
- package/dist/config/Config.js +2 -0
- package/dist/config/Plugin.d.ts +9 -0
- package/dist/config/Plugin.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -1
- package/dist/network/NetworkProvider.d.ts +3 -3
- package/dist/network/createNetworkProvider.d.ts +1 -1
- package/dist/network/createNetworkProvider.js +49 -12
- package/dist/network/send/MnemonicProvider.d.ts +2 -2
- package/dist/templates/func/counter/tests/spec.ts.template +2 -1
- package/dist/templates/func/empty/tests/spec.ts.template +2 -1
- package/dist/templates/tact/counter/tests/spec.ts.template +2 -1
- package/dist/templates/tact/empty/tests/spec.ts.template +2 -1
- package/dist/utils.js +2 -2
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,24 @@ 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.14.0] - 2023-11-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added `verify` command to quickly verify contracts on [verifier.ton.org](https://verifier.ton.org)
|
|
13
|
+
|
|
14
|
+
## [0.13.0] - 2023-11-05
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Added plugin support
|
|
19
|
+
- Added custom API v2 endpoints
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Improved docs
|
|
24
|
+
- Changed deployed contract explorer link to use tonviewer
|
|
25
|
+
- Moved `deployer` to the global `describe` context in default tests
|
|
8
26
|
|
|
9
27
|
## [0.12.1] - 2023-07-31
|
|
10
28
|
|
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ npm create ton@latest
|
|
|
30
30
|
### Requirements
|
|
31
31
|
|
|
32
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)
|
|
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/18541-ton-development)
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
|
|
@@ -49,11 +49,11 @@ npm create ton@latest
|
|
|
49
49
|
* `scripts/` - Deployment scripts to mainnet/testnet and other scripts interacting with live contracts
|
|
50
50
|
* `build/` - Compilation artifacts created here after running a build command
|
|
51
51
|
|
|
52
|
-
### Build
|
|
52
|
+
### Build contracts
|
|
53
53
|
|
|
54
54
|
1. You need a compilation script in `wrappers/<CONTRACT>.compile.ts` - [example](/example/wrappers/Counter.compile.ts)
|
|
55
55
|
2. Run interactive: `npx blueprint build` or `yarn blueprint build`
|
|
56
|
-
3. Non-interactive: `npx/yarn blueprint build <CONTRACT>`
|
|
56
|
+
3. Non-interactive: `npx/yarn blueprint build <CONTRACT>` OR build all contracts `yarn blueprint build --all`
|
|
57
57
|
* Example: `yarn blueprint build counter`
|
|
58
58
|
4. Build results are generated in `build/<CONTRACT>.compiled.json`
|
|
59
59
|
|
|
@@ -62,6 +62,8 @@ npm create ton@latest
|
|
|
62
62
|
1. Run in terminal: `npx blueprint test` or `yarn blueprint test`
|
|
63
63
|
2. Alternative method: `npm test` or `yarn test`
|
|
64
64
|
|
|
65
|
+
> Learn more about writing tests from the Sandbox's documentation - [here](https://github.com/ton-org/sandbox#writing-tests).
|
|
66
|
+
|
|
65
67
|
### Deploy one of the contracts
|
|
66
68
|
|
|
67
69
|
1. You need a deploy script in `scripts/deploy<CONTRACT>.ts` - [example](/example/scripts/deployCounter.ts)
|
|
@@ -93,13 +95,33 @@ Run in terminal: `npx blueprint help` or `yarn blueprint he
|
|
|
93
95
|
1. Implement TypeScript tests in `tests/<CONTRACT>.spec.ts`
|
|
94
96
|
2. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to interact with the contract
|
|
95
97
|
|
|
98
|
+
> Learn more about writing tests from the Sandbox's documentation - [here](https://github.com/ton-org/sandbox#writing-tests).
|
|
99
|
+
|
|
96
100
|
### Compilation and deployment
|
|
97
101
|
|
|
98
102
|
1. Implement a compilation script in `wrappers/<CONTRACT>.compile.ts`
|
|
99
103
|
2. Implement a deployment script in `scripts/deploy<CONTRACT>.ts`
|
|
100
104
|
3. Rely on the wrapper TypeScript class from `wrappers/<CONTRACT>.ts` to initialize the contract
|
|
101
105
|
|
|
102
|
-
|
|
106
|
+
## Plugins
|
|
107
|
+
|
|
108
|
+
Blueprint has a plugin system to allow the community to develop their own additions for the ecosystem without the need to change blueprint's code.
|
|
109
|
+
|
|
110
|
+
In order to use plugins, create a `blueprint.config.ts` file in the root of your project with something like this:
|
|
111
|
+
```typescript
|
|
112
|
+
import { Config } from '@ton/blueprint';
|
|
113
|
+
import { ScaffoldPlugin } from 'blueprint-scaffold';
|
|
114
|
+
|
|
115
|
+
export const config: Config = {
|
|
116
|
+
plugins: [new ScaffoldPlugin()],
|
|
117
|
+
};
|
|
118
|
+
```
|
|
119
|
+
(This example shows how to add the [scaffold](https://github.com/1IxI1/blueprint-scaffold) plugin)
|
|
120
|
+
|
|
121
|
+
It is important that the config is exported, is named `config`, and is not `default` exported.
|
|
122
|
+
|
|
123
|
+
Here are some of the plugins developed by the community:
|
|
124
|
+
- [scaffold](https://github.com/1IxI1/blueprint-scaffold) - allows developers to quickly create a simple dapp automatically using the wrappers' code
|
|
103
125
|
|
|
104
126
|
## Contributors
|
|
105
127
|
|
package/dist/build.d.ts
ADDED
package/dist/build.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
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.buildAll = exports.buildOne = void 0;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
9
|
+
const compile_1 = require("./compile/compile");
|
|
10
|
+
const paths_1 = require("./paths");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
async function buildOne(contract, ui) {
|
|
13
|
+
ui?.write(`Build script running, compiling ${contract}`);
|
|
14
|
+
const buildArtifactPath = path_1.default.join(paths_1.BUILD_DIR, `${contract}.compiled.json`);
|
|
15
|
+
try {
|
|
16
|
+
await promises_1.default.unlink(buildArtifactPath);
|
|
17
|
+
}
|
|
18
|
+
catch (e) { }
|
|
19
|
+
ui?.setActionPrompt('⏳ Compiling...');
|
|
20
|
+
try {
|
|
21
|
+
const result = await (0, compile_1.doCompile)(contract);
|
|
22
|
+
if (result.lang === 'tact') {
|
|
23
|
+
for (const [k, v] of result.fs) {
|
|
24
|
+
await promises_1.default.mkdir(path_1.default.dirname(k), {
|
|
25
|
+
recursive: true,
|
|
26
|
+
});
|
|
27
|
+
await promises_1.default.writeFile(k, v);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const cell = result.code;
|
|
31
|
+
ui?.clearActionPrompt();
|
|
32
|
+
ui?.write('\n✅ Compiled successfully! Cell BOC hex result:\n\n');
|
|
33
|
+
ui?.write(cell.toBoc().toString('hex'));
|
|
34
|
+
await promises_1.default.mkdir(paths_1.BUILD_DIR, { recursive: true });
|
|
35
|
+
await promises_1.default.writeFile(buildArtifactPath, JSON.stringify({
|
|
36
|
+
hex: cell.toBoc().toString('hex'),
|
|
37
|
+
}));
|
|
38
|
+
ui?.write(`\n✅ Wrote compilation artifact to ${path_1.default.relative(process.cwd(), buildArtifactPath)}`);
|
|
39
|
+
}
|
|
40
|
+
catch (e) {
|
|
41
|
+
if (ui) {
|
|
42
|
+
ui?.clearActionPrompt();
|
|
43
|
+
ui?.write(e.toString());
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
throw e;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.buildOne = buildOne;
|
|
52
|
+
async function buildAll(ui) {
|
|
53
|
+
for (const file of await (0, utils_1.findCompiles)()) {
|
|
54
|
+
await buildOne(file.name, ui);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.buildAll = buildAll;
|
package/dist/cli/build.d.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import { Runner } from './
|
|
1
|
+
import { Args, Runner } from './Runner';
|
|
2
2
|
import { UIProvider } from '../ui/UIProvider';
|
|
3
|
-
export declare function
|
|
3
|
+
export declare function selectCompile(ui: UIProvider, args: Args): Promise<{
|
|
4
|
+
module: any;
|
|
5
|
+
name: string;
|
|
6
|
+
path: string;
|
|
7
|
+
}>;
|
|
4
8
|
export declare const build: Runner;
|
package/dist/cli/build.js
CHANGED
|
@@ -3,64 +3,28 @@ 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.build = exports.
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const paths_1 = require("../paths");
|
|
6
|
+
exports.build = exports.selectCompile = void 0;
|
|
9
7
|
const utils_1 = require("../utils");
|
|
10
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
11
|
-
const compile_1 = require("../compile/compile");
|
|
12
8
|
const arg_1 = __importDefault(require("arg"));
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ui.write('⏳ Compiling...\n');
|
|
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.write('✅ Compiled successfully! Cell BOC hex result:\n\n');
|
|
33
|
-
ui.write(cell.toBoc().toString('hex'));
|
|
34
|
-
await promises_1.default.mkdir(paths_1.BUILD_DIR, { recursive: true });
|
|
35
|
-
await promises_1.default.writeFile(buildArtifactPath, JSON.stringify({
|
|
36
|
-
hex: cell.toBoc().toString('hex'),
|
|
37
|
-
}));
|
|
38
|
-
ui.write(`\n✅ Wrote compilation artifact to ${path_1.default.relative(process.cwd(), buildArtifactPath)}`);
|
|
39
|
-
}
|
|
40
|
-
catch (e) {
|
|
41
|
-
ui.write(e.toString());
|
|
42
|
-
process.exit(1);
|
|
43
|
-
}
|
|
9
|
+
const build_1 = require("../build");
|
|
10
|
+
async function selectCompile(ui, args) {
|
|
11
|
+
return await (0, utils_1.selectFile)(await (0, utils_1.findCompiles)(), {
|
|
12
|
+
ui,
|
|
13
|
+
hint: args._.length > 1 && args._[1].length > 0 ? args._[1] : undefined,
|
|
14
|
+
import: false,
|
|
15
|
+
});
|
|
44
16
|
}
|
|
45
|
-
exports.
|
|
17
|
+
exports.selectCompile = selectCompile;
|
|
46
18
|
const build = async (args, ui) => {
|
|
47
|
-
require('ts-node/register');
|
|
48
19
|
const localArgs = (0, arg_1.default)({
|
|
49
20
|
'--all': Boolean,
|
|
50
21
|
});
|
|
51
|
-
const files = await (0, utils_1.findCompiles)();
|
|
52
22
|
if (localArgs['--all']) {
|
|
53
|
-
|
|
54
|
-
await buildOne(file.name, ui);
|
|
55
|
-
}
|
|
23
|
+
await (0, build_1.buildAll)();
|
|
56
24
|
}
|
|
57
25
|
else {
|
|
58
|
-
const sel = await (
|
|
59
|
-
|
|
60
|
-
hint: args._.length > 1 && args._[1].length > 0 ? args._[1] : undefined,
|
|
61
|
-
import: false,
|
|
62
|
-
});
|
|
63
|
-
await buildOne(sel.name, ui);
|
|
26
|
+
const sel = await selectCompile(ui, args);
|
|
27
|
+
await (0, build_1.buildOne)(sel.name, ui);
|
|
64
28
|
}
|
|
65
29
|
};
|
|
66
30
|
exports.build = build;
|
package/dist/cli/cli.d.ts
CHANGED
package/dist/cli/cli.js
CHANGED
|
@@ -35,33 +35,77 @@ const create_1 = require("./create");
|
|
|
35
35
|
const run_1 = require("./run");
|
|
36
36
|
const build_1 = require("./build");
|
|
37
37
|
const test_1 = require("./test");
|
|
38
|
+
const verify_1 = require("./verify");
|
|
38
39
|
const help_1 = require("./help");
|
|
39
40
|
const InquirerUIProvider_1 = require("../ui/InquirerUIProvider");
|
|
40
|
-
const
|
|
41
|
+
const Runner_1 = require("./Runner");
|
|
42
|
+
const path_1 = __importDefault(require("path"));
|
|
41
43
|
const runners = {
|
|
42
44
|
create: create_1.create,
|
|
43
45
|
run: run_1.run,
|
|
44
46
|
build: build_1.build,
|
|
45
47
|
test: test_1.test,
|
|
46
48
|
help: help_1.help,
|
|
49
|
+
verify: verify_1.verify,
|
|
47
50
|
};
|
|
48
51
|
async function main() {
|
|
49
|
-
|
|
52
|
+
var _a;
|
|
53
|
+
require('ts-node/register');
|
|
54
|
+
const args = (0, arg_1.default)(Runner_1.argSpec, {
|
|
50
55
|
permissive: true,
|
|
51
56
|
});
|
|
52
57
|
if (args._.length === 0) {
|
|
53
58
|
showHelp();
|
|
54
59
|
process.exit(0);
|
|
55
60
|
}
|
|
56
|
-
|
|
61
|
+
let effectiveRunners = {};
|
|
62
|
+
try {
|
|
63
|
+
const configModule = await (_a = path_1.default.join(process.cwd(), 'blueprint.config.ts'), Promise.resolve().then(() => __importStar(require(_a))));
|
|
64
|
+
try {
|
|
65
|
+
if ('config' in configModule && typeof configModule.config === 'object') {
|
|
66
|
+
const config = configModule.config;
|
|
67
|
+
for (const plugin of config.plugins) {
|
|
68
|
+
for (const runner of plugin.runners()) {
|
|
69
|
+
effectiveRunners[runner.name] = runner.runner;
|
|
70
|
+
help_1.additionalHelpMessages[runner.name] = runner.help;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch (e) {
|
|
76
|
+
// if plugin.runners() throws
|
|
77
|
+
console.error('Could not load one or more plugins');
|
|
78
|
+
console.error(e);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
// no config
|
|
83
|
+
}
|
|
84
|
+
effectiveRunners = {
|
|
85
|
+
...effectiveRunners,
|
|
86
|
+
...runners,
|
|
87
|
+
};
|
|
88
|
+
const runner = effectiveRunners[args._[0]];
|
|
57
89
|
if (!runner) {
|
|
58
90
|
console.log(chalk_1.default.redBright(` Error: command not found.`) + ` Run 'blueprint help' to see available commands\n`);
|
|
59
91
|
process.exit(1);
|
|
60
92
|
}
|
|
61
93
|
const ui = new InquirerUIProvider_1.InquirerUIProvider();
|
|
94
|
+
const waitingForCustomLink = args._.includes('--custom');
|
|
62
95
|
await runner({
|
|
63
96
|
...args,
|
|
64
|
-
_: args._.filter((a) =>
|
|
97
|
+
_: args._.filter((a, inx) => {
|
|
98
|
+
// filter out the flags
|
|
99
|
+
if (a.length > 1 && a[0] === '-')
|
|
100
|
+
return false;
|
|
101
|
+
// and endpoint urls
|
|
102
|
+
if (waitingForCustomLink) {
|
|
103
|
+
if (args._[inx - 1] === '--custom' && // url goes after --custom
|
|
104
|
+
a.startsWith('http'))
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
return true;
|
|
108
|
+
}),
|
|
65
109
|
}, ui);
|
|
66
110
|
ui.close();
|
|
67
111
|
}
|
package/dist/cli/create.d.ts
CHANGED
package/dist/cli/create.js
CHANGED
|
@@ -9,7 +9,7 @@ const path_1 = __importDefault(require("path"));
|
|
|
9
9
|
const template_1 = require("../template");
|
|
10
10
|
const utils_1 = require("../utils");
|
|
11
11
|
const arg_1 = __importDefault(require("arg"));
|
|
12
|
-
const build_1 = require("
|
|
12
|
+
const build_1 = require("../build");
|
|
13
13
|
function toSnakeCase(v) {
|
|
14
14
|
const r = v.replace(/[A-Z]/g, (sub) => '_' + sub.toLowerCase());
|
|
15
15
|
return r[0] === '_' ? r.substring(1) : r;
|
package/dist/cli/help.d.ts
CHANGED
package/dist/cli/help.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.help = void 0;
|
|
3
|
+
exports.help = exports.additionalHelpMessages = void 0;
|
|
4
4
|
const create_1 = require("./create");
|
|
5
5
|
const helpMessages = {
|
|
6
6
|
help: `Usage: blueprint help [command]
|
|
@@ -14,7 +14,8 @@ List of available commands:
|
|
|
14
14
|
- run
|
|
15
15
|
- build
|
|
16
16
|
- help
|
|
17
|
-
- test
|
|
17
|
+
- test
|
|
18
|
+
- verify`,
|
|
18
19
|
create: `Usage: blueprint create [contract name] [flags]
|
|
19
20
|
|
|
20
21
|
Creates a new contract together with supporting files according to a template.
|
|
@@ -33,8 +34,9 @@ Script name is matched (ignoring case) to a file in the scripts directory. If no
|
|
|
33
34
|
|
|
34
35
|
Flags:
|
|
35
36
|
--mainnet, --testnet - specifies the network to use when running the script. If not specified on the command line, it will be asked interactively.
|
|
37
|
+
--custom [api-v2-endpoint] - indicates that a custom API should be used when running the script, and the API URL optionally.
|
|
36
38
|
--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, --
|
|
39
|
+
--tonscan, --tonviewer, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonscan.`,
|
|
38
40
|
build: `Usage: blueprint build [contract name] [flags]
|
|
39
41
|
|
|
40
42
|
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.
|
|
@@ -46,10 +48,24 @@ Flags:
|
|
|
46
48
|
test: `Usage: blueprint test
|
|
47
49
|
|
|
48
50
|
Just runs \`npm test\`, which by default runs \`jest\`.`,
|
|
51
|
+
verify: `Usage: blueprint verify [contract name] [flags]
|
|
52
|
+
|
|
53
|
+
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.
|
|
54
|
+
|
|
55
|
+
Flags:
|
|
56
|
+
--mainnet, --testnet - specifies the network on which to verify the contract. If not specified on the command line, it will be asked interactively.`
|
|
49
57
|
};
|
|
58
|
+
exports.additionalHelpMessages = {};
|
|
50
59
|
const help = async (args, ui) => {
|
|
51
60
|
const cmd = args._.length >= 2 ? args._[1].toLowerCase() : '';
|
|
52
|
-
const
|
|
61
|
+
const effectiveHelpMessages = {
|
|
62
|
+
...exports.additionalHelpMessages,
|
|
63
|
+
...helpMessages,
|
|
64
|
+
};
|
|
65
|
+
for (const k in exports.additionalHelpMessages) {
|
|
66
|
+
effectiveHelpMessages.help += '\n- ' + k;
|
|
67
|
+
}
|
|
68
|
+
const helpMessage = cmd in effectiveHelpMessages ? effectiveHelpMessages[cmd] : effectiveHelpMessages['help'];
|
|
53
69
|
ui.write(helpMessage);
|
|
54
70
|
};
|
|
55
71
|
exports.help = help;
|
package/dist/cli/run.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Runner } from './
|
|
1
|
+
import { Runner } from './Runner';
|
|
2
2
|
export declare const run: Runner;
|
package/dist/cli/run.js
CHANGED
|
@@ -4,7 +4,6 @@ exports.run = void 0;
|
|
|
4
4
|
const createNetworkProvider_1 = require("../network/createNetworkProvider");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
const run = async (args, ui) => {
|
|
7
|
-
require('ts-node/register');
|
|
8
7
|
const { module: mod } = await (0, utils_1.selectFile)(await (0, utils_1.findScripts)(), {
|
|
9
8
|
ui,
|
|
10
9
|
hint: args._.length > 1 && args._[1].length > 0 ? args._[1] : undefined,
|
package/dist/cli/test.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Runner } from './
|
|
1
|
+
import { Runner } from './Runner';
|
|
2
2
|
export declare const test: Runner;
|
package/dist/cli/test.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.test = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const test = async () => {
|
|
6
|
-
require('ts-node/register');
|
|
7
6
|
(0, child_process_1.execSync)('npm test', { stdio: 'inherit' });
|
|
8
7
|
};
|
|
9
8
|
exports.test = test;
|
|
@@ -0,0 +1,179 @@
|
|
|
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.verify = void 0;
|
|
7
|
+
const core_1 = require("@ton/core");
|
|
8
|
+
const compile_1 = require("../compile/compile");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const createNetworkProvider_1 = require("../network/createNetworkProvider");
|
|
11
|
+
const build_1 = require("./build");
|
|
12
|
+
const backends = {
|
|
13
|
+
mainnet: {
|
|
14
|
+
verifierRegistry: core_1.Address.parse('EQDS0AW7NV1w3nFwx-mmryfpH4OGQ3PXnoFGOJA_8PTHuLrw'),
|
|
15
|
+
backends: [
|
|
16
|
+
'https://ton-source-prod-1.herokuapp.com',
|
|
17
|
+
'https://ton-source-prod-2.herokuapp.com',
|
|
18
|
+
'https://ton-source-prod-3.herokuapp.com',
|
|
19
|
+
],
|
|
20
|
+
id: 'orbs.com',
|
|
21
|
+
},
|
|
22
|
+
testnet: {
|
|
23
|
+
verifierRegistry: core_1.Address.parse('EQB--CRXUbqYbqJKScEWeOrnk0TKJxB071M-WwvMpMEvq6Ed'),
|
|
24
|
+
backends: ['https://ton-source-prod-testnet-1.herokuapp.com'],
|
|
25
|
+
id: 'orbs-testnet',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
function removeRandom(els) {
|
|
29
|
+
return els.splice(Math.floor(Math.random() * els.length), 1)[0];
|
|
30
|
+
}
|
|
31
|
+
class VerifierRegistry {
|
|
32
|
+
constructor(address) {
|
|
33
|
+
this.address = address;
|
|
34
|
+
}
|
|
35
|
+
async getVerifiers(provider) {
|
|
36
|
+
const res = await provider.get('get_verifiers', []);
|
|
37
|
+
const item = res.stack.readCell();
|
|
38
|
+
const c = item.beginParse();
|
|
39
|
+
const d = c.loadDict(core_1.Dictionary.Keys.BigUint(256), {
|
|
40
|
+
serialize: () => {
|
|
41
|
+
throw undefined;
|
|
42
|
+
},
|
|
43
|
+
parse: (s) => s,
|
|
44
|
+
});
|
|
45
|
+
return Array.from(d.values()).map((v) => {
|
|
46
|
+
const admin = v.loadAddress();
|
|
47
|
+
const quorom = v.loadUint(8);
|
|
48
|
+
const pubKeyEndpoints = v.loadDict(core_1.Dictionary.Keys.BigUint(256), core_1.Dictionary.Values.Uint(32));
|
|
49
|
+
return {
|
|
50
|
+
admin: admin,
|
|
51
|
+
quorum: quorom,
|
|
52
|
+
pubKeyEndpoints: new Map(Array.from(pubKeyEndpoints).map(([k, v]) => [k, v])),
|
|
53
|
+
name: v.loadRef().beginParse().loadStringTail(),
|
|
54
|
+
url: v.loadRef().beginParse().loadStringTail(),
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const verify = async (args, ui) => {
|
|
60
|
+
const sel = await (0, build_1.selectCompile)(ui, args);
|
|
61
|
+
const networkProvider = await (0, createNetworkProvider_1.createNetworkProvider)(ui, false);
|
|
62
|
+
const sender = networkProvider.sender();
|
|
63
|
+
const senderAddress = sender.address;
|
|
64
|
+
if (senderAddress === undefined) {
|
|
65
|
+
throw new Error('Sender address needs to be known');
|
|
66
|
+
}
|
|
67
|
+
const network = networkProvider.network();
|
|
68
|
+
if (network === 'custom') {
|
|
69
|
+
throw new Error('Cannot use custom network');
|
|
70
|
+
}
|
|
71
|
+
const addr = await ui.input('Deployed contract address');
|
|
72
|
+
const result = await (0, compile_1.doCompile)(sel.name);
|
|
73
|
+
let src;
|
|
74
|
+
const fd = new FormData();
|
|
75
|
+
if (result.lang === 'func') {
|
|
76
|
+
for (const f of result.snapshot) {
|
|
77
|
+
fd.append(f.filename, new Blob([f.content]), path_1.default.basename(f.filename));
|
|
78
|
+
}
|
|
79
|
+
src = {
|
|
80
|
+
compiler: 'func',
|
|
81
|
+
compilerSettings: {
|
|
82
|
+
funcVersion: result.version,
|
|
83
|
+
commandLine: '-SPA ' + result.targets.join(' '),
|
|
84
|
+
},
|
|
85
|
+
knownContractAddress: addr,
|
|
86
|
+
knownContractHash: result.code.hash().toString('base64'),
|
|
87
|
+
sources: result.snapshot.map((s) => ({
|
|
88
|
+
includeInCommand: result.targets.includes(s.filename),
|
|
89
|
+
isEntrypoint: result.targets.includes(s.filename),
|
|
90
|
+
isStdLib: false,
|
|
91
|
+
hasIncludeDirectives: true,
|
|
92
|
+
folder: path_1.default.dirname(s.filename),
|
|
93
|
+
})),
|
|
94
|
+
senderAddress: senderAddress.toString(),
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
else if (result.lang === 'tact') {
|
|
98
|
+
let pkg = undefined;
|
|
99
|
+
for (const [k, v] of result.fs) {
|
|
100
|
+
if (k.endsWith('.pkg')) {
|
|
101
|
+
pkg = {
|
|
102
|
+
name: k,
|
|
103
|
+
content: v,
|
|
104
|
+
};
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (pkg === undefined) {
|
|
109
|
+
throw new Error('Could not find .pkg in compilation results');
|
|
110
|
+
}
|
|
111
|
+
fd.append(path_1.default.basename(pkg.name), new Blob([pkg.content]), path_1.default.basename(pkg.name));
|
|
112
|
+
src = {
|
|
113
|
+
compiler: 'tact',
|
|
114
|
+
compilerSettings: {
|
|
115
|
+
tactVersion: '',
|
|
116
|
+
},
|
|
117
|
+
knownContractAddress: addr,
|
|
118
|
+
knownContractHash: result.code.hash().toString('base64'),
|
|
119
|
+
sources: [
|
|
120
|
+
{
|
|
121
|
+
includeInCommand: true,
|
|
122
|
+
isEntrypoint: false,
|
|
123
|
+
isStdLib: false,
|
|
124
|
+
hasIncludeDirectives: false,
|
|
125
|
+
folder: '',
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
senderAddress: senderAddress.toString(),
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
// future proofing
|
|
133
|
+
throw new Error('Unsupported language ' + result.lang);
|
|
134
|
+
}
|
|
135
|
+
fd.append('json', new Blob([JSON.stringify(src)], {
|
|
136
|
+
type: 'application/json',
|
|
137
|
+
}), 'blob');
|
|
138
|
+
const backend = backends[network];
|
|
139
|
+
const verifierRegistry = networkProvider.open(new VerifierRegistry(backend.verifierRegistry));
|
|
140
|
+
const verifier = (await verifierRegistry.getVerifiers()).find((v) => v.name === backend.id);
|
|
141
|
+
if (verifier === undefined) {
|
|
142
|
+
throw new Error('Could not find verifier');
|
|
143
|
+
}
|
|
144
|
+
const remainingBackends = [...backend.backends];
|
|
145
|
+
const sourceResponse = await fetch(removeRandom(remainingBackends) + '/source', {
|
|
146
|
+
method: 'POST',
|
|
147
|
+
body: fd,
|
|
148
|
+
});
|
|
149
|
+
if (sourceResponse.status !== 200) {
|
|
150
|
+
throw new Error('Could not compile on backend:\n' + (await sourceResponse.text()));
|
|
151
|
+
}
|
|
152
|
+
const sourceResult = await sourceResponse.json();
|
|
153
|
+
if (sourceResult.compileResult.result !== 'similar') {
|
|
154
|
+
throw new Error('The code is not similar');
|
|
155
|
+
}
|
|
156
|
+
let msgCell = sourceResult.msgCell;
|
|
157
|
+
let acquiredSigs = 1;
|
|
158
|
+
while (acquiredSigs < verifier.quorum) {
|
|
159
|
+
const signResponse = await fetch(removeRandom(remainingBackends) + '/sign', {
|
|
160
|
+
method: 'POST',
|
|
161
|
+
body: JSON.stringify({
|
|
162
|
+
messageCell: msgCell,
|
|
163
|
+
}),
|
|
164
|
+
});
|
|
165
|
+
if (signResponse.status !== 200) {
|
|
166
|
+
throw new Error('Could not compile on backend:\n' + (await signResponse.text()));
|
|
167
|
+
}
|
|
168
|
+
const signResult = await signResponse.json();
|
|
169
|
+
msgCell = signResult.msgCell;
|
|
170
|
+
acquiredSigs++;
|
|
171
|
+
}
|
|
172
|
+
const c = core_1.Cell.fromBoc(Buffer.from(msgCell.data))[0];
|
|
173
|
+
await networkProvider.sender().send({
|
|
174
|
+
to: backend.verifierRegistry,
|
|
175
|
+
value: (0, core_1.toNano)('0.5'),
|
|
176
|
+
body: c,
|
|
177
|
+
});
|
|
178
|
+
};
|
|
179
|
+
exports.verify = verify;
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { SourcesArray } from '@ton-community/func-js';
|
|
2
3
|
import { Cell } from '@ton/core';
|
|
3
4
|
export type FuncCompileResult = {
|
|
4
5
|
lang: 'func';
|
|
5
6
|
code: Cell;
|
|
7
|
+
targets: string[];
|
|
8
|
+
snapshot: SourcesArray;
|
|
9
|
+
version: string;
|
|
6
10
|
};
|
|
7
11
|
export type TactCompileResult = {
|
|
8
12
|
lang: 'tact';
|
package/dist/compile/compile.js
CHANGED
|
@@ -36,7 +36,6 @@ const compiler_1 = require("@tact-lang/compiler");
|
|
|
36
36
|
const OverwritableVirtualFileSystem_1 = require("./OverwritableVirtualFileSystem");
|
|
37
37
|
async function getCompilerConfigForContract(name) {
|
|
38
38
|
var _a;
|
|
39
|
-
require('ts-node/register');
|
|
40
39
|
const mod = await (_a = path_1.default.join(paths_1.WRAPPERS_DIR, name + '.compile.ts'), Promise.resolve().then(() => __importStar(require(_a))));
|
|
41
40
|
if (typeof mod.compile !== 'object') {
|
|
42
41
|
throw new Error(`Object 'compile' is missing`);
|
|
@@ -47,9 +46,19 @@ async function doCompileFunc(config) {
|
|
|
47
46
|
const cr = await (0, func_js_1.compileFunc)(config);
|
|
48
47
|
if (cr.status === 'error')
|
|
49
48
|
throw new Error(cr.message);
|
|
49
|
+
let targets = [];
|
|
50
|
+
if (config.targets) {
|
|
51
|
+
targets = config.targets;
|
|
52
|
+
}
|
|
53
|
+
else if (Array.isArray(config.sources)) {
|
|
54
|
+
targets = config.sources.map((s) => s.filename);
|
|
55
|
+
}
|
|
50
56
|
return {
|
|
51
57
|
lang: 'func',
|
|
52
58
|
code: core_1.Cell.fromBase64(cr.codeBoc),
|
|
59
|
+
targets,
|
|
60
|
+
snapshot: cr.snapshot,
|
|
61
|
+
version: (await (0, func_js_1.compilerVersion)()).funcVersion,
|
|
53
62
|
};
|
|
54
63
|
}
|
|
55
64
|
function findTactBoc(fs) {
|
package/dist/index.d.ts
CHANGED
|
@@ -4,3 +4,7 @@ export { createNetworkProvider } from './network/createNetworkProvider';
|
|
|
4
4
|
export { compile } from './compile/compile';
|
|
5
5
|
export { CompilerConfig } from './compile/CompilerConfig';
|
|
6
6
|
export { UIProvider } from './ui/UIProvider';
|
|
7
|
+
export { Config } from './config/Config';
|
|
8
|
+
export { Args, Runner } from './cli/Runner';
|
|
9
|
+
export { PluginRunner, Plugin } from './config/Plugin';
|
|
10
|
+
export { buildOne, buildAll } from './build';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compile = exports.createNetworkProvider = exports.sleep = exports.tonDeepLink = void 0;
|
|
3
|
+
exports.buildAll = exports.buildOne = 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,3 +8,6 @@ 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
|
+
var build_1 = require("./build");
|
|
12
|
+
Object.defineProperty(exports, "buildOne", { enumerable: true, get: function () { return build_1.buildOne; } });
|
|
13
|
+
Object.defineProperty(exports, "buildAll", { enumerable: true, get: function () { return build_1.buildAll; } });
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { TonClient4 } from '@ton/ton';
|
|
1
|
+
import { TonClient, TonClient4 } from '@ton/ton';
|
|
2
2
|
import { Address, Cell, Contract, ContractProvider, OpenedContract, Sender } from '@ton/core';
|
|
3
3
|
import { UIProvider } from '../ui/UIProvider';
|
|
4
4
|
export interface NetworkProvider {
|
|
5
|
-
network(): 'mainnet' | 'testnet';
|
|
5
|
+
network(): 'mainnet' | 'testnet' | 'custom';
|
|
6
6
|
sender(): Sender;
|
|
7
|
-
api(): TonClient4;
|
|
7
|
+
api(): TonClient4 | TonClient;
|
|
8
8
|
provider(address: Address, init?: {
|
|
9
9
|
code?: Cell;
|
|
10
10
|
data?: Cell;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { UIProvider } from '../ui/UIProvider';
|
|
2
2
|
import { NetworkProvider } from './NetworkProvider';
|
|
3
|
-
export declare function createNetworkProvider(ui: UIProvider): Promise<NetworkProvider>;
|
|
3
|
+
export declare function createNetworkProvider(ui: UIProvider, allowCustom?: boolean): Promise<NetworkProvider>;
|
|
@@ -32,12 +32,13 @@ const MnemonicProvider_1 = require("./send/MnemonicProvider");
|
|
|
32
32
|
const argSpec = {
|
|
33
33
|
'--mainnet': Boolean,
|
|
34
34
|
'--testnet': Boolean,
|
|
35
|
+
'--custom': String,
|
|
35
36
|
'--tonconnect': Boolean,
|
|
36
37
|
'--deeplink': Boolean,
|
|
37
38
|
'--tonhub': Boolean,
|
|
38
39
|
'--mnemonic': Boolean,
|
|
39
40
|
'--tonscan': Boolean,
|
|
40
|
-
'--
|
|
41
|
+
'--tonviewer': Boolean,
|
|
41
42
|
'--toncx': Boolean,
|
|
42
43
|
'--dton': Boolean,
|
|
43
44
|
};
|
|
@@ -52,7 +53,7 @@ class SendProviderSender {
|
|
|
52
53
|
console.warn("Warning: blueprint's Sender does not support `bounce` flag, because it is ignored by all used Sender APIs");
|
|
53
54
|
console.warn('To silence this warning, change your `bounce` flags passed to Senders to unset or undefined');
|
|
54
55
|
}
|
|
55
|
-
if (!(args.sendMode === undefined || args.sendMode
|
|
56
|
+
if (!(args.sendMode === undefined || args.sendMode === core_1.SendMode.PAY_GAS_SEPARATELY)) {
|
|
56
57
|
throw new Error('Deployer sender does not support `sendMode` other than `PAY_GAS_SEPARATELY`');
|
|
57
58
|
}
|
|
58
59
|
await __classPrivateFieldGet(this, _SendProviderSender_provider, "f").sendTransaction(args.to, args.value, args.body ?? undefined, args.init ?? undefined);
|
|
@@ -116,10 +117,20 @@ class NetworkProviderImpl {
|
|
|
116
117
|
return __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f");
|
|
117
118
|
}
|
|
118
119
|
provider(address, init) {
|
|
119
|
-
|
|
120
|
+
if (__classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f") instanceof ton_1.TonClient4) {
|
|
121
|
+
return new WrappedContractProvider(address, __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").provider(address, init ? { code: init.code ?? new core_1.Cell(), data: init.data ?? new core_1.Cell() } : undefined), init);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
return new WrappedContractProvider(address, __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").provider(address, { code: init?.code ?? new core_1.Cell(), data: init?.data ?? new core_1.Cell() }), init);
|
|
125
|
+
}
|
|
120
126
|
}
|
|
121
127
|
async isContractDeployed(address) {
|
|
122
|
-
|
|
128
|
+
if (__classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f") instanceof ton_1.TonClient4) {
|
|
129
|
+
return __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").isContractDeployed((await __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").getLastBlock()).last.seqno, address);
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
return (await __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").getContractState(address)).state === 'active';
|
|
133
|
+
}
|
|
123
134
|
}
|
|
124
135
|
async waitForDeploy(address, attempts = 10, sleepDuration = 2000) {
|
|
125
136
|
if (attempts <= 0) {
|
|
@@ -185,24 +196,40 @@ async function createMnemonicProvider(client, ui) {
|
|
|
185
196
|
});
|
|
186
197
|
}
|
|
187
198
|
class NetworkProviderBuilder {
|
|
188
|
-
constructor(args, ui) {
|
|
199
|
+
constructor(args, ui, allowCustom = true) {
|
|
189
200
|
this.args = args;
|
|
190
201
|
this.ui = ui;
|
|
202
|
+
this.allowCustom = allowCustom;
|
|
191
203
|
}
|
|
192
204
|
async chooseNetwork() {
|
|
193
205
|
let network = (0, utils_1.oneOrZeroOf)({
|
|
194
206
|
mainnet: this.args['--mainnet'],
|
|
195
207
|
testnet: this.args['--testnet'],
|
|
208
|
+
custom: this.args['--custom'] !== undefined,
|
|
196
209
|
});
|
|
197
210
|
if (!network) {
|
|
198
|
-
|
|
211
|
+
let nets = ['mainnet', 'testnet'];
|
|
212
|
+
if (this.allowCustom) {
|
|
213
|
+
nets = ['mainnet', 'testnet', 'custom'];
|
|
214
|
+
}
|
|
215
|
+
network = await this.ui.choose('Which network do you want to use?', nets, (c) => c);
|
|
216
|
+
if (network === 'custom') {
|
|
217
|
+
const defaultCustomEndpoint = 'http://localhost:8081/';
|
|
218
|
+
this.args['--custom'] = (await this.ui.input(`Provide a custom API v2 endpoint (default is ${defaultCustomEndpoint})`)).trim();
|
|
219
|
+
if (this.args['--custom'] === '')
|
|
220
|
+
this.args['--custom'] = defaultCustomEndpoint;
|
|
221
|
+
this.args['--custom'] += 'jsonRPC';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (network === 'custom' && !this.allowCustom) {
|
|
225
|
+
throw new Error('Custom network is not allowed');
|
|
199
226
|
}
|
|
200
227
|
return network;
|
|
201
228
|
}
|
|
202
229
|
chooseExplorer() {
|
|
203
230
|
return ((0, utils_1.oneOrZeroOf)({
|
|
204
231
|
tonscan: this.args['--tonscan'],
|
|
205
|
-
|
|
232
|
+
tonviewer: this.args['--tonviewer'],
|
|
206
233
|
toncx: this.args['--toncx'],
|
|
207
234
|
dton: this.args['--dton'],
|
|
208
235
|
}) ?? 'tonscan');
|
|
@@ -241,9 +268,13 @@ class NetworkProviderBuilder {
|
|
|
241
268
|
provider = new DeeplinkProvider_1.DeeplinkProvider(this.ui);
|
|
242
269
|
break;
|
|
243
270
|
case 'tonconnect':
|
|
271
|
+
if (network === 'custom')
|
|
272
|
+
throw new Error('Tonkeeper cannot work with custom network.');
|
|
244
273
|
provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui);
|
|
245
274
|
break;
|
|
246
275
|
case 'tonhub':
|
|
276
|
+
if (network === 'custom')
|
|
277
|
+
throw new Error('TonHub cannot work with custom network.');
|
|
247
278
|
provider = new TonHubProvider_1.TonHubProvider(network, new FSStorage_1.FSStorage(storagePath), this.ui);
|
|
248
279
|
break;
|
|
249
280
|
case 'mnemonic':
|
|
@@ -257,9 +288,15 @@ class NetworkProviderBuilder {
|
|
|
257
288
|
async build() {
|
|
258
289
|
const network = await this.chooseNetwork();
|
|
259
290
|
const explorer = this.chooseExplorer();
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
291
|
+
let tc;
|
|
292
|
+
if (network === 'custom') {
|
|
293
|
+
tc = new ton_1.TonClient({ endpoint: this.args['--custom'] });
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
tc = new ton_1.TonClient4({
|
|
297
|
+
endpoint: await (0, ton_access_1.getHttpV4Endpoint)({ network }),
|
|
298
|
+
});
|
|
299
|
+
}
|
|
263
300
|
const sendProvider = await this.chooseSendProvider(network, tc);
|
|
264
301
|
try {
|
|
265
302
|
await sendProvider.connect();
|
|
@@ -275,8 +312,8 @@ class NetworkProviderBuilder {
|
|
|
275
312
|
return new NetworkProviderImpl(tc, sender, network, explorer, this.ui);
|
|
276
313
|
}
|
|
277
314
|
}
|
|
278
|
-
async function createNetworkProvider(ui) {
|
|
315
|
+
async function createNetworkProvider(ui, allowCustom = true) {
|
|
279
316
|
const args = (0, arg_1.default)(argSpec);
|
|
280
|
-
return await new NetworkProviderBuilder(args, ui).build();
|
|
317
|
+
return await new NetworkProviderBuilder(args, ui, allowCustom).build();
|
|
281
318
|
}
|
|
282
319
|
exports.createNetworkProvider = createNetworkProvider;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { TonClient4 } from '@ton/ton';
|
|
2
|
+
import { TonClient, TonClient4 } from '@ton/ton';
|
|
3
3
|
import { Address, Cell, StateInit } from '@ton/core';
|
|
4
4
|
import { SendProvider } from './SendProvider';
|
|
5
5
|
import { UIProvider } from '../../ui/UIProvider';
|
|
@@ -10,7 +10,7 @@ export declare class MnemonicProvider implements SendProvider {
|
|
|
10
10
|
version: WalletVersion;
|
|
11
11
|
workchain?: number;
|
|
12
12
|
secretKey: Buffer;
|
|
13
|
-
client: TonClient4;
|
|
13
|
+
client: TonClient4 | TonClient;
|
|
14
14
|
ui: UIProvider;
|
|
15
15
|
});
|
|
16
16
|
connect(): Promise<void>;
|
|
@@ -13,6 +13,7 @@ describe('{{name}}', () => {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
let blockchain: Blockchain;
|
|
16
|
+
let deployer: SandboxContract<TreasuryContract>;
|
|
16
17
|
let {{loweredName}}: SandboxContract<{{name}}>;
|
|
17
18
|
|
|
18
19
|
beforeEach(async () => {
|
|
@@ -28,7 +29,7 @@ describe('{{name}}', () => {
|
|
|
28
29
|
)
|
|
29
30
|
);
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
deployer = await blockchain.treasury('deployer');
|
|
32
33
|
|
|
33
34
|
const deployResult = await {{loweredName}}.sendDeploy(deployer.getSender(), toNano('0.05'));
|
|
34
35
|
|
|
@@ -13,6 +13,7 @@ describe('{{name}}', () => {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
let blockchain: Blockchain;
|
|
16
|
+
let deployer: SandboxContract<TreasuryContract>;
|
|
16
17
|
let {{loweredName}}: SandboxContract<{{name}}>;
|
|
17
18
|
|
|
18
19
|
beforeEach(async () => {
|
|
@@ -20,7 +21,7 @@ describe('{{name}}', () => {
|
|
|
20
21
|
|
|
21
22
|
{{loweredName}} = blockchain.openContract({{name}}.createFromConfig({}, code));
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
deployer = await blockchain.treasury('deployer');
|
|
24
25
|
|
|
25
26
|
const deployResult = await {{loweredName}}.sendDeploy(deployer.getSender(), toNano('0.05'));
|
|
26
27
|
|
|
@@ -6,6 +6,7 @@ import '@ton/test-utils';
|
|
|
6
6
|
|
|
7
7
|
describe('{{name}}', () => {
|
|
8
8
|
let blockchain: Blockchain;
|
|
9
|
+
let deployer: SandboxContract<TreasuryContract>;
|
|
9
10
|
let {{loweredName}}: SandboxContract<{{name}}>;
|
|
10
11
|
|
|
11
12
|
beforeEach(async () => {
|
|
@@ -13,7 +14,7 @@ describe('{{name}}', () => {
|
|
|
13
14
|
|
|
14
15
|
{{loweredName}} = blockchain.openContract(await {{name}}.fromInit(0n));
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
deployer = await blockchain.treasury('deployer');
|
|
17
18
|
|
|
18
19
|
const deployResult = await {{loweredName}}.send(
|
|
19
20
|
deployer.getSender(),
|
|
@@ -6,6 +6,7 @@ import '@ton/test-utils';
|
|
|
6
6
|
|
|
7
7
|
describe('{{name}}', () => {
|
|
8
8
|
let blockchain: Blockchain;
|
|
9
|
+
let deployer: SandboxContract<TreasuryContract>;
|
|
9
10
|
let {{loweredName}}: SandboxContract<{{name}}>;
|
|
10
11
|
|
|
11
12
|
beforeEach(async () => {
|
|
@@ -13,7 +14,7 @@ describe('{{name}}', () => {
|
|
|
13
14
|
|
|
14
15
|
{{loweredName}} = blockchain.openContract(await {{name}}.fromInit());
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
deployer = await blockchain.treasury('deployer');
|
|
17
18
|
|
|
18
19
|
const deployResult = await {{loweredName}}.send(
|
|
19
20
|
deployer.getSender(),
|
package/dist/utils.js
CHANGED
|
@@ -109,8 +109,8 @@ function getExplorerLink(address, network, explorer) {
|
|
|
109
109
|
switch (explorer) {
|
|
110
110
|
case 'tonscan':
|
|
111
111
|
return `https://${networkPrefix}tonscan.org/address/${address}`;
|
|
112
|
-
case '
|
|
113
|
-
return `https://${networkPrefix}
|
|
112
|
+
case 'tonviewer':
|
|
113
|
+
return `https://${networkPrefix}tonviewer.com/${address}`;
|
|
114
114
|
case 'toncx':
|
|
115
115
|
return `https://${networkPrefix}ton.cx/address/${address}`;
|
|
116
116
|
case 'dton':
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ton/blueprint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Framework for development of TON smart contracts",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": "./dist/cli/cli.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@types/inquirer": "^8.2.6",
|
|
26
26
|
"@types/node": "^20.2.5",
|
|
27
27
|
"@types/qrcode-terminal": "^0.12.0",
|
|
28
|
-
"prettier": "^
|
|
28
|
+
"prettier": "^3.0.3",
|
|
29
29
|
"typescript": "^4.9.5"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|