@lifi/widget 3.4.4 → 3.5.1-beta.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.
Files changed (121) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/_esm/components/AppContainer.js +11 -3
  3. package/_esm/components/AppContainer.js.map +1 -1
  4. package/_esm/components/Card/CardIconButton.d.ts +1 -1
  5. package/_esm/components/Header/WalletMenu.js +5 -1
  6. package/_esm/components/Header/WalletMenu.js.map +1 -1
  7. package/_esm/components/Step/Step.js +3 -3
  8. package/_esm/components/Step/Step.js.map +1 -1
  9. package/_esm/components/Step/StepProcess.js +3 -1
  10. package/_esm/components/Step/StepProcess.js.map +1 -1
  11. package/_esm/components/Tabs/Tabs.style.d.ts +1 -1
  12. package/_esm/components/Token/Token.js +8 -12
  13. package/_esm/components/Token/Token.js.map +1 -1
  14. package/_esm/components/TokenList/TokenList.js +4 -1
  15. package/_esm/components/TokenList/TokenList.js.map +1 -1
  16. package/_esm/components/TokenList/TokenList.style.d.ts +2 -2
  17. package/_esm/components/TokenList/TokenListItem.js +3 -1
  18. package/_esm/components/TokenList/TokenListItem.js.map +1 -1
  19. package/_esm/components/TransactionDetails.js +5 -11
  20. package/_esm/components/TransactionDetails.js.map +1 -1
  21. package/_esm/config/constants.d.ts +2 -1
  22. package/_esm/config/constants.js +2 -1
  23. package/_esm/config/constants.js.map +1 -1
  24. package/_esm/config/version.d.ts +1 -1
  25. package/_esm/config/version.js +1 -1
  26. package/_esm/config/version.js.map +1 -1
  27. package/_esm/hooks/useExplorer.d.ts +5 -0
  28. package/_esm/hooks/useExplorer.js +40 -0
  29. package/_esm/hooks/useExplorer.js.map +1 -0
  30. package/_esm/hooks/useProcessMessage.js +1 -1
  31. package/_esm/hooks/useRoutes.d.ts +1 -1
  32. package/_esm/hooks/useRoutes.js +4 -0
  33. package/_esm/hooks/useRoutes.js.map +1 -1
  34. package/_esm/i18n/bn.json +42 -33
  35. package/_esm/i18n/de.json +43 -34
  36. package/_esm/i18n/en.json +3 -2
  37. package/_esm/i18n/es.json +113 -104
  38. package/_esm/i18n/fr.json +45 -36
  39. package/_esm/i18n/hi.json +38 -29
  40. package/_esm/i18n/id.json +42 -33
  41. package/_esm/i18n/it.json +43 -34
  42. package/_esm/i18n/ja.json +45 -36
  43. package/_esm/i18n/ko.json +43 -34
  44. package/_esm/i18n/pt.json +45 -36
  45. package/_esm/i18n/th.json +45 -36
  46. package/_esm/i18n/tr.json +44 -35
  47. package/_esm/i18n/uk.json +45 -36
  48. package/_esm/i18n/vi.json +45 -36
  49. package/_esm/i18n/zh.json +45 -36
  50. package/_esm/pages/SelectTokenPage/useTokenListHeight.js +2 -0
  51. package/_esm/pages/SelectTokenPage/useTokenListHeight.js.map +1 -1
  52. package/_esm/pages/SendToWallet/BookmarksPage.js +3 -4
  53. package/_esm/pages/SendToWallet/BookmarksPage.js.map +1 -1
  54. package/_esm/pages/SendToWallet/ConnectedWalletsPage.js +5 -4
  55. package/_esm/pages/SendToWallet/ConnectedWalletsPage.js.map +1 -1
  56. package/_esm/pages/SendToWallet/RecentWalletsPage.js +3 -4
  57. package/_esm/pages/SendToWallet/RecentWalletsPage.js.map +1 -1
  58. package/_esm/pages/SendToWallet/SendToConfiguredWalletPage.js +3 -4
  59. package/_esm/pages/SendToWallet/SendToConfiguredWalletPage.js.map +1 -1
  60. package/_esm/pages/SendToWallet/SendToWalletPage.style.js +3 -1
  61. package/_esm/pages/SendToWallet/SendToWalletPage.style.js.map +1 -1
  62. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js +2 -11
  63. package/_esm/pages/TransactionDetailsPage/TransactionDetailsPage.js.map +1 -1
  64. package/_esm/pages/TransactionDetailsPage/TransferIdCard.d.ts +5 -0
  65. package/_esm/pages/TransactionDetailsPage/TransferIdCard.js +32 -0
  66. package/_esm/pages/TransactionDetailsPage/TransferIdCard.js.map +1 -0
  67. package/_esm/pages/TransactionPage/StatusBottomSheet.js +3 -2
  68. package/_esm/pages/TransactionPage/StatusBottomSheet.js.map +1 -1
  69. package/_esm/providers/I18nProvider/I18nProvider.js +2 -0
  70. package/_esm/providers/I18nProvider/I18nProvider.js.map +1 -1
  71. package/_esm/providers/I18nProvider/percentFormatter.d.ts +7 -0
  72. package/_esm/providers/I18nProvider/percentFormatter.js +19 -0
  73. package/_esm/providers/I18nProvider/percentFormatter.js.map +1 -0
  74. package/_esm/types/widget.d.ts +9 -2
  75. package/_esm/types/widget.js.map +1 -1
  76. package/_esm/utils/elements.d.ts +2 -1
  77. package/_esm/utils/elements.js +1 -0
  78. package/_esm/utils/elements.js.map +1 -1
  79. package/components/AppContainer.tsx +31 -18
  80. package/components/Header/WalletMenu.tsx +7 -1
  81. package/components/Step/Step.tsx +3 -6
  82. package/components/Step/StepProcess.tsx +5 -2
  83. package/components/Token/Token.tsx +15 -18
  84. package/components/TokenList/TokenList.tsx +8 -1
  85. package/components/TokenList/TokenListItem.tsx +4 -1
  86. package/components/TransactionDetails.tsx +8 -17
  87. package/config/constants.ts +3 -1
  88. package/config/version.ts +1 -1
  89. package/hooks/useExplorer.ts +51 -0
  90. package/hooks/useProcessMessage.ts +1 -1
  91. package/hooks/useRoutes.ts +5 -0
  92. package/i18n/bn.json +42 -33
  93. package/i18n/de.json +43 -34
  94. package/i18n/en.json +3 -2
  95. package/i18n/es.json +113 -104
  96. package/i18n/fr.json +45 -36
  97. package/i18n/hi.json +38 -29
  98. package/i18n/id.json +42 -33
  99. package/i18n/it.json +43 -34
  100. package/i18n/ja.json +45 -36
  101. package/i18n/ko.json +43 -34
  102. package/i18n/pt.json +45 -36
  103. package/i18n/th.json +45 -36
  104. package/i18n/tr.json +44 -35
  105. package/i18n/uk.json +45 -36
  106. package/i18n/vi.json +45 -36
  107. package/i18n/zh.json +45 -36
  108. package/package.json +12 -12
  109. package/pages/SelectTokenPage/useTokenListHeight.ts +3 -0
  110. package/pages/SendToWallet/BookmarksPage.tsx +6 -4
  111. package/pages/SendToWallet/ConnectedWalletsPage.tsx +8 -7
  112. package/pages/SendToWallet/RecentWalletsPage.tsx +6 -6
  113. package/pages/SendToWallet/SendToConfiguredWalletPage.tsx +6 -6
  114. package/pages/SendToWallet/SendToWalletPage.style.tsx +3 -0
  115. package/pages/TransactionDetailsPage/TransactionDetailsPage.tsx +2 -32
  116. package/pages/TransactionDetailsPage/TransferIdCard.tsx +67 -0
  117. package/pages/TransactionPage/StatusBottomSheet.tsx +4 -0
  118. package/providers/I18nProvider/I18nProvider.tsx +2 -0
  119. package/providers/I18nProvider/percentFormatter.ts +18 -0
  120. package/types/widget.ts +7 -2
  121. package/utils/elements.ts +1 -0
package/i18n/zh.json CHANGED
@@ -4,18 +4,20 @@
4
4
  "title": "语言"
5
5
  },
6
6
  "format": {
7
- "currency": "{{value, currency(currency: USD)}}",
8
- "number": "{{value, number(maximumFractionDigits: 9)}}"
7
+ "currency": "",
8
+ "number": "{{value, number(maximumFractionDigits: 9)}}",
9
+ "percent": ""
9
10
  },
10
11
  "button": {
11
12
  "auto": "自动",
12
13
  "bookmark": "收藏",
13
14
  "bookmarks": "收藏夹",
14
15
  "bridge": "跨链",
16
+ "bridgeReview": "",
15
17
  "buy": "购买",
16
- "buyNow": "立即购买",
17
18
  "cancel": "取消",
18
19
  "changeWallet": "更换钱包",
20
+ "checkoutReview": "",
19
21
  "close": "关闭",
20
22
  "confirm": "确认",
21
23
  "connectWallet": "关联钱包",
@@ -24,6 +26,8 @@
24
26
  "copyAddress": "复制地址",
25
27
  "dark": "深色主题",
26
28
  "delete": "删除",
29
+ "deposit": "",
30
+ "depositReview": "",
27
31
  "disconnect": "断开连接",
28
32
  "done": "确认",
29
33
  "exchange": "兑换",
@@ -36,14 +40,12 @@
36
40
  "removeTransaction": "删除交易",
37
41
  "reset": "重置",
38
42
  "resetSettings": "恢复默认设置",
39
- "reviewBridge": "查看跨链详情",
40
- "reviewPurchase": "查看购买详情",
41
- "reviewSwap": "查看该兑换",
42
43
  "seeDetails": "查看详情",
43
44
  "showAll": "显示所有",
44
45
  "startBridging": "开始跨链",
45
46
  "startSwapping": "开始兑换",
46
47
  "swap": "兑换",
48
+ "swapReview": "",
47
49
  "tryAgain": "重试",
48
50
  "viewCoverage": "查看我们的覆盖范围",
49
51
  "viewOnExplorer": "在区块链浏览器上查看"
@@ -53,15 +55,18 @@
53
55
  "bookmarkedWallets": "已收藏的钱包",
54
56
  "bridge": "跨链",
55
57
  "checkout": "支付",
58
+ "checkoutDetails": "",
59
+ "deposit": "",
60
+ "depositDetails": "",
56
61
  "exchange": "兑换",
57
62
  "from": "兑换自",
58
63
  "gas": "燃气费",
59
64
  "payWith": "支付方式",
60
- "purchase": "购买",
61
- "purchaseDetails": "交易明细",
65
+ "receive": "",
62
66
  "recentWallets": "最近使用的钱包",
63
67
  "selectChain": "选择网络",
64
68
  "selectWallet": "选择你的钱包",
69
+ "send": "",
65
70
  "sendToWallet": "发送到该钱包",
66
71
  "settings": "设置",
67
72
  "swap": "兑换",
@@ -69,7 +74,8 @@
69
74
  "transactionDetails": "交易详情",
70
75
  "transactionHistory": "交易记录",
71
76
  "walletConnected": "连接钱包",
72
- "youGet": "您获得"
77
+ "youGet": "您获得",
78
+ "youPay": ""
73
79
  },
74
80
  "info": {
75
81
  "message": {
@@ -82,7 +88,7 @@
82
88
  "routeNotFound": "导致其的原因可能是:流动性低,所选定代币的数额太低,燃气费过高,或者当前没有合适的交易路径。"
83
89
  },
84
90
  "title": {
85
- "autoRefuel": "获得燃气费",
91
+ "autoRefuel": "",
86
92
  "emptyActiveTransactions": "没有正在进行的交易",
87
93
  "emptyTransactionHistory": "近期无交易",
88
94
  "routeNotFound": "没有可用的路由"
@@ -90,14 +96,15 @@
90
96
  },
91
97
  "success": {
92
98
  "message": {
93
- "exchangePartiallySuccessful": "我们尝试完成本次交易,但是 {{tool}} 的 {{tokenSymbol}} 代币流动性不足。",
99
+ "exchangePartiallySuccessful": "",
94
100
  "exchangeSuccessful": "{{walletAddress}} 钱包在 {{chainName}} 链上收到 {{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}}",
95
- "purchaseSuccessful": "您的 {{walletAddress}} 钱包在 {{chainName}} 链上拥有该 {{assetName}} 财产"
101
+ "checkoutSuccessful": ""
96
102
  },
97
103
  "title": {
98
104
  "bridgePartiallySuccessful": "跨链部分成功",
99
105
  "bridgeSuccessful": "跨链成功",
100
- "purchaseSuccessful": "购买成功",
106
+ "depositSuccessful": "",
107
+ "checkoutSuccessful": "",
101
108
  "refundIssued": "退款已受理",
102
109
  "swapPartiallySuccessful": "兑换部分完成",
103
110
  "swapSuccessful": "兑换成功"
@@ -132,8 +139,10 @@
132
139
  "signatureRejected": "需要您签名来完成此次交易。不用担心,{{chainName}} 链上 {{amount, number(maximumFractionDigits: 9)}} 个 {{tokenSymbol}} 仍在您的钱包里。",
133
140
  "slippageThreshold": "滑点大于预设值,请选择其他路由并获取新的价格。",
134
141
  "transactionCanceled": "交易已被取消。",
142
+ "transactionExpired": "",
135
143
  "transactionFailed": "请查看区块浏览器以了解更多信息。",
136
144
  "transactionNotSent": "交易未能发送。",
145
+ "transactionSimulationFailed": "",
137
146
  "unknown": "请再试一次或者联系支持。",
138
147
  "walletChangedDuringExecution": ""
139
148
  },
@@ -149,7 +158,9 @@
149
158
  "signatureRejected": "交易需要签名。",
150
159
  "slippageNotMet": "滑点未满足",
151
160
  "transactionCanceled": "交易取消",
161
+ "transactionExpired": "",
152
162
  "transactionFailed": "交易失败",
163
+ "transactionSimulationFailed": "",
153
164
  "transactionUnderpriced": "交易定价过低",
154
165
  "transactionUnprepared": "无法开始该交易",
155
166
  "unknown": "未知错误",
@@ -161,16 +172,20 @@
161
172
  }
162
173
  },
163
174
  "tooltip": {
164
- "estimatedTime": "预计兑换的执行时间(分钟)。",
175
+ "deselectAll": "取消全选",
176
+ "estimatedTime": "",
177
+ "feeCollection": "",
178
+ "minReceived": "",
165
179
  "notFound": {
166
180
  "text": "我们找不到这个页面。",
167
181
  "title": "404"
168
182
  },
169
- "numberOfSteps": "一系列的兑换步骤,每个步骤可能包含1-2个需要签名的交易。",
183
+ "numberOfSteps": "",
184
+ "priceImpact": "",
170
185
  "progressToNextUpdate": "数据将在{{value}} 秒后自动刷新,点击这里可以手动更新。",
171
- "settingsModified": "设置(已修改)",
172
186
  "selectAll": "全选",
173
- "deselectAll": "取消全选"
187
+ "settingsModified": "设置(已修改)",
188
+ "slippage": ""
174
189
  },
175
190
  "main": {
176
191
  "allTokens": "所有代币",
@@ -180,21 +195,22 @@
180
195
  "depositStepDetails": "通过 {{tool}} 存入资金",
181
196
  "featuredTokens": "精选代币",
182
197
  "fees": {
183
- "estimated": "预估费用",
184
- "networkEstimated": "预估网络费用:",
185
- "networkPaid": "已支付网络费用:",
186
- "paid": "已支付费用",
187
- "providerEstimated": "预估流动性提供商费用:",
188
- "providerPaid": "已支付流动性提供商费用:"
198
+ "defaultIntegrator": "",
199
+ "estimated": "",
200
+ "integrator": "",
201
+ "network": "",
202
+ "paid": "",
203
+ "provider": ""
189
204
  },
190
205
  "from": "从",
191
- "fromAmount": "需要支付",
192
- "gasCost": "燃气费消耗",
193
206
  "inProgress": "进行中",
207
+ "maxSlippage": "",
208
+ "minReceived": "",
194
209
  "myTokens": "我的代币",
195
210
  "onChain": "在{{chainName}} 上",
196
211
  "ownedBy": "属于",
197
212
  "popularTokens": "热门代币",
213
+ "priceImpact": "",
198
214
  "process": {
199
215
  "bridge": {
200
216
  "actionRequired": "请签署此交易",
@@ -243,18 +259,17 @@
243
259
  "sentToAddress": "发送到{{address}}",
244
260
  "stepBridge": "跨链",
245
261
  "stepBridgeAndBuy": "跨链并购买",
262
+ "stepBridgeAndDeposit": "",
246
263
  "stepDetails": "通过 LI.FI {{tool}}",
247
264
  "stepSwap": "兑换",
248
265
  "stepSwapAndBridge": "兑换和跨链",
249
266
  "stepSwapAndBuy": "兑换并购买",
267
+ "stepSwapAndDeposit": "",
250
268
  "supportId": "支持ID",
251
269
  "swapStepDetails": "通过{{tool}}在{{chain}}链上兑换代币",
252
270
  "tags": {
253
271
  "cheapest": "最佳报价",
254
- "fastest": "速度最坏",
255
- "insurable": "可投保",
256
- "insurance": "保险",
257
- "insured": "受保中"
272
+ "fastest": "速度最坏"
258
273
  },
259
274
  "to": "到",
260
275
  "tokenOnChain": "{{chainName}}链上的{{tokenSymbol}}",
@@ -262,12 +277,6 @@
262
277
  "tokenSearch": "按代币名称或者地址搜索",
263
278
  "valueLoss": "资金损失"
264
279
  },
265
- "insurance": {
266
- "bridgeExploits": "跨链桥故障、被黑或者被利用漏洞",
267
- "insure": "在跨链期间为<0>{{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}}</0> 投保。",
268
- "insured": "在跨链期间为<0>{{amount, number(maximumFractionDigits: 9)}} {{tokenSymbol}}</0> 投保。",
269
- "slippageError": "目标链代币的滑点错误"
270
- },
271
280
  "settings": {
272
281
  "theme": "主题",
273
282
  "enabledBridges": "跨链桥",
@@ -279,7 +288,7 @@
279
288
  "title": "燃气费"
280
289
  },
281
290
  "routePriority": "路由优先级",
282
- "slippage": "滑点",
291
+ "slippage": "",
283
292
  "custom": "自定义",
284
293
  "resetSettings": "您正在使用自定义设置来过滤可用路由。"
285
294
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifi/widget",
3
- "version": "3.4.4",
3
+ "version": "3.5.1-beta.0",
4
4
  "description": "LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.",
5
5
  "type": "module",
6
6
  "main": "./_esm/index.js",
@@ -32,29 +32,29 @@
32
32
  "lifi"
33
33
  ],
34
34
  "dependencies": {
35
- "@emotion/react": "^11.13.0",
35
+ "@emotion/react": "^11.13.3",
36
36
  "@emotion/styled": "^11.13.0",
37
- "@lifi/sdk": "^3.1.5",
38
- "@lifi/wallet-management": "^3.1.3",
37
+ "@lifi/sdk": "^3.2.0",
38
+ "@lifi/wallet-management": "^3.1.5-beta.0",
39
39
  "@mui/icons-material": "^5.16.7",
40
40
  "@mui/lab": "^5.0.0-alpha.173",
41
41
  "@mui/material": "^5.16.7",
42
42
  "@solana/wallet-adapter-base": "^0.9.23",
43
43
  "@solana/wallet-adapter-react": "^0.15.35",
44
- "@solana/web3.js": "^1.95.2",
45
- "@tanstack/react-query": "^5.51.23",
46
- "@tanstack/react-virtual": "^3.9.0",
47
- "i18next": "^23.12.3",
44
+ "@solana/web3.js": "^1.95.3",
45
+ "@tanstack/react-query": "^5.55.4",
46
+ "@tanstack/react-virtual": "^3.10.7",
47
+ "i18next": "^23.15.1",
48
48
  "microdiff": "^1.4.0",
49
49
  "mitt": "^3.0.1",
50
50
  "react": "^18.3.1",
51
51
  "react-dom": "^18.3.1",
52
52
  "react-i18next": "^15.0.1",
53
- "react-intersection-observer": "^9.13.0",
54
- "react-router-dom": "^6.26.0",
53
+ "react-intersection-observer": "^9.13.1",
54
+ "react-router-dom": "^6.26.2",
55
55
  "uuid": "^10.0.0",
56
- "viem": "^2.19.4",
57
- "wagmi": "^2.12.5",
56
+ "viem": "^2.21.4",
57
+ "wagmi": "^2.12.9",
58
58
  "zustand": "^4.5.5"
59
59
  },
60
60
  "peerDependencies": {
@@ -78,6 +78,9 @@ export const useTokenListHeight = ({
78
78
 
79
79
  const processResize = debounce(() => handleResize(), 40);
80
80
 
81
+ // calling this on initial mount prevents the lists resizing appearing glitchy
82
+ handleResize();
83
+
81
84
  const appContainer = document.getElementById(
82
85
  createElementId(ElementId.AppExpandedContainer, elementId),
83
86
  );
@@ -15,7 +15,7 @@ import type { BottomSheetBase } from '../../components/BottomSheet/types.js';
15
15
  import { ListItemButton } from '../../components/ListItem//ListItemButton.js';
16
16
  import { ListItem } from '../../components/ListItem/ListItem.js';
17
17
  import { Menu } from '../../components/Menu.js';
18
- import { useChains } from '../../hooks/useChains.js';
18
+ import { useExplorer } from '../../hooks/useExplorer.js';
19
19
  import { useHeader } from '../../hooks/useHeader.js';
20
20
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
21
21
  import { useWidgetConfig } from '../../providers/WidgetProvider/WidgetProvider.js';
@@ -43,11 +43,11 @@ export const BookmarksPage = () => {
43
43
  const { requiredToChainType } = useToAddressRequirements();
44
44
  const { addBookmark, removeBookmark, setSelectedBookmark } =
45
45
  useBookmarkActions();
46
- const { getChainById } = useChains();
47
46
  const navigate = useNavigate();
48
47
  const { setFieldValue } = useFieldActions();
49
48
  const { setSendToWallet } = useSendToWalletActions();
50
49
  const { variant } = useWidgetConfig();
50
+ const { getAddressLink } = useExplorer();
51
51
 
52
52
  useHeader(t(`header.bookmarkedWallets`));
53
53
 
@@ -88,9 +88,11 @@ export const BookmarksPage = () => {
88
88
 
89
89
  const handleViewOnExplorer = () => {
90
90
  if (bookmark) {
91
- const chain = getChainById(defaultChainIdsByType[bookmark.chainType]);
92
91
  window.open(
93
- `${chain?.metamask.blockExplorerUrls[0]}address/${bookmark.address}`,
92
+ getAddressLink(
93
+ bookmark.address,
94
+ defaultChainIdsByType[bookmark.chainType],
95
+ ),
94
96
  '_blank',
95
97
  );
96
98
  }
@@ -14,7 +14,7 @@ import { ListItemButton } from '../../components/ListItem/ListItemButton.js';
14
14
  import { Menu } from '../../components/Menu.js';
15
15
  import type { Account } from '../../hooks/useAccount.js';
16
16
  import { useAccount } from '../../hooks/useAccount.js';
17
- import { useChains } from '../../hooks/useChains.js';
17
+ import { useExplorer } from '../../hooks/useExplorer.js';
18
18
  import { useHeader } from '../../hooks/useHeader.js';
19
19
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
20
20
  import { useBookmarkActions } from '../../stores/bookmarks/useBookmarkActions.js';
@@ -33,7 +33,6 @@ export const ConnectedWalletsPage = () => {
33
33
  const [selectedAccount, setSelectedAccount] = useState<Account>();
34
34
  const { accounts } = useAccount();
35
35
  const { setSelectedBookmark } = useBookmarkActions();
36
- const { getChainById } = useChains();
37
36
  const { requiredToChainType } = useToAddressRequirements();
38
37
  const navigate = useNavigate();
39
38
  const { setFieldValue } = useFieldActions();
@@ -41,6 +40,7 @@ export const ConnectedWalletsPage = () => {
41
40
  const [moreMenuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>();
42
41
  const moreMenuId = useId();
43
42
  const open = Boolean(moreMenuAnchorEl);
43
+ const { getAddressLink } = useExplorer();
44
44
 
45
45
  useHeader(t('sendToWallet.connectedWallets'));
46
46
 
@@ -79,11 +79,12 @@ export const ConnectedWalletsPage = () => {
79
79
 
80
80
  const handleViewOnExplorer = () => {
81
81
  if (selectedAccount?.chainId) {
82
- const chain = getChainById(selectedAccount.chainId);
83
- window.open(
84
- `${chain?.metamask.blockExplorerUrls[0]}address/${selectedAccount.address}`,
85
- '_blank',
86
- );
82
+ if (selectedAccount.address) {
83
+ window.open(
84
+ getAddressLink(selectedAccount.address, selectedAccount.chainId),
85
+ '_blank',
86
+ );
87
+ }
87
88
  }
88
89
  closeMenu();
89
90
  };
@@ -15,7 +15,7 @@ import type { BottomSheetBase } from '../../components/BottomSheet/types.js';
15
15
  import { ListItem } from '../../components/ListItem/ListItem.js';
16
16
  import { ListItemButton } from '../../components/ListItem/ListItemButton.js';
17
17
  import { Menu } from '../../components/Menu.js';
18
- import { useChains } from '../../hooks/useChains.js';
18
+ import { useExplorer } from '../../hooks/useExplorer.js';
19
19
  import { useHeader } from '../../hooks/useHeader.js';
20
20
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
21
21
  import type { Bookmark } from '../../stores/bookmarks/types.js';
@@ -47,12 +47,12 @@ export const RecentWalletsPage = () => {
47
47
  setSelectedBookmark,
48
48
  addRecentWallet,
49
49
  } = useBookmarkActions();
50
- const { getChainById } = useChains();
51
50
  const { setFieldValue } = useFieldActions();
52
51
  const { setSendToWallet } = useSendToWalletActions();
53
52
  const moreMenuId = useId();
54
53
  const [moreMenuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>();
55
54
  const open = Boolean(moreMenuAnchorEl);
55
+ const { getAddressLink } = useExplorer();
56
56
 
57
57
  useHeader(t(`header.recentWallets`));
58
58
 
@@ -95,11 +95,11 @@ export const RecentWalletsPage = () => {
95
95
 
96
96
  const handleViewOnExplorer = () => {
97
97
  if (selectedRecent) {
98
- const chain = getChainById(
99
- defaultChainIdsByType[selectedRecent.chainType],
100
- );
101
98
  window.open(
102
- `${chain?.metamask.blockExplorerUrls[0]}address/${selectedRecent.address}`,
99
+ getAddressLink(
100
+ selectedRecent.address,
101
+ defaultChainIdsByType[selectedRecent.chainType],
102
+ ),
103
103
  '_blank',
104
104
  );
105
105
  }
@@ -10,7 +10,7 @@ import { AccountAvatar } from '../../components/Avatar/AccountAvatar.js';
10
10
  import { ListItem } from '../../components/ListItem/ListItem.js';
11
11
  import { ListItemButton } from '../../components/ListItem/ListItemButton.js';
12
12
  import { Menu } from '../../components/Menu.js';
13
- import { useChains } from '../../hooks/useChains.js';
13
+ import { useExplorer } from '../../hooks/useExplorer.js';
14
14
  import { useHeader } from '../../hooks/useHeader.js';
15
15
  import { useNavigateBack } from '../../hooks/useNavigateBack.js';
16
16
  import { useToAddressRequirements } from '../../hooks/useToAddressRequirements.js';
@@ -34,10 +34,10 @@ export const SendToConfiguredWalletPage = () => {
34
34
  const { requiredToChainType } = useToAddressRequirements();
35
35
  const { setSelectedBookmark } = useBookmarkActions();
36
36
  const { setFieldValue } = useFieldActions();
37
- const { getChainById } = useChains();
38
37
  const moreMenuId = useId();
39
38
  const [moreMenuAnchorEl, setMenuAnchorEl] = useState<HTMLElement | null>();
40
39
  const open = Boolean(moreMenuAnchorEl);
40
+ const { getAddressLink } = useExplorer();
41
41
 
42
42
  useHeader(t(`header.sendToWallet`));
43
43
 
@@ -65,11 +65,11 @@ export const SendToConfiguredWalletPage = () => {
65
65
 
66
66
  const handleViewOnExplorer = () => {
67
67
  if (selectedToAddress) {
68
- const chain = getChainById(
69
- defaultChainIdsByType[selectedToAddress.chainType],
70
- );
71
68
  window.open(
72
- `${chain?.metamask.blockExplorerUrls[0]}address/${selectedToAddress.address}`,
69
+ getAddressLink(
70
+ selectedToAddress.address,
71
+ defaultChainIdsByType[selectedToAddress.chainType],
72
+ ),
73
73
  '_blank',
74
74
  );
75
75
  }
@@ -44,6 +44,9 @@ interface FullHeightAdjustablePageContainerProps extends PageContainerProps {
44
44
 
45
45
  export const FullHeightAdjustablePageContainer = styled(
46
46
  SendToWalletPageContainer,
47
+ {
48
+ shouldForwardProp: (prop) => prop !== 'enableFullHeight',
49
+ },
47
50
  )<FullHeightAdjustablePageContainerProps>(({ theme, enableFullHeight }) => ({
48
51
  justifyContent: 'space-between',
49
52
  ...(enableFullHeight && theme.container?.height === '100%'
@@ -1,12 +1,8 @@
1
1
  import type { FullStatusData } from '@lifi/sdk';
2
- import { ContentCopyRounded } from '@mui/icons-material';
3
2
  import { Box, Typography } from '@mui/material';
4
3
  import { useEffect, useMemo } from 'react';
5
4
  import { useTranslation } from 'react-i18next';
6
5
  import { useLocation } from 'react-router-dom';
7
- import { Card } from '../../components/Card/Card.js';
8
- import { CardIconButton } from '../../components/Card/CardIconButton.js';
9
- import { CardTitle } from '../../components/Card/CardTitle.js';
10
6
  import { ContractComponent } from '../../components/ContractComponent/ContractComponent.js';
11
7
  import { PageContainer } from '../../components/PageContainer.js';
12
8
  import { getStepList } from '../../components/Step/StepList.js';
@@ -22,6 +18,7 @@ import { buildRouteFromTxHistory } from '../../utils/converters.js';
22
18
  import { navigationRoutes } from '../../utils/navigationRoutes.js';
23
19
  import { ContactSupportButton } from './ContactSupportButton.js';
24
20
  import { TransactionDetailsSkeleton } from './TransactionDetailsSkeleton.js';
21
+ import { TransferIdCard } from './TransferIdCard.js';
25
22
 
26
23
  export const TransactionDetailsPage: React.FC = () => {
27
24
  const { t, i18n } = useTranslation();
@@ -66,10 +63,6 @@ export const TransactionDetailsPage: React.FC = () => {
66
63
  }
67
64
  }, [isLoading, navigate, routeExecution]);
68
65
 
69
- const copySupportId = async () => {
70
- await navigator.clipboard.writeText(supportId);
71
- };
72
-
73
66
  const sourceTxHash = getSourceTxHash(routeExecution?.route);
74
67
 
75
68
  let supportId = sourceTxHash ?? routeExecution?.route.id ?? '';
@@ -117,30 +110,7 @@ export const TransactionDetailsPage: React.FC = () => {
117
110
  sx={{ marginTop: 2 }}
118
111
  />
119
112
  ) : null}
120
- <Card sx={{ marginTop: 2 }}>
121
- <Box
122
- sx={{
123
- display: 'flex',
124
- flex: 1,
125
- }}
126
- >
127
- <CardTitle flex={1}>{t('main.supportId')}</CardTitle>
128
- <Box mr={2} mt={1}>
129
- <CardIconButton size="small" onClick={copySupportId}>
130
- <ContentCopyRounded fontSize="inherit" />
131
- </CardIconButton>
132
- </Box>
133
- </Box>
134
- <Typography
135
- variant="body2"
136
- pt={1}
137
- pb={2}
138
- px={2}
139
- sx={{ wordBreak: 'break-all' }}
140
- >
141
- {supportId}
142
- </Typography>
143
- </Card>
113
+ <TransferIdCard transferId={supportId} />
144
114
  <Box mt={2}>
145
115
  <ContactSupportButton supportId={supportId} />
146
116
  </Box>
@@ -0,0 +1,67 @@
1
+ import { ContentCopyRounded, OpenInNew } from '@mui/icons-material';
2
+ import { Box, Typography } from '@mui/material';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { Card } from '../../components/Card/Card.js';
5
+ import { CardIconButton } from '../../components/Card/CardIconButton.js';
6
+ import { CardTitle } from '../../components/Card/CardTitle.js';
7
+ import { useExplorer } from '../../hooks/useExplorer.js';
8
+
9
+ interface TransferIdCardProps {
10
+ transferId: string;
11
+ }
12
+
13
+ const getTxHash = (transferId: string) =>
14
+ transferId.indexOf('_') !== -1
15
+ ? transferId.substring(0, transferId.indexOf('_'))
16
+ : transferId;
17
+
18
+ export const TransferIdCard = ({ transferId }: TransferIdCardProps) => {
19
+ const { t } = useTranslation();
20
+ const { getTransactionLink } = useExplorer();
21
+
22
+ const copyTransferId = async () => {
23
+ await navigator.clipboard.writeText(transferId);
24
+ };
25
+
26
+ const openTransferIdInExplorer = () => {
27
+ const txHash = getTxHash(transferId);
28
+ window.open(getTransactionLink(txHash), '_blank');
29
+ };
30
+
31
+ return (
32
+ <Card sx={{ marginTop: 2 }}>
33
+ <Box
34
+ sx={{
35
+ display: 'flex',
36
+ flex: 1,
37
+ }}
38
+ >
39
+ <CardTitle flex={1}>{t('main.transferId')}</CardTitle>
40
+ <Box
41
+ sx={{
42
+ gap: 1,
43
+ display: 'flex',
44
+ marginRight: 2,
45
+ marginTop: 1,
46
+ }}
47
+ >
48
+ <CardIconButton size="small" onClick={copyTransferId}>
49
+ <ContentCopyRounded fontSize="inherit" />
50
+ </CardIconButton>
51
+ <CardIconButton size="small" onClick={openTransferIdInExplorer}>
52
+ <OpenInNew fontSize="inherit" />
53
+ </CardIconButton>
54
+ </Box>
55
+ </Box>
56
+ <Typography
57
+ variant="body2"
58
+ pt={1}
59
+ pb={2}
60
+ px={2}
61
+ sx={{ wordBreak: 'break-all' }}
62
+ >
63
+ {transferId}
64
+ </Typography>
65
+ </Card>
66
+ );
67
+ };
@@ -85,6 +85,7 @@ export const StatusBottomSheetContent: React.FC<
85
85
  subvariantOptions,
86
86
  contractSecondaryComponent,
87
87
  contractCompactComponent,
88
+ feeConfig,
88
89
  } = useWidgetConfig();
89
90
  const { getChainById } = useAvailableChains();
90
91
 
@@ -251,6 +252,8 @@ export const StatusBottomSheetContent: React.FC<
251
252
  hasEnumFlag(status, RouteExecutionStatus.Done) &&
252
253
  (contractCompactComponent || contractSecondaryComponent);
253
254
 
255
+ const VcComponent = feeConfig?._vcComponent;
256
+
254
257
  return (
255
258
  <Box p={3} ref={ref}>
256
259
  {!showContractComponent ? (
@@ -296,6 +299,7 @@ export const StatusBottomSheetContent: React.FC<
296
299
  {secondaryMessage ? (
297
300
  <Typography py={1}>{secondaryMessage}</Typography>
298
301
  ) : null}
302
+ {VcComponent ? <VcComponent route={route} /> : null}
299
303
  <Box mt={2}>
300
304
  <Button variant="contained" fullWidth onClick={handlePrimaryButton}>
301
305
  {status === RouteExecutionStatus.Idle ? t('button.ok') : null}
@@ -8,6 +8,7 @@ import { deepMerge } from '../../utils/deepMerge.js';
8
8
  import { isItemAllowed } from '../../utils/item.js';
9
9
  import { useWidgetConfig } from '../WidgetProvider/WidgetProvider.js';
10
10
  import { currencyExtendedFormatter } from './currencyExtendedFormatter.js';
11
+ import { percentFormatter } from './percentFormatter.js';
11
12
  import type { LanguageKey, LanguageTranslationResources } from './types.js';
12
13
 
13
14
  export const I18nProvider: React.FC<React.PropsWithChildren> = ({
@@ -66,6 +67,7 @@ export const I18nProvider: React.FC<React.PropsWithChildren> = ({
66
67
  'currencyExt',
67
68
  currencyExtendedFormatter,
68
69
  );
70
+ i18n.services.formatter?.addCached('percent', percentFormatter);
69
71
 
70
72
  return i18n;
71
73
  }, [language, languageResources, languages]);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * We use <0.01% for both small positive and negative changes to keep it simple and clear, focusing on minimal impact rather than direction.
3
+ * Examples:
4
+ * +0.007% -> <0.01%
5
+ * -0.003% -> <0.01%
6
+ */
7
+ export const percentFormatter = (lng: string | undefined, options: any) => {
8
+ const formatter = new Intl.NumberFormat(lng, {
9
+ ...options,
10
+ style: 'percent',
11
+ });
12
+ return (value: any) => {
13
+ if ((value > 0 && value < 0.0001) || (value < 0 && value > -0.0001)) {
14
+ return `<${formatter.format(0.0001)}`;
15
+ }
16
+ return formatter.format(value);
17
+ };
18
+ };