@ton/blueprint 0.23.0 → 0.24.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 CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.24.0] - 2024-09-16
9
+
10
+ ### Added
11
+
12
+ - Added support for wallet v5 in the Mnemonic provider
13
+
14
+ ### Changed
15
+
16
+ - Changed the default API provider to Toncenter v2 (instead of Orbs TON Access). Rate limited requests are automatically retried
17
+ - Updated dependencies
18
+
19
+ ### Removed
20
+
21
+ - Removed the specialized TonHub connector. Use TON Connect instead
22
+
8
23
  ## [0.23.0] - 2024-09-11
9
24
 
10
25
  ### Changed
package/README.md CHANGED
@@ -53,7 +53,7 @@ Blueprint is an all-in-one development environment designed to enhance the proce
53
53
  1. Compiling FunC with https://github.com/ton-community/func-js
54
54
  2. Compiling Tact with https://github.com/tact-lang/tact
55
55
  3. Testing smart contracts with https://github.com/ton-org/sandbox
56
- 4. Deploying smart contracts with [TON Connect 2](https://github.com/ton-connect), [Tonhub wallet](https://tonhub.com/) or a `ton://` deeplink
56
+ 4. Deploying smart contracts with [TON Connect 2](https://github.com/ton-connect) or a `ton://` deeplink
57
57
 
58
58
  ### Requirements
59
59
 
@@ -58,7 +58,7 @@ Flags:
58
58
  --custom-version - specifies the API version to use with the custom API. Options: v2 (defualt), v4.
59
59
  --custom-key - specifies the API key to use with the custom API, can only be used with API v2.
60
60
  --custom-type - specifies the network type to be indicated to scripts. Options: custom (default), mainnet, testnet.
61
- --tonconnect, --tonhub, --deeplink, --mnemonic - specifies the deployer to use when running the script. If not specified on the command line, it will be asked interactively.
61
+ --tonconnect, --deeplink, --mnemonic - specifies the deployer to use when running the script. If not specified on the command line, it will be asked interactively.
62
62
  --tonscan, --tonviewer, --toncx, --dton - specifies the network explorer to use when displaying links to the deployed contracts. Default: tonscan.`,
63
63
  build: `Usage: blueprint build [contract name] [flags]
64
64
 
@@ -11,7 +11,6 @@ export declare const argSpec: {
11
11
  '--custom-key': StringConstructor;
12
12
  '--tonconnect': BooleanConstructor;
13
13
  '--deeplink': BooleanConstructor;
14
- '--tonhub': BooleanConstructor;
15
14
  '--mnemonic': BooleanConstructor;
16
15
  '--tonscan': BooleanConstructor;
17
16
  '--tonviewer': BooleanConstructor;
@@ -19,7 +19,6 @@ exports.createNetworkProvider = exports.argSpec = void 0;
19
19
  const utils_1 = require("../utils");
20
20
  const DeeplinkProvider_1 = require("./send/DeeplinkProvider");
21
21
  const TonConnectProvider_1 = require("./send/TonConnectProvider");
22
- const TonHubProvider_1 = require("./send/TonHubProvider");
23
22
  const core_1 = require("@ton/core");
24
23
  const ton_1 = require("@ton/ton");
25
24
  const FSStorage_1 = require("./storage/FSStorage");
@@ -39,7 +38,6 @@ exports.argSpec = {
39
38
  '--custom-key': String,
40
39
  '--tonconnect': Boolean,
41
40
  '--deeplink': Boolean,
42
- '--tonhub': Boolean,
43
41
  '--mnemonic': Boolean,
44
42
  '--tonscan': Boolean,
45
43
  '--tonviewer': Boolean,
@@ -140,7 +138,7 @@ class NetworkProviderImpl {
140
138
  return (await __classPrivateFieldGet(this, _NetworkProviderImpl_tc, "f").getContractState(address)).state === 'active';
141
139
  }
142
140
  }
143
- async waitForDeploy(address, attempts = 10, sleepDuration = 2000) {
141
+ async waitForDeploy(address, attempts = 20, sleepDuration = 2000) {
144
142
  if (attempts <= 0) {
145
143
  throw new Error('Attempt number must be positive');
146
144
  }
@@ -243,7 +241,6 @@ class NetworkProviderBuilder {
243
241
  let deployUsing = (0, utils_1.oneOrZeroOf)({
244
242
  tonconnect: this.args['--tonconnect'],
245
243
  deeplink: this.args['--deeplink'],
246
- tonhub: this.args['--tonhub'],
247
244
  mnemonic: this.args['--mnemonic'],
248
245
  });
249
246
  if (!deployUsing) {
@@ -256,10 +253,6 @@ class NetworkProviderBuilder {
256
253
  name: 'Create a ton:// deep link',
257
254
  value: 'deeplink',
258
255
  },
259
- {
260
- name: 'Tonhub wallet',
261
- value: 'tonhub',
262
- },
263
256
  {
264
257
  name: 'Mnemonic',
265
258
  value: 'mnemonic',
@@ -277,11 +270,6 @@ class NetworkProviderBuilder {
277
270
  throw new Error('Tonkeeper cannot work with custom network.');
278
271
  provider = new TonConnectProvider_1.TonConnectProvider(new FSStorage_1.FSStorage(storagePath), this.ui);
279
272
  break;
280
- case 'tonhub':
281
- if (network === 'custom')
282
- throw new Error('TonHub cannot work with custom network.');
283
- provider = new TonHubProvider_1.TonHubProvider(network, new FSStorage_1.FSStorage(storagePath), this.ui);
284
- break;
285
273
  case 'mnemonic':
286
274
  provider = await createMnemonicProvider(client, this.ui);
287
275
  break;
@@ -355,29 +343,30 @@ class NetworkProviderBuilder {
355
343
  }
356
344
  }
357
345
  else {
358
- tc = new ton_1.TonClient({
359
- endpoint: network === 'mainnet' ? 'https://toncenter.com/api/v2/jsonRPC' : 'https://testnet.toncenter.com/api/v2/jsonRPC',
360
- httpAdapter: async (config) => {
361
- let r;
362
- let delay = INITIAL_DELAY;
363
- let attempts = 0;
364
- while (true) {
365
- r = await (0, axios_1.default)({
366
- ...config,
367
- adapter: undefined,
368
- validateStatus: (status) => (status >= 200 && status < 300) || status === 429,
369
- });
370
- if (r.status !== 429) {
371
- return r;
372
- }
373
- await (0, utils_1.sleep)(delay);
374
- delay *= 2;
375
- attempts++;
376
- if (attempts >= MAX_ATTEMPTS) {
377
- throw new Error('Max attempts reached');
378
- }
346
+ const httpAdapter = async (config) => {
347
+ let r;
348
+ let delay = INITIAL_DELAY;
349
+ let attempts = 0;
350
+ while (true) {
351
+ r = await (0, axios_1.default)({
352
+ ...config,
353
+ adapter: undefined,
354
+ validateStatus: (status) => (status >= 200 && status < 300) || status === 429,
355
+ });
356
+ if (r.status !== 429) {
357
+ return r;
358
+ }
359
+ await (0, utils_1.sleep)(delay);
360
+ delay *= 2;
361
+ attempts++;
362
+ if (attempts >= MAX_ATTEMPTS) {
363
+ throw new Error('Max attempts reached');
379
364
  }
380
365
  }
366
+ };
367
+ tc = new ton_1.TonClient({
368
+ endpoint: network === 'mainnet' ? 'https://toncenter.com/api/v2/jsonRPC' : 'https://testnet.toncenter.com/api/v2/jsonRPC',
369
+ httpAdapter,
381
370
  });
382
371
  }
383
372
  const sendProvider = await this.chooseSendProvider(network, tc);
@@ -3,7 +3,7 @@ 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';
6
- export type WalletVersion = 'v1r1' | 'v1r2' | 'v1r3' | 'v2r1' | 'v2r2' | 'v3r1' | 'v3r2' | 'v4';
6
+ export type WalletVersion = 'v1r1' | 'v1r2' | 'v1r3' | 'v2r1' | 'v2r2' | 'v3r1' | 'v3r2' | 'v4' | 'v5r1';
7
7
  export declare class MnemonicProvider implements SendProvider {
8
8
  #private;
9
9
  constructor(params: {
@@ -25,6 +25,7 @@ const wallets = {
25
25
  v3r1: ton_1.WalletContractV3R1,
26
26
  v3r2: ton_1.WalletContractV3R2,
27
27
  v4: ton_1.WalletContractV4,
28
+ v5r1: ton_1.WalletContractV5R1,
28
29
  };
29
30
  class MnemonicProvider {
30
31
  constructor(params) {
@@ -69,6 +70,7 @@ class MnemonicProvider {
69
70
  },
70
71
  },
71
72
  ],
73
+ sendMode: core_1.SendMode.PAY_GAS_SEPARATELY,
72
74
  });
73
75
  __classPrivateFieldGet(this, _MnemonicProvider_ui, "f").write('Sent transaction');
74
76
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ton/blueprint",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Framework for development of TON smart contracts",
5
5
  "main": "dist/index.js",
6
6
  "bin": "./dist/cli/cli.js",
@@ -19,9 +19,9 @@
19
19
  "format": "prettier --write src"
20
20
  },
21
21
  "devDependencies": {
22
- "@ton/core": "^0.56.0",
23
- "@ton/crypto": "^3.2.0",
24
- "@ton/ton": "^13.11.0",
22
+ "@ton/core": "^0.58.1",
23
+ "@ton/crypto": "^3.3.0",
24
+ "@ton/ton": "^15.0.0",
25
25
  "@types/inquirer": "^8.2.6",
26
26
  "@types/node": "^20.2.5",
27
27
  "@types/qrcode-terminal": "^0.12.0",
@@ -29,9 +29,9 @@
29
29
  "typescript": "^4.9.5"
30
30
  },
31
31
  "peerDependencies": {
32
- "@ton/core": ">=0.56.0",
33
- "@ton/crypto": ">=3.2.0",
34
- "@ton/ton": ">=13.11.0"
32
+ "@ton/core": ">=0.58.1",
33
+ "@ton/crypto": ">=3.3.0",
34
+ "@ton/ton": ">=15.0.0"
35
35
  },
36
36
  "dependencies": {
37
37
  "@tact-lang/compiler": "^1.4.0",
@@ -42,7 +42,6 @@
42
42
  "dotenv": "^16.1.4",
43
43
  "inquirer": "^8.2.5",
44
44
  "qrcode-terminal": "^0.12.0",
45
- "ton-x": "^2.1.0",
46
45
  "ts-node": "^10.9.1"
47
46
  },
48
47
  "packageManager": "yarn@4.3.1"
@@ -1,16 +0,0 @@
1
- import { Address, Cell, StateInit } from '@ton/core';
2
- import { SendProvider } from './SendProvider';
3
- import { Storage } from '../storage/Storage';
4
- import { UIProvider } from '../../ui/UIProvider';
5
- export declare class TonHubProvider implements SendProvider {
6
- #private;
7
- constructor(network: 'mainnet' | 'testnet', storage: Storage, ui: UIProvider);
8
- private getExistingSession;
9
- private getSession;
10
- connect(): Promise<void>;
11
- address(): Address | undefined;
12
- sendTransaction(address: Address, amount: bigint, payload?: Cell, stateInit?: StateInit): Promise<{
13
- type: "success";
14
- response: string;
15
- }>;
16
- }
@@ -1,110 +0,0 @@
1
- "use strict";
2
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
- if (kind === "m") throw new TypeError("Private method is not writable");
4
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
6
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
- };
8
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
11
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
- };
13
- var __importDefault = (this && this.__importDefault) || function (mod) {
14
- return (mod && mod.__esModule) ? mod : { "default": mod };
15
- };
16
- var _TonHubProvider_connector, _TonHubProvider_storage, _TonHubProvider_ui, _TonHubProvider_session;
17
- Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.TonHubProvider = void 0;
19
- const core_1 = require("@ton/core");
20
- const ton_x_1 = require("ton-x");
21
- const qrcode_terminal_1 = __importDefault(require("qrcode-terminal"));
22
- const KEY_NAME = 'tonhub_session';
23
- class TonHubProvider {
24
- constructor(network, storage, ui) {
25
- _TonHubProvider_connector.set(this, void 0);
26
- _TonHubProvider_storage.set(this, void 0);
27
- _TonHubProvider_ui.set(this, void 0);
28
- _TonHubProvider_session.set(this, void 0);
29
- __classPrivateFieldSet(this, _TonHubProvider_connector, new ton_x_1.TonhubConnector({
30
- network,
31
- }), "f");
32
- __classPrivateFieldSet(this, _TonHubProvider_storage, storage, "f");
33
- __classPrivateFieldSet(this, _TonHubProvider_ui, ui, "f");
34
- }
35
- async getExistingSession() {
36
- const sessionString = await __classPrivateFieldGet(this, _TonHubProvider_storage, "f").getItem(KEY_NAME);
37
- if (sessionString === null)
38
- return undefined;
39
- let session = JSON.parse(sessionString);
40
- const state = await __classPrivateFieldGet(this, _TonHubProvider_connector, "f").getSessionState(session.id);
41
- if (state.state === 'ready') {
42
- session = {
43
- ...state,
44
- id: session.id,
45
- seed: session.seed,
46
- };
47
- await __classPrivateFieldGet(this, _TonHubProvider_storage, "f").setItem(KEY_NAME, JSON.stringify(session));
48
- return session;
49
- }
50
- }
51
- async getSession() {
52
- const existing = await this.getExistingSession();
53
- if (existing !== undefined)
54
- return existing;
55
- const createdSession = await __classPrivateFieldGet(this, _TonHubProvider_connector, "f").createNewSession({
56
- name: 'TON template project',
57
- url: 'https://example.com/',
58
- });
59
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").setActionPrompt('Connecting to wallet...\n');
60
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").write('\n');
61
- qrcode_terminal_1.default.generate(createdSession.link, { small: true }, (qr) => __classPrivateFieldGet(this, _TonHubProvider_ui, "f").write(qr));
62
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").write('\n' + createdSession.link + '\n\n');
63
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").setActionPrompt('Scan the QR code in your wallet or open the link...');
64
- const state = await __classPrivateFieldGet(this, _TonHubProvider_connector, "f").awaitSessionReady(createdSession.id, 5 * 60 * 1000);
65
- if (state.state === 'ready') {
66
- const session = {
67
- ...state,
68
- id: createdSession.id,
69
- seed: createdSession.seed,
70
- };
71
- await __classPrivateFieldGet(this, _TonHubProvider_storage, "f").setItem(KEY_NAME, JSON.stringify(session));
72
- return session;
73
- }
74
- throw new Error('Could not create new session');
75
- }
76
- async connect() {
77
- __classPrivateFieldSet(this, _TonHubProvider_session, await this.getSession(), "f");
78
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").write(`Connected to wallet at address: ${core_1.Address.parse(__classPrivateFieldGet(this, _TonHubProvider_session, "f").wallet.address).toString()}\n`);
79
- }
80
- address() {
81
- if (!__classPrivateFieldGet(this, _TonHubProvider_session, "f"))
82
- return undefined;
83
- return core_1.Address.parse(__classPrivateFieldGet(this, _TonHubProvider_session, "f").wallet.address);
84
- }
85
- async sendTransaction(address, amount, payload, stateInit) {
86
- if (!__classPrivateFieldGet(this, _TonHubProvider_session, "f"))
87
- throw new Error('TonhubProvider is not connected');
88
- const request = {
89
- seed: __classPrivateFieldGet(this, _TonHubProvider_session, "f").seed,
90
- appPublicKey: __classPrivateFieldGet(this, _TonHubProvider_session, "f").wallet.appPublicKey,
91
- to: address.toString(),
92
- value: amount.toString(),
93
- timeout: 5 * 60 * 1000,
94
- payload: payload ? payload.toBoc().toString('base64') : undefined,
95
- stateInit: stateInit
96
- ? (0, core_1.beginCell)().storeWritable((0, core_1.storeStateInit)(stateInit)).endCell().toBoc().toString('base64')
97
- : undefined,
98
- };
99
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").setActionPrompt('Sending transaction. Approve it in your wallet...');
100
- const response = await __classPrivateFieldGet(this, _TonHubProvider_connector, "f").requestTransaction(request);
101
- if (response.type !== 'success') {
102
- throw new Error(`Tonhub transaction request was not successful (${response.type})`);
103
- }
104
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").clearActionPrompt();
105
- __classPrivateFieldGet(this, _TonHubProvider_ui, "f").write('Sent transaction');
106
- return response;
107
- }
108
- }
109
- exports.TonHubProvider = TonHubProvider;
110
- _TonHubProvider_connector = new WeakMap(), _TonHubProvider_storage = new WeakMap(), _TonHubProvider_ui = new WeakMap(), _TonHubProvider_session = new WeakMap();