@tonconnect/sdk 3.3.0-beta.0 → 3.3.0-beta.2

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/lib/esm/index.mjs CHANGED
@@ -3,7 +3,7 @@ export { CHAIN, CONNECT_EVENT_ERROR_CODES, CONNECT_ITEM_ERROR_CODES, SEND_TRANSA
3
3
  import '@tonconnect/isomorphic-eventsource';
4
4
  import '@tonconnect/isomorphic-fetch';
5
5
 
6
- /*! *****************************************************************************
6
+ /******************************************************************************
7
7
  Copyright (c) Microsoft Corporation.
8
8
 
9
9
  Permission to use, copy, modify, and/or distribute this software for any
@@ -17,6 +17,8 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
17
17
  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18
18
  PERFORMANCE OF THIS SOFTWARE.
19
19
  ***************************************************************************** */
20
+ /* global Reflect, Promise, SuppressedError, Symbol, Iterator */
21
+
20
22
 
21
23
  function __rest(s, e) {
22
24
  var t = {};
@@ -38,20 +40,25 @@ function __awaiter(thisArg, _arguments, P, generator) {
38
40
  function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
39
41
  step((generator = generator.apply(thisArg, _arguments || [])).next());
40
42
  });
41
- }
43
+ }
44
+
45
+ typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
46
+ var e = new Error(message);
47
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
48
+ };
42
49
 
43
50
  /**
44
51
  * Base class for TonConnect errors. You can check if the error was triggered by the @tonconnect/sdk using `err instanceof TonConnectError`.
45
52
  */
46
53
  class TonConnectError extends Error {
54
+ get info() {
55
+ return '';
56
+ }
47
57
  constructor(message, options) {
48
58
  super(message, options);
49
59
  this.message = `${TonConnectError.prefix} ${this.constructor.name}${this.info ? ': ' + this.info : ''}${message ? '\n' + message : ''}`;
50
60
  Object.setPrototypeOf(this, TonConnectError.prototype);
51
61
  }
52
- get info() {
53
- return '';
54
- }
55
62
  }
56
63
  TonConnectError.prefix = '[TON_CONNECT_SDK_ERROR]';
57
64
 
@@ -405,12 +412,12 @@ function delay(timeout, options) {
405
412
  return __awaiter(this, void 0, void 0, function* () {
406
413
  return new Promise((resolve, reject) => {
407
414
  var _a, _b;
408
- if ((_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.aborted) {
415
+ if ((_a = void 0 ) === null || _a === void 0 ? void 0 : _a.aborted) {
409
416
  reject(new TonConnectError('Delay aborted'));
410
417
  return;
411
418
  }
412
419
  const timeoutId = setTimeout(() => resolve(), timeout);
413
- (_b = options === null || options === void 0 ? void 0 : options.signal) === null || _b === void 0 ? void 0 : _b.addEventListener('abort', () => {
420
+ (_b = void 0 ) === null || _b === void 0 ? void 0 : _b.addEventListener('abort', () => {
414
421
  clearTimeout(timeoutId);
415
422
  reject(new TonConnectError('Delay aborted'));
416
423
  });
@@ -441,9 +448,10 @@ function createAbortController(signal) {
441
448
  * @param {T} fn - function to call
442
449
  * @param {CallForSuccessOptions} [options] - optional configuration options
443
450
  */
451
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
444
452
  function callForSuccess(fn, options) {
445
- var _a, _b;
446
453
  return __awaiter(this, void 0, void 0, function* () {
454
+ var _a, _b;
447
455
  const attempts = (_a = options === null || options === void 0 ? void 0 : options.attempts) !== null && _a !== void 0 ? _a : 10;
448
456
  const delayMs = (_b = options === null || options === void 0 ? void 0 : options.delayMs) !== null && _b !== void 0 ? _b : 200;
449
457
  const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
@@ -505,6 +513,7 @@ function logWarning(...args) {
505
513
  * @param {(...args: Args) => Promise<T>} createFn - A function that creates the resource.
506
514
  * @param {(resource: T) => Promise<void>} [disposeFn] - An optional function that disposes the resource.
507
515
  */
516
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
508
517
  function createResource(createFn, disposeFn) {
509
518
  let currentResource = null;
510
519
  let currentArgs = null;
@@ -614,6 +623,18 @@ function timeout(fn, options) {
614
623
  }
615
624
 
616
625
  class BridgeGateway {
626
+ get isReady() {
627
+ const eventSource = this.eventSource.current();
628
+ return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) === EventSource.OPEN;
629
+ }
630
+ get isClosed() {
631
+ const eventSource = this.eventSource.current();
632
+ return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) !== EventSource.OPEN;
633
+ }
634
+ get isConnecting() {
635
+ const eventSource = this.eventSource.current();
636
+ return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) === EventSource.CONNECTING;
637
+ }
617
638
  constructor(storage, bridgeUrl, sessionId, listener, errorsListener) {
618
639
  this.bridgeUrl = bridgeUrl;
619
640
  this.sessionId = sessionId;
@@ -642,26 +663,14 @@ class BridgeGateway {
642
663
  }));
643
664
  this.bridgeGatewayStorage = new HttpBridgeGatewayStorage(storage, bridgeUrl);
644
665
  }
645
- get isReady() {
646
- const eventSource = this.eventSource.current();
647
- return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) === EventSource.OPEN;
648
- }
649
- get isClosed() {
650
- const eventSource = this.eventSource.current();
651
- return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) !== EventSource.OPEN;
652
- }
653
- get isConnecting() {
654
- const eventSource = this.eventSource.current();
655
- return (eventSource === null || eventSource === void 0 ? void 0 : eventSource.readyState) === EventSource.CONNECTING;
656
- }
657
666
  registerSession(options) {
658
667
  return __awaiter(this, void 0, void 0, function* () {
659
668
  yield this.eventSource.create(options === null || options === void 0 ? void 0 : options.signal, options === null || options === void 0 ? void 0 : options.openingDeadlineMS);
660
669
  });
661
670
  }
662
671
  send(message, receiver, topic, ttlOrOptions) {
663
- var _a;
664
672
  return __awaiter(this, void 0, void 0, function* () {
673
+ var _a;
665
674
  // TODO: remove deprecated method
666
675
  const options = {};
667
676
  if (typeof ttlOrOptions === 'number') {
@@ -1010,6 +1019,16 @@ class BridgeConnectionStorage {
1010
1019
  const PROTOCOL_VERSION = 2;
1011
1020
 
1012
1021
  class BridgeProvider {
1022
+ static fromStorage(storage) {
1023
+ return __awaiter(this, void 0, void 0, function* () {
1024
+ const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
1025
+ const connection = yield bridgeConnectionStorage.getHttpConnection();
1026
+ if (isPendingConnectionHttp(connection)) {
1027
+ return new BridgeProvider(storage, connection.connectionSource);
1028
+ }
1029
+ return new BridgeProvider(storage, { bridgeUrl: connection.session.bridgeUrl });
1030
+ });
1031
+ }
1013
1032
  constructor(storage, walletConnectionSource) {
1014
1033
  this.storage = storage;
1015
1034
  this.walletConnectionSource = walletConnectionSource;
@@ -1024,16 +1043,6 @@ class BridgeProvider {
1024
1043
  this.defaultRetryTimeoutMS = 2000;
1025
1044
  this.connectionStorage = new BridgeConnectionStorage(storage);
1026
1045
  }
1027
- static fromStorage(storage) {
1028
- return __awaiter(this, void 0, void 0, function* () {
1029
- const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
1030
- const connection = yield bridgeConnectionStorage.getHttpConnection();
1031
- if (isPendingConnectionHttp(connection)) {
1032
- return new BridgeProvider(storage, connection.connectionSource);
1033
- }
1034
- return new BridgeProvider(storage, { bridgeUrl: connection.session.bridgeUrl });
1035
- });
1036
- }
1037
1046
  connect(message, options) {
1038
1047
  var _a;
1039
1048
  const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
@@ -1076,8 +1085,8 @@ class BridgeProvider {
1076
1085
  return this.generateUniversalLink(universalLink, message);
1077
1086
  }
1078
1087
  restoreConnection(options) {
1079
- var _a, _b;
1080
1088
  return __awaiter(this, void 0, void 0, function* () {
1089
+ var _a, _b;
1081
1090
  const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
1082
1091
  (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
1083
1092
  this.abortController = abortController;
@@ -1423,15 +1432,15 @@ function isJSBridgeWithMetadata(value) {
1423
1432
  * Uses as a fallback for localStorage in Safari's private mode.
1424
1433
  */
1425
1434
  class InMemoryStorage {
1426
- constructor() {
1427
- this.storage = {};
1428
- }
1429
1435
  static getInstance() {
1430
1436
  if (!InMemoryStorage.instance) {
1431
1437
  InMemoryStorage.instance = new InMemoryStorage();
1432
1438
  }
1433
1439
  return InMemoryStorage.instance;
1434
1440
  }
1441
+ constructor() {
1442
+ this.storage = {};
1443
+ }
1435
1444
  get length() {
1436
1445
  return Object.keys(this.storage).length;
1437
1446
  }
@@ -1526,19 +1535,6 @@ function isNodeJs() {
1526
1535
  }
1527
1536
 
1528
1537
  class InjectedProvider {
1529
- constructor(storage, injectedWalletKey) {
1530
- this.injectedWalletKey = injectedWalletKey;
1531
- this.type = 'injected';
1532
- this.unsubscribeCallback = null;
1533
- this.listenSubscriptions = false;
1534
- this.listeners = [];
1535
- const window = InjectedProvider.window;
1536
- if (!InjectedProvider.isWindowContainsWallet(window, injectedWalletKey)) {
1537
- throw new WalletNotInjectedError();
1538
- }
1539
- this.connectionStorage = new BridgeConnectionStorage(storage);
1540
- this.injectedWallet = window[injectedWalletKey].tonconnect;
1541
- }
1542
1538
  static fromStorage(storage) {
1543
1539
  return __awaiter(this, void 0, void 0, function* () {
1544
1540
  const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
@@ -1580,6 +1576,19 @@ class InjectedProvider {
1580
1576
  typeof window[injectedWalletKey] === 'object' &&
1581
1577
  'tonconnect' in window[injectedWalletKey]);
1582
1578
  }
1579
+ constructor(storage, injectedWalletKey) {
1580
+ this.injectedWalletKey = injectedWalletKey;
1581
+ this.type = 'injected';
1582
+ this.unsubscribeCallback = null;
1583
+ this.listenSubscriptions = false;
1584
+ this.listeners = [];
1585
+ const window = InjectedProvider.window;
1586
+ if (!InjectedProvider.isWindowContainsWallet(window, injectedWalletKey)) {
1587
+ throw new WalletNotInjectedError();
1588
+ }
1589
+ this.connectionStorage = new BridgeConnectionStorage(storage);
1590
+ this.injectedWallet = window[injectedWalletKey].tonconnect;
1591
+ }
1583
1592
  connect(message) {
1584
1593
  this._connect(PROTOCOL_VERSION, message);
1585
1594
  }
@@ -1641,8 +1650,8 @@ class InjectedProvider {
1641
1650
  return () => (this.listeners = this.listeners.filter(listener => listener !== eventsCallback));
1642
1651
  }
1643
1652
  sendRequest(request, optionsOrOnRequestSent) {
1644
- var _a;
1645
1653
  return __awaiter(this, void 0, void 0, function* () {
1654
+ var _a;
1646
1655
  // TODO: remove deprecated method
1647
1656
  const options = {};
1648
1657
  if (typeof optionsOrOnRequestSent === 'function') {
@@ -2081,13 +2090,133 @@ const FALLBACK_WALLETS_LIST = [
2081
2090
  }
2082
2091
  ];
2083
2092
 
2093
+ let qaModeEnabled = false;
2094
+ let bannerObserver = null;
2095
+ function enableQaMode() {
2096
+ qaModeEnabled = true;
2097
+ console.warn('🚨 QA Mode enabled - validation is disabled. This is unsafe for production!');
2098
+ showQaModeBanner();
2099
+ startBannerObserver();
2100
+ addQaModeStyles();
2101
+ }
2102
+ function isQaModeEnabled() {
2103
+ return qaModeEnabled;
2104
+ }
2105
+ function logValidationError(message) {
2106
+ if (isQaModeEnabled()) {
2107
+ console.error(`[QA Mode] Validation failed: ${message}`);
2108
+ }
2109
+ }
2110
+ function showQaModeBanner() {
2111
+ if (typeof window === 'undefined')
2112
+ return;
2113
+ const existingBanner = document.getElementById('ton-connect-qa-banner');
2114
+ if (existingBanner)
2115
+ return;
2116
+ const banner = document.createElement('div');
2117
+ banner.id = 'ton-connect-qa-banner';
2118
+ banner.style.cssText = `
2119
+ position: fixed;
2120
+ top: 0;
2121
+ left: 0;
2122
+ right: 0;
2123
+ background: linear-gradient(90deg, #ff6b6b, #ff8e8e);
2124
+ color: white;
2125
+ padding: 12px 20px;
2126
+ text-align: center;
2127
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
2128
+ font-weight: 600;
2129
+ font-size: 14px;
2130
+ z-index: 999999;
2131
+ box-shadow: 0 2px 8px rgba(0,0,0,0.2);
2132
+ animation: slideDown 0.3s ease-out;
2133
+ user-select: none;
2134
+ pointer-events: none;
2135
+ `;
2136
+ banner.innerHTML = `
2137
+ 🚨 QA Mode Active - Validation Disabled (Unsafe for Production)
2138
+ `;
2139
+ // Add CSS animation
2140
+ const style = document.createElement('style');
2141
+ style.textContent = `
2142
+ @keyframes slideDown {
2143
+ from { transform: translateY(-100%); }
2144
+ to { transform: translateY(0); }
2145
+ }
2146
+ `;
2147
+ document.head.appendChild(style);
2148
+ document.body.appendChild(banner);
2149
+ addQaModeStyles();
2150
+ }
2151
+ function addQaModeStyles() {
2152
+ if (typeof window === 'undefined')
2153
+ return;
2154
+ const existingStyle = document.getElementById('ton-connect-qa-mode-styles');
2155
+ if (existingStyle)
2156
+ return;
2157
+ const style = document.createElement('style');
2158
+ style.id = 'ton-connect-qa-mode-styles';
2159
+ style.textContent = `
2160
+ body.qa-mode-active {
2161
+ padding-top: 48px !important;
2162
+ }
2163
+
2164
+ body.qa-mode-active header {
2165
+ margin-top: 48px !important;
2166
+ }
2167
+
2168
+ body.qa-mode-active .qa-mode-control {
2169
+ top: 128px !important;
2170
+ }
2171
+ `;
2172
+ document.head.appendChild(style);
2173
+ document.body.classList.add('qa-mode-active');
2174
+ }
2175
+ function startBannerObserver() {
2176
+ if (typeof window === 'undefined' || bannerObserver)
2177
+ return;
2178
+ bannerObserver = new MutationObserver(mutations => {
2179
+ mutations.forEach(mutation => {
2180
+ if (mutation.type === 'childList') {
2181
+ mutation.removedNodes.forEach(node => {
2182
+ if (node.nodeType === Node.ELEMENT_NODE) {
2183
+ const element = node;
2184
+ if (element.id === 'ton-connect-qa-banner' && qaModeEnabled) {
2185
+ console.warn('QA Mode banner was removed, restoring...');
2186
+ setTimeout(() => showQaModeBanner(), 100);
2187
+ }
2188
+ else if (element.id === 'ton-connect-qa-mode-styles' && qaModeEnabled) {
2189
+ console.warn('QA Mode styles were removed, restoring...');
2190
+ setTimeout(() => addQaModeStyles(), 100);
2191
+ }
2192
+ }
2193
+ });
2194
+ }
2195
+ });
2196
+ });
2197
+ bannerObserver.observe(document.body, {
2198
+ childList: true,
2199
+ subtree: false
2200
+ });
2201
+ bannerObserver.observe(document.head, {
2202
+ childList: true,
2203
+ subtree: false
2204
+ });
2205
+ }
2206
+
2084
2207
  class WalletsListManager {
2085
2208
  constructor(options) {
2086
2209
  var _a;
2087
2210
  this.walletsListCache = null;
2088
2211
  this.walletsListCacheCreationTimestamp = null;
2089
- this.walletsListSource =
2090
- (_a = options === null || options === void 0 ? void 0 : options.walletsListSource) !== null && _a !== void 0 ? _a : 'https://raw.githubusercontent.com/ton-blockchain/wallets-list/main/wallets-v2.json';
2212
+ if (isQaModeEnabled()) {
2213
+ this.walletsListSource =
2214
+ 'https://raw.githubusercontent.com/ton-connect/wallets-list-staging/refs/heads/main/wallets-v2.json';
2215
+ }
2216
+ else {
2217
+ this.walletsListSource =
2218
+ (_a = options === null || options === void 0 ? void 0 : options.walletsListSource) !== null && _a !== void 0 ? _a : 'https://raw.githubusercontent.com/ton-blockchain/wallets-list/main/wallets-v2.json';
2219
+ }
2091
2220
  this.cacheTTLMs = options === null || options === void 0 ? void 0 : options.cacheTTLMs;
2092
2221
  }
2093
2222
  getWallets() {
@@ -2514,8 +2643,8 @@ class BrowserEventDispatcher {
2514
2643
  * @returns A promise that resolves when the event has been dispatched.
2515
2644
  */
2516
2645
  dispatchEvent(eventName, eventDetails) {
2517
- var _a;
2518
2646
  return __awaiter(this, void 0, void 0, function* () {
2647
+ var _a;
2519
2648
  const event = new CustomEvent(eventName, { detail: eventDetails });
2520
2649
  (_a = this.window) === null || _a === void 0 ? void 0 : _a.dispatchEvent(event);
2521
2650
  });
@@ -2528,8 +2657,8 @@ class BrowserEventDispatcher {
2528
2657
  * @returns A function that removes the listener.
2529
2658
  */
2530
2659
  addEventListener(eventName, listener, options) {
2531
- var _a;
2532
2660
  return __awaiter(this, void 0, void 0, function* () {
2661
+ var _a;
2533
2662
  (_a = this.window) === null || _a === void 0 ? void 0 : _a.addEventListener(eventName, listener, options);
2534
2663
  return () => {
2535
2664
  var _a;
@@ -2567,6 +2696,15 @@ class BrowserEventDispatcher {
2567
2696
  * @internal
2568
2697
  */
2569
2698
  class TonConnectTracker {
2699
+ /**
2700
+ * Version of the library.
2701
+ */
2702
+ get version() {
2703
+ return createVersionInfo({
2704
+ ton_connect_sdk_lib: this.tonConnectSdkVersion,
2705
+ ton_connect_ui_lib: this.tonConnectUiVersion
2706
+ });
2707
+ }
2570
2708
  constructor(options) {
2571
2709
  var _a;
2572
2710
  /**
@@ -2582,15 +2720,6 @@ class TonConnectTracker {
2582
2720
  this.tonConnectSdkVersion = options.tonConnectSdkVersion;
2583
2721
  this.init().catch();
2584
2722
  }
2585
- /**
2586
- * Version of the library.
2587
- */
2588
- get version() {
2589
- return createVersionInfo({
2590
- ton_connect_sdk_lib: this.tonConnectSdkVersion,
2591
- ton_connect_ui_lib: this.tonConnectUiVersion
2592
- });
2593
- }
2594
2723
  /**
2595
2724
  * Called once when the tracker is created and request version other libraries.
2596
2725
  */
@@ -2791,36 +2920,384 @@ class TonConnectTracker {
2791
2920
  }
2792
2921
  }
2793
2922
 
2794
- const tonConnectSdkVersion = "3.3.0-beta.0";
2923
+ const tonConnectSdkVersion = "3.3.0-beta.2";
2795
2924
 
2796
- class TonConnect {
2797
- constructor(options) {
2798
- this.walletsList = new WalletsListManager();
2799
- this._wallet = null;
2800
- this.provider = null;
2801
- this.statusChangeSubscriptions = [];
2802
- this.statusChangeErrorSubscriptions = [];
2803
- this.dappSettings = {
2804
- manifestUrl: (options === null || options === void 0 ? void 0 : options.manifestUrl) || getWebPageManifest(),
2805
- storage: (options === null || options === void 0 ? void 0 : options.storage) || new DefaultStorage()
2806
- };
2807
- this.walletsRequiredFeatures = options === null || options === void 0 ? void 0 : options.walletsRequiredFeatures;
2808
- this.walletsList = new WalletsListManager({
2809
- walletsListSource: options === null || options === void 0 ? void 0 : options.walletsListSource,
2810
- cacheTTLMs: options === null || options === void 0 ? void 0 : options.walletsListCacheTTLMs
2811
- });
2812
- this.tracker = new TonConnectTracker({
2813
- eventDispatcher: options === null || options === void 0 ? void 0 : options.eventDispatcher,
2814
- tonConnectSdkVersion: tonConnectSdkVersion
2815
- });
2816
- if (!this.dappSettings.manifestUrl) {
2817
- throw new DappMetadataError('Dapp tonconnect-manifest.json must be specified if window.location.origin is undefined. See more https://github.com/ton-connect/docs/blob/main/requests-responses.md#app-manifest');
2925
+ const noBounceableTag = 0x51;
2926
+ const testOnlyTag = 0x80;
2927
+ /**
2928
+ * Converts raw TON address to no-bounceable user-friendly format. [See details]{@link https://ton.org/docs/learn/overviews/addresses#user-friendly-address}
2929
+ * @param hexAddress raw TON address formatted as "0:<hex string without 0x>".
2930
+ * @param [testOnly=false] convert address to test-only form. [See details]{@link https://ton.org/docs/learn/overviews/addresses#user-friendly-address}
2931
+ */
2932
+ function toUserFriendlyAddress(hexAddress, testOnly = false) {
2933
+ const { wc, hex } = parseHexAddress(hexAddress);
2934
+ let tag = noBounceableTag;
2935
+ if (testOnly) {
2936
+ tag |= testOnlyTag;
2937
+ }
2938
+ const addr = new Int8Array(34);
2939
+ addr[0] = tag;
2940
+ addr[1] = wc;
2941
+ addr.set(hex, 2);
2942
+ const addressWithChecksum = new Uint8Array(36);
2943
+ addressWithChecksum.set(addr);
2944
+ addressWithChecksum.set(crc16(addr), 34);
2945
+ let addressBase64 = Base64.encode(addressWithChecksum);
2946
+ return addressBase64.replace(/\+/g, '-').replace(/\//g, '_');
2947
+ }
2948
+ /**
2949
+ * Validates if the address is in user-friendly format by attempting to parse it.
2950
+ * @param address address to validate
2951
+ * @returns true if the address is valid user-friendly format, false otherwise
2952
+ */
2953
+ function isValidUserFriendlyAddress(address) {
2954
+ try {
2955
+ parseUserFriendlyAddress(address);
2956
+ return true;
2957
+ }
2958
+ catch (_a) {
2959
+ return false;
2960
+ }
2961
+ }
2962
+ /**
2963
+ * Validates if the address is in raw hex format (e.g., "0:1234..." or "-1:1234...").
2964
+ * @param address address to validate
2965
+ * @returns true if the address is valid raw format, false otherwise
2966
+ */
2967
+ function isValidRawAddress(address) {
2968
+ try {
2969
+ parseHexAddress(address);
2970
+ return true;
2971
+ }
2972
+ catch (_a) {
2973
+ return false;
2974
+ }
2975
+ }
2976
+ /**
2977
+ * Parses user-friendly address and returns its components.
2978
+ * @param address user-friendly address
2979
+ * @returns parsed address components
2980
+ */
2981
+ function parseUserFriendlyAddress(address) {
2982
+ const base64 = address.replace(/-/g, '+').replace(/_/g, '/');
2983
+ let decoded;
2984
+ try {
2985
+ decoded = Base64.decode(base64).toUint8Array();
2986
+ }
2987
+ catch (_a) {
2988
+ throw new WrongAddressError(`Invalid base64 encoding in address: ${address}`);
2989
+ }
2990
+ if (decoded.length !== 36) {
2991
+ throw new WrongAddressError(`Invalid address length: ${address}`);
2992
+ }
2993
+ const addr = decoded.slice(0, 34);
2994
+ const checksum = decoded.slice(34);
2995
+ const calculatedChecksum = crc16(addr);
2996
+ if (!checksum.every((byte, i) => byte === calculatedChecksum[i])) {
2997
+ throw new WrongAddressError(`Invalid checksum in address: ${address}`);
2998
+ }
2999
+ const tag = addr[0];
3000
+ const wc = addr[1];
3001
+ const hex = addr.slice(2);
3002
+ if (wc !== 0 && wc !== -1) {
3003
+ throw new WrongAddressError(`Invalid workchain: ${wc}`);
3004
+ }
3005
+ const testOnly = (tag & testOnlyTag) !== 0;
3006
+ const isBounceable = (tag & 0x40) !== 0;
3007
+ return {
3008
+ wc,
3009
+ hex: Array.from(hex)
3010
+ .map(b => b.toString(16).padStart(2, '0'))
3011
+ .join(''),
3012
+ testOnly,
3013
+ isBounceable
3014
+ };
3015
+ }
3016
+ function parseHexAddress(hexAddress) {
3017
+ if (!hexAddress.includes(':')) {
3018
+ throw new WrongAddressError(`Wrong address ${hexAddress}. Address must include ":".`);
3019
+ }
3020
+ const parts = hexAddress.split(':');
3021
+ if (parts.length !== 2) {
3022
+ throw new WrongAddressError(`Wrong address ${hexAddress}. Address must include ":" only once.`);
3023
+ }
3024
+ const wc = parseInt(parts[0]);
3025
+ if (wc !== 0 && wc !== -1) {
3026
+ throw new WrongAddressError(`Wrong address ${hexAddress}. WC must be eq 0 or -1, but ${wc} received.`);
3027
+ }
3028
+ const hex = parts[1];
3029
+ if ((hex === null || hex === void 0 ? void 0 : hex.length) !== 64) {
3030
+ throw new WrongAddressError(`Wrong address ${hexAddress}. Hex part must be 64bytes length, but ${hex === null || hex === void 0 ? void 0 : hex.length} received.`);
3031
+ }
3032
+ return {
3033
+ wc,
3034
+ hex: hexToBytes(hex)
3035
+ };
3036
+ }
3037
+ function crc16(data) {
3038
+ const poly = 0x1021;
3039
+ let reg = 0;
3040
+ const message = new Uint8Array(data.length + 2);
3041
+ message.set(data);
3042
+ for (let byte of message) {
3043
+ let mask = 0x80;
3044
+ while (mask > 0) {
3045
+ reg <<= 1;
3046
+ if (byte & mask) {
3047
+ reg += 1;
3048
+ }
3049
+ mask >>= 1;
3050
+ if (reg > 0xffff) {
3051
+ reg &= 0xffff;
3052
+ reg ^= poly;
3053
+ }
2818
3054
  }
2819
- this.bridgeConnectionStorage = new BridgeConnectionStorage(this.dappSettings.storage);
2820
- if (!(options === null || options === void 0 ? void 0 : options.disableAutoPauseConnection)) {
2821
- this.addWindowFocusAndBlurSubscriptions();
3055
+ }
3056
+ return new Uint8Array([Math.floor(reg / 256), reg % 256]);
3057
+ }
3058
+ const toByteMap = {};
3059
+ for (let ord = 0; ord <= 0xff; ord++) {
3060
+ let s = ord.toString(16);
3061
+ if (s.length < 2) {
3062
+ s = '0' + s;
3063
+ }
3064
+ toByteMap[s] = ord;
3065
+ }
3066
+ function hexToBytes(hex) {
3067
+ hex = hex.toLowerCase();
3068
+ const length2 = hex.length;
3069
+ if (length2 % 2 !== 0) {
3070
+ throw new ParseHexError('Hex string must have length a multiple of 2: ' + hex);
3071
+ }
3072
+ const length = length2 / 2;
3073
+ const result = new Uint8Array(length);
3074
+ for (let i = 0; i < length; i++) {
3075
+ const doubled = i * 2;
3076
+ const hexSubstring = hex.substring(doubled, doubled + 2);
3077
+ if (!toByteMap.hasOwnProperty(hexSubstring)) {
3078
+ throw new ParseHexError('Invalid hex character: ' + hexSubstring);
3079
+ }
3080
+ result[i] = toByteMap[hexSubstring];
3081
+ }
3082
+ return result;
3083
+ }
3084
+
3085
+ const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
3086
+ const BOC_PREFIX = 'te6cc';
3087
+ const INTEGER_REGEX = /^-?\d+$/;
3088
+ const POSITIVE_INTEGER_REGEX = /^\d+$/;
3089
+ function isValidNumber(value) {
3090
+ return typeof value === 'number' && !isNaN(value);
3091
+ }
3092
+ function isValidString(value) {
3093
+ return typeof value === 'string' && value.length > 0;
3094
+ }
3095
+ function isValidBoc(value) {
3096
+ return typeof value === 'string' && BASE64_REGEX.test(value) && value.startsWith(BOC_PREFIX);
3097
+ }
3098
+ function isValidObject(value) {
3099
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
3100
+ }
3101
+ function isValidArray(value) {
3102
+ return Array.isArray(value);
3103
+ }
3104
+ function hasExtraProperties(obj, allowedKeys) {
3105
+ return Object.keys(obj).some(key => !allowedKeys.includes(key));
3106
+ }
3107
+ function validateSendTransactionRequest(data) {
3108
+ // eslint-disable-next-line no-console
3109
+ console.log('[Validation Debug] validateSendTransactionRequest called');
3110
+ // eslint-disable-next-line no-console
3111
+ console.log('[Validation Debug] isQaModeEnabled():', isQaModeEnabled());
3112
+ if (!isValidObject(data)) {
3113
+ const error = 'Request must be an object';
3114
+ logValidationError(error);
3115
+ const shouldReturnNull = isQaModeEnabled();
3116
+ // eslint-disable-next-line no-console
3117
+ console.log('[Validation Debug] Should return null:', shouldReturnNull);
3118
+ return shouldReturnNull ? null : error;
3119
+ }
3120
+ const allowedKeys = ['validUntil', 'network', 'from', 'messages'];
3121
+ if (hasExtraProperties(data, allowedKeys)) {
3122
+ const error = 'Request contains extra properties';
3123
+ logValidationError(error);
3124
+ return isQaModeEnabled() ? null : error;
3125
+ }
3126
+ if (!isValidNumber(data.validUntil)) {
3127
+ const error = "Incorrect 'validUntil'";
3128
+ logValidationError(error);
3129
+ return isQaModeEnabled() ? null : error;
3130
+ }
3131
+ const now = Math.floor(Date.now() / 1000);
3132
+ const fiveMinutesFromNow = now + 300;
3133
+ if (data.validUntil > fiveMinutesFromNow) {
3134
+ console.warn(`validUntil (${data.validUntil}) is more than 5 minutes from now (${now})`);
3135
+ }
3136
+ if (data.network !== undefined) {
3137
+ if (!isValidString(data.network) || !/^[\d-]+$/.test(data.network)) {
3138
+ const error = "Invalid 'network' format";
3139
+ logValidationError(error);
3140
+ return isQaModeEnabled() ? null : error;
3141
+ }
3142
+ }
3143
+ if (data.from !== undefined) {
3144
+ if (!isValidString(data.from) || !isValidRawAddress(data.from)) {
3145
+ const error = "Invalid 'from' address format";
3146
+ logValidationError(error);
3147
+ return isQaModeEnabled() ? null : error;
2822
3148
  }
2823
3149
  }
3150
+ if (!isValidArray(data.messages) || data.messages.length === 0) {
3151
+ const error = "'messages' is required";
3152
+ logValidationError(error);
3153
+ return isQaModeEnabled() ? null : error;
3154
+ }
3155
+ for (let i = 0; i < data.messages.length; i++) {
3156
+ const message = data.messages[i];
3157
+ const messageError = validateTransactionMessage(message, i);
3158
+ if (messageError) {
3159
+ return messageError;
3160
+ }
3161
+ }
3162
+ return null;
3163
+ }
3164
+ function validateTransactionMessage(message, index) {
3165
+ if (!isValidObject(message)) {
3166
+ return `Message at index ${index} must be an object`;
3167
+ }
3168
+ const allowedKeys = ['address', 'amount', 'stateInit', 'payload', 'extraCurrency'];
3169
+ if (hasExtraProperties(message, allowedKeys)) {
3170
+ return `Message at index ${index} contains extra properties`;
3171
+ }
3172
+ if (!isValidString(message.address)) {
3173
+ return `'address' is required in message at index ${index}`;
3174
+ }
3175
+ if (!isValidUserFriendlyAddress(message.address)) {
3176
+ return `Wrong 'address' format in message at index ${index}`;
3177
+ }
3178
+ if (!isValidString(message.amount)) {
3179
+ return `'amount' is required in message at index ${index}`;
3180
+ }
3181
+ if (!/^[0-9]+$/.test(message.amount)) {
3182
+ return `Incorrect 'amount' in message at index ${index}`;
3183
+ }
3184
+ if (message.stateInit !== undefined) {
3185
+ if (!isValidString(message.stateInit) || !isValidBoc(message.stateInit)) {
3186
+ return `Invalid 'stateInit' in message at index ${index}`;
3187
+ }
3188
+ }
3189
+ if (message.payload !== undefined) {
3190
+ if (!isValidString(message.payload) || !isValidBoc(message.payload)) {
3191
+ return `Invalid 'payload' in message at index ${index}`;
3192
+ }
3193
+ }
3194
+ if (message.extraCurrency !== undefined) {
3195
+ if (!isValidObject(message.extraCurrency)) {
3196
+ return `Invalid 'extraCurrency' in message at index ${index}`;
3197
+ }
3198
+ for (const [key, value] of Object.entries(message.extraCurrency)) {
3199
+ if (!INTEGER_REGEX.test(key) ||
3200
+ typeof value !== 'string' ||
3201
+ !POSITIVE_INTEGER_REGEX.test(value)) {
3202
+ return `Invalid 'extraCurrency' format in message at index ${index}`;
3203
+ }
3204
+ }
3205
+ }
3206
+ return null;
3207
+ }
3208
+ function validateConnectAdditionalRequest(data) {
3209
+ if (!isValidObject(data)) {
3210
+ return 'Request must be an object';
3211
+ }
3212
+ const allowedKeys = ['tonProof'];
3213
+ if (hasExtraProperties(data, allowedKeys)) {
3214
+ return 'Request contains extra properties';
3215
+ }
3216
+ if (data.tonProof !== undefined && !isValidString(data.tonProof)) {
3217
+ return "Invalid 'tonProof'";
3218
+ }
3219
+ return null;
3220
+ }
3221
+ function validateSignDataPayload(data) {
3222
+ if (!isValidObject(data)) {
3223
+ return 'Payload must be an object';
3224
+ }
3225
+ if (!isValidString(data.type)) {
3226
+ return "'type' is required";
3227
+ }
3228
+ switch (data.type) {
3229
+ case 'text':
3230
+ return validateSignDataPayloadText(data);
3231
+ case 'binary':
3232
+ return validateSignDataPayloadBinary(data);
3233
+ case 'cell':
3234
+ return validateSignDataPayloadCell(data);
3235
+ default:
3236
+ return "Invalid 'type' value";
3237
+ }
3238
+ }
3239
+ function validateSignDataPayloadText(data) {
3240
+ const allowedKeys = ['type', 'text', 'network', 'from'];
3241
+ if (hasExtraProperties(data, allowedKeys)) {
3242
+ return 'Text payload contains extra properties';
3243
+ }
3244
+ if (!isValidString(data.text)) {
3245
+ return "'text' is required";
3246
+ }
3247
+ if (data.network !== undefined) {
3248
+ if (!isValidString(data.network) || !/^\d+$/.test(data.network)) {
3249
+ return "Invalid 'network' format";
3250
+ }
3251
+ }
3252
+ if (data.from !== undefined && !isValidString(data.from)) {
3253
+ return "Invalid 'from'";
3254
+ }
3255
+ return null;
3256
+ }
3257
+ function validateSignDataPayloadBinary(data) {
3258
+ const allowedKeys = ['type', 'bytes', 'network', 'from'];
3259
+ if (hasExtraProperties(data, allowedKeys)) {
3260
+ return 'Binary payload contains extra properties';
3261
+ }
3262
+ if (!isValidString(data.bytes)) {
3263
+ return "'bytes' is required";
3264
+ }
3265
+ if (data.network !== undefined) {
3266
+ if (!isValidString(data.network) || !/^\d+$/.test(data.network)) {
3267
+ return "Invalid 'network' format";
3268
+ }
3269
+ }
3270
+ if (data.from !== undefined && !isValidString(data.from)) {
3271
+ return "Invalid 'from'";
3272
+ }
3273
+ return null;
3274
+ }
3275
+ function validateSignDataPayloadCell(data) {
3276
+ const allowedKeys = ['type', 'schema', 'cell', 'network', 'from'];
3277
+ if (hasExtraProperties(data, allowedKeys)) {
3278
+ return 'Cell payload contains extra properties';
3279
+ }
3280
+ if (!isValidString(data.schema)) {
3281
+ return "'schema' is required";
3282
+ }
3283
+ if (!isValidString(data.cell)) {
3284
+ return "'cell' is required";
3285
+ }
3286
+ if (!isValidBoc(data.cell)) {
3287
+ return "Invalid 'cell' format (must be valid base64)";
3288
+ }
3289
+ if (data.network !== undefined) {
3290
+ if (!isValidString(data.network) || !/^\d+$/.test(data.network)) {
3291
+ return "Invalid 'network' format";
3292
+ }
3293
+ }
3294
+ if (data.from !== undefined && !isValidString(data.from)) {
3295
+ return "Invalid 'from'";
3296
+ }
3297
+ return null;
3298
+ }
3299
+
3300
+ class TonConnect {
2824
3301
  /**
2825
3302
  * Returns available wallets list.
2826
3303
  */
@@ -2850,6 +3327,33 @@ class TonConnect {
2850
3327
  this._wallet = value;
2851
3328
  this.statusChangeSubscriptions.forEach(callback => callback(this._wallet));
2852
3329
  }
3330
+ constructor(options) {
3331
+ this.walletsList = new WalletsListManager();
3332
+ this._wallet = null;
3333
+ this.provider = null;
3334
+ this.statusChangeSubscriptions = [];
3335
+ this.statusChangeErrorSubscriptions = [];
3336
+ this.dappSettings = {
3337
+ manifestUrl: (options === null || options === void 0 ? void 0 : options.manifestUrl) || getWebPageManifest(),
3338
+ storage: (options === null || options === void 0 ? void 0 : options.storage) || new DefaultStorage()
3339
+ };
3340
+ this.walletsRequiredFeatures = options === null || options === void 0 ? void 0 : options.walletsRequiredFeatures;
3341
+ this.walletsList = new WalletsListManager({
3342
+ walletsListSource: options === null || options === void 0 ? void 0 : options.walletsListSource,
3343
+ cacheTTLMs: options === null || options === void 0 ? void 0 : options.walletsListCacheTTLMs
3344
+ });
3345
+ this.tracker = new TonConnectTracker({
3346
+ eventDispatcher: options === null || options === void 0 ? void 0 : options.eventDispatcher,
3347
+ tonConnectSdkVersion: tonConnectSdkVersion
3348
+ });
3349
+ if (!this.dappSettings.manifestUrl) {
3350
+ throw new DappMetadataError('Dapp tonconnect-manifest.json must be specified if window.location.origin is undefined. See more https://github.com/ton-connect/docs/blob/main/requests-responses.md#app-manifest');
3351
+ }
3352
+ this.bridgeConnectionStorage = new BridgeConnectionStorage(this.dappSettings.storage);
3353
+ if (!(options === null || options === void 0 ? void 0 : options.disableAutoPauseConnection)) {
3354
+ this.addWindowFocusAndBlurSubscriptions();
3355
+ }
3356
+ }
2853
3357
  /**
2854
3358
  * Returns available wallets list.
2855
3359
  */
@@ -2889,6 +3393,17 @@ class TonConnect {
2889
3393
  options.openingDeadlineMS = requestOrOptions === null || requestOrOptions === void 0 ? void 0 : requestOrOptions.openingDeadlineMS;
2890
3394
  options.signal = requestOrOptions === null || requestOrOptions === void 0 ? void 0 : requestOrOptions.signal;
2891
3395
  }
3396
+ if (options.request) {
3397
+ const validationError = validateConnectAdditionalRequest(options.request);
3398
+ if (validationError) {
3399
+ if (isQaModeEnabled()) {
3400
+ console.error('ConnectAdditionalRequest validation failed: ' + validationError);
3401
+ }
3402
+ else {
3403
+ throw new TonConnectError('ConnectAdditionalRequest validation failed: ' + validationError);
3404
+ }
3405
+ }
3406
+ }
2892
3407
  if (this.connected) {
2893
3408
  throw new WalletAlreadyConnectedError();
2894
3409
  }
@@ -2915,8 +3430,8 @@ class TonConnect {
2915
3430
  * Try to restore existing session and reconnect to the corresponding wallet. Call it immediately when your app is loaded.
2916
3431
  */
2917
3432
  restoreConnection(options) {
2918
- var _a, _b;
2919
3433
  return __awaiter(this, void 0, void 0, function* () {
3434
+ var _a, _b;
2920
3435
  this.tracker.trackConnectionRestoringStarted();
2921
3436
  const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
2922
3437
  (_a = this.abortController) === null || _a === void 0 ? void 0 : _a.abort();
@@ -3011,6 +3526,16 @@ class TonConnect {
3011
3526
  options.onRequestSent = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.onRequestSent;
3012
3527
  options.signal = optionsOrOnRequestSent === null || optionsOrOnRequestSent === void 0 ? void 0 : optionsOrOnRequestSent.signal;
3013
3528
  }
3529
+ // Validate transaction
3530
+ const validationError = validateSendTransactionRequest(transaction);
3531
+ if (validationError) {
3532
+ if (isQaModeEnabled()) {
3533
+ console.error('SendTransactionRequest validation failed: ' + validationError);
3534
+ }
3535
+ else {
3536
+ throw new TonConnectError('SendTransactionRequest validation failed: ' + validationError);
3537
+ }
3538
+ }
3014
3539
  const abortController = createAbortController(options === null || options === void 0 ? void 0 : options.signal);
3015
3540
  if (abortController.signal.aborted) {
3016
3541
  throw new TonConnectError('Transaction sending was aborted');
@@ -3046,6 +3571,16 @@ class TonConnect {
3046
3571
  if (abortController.signal.aborted) {
3047
3572
  throw new TonConnectError('data sending was aborted');
3048
3573
  }
3574
+ // Validate sign data
3575
+ const validationError = validateSignDataPayload(data);
3576
+ if (validationError) {
3577
+ if (isQaModeEnabled()) {
3578
+ console.error('SignDataPayload validation failed: ' + validationError);
3579
+ }
3580
+ else {
3581
+ throw new TonConnectError('SignDataPayload validation failed: ' + validationError);
3582
+ }
3583
+ }
3049
3584
  this.checkConnection();
3050
3585
  checkSignDataSupport(this.wallet.device.features, { requiredTypes: [data.type] });
3051
3586
  this.tracker.trackDataSentForSignature(this.wallet, data);
@@ -3066,8 +3601,8 @@ class TonConnect {
3066
3601
  * Disconnect form thw connected wallet and drop current session.
3067
3602
  */
3068
3603
  disconnect(options) {
3069
- var _a;
3070
3604
  return __awaiter(this, void 0, void 0, function* () {
3605
+ var _a;
3071
3606
  if (!this.connected) {
3072
3607
  throw new WalletNotConnectedError();
3073
3608
  }
@@ -3175,26 +3710,28 @@ class TonConnect {
3175
3710
  if (tonProofItem) {
3176
3711
  let tonProof = undefined;
3177
3712
  try {
3178
- if ('proof' in tonProofItem) { // success
3713
+ if ('proof' in tonProofItem) {
3714
+ // success
3179
3715
  tonProof = {
3180
3716
  name: 'ton_proof',
3181
3717
  proof: {
3182
3718
  timestamp: tonProofItem.proof.timestamp,
3183
3719
  domain: {
3184
3720
  lengthBytes: tonProofItem.proof.domain.lengthBytes,
3185
- value: tonProofItem.proof.domain.value,
3721
+ value: tonProofItem.proof.domain.value
3186
3722
  },
3187
3723
  payload: tonProofItem.proof.payload,
3188
- signature: tonProofItem.proof.signature,
3724
+ signature: tonProofItem.proof.signature
3189
3725
  }
3190
3726
  };
3191
3727
  }
3192
- else if ('error' in tonProofItem) { // error
3728
+ else if ('error' in tonProofItem) {
3729
+ // error
3193
3730
  tonProof = {
3194
3731
  name: 'ton_proof',
3195
3732
  error: {
3196
3733
  code: tonProofItem.error.code,
3197
- message: tonProofItem.error.message,
3734
+ message: tonProofItem.error.message
3198
3735
  }
3199
3736
  };
3200
3737
  }
@@ -3263,97 +3800,5 @@ TonConnect.isWalletInjected = (walletJSKey) => InjectedProvider.isWalletInjected
3263
3800
  */
3264
3801
  TonConnect.isInsideWalletBrowser = (walletJSKey) => InjectedProvider.isInsideWalletBrowser(walletJSKey);
3265
3802
 
3266
- const noBounceableTag = 0x51;
3267
- const testOnlyTag = 0x80;
3268
- /**
3269
- * Converts raw TON address to no-bounceable user-friendly format. [See details]{@link https://ton.org/docs/learn/overviews/addresses#user-friendly-address}
3270
- * @param hexAddress raw TON address formatted as "0:<hex string without 0x>".
3271
- * @param [testOnly=false] convert address to test-only form. [See details]{@link https://ton.org/docs/learn/overviews/addresses#user-friendly-address}
3272
- */
3273
- function toUserFriendlyAddress(hexAddress, testOnly = false) {
3274
- const { wc, hex } = parseHexAddress(hexAddress);
3275
- let tag = noBounceableTag;
3276
- if (testOnly) {
3277
- tag |= testOnlyTag;
3278
- }
3279
- const addr = new Int8Array(34);
3280
- addr[0] = tag;
3281
- addr[1] = wc;
3282
- addr.set(hex, 2);
3283
- const addressWithChecksum = new Uint8Array(36);
3284
- addressWithChecksum.set(addr);
3285
- addressWithChecksum.set(crc16(addr), 34);
3286
- let addressBase64 = Base64.encode(addressWithChecksum);
3287
- return addressBase64.replace(/\+/g, '-').replace(/\//g, '_');
3288
- }
3289
- function parseHexAddress(hexAddress) {
3290
- if (!hexAddress.includes(':')) {
3291
- throw new WrongAddressError(`Wrong address ${hexAddress}. Address must include ":".`);
3292
- }
3293
- const parts = hexAddress.split(':');
3294
- if (parts.length !== 2) {
3295
- throw new WrongAddressError(`Wrong address ${hexAddress}. Address must include ":" only once.`);
3296
- }
3297
- const wc = parseInt(parts[0]);
3298
- if (wc !== 0 && wc !== -1) {
3299
- throw new WrongAddressError(`Wrong address ${hexAddress}. WC must be eq 0 or -1, but ${wc} received.`);
3300
- }
3301
- const hex = parts[1];
3302
- if ((hex === null || hex === void 0 ? void 0 : hex.length) !== 64) {
3303
- throw new WrongAddressError(`Wrong address ${hexAddress}. Hex part must be 64bytes length, but ${hex === null || hex === void 0 ? void 0 : hex.length} received.`);
3304
- }
3305
- return {
3306
- wc,
3307
- hex: hexToBytes(hex)
3308
- };
3309
- }
3310
- function crc16(data) {
3311
- const poly = 0x1021;
3312
- let reg = 0;
3313
- const message = new Uint8Array(data.length + 2);
3314
- message.set(data);
3315
- for (let byte of message) {
3316
- let mask = 0x80;
3317
- while (mask > 0) {
3318
- reg <<= 1;
3319
- if (byte & mask) {
3320
- reg += 1;
3321
- }
3322
- mask >>= 1;
3323
- if (reg > 0xffff) {
3324
- reg &= 0xffff;
3325
- reg ^= poly;
3326
- }
3327
- }
3328
- }
3329
- return new Uint8Array([Math.floor(reg / 256), reg % 256]);
3330
- }
3331
- const toByteMap = {};
3332
- for (let ord = 0; ord <= 0xff; ord++) {
3333
- let s = ord.toString(16);
3334
- if (s.length < 2) {
3335
- s = '0' + s;
3336
- }
3337
- toByteMap[s] = ord;
3338
- }
3339
- function hexToBytes(hex) {
3340
- hex = hex.toLowerCase();
3341
- const length2 = hex.length;
3342
- if (length2 % 2 !== 0) {
3343
- throw new ParseHexError('Hex string must have length a multiple of 2: ' + hex);
3344
- }
3345
- const length = length2 / 2;
3346
- const result = new Uint8Array(length);
3347
- for (let i = 0; i < length; i++) {
3348
- const doubled = i * 2;
3349
- const hexSubstring = hex.substring(doubled, doubled + 2);
3350
- if (!toByteMap.hasOwnProperty(hexSubstring)) {
3351
- throw new ParseHexError('Invalid hex character: ' + hexSubstring);
3352
- }
3353
- result[i] = toByteMap[hexSubstring];
3354
- }
3355
- return result;
3356
- }
3357
-
3358
- export { BadRequestError, BrowserEventDispatcher, FetchWalletsError, LocalstorageNotFoundError, ParseHexError, TonConnect, TonConnectError, UnknownAppError, UnknownError, UserRejectsError, WalletAlreadyConnectedError, WalletMissingRequiredFeaturesError, WalletNotConnectedError, WalletNotInjectedError, WalletNotSupportFeatureError, WalletsListManager, WrongAddressError, checkRequiredWalletFeatures, createConnectionCompletedEvent, createConnectionErrorEvent, createConnectionRestoringCompletedEvent, createConnectionRestoringErrorEvent, createConnectionRestoringStartedEvent, createConnectionStartedEvent, createDataSentForSignatureEvent, createDataSignedEvent, createDataSigningFailedEvent, createDisconnectionEvent, createRequestVersionEvent, createResponseVersionEvent, createTransactionSentForSignatureEvent, createTransactionSignedEvent, createTransactionSigningFailedEvent, createVersionInfo, TonConnect as default, encodeTelegramUrlParameters, isTelegramUrl, isWalletInfoCurrentlyEmbedded, isWalletInfoCurrentlyInjected, isWalletInfoInjectable, isWalletInfoInjected, isWalletInfoRemote, toUserFriendlyAddress };
3803
+ export { BadRequestError, BrowserEventDispatcher, FetchWalletsError, LocalstorageNotFoundError, ParseHexError, TonConnect, TonConnectError, UnknownAppError, UnknownError, UserRejectsError, WalletAlreadyConnectedError, WalletMissingRequiredFeaturesError, WalletNotConnectedError, WalletNotInjectedError, WalletNotSupportFeatureError, WalletsListManager, WrongAddressError, checkRequiredWalletFeatures, createConnectionCompletedEvent, createConnectionErrorEvent, createConnectionRestoringCompletedEvent, createConnectionRestoringErrorEvent, createConnectionRestoringStartedEvent, createConnectionStartedEvent, createDataSentForSignatureEvent, createDataSignedEvent, createDataSigningFailedEvent, createDisconnectionEvent, createRequestVersionEvent, createResponseVersionEvent, createTransactionSentForSignatureEvent, createTransactionSignedEvent, createTransactionSigningFailedEvent, createVersionInfo, TonConnect as default, enableQaMode, encodeTelegramUrlParameters, isQaModeEnabled, isTelegramUrl, isWalletInfoCurrentlyEmbedded, isWalletInfoCurrentlyInjected, isWalletInfoInjectable, isWalletInfoInjected, isWalletInfoRemote, toUserFriendlyAddress };
3359
3804
  //# sourceMappingURL=index.mjs.map