@unisat/wallet-state 1.0.5 → 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,302 @@
1
+ import { KeyringType } from '@unisat/keyring-service/types'
2
+ import { SignedMessage, SignState, ToSignMessage, WebsiteResult } from '@unisat/wallet-shared'
3
+ import logger from 'loglevel'
4
+ import { useEffect, useMemo, useRef, useState } from 'react'
5
+ import { useApproval, useI18n, useTools, useWallet } from 'src/context'
6
+ import { useCurrentAccount } from 'src/hooks'
7
+ import { shortAddress, useAsyncEffect } from 'src/utils/ui-utils'
8
+ export interface SignMessageProps {
9
+ header?: React.ReactNode
10
+ params: {
11
+ data: {
12
+ toSignMessages: ToSignMessage[]
13
+ }
14
+ session?: {
15
+ origin: string
16
+ icon: string
17
+ name: string
18
+ }
19
+ }
20
+ handleCancel?: () => void
21
+ handleConfirm?: (signedMessages: SignedMessage[]) => void
22
+ }
23
+
24
+ export function useSignMessageLogic(props: SignMessageProps) {
25
+ const {
26
+ params: {
27
+ data: { toSignMessages },
28
+ session,
29
+ },
30
+ handleCancel,
31
+ handleConfirm,
32
+ } = props
33
+
34
+ const { resolveApproval, rejectApproval } = useApproval()
35
+
36
+ const [loading, setLoading] = useState(false)
37
+ const [isKeystoneSigning, setIsKeystoneSigning] = useState(false)
38
+ const [isColdWalletSigning, setIsColdWalletSigning] = useState(false)
39
+
40
+ const wallet = useWallet()
41
+ const tools = useTools()
42
+ const currentAccount = useCurrentAccount()
43
+ const keyringType = currentAccount.type
44
+
45
+ const { t } = useI18n()
46
+
47
+ const [disclaimerVisible, setDisclaimerVisible] = useState(false)
48
+
49
+ const [signingTxIndex, setSigningTxIndex] = useState(toSignMessages.length > 1 ? -1 : 0)
50
+ const [signedStates, setSignedStates] = useState<SignState[]>(
51
+ toSignMessages.map(() => SignState.PENDING)
52
+ )
53
+
54
+ const [websiteResult, setWebsiteResult] = useState<WebsiteResult>({
55
+ isScammer: false,
56
+ warning: '',
57
+ allowQuickMultiSign: false,
58
+ })
59
+
60
+ const isMultipleViewMode = toSignMessages.length > 1
61
+ const [allowQuickMultiSign, setAllowQuickMultiSign] = useState(false)
62
+
63
+ useEffect(() => {
64
+ if (toSignMessages.length <= 1) {
65
+ return
66
+ }
67
+
68
+ if (
69
+ keyringType === KeyringType.KeystoneKeyring ||
70
+ keyringType === KeyringType.ColdWalletKeyring
71
+ ) {
72
+ return
73
+ }
74
+
75
+ setAllowQuickMultiSign(websiteResult.allowQuickMultiSign && toSignMessages.length > 1)
76
+ }, [websiteResult, keyringType])
77
+
78
+ useAsyncEffect(async () => {
79
+ const website = session?.origin
80
+ if (website) {
81
+ const result = await wallet.checkWebsite(website)
82
+ setWebsiteResult(result)
83
+
84
+ // Also check local user-granted trust
85
+ if (!result.allowQuickMultiSign && toSignMessages.length > 1) {
86
+ const sites = await wallet.getConnectedSites()
87
+ const site = sites.find(s => s.origin === website)
88
+ if (site?.allowQuickMultiSign) {
89
+ setAllowQuickMultiSign(true)
90
+ }
91
+ }
92
+ }
93
+ }, [])
94
+
95
+ const currentToSignMessage = toSignMessages[signingTxIndex]
96
+
97
+ const signedMessages = useRef<SignedMessage[]>([])
98
+
99
+ const isScammer = websiteResult ? websiteResult.isScammer : false
100
+
101
+ const isAllSigned = signedStates.every(state => state === SignState.SUCCESS)
102
+ const signedCount = signedStates.filter(state => state === SignState.SUCCESS).length
103
+
104
+ const defaultHandleCancel = () => rejectApproval()
105
+ const actualHandleCancel = handleCancel || defaultHandleCancel
106
+
107
+ const multiSignList = useMemo(() => {
108
+ return toSignMessages.map((data, index) => {
109
+ const signState = signedStates[index]
110
+ let buttonText = 'View'
111
+ if (signState == SignState.PENDING) {
112
+ buttonText = t('view')
113
+ } else if (signState == SignState.SUCCESS) {
114
+ buttonText = t('signed')
115
+ } else if (signState == SignState.FAILED) {
116
+ buttonText = t('reject')
117
+ }
118
+
119
+ let buttonPreset = 'primary'
120
+ if (signState === SignState.SUCCESS) {
121
+ buttonPreset = 'approval'
122
+ } else if (signState === SignState.FAILED) {
123
+ buttonPreset = 'danger'
124
+ }
125
+
126
+ let title = shortAddress(data.text, 10)
127
+
128
+ const onClick = () => {
129
+ setSigningTxIndex(index)
130
+ }
131
+ return {
132
+ index,
133
+ title,
134
+ buttonText,
135
+ buttonPreset,
136
+ onClick,
137
+ }
138
+ })
139
+ }, [toSignMessages, signedStates, t])
140
+
141
+ // action
142
+ const onClickBack = () => {
143
+ if (isMultipleViewMode && signingTxIndex != -1) {
144
+ // back to multi sign view
145
+ setSigningTxIndex(-1)
146
+ return
147
+ }
148
+ actualHandleCancel()
149
+ }
150
+
151
+ const onClickSign = () => {
152
+ onNextStep()
153
+ }
154
+
155
+ const onTryMultiSign = async () => {
156
+ setDisclaimerVisible(true)
157
+ }
158
+
159
+ const onTrustSite = async () => {
160
+ const origin = session?.origin
161
+ if (!origin) return
162
+ await wallet.updateConnectSite(origin, { allowQuickMultiSign: true })
163
+ setAllowQuickMultiSign(true)
164
+ }
165
+
166
+ const onQuickMultiSign = async () => {
167
+ for (let i = 0; i < toSignMessages.length; i++) {
168
+ try {
169
+ const toSignMessage = toSignMessages[i]
170
+ const signedData = await wallet.signMessage(toSignMessage)
171
+ onSignedData(signedData, i)
172
+ } catch (e) {
173
+ signedStates[i] = SignState.FAILED
174
+ setSignedStates([...signedStates])
175
+ logger.error(`Quick signing message ${i} failed:`, e)
176
+ }
177
+ }
178
+ }
179
+
180
+ const localSign = async () => {
181
+ try {
182
+ const toSignMessage = toSignMessages[signingTxIndex]
183
+ const signedData = await wallet.signMessage(toSignMessage)
184
+ onSignedData(signedData, signingTxIndex)
185
+ } catch (e) {
186
+ signedStates[signingTxIndex] = SignState.FAILED
187
+ setSignedStates([...signedStates])
188
+ logger.error('Local signing failed:', e)
189
+ }
190
+ }
191
+
192
+ const onNextStep = () => {
193
+ if (keyringType === KeyringType.KeystoneKeyring) {
194
+ setIsKeystoneSigning(true)
195
+ } else if (keyringType === KeyringType.ColdWalletKeyring) {
196
+ setIsColdWalletSigning(true)
197
+ } else {
198
+ localSign()
199
+ }
200
+ }
201
+
202
+ const onSignedData = (data: SignedMessage, signingTxIndex: number) => {
203
+ signedStates[signingTxIndex] = SignState.SUCCESS
204
+ setSignedStates([...signedStates])
205
+
206
+ signedMessages.current[signingTxIndex] = data
207
+
208
+ // check if all signed
209
+
210
+ // single mode
211
+ if (!isMultipleViewMode) {
212
+ if (handleConfirm) {
213
+ handleConfirm(signedMessages.current)
214
+ } else {
215
+ resolveApproval(signedMessages.current)
216
+ }
217
+ return
218
+ }
219
+
220
+ // multiple mode
221
+ const isAllSigned = signedStates.every(state => state === SignState.SUCCESS)
222
+ if (isAllSigned) {
223
+ if (handleConfirm) {
224
+ handleConfirm(signedMessages.current)
225
+ } else {
226
+ resolveApproval(signedMessages.current)
227
+ }
228
+ return
229
+ } else {
230
+ setSigningTxIndex(-1)
231
+ return
232
+ }
233
+ }
234
+
235
+ // keystone
236
+ const onKeystoneSigningSuccess = (data: SignedMessage) => {
237
+ setIsKeystoneSigning(false)
238
+ onSignedData(data, signingTxIndex)
239
+ }
240
+
241
+ const onKeystoneSigningBack = () => {
242
+ setIsKeystoneSigning(false)
243
+ }
244
+
245
+ // coldwallet
246
+ const onColdWalletSigningSuccess = (data: SignedMessage) => {
247
+ setIsColdWalletSigning(false)
248
+ onSignedData(data, signingTxIndex)
249
+ }
250
+
251
+ const onColdWalletSigningBack = () => {
252
+ setIsColdWalletSigning(false)
253
+ }
254
+
255
+ // disclaimer modal
256
+ const onDisclaimerModalClose = () => {
257
+ setDisclaimerVisible(false)
258
+ }
259
+
260
+ const showMultiSignView = isMultipleViewMode && signingTxIndex == -1
261
+
262
+ return {
263
+ loading,
264
+ t,
265
+ session,
266
+
267
+ // page state
268
+ isKeystoneSigning,
269
+ isColdWalletSigning,
270
+ showMultiSignView,
271
+
272
+ disclaimerVisible,
273
+
274
+ // data
275
+ toSignMessages,
276
+ currentToSignMessage,
277
+
278
+ // state
279
+ isScammer,
280
+ allowQuickMultiSign,
281
+
282
+ // multiple sign state
283
+ isAllSigned,
284
+ signedCount,
285
+ multiSignList,
286
+
287
+ // actions
288
+ onClickBack,
289
+ onClickSign,
290
+ onQuickMultiSign,
291
+ onTryMultiSign,
292
+ onTrustSite,
293
+
294
+ onKeystoneSigningSuccess,
295
+ onKeystoneSigningBack,
296
+
297
+ onColdWalletSigningSuccess,
298
+ onColdWalletSigningBack,
299
+
300
+ onDisclaimerModalClose,
301
+ }
302
+ }