@tonconnect/sdk 3.0.7 → 3.1.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/lib/cjs/index.cjs CHANGED
@@ -123,6 +123,45 @@ class WalletNotConnectedError extends TonConnectError {
123
123
  }
124
124
  }
125
125
 
126
+ /**
127
+ * Thrown when there is an attempt to connect to the injected wallet while it is not exists in the webpage.
128
+ */
129
+ class WalletNotInjectedError extends TonConnectError {
130
+ get info() {
131
+ return 'There is an attempt to connect to the injected wallet while it is not exists in the webpage.';
132
+ }
133
+ constructor(...args) {
134
+ super(...args);
135
+ Object.setPrototypeOf(this, WalletNotInjectedError.prototype);
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Thrown when wallet doesn't support requested feature method.
141
+ */
142
+ class WalletNotSupportFeatureError extends TonConnectError {
143
+ get info() {
144
+ return "Wallet doesn't support requested feature method.";
145
+ }
146
+ constructor(...args) {
147
+ super(...args);
148
+ Object.setPrototypeOf(this, WalletNotSupportFeatureError.prototype);
149
+ }
150
+ }
151
+
152
+ /**
153
+ * Thrown when wallet can't get manifest by passed manifestUrl.
154
+ */
155
+ class WalletMissingRequiredFeaturesError extends TonConnectError {
156
+ get info() {
157
+ return 'Missing required features. You need to update your wallet.';
158
+ }
159
+ constructor(message, options) {
160
+ super(message, options);
161
+ Object.setPrototypeOf(this, WalletMissingRequiredFeaturesError.prototype);
162
+ }
163
+ }
164
+
126
165
  function isWalletConnectionSourceJS(value) {
127
166
  return 'jsBridgeKey' in value;
128
167
  }
@@ -166,19 +205,6 @@ class UnknownAppError extends TonConnectError {
166
205
  }
167
206
  }
168
207
 
169
- /**
170
- * Thrown when there is an attempt to connect to the injected wallet while it is not exists in the webpage.
171
- */
172
- class WalletNotInjectedError extends TonConnectError {
173
- get info() {
174
- return 'There is an attempt to connect to the injected wallet while it is not exists in the webpage.';
175
- }
176
- constructor(...args) {
177
- super(...args);
178
- Object.setPrototypeOf(this, WalletNotInjectedError.prototype);
179
- }
180
- }
181
-
182
208
  /**
183
209
  * Thrown when `Storage` was not specified in the `DappMetadata` and default `localStorage` was not detected in the Node.js environment.
184
210
  */
@@ -1508,7 +1534,8 @@ class InjectedProvider {
1508
1534
  jsBridgeKey,
1509
1535
  injected: true,
1510
1536
  embedded: wallet.tonconnect.isWalletBrowser,
1511
- platforms: wallet.tonconnect.walletInfo.platforms
1537
+ platforms: wallet.tonconnect.walletInfo.platforms,
1538
+ features: wallet.tonconnect.walletInfo.features
1512
1539
  }));
1513
1540
  }
1514
1541
  static isWindowContainsWallet(window, injectedWalletKey) {
@@ -2020,15 +2047,12 @@ const FALLBACK_WALLETS_LIST = [
2020
2047
 
2021
2048
  class WalletsListManager {
2022
2049
  constructor(options) {
2050
+ var _a;
2023
2051
  this.walletsListCache = null;
2024
2052
  this.walletsListCacheCreationTimestamp = null;
2025
- this.walletsListSource = 'https://raw.githubusercontent.com/ton-blockchain/wallets-list/main/wallets-v2.json';
2026
- if (options === null || options === void 0 ? void 0 : options.walletsListSource) {
2027
- this.walletsListSource = options.walletsListSource;
2028
- }
2029
- if (options === null || options === void 0 ? void 0 : options.cacheTTLMs) {
2030
- this.cacheTTLMs = options.cacheTTLMs;
2031
- }
2053
+ this.walletsListSource =
2054
+ (_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';
2055
+ this.cacheTTLMs = options === null || options === void 0 ? void 0 : options.cacheTTLMs;
2032
2056
  }
2033
2057
  getWallets() {
2034
2058
  return __awaiter(this, void 0, void 0, function* () {
@@ -2055,10 +2079,7 @@ class WalletsListManager {
2055
2079
  return __awaiter(this, void 0, void 0, function* () {
2056
2080
  const walletsList = yield this.getWallets();
2057
2081
  const embeddedWallets = walletsList.filter(isWalletInfoCurrentlyEmbedded);
2058
- if (embeddedWallets.length !== 1) {
2059
- return null;
2060
- }
2061
- return embeddedWallets[0];
2082
+ return embeddedWallets.length === 1 ? embeddedWallets[0] : null;
2062
2083
  });
2063
2084
  }
2064
2085
  fetchWalletsList() {
@@ -2073,7 +2094,7 @@ class WalletsListManager {
2073
2094
  const wrongFormatWallets = walletsList.filter(wallet => !this.isCorrectWalletConfigDTO(wallet));
2074
2095
  if (wrongFormatWallets.length) {
2075
2096
  logError(`Wallet(s) ${wrongFormatWallets
2076
- .map(wallet => wallet.name)
2097
+ .map(wallet => (wallet === null || wallet === void 0 ? void 0 : wallet.name) || 'unknown')
2077
2098
  .join(', ')} config format is wrong. They were removed from the wallets list.`);
2078
2099
  walletsList = walletsList.filter(wallet => this.isCorrectWalletConfigDTO(wallet));
2079
2100
  }
@@ -2094,15 +2115,15 @@ class WalletsListManager {
2094
2115
  }
2095
2116
  walletConfigDTOListToWalletConfigList(walletConfigDTO) {
2096
2117
  return walletConfigDTO.map(walletConfigDTO => {
2097
- const walletConfigBase = {
2118
+ const walletConfig = {
2098
2119
  name: walletConfigDTO.name,
2099
2120
  appName: walletConfigDTO.app_name,
2100
2121
  imageUrl: walletConfigDTO.image,
2101
2122
  aboutUrl: walletConfigDTO.about_url,
2102
2123
  tondns: walletConfigDTO.tondns,
2103
- platforms: walletConfigDTO.platforms
2124
+ platforms: walletConfigDTO.platforms,
2125
+ features: walletConfigDTO.features
2104
2126
  };
2105
- const walletConfig = walletConfigBase;
2106
2127
  walletConfigDTO.bridge.forEach(bridge => {
2107
2128
  if (bridge.type === 'sse') {
2108
2129
  walletConfig.bridgeUrl = bridge.url;
@@ -2163,7 +2184,7 @@ class WalletsListManager {
2163
2184
  }
2164
2185
  const sseBridge = bridge.find(item => item.type === 'sse');
2165
2186
  if (sseBridge) {
2166
- if (!('url' in sseBridge) ||
2187
+ if (!(typeof sseBridge === 'object' && 'url' in sseBridge) ||
2167
2188
  !sseBridge.url ||
2168
2189
  !value.universal_url) {
2169
2190
  return false;
@@ -2171,7 +2192,9 @@ class WalletsListManager {
2171
2192
  }
2172
2193
  const jsBridge = bridge.find(item => item.type === 'js');
2173
2194
  if (jsBridge) {
2174
- if (!('key' in jsBridge) || !jsBridge.key) {
2195
+ if (typeof jsBridge !== 'object' ||
2196
+ !('key' in jsBridge) ||
2197
+ !jsBridge.key) {
2175
2198
  return false;
2176
2199
  }
2177
2200
  }
@@ -2179,22 +2202,9 @@ class WalletsListManager {
2179
2202
  }
2180
2203
  }
2181
2204
 
2182
- /**
2183
- * Thrown when wallet doesn't support requested feature method.
2184
- */
2185
- class WalletNotSupportFeatureError extends TonConnectError {
2186
- get info() {
2187
- return "Wallet doesn't support requested feature method.";
2188
- }
2189
- constructor(...args) {
2190
- super(...args);
2191
- Object.setPrototypeOf(this, WalletNotSupportFeatureError.prototype);
2192
- }
2193
- }
2194
-
2195
2205
  function checkSendTransactionSupport(features, options) {
2196
2206
  const supportsDeprecatedSendTransactionFeature = features.includes('SendTransaction');
2197
- const sendTransactionFeature = features.find(feature => feature && typeof feature === 'object' && feature.name === 'SendTransaction');
2207
+ const sendTransactionFeature = findFeature(features, 'SendTransaction');
2198
2208
  if (!supportsDeprecatedSendTransactionFeature && !sendTransactionFeature) {
2199
2209
  throw new WalletNotSupportFeatureError("Wallet doesn't support SendTransaction feature.");
2200
2210
  }
@@ -2211,6 +2221,31 @@ function checkSendTransactionSupport(features, options) {
2211
2221
  }
2212
2222
  logWarning("Connected wallet didn't provide information about max allowed messages in the SendTransaction request. Request may be rejected by the wallet.");
2213
2223
  }
2224
+ function checkRequiredWalletFeatures(features, walletsRequiredFeatures) {
2225
+ if (typeof walletsRequiredFeatures !== 'object') {
2226
+ return true;
2227
+ }
2228
+ const { sendTransaction } = walletsRequiredFeatures;
2229
+ if (sendTransaction) {
2230
+ const feature = findFeature(features, 'SendTransaction');
2231
+ if (!feature) {
2232
+ return false;
2233
+ }
2234
+ if (!checkSendTransaction(feature, sendTransaction)) {
2235
+ return false;
2236
+ }
2237
+ }
2238
+ return true;
2239
+ }
2240
+ function findFeature(features, requiredFeatureName) {
2241
+ return features.find(f => f && typeof f === 'object' && f.name === requiredFeatureName);
2242
+ }
2243
+ function checkSendTransaction(feature, requiredFeature) {
2244
+ const correctMessagesNumber = requiredFeature.minMessages === undefined ||
2245
+ requiredFeature.minMessages <= feature.maxMessages;
2246
+ const correctExtraCurrency = !requiredFeature.extraCurrencyRequired || feature.extraCurrencySupported;
2247
+ return !!(correctMessagesNumber && correctExtraCurrency);
2248
+ }
2214
2249
 
2215
2250
  /**
2216
2251
  * Create a request version event.
@@ -2628,7 +2663,7 @@ class TonConnectTracker {
2628
2663
  }
2629
2664
  }
2630
2665
 
2631
- const tonConnectSdkVersion = "3.0.7";
2666
+ const tonConnectSdkVersion = "3.1.0";
2632
2667
 
2633
2668
  class TonConnect {
2634
2669
  constructor(options) {
@@ -2641,6 +2676,7 @@ class TonConnect {
2641
2676
  manifestUrl: (options === null || options === void 0 ? void 0 : options.manifestUrl) || getWebPageManifest(),
2642
2677
  storage: (options === null || options === void 0 ? void 0 : options.storage) || new DefaultStorage()
2643
2678
  };
2679
+ this.walletsRequiredFeatures = options === null || options === void 0 ? void 0 : options.walletsRequiredFeatures;
2644
2680
  this.walletsList = new WalletsListManager({
2645
2681
  walletsListSource: options === null || options === void 0 ? void 0 : options.walletsListSource,
2646
2682
  cacheTTLMs: options === null || options === void 0 ? void 0 : options.walletsListCacheTTLMs
@@ -2955,18 +2991,27 @@ class TonConnect {
2955
2991
  this.onWalletConnected(e.payload);
2956
2992
  break;
2957
2993
  case 'connect_error':
2958
- this.onWalletConnectError(e.payload);
2994
+ this.tracker.trackConnectionError(e.payload.message, e.payload.code);
2995
+ const walletError = connectErrorsParser.parseError(e.payload);
2996
+ this.onWalletConnectError(walletError);
2959
2997
  break;
2960
2998
  case 'disconnect':
2961
2999
  this.onWalletDisconnected('wallet');
2962
3000
  }
2963
3001
  }
2964
3002
  onWalletConnected(connectEvent) {
3003
+ var _a;
2965
3004
  const tonAccountItem = connectEvent.items.find(item => item.name === 'ton_addr');
2966
3005
  const tonProofItem = connectEvent.items.find(item => item.name === 'ton_proof');
2967
3006
  if (!tonAccountItem) {
2968
3007
  throw new TonConnectError('ton_addr connection item was not found');
2969
3008
  }
3009
+ const hasRequiredFeatures = checkRequiredWalletFeatures(connectEvent.device.features, this.walletsRequiredFeatures);
3010
+ if (!hasRequiredFeatures) {
3011
+ (_a = this.provider) === null || _a === void 0 ? void 0 : _a.disconnect();
3012
+ this.onWalletConnectError(new WalletMissingRequiredFeaturesError('Wallet does not support required features', { cause: { connectEvent } }));
3013
+ return;
3014
+ }
2970
3015
  const wallet = {
2971
3016
  device: connectEvent.device,
2972
3017
  provider: this.provider.type,
@@ -2985,11 +3030,9 @@ class TonConnect {
2985
3030
  this.wallet = wallet;
2986
3031
  this.tracker.trackConnectionCompleted(wallet);
2987
3032
  }
2988
- onWalletConnectError(connectEventError) {
2989
- const error = connectErrorsParser.parseError(connectEventError);
3033
+ onWalletConnectError(error) {
2990
3034
  this.statusChangeErrorSubscriptions.forEach(errorsHandler => errorsHandler(error));
2991
3035
  logDebug(error);
2992
- this.tracker.trackConnectionError(connectEventError.message, connectEventError.code);
2993
3036
  if (error instanceof ManifestNotFoundError || error instanceof ManifestContentErrorError) {
2994
3037
  logError(error);
2995
3038
  throw error;
@@ -3153,10 +3196,13 @@ exports.UnknownAppError = UnknownAppError;
3153
3196
  exports.UnknownError = UnknownError;
3154
3197
  exports.UserRejectsError = UserRejectsError;
3155
3198
  exports.WalletAlreadyConnectedError = WalletAlreadyConnectedError;
3199
+ exports.WalletMissingRequiredFeaturesError = WalletMissingRequiredFeaturesError;
3156
3200
  exports.WalletNotConnectedError = WalletNotConnectedError;
3157
3201
  exports.WalletNotInjectedError = WalletNotInjectedError;
3202
+ exports.WalletNotSupportFeatureError = WalletNotSupportFeatureError;
3158
3203
  exports.WalletsListManager = WalletsListManager;
3159
3204
  exports.WrongAddressError = WrongAddressError;
3205
+ exports.checkRequiredWalletFeatures = checkRequiredWalletFeatures;
3160
3206
  exports.createConnectionCompletedEvent = createConnectionCompletedEvent;
3161
3207
  exports.createConnectionErrorEvent = createConnectionErrorEvent;
3162
3208
  exports.createConnectionRestoringCompletedEvent = createConnectionRestoringCompletedEvent;