@unisat/wallet-state 1.0.4 → 1.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.
Files changed (99) hide show
  1. package/LICENSE +0 -5
  2. package/lib/index.d.mts +2012 -200
  3. package/lib/index.d.ts +2012 -200
  4. package/lib/index.js +6951 -570
  5. package/lib/index.js.map +1 -1
  6. package/lib/index.mjs +6754 -517
  7. package/lib/index.mjs.map +1 -1
  8. package/lib/types/index.d.mts +1 -1
  9. package/lib/types/index.d.ts +1 -1
  10. package/package.json +19 -15
  11. package/src/.DS_Store +0 -0
  12. package/src/context/ApprovalContext.tsx +27 -0
  13. package/src/context/DeviceContext.tsx +36 -0
  14. package/src/context/I18nContext.tsx +14 -172
  15. package/src/context/NavigationContext.tsx +305 -0
  16. package/src/context/PriceContext.tsx +2 -2
  17. package/src/context/StorageContext.tsx +393 -0
  18. package/src/context/ToolsContext.tsx +50 -0
  19. package/src/context/WalletContext.tsx +119 -108
  20. package/src/context/index.ts +17 -2
  21. package/src/hooks/accounts.ts +11 -5
  22. package/src/hooks/browser.ts +11 -0
  23. package/src/hooks/global.ts +170 -7
  24. package/src/hooks/index.ts +1 -2
  25. package/src/hooks/settings.ts +28 -37
  26. package/src/hooks/transactions.ts +28 -155
  27. package/src/hooks/ui.ts +232 -36
  28. package/src/index.ts +33 -24
  29. package/src/reducers/accounts.ts +19 -2
  30. package/src/reducers/browser.ts +223 -0
  31. package/src/reducers/global.ts +67 -1
  32. package/src/reducers/index.ts +1 -0
  33. package/src/reducers/transactions.ts +0 -9
  34. package/src/reducers/ui.ts +127 -8
  35. package/src/types/index.ts +1 -1
  36. package/src/ui-hooks/index.ts +107 -0
  37. package/src/ui-hooks/useActionOverviewSectionLogic.ts +150 -0
  38. package/src/ui-hooks/useAddressTypeScreenLogic.ts +160 -0
  39. package/src/ui-hooks/useAlkanesBalanceCardLogic.ts +41 -0
  40. package/src/ui-hooks/useAlkanesCollectionListLogic.ts +68 -0
  41. package/src/ui-hooks/useAlkanesListLogic.ts +69 -0
  42. package/src/ui-hooks/useAlkanesNFTListLogic.ts +42 -0
  43. package/src/ui-hooks/useAlkanesNFTScreenLogic.ts +45 -0
  44. package/src/ui-hooks/useAlkanesTokenScreenLogic.ts +130 -0
  45. package/src/ui-hooks/useAmountInputLogic.ts +80 -0
  46. package/src/ui-hooks/useAnnouncementCardLogic.ts +91 -0
  47. package/src/ui-hooks/useBRC20BalanceCardLogic.ts +115 -0
  48. package/src/ui-hooks/useBRC20InscribeTransferLogic.ts +398 -0
  49. package/src/ui-hooks/useBRC20ListLogic.ts +75 -0
  50. package/src/ui-hooks/useBRC20ProgListLogic.ts +77 -0
  51. package/src/ui-hooks/useBRC20SendScreenLogic.ts +411 -0
  52. package/src/ui-hooks/useBRC20SingleStepScreenLogic.ts +208 -0
  53. package/src/ui-hooks/useBRC20TokenScreenLogic.ts +469 -0
  54. package/src/ui-hooks/useBalanceCardLogic.ts +164 -0
  55. package/src/ui-hooks/useBtcDisplayLogic.ts +16 -0
  56. package/src/ui-hooks/useCAT20BalanceCardLogic.ts +35 -0
  57. package/src/ui-hooks/useCAT20ListLogic.ts +83 -0
  58. package/src/ui-hooks/useCAT20TokenScreenLogic.ts +122 -0
  59. package/src/ui-hooks/useCAT721ListLogic.ts +68 -0
  60. package/src/ui-hooks/useCAT721NFTScreenLogic.ts +37 -0
  61. package/src/ui-hooks/useCreatePasswordScreenLogic.ts +92 -0
  62. package/src/ui-hooks/useCreateWalletLogicImportWordsStep.ts +299 -0
  63. package/src/ui-hooks/useEditAccountNameScreenLogic.ts +71 -0
  64. package/src/ui-hooks/useEditContactScreenLogic.ts +162 -0
  65. package/src/ui-hooks/useEditWalletNameScreenLogic.ts +58 -0
  66. package/src/ui-hooks/useExportMnemonicsScreenLogic.ts +75 -0
  67. package/src/ui-hooks/useExportPrivateKeyScreenLogic.ts +64 -0
  68. package/src/ui-hooks/useFeeRateBarLogic.ts +303 -0
  69. package/src/ui-hooks/useInfiniteList.ts +85 -0
  70. package/src/ui-hooks/useInscriptionListLogic.ts +68 -0
  71. package/src/ui-hooks/useLockTimePageLogic.ts +43 -0
  72. package/src/ui-hooks/useNotificationsLogic.ts +115 -0
  73. package/src/ui-hooks/useOrdinalsInscriptionScreenLogic.ts +130 -0
  74. package/src/ui-hooks/useRunesBalanceCardLogic.ts +44 -0
  75. package/src/ui-hooks/useRunesListLogic.ts +74 -0
  76. package/src/ui-hooks/useRunesTokenScreenLogic.ts +149 -0
  77. package/src/ui-hooks/useSecurityCardLogic.ts +0 -0
  78. package/src/ui-hooks/useSendAlkanesNFTScreenLogic.ts +138 -0
  79. package/src/ui-hooks/useSendAlkanesScreenLogic.ts +192 -0
  80. package/src/ui-hooks/useSendCAT20ScreenLogic.ts +297 -0
  81. package/src/ui-hooks/useSendCAT721ScreenLogic.ts +205 -0
  82. package/src/ui-hooks/useSendOrdinalsInscriptionScreenLogic.ts +137 -0
  83. package/src/ui-hooks/useSendRunesScreenLogic.ts +172 -0
  84. package/src/ui-hooks/useSettingsTabScreenLogic.ts +211 -0
  85. package/src/ui-hooks/useSignMessageLogic.ts +302 -0
  86. package/src/ui-hooks/useSignPsbtLogic.ts +517 -0
  87. package/src/ui-hooks/useSplitOrdinalsInscriptionScreenLogic.ts +95 -0
  88. package/src/ui-hooks/useTxConfirmScreenLogic.ts +47 -0
  89. package/src/ui-hooks/useTxCreateScreenLogic.ts +161 -0
  90. package/src/ui-hooks/useTxFailScreenLogic.ts +26 -0
  91. package/src/ui-hooks/useTxSuccessScreenLogic.ts +33 -0
  92. package/src/updater/accounts.ts +11 -11
  93. package/src/utils/bitcoin-utils.ts +17 -8
  94. package/src/utils/eventBus.ts +2 -1
  95. package/src/utils/password-utils.ts +78 -0
  96. package/src/utils/ui-utils.ts +28 -0
  97. package/src/hooks/approval.ts +0 -72
  98. package/src/hooks/i18n.ts +0 -53
  99. package/src/utils/i18n.ts +0 -41
@@ -0,0 +1,469 @@
1
+ import { AddressTokenSummary, BRC20HistoryItem, Inscription } from '@unisat/wallet-shared'
2
+ import { ChainType } from '@unisat/wallet-types'
3
+ import { useEffect, useMemo, useState } from 'react'
4
+ import {
5
+ useBRC20IconInfo,
6
+ useChain,
7
+ useChainType,
8
+ useCurrentAccount,
9
+ useI18n,
10
+ useNavigation,
11
+ useResetTxState,
12
+ useTools,
13
+ useWallet,
14
+ } from '..'
15
+ import { shortAddress } from '../utils/ui-utils'
16
+
17
+ import BigNumber from 'bignumber.js'
18
+ const SWAP_MODULE_ADDRESS = '6a2095ee19329a210f8d5ded9b5cfa55b74fdd3b1e9af1e202072db6d1be82d45bfd'
19
+ const BRIDGE_BURN_ADDRESS = '6a20ada13e56859a2ab2eeb93cb4dc19c6e3f5e94d0ed38ed95a30ddc43711a0ff14'
20
+ const BRC20PROG_MODULE_ADDRESS = '6a09425243323050524f47'
21
+ export enum BRC20TokenScreenTabKey {
22
+ DETAILS = 'details',
23
+ HISTORY = 'history',
24
+ }
25
+
26
+ export interface BRC20OutWalletBalanceItem {
27
+ key: 'wallet' | 'swap' | 'prog'
28
+ label: string
29
+ amount: string
30
+ }
31
+
32
+ export function useBRC20TokenHistoryLogic(props: { ticker: string; displayName?: string }) {
33
+ const wallet = useWallet()
34
+ const { t } = useI18n()
35
+
36
+ const account = useCurrentAccount()
37
+
38
+ const nav = useNavigation()
39
+ const { ticker, displayName } = props
40
+
41
+ const [items, setItems] = useState<BRC20HistoryItem[]>([])
42
+
43
+ const [loading, setLoading] = useState(true)
44
+
45
+ const [failed, setFailed] = useState(false)
46
+
47
+ useEffect(() => {
48
+ wallet
49
+ .getBRC20RecentHistory(account.address, ticker)
50
+ .then(setItems)
51
+ .catch(() => setFailed(true))
52
+ .finally(() => setLoading(false))
53
+ }, [account.address, ticker])
54
+
55
+ const groupedItems = useMemo(() => {
56
+ const groups: { [date: string]: BRC20HistoryItem[] } = {}
57
+ items.forEach(item => {
58
+ let time = item.blocktime
59
+ if (item.blocktime == 0) {
60
+ time = Date.now() / 1000
61
+ }
62
+ const date = new Date(time * 1000).toLocaleDateString()
63
+ if (!groups[date]) {
64
+ groups[date] = []
65
+ }
66
+ groups[date].push(item)
67
+ })
68
+ return Object.entries(groups).map(([date, items]) => ({ date, items }))
69
+ }, [items])
70
+
71
+ const displayItems = useMemo(() => {
72
+ return groupedItems
73
+ .map(({ date, items }) => ({
74
+ date,
75
+ items: items
76
+ .map(item => {
77
+ const key = item.txid + item.type
78
+
79
+ let mainTitle = item.type
80
+ let subTitle = ''
81
+ let icon = ''
82
+ let isPending = false
83
+ if (item.blocktime == 0) {
84
+ isPending = true
85
+ }
86
+
87
+ if (item.type === 'send') {
88
+ mainTitle = t('brc20_history_type_send')
89
+ subTitle = t('brc20_history_to') + ' ' + shortAddress(item.to)
90
+ icon = 'history_send'
91
+ if (item.to === SWAP_MODULE_ADDRESS) {
92
+ mainTitle = t('brc20_history_type_wrap')
93
+ subTitle = t('brc20_history_to') + ' ' + 'InSwap'
94
+ icon = 'history_wrap'
95
+ } else if (item.to === BRC20PROG_MODULE_ADDRESS) {
96
+ mainTitle = t('brc20_history_type_wrap')
97
+ subTitle = t('brc20_history_to') + ' ' + 'brc2.0'
98
+ icon = 'history_wrap'
99
+ }
100
+ } else if (item.type === 'single-step-transfer') {
101
+ if (item.from === account.address) {
102
+ mainTitle = t('brc20_history_type_send')
103
+ subTitle = t('brc20_history_to') + ' ' + shortAddress(item.to)
104
+ icon = 'history_send'
105
+ } else {
106
+ mainTitle = t('brc20_history_type_receive')
107
+ subTitle = t('brc20_history_from') + ' ' + shortAddress(item.from)
108
+ icon = 'history_receive'
109
+ }
110
+ } else if (item.type === 'receive') {
111
+ mainTitle = t('brc20_history_type_receive')
112
+ subTitle = t('brc20_history_from') + ' ' + shortAddress(item.from)
113
+ icon = 'history_receive'
114
+ } else if (item.type === 'withdraw') {
115
+ mainTitle = t('brc20_history_type_unwrap')
116
+ subTitle = t('brc20_history_from') + ' ' + 'InSwap'
117
+ icon = 'history_unwrap'
118
+ } else if (item.type === 'inscribe-transfer') {
119
+ mainTitle = t('brc20_history_type_inscribe_transfer')
120
+ icon = 'history_inscribe'
121
+ } else if (item.type === 'inscribe-mint') {
122
+ mainTitle = t('brc20_history_type_inscribe_mint')
123
+ icon = 'history_inscribe'
124
+ } else if (item.type === 'inscribe-deploy') {
125
+ mainTitle = t('brc20_history_type_inscribe_deploy')
126
+ icon = 'history_inscribe'
127
+ } else if (item.type === 'brc20prog-withdraw-transfer') {
128
+ mainTitle = t('brc20_history_type_unwrap')
129
+ subTitle = t('brc20_history_from') + ' ' + 'brc2.0'
130
+ icon = 'history_unwrap'
131
+ } else if (item.type === 'brc20prog-withdraw-inscribe') {
132
+ mainTitle = t('brc20_history_type_inscribe_transfer')
133
+ subTitle = t('brc20_history_type_unwrap') + ' brc2.0'
134
+ icon = 'history_inscribe'
135
+ } else {
136
+ const isSendLike = item.from === account.address
137
+ mainTitle = isSendLike
138
+ ? t('brc20_history_type_send')
139
+ : t('brc20_history_type_receive')
140
+ subTitle = isSendLike
141
+ ? t('brc20_history_to') + ' ' + shortAddress(item.to)
142
+ : t('brc20_history_from') + ' ' + shortAddress(item.from)
143
+ icon = isSendLike ? 'history_send' : 'history_receive'
144
+ }
145
+
146
+ const amount = item.amount
147
+
148
+ return {
149
+ key,
150
+ icon,
151
+ mainTitle,
152
+ subTitle,
153
+ amount,
154
+ pending: isPending,
155
+ txid: item.txid,
156
+ }
157
+ })
158
+ .filter(v => v !== null),
159
+ }))
160
+ .filter(group => group.items.length > 0)
161
+ }, [account.address, t, groupedItems])
162
+
163
+ return {
164
+ displayItems,
165
+ isFailed: failed,
166
+ isEmpty: displayItems.length === 0,
167
+ isLoading: loading,
168
+ }
169
+ }
170
+
171
+ export function useBRC20TokenScreenLogic() {
172
+ const nav = useNavigation()
173
+ const { ticker } = nav.getRouteState<'BRC20TokenScreen'>()
174
+ const { t } = useI18n()
175
+
176
+ const [activeTab, setActiveTab] = useState<BRC20TokenScreenTabKey>(BRC20TokenScreenTabKey.HISTORY)
177
+
178
+ const [tokenSummary, setTokenSummary] = useState<AddressTokenSummary>({
179
+ tokenBalance: {
180
+ ticker,
181
+ overallBalance: '',
182
+ availableBalance: '',
183
+ transferableBalance: '',
184
+ availableBalanceSafe: '',
185
+ availableBalanceUnSafe: '',
186
+ selfMint: false,
187
+ },
188
+ tokenInfo: {
189
+ totalSupply: '',
190
+ totalMinted: '',
191
+ decimal: 18,
192
+ holder: '',
193
+ inscriptionId: '',
194
+ holdersCount: 0,
195
+ historyCount: 0,
196
+ logo: 'https://static.unisat.io/icon/brc20/unknown',
197
+ },
198
+ historyList: [],
199
+ transferableList: [],
200
+ })
201
+
202
+ const wallet = useWallet()
203
+
204
+ const account = useCurrentAccount()
205
+
206
+ const [loading, setLoading] = useState(true)
207
+
208
+ const [deployInscription, setDeployInscription] = useState<Inscription>()
209
+
210
+ const resetTxState = useResetTxState()
211
+ useEffect(() => {
212
+ wallet
213
+ .getBRC20Summary(account.address, ticker)
214
+ .then(tokenSummary => {
215
+ if (tokenSummary.tokenInfo.holder == account.address) {
216
+ wallet
217
+ .getInscriptionInfo(tokenSummary.tokenInfo.inscriptionId)
218
+ .then(data => {
219
+ setDeployInscription(data)
220
+ })
221
+ .finally(() => {
222
+ setTokenSummary(tokenSummary)
223
+ setLoading(false)
224
+ })
225
+ } else {
226
+ setTokenSummary(tokenSummary)
227
+ setLoading(false)
228
+ }
229
+ })
230
+ .finally(() => {
231
+ setLoading(false)
232
+ })
233
+ }, [])
234
+
235
+ const enableMint = useMemo(() => {
236
+ let enable = false
237
+ if (tokenSummary.tokenBalance.selfMint) {
238
+ if (tokenSummary.tokenInfo.holder == account.address) {
239
+ if (tokenSummary.tokenInfo.totalMinted != tokenSummary.tokenInfo.totalSupply) {
240
+ enable = true
241
+ }
242
+ }
243
+ } else {
244
+ if (tokenSummary.tokenInfo.totalMinted != tokenSummary.tokenInfo.totalSupply) {
245
+ enable = true
246
+ }
247
+ }
248
+ return enable
249
+ }, [tokenSummary])
250
+
251
+ const enableTransfer = useMemo(() => {
252
+ let enable = false
253
+ if (
254
+ tokenSummary.tokenBalance.overallBalance !== '0' &&
255
+ tokenSummary.tokenBalance.overallBalance !== ''
256
+ ) {
257
+ enable = true
258
+ }
259
+ return enable
260
+ }, [tokenSummary])
261
+
262
+ const tools = useTools()
263
+ const chainType = useChainType()
264
+ const chain = useChain()
265
+
266
+ const isBrc20Prog = useMemo(() => {
267
+ if (chainType === ChainType.BITCOIN_MAINNET || chainType === ChainType.BITCOIN_SIGNET) {
268
+ if (ticker.length == 6) {
269
+ return true
270
+ }
271
+ }
272
+ return false
273
+ }, [ticker, chainType])
274
+
275
+ const enableTrade = useMemo(() => {
276
+ if (
277
+ chainType === ChainType.BITCOIN_MAINNET ||
278
+ chainType === ChainType.FRACTAL_BITCOIN_MAINNET
279
+ ) {
280
+ return true
281
+ } else {
282
+ return false
283
+ }
284
+ }, [chainType])
285
+
286
+ const enableHistory = true
287
+
288
+ const tabItems = useMemo(() => {
289
+ if (enableHistory) {
290
+ const items = [
291
+ {
292
+ key: BRC20TokenScreenTabKey.HISTORY,
293
+ label: t('history'),
294
+ },
295
+ {
296
+ key: BRC20TokenScreenTabKey.DETAILS,
297
+ label: t('details'),
298
+ },
299
+ ]
300
+ return items
301
+ } else {
302
+ return [
303
+ {
304
+ key: BRC20TokenScreenTabKey.DETAILS,
305
+ label: t('details'),
306
+ },
307
+ ]
308
+ }
309
+ }, [t, enableHistory])
310
+
311
+ const onSwapBalance = tokenSummary?.tokenBalance?.swapBalance
312
+ const onProgBalance = tokenSummary?.tokenBalance?.progBalance
313
+ const inWalletBalance = tokenSummary?.tokenBalance?.overallBalance
314
+ const outWalletBalanceItems = useMemo<BRC20OutWalletBalanceItem[]>(() => {
315
+ const items: BRC20OutWalletBalanceItem[] = [
316
+ {
317
+ key: 'wallet',
318
+ label: t('brc20_in_wallet'),
319
+ amount: inWalletBalance || '0',
320
+ },
321
+ ]
322
+
323
+ if (onSwapBalance && onSwapBalance !== '0') {
324
+ items.push({
325
+ key: 'swap',
326
+ label: t('brc20_on_swap'),
327
+ amount: onSwapBalance,
328
+ })
329
+ }
330
+
331
+ if (onProgBalance && onProgBalance !== '0') {
332
+ items.push({
333
+ key: 'prog',
334
+ label: t('brc20_on_prog'),
335
+ amount: onProgBalance,
336
+ })
337
+ }
338
+
339
+ return items
340
+ }, [inWalletBalance, onProgBalance, onSwapBalance, t])
341
+ const totalBalance = useMemo(() => {
342
+ if (!inWalletBalance) {
343
+ return '--'
344
+ }
345
+ return new BigNumber(inWalletBalance)
346
+ .plus(new BigNumber(onSwapBalance || 0))
347
+ .plus(new BigNumber(onProgBalance || 0))
348
+ .toString()
349
+ }, [onSwapBalance, onProgBalance, inWalletBalance])
350
+
351
+ let hasOutWalletBalance = false
352
+ if (onSwapBalance && onSwapBalance !== '0') {
353
+ hasOutWalletBalance = true
354
+ }
355
+ if (onProgBalance && onProgBalance !== '0') {
356
+ hasOutWalletBalance = true
357
+ }
358
+
359
+ const onClickWrapBrc20Prog = () => {
360
+ const url = `https://link.unisat.space/btc/wrap?tick=${encodeURIComponent(ticker)}`
361
+ nav.navToUrl(url)
362
+ }
363
+
364
+ const onClickUnwrapBrc20Prog = () => {
365
+ const url = `https://link.unisat.space/btc/wrap?action=unwrap&tick=${encodeURIComponent(ticker)}`
366
+ nav.navToUrl(url)
367
+ }
368
+
369
+ const onClickSendBrc20Prog = () => {
370
+ const url = `https://bestinslot.xyz/brc2.0/${encodeURIComponent(ticker)}/transfer`
371
+ nav.navToUrl(url)
372
+ }
373
+
374
+ const onClickSwapInSwap = () => {
375
+ const url = `https://inswap.cc/swap?t0=${encodeURIComponent(ticker)}`
376
+ nav.navToUrl(url)
377
+ }
378
+
379
+ const onClickAddLiquidityInSwap = () => {
380
+ const url = `https://inswap.cc/swap/pools?t0=${encodeURIComponent(ticker)}&t1=sFB___000&action=add`
381
+ nav.navToUrl(url)
382
+ }
383
+
384
+ const onClickRemoveLiquidityInSwap = () => {
385
+ const url = `https://inswap.cc/swap/pools?t0=${encodeURIComponent(ticker)}&t1=sFB___000&action=remove`
386
+ nav.navToUrl(url)
387
+ }
388
+
389
+ const onClickWrapInSwap = () => {
390
+ const url = `https://inswap.cc/swap?tab=deposit&t=${encodeURIComponent(ticker)}`
391
+ nav.navToUrl(url)
392
+ }
393
+
394
+ const onClickUnwrapInSwap = () => {
395
+ const url = `https://inswap.cc/swap?tab=withdraw&t=${encodeURIComponent(ticker)}`
396
+ nav.navToUrl(url)
397
+ }
398
+
399
+ const onClickSendInSwap = () => {
400
+ const url = `https://inswap.cc/swap/assets/account`
401
+ nav.navToUrl(url)
402
+ }
403
+
404
+ const onClickMint = () => {
405
+ nav.navToInscribeBrc20(ticker)
406
+ }
407
+
408
+ const onClickSend = () => {
409
+ resetTxState()
410
+ nav.navigate('BRC20SendScreen', {
411
+ tokenBalance: tokenSummary.tokenBalance,
412
+ tokenInfo: tokenSummary.tokenInfo,
413
+ })
414
+ }
415
+
416
+ const onClickTrade = () => {
417
+ nav.navToMarketPlaceBrc20(ticker)
418
+ }
419
+
420
+ const onClickSingleStepSend = () => {
421
+ resetTxState()
422
+ nav.navigate('BRC20SingleStepScreen', {
423
+ tokenBalance: tokenSummary.tokenBalance,
424
+ tokenInfo: tokenSummary.tokenInfo,
425
+ })
426
+ }
427
+
428
+ const iconInfo = useBRC20IconInfo(ticker)
429
+
430
+ return {
431
+ totalBalance,
432
+ onSwapBalance,
433
+ onProgBalance,
434
+ inWalletBalance,
435
+ outWalletBalanceItems,
436
+ hasOutWalletBalance,
437
+ enableHistory,
438
+ enableTrade,
439
+ enableMint,
440
+ enableTransfer,
441
+ loading,
442
+ tokenSummary,
443
+ deployInscription,
444
+ activeTab,
445
+ setActiveTab,
446
+ tabItems,
447
+ t,
448
+ ticker,
449
+ chain,
450
+ tools,
451
+ isBrc20Prog,
452
+ iconInfo,
453
+ onClickWrapBrc20Prog,
454
+ onClickUnwrapBrc20Prog,
455
+ onClickSendBrc20Prog,
456
+
457
+ onClickSwapInSwap,
458
+ onClickAddLiquidityInSwap,
459
+ onClickRemoveLiquidityInSwap,
460
+ onClickWrapInSwap,
461
+ onClickUnwrapInSwap,
462
+ onClickSendInSwap,
463
+
464
+ onClickMint,
465
+ onClickSend,
466
+ onClickTrade,
467
+ onClickSingleStepSend,
468
+ }
469
+ }
@@ -0,0 +1,164 @@
1
+ import { numUtils } from '@unisat/base-utils'
2
+ import { ChainType } from '@unisat/wallet-types'
3
+ import { useCallback, useEffect, useMemo, useRef } from 'react'
4
+ import { useDispatch, useSelector } from 'react-redux'
5
+ import { accountActions, AppState, uiActions } from 'src'
6
+ import { useI18n, useNavigation } from '../context'
7
+ import {
8
+ useAccountBalance,
9
+ useBalanceCardDetailExpanded,
10
+ useBTCUnit,
11
+ useChain,
12
+ useFetchBalanceCallback,
13
+ useToggleBalanceCardDetailExpanded,
14
+ useWalletConfig,
15
+ } from '../hooks'
16
+
17
+ const DEBOUNCE_DELAY = 1000
18
+
19
+ export function useBalanceCardLogic() {
20
+ const { t } = useI18n()
21
+
22
+ const walletConfig = useWalletConfig()
23
+
24
+ const accountBalance = useAccountBalance()
25
+ const chain = useChain()
26
+ const dispatch = useDispatch()
27
+
28
+ const fetchBalance = useFetchBalanceCallback()
29
+
30
+ const btcUnit = useBTCUnit()
31
+ const nav = useNavigation()
32
+
33
+ const isBtcMainnet = chain.enum === ChainType.BITCOIN_MAINNET
34
+
35
+ const debounceTimerRef = useRef<NodeJS.Timeout | null>(null)
36
+
37
+ // Detail expand state
38
+ const isDetailExpanded = useBalanceCardDetailExpanded()
39
+ const toggleBalanceCardDetailExpanded = useToggleBalanceCardDetailExpanded()
40
+ const handleExpandToggle = () => {
41
+ toggleBalanceCardDetailExpanded()
42
+ }
43
+
44
+ // Balance visibility
45
+ const isBalanceHidden = useSelector((state: AppState) => state.ui.isBalanceHidden)
46
+ const handleHiddenToggle = (e?: React.MouseEvent) => {
47
+ if (e) e.stopPropagation()
48
+ dispatch(uiActions['setBalanceHidden'](!isBalanceHidden))
49
+ }
50
+
51
+ const isCurrentChainBalance = chain.enum == accountBalance.chainType
52
+ const balanceValue = useMemo(() => {
53
+ if (!isCurrentChainBalance) {
54
+ return '--'
55
+ }
56
+ return numUtils.satoshisToAmount(accountBalance.totalBalance)
57
+ }, [accountBalance.totalBalance, isCurrentChainBalance])
58
+
59
+ const unavailableTipText = useMemo(() => {
60
+ let tipText = ''
61
+ tipText += t('unavailable_tooltip')
62
+
63
+ if (walletConfig.disableUtxoTools) {
64
+ tipText += t('future_versions_will_support_spending_these_assets')
65
+ } else {
66
+ tipText += t('you_can_unlock_these_assets_by_using_the_utxos_tools')
67
+ }
68
+ return tipText
69
+ }, [t, walletConfig.disableUtxoTools])
70
+
71
+ const showUtxoToolButton = walletConfig.disableUtxoTools
72
+ ? false
73
+ : isCurrentChainBalance && accountBalance.unavailableBalance > 0
74
+
75
+ const totalBalance = accountBalance.totalBalance
76
+ const availableBalance = accountBalance.availableBalance
77
+ const unavailableBalance = accountBalance.unavailableBalance
78
+
79
+ const totalAmount = numUtils.satoshisToAmount(accountBalance.totalBalance)
80
+ const availableAmount = numUtils.satoshisToAmount(accountBalance.availableBalance)
81
+ const unavailableAmount = numUtils.satoshisToAmount(accountBalance.unavailableBalance)
82
+
83
+ const totalAmountMainPart = isBtcMainnet ? totalAmount.slice(0, -4) : totalAmount.slice(0, -8)
84
+ const totalAmountSubPart = isBtcMainnet ? totalAmount.slice(-4) : totalAmount.slice(-8)
85
+
86
+ // Passive refresh every 10 seconds
87
+ useEffect(() => {
88
+ const intervalId = setInterval(() => {
89
+ dispatch(accountActions['expireBalance'](null))
90
+ fetchBalance()
91
+ }, 10000)
92
+
93
+ return () => clearInterval(intervalId)
94
+ }, [dispatch, fetchBalance])
95
+
96
+ const refreshBalance = useCallback(
97
+ (e?: React.MouseEvent) => {
98
+ if (e) {
99
+ e.stopPropagation()
100
+ }
101
+
102
+ if (debounceTimerRef.current) {
103
+ clearTimeout(debounceTimerRef.current)
104
+ }
105
+
106
+ debounceTimerRef.current = setTimeout(() => {
107
+ dispatch((accountActions as any).expireBalance(null))
108
+ fetchBalance()
109
+ debounceTimerRef.current = null
110
+ }, DEBOUNCE_DELAY)
111
+ },
112
+ [dispatch, fetchBalance]
113
+ )
114
+
115
+ useEffect(() => {
116
+ return () => {
117
+ if (debounceTimerRef.current) {
118
+ clearTimeout(debounceTimerRef.current)
119
+ }
120
+ }
121
+ }, [])
122
+
123
+ const handleUnlock = (e?: React.MouseEvent) => {
124
+ if (e) e.stopPropagation()
125
+ if (walletConfig.disableUtxoTools) return
126
+
127
+ nav.navToUtxoTools()
128
+ }
129
+
130
+ return {
131
+ // state
132
+ totalBalance,
133
+ availableBalance,
134
+ unavailableBalance,
135
+
136
+ totalAmount,
137
+ availableAmount,
138
+ unavailableAmount,
139
+
140
+ totalAmountMainPart,
141
+ totalAmountSubPart,
142
+
143
+ balanceValue,
144
+ unavailableTipText,
145
+ isCurrentChainBalance,
146
+ showUtxoToolButton,
147
+
148
+ // action
149
+ handleUnlock,
150
+
151
+ isDetailExpanded,
152
+ handleExpandToggle,
153
+
154
+ isBalanceHidden,
155
+ handleHiddenToggle,
156
+
157
+ refreshBalance,
158
+ btcUnit,
159
+ isBtcMainnet,
160
+
161
+ chain,
162
+ t,
163
+ }
164
+ }
@@ -0,0 +1,16 @@
1
+ import { ChainType } from '@unisat/wallet-types'
2
+ import { useChainType } from 'src/hooks'
3
+
4
+ export function useBtcDisplayLogic(balance: string) {
5
+ const chainType = useChainType()
6
+
7
+ const totalAmountMainPart =
8
+ chainType === ChainType.BITCOIN_MAINNET ? balance.slice(0, -4) : balance.slice(0, -8)
9
+ const totalAmountSubPart =
10
+ chainType === ChainType.BITCOIN_MAINNET ? balance.slice(-4) : balance.slice(-8)
11
+
12
+ return {
13
+ totalAmountMainPart,
14
+ totalAmountSubPart,
15
+ }
16
+ }
@@ -0,0 +1,35 @@
1
+ import { bnUtils } from '@unisat/base-utils'
2
+ import { CAT20Balance, TickPriceItem } from '@unisat/wallet-shared'
3
+ import { useCAT20IconInfo } from 'src/hooks'
4
+
5
+ export interface CAT20BalanceCardProps {
6
+ tokenBalance: CAT20Balance
7
+ onClick?: () => void
8
+ showPrice?: boolean
9
+ price?: TickPriceItem
10
+ }
11
+
12
+ export function useCAT20BalanceCardLogic(props: CAT20BalanceCardProps) {
13
+ const { tokenBalance, onClick, showPrice, price } = props
14
+ const balance = bnUtils.toDecimalNumber(tokenBalance.amount, tokenBalance.decimals)
15
+ const balanceStr = balance.toString()
16
+
17
+ const iconInfo = useCAT20IconInfo(tokenBalance.name, tokenBalance.tokenId)
18
+
19
+ return {
20
+ // balance
21
+ tokenBalance,
22
+ balance,
23
+ balanceStr,
24
+
25
+ // price
26
+ price,
27
+ showPrice,
28
+
29
+ // icon
30
+ iconInfo,
31
+
32
+ // click
33
+ onClick,
34
+ }
35
+ }