@tonconnect/ui-react 0.0.4 → 0.0.5

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.
@@ -45,6 +45,10 @@ export interface TonConnectUIProviderPropsBase {
45
45
  * @default `div#tc-widget-root`.
46
46
  */
47
47
  widgetRootId: string;
48
+ /**
49
+ * @deprecated Don't use it
50
+ */
51
+ walletsListSource: string;
48
52
  }
49
53
  declare const _default: import("react").NamedExoticComponent<TonConnectUIProviderProps>;
50
54
  export default _default;
package/lib/index.js CHANGED
@@ -4218,7 +4218,8 @@ var __awaiter$3 = globalThis && globalThis.__awaiter || function(thisArg, _argum
4218
4218
  });
4219
4219
  };
4220
4220
  class InjectedProvider {
4221
- constructor(injectedWalletKey) {
4221
+ constructor(storage, injectedWalletKey) {
4222
+ this.injectedWalletKey = injectedWalletKey;
4222
4223
  this.type = "injected";
4223
4224
  this.unsubscribeCallback = null;
4224
4225
  this.listenSubscriptions = false;
@@ -4227,13 +4228,14 @@ class InjectedProvider {
4227
4228
  if (!InjectedProvider.isWindowContainsWallet(window2, injectedWalletKey)) {
4228
4229
  throw new WalletNotInjectedError();
4229
4230
  }
4231
+ this.connectionStorage = new BridgeConnectionStorage(storage);
4230
4232
  this.injectedWallet = window2[injectedWalletKey].tonconnect;
4231
4233
  }
4232
4234
  static fromStorage(storage) {
4233
4235
  return __awaiter$3(this, void 0, void 0, function* () {
4234
4236
  const bridgeConnectionStorage = new BridgeConnectionStorage(storage);
4235
4237
  const connection = yield bridgeConnectionStorage.getInjectedConnection();
4236
- return new InjectedProvider(connection.jsBridgeKey);
4238
+ return new InjectedProvider(storage, connection.jsBridgeKey);
4237
4239
  });
4238
4240
  }
4239
4241
  static isWalletInjected(injectedWalletKey) {
@@ -4248,23 +4250,8 @@ class InjectedProvider {
4248
4250
  static isWindowContainsWallet(window2, injectedWalletKey) {
4249
4251
  return !!window2 && injectedWalletKey in window2 && typeof window2[injectedWalletKey] === "object" && "tonconnect" in window2[injectedWalletKey];
4250
4252
  }
4251
- connect(message, auto = false) {
4252
- this.injectedWallet.connect(PROTOCOL_VERSION, message, auto).then((connectEvent) => {
4253
- if (connectEvent.event === "connect") {
4254
- this.makeSubscriptions();
4255
- this.listenSubscriptions = true;
4256
- }
4257
- this.listeners.forEach((listener) => listener(connectEvent));
4258
- }).catch((e2) => {
4259
- const connectEventError = {
4260
- event: "connect_error",
4261
- payload: {
4262
- code: 0,
4263
- message: e2 === null || e2 === void 0 ? void 0 : e2.toString()
4264
- }
4265
- };
4266
- this.listeners.forEach((listener) => listener(connectEventError));
4267
- });
4253
+ connect(message) {
4254
+ this._connect(PROTOCOL_VERSION, message);
4268
4255
  }
4269
4256
  restoreConnection() {
4270
4257
  return __awaiter$3(this, void 0, void 0, function* () {
@@ -4272,10 +4259,12 @@ class InjectedProvider {
4272
4259
  const connectEvent = yield this.injectedWallet.restoreConnection();
4273
4260
  if (connectEvent.event === "connect") {
4274
4261
  this.makeSubscriptions();
4275
- this.listenSubscriptions = true;
4276
4262
  this.listeners.forEach((listener) => listener(connectEvent));
4263
+ } else {
4264
+ yield this.connectionStorage.removeConnection();
4277
4265
  }
4278
4266
  } catch (e2) {
4267
+ yield this.connectionStorage.removeConnection();
4279
4268
  console.error(e2);
4280
4269
  }
4281
4270
  });
@@ -4289,7 +4278,7 @@ class InjectedProvider {
4289
4278
  disconnect() {
4290
4279
  this.closeAllListeners();
4291
4280
  this.injectedWallet.disconnect();
4292
- return Promise.resolve();
4281
+ return this.connectionStorage.removeConnection();
4293
4282
  }
4294
4283
  closeAllListeners() {
4295
4284
  var _a;
@@ -4306,7 +4295,30 @@ class InjectedProvider {
4306
4295
  return this.injectedWallet.send(Object.assign(Object.assign({}, request), { id: "0" }));
4307
4296
  });
4308
4297
  }
4298
+ _connect(protocolVersion, message) {
4299
+ return __awaiter$3(this, void 0, void 0, function* () {
4300
+ try {
4301
+ const connectEvent = yield this.injectedWallet.connect(protocolVersion, message);
4302
+ if (connectEvent.event === "connect") {
4303
+ yield this.updateSession();
4304
+ this.makeSubscriptions();
4305
+ }
4306
+ this.listeners.forEach((listener) => listener(connectEvent));
4307
+ } catch (e2) {
4308
+ console.debug(e2);
4309
+ const connectEventError = {
4310
+ event: "connect_error",
4311
+ payload: {
4312
+ code: 0,
4313
+ message: e2 === null || e2 === void 0 ? void 0 : e2.toString()
4314
+ }
4315
+ };
4316
+ this.listeners.forEach((listener) => listener(connectEventError));
4317
+ }
4318
+ });
4319
+ }
4309
4320
  makeSubscriptions() {
4321
+ this.listenSubscriptions = true;
4310
4322
  this.unsubscribeCallback = this.injectedWallet.listen((e2) => {
4311
4323
  if (this.listenSubscriptions) {
4312
4324
  this.listeners.forEach((listener) => listener(e2));
@@ -4316,6 +4328,12 @@ class InjectedProvider {
4316
4328
  }
4317
4329
  });
4318
4330
  }
4331
+ updateSession() {
4332
+ return this.connectionStorage.storeConnection({
4333
+ type: "injected",
4334
+ jsBridgeKey: this.injectedWalletKey
4335
+ });
4336
+ }
4319
4337
  }
4320
4338
  InjectedProvider.window = getWindow$1();
4321
4339
  var __awaiter$2 = globalThis && globalThis.__awaiter || function(thisArg, _arguments, P2, generator) {
@@ -4400,9 +4418,12 @@ var __awaiter$1 = globalThis && globalThis.__awaiter || function(thisArg, _argum
4400
4418
  });
4401
4419
  };
4402
4420
  class WalletsListManager {
4403
- constructor() {
4421
+ constructor(walletsListSource) {
4404
4422
  this.walletsListCache = null;
4405
4423
  this.walletsListSource = "https://raw.githubusercontent.com/ton-connect/wallets-list/main/wallets.json";
4424
+ if (walletsListSource) {
4425
+ this.walletsListSource = walletsListSource;
4426
+ }
4406
4427
  }
4407
4428
  getWallets() {
4408
4429
  return __awaiter$1(this, void 0, void 0, function* () {
@@ -4416,11 +4437,11 @@ class WalletsListManager {
4416
4437
  getEmbeddedWallet() {
4417
4438
  return __awaiter$1(this, void 0, void 0, function* () {
4418
4439
  const walletsList = yield this.getWallets();
4419
- const injectedWallets = walletsList.filter(isWalletInfoInjected);
4420
- if (injectedWallets.length !== 1) {
4440
+ const embeddedWallets = walletsList.filter((item) => isWalletInfoInjected(item) && item.embedded);
4441
+ if (embeddedWallets.length !== 1) {
4421
4442
  return null;
4422
4443
  }
4423
- return injectedWallets[0].embedded ? injectedWallets[0] : null;
4444
+ return embeddedWallets[0];
4424
4445
  });
4425
4446
  }
4426
4447
  fetchWalletsList() {
@@ -4543,6 +4564,7 @@ class TonConnect {
4543
4564
  manifestUrl: (options === null || options === void 0 ? void 0 : options.manifestUrl) || getWebPageManifest(),
4544
4565
  storage: (options === null || options === void 0 ? void 0 : options.storage) || new DefaultStorage()
4545
4566
  };
4567
+ this.walletsList = new WalletsListManager(options === null || options === void 0 ? void 0 : options.walletsListSource);
4546
4568
  if (!this.dappSettings.manifestUrl) {
4547
4569
  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");
4548
4570
  }
@@ -4637,7 +4659,7 @@ class TonConnect {
4637
4659
  createProvider(wallet) {
4638
4660
  let provider;
4639
4661
  if (isWalletConnectionSourceJS(wallet)) {
4640
- provider = new InjectedProvider(wallet.jsBridgeKey);
4662
+ provider = new InjectedProvider(this.dappSettings.storage, wallet.jsBridgeKey);
4641
4663
  } else {
4642
4664
  provider = new BridgeProvider(this.dappSettings.storage, wallet);
4643
4665
  }
@@ -4720,6 +4742,8 @@ class TonConnect {
4720
4742
  }
4721
4743
  }
4722
4744
  TonConnect.walletsList = new WalletsListManager();
4745
+ TonConnect.isWalletInjected = (walletJSKey) => InjectedProvider.isWalletInjected(walletJSKey);
4746
+ TonConnect.isInsideWalletBrowser = (walletJSKey) => InjectedProvider.isInsideWalletBrowser(walletJSKey);
4723
4747
  function toUserFriendlyAddress$1(hexAddress) {
4724
4748
  const { wc, hex } = parseHexAddress$1(hexAddress);
4725
4749
  const bounceableTag = 17;
@@ -11039,8 +11063,64 @@ const LoaderContainerStyled = styled.div`
11039
11063
  `;
11040
11064
  const [appState, setAppState] = createStore({
11041
11065
  buttonRootId: null,
11042
- language: "en"
11066
+ language: "en",
11067
+ buttonConfiguration: {},
11068
+ widgetConfiguration: {}
11043
11069
  });
11070
+ class TonConnectUIError extends TonConnectError$1 {
11071
+ constructor(...args) {
11072
+ super(...args);
11073
+ Object.setPrototypeOf(this, TonConnectUIError.prototype);
11074
+ }
11075
+ }
11076
+ class WalletNotFoundError extends TonConnectUIError {
11077
+ constructor(...args) {
11078
+ super(...args);
11079
+ Object.setPrototypeOf(this, WalletNotFoundError.prototype);
11080
+ }
11081
+ }
11082
+ function uiWalletToWalletInfo(uiWallet) {
11083
+ if ("jsBridgeKey" in uiWallet) {
11084
+ return __spreadProps(__spreadValues({}, uiWallet), {
11085
+ injected: TonConnect.isWalletInjected(uiWallet.jsBridgeKey),
11086
+ embedded: TonConnect.isInsideWalletBrowser(uiWallet.jsBridgeKey)
11087
+ });
11088
+ }
11089
+ return uiWallet;
11090
+ }
11091
+ function applyWalletsListConfiguration(walletsList, configuration) {
11092
+ var _a;
11093
+ if (!configuration) {
11094
+ return walletsList;
11095
+ }
11096
+ if ("wallets" in configuration) {
11097
+ return configuration.wallets.map((wallet) => {
11098
+ if (typeof wallet === "string") {
11099
+ const walletInfo = walletsList.find((item) => item.name === wallet);
11100
+ if (!walletInfo) {
11101
+ throw new WalletNotFoundError(
11102
+ `Wallet with name === '${wallet}' wasn't found in the wallets list. Check ${wallet} correctness.`
11103
+ );
11104
+ }
11105
+ return walletInfo;
11106
+ }
11107
+ return uiWalletToWalletInfo(wallet);
11108
+ });
11109
+ }
11110
+ const filteredWalletsList = ((_a = configuration.excludeWallets) == null ? void 0 : _a.length) ? walletsList.filter(
11111
+ (wallet) => {
11112
+ var _a2;
11113
+ return (_a2 = configuration.excludeWallets) == null ? void 0 : _a2.every((item) => item !== wallet.name);
11114
+ }
11115
+ ) : walletsList;
11116
+ if (!configuration.includeWallets) {
11117
+ return filteredWalletsList;
11118
+ }
11119
+ if (configuration.includeWalletsOrder === "start") {
11120
+ return configuration.includeWallets.map(uiWalletToWalletInfo).concat(walletsList);
11121
+ }
11122
+ return walletsList.concat(configuration.includeWallets.map(uiWalletToWalletInfo));
11123
+ }
11044
11124
  const WalletsModal = () => {
11045
11125
  const {
11046
11126
  locale
@@ -11048,8 +11128,14 @@ const WalletsModal = () => {
11048
11128
  createEffect(() => locale(appState.language));
11049
11129
  const connector = useContext(ConnectorContext);
11050
11130
  const tonConnectUI2 = useContext(TonConnectUiContext);
11051
- const [walletsList] = createResource(() => tonConnectUI2.getWallets());
11131
+ const [fetchedWalletsList] = createResource(() => tonConnectUI2.getWallets());
11052
11132
  const [selectedWalletInfo, setSelectedWalletInfo] = createSignal(null);
11133
+ const walletsList = createMemo(() => {
11134
+ if (fetchedWalletsList.state !== "ready") {
11135
+ return null;
11136
+ }
11137
+ return applyWalletsListConfiguration(fetchedWalletsList(), appState.widgetConfiguration.wallets);
11138
+ });
11053
11139
  const onClose = () => {
11054
11140
  setWalletsModalOpen(false);
11055
11141
  setSelectedWalletInfo(null);
@@ -11062,7 +11148,11 @@ const WalletsModal = () => {
11062
11148
  if (isWalletInfoInjected(walletInfo) && walletInfo.injected) {
11063
11149
  return onSelectIfInjected(walletInfo);
11064
11150
  }
11065
- setSelectedWalletInfo(walletInfo);
11151
+ if ("bridgeUrl" in walletInfo) {
11152
+ setSelectedWalletInfo(walletInfo);
11153
+ return;
11154
+ }
11155
+ openLink(walletInfo.aboutUrl, "_blank");
11066
11156
  };
11067
11157
  const onSelectIfMobile = (walletInfo) => {
11068
11158
  const universalLink = connector.connect({
@@ -11092,7 +11182,7 @@ const WalletsModal = () => {
11092
11182
  get children() {
11093
11183
  return [createComponent(Show, {
11094
11184
  get when() {
11095
- return walletsList.state !== "ready";
11185
+ return !walletsList();
11096
11186
  },
11097
11187
  get children() {
11098
11188
  return [createComponent(H1Styled$1, {
@@ -11108,7 +11198,7 @@ const WalletsModal = () => {
11108
11198
  }
11109
11199
  }), createComponent(Show, {
11110
11200
  get when() {
11111
- return walletsList.state === "ready";
11201
+ return walletsList();
11112
11202
  },
11113
11203
  get children() {
11114
11204
  return [createComponent(Show, {
@@ -11338,12 +11428,6 @@ const widgetController = {
11338
11428
  tonConnectUI: tonConnectUI2
11339
11429
  }), document.getElementById(root))
11340
11430
  };
11341
- class TonConnectUIError extends TonConnectError$1 {
11342
- constructor(...args) {
11343
- super(...args);
11344
- Object.setPrototypeOf(this, TonConnectUIError.prototype);
11345
- }
11346
- }
11347
11431
  class WalletInfoStorage {
11348
11432
  constructor() {
11349
11433
  __publicField(this, "localStorage");
@@ -11508,7 +11592,10 @@ class TonConnectUI {
11508
11592
  if (options && "connector" in options && options.connector) {
11509
11593
  this.connector = options.connector;
11510
11594
  } else if (options && "manifestUrl" in options && options.manifestUrl) {
11511
- this.connector = new TonConnect({ manifestUrl: options.manifestUrl });
11595
+ this.connector = new TonConnect({
11596
+ manifestUrl: options.manifestUrl,
11597
+ walletsListSource: options.walletsListSource
11598
+ });
11512
11599
  } else {
11513
11600
  throw new TonConnectUIError(
11514
11601
  "You have to specify a `manifestUrl` or a `connector` in the options."
@@ -11518,7 +11605,11 @@ class TonConnectUI {
11518
11605
  const rootId = this.normalizeWidgetRoot(options == null ? void 0 : options.widgetRootId);
11519
11606
  this.subscribeToWalletChange();
11520
11607
  if ((options == null ? void 0 : options.restoreConnection) !== false) {
11521
- this.connector.restoreConnection();
11608
+ this.connector.restoreConnection().then(() => {
11609
+ if (!this.connector.connected) {
11610
+ this.walletInfoStorage.removeWalletInfo();
11611
+ }
11612
+ });
11522
11613
  }
11523
11614
  this.uiOptions = options || {};
11524
11615
  setAppState({ connector: this.connector });
@@ -11557,11 +11648,11 @@ class TonConnectUI {
11557
11648
  }
11558
11649
  setAppState((state) => {
11559
11650
  const merged = mergeOptions(
11560
- {
11561
- language: options.language,
11562
- buttonConfiguration: options.buttonConfiguration,
11651
+ __spreadValues(__spreadValues(__spreadValues({}, options.language && { language: options.language }), options.buttonConfiguration && {
11652
+ buttonConfiguration: options.buttonConfiguration
11653
+ }), options.widgetConfiguration && {
11563
11654
  widgetConfiguration: options.widgetConfiguration
11564
- },
11655
+ }),
11565
11656
  unwrap(state)
11566
11657
  );
11567
11658
  if (options.buttonRootId !== void 0) {