@suilend/sui-fe-next 2.0.14 → 2.0.16

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.
@@ -62,11 +62,12 @@ import { DAppKitProvider, useCurrentAccount, useCurrentWallet, useDAppKit, useWa
62
62
  import { SuiJsonRpcClient, } from "@mysten/sui/jsonRpc";
63
63
  import { Transaction } from "@mysten/sui/transactions";
64
64
  import { SUI_DECIMALS, toBase64 } from "@mysten/sui/utils";
65
+ import { getWallets } from "@wallet-standard/app";
65
66
  import BigNumber from "bignumber.js";
66
67
  import { useLDClient } from "launchdarkly-react-client-sdk";
67
68
  import { useLocalStorage } from "usehooks-ts";
68
69
  import { API_URL, formatAddress, isInMsafeApp } from "@suilend/sui-fe";
69
- import { WC_SUI_METHODS, getWalletConnectProvider } from "../lib/connector";
70
+ import { WC_SUI_METHODS, getWalletConnectModal, getWalletConnectProvider, } from "../lib/connector";
70
71
  import { showErrorToast, showInfoToast } from "../lib/toasts";
71
72
  import { useSettingsContext } from "./SettingsContext";
72
73
  export var WalletType;
@@ -217,10 +218,10 @@ function Inner(_a) {
217
218
  var queryParams = (_b = {},
218
219
  _b[WalletContextQueryParams.WALLET] = router.query[WalletContextQueryParams.WALLET],
219
220
  _b);
220
- var suiClient = useSettingsContext().suiClient;
221
+ var _f = useSettingsContext(), rpc = _f.rpc, suiClient = _f.suiClient;
221
222
  // WalletConnect via @walletconnect/universal-provider
222
223
  // Matches the reference implementation: https://github.com/WalletConnect/react-core-up-sui
223
- var _f = useState(), wcSession = _f[0], setWcSession = _f[1];
224
+ var _g = useState(), wcSession = _g[0], setWcSession = _g[1];
224
225
  var sessionAddress = useMemo(function () {
225
226
  var _a, _b, _c;
226
227
  var raw = (_c = (_b = (_a = wcSession === null || wcSession === void 0 ? void 0 : wcSession.namespaces) === null || _a === void 0 ? void 0 : _a.sui) === null || _b === void 0 ? void 0 : _b.accounts) === null || _c === void 0 ? void 0 : _c[0];
@@ -355,7 +356,7 @@ function Inner(_a) {
355
356
  wallets__web,
356
357
  ]);
357
358
  // Wallet
358
- var _g = useState(false), isConnectWalletDropdownOpen = _g[0], setIsConnectWalletDropdownOpen = _g[1];
359
+ var _h = useState(false), isConnectWalletDropdownOpen = _h[0], setIsConnectWalletDropdownOpen = _h[1];
359
360
  var rawWallet = useCurrentWallet();
360
361
  var wallet = useMemo(function () {
361
362
  if (sessionAddress) {
@@ -392,15 +393,22 @@ function Inner(_a) {
392
393
  });
393
394
  }); }, [sessionAddress]);
394
395
  var connectWalletWrapper = useCallback(function (_wallet) { return __awaiter(_this, void 0, void 0, function () {
395
- var provider, _a, provider, _b, err_1;
396
+ var provider, modal, _a, provider, _b, err_1;
396
397
  return __generator(this, function (_c) {
397
398
  switch (_c.label) {
398
399
  case 0:
399
- _c.trys.push([0, 14, , 15]);
400
- if (!(_wallet === null || _wallet === void 0 ? void 0 : _wallet.walletConnect)) return [3 /*break*/, 7];
400
+ _c.trys.push([0, 17, , 18]);
401
+ if (!(_wallet === null || _wallet === void 0 ? void 0 : _wallet.walletConnect)) return [3 /*break*/, 10];
401
402
  return [4 /*yield*/, getWalletConnectProvider()];
402
403
  case 1:
403
404
  provider = _c.sent();
405
+ return [4 /*yield*/, getWalletConnectModal(rpc.url)];
406
+ case 2:
407
+ modal = _c.sent();
408
+ modal.open();
409
+ _c.label = 3;
410
+ case 3:
411
+ _c.trys.push([3, , 5, 6]);
404
412
  return [4 /*yield*/, provider.connect({
405
413
  optionalNamespaces: {
406
414
  sui: {
@@ -414,54 +422,57 @@ function Inner(_a) {
414
422
  },
415
423
  },
416
424
  })];
417
- case 2:
418
- _c.sent();
419
- _c.label = 3;
420
- case 3:
421
- _c.trys.push([3, 5, , 6]);
422
- return [4 /*yield*/, disconnectWallet()];
423
425
  case 4:
424
426
  _c.sent();
425
427
  return [3 /*break*/, 6];
426
428
  case 5:
427
- _a = _c.sent();
428
- return [3 /*break*/, 6];
429
+ modal.close();
430
+ return [7 /*endfinally*/];
429
431
  case 6:
432
+ _c.trys.push([6, 8, , 9]);
433
+ return [4 /*yield*/, disconnectWallet()];
434
+ case 7:
435
+ _c.sent();
436
+ return [3 /*break*/, 9];
437
+ case 8:
438
+ _a = _c.sent();
439
+ return [3 /*break*/, 9];
440
+ case 9:
430
441
  setWcSession(provider.session);
431
442
  return [2 /*return*/];
432
- case 7:
443
+ case 10:
433
444
  if (!_wallet.raw)
434
445
  throw new Error("Missing wallet");
435
446
  return [4 /*yield*/, connectWallet({ wallet: _wallet.raw })];
436
- case 8:
447
+ case 11:
437
448
  _c.sent();
438
- _c.label = 9;
439
- case 9:
440
- _c.trys.push([9, 12, , 13]);
449
+ _c.label = 12;
450
+ case 12:
451
+ _c.trys.push([12, 15, , 16]);
441
452
  return [4 /*yield*/, getWalletConnectProvider()];
442
- case 10:
453
+ case 13:
443
454
  provider = _c.sent();
444
455
  return [4 /*yield*/, provider.disconnect()];
445
- case 11:
456
+ case 14:
446
457
  _c.sent();
447
- return [3 /*break*/, 13];
448
- case 12:
458
+ return [3 /*break*/, 16];
459
+ case 15:
449
460
  _b = _c.sent();
450
- return [3 /*break*/, 13];
451
- case 13:
461
+ return [3 /*break*/, 16];
462
+ case 16:
452
463
  setWcSession(null);
453
464
  showInfoToast("Connected ".concat(_wallet.name));
454
465
  setIsConnectWalletDropdownOpen(false);
455
- return [3 /*break*/, 15];
456
- case 14:
466
+ return [3 /*break*/, 18];
467
+ case 17:
457
468
  err_1 = _c.sent();
458
469
  showErrorToast("Failed to connect ".concat(_wallet.name), err_1);
459
470
  console.error(err_1);
460
- return [3 /*break*/, 15];
461
- case 15: return [2 /*return*/];
471
+ return [3 /*break*/, 18];
472
+ case 18: return [2 /*return*/];
462
473
  }
463
474
  });
464
- }); }, [connectWallet, disconnectWallet]);
475
+ }); }, [rpc.url, connectWallet, disconnectWallet]);
465
476
  var disconnectWalletWrapper = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
466
477
  var provider, err_2;
467
478
  return __generator(this, function (_a) {
@@ -655,7 +666,7 @@ function Inner(_a) {
655
666
  });
656
667
  }); }, [suiClient]);
657
668
  var signExecuteAndWaitForTransaction = useCallback(function (transaction, onSetGasBudget, onSign, onExecute) { return __awaiter(_this, void 0, void 0, function () {
658
- var _address, provider, txBytes, txBase64, params, res_1, signAndExecErr_1, signRes, execRes, usedSignOnly, signedTransaction, res1, err_5, message, res, digest, err_6;
669
+ var _address, provider, txBytes, txBase64, params, res_1, signAndExecErr_1, signRes, execRes, msafeWallet, msafeFeature, msafeAccount, usedSignOnly, signedTransaction, res1, err_5, message, res, digest, err_6;
659
670
  return __generator(this, function (_a) {
660
671
  switch (_a.label) {
661
672
  case 0:
@@ -668,7 +679,7 @@ function Inner(_a) {
668
679
  }
669
680
  _a.label = 1;
670
681
  case 1:
671
- _a.trys.push([1, 21, , 22]);
682
+ _a.trys.push([1, 24, , 25]);
672
683
  // Gas budget
673
684
  if (gasBudget !== "")
674
685
  transaction.setGasBudget(+new BigNumber(gasBudget)
@@ -723,14 +734,36 @@ function Inner(_a) {
723
734
  return [4 /*yield*/, waitForTransactionWithCheck(execRes.digest)];
724
735
  case 11: return [2 /*return*/, _a.sent()];
725
736
  case 12:
726
- usedSignOnly = false;
727
- _a.label = 13;
737
+ if (!isInMsafeApp()) return [3 /*break*/, 15];
738
+ msafeWallet = getWallets()
739
+ .get()
740
+ .find(function (w) { return w.name === WalletName.MSAFE_WALLET; });
741
+ msafeFeature = msafeWallet === null || msafeWallet === void 0 ? void 0 : msafeWallet.features["sui:signAndExecuteTransactionBlock"];
742
+ if (!(msafeFeature && account)) return [3 /*break*/, 14];
743
+ msafeAccount = msafeWallet.accounts.find(function (a) { return a.address === account.address; });
744
+ if (!msafeAccount)
745
+ throw new Error("MSafe account not found");
746
+ return [4 /*yield*/, msafeFeature.signAndExecuteTransactionBlock({
747
+ transactionBlock: transaction,
748
+ account: msafeAccount,
749
+ chain: "sui:mainnet",
750
+ })];
728
751
  case 13:
729
- _a.trys.push([13, 17, , 18]);
752
+ _a.sent();
753
+ // MSafe proposes the transaction to the multisig queue;
754
+ // the promise never resolves (only rejects on cancel).
755
+ // If we reach here the proposal was accepted.
756
+ throw new Error("Unreachable");
757
+ case 14: throw new Error("MSafe wallet not found. Please reload the page inside MSafe.");
758
+ case 15:
759
+ usedSignOnly = false;
760
+ _a.label = 16;
761
+ case 16:
762
+ _a.trys.push([16, 20, , 21]);
730
763
  return [4 /*yield*/, dAppKit.signTransaction({
731
764
  transaction: transaction,
732
765
  })];
733
- case 14:
766
+ case 17:
734
767
  signedTransaction = _a.sent();
735
768
  usedSignOnly = true;
736
769
  onSign === null || onSign === void 0 ? void 0 : onSign(signedTransaction);
@@ -738,12 +771,12 @@ function Inner(_a) {
738
771
  transactionBlock: signedTransaction.bytes,
739
772
  signature: signedTransaction.signature,
740
773
  })];
741
- case 15:
774
+ case 18:
742
775
  res1 = _a.sent();
743
776
  onExecute === null || onExecute === void 0 ? void 0 : onExecute(res1);
744
777
  return [4 /*yield*/, waitForTransactionWithCheck(res1.digest)];
745
- case 16: return [2 /*return*/, _a.sent()];
746
- case 17:
778
+ case 19: return [2 /*return*/, _a.sent()];
779
+ case 20:
747
780
  err_5 = _a.sent();
748
781
  if (usedSignOnly)
749
782
  throw err_5;
@@ -751,36 +784,36 @@ function Inner(_a) {
751
784
  if (!message.includes("does not support"))
752
785
  throw err_5;
753
786
  console.warn("[WalletContext] Wallet does not support sign-only, falling back to signAndExecuteTransaction");
754
- return [3 /*break*/, 18];
755
- case 18: return [4 /*yield*/, dAppKit.signAndExecuteTransaction({
787
+ return [3 /*break*/, 21];
788
+ case 21: return [4 /*yield*/, dAppKit.signAndExecuteTransaction({
756
789
  transaction: transaction,
757
790
  })];
758
- case 19:
791
+ case 22:
759
792
  res = _a.sent();
760
793
  digest = res.$kind === "Transaction"
761
794
  ? res.Transaction.digest
762
795
  : res.FailedTransaction.digest;
763
796
  return [4 /*yield*/, waitForTransactionWithCheck(digest)];
764
- case 20: return [2 /*return*/, _a.sent()];
765
- case 21:
797
+ case 23: return [2 /*return*/, _a.sent()];
798
+ case 24:
766
799
  err_6 = _a.sent();
767
800
  console.error(err_6);
768
801
  throw err_6;
769
- case 22: return [2 /*return*/];
802
+ case 25: return [2 /*return*/];
770
803
  }
771
804
  });
772
805
  }); }, [
773
806
  sessionAddress,
774
807
  gasBudget,
775
808
  impersonatedAddress,
776
- account === null || account === void 0 ? void 0 : account.address,
809
+ account,
777
810
  dryRunTransaction,
778
811
  suiClient,
779
812
  dAppKit,
780
813
  waitForTransactionWithCheck,
781
814
  ]);
782
815
  // Using Ledger
783
- var _h = useLocalStorage("isUsingLedger-".concat(impersonatedAddress !== null && impersonatedAddress !== void 0 ? impersonatedAddress : account === null || account === void 0 ? void 0 : account.address), false), isUsingLedger = _h[0], setIsUsingLedger = _h[1];
816
+ var _j = useLocalStorage("isUsingLedger-".concat(impersonatedAddress !== null && impersonatedAddress !== void 0 ? impersonatedAddress : account === null || account === void 0 ? void 0 : account.address), false), isUsingLedger = _j[0], setIsUsingLedger = _j[1];
784
817
  // Context
785
818
  var contextValue = useMemo(function () {
786
819
  return {
@@ -1,6 +1,8 @@
1
+ import { type AppKit } from "@reown/appkit/core";
1
2
  import UniversalProvider from "@walletconnect/universal-provider";
2
3
  export declare const projectId = "eebad6a56ec8b3f08b70175934d35a9d";
3
4
  export declare function getWalletConnectProvider(): Promise<UniversalProvider>;
5
+ export declare function getWalletConnectModal(rpcUrl: string): Promise<AppKit>;
4
6
  export declare const WC_SUI_METHODS: {
5
7
  readonly SIGN_TRANSACTION: "sui_signTransaction";
6
8
  readonly SIGN_AND_EXECUTE_TRANSACTION: "sui_signAndExecuteTransaction";
package/lib/connector.js CHANGED
@@ -34,6 +34,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
34
34
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
35
35
  }
36
36
  };
37
+ import { createAppKit } from "@reown/appkit/core";
37
38
  import UniversalProvider from "@walletconnect/universal-provider";
38
39
  export var projectId = "eebad6a56ec8b3f08b70175934d35a9d";
39
40
  var provider;
@@ -60,6 +61,44 @@ export function getWalletConnectProvider() {
60
61
  });
61
62
  });
62
63
  }
64
+ var modal;
65
+ var modalRpcUrl;
66
+ export function getWalletConnectModal(rpcUrl) {
67
+ return __awaiter(this, void 0, void 0, function () {
68
+ var universalProvider;
69
+ return __generator(this, function (_a) {
70
+ switch (_a.label) {
71
+ case 0:
72
+ if (!(!modal || modalRpcUrl !== rpcUrl)) return [3 /*break*/, 2];
73
+ return [4 /*yield*/, getWalletConnectProvider()];
74
+ case 1:
75
+ universalProvider = _a.sent();
76
+ modal = createAppKit({
77
+ projectId: projectId,
78
+ networks: [
79
+ {
80
+ id: 784,
81
+ chainNamespace: "sui",
82
+ caipNetworkId: "sui:mainnet",
83
+ name: "Sui",
84
+ nativeCurrency: { name: "SUI", symbol: "SUI", decimals: 9 },
85
+ rpcUrls: {
86
+ default: {
87
+ http: [rpcUrl],
88
+ },
89
+ },
90
+ },
91
+ ],
92
+ universalProvider: universalProvider,
93
+ manualWCControl: true,
94
+ });
95
+ modalRpcUrl = rpcUrl;
96
+ _a.label = 2;
97
+ case 2: return [2 /*return*/, modal];
98
+ }
99
+ });
100
+ });
101
+ }
63
102
  export var WC_SUI_METHODS = {
64
103
  SIGN_TRANSACTION: "sui_signTransaction",
65
104
  SIGN_AND_EXECUTE_TRANSACTION: "sui_signAndExecuteTransaction",
package/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@suilend/sui-fe-next","version":"2.0.14","private":false,"description":"A collection of TypeScript frontend components and hooks","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./contexts/WalletContext":"./contexts/WalletContext.jsx","./contexts/SettingsContext":"./contexts/SettingsContext.jsx","./contexts":"./contexts/index.js","./fetchers":"./fetchers/index.js","./fetchers/useFetchBalances":"./fetchers/useFetchBalances.js","./hooks/useRefreshOnBalancesChange":"./hooks/useRefreshOnBalancesChange.js","./hooks/useLedgerHashDialog":"./hooks/useLedgerHashDialog.js","./hooks/useIsAndroid":"./hooks/useIsAndroid.jsx","./hooks/useCoinMetadataMap":"./hooks/useCoinMetadataMap.js","./hooks":"./hooks/index.js","./hooks/useIsTouchscreen":"./hooks/useIsTouchscreen.jsx","./hooks/useIsiOS":"./hooks/useIsiOS.jsx","./hooks/keypair":"./hooks/keypair.js","./lib/track":"./lib/track.js","./lib":"./lib/index.js","./lib/router":"./lib/router.js","./lib/toasts":"./lib/toasts.jsx","./lib/connector":"./lib/connector.js"},"types":"./index.js","scripts":{"build":"rm -rf ./dist && bun tsc","eslint":"eslint --fix src/","prettier":"prettier --write src/","lint":"bun eslint && bun prettier && bun tsc --noEmit","release":"bun run build && bun ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/suilend/sui-fe.git"},"bugs":{"url":"https://github.com/suilend/sui-fe/issues"},"dependencies":{"@reown/appkit":"1.8.2","@walletconnect/universal-provider":"2.21.1","@tanstack/react-query":"^5.60.2","bignumber.js":"^9.1.2","launchdarkly-react-client-sdk":"^3.6.0","lodash":"^4.17.21","mixpanel-browser":"^2.72.0","next":"^15.0.3","react":"18.3.1","react-dom":"18.3.1","react-responsive":"^10.0.0","sonner":"1.4.41","swr":"^2.2.5","tailwind-merge":"^2.5.4","usehooks-ts":"^3.1.1"},"devDependencies":{"@tsconfig/next":"^2.0.3","@types/lodash":"^4.17.13","@types/node":"^22.9.0","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@typescript-eslint/eslint-plugin":"^8.14.0","@typescript-eslint/parser":"^8.14.0","eslint":"^9.14.0","eslint-config-next":"^15.0.3","eslint-config-prettier":"^9.1.0","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^5.2.1","prettier":"^3.3.3","ts-node":"^10.9.2","typescript":"^5.6.3"},"peerDependencies":{"@mysten/dapp-kit-core":"1.0.3","@mysten/dapp-kit-react":"1.0.1","@mysten/sui":"2.3.1","@mysten/wallet-standard":"0.20.0","@suilend/sui-fe":"^2.0.10"}}
1
+ {"name":"@suilend/sui-fe-next","version":"2.0.16","private":false,"description":"A collection of TypeScript frontend components and hooks","author":"Suilend","license":"MIT","main":"./index.js","exports":{".":"./index.js","./contexts/WalletContext":"./contexts/WalletContext.jsx","./contexts/SettingsContext":"./contexts/SettingsContext.jsx","./contexts":"./contexts/index.js","./fetchers":"./fetchers/index.js","./fetchers/useFetchBalances":"./fetchers/useFetchBalances.js","./hooks/useRefreshOnBalancesChange":"./hooks/useRefreshOnBalancesChange.js","./hooks/useLedgerHashDialog":"./hooks/useLedgerHashDialog.js","./hooks/useIsAndroid":"./hooks/useIsAndroid.jsx","./hooks/useCoinMetadataMap":"./hooks/useCoinMetadataMap.js","./hooks":"./hooks/index.js","./hooks/useIsTouchscreen":"./hooks/useIsTouchscreen.jsx","./hooks/useIsiOS":"./hooks/useIsiOS.jsx","./hooks/keypair":"./hooks/keypair.js","./lib/track":"./lib/track.js","./lib":"./lib/index.js","./lib/router":"./lib/router.js","./lib/toasts":"./lib/toasts.jsx","./lib/connector":"./lib/connector.js"},"types":"./index.js","scripts":{"build":"rm -rf ./dist && bun tsc","eslint":"eslint --fix src/","prettier":"prettier --write src/","lint":"bun eslint && bun prettier && bun tsc --noEmit","release":"bun run build && bun ./release.js && cd ./dist && npm publish --access public"},"repository":{"type":"git","url":"git+https://github.com/suilend/sui-fe.git"},"bugs":{"url":"https://github.com/suilend/sui-fe/issues"},"dependencies":{"@reown/appkit":"1.8.2","@tanstack/react-query":"^5.60.2","@wallet-standard/app":"^1.1.0","@walletconnect/universal-provider":"2.21.1","bignumber.js":"^9.1.2","launchdarkly-react-client-sdk":"^3.6.0","lodash":"^4.17.21","mixpanel-browser":"^2.72.0","next":"^15.0.3","react":"18.3.1","react-dom":"18.3.1","react-responsive":"^10.0.0","sonner":"1.4.41","swr":"^2.2.5","tailwind-merge":"^2.5.4","usehooks-ts":"^3.1.1"},"devDependencies":{"@tsconfig/next":"^2.0.3","@types/lodash":"^4.17.13","@types/node":"^22.9.0","@types/react":"^18.3.12","@types/react-dom":"^18.3.1","@typescript-eslint/eslint-plugin":"^8.14.0","@typescript-eslint/parser":"^8.14.0","eslint":"^9.14.0","eslint-config-next":"^15.0.3","eslint-config-prettier":"^9.1.0","eslint-plugin-import":"^2.31.0","eslint-plugin-prettier":"^5.2.1","prettier":"^3.3.3","ts-node":"^10.9.2","typescript":"^5.6.3"},"peerDependencies":{"@mysten/dapp-kit-core":"1.0.3","@mysten/dapp-kit-react":"1.0.1","@mysten/sui":"2.3.1","@mysten/wallet-standard":"0.20.0","@suilend/sui-fe":"^2.0.10"}}