@ton/blueprint 0.33.1 → 0.35.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 +37 -0
- package/README.md +164 -16
- package/dist/cli/Runner.d.ts +2 -0
- package/dist/cli/Runner.js +9 -1
- package/dist/cli/build.d.ts +1 -2
- package/dist/cli/build.js +3 -6
- package/dist/cli/cli.js +8 -1
- package/dist/cli/constants.d.ts +4 -0
- package/dist/cli/constants.js +44 -6
- package/dist/cli/create.js +2 -13
- package/dist/cli/help.js +2 -1
- package/dist/cli/pack.d.ts +2 -0
- package/dist/cli/pack.js +98 -0
- package/dist/cli/rename.d.ts +6 -0
- package/dist/cli/rename.js +101 -0
- package/dist/cli/rename.spec.d.ts +1 -0
- package/dist/cli/rename.spec.js +59 -0
- package/dist/cli/run.js +2 -1
- package/dist/cli/snapshot.d.ts +6 -0
- package/dist/cli/snapshot.js +36 -0
- package/dist/cli/test.d.ts +4 -0
- package/dist/cli/test.js +20 -4
- package/dist/cli/verify.js +21 -0
- package/dist/compile/compile.d.ts +16 -0
- package/dist/compile/compile.js +23 -7
- package/dist/compile/tact/compile.tact.d.ts +2 -1
- package/dist/compile/tact/compile.tact.js +9 -5
- package/dist/config/Config.d.ts +21 -0
- package/dist/config/CustomNetwork.d.ts +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/network/Network.d.ts +1 -0
- package/dist/network/Network.js +2 -0
- package/dist/network/NetworkProvider.d.ts +2 -1
- package/dist/network/createNetworkProvider.js +51 -6
- package/dist/network/send/DeeplinkProvider.d.ts +2 -1
- package/dist/network/send/DeeplinkProvider.js +6 -4
- package/dist/network/send/MnemonicProvider.d.ts +16 -8
- package/dist/network/send/MnemonicProvider.js +31 -22
- package/dist/network/send/TonConnectProvider.d.ts +2 -1
- package/dist/network/send/TonConnectProvider.js +11 -5
- package/dist/network/send/wallets.d.ts +25 -0
- package/dist/network/send/wallets.js +30 -0
- package/dist/paths.d.ts +3 -0
- package/dist/paths.js +4 -1
- package/dist/templates/func/common/contracts/imports/stdlib.fc.template +8 -7
- package/dist/templates/func/not-separated-common/contracts/imports/stdlib.fc.template +8 -7
- package/dist/templates/tact/counter/scripts/deploy.ts.template +1 -1
- package/dist/templates/tact/counter/scripts/increment.ts.template +1 -1
- package/dist/templates/tact/empty/scripts/deploy.ts.template +1 -1
- package/dist/templates/tolk/counter/contracts/contract.tolk.template +41 -38
- package/dist/utils/selection.utils.js +5 -4
- package/dist/utils/string.utils.d.ts +3 -0
- package/dist/utils/string.utils.js +20 -0
- package/dist/utils/ton.utils.d.ts +2 -1
- package/dist/utils/ton.utils.js +3 -1
- package/package.json +7 -6
|
@@ -0,0 +1,101 @@
|
|
|
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.rename = void 0;
|
|
7
|
+
exports.renameExactIfRequired = renameExactIfRequired;
|
|
8
|
+
const arg_1 = __importDefault(require("arg"));
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const paths_1 = require("../paths");
|
|
12
|
+
const Runner_1 = require("./Runner");
|
|
13
|
+
const utils_1 = require("../utils");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
15
|
+
const build_1 = require("./build");
|
|
16
|
+
function renameExactIfRequired(str, replaces) {
|
|
17
|
+
let renamedString = str;
|
|
18
|
+
let isRenamed = false;
|
|
19
|
+
for (const [oldValue, newValue] of Object.entries(replaces)) {
|
|
20
|
+
const regex = new RegExp(`\\b${oldValue}\\b`, 'g');
|
|
21
|
+
if (regex.test(renamedString)) {
|
|
22
|
+
isRenamed = true;
|
|
23
|
+
renamedString = renamedString.replace(regex, newValue);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return { isRenamed, newValue: renamedString };
|
|
27
|
+
}
|
|
28
|
+
// Introduced this class to prevent fails in the middle of renaming, when the part is renamed and part is not
|
|
29
|
+
class RenameContext {
|
|
30
|
+
constructor(replaces) {
|
|
31
|
+
this.replaces = replaces;
|
|
32
|
+
this.effects = [];
|
|
33
|
+
}
|
|
34
|
+
async prepareRenameExactOccurrencesInDirectory(directory) {
|
|
35
|
+
if (!(0, fs_1.existsSync)(directory)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const dir = await fs_1.promises.readdir(directory, { recursive: true, withFileTypes: true });
|
|
39
|
+
await Promise.all(dir.map(async (dir) => {
|
|
40
|
+
if (!dir.isFile()) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const filePath = path_1.default.join(dir.path, dir.name);
|
|
44
|
+
await this.prepareRenameContentInFile(filePath);
|
|
45
|
+
const pathRenameResult = renameExactIfRequired(dir.name, this.replaces);
|
|
46
|
+
if (pathRenameResult.isRenamed) {
|
|
47
|
+
this.effects.push(() => fs_1.promises.rename(path_1.default.join(dir.path, dir.name), path_1.default.join(dir.path, pathRenameResult.newValue)));
|
|
48
|
+
}
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
async prepareRenameContentInFile(filePath) {
|
|
52
|
+
const content = await fs_1.promises.readFile(filePath, 'utf8');
|
|
53
|
+
const { isRenamed, newValue } = renameExactIfRequired(content, this.replaces);
|
|
54
|
+
if (isRenamed) {
|
|
55
|
+
this.effects.push(() => fs_1.promises.writeFile(filePath, newValue, 'utf8'));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async applyEffects() {
|
|
59
|
+
for (const effect of this.effects) {
|
|
60
|
+
await effect();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const rename = async (args, ui, context) => {
|
|
65
|
+
const localArgs = (0, arg_1.default)(constants_1.helpArgs);
|
|
66
|
+
if (localArgs['--help']) {
|
|
67
|
+
ui.write(constants_1.helpMessages['rename']);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const oldName = await (0, build_1.selectContract)(ui, (0, Runner_1.extractFirstArg)(localArgs));
|
|
71
|
+
const newName = (0, Runner_1.extractSecondArg)(localArgs) ?? (await ui.input('New contract name (PascalCase)'));
|
|
72
|
+
(0, utils_1.assertValidContractName)(newName);
|
|
73
|
+
const contracts = await (0, utils_1.findContracts)();
|
|
74
|
+
if (contracts.includes(newName)) {
|
|
75
|
+
ui.write(`Contract with name ${newName} already exists.`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const modifiers = [
|
|
79
|
+
(name) => name,
|
|
80
|
+
utils_1.toSnakeCase,
|
|
81
|
+
utils_1.toLowerCase,
|
|
82
|
+
(name) => `deploy${name}`,
|
|
83
|
+
(name) => `${name}_${name}`,
|
|
84
|
+
(name) => `increment${name}`,
|
|
85
|
+
(name) => `${(0, utils_1.toLowerCase)(name)}ConfigToCell`,
|
|
86
|
+
(name) => `${name}Config`,
|
|
87
|
+
];
|
|
88
|
+
const replaces = Object.fromEntries(modifiers.map((modifier) => [modifier(oldName), modifier(newName)]));
|
|
89
|
+
ui.setActionPrompt('Renaming in progress...');
|
|
90
|
+
const renameContext = new RenameContext(replaces);
|
|
91
|
+
for (const directory of [paths_1.SCRIPTS_DIR, paths_1.WRAPPERS_DIR, paths_1.CONTRACTS_DIR, paths_1.TESTS_DIR, paths_1.COMPILABLES_DIR]) {
|
|
92
|
+
await renameContext.prepareRenameExactOccurrencesInDirectory(directory);
|
|
93
|
+
}
|
|
94
|
+
if ((0, fs_1.existsSync)(paths_1.TACT_ROOT_CONFIG)) {
|
|
95
|
+
await renameContext.prepareRenameContentInFile(paths_1.TACT_ROOT_CONFIG);
|
|
96
|
+
}
|
|
97
|
+
await renameContext.applyEffects();
|
|
98
|
+
ui.clearActionPrompt();
|
|
99
|
+
ui.write('Contract successfully renamed!');
|
|
100
|
+
};
|
|
101
|
+
exports.rename = rename;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
const node_test_1 = require("node:test");
|
|
7
|
+
const node_assert_1 = __importDefault(require("node:assert"));
|
|
8
|
+
const rename_1 = require("./rename");
|
|
9
|
+
(0, node_test_1.describe)('Rename', function () {
|
|
10
|
+
(0, node_test_1.it)('It should rename exact match', function () {
|
|
11
|
+
const replaces = {
|
|
12
|
+
a: 'b',
|
|
13
|
+
};
|
|
14
|
+
const result = (0, rename_1.renameExactIfRequired)('a a', replaces);
|
|
15
|
+
node_assert_1.default.strictEqual(result.isRenamed, true);
|
|
16
|
+
node_assert_1.default.strictEqual(result.newValue, 'b b');
|
|
17
|
+
});
|
|
18
|
+
(0, node_test_1.it)('It should not rename not exact match', function () {
|
|
19
|
+
const replaces = {
|
|
20
|
+
a: 'b',
|
|
21
|
+
};
|
|
22
|
+
const result = (0, rename_1.renameExactIfRequired)('and', replaces);
|
|
23
|
+
node_assert_1.default.strictEqual(result.isRenamed, false);
|
|
24
|
+
node_assert_1.default.strictEqual(result.newValue, 'and');
|
|
25
|
+
});
|
|
26
|
+
(0, node_test_1.it)('It should not rename another case', function () {
|
|
27
|
+
const replaces = {
|
|
28
|
+
a: 'b',
|
|
29
|
+
};
|
|
30
|
+
const result = (0, rename_1.renameExactIfRequired)('A', replaces);
|
|
31
|
+
node_assert_1.default.strictEqual(result.isRenamed, false);
|
|
32
|
+
node_assert_1.default.strictEqual(result.newValue, 'A');
|
|
33
|
+
});
|
|
34
|
+
(0, node_test_1.it)('It should rename contract name in brackets', function () {
|
|
35
|
+
const replaces = {
|
|
36
|
+
['MyContract']: 'NotMyContract',
|
|
37
|
+
};
|
|
38
|
+
const result = (0, rename_1.renameExactIfRequired)(`compile('MyContract')`, replaces);
|
|
39
|
+
node_assert_1.default.strictEqual(result.isRenamed, true);
|
|
40
|
+
node_assert_1.default.strictEqual(result.newValue, `compile('NotMyContract')`);
|
|
41
|
+
});
|
|
42
|
+
(0, node_test_1.it)('It should not rename contract name if not exact match', function () {
|
|
43
|
+
const replaces = {
|
|
44
|
+
['MyContract']: 'NotMyContract',
|
|
45
|
+
};
|
|
46
|
+
const result = (0, rename_1.renameExactIfRequired)(`compile('MyContract2')`, replaces);
|
|
47
|
+
node_assert_1.default.strictEqual(result.isRenamed, false);
|
|
48
|
+
node_assert_1.default.strictEqual(result.newValue, `compile('MyContract2')`);
|
|
49
|
+
});
|
|
50
|
+
(0, node_test_1.it)('It should do multiple replaces', function () {
|
|
51
|
+
const replaces = {
|
|
52
|
+
['myContract']: 'notMyContract',
|
|
53
|
+
['MyContract']: 'NotMyContract',
|
|
54
|
+
};
|
|
55
|
+
const result = (0, rename_1.renameExactIfRequired)(`let myContract: MyContract;`, replaces);
|
|
56
|
+
node_assert_1.default.strictEqual(result.isRenamed, true);
|
|
57
|
+
node_assert_1.default.strictEqual(result.newValue, `let notMyContract: NotMyContract;`);
|
|
58
|
+
});
|
|
59
|
+
});
|
package/dist/cli/run.js
CHANGED
|
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.run = void 0;
|
|
7
|
+
const Runner_1 = require("./Runner");
|
|
7
8
|
const createNetworkProvider_1 = require("../network/createNetworkProvider");
|
|
8
9
|
const utils_1 = require("../utils");
|
|
9
10
|
const arg_1 = __importDefault(require("arg"));
|
|
@@ -16,7 +17,7 @@ const run = async (args, ui, context) => {
|
|
|
16
17
|
}
|
|
17
18
|
const { module: mod } = await (0, utils_1.selectFile)(await (0, utils_1.findScripts)(), {
|
|
18
19
|
ui,
|
|
19
|
-
hint:
|
|
20
|
+
hint: (0, Runner_1.extractFirstArg)(localArgs),
|
|
20
21
|
});
|
|
21
22
|
if (typeof mod.run !== 'function') {
|
|
22
23
|
throw new Error('Function `run` is missing!');
|
|
@@ -0,0 +1,36 @@
|
|
|
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.snapshot = exports.argSpec = void 0;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const arg_1 = __importDefault(require("arg"));
|
|
9
|
+
const constants_1 = require("./constants");
|
|
10
|
+
exports.argSpec = {
|
|
11
|
+
'--label': String,
|
|
12
|
+
'-l': '--label',
|
|
13
|
+
};
|
|
14
|
+
const snapshot = async (args, ui) => {
|
|
15
|
+
const localArgs = (0, arg_1.default)({ ...exports.argSpec, ...constants_1.helpArgs });
|
|
16
|
+
if (localArgs['--help']) {
|
|
17
|
+
ui.write(constants_1.helpMessages['snapshot']);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let comment = localArgs['--label'];
|
|
21
|
+
let testArgs = args._.slice(1); // first argument is `snapshot`, need to get rid of it
|
|
22
|
+
if (typeof comment === 'undefined') {
|
|
23
|
+
comment = await ui.input('Enter comment:');
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
testArgs = testArgs.slice(2);
|
|
27
|
+
}
|
|
28
|
+
(0, node_child_process_1.execSync)(`npm test -- ${testArgs.join(' ')}`, {
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
env: {
|
|
31
|
+
...process.env,
|
|
32
|
+
BENCH_NEW: comment,
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
exports.snapshot = snapshot;
|
package/dist/cli/test.d.ts
CHANGED
package/dist/cli/test.js
CHANGED
|
@@ -3,17 +3,33 @@ 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.test = void 0;
|
|
6
|
+
exports.test = exports.argSpec = void 0;
|
|
7
7
|
const child_process_1 = require("child_process");
|
|
8
8
|
const arg_1 = __importDefault(require("arg"));
|
|
9
9
|
const constants_1 = require("./constants");
|
|
10
|
+
exports.argSpec = {
|
|
11
|
+
'--gas-report': Boolean,
|
|
12
|
+
'-g': '--gas-report',
|
|
13
|
+
};
|
|
10
14
|
const test = async (args, ui) => {
|
|
11
|
-
const localArgs = (0, arg_1.default)(
|
|
15
|
+
const localArgs = (0, arg_1.default)({
|
|
16
|
+
...constants_1.helpArgs,
|
|
17
|
+
...exports.argSpec,
|
|
18
|
+
});
|
|
12
19
|
if (localArgs['--help']) {
|
|
13
20
|
ui.write(constants_1.helpMessages['test']);
|
|
14
21
|
return;
|
|
15
22
|
}
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
let testArgs = args._.slice(1); // first argument is `test`, need to get rid of it
|
|
24
|
+
if (localArgs['--gas-report']) {
|
|
25
|
+
testArgs = testArgs.slice(1);
|
|
26
|
+
}
|
|
27
|
+
(0, child_process_1.execSync)(`npm test -- ${testArgs.join(' ')}`, {
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
env: {
|
|
30
|
+
...process.env,
|
|
31
|
+
BENCH_DIFF: localArgs['--gas-report'] ? 'true' : 'false',
|
|
32
|
+
},
|
|
33
|
+
});
|
|
18
34
|
};
|
|
19
35
|
exports.test = test;
|
package/dist/cli/verify.js
CHANGED
|
@@ -217,6 +217,27 @@ const verify = async (args, ui, context) => {
|
|
|
217
217
|
senderAddress: senderAddress.toString(),
|
|
218
218
|
};
|
|
219
219
|
}
|
|
220
|
+
else if (result.lang === 'tolk') {
|
|
221
|
+
for (const f of result.snapshot) {
|
|
222
|
+
fd.append(f.filename, new Blob([f.content]), path_1.default.basename(f.filename));
|
|
223
|
+
}
|
|
224
|
+
src = {
|
|
225
|
+
compiler: 'tolk',
|
|
226
|
+
compilerSettings: {
|
|
227
|
+
tolkVersion: result.version,
|
|
228
|
+
},
|
|
229
|
+
knownContractAddress: addr,
|
|
230
|
+
knownContractHash: result.code.hash().toString('base64'),
|
|
231
|
+
sources: result.snapshot.map((s) => ({
|
|
232
|
+
includeInCommand: true,
|
|
233
|
+
isStdLib: false,
|
|
234
|
+
hasIncludeDirectives: true,
|
|
235
|
+
isEntrypoint: s === result.snapshot[0],
|
|
236
|
+
folder: path_1.default.dirname(s.filename),
|
|
237
|
+
})),
|
|
238
|
+
senderAddress: senderAddress.toString(),
|
|
239
|
+
};
|
|
240
|
+
}
|
|
220
241
|
else {
|
|
221
242
|
// future proofing
|
|
222
243
|
throw new Error('Unsupported language ' + result.lang);
|
|
@@ -6,6 +6,22 @@ import { TolkCompileResult } from './tolk/compile.tolk';
|
|
|
6
6
|
export declare function getCompilablesDirectory(): Promise<string>;
|
|
7
7
|
export declare function extractCompilableConfig(path: string): CompilableConfig;
|
|
8
8
|
export declare const COMPILE_END = ".compile.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Retrieves the compiler configuration for a specific contract.
|
|
11
|
+
*
|
|
12
|
+
* This function checks if a Tact configuration exists for the given contract
|
|
13
|
+
* `tact.config.json`. If found, it returns that configuration. Otherwise, it falls back
|
|
14
|
+
* to loading and extracting the `.compile.ts` configuration file from the appropriate
|
|
15
|
+
* compilables directory (`compilables/` or `wrappers/`).
|
|
16
|
+
*
|
|
17
|
+
* @param {string} name - The name of the contract
|
|
18
|
+
*
|
|
19
|
+
* @throws Error Throws if configuration is invalid or not found.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* const config = await getCompilerConfigForContract('MyContract');
|
|
23
|
+
* console.log('Compiler config:', config);
|
|
24
|
+
*/
|
|
9
25
|
export declare function getCompilerConfigForContract(name: string): Promise<CompilerConfig>;
|
|
10
26
|
export type CompileResult = TactCompileResult | FuncCompileResult | TolkCompileResult;
|
|
11
27
|
export declare function getCompilerOptions(config: CompilerConfig): Promise<{
|
package/dist/compile/compile.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.COMPILE_END = void 0;
|
|
7
4
|
exports.getCompilablesDirectory = getCompilablesDirectory;
|
|
@@ -11,13 +8,13 @@ exports.getCompilerOptions = getCompilerOptions;
|
|
|
11
8
|
exports.doCompile = doCompile;
|
|
12
9
|
exports.compile = compile;
|
|
13
10
|
const fs_1 = require("fs");
|
|
14
|
-
const path_1 = __importDefault(require("path"));
|
|
15
11
|
const paths_1 = require("../paths");
|
|
16
12
|
const CompilerConfig_1 = require("./CompilerConfig");
|
|
17
13
|
const utils_1 = require("../config/utils");
|
|
18
14
|
const compile_func_1 = require("./func/compile.func");
|
|
19
15
|
const compile_tact_1 = require("./tact/compile.tact");
|
|
20
16
|
const compile_tolk_1 = require("./tolk/compile.tolk");
|
|
17
|
+
const utils_2 = require("../utils");
|
|
21
18
|
async function getCompilablesDirectory() {
|
|
22
19
|
const config = await (0, utils_1.getConfig)();
|
|
23
20
|
if (config?.separateCompilables) {
|
|
@@ -34,14 +31,33 @@ function extractCompilableConfig(path) {
|
|
|
34
31
|
return mod.compile;
|
|
35
32
|
}
|
|
36
33
|
exports.COMPILE_END = '.compile.ts';
|
|
37
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Retrieves the compiler configuration for a specific contract.
|
|
36
|
+
*
|
|
37
|
+
* This function checks if a Tact configuration exists for the given contract
|
|
38
|
+
* `tact.config.json`. If found, it returns that configuration. Otherwise, it falls back
|
|
39
|
+
* to loading and extracting the `.compile.ts` configuration file from the appropriate
|
|
40
|
+
* compilables directory (`compilables/` or `wrappers/`).
|
|
41
|
+
*
|
|
42
|
+
* @param {string} name - The name of the contract
|
|
43
|
+
*
|
|
44
|
+
* @throws Error Throws if configuration is invalid or not found.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const config = await getCompilerConfigForContract('MyContract');
|
|
48
|
+
* console.log('Compiler config:', config);
|
|
49
|
+
*/
|
|
38
50
|
async function getCompilerConfigForContract(name) {
|
|
39
51
|
const tactConfig = (0, compile_tact_1.getTactConfigForContract)(name);
|
|
40
52
|
if (tactConfig) {
|
|
41
53
|
return tactConfig;
|
|
42
54
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
55
|
+
const compilables = await (0, utils_2.findCompiles)();
|
|
56
|
+
const compilable = compilables.find((c) => c.name === name);
|
|
57
|
+
if (compilable === undefined) {
|
|
58
|
+
throw new Error(`Contract '${name}' not found`);
|
|
59
|
+
}
|
|
60
|
+
return extractCompilableConfig(compilable.path);
|
|
45
61
|
}
|
|
46
62
|
async function doCompileInner(name, config) {
|
|
47
63
|
if ((0, CompilerConfig_1.isCompilableConfig)(config)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Options } from '@tact-lang/compiler';
|
|
1
|
+
import { Options, Project } from '@tact-lang/compiler';
|
|
2
2
|
import { Cell } from '@ton/core';
|
|
3
3
|
import { TactCompilerConfig, TactLegacyCompilerConfig } from './config';
|
|
4
4
|
export type TactCompileResult = {
|
|
@@ -10,4 +10,5 @@ export type TactCompileResult = {
|
|
|
10
10
|
};
|
|
11
11
|
export declare function getTactConfigForContract(name: string): TactCompilerConfig | undefined;
|
|
12
12
|
export declare function getTactVersion(): Promise<any>;
|
|
13
|
+
export declare function extractContractConfig(config: TactCompilerConfig, name: string): Project;
|
|
13
14
|
export declare function doCompileTact(config: TactLegacyCompilerConfig | TactCompilerConfig, name: string): Promise<TactCompileResult>;
|
|
@@ -38,6 +38,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.getTactConfigForContract = getTactConfigForContract;
|
|
40
40
|
exports.getTactVersion = getTactVersion;
|
|
41
|
+
exports.extractContractConfig = extractContractConfig;
|
|
41
42
|
exports.doCompileTact = doCompileTact;
|
|
42
43
|
const path_1 = __importDefault(require("path"));
|
|
43
44
|
const compiler_1 = require("@tact-lang/compiler");
|
|
@@ -85,6 +86,13 @@ async function getTactVersion() {
|
|
|
85
86
|
function isLegacyTactConfig(config) {
|
|
86
87
|
return 'lang' in config;
|
|
87
88
|
}
|
|
89
|
+
function extractContractConfig(config, name) {
|
|
90
|
+
const project = config.projects.find((p) => p.name === name);
|
|
91
|
+
if (!project) {
|
|
92
|
+
throw new Error(`Config for project ${name} not found`);
|
|
93
|
+
}
|
|
94
|
+
return project;
|
|
95
|
+
}
|
|
88
96
|
function getTactBuildProject(config, name) {
|
|
89
97
|
if (isLegacyTactConfig(config)) {
|
|
90
98
|
const rootConfigOptions = getRootTactConfigOptionsForContract(name);
|
|
@@ -95,11 +103,7 @@ function getTactBuildProject(config, name) {
|
|
|
95
103
|
options: { ...rootConfigOptions, ...config.options },
|
|
96
104
|
};
|
|
97
105
|
}
|
|
98
|
-
|
|
99
|
-
if (!project) {
|
|
100
|
-
throw new Error(`Config for project ${name} not found`);
|
|
101
|
-
}
|
|
102
|
-
return project;
|
|
106
|
+
return extractContractConfig(config, name);
|
|
103
107
|
}
|
|
104
108
|
async function doCompileTact(config, name) {
|
|
105
109
|
const fs = new OverwritableVirtualFileSystem_1.OverwritableVirtualFileSystem(process.cwd());
|
package/dist/config/Config.d.ts
CHANGED
|
@@ -37,4 +37,25 @@ export interface Config {
|
|
|
37
37
|
* @default false
|
|
38
38
|
*/
|
|
39
39
|
separateCompilables?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* HTTP request timeout in milliseconds.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* export const config: Config = {
|
|
45
|
+
* requestTimeout: 10000 // 10 seconds
|
|
46
|
+
* };
|
|
47
|
+
*/
|
|
48
|
+
requestTimeout?: number;
|
|
49
|
+
/**
|
|
50
|
+
* If true, the `wrappers`/`compilables` directory will be searched recursively for contracts.
|
|
51
|
+
*
|
|
52
|
+
* @default false
|
|
53
|
+
*/
|
|
54
|
+
recursiveWrappers?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Manifest url passed to TonConnect provider.
|
|
57
|
+
*
|
|
58
|
+
* @default https://raw.githubusercontent.com/ton-org/blueprint/main/tonconnect/manifest.json
|
|
59
|
+
*/
|
|
60
|
+
manifestUrl?: string;
|
|
40
61
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export { PluginRunner, Plugin } from './config/Plugin';
|
|
|
10
10
|
export { CustomNetwork } from './config/CustomNetwork';
|
|
11
11
|
export { buildOne, buildAll, buildAllTact } from './build';
|
|
12
12
|
export { SourceSnapshot } from "./compile/SourceSnapshot";
|
|
13
|
+
export { getCompilerConfigForContract } from './compile/compile';
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.buildAllTact = exports.buildAll = exports.buildOne = exports.compile = exports.createNetworkProvider = exports.sleep = exports.tonDeepLink = void 0;
|
|
3
|
+
exports.getCompilerConfigForContract = exports.buildAllTact = 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; } });
|
|
@@ -12,3 +12,5 @@ var build_1 = require("./build");
|
|
|
12
12
|
Object.defineProperty(exports, "buildOne", { enumerable: true, get: function () { return build_1.buildOne; } });
|
|
13
13
|
Object.defineProperty(exports, "buildAll", { enumerable: true, get: function () { return build_1.buildAll; } });
|
|
14
14
|
Object.defineProperty(exports, "buildAllTact", { enumerable: true, get: function () { return build_1.buildAllTact; } });
|
|
15
|
+
var compile_2 = require("./compile/compile");
|
|
16
|
+
Object.defineProperty(exports, "getCompilerConfigForContract", { enumerable: true, get: function () { return compile_2.getCompilerConfigForContract; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Network = 'mainnet' | 'testnet' | 'custom';
|
|
@@ -2,7 +2,8 @@ import { TonClient, TonClient4 } from '@ton/ton';
|
|
|
2
2
|
import { Address, Cell, Contract, ContractProvider, OpenedContract, Sender } from '@ton/core';
|
|
3
3
|
import { ContractAdapter } from '@ton-api/ton-adapter';
|
|
4
4
|
import { UIProvider } from '../ui/UIProvider';
|
|
5
|
-
|
|
5
|
+
import { LiteClient } from "ton-lite-client";
|
|
6
|
+
export type BlueprintTonClient = TonClient4 | TonClient | ContractAdapter | LiteClient;
|
|
6
7
|
/**
|
|
7
8
|
* Interface representing a network provider for interacting with TON blockchain.
|
|
8
9
|
*/
|
|
@@ -30,6 +30,7 @@ const paths_1 = require("../paths");
|
|
|
30
30
|
const crypto_1 = require("@ton/crypto");
|
|
31
31
|
const MnemonicProvider_1 = require("./send/MnemonicProvider");
|
|
32
32
|
const axios_1 = __importDefault(require("axios"));
|
|
33
|
+
const ton_lite_client_1 = require("ton-lite-client");
|
|
33
34
|
const INITIAL_DELAY = 400;
|
|
34
35
|
const MAX_ATTEMPTS = 4;
|
|
35
36
|
exports.argSpec = {
|
|
@@ -148,9 +149,10 @@ class NetworkProviderImpl {
|
|
|
148
149
|
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").setActionPrompt(`Awaiting contract deployment... [Attempt ${i}/${attempts}]`);
|
|
149
150
|
const isDeployed = await this.isContractDeployed(address);
|
|
150
151
|
if (isDeployed) {
|
|
152
|
+
const formattedAddress = address.toString({ testOnly: __classPrivateFieldGet(this, _NetworkProviderImpl_network, "f") === 'testnet' });
|
|
151
153
|
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").clearActionPrompt();
|
|
152
|
-
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").write(`Contract deployed at address ${
|
|
153
|
-
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").write(`You can view it at ${(0, utils_1.getExplorerLink)(
|
|
154
|
+
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").write(`Contract deployed at address ${formattedAddress}`);
|
|
155
|
+
__classPrivateFieldGet(this, _NetworkProviderImpl_ui, "f").write(`You can view it at ${(0, utils_1.getExplorerLink)(formattedAddress, __classPrivateFieldGet(this, _NetworkProviderImpl_network, "f"), __classPrivateFieldGet(this, _NetworkProviderImpl_explorer, "f"))}`);
|
|
154
156
|
return;
|
|
155
157
|
}
|
|
156
158
|
await (0, utils_1.sleep)(sleepDuration);
|
|
@@ -189,20 +191,59 @@ class NetworkProviderImpl {
|
|
|
189
191
|
}
|
|
190
192
|
}
|
|
191
193
|
_NetworkProviderImpl_tc = new WeakMap(), _NetworkProviderImpl_sender = new WeakMap(), _NetworkProviderImpl_network = new WeakMap(), _NetworkProviderImpl_explorer = new WeakMap(), _NetworkProviderImpl_ui = new WeakMap();
|
|
192
|
-
|
|
194
|
+
function getOptionalNumberEnv(envName) {
|
|
195
|
+
const value = process.env[envName] ? Number(process.env[envName]) : undefined;
|
|
196
|
+
if (value !== undefined && Number.isNaN(value)) {
|
|
197
|
+
throw new Error(`Invalid ${envName} provided`);
|
|
198
|
+
}
|
|
199
|
+
return value;
|
|
200
|
+
}
|
|
201
|
+
async function createMnemonicProvider(client, network, ui) {
|
|
193
202
|
const mnemonic = process.env.WALLET_MNEMONIC ?? '';
|
|
194
203
|
const walletVersion = process.env.WALLET_VERSION ?? '';
|
|
195
204
|
if (mnemonic.length === 0 || walletVersion.length === 0) {
|
|
196
205
|
throw new Error('Mnemonic deployer was chosen, but env variables WALLET_MNEMONIC and WALLET_VERSION are not set');
|
|
197
206
|
}
|
|
207
|
+
const walletId = getOptionalNumberEnv('WALLET_ID');
|
|
208
|
+
const subwalletNumber = getOptionalNumberEnv('SUBWALLET_NUMBER');
|
|
198
209
|
const keyPair = await (0, crypto_1.mnemonicToPrivateKey)(mnemonic.split(' '));
|
|
199
210
|
return new MnemonicProvider_1.MnemonicProvider({
|
|
200
211
|
version: walletVersion.toLowerCase(),
|
|
201
212
|
client,
|
|
202
213
|
secretKey: keyPair.secretKey,
|
|
203
214
|
ui,
|
|
215
|
+
walletId,
|
|
216
|
+
subwalletNumber,
|
|
217
|
+
network,
|
|
204
218
|
});
|
|
205
219
|
}
|
|
220
|
+
function intToIP(int) {
|
|
221
|
+
const part1 = int & 255;
|
|
222
|
+
const part2 = (int >> 8) & 255;
|
|
223
|
+
const part3 = (int >> 16) & 255;
|
|
224
|
+
const part4 = (int >> 24) & 255;
|
|
225
|
+
return `${(part4 + 256) % 256}.${(part3 + 256) % 256}.${(part2 + 256) % 256}.${(part1 + 256) % 256}`;
|
|
226
|
+
}
|
|
227
|
+
async function buildLiteClient(configEndpoint) {
|
|
228
|
+
const { data } = await axios_1.default.get(configEndpoint);
|
|
229
|
+
if (!Array.isArray(data.liteservers)) {
|
|
230
|
+
throw new Error(`Invalid liteclient configuration on ${configEndpoint}. Use https://ton.org/testnet-global.config.json for testnet or https://ton.org/global.config.json for mainnet.`);
|
|
231
|
+
}
|
|
232
|
+
const engines = data.liteservers.map((server) => {
|
|
233
|
+
if (typeof server?.ip !== 'number' ||
|
|
234
|
+
typeof server?.port !== 'number' ||
|
|
235
|
+
typeof server?.id !== 'object' ||
|
|
236
|
+
typeof server?.id?.key !== 'string') {
|
|
237
|
+
throw new Error(`Invalid liteclient configuration on ${configEndpoint}`);
|
|
238
|
+
}
|
|
239
|
+
return new ton_lite_client_1.LiteSingleEngine({
|
|
240
|
+
host: `tcp://${intToIP(server.ip)}:${server.port}`,
|
|
241
|
+
publicKey: Buffer.from(server.id.key, 'base64'),
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
const engine = new ton_lite_client_1.LiteRoundRobinEngine(engines);
|
|
245
|
+
return new ton_lite_client_1.LiteClient({ engine });
|
|
246
|
+
}
|
|
206
247
|
class NetworkProviderBuilder {
|
|
207
248
|
constructor(args, ui, config, allowCustom = true) {
|
|
208
249
|
this.args = args;
|
|
@@ -265,15 +306,15 @@ class NetworkProviderBuilder {
|
|
|
265
306
|
let provider;
|
|
266
307
|
switch (deployUsing) {
|
|
267
308
|
case 'deeplink':
|
|
268
|
-
provider = new DeeplinkProvider_1.DeeplinkProvider(this.ui);
|
|
309
|
+
provider = new DeeplinkProvider_1.DeeplinkProvider(network, this.ui);
|
|
269
310
|
break;
|
|
270
311
|
case 'tonconnect':
|
|
271
312
|
if (network === 'custom')
|
|
272
313
|
throw new Error('Tonkeeper cannot work with custom network.');
|
|
273
|
-
provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui);
|
|
314
|
+
provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui, network, this.config?.manifestUrl);
|
|
274
315
|
break;
|
|
275
316
|
case 'mnemonic':
|
|
276
|
-
provider = await createMnemonicProvider(client, this.ui);
|
|
317
|
+
provider = await createMnemonicProvider(client, network, this.ui);
|
|
277
318
|
break;
|
|
278
319
|
default:
|
|
279
320
|
throw new Error('Unknown deploy option');
|
|
@@ -336,6 +377,9 @@ class NetworkProviderBuilder {
|
|
|
336
377
|
apiKey: configNetwork.key,
|
|
337
378
|
}));
|
|
338
379
|
}
|
|
380
|
+
else if (configNetwork.version === 'liteclient') {
|
|
381
|
+
tc = await buildLiteClient(configNetwork.endpoint);
|
|
382
|
+
}
|
|
339
383
|
else {
|
|
340
384
|
throw new Error('Unknown API version: ' + configNetwork.version);
|
|
341
385
|
}
|
|
@@ -373,6 +417,7 @@ class NetworkProviderBuilder {
|
|
|
373
417
|
}
|
|
374
418
|
};
|
|
375
419
|
tc = new ton_1.TonClient({
|
|
420
|
+
timeout: this.config?.requestTimeout,
|
|
376
421
|
endpoint: network === 'mainnet'
|
|
377
422
|
? 'https://toncenter.com/api/v2/jsonRPC'
|
|
378
423
|
: 'https://testnet.toncenter.com/api/v2/jsonRPC',
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { Address, Cell, StateInit } from '@ton/core';
|
|
2
2
|
import { SendProvider } from './SendProvider';
|
|
3
3
|
import { UIProvider } from '../../ui/UIProvider';
|
|
4
|
+
import { Network } from '../Network';
|
|
4
5
|
export declare class DeeplinkProvider implements SendProvider {
|
|
5
6
|
#private;
|
|
6
|
-
constructor(ui: UIProvider);
|
|
7
|
+
constructor(network: Network, ui: UIProvider);
|
|
7
8
|
connect(): Promise<void>;
|
|
8
9
|
sendTransaction(address: Address, amount: bigint, payload?: Cell, stateInit?: StateInit): Promise<void>;
|
|
9
10
|
address(): Address | undefined;
|