@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,71 @@
1
+ import { Account } from '@unisat/wallet-shared'
2
+ import { useMemo, useState } from 'react'
3
+ import { useLocation } from 'react-router-dom'
4
+ import { useI18n, useNavigation, useWallet } from 'src/context'
5
+ import { useAppDispatch } from 'src/hooks'
6
+ import { accountActions, keyringsActions } from 'src/reducers'
7
+
8
+ export function useEditAccountNameScreenLogic() {
9
+ const nav = useNavigation()
10
+ const { t } = useI18n()
11
+
12
+ const { state } = useLocation()
13
+ const { account } = state as {
14
+ account: Account
15
+ }
16
+
17
+ const wallet = useWallet()
18
+ const [alianName, setAlianName] = useState(account.alianName || '')
19
+ const dispatch = useAppDispatch()
20
+ const handleOnClick = async () => {
21
+ const newAccount = await wallet.setAccountAlianName(account, alianName)
22
+ // @ts-ignore SAFE
23
+ dispatch(keyringsActions.updateAccountName(newAccount))
24
+ // @ts-ignore SAFE
25
+ dispatch(accountActions.updateAccountName(newAccount))
26
+ nav.goBack()
27
+ }
28
+
29
+ const handleOnKeyUp = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
30
+ if ('Enter' == e.key && e.ctrlKey) {
31
+ handleOnClick()
32
+ }
33
+ }
34
+
35
+ const isValidName = useMemo(() => {
36
+ if (alianName.length == 0) {
37
+ return false
38
+ }
39
+ return true
40
+ }, [alianName])
41
+
42
+ const truncatedTitle = useMemo(() => {
43
+ const name = account.alianName || ''
44
+ if (name.length > 20) {
45
+ return name.slice(0, 10) + '...'
46
+ }
47
+ return name
48
+ }, [account.alianName])
49
+
50
+ const onInputChange = (e: { target: { value: string } } | string) => {
51
+ const value = typeof e === 'string' ? e : e.target.value
52
+ if (value.length <= 20) {
53
+ setAlianName(value)
54
+ }
55
+ }
56
+
57
+ const onClickBack = () => {
58
+ nav.goBack()
59
+ }
60
+ return {
61
+ alianName,
62
+ handleOnClick,
63
+ handleOnKeyUp,
64
+ isValidName,
65
+ truncatedTitle,
66
+ t,
67
+ account,
68
+ onInputChange,
69
+ onClickBack,
70
+ }
71
+ }
@@ -0,0 +1,162 @@
1
+ import { CHAINS_MAP } from '@unisat/wallet-shared'
2
+ import { ChainType } from '@unisat/wallet-types'
3
+ import { useEffect, useState } from 'react'
4
+ import { useI18n, useNavigation, useWallet } from 'src/context'
5
+ import { isValidAddress } from 'src/utils/bitcoin-utils'
6
+
7
+ export function useEditContactScreenLogic() {
8
+ const nav = useNavigation()
9
+
10
+ // Required parameters
11
+ const { address, chain, selectedNetworkFilter } = nav.getRouteState<'EditContactScreen'>()
12
+ const wallet = useWallet()
13
+ const [name, setName] = useState('')
14
+ const [contactAddress, setContactAddress] = useState(address || '')
15
+ const [originalAddress, setOriginalAddress] = useState('')
16
+ const [originalChain, setOriginalChain] = useState<ChainType | undefined>()
17
+ const [chainType, setChainType] = useState<ChainType>(ChainType.BITCOIN_MAINNET)
18
+ const [error, setError] = useState('')
19
+ const [loading, setLoading] = useState(false)
20
+ const { t } = useI18n()
21
+
22
+ useEffect(() => {
23
+ if (address) {
24
+ fetchContact()
25
+ } else {
26
+ const preselectedChainType = selectedNetworkFilter as ChainType
27
+
28
+ if (preselectedChainType) {
29
+ setChainType(preselectedChainType)
30
+ }
31
+ }
32
+ }, [address, chain, selectedNetworkFilter])
33
+
34
+ const fetchContact = async () => {
35
+ if (!address || !chain) return
36
+
37
+ try {
38
+ const chainEnum = chain as ChainType
39
+ const contact = await wallet.getContactByAddressAndChain(address, chainEnum)
40
+
41
+ if (contact) {
42
+ setName(contact.name)
43
+ setContactAddress(contact.address)
44
+ setOriginalAddress(contact.address)
45
+ setOriginalChain(contact.chain)
46
+ setChainType(contact.chain)
47
+ } else {
48
+ setError(t('contact_not_found'))
49
+ setTimeout(() => {
50
+ nav.navigate('ContactsScreen', {})
51
+ }, 1500)
52
+ }
53
+ } catch (err) {
54
+ console.error('Error fetching contact:', err)
55
+ setError(t('failed_to_load_contact_information'))
56
+ }
57
+ }
58
+
59
+ const handleSubmit = async () => {
60
+ if (!name.trim()) {
61
+ setError(t('please_enter_name'))
62
+ return
63
+ }
64
+
65
+ if (!contactAddress.trim()) {
66
+ setError(t('please_enter_address'))
67
+ return
68
+ }
69
+
70
+ const networkType = CHAINS_MAP[chainType].networkType
71
+
72
+ if (!isValidAddress(contactAddress, networkType)) {
73
+ setError(t('invalid_address_format_for_selected_network'))
74
+ return
75
+ }
76
+
77
+ setError('')
78
+ setLoading(true)
79
+
80
+ try {
81
+ if (
82
+ originalAddress &&
83
+ originalChain &&
84
+ (originalAddress !== contactAddress.trim() || originalChain !== chainType)
85
+ ) {
86
+ await wallet.removeContact(originalAddress, originalChain)
87
+ }
88
+
89
+ await wallet.updateContact({
90
+ name: name.trim(),
91
+ address: contactAddress.trim(),
92
+ chain: chainType,
93
+ isContact: true,
94
+ isAlias: false,
95
+ })
96
+
97
+ nav.goBack()
98
+ } catch (err) {
99
+ setError(t('failed_to_save_contact'))
100
+ } finally {
101
+ setLoading(false)
102
+ }
103
+ }
104
+
105
+ const handleDelete = async () => {
106
+ if (!address || !originalChain) return
107
+
108
+ setLoading(true)
109
+ try {
110
+ await wallet.removeContact(address, originalChain)
111
+
112
+ nav.navigate('ContactsScreen', {
113
+ returnWithNetwork: chainType,
114
+ })
115
+ } catch (err) {
116
+ setError(t('failed_to_delete_contact'))
117
+ } finally {
118
+ setLoading(false)
119
+ }
120
+ }
121
+
122
+ const handleAddressChange = (e: { target: { value: string } } | string) => {
123
+ const value = (typeof e === 'string' ? e : e.target.value).trim()
124
+ setContactAddress(value)
125
+
126
+ if (error.includes('Invalid address') || !value) {
127
+ setError('')
128
+ }
129
+
130
+ if (value) {
131
+ const networkType = CHAINS_MAP[chainType].networkType
132
+
133
+ if (value.length > 15 && !isValidAddress(value, networkType)) {
134
+ setError(t('invalid_address_format_for_selected_network'))
135
+ }
136
+ }
137
+ }
138
+
139
+ const handleNameChange = (e: { target: { value: string } } | string) => {
140
+ const value = typeof e === 'string' ? e : e.target.value
141
+ setName(value)
142
+ }
143
+
144
+ const onClickBack = () => {
145
+ nav.goBack()
146
+ }
147
+
148
+ return {
149
+ name,
150
+ contactAddress,
151
+ chainType,
152
+ error,
153
+ loading,
154
+ handleNameChange,
155
+ handleAddressChange,
156
+ handleSubmit,
157
+ handleDelete,
158
+ onClickBack,
159
+ address,
160
+ t,
161
+ }
162
+ }
@@ -0,0 +1,58 @@
1
+ import { useMemo, useState } from 'react'
2
+
3
+ import { keyringsActions, useAppDispatch, useI18n, useNavigation, useWallet } from '..'
4
+ export function useEditWalletNameScreenLogic() {
5
+ const nav = useNavigation()
6
+ const { keyring } = nav.getRouteState<'EditWalletNameScreen'>()
7
+ const { t } = useI18n()
8
+ const wallet = useWallet()
9
+ const [alianName, setAlianName] = useState(keyring.alianName || '')
10
+ const dispatch = useAppDispatch()
11
+ const handleOnClick = async () => {
12
+ try {
13
+ const newKeyring = await wallet.setKeyringAlianName(keyring, alianName || keyring.alianName)
14
+ //@ts-ignore SAFE
15
+ dispatch(keyringsActions.updateKeyringName(newKeyring))
16
+ nav.goBack()
17
+ } catch (e) {
18
+ console.log(e)
19
+ }
20
+ }
21
+
22
+ const handleOnKeyUp = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
23
+ if ('Enter' == e.key && e.ctrlKey) {
24
+ handleOnClick()
25
+ }
26
+ }
27
+
28
+ const isValidName = useMemo(() => {
29
+ if (alianName.length == 0) {
30
+ return false
31
+ }
32
+ return true
33
+ }, [alianName])
34
+
35
+ const truncatedTitle = useMemo(() => {
36
+ if (keyring.alianName && keyring.alianName.length > 20) {
37
+ return keyring.alianName.slice(0, 20) + '...'
38
+ }
39
+ return keyring.alianName || ''
40
+ }, [keyring.alianName])
41
+
42
+ const onInputChange = (e: { target: { value: string } } | string) => {
43
+ const value = typeof e === 'string' ? e : e.target.value
44
+ if (value.length <= 20) {
45
+ setAlianName(value)
46
+ }
47
+ }
48
+
49
+ return {
50
+ t,
51
+ keyring,
52
+ isValidName,
53
+ truncatedTitle,
54
+ handleOnClick,
55
+ handleOnKeyUp,
56
+ onInputChange,
57
+ }
58
+ }
@@ -0,0 +1,75 @@
1
+ import { ADDRESS_TYPES } from '@unisat/wallet-shared'
2
+ import { useEffect, useState } from 'react'
3
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
4
+ type Status = '' | 'error' | 'warning' | undefined
5
+
6
+ export function useExportMnemonicsScreenLogic() {
7
+ const nav = useNavigation()
8
+ const { keyring } = nav.getRouteState<'ExportMnemonicsScreen'>()
9
+
10
+ const { t } = useI18n()
11
+
12
+ const [password, setPassword] = useState('')
13
+ const [disabled, setDisabled] = useState(true)
14
+
15
+ const [mnemonic, setMnemonic] = useState('')
16
+ const [status, setStatus] = useState<Status>('')
17
+ const [error, setError] = useState('')
18
+ const wallet = useWallet()
19
+ const tools = useTools()
20
+
21
+ const [passphrase, setPassphrase] = useState('')
22
+
23
+ const btnClick = async () => {
24
+ try {
25
+ const { mnemonic, hdPath, passphrase } = await wallet.getMnemonics(password, keyring)
26
+ setMnemonic(mnemonic)
27
+ setPassphrase(passphrase)
28
+ } catch (e) {
29
+ setStatus('error')
30
+ setError((e as any).message)
31
+ }
32
+ }
33
+
34
+ const handleOnKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
35
+ if ('Enter' == e.key) {
36
+ btnClick()
37
+ }
38
+ }
39
+
40
+ useEffect(() => {
41
+ setDisabled(true)
42
+ if (password) {
43
+ setDisabled(false)
44
+ setStatus('')
45
+ setError('')
46
+ }
47
+ }, [password])
48
+
49
+ function copy(str: string) {
50
+ tools.copyToClipboard(str)
51
+ }
52
+ const words = mnemonic.split(' ')
53
+
54
+ const pathName = ADDRESS_TYPES.find(v => v.hdPath === keyring.hdPath)?.name || 'custom'
55
+
56
+ const onClickBack = () => {
57
+ nav.goBack()
58
+ }
59
+
60
+ return {
61
+ words,
62
+ pathName,
63
+ t,
64
+ setPassword,
65
+ disabled,
66
+ btnClick,
67
+ handleOnKeyUp,
68
+ mnemonic,
69
+ passphrase,
70
+ error,
71
+ copy,
72
+ keyring,
73
+ onClickBack,
74
+ }
75
+ }
@@ -0,0 +1,64 @@
1
+ import { useEffect, useState } from 'react'
2
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
3
+
4
+ type Status = '' | 'error' | 'warning' | undefined
5
+ export function useExportPrivateKeyScreenLogic() {
6
+ const { t } = useI18n()
7
+
8
+ const nav = useNavigation()
9
+ const { account } = nav.getRouteState<'ExportPrivateKeyScreen'>()
10
+
11
+ const [password, setPassword] = useState('')
12
+ const [disabled, setDisabled] = useState(true)
13
+
14
+ const [privateKey, setPrivateKey] = useState({ hex: '', wif: '' })
15
+ const [status, setStatus] = useState<Status>('')
16
+ const [error, setError] = useState('')
17
+ const wallet = useWallet()
18
+ const tools = useTools()
19
+
20
+ const btnClick = async () => {
21
+ try {
22
+ const _res = await wallet.getPrivateKey(password, account)
23
+ setPrivateKey(_res)
24
+ } catch (e) {
25
+ setStatus('error')
26
+ setError((e as any).message)
27
+ }
28
+ }
29
+
30
+ const handleOnKeyUp = (e: React.KeyboardEvent<HTMLInputElement>) => {
31
+ if ('Enter' == e.key) {
32
+ btnClick()
33
+ }
34
+ }
35
+
36
+ useEffect(() => {
37
+ setDisabled(true)
38
+ if (password) {
39
+ setDisabled(false)
40
+ setStatus('')
41
+ setError('')
42
+ }
43
+ }, [password])
44
+
45
+ function copy(str: string) {
46
+ tools.copyToClipboard(str)
47
+ }
48
+
49
+ const onClickBack = () => {
50
+ nav.goBack()
51
+ }
52
+
53
+ return {
54
+ t,
55
+ setPassword,
56
+ disabled,
57
+ btnClick,
58
+ handleOnKeyUp,
59
+ privateKey,
60
+ error,
61
+ copy,
62
+ onClickBack,
63
+ }
64
+ }