@unisat/wallet-state 1.0.0 → 1.0.1
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.
- package/package.json +16 -3
- package/src/actions/global.ts +5 -0
- package/src/context/I18nContext.tsx +191 -0
- package/src/context/PriceContext.tsx +81 -0
- package/src/context/WalletContext.tsx +703 -0
- package/src/context/index.ts +3 -0
- package/src/hooks/accounts.ts +23 -21
- package/src/hooks/approval.ts +72 -0
- package/src/hooks/base.ts +6 -0
- package/src/hooks/discovery.ts +29 -0
- package/src/hooks/global.ts +129 -5
- package/src/hooks/i18n.ts +53 -0
- package/src/hooks/index.ts +9 -15
- package/src/hooks/keyrings.ts +14 -5
- package/src/hooks/settings.ts +318 -5
- package/src/hooks/transactions.ts +44 -38
- package/src/hooks/ui.ts +133 -5
- package/src/index.ts +42 -5
- package/src/{slices → reducers}/accounts.ts +12 -12
- package/src/reducers/discovery.ts +73 -0
- package/src/reducers/global.ts +51 -0
- package/src/{slices → reducers}/keyrings.ts +7 -6
- package/src/{slices → reducers}/settings.ts +5 -5
- package/src/{slices → reducers}/transactions.ts +4 -5
- package/src/{slices → reducers}/ui.ts +4 -5
- package/src/updater/accounts.ts +107 -0
- package/src/updater/index.ts +1 -0
- package/src/utils/bitcoin-utils.ts +81 -0
- package/src/utils/eventBus.ts +49 -0
- package/src/utils/i18n.ts +41 -0
- package/src/slices/global.ts +0 -52
- package/src/slices/index.ts +0 -10
- package/src/store/index.ts +0 -43
- package/src/types/index.ts +0 -37
package/src/hooks/accounts.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { useCallback } from 'react'
|
|
2
2
|
|
|
3
|
-
import { Account
|
|
4
|
-
|
|
3
|
+
import { Account } from '@unisat/wallet-shared'
|
|
4
|
+
|
|
5
|
+
import { AddressType } from '@unisat/wallet-types'
|
|
5
6
|
import { KeyringType } from '@unisat/keyring-service/types'
|
|
6
7
|
|
|
7
8
|
import { AppState } from '..'
|
|
8
|
-
import { useAppDispatch, useAppSelector } from '
|
|
9
|
-
import { useCurrentKeyring } from '
|
|
10
|
-
import { keyringsActions } from '../keyrings
|
|
11
|
-
import { settingsActions } from '../settings
|
|
12
|
-
import { accountActions } from '
|
|
9
|
+
import { useAppDispatch, useAppSelector } from './base'
|
|
10
|
+
import { useCurrentKeyring } from './keyrings'
|
|
11
|
+
import { keyringsActions } from '../reducers/keyrings'
|
|
12
|
+
import { settingsActions } from '../reducers/settings'
|
|
13
|
+
import { accountActions } from '../reducers/accounts'
|
|
14
|
+
import { useWallet } from '../context/WalletContext'
|
|
13
15
|
|
|
14
16
|
export function useAccountsState(): AppState['accounts'] {
|
|
15
17
|
return useAppSelector(state => state.accounts)
|
|
@@ -78,7 +80,7 @@ export function useReadTab() {
|
|
|
78
80
|
await wallet.readTab(name)
|
|
79
81
|
if (name == 'app') {
|
|
80
82
|
const appSummary = await wallet.getAppSummary()
|
|
81
|
-
dispatch(accountActions
|
|
83
|
+
dispatch(accountActions['setAppSummary']!(appSummary))
|
|
82
84
|
}
|
|
83
85
|
},
|
|
84
86
|
[dispatch, wallet, appSummary]
|
|
@@ -93,7 +95,7 @@ export function useReadApp() {
|
|
|
93
95
|
async (id: number) => {
|
|
94
96
|
await wallet.readApp(id)
|
|
95
97
|
const appSummary = await wallet.getAppSummary()
|
|
96
|
-
dispatch(accountActions
|
|
98
|
+
dispatch(accountActions['setAppSummary']!(appSummary))
|
|
97
99
|
},
|
|
98
100
|
[dispatch, wallet, appSummary]
|
|
99
101
|
)
|
|
@@ -114,7 +116,7 @@ export function useSetCurrentAccountCallback() {
|
|
|
114
116
|
const dispatch = useAppDispatch()
|
|
115
117
|
return useCallback(
|
|
116
118
|
(account: Account) => {
|
|
117
|
-
dispatch(accountActions
|
|
119
|
+
dispatch(accountActions['setCurrent']!(account))
|
|
118
120
|
},
|
|
119
121
|
[dispatch]
|
|
120
122
|
)
|
|
@@ -132,7 +134,7 @@ export function useImportAccountCallback() {
|
|
|
132
134
|
const alianName = await wallet.getNextAlianName(currentKeyring)
|
|
133
135
|
await wallet.createKeyringWithPrivateKey(privateKey, addressType, alianName)
|
|
134
136
|
const currentAccount = await wallet.getCurrentAccount()
|
|
135
|
-
dispatch(accountActions
|
|
137
|
+
dispatch(accountActions['setCurrent']!(currentAccount))
|
|
136
138
|
|
|
137
139
|
success = true
|
|
138
140
|
} catch (e) {
|
|
@@ -154,7 +156,7 @@ export function useChangeAddressFlagCallback() {
|
|
|
154
156
|
const account = isAdd
|
|
155
157
|
? await wallet.addAddressFlag(currentAccount, flag)
|
|
156
158
|
: await wallet.removeAddressFlag(currentAccount, flag)
|
|
157
|
-
dispatch(accountActions
|
|
159
|
+
dispatch(accountActions['setCurrentAddressFlag']!(account.flag))
|
|
158
160
|
},
|
|
159
161
|
[dispatch, wallet, currentAccount]
|
|
160
162
|
)
|
|
@@ -201,11 +203,11 @@ export function useFetchBalanceCallback() {
|
|
|
201
203
|
|
|
202
204
|
const summary = await wallet.getAddressSummary(currentAccount.address)
|
|
203
205
|
summary.address = currentAccount.address
|
|
204
|
-
dispatch(accountActions
|
|
206
|
+
dispatch(accountActions['setAddressSummary']!(summary))
|
|
205
207
|
|
|
206
208
|
const balanceV2 = await wallet.getAddressBalanceV2(currentAccount.address)
|
|
207
209
|
dispatch(
|
|
208
|
-
accountActions
|
|
210
|
+
accountActions['setBalanceV2']!({
|
|
209
211
|
address: currentAccount.address,
|
|
210
212
|
balance: balanceV2,
|
|
211
213
|
})
|
|
@@ -218,22 +220,22 @@ export function useReloadAccounts() {
|
|
|
218
220
|
const wallet = useWallet()
|
|
219
221
|
return useCallback(async () => {
|
|
220
222
|
const keyrings = await wallet.getKeyrings()
|
|
221
|
-
dispatch(keyringsActions
|
|
223
|
+
dispatch(keyringsActions['setKeyrings']!(keyrings))
|
|
222
224
|
|
|
223
225
|
const currentKeyring = await wallet.getCurrentKeyring()
|
|
224
|
-
dispatch(keyringsActions
|
|
226
|
+
dispatch(keyringsActions['setCurrent']!(currentKeyring))
|
|
225
227
|
|
|
226
228
|
const _accounts = await wallet.getAccounts()
|
|
227
|
-
dispatch(accountActions
|
|
229
|
+
dispatch(accountActions['setAccounts']!(_accounts))
|
|
228
230
|
|
|
229
231
|
const account = await wallet.getCurrentAccount()
|
|
230
|
-
dispatch(accountActions
|
|
232
|
+
dispatch(accountActions['setCurrent']!(account))
|
|
231
233
|
|
|
232
|
-
dispatch(accountActions
|
|
233
|
-
dispatch(accountActions
|
|
234
|
+
dispatch(accountActions['expireBalance']!(null))
|
|
235
|
+
dispatch(accountActions['expireInscriptions']!(null))
|
|
234
236
|
|
|
235
237
|
wallet.getWalletConfig().then(data => {
|
|
236
|
-
dispatch(settingsActions
|
|
238
|
+
dispatch(settingsActions['updateSettings']!({ walletConfig: data }))
|
|
237
239
|
})
|
|
238
240
|
}, [dispatch, wallet])
|
|
239
241
|
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react'
|
|
2
|
+
import { useNavigate } from 'react-router-dom'
|
|
3
|
+
|
|
4
|
+
import { useWallet } from '../context/WalletContext'
|
|
5
|
+
|
|
6
|
+
const UI_TYPE = {
|
|
7
|
+
Tab: 'index',
|
|
8
|
+
Pop: 'popup',
|
|
9
|
+
Notification: 'notification',
|
|
10
|
+
SidePanel: 'sidepanel',
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type UiTypeCheck = {
|
|
14
|
+
isTab: boolean
|
|
15
|
+
isNotification: boolean
|
|
16
|
+
isPop: boolean
|
|
17
|
+
isSidePanel: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const getUiType = (): UiTypeCheck => {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
const { pathname } = window.location
|
|
23
|
+
return Object.entries(UI_TYPE).reduce((m, [key, value]) => {
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
m[`is${key}`] = pathname === `/${value}.html`
|
|
26
|
+
|
|
27
|
+
return m
|
|
28
|
+
}, {} as UiTypeCheck)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const useApproval = () => {
|
|
32
|
+
const wallet = useWallet()
|
|
33
|
+
const navigate = useNavigate()
|
|
34
|
+
const getApproval = wallet.getApproval
|
|
35
|
+
|
|
36
|
+
const resolveApproval = async (data?: any, stay = false, forceReject = false) => {
|
|
37
|
+
const approval = await getApproval()
|
|
38
|
+
|
|
39
|
+
if (approval) {
|
|
40
|
+
wallet.resolveApproval(data, forceReject)
|
|
41
|
+
}
|
|
42
|
+
if (stay) {
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
setTimeout(() => {
|
|
46
|
+
navigate('/')
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const rejectApproval = async (err: any, stay = false, isInternal = false) => {
|
|
51
|
+
const approval = await getApproval()
|
|
52
|
+
if (approval) {
|
|
53
|
+
await wallet.rejectApproval(err, stay, isInternal)
|
|
54
|
+
}
|
|
55
|
+
if (!stay) {
|
|
56
|
+
navigate('/')
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (!getUiType().isNotification) {
|
|
62
|
+
return () => {}
|
|
63
|
+
}
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
window.addEventListener('beforeunload', rejectApproval)
|
|
66
|
+
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
return () => window.removeEventListener('beforeunload', rejectApproval)
|
|
69
|
+
}, [])
|
|
70
|
+
|
|
71
|
+
return [getApproval, resolveApproval, rejectApproval] as const
|
|
72
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
|
|
2
|
+
|
|
3
|
+
import { AppDispatch, AppState } from '../index'
|
|
4
|
+
|
|
5
|
+
export const useAppDispatch = () => useDispatch<AppDispatch>()
|
|
6
|
+
export const useAppSelector: TypedUseSelectorHook<AppState> = useSelector
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { AppState } from '..'
|
|
2
|
+
import { useAppSelector } from './base'
|
|
3
|
+
|
|
4
|
+
export function useDiscoveryState(): AppState['discovery'] {
|
|
5
|
+
return useAppSelector(state => state.discovery)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function useAppList() {
|
|
9
|
+
const state = useDiscoveryState()
|
|
10
|
+
return state.appList
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function useBannerList() {
|
|
14
|
+
const state = useDiscoveryState()
|
|
15
|
+
return state.bannerList
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function useLastFetchInfo() {
|
|
19
|
+
const state = useDiscoveryState()
|
|
20
|
+
return {
|
|
21
|
+
lastFetchTime: state.lastFetchTime,
|
|
22
|
+
lasfFetchChainType: state.lastFetchChainType,
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function useHasNewBanner() {
|
|
27
|
+
const state = useDiscoveryState()
|
|
28
|
+
return state.hasNewBanner
|
|
29
|
+
}
|
package/src/hooks/global.ts
CHANGED
|
@@ -1,7 +1,131 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
return useWalletSelector((state) => state.global);
|
|
5
|
-
};
|
|
3
|
+
import { AddressType } from '@unisat/wallet-types'
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
import { AppState } from '..'
|
|
6
|
+
import { useAppDispatch, useAppSelector } from './base'
|
|
7
|
+
import { TabOption, globalActions } from '../reducers/global'
|
|
8
|
+
import { useWallet } from '../context/WalletContext'
|
|
9
|
+
import { useApproval } from './approval'
|
|
10
|
+
|
|
11
|
+
export function useGlobalState(): AppState['global'] {
|
|
12
|
+
return useAppSelector(state => state.global)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function useTab() {
|
|
16
|
+
const globalState = useGlobalState()
|
|
17
|
+
return globalState.tab
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function useSetTabCallback() {
|
|
21
|
+
const dispatch = useAppDispatch()
|
|
22
|
+
return useCallback(
|
|
23
|
+
(tab: TabOption) => {
|
|
24
|
+
dispatch(
|
|
25
|
+
globalActions['update']!({
|
|
26
|
+
tab,
|
|
27
|
+
})
|
|
28
|
+
)
|
|
29
|
+
},
|
|
30
|
+
[dispatch]
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function useBooted() {
|
|
35
|
+
const globalState = useGlobalState()
|
|
36
|
+
return globalState.isBooted
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function useIsUnlocked() {
|
|
40
|
+
const globalState = useGlobalState()
|
|
41
|
+
return globalState.isUnlocked
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function useIsReady() {
|
|
45
|
+
const globalState = useGlobalState()
|
|
46
|
+
return globalState.isReady
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function useUnlockCallback() {
|
|
50
|
+
const dispatch = useAppDispatch()
|
|
51
|
+
const wallet = useWallet()
|
|
52
|
+
const [, resolveApproval] = useApproval()
|
|
53
|
+
return useCallback(
|
|
54
|
+
async (password: string) => {
|
|
55
|
+
await wallet.unlock(password)
|
|
56
|
+
dispatch(globalActions.update({ isUnlocked: true }))
|
|
57
|
+
resolveApproval()
|
|
58
|
+
},
|
|
59
|
+
[dispatch, wallet]
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function useCreateAccountCallback() {
|
|
64
|
+
const dispatch = useAppDispatch()
|
|
65
|
+
const wallet = useWallet()
|
|
66
|
+
return useCallback(
|
|
67
|
+
async (
|
|
68
|
+
mnemonics: string,
|
|
69
|
+
hdPath: string,
|
|
70
|
+
passphrase: string,
|
|
71
|
+
addressType: AddressType,
|
|
72
|
+
accountCount: number
|
|
73
|
+
) => {
|
|
74
|
+
await wallet.createKeyringWithMnemonics(
|
|
75
|
+
mnemonics,
|
|
76
|
+
hdPath,
|
|
77
|
+
passphrase,
|
|
78
|
+
addressType,
|
|
79
|
+
accountCount
|
|
80
|
+
)
|
|
81
|
+
dispatch(globalActions.update({ isUnlocked: true }))
|
|
82
|
+
},
|
|
83
|
+
[dispatch, wallet]
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function useImportAccountsFromKeystoneCallback() {
|
|
88
|
+
const dispatch = useAppDispatch()
|
|
89
|
+
const wallet = useWallet()
|
|
90
|
+
return useCallback(
|
|
91
|
+
async (
|
|
92
|
+
urType: string,
|
|
93
|
+
urCbor: string,
|
|
94
|
+
addressType: AddressType,
|
|
95
|
+
accountCount: number,
|
|
96
|
+
hdPath: string,
|
|
97
|
+
filterPubkey?: string[],
|
|
98
|
+
connectionType: 'USB' | 'QR' = 'USB'
|
|
99
|
+
) => {
|
|
100
|
+
await wallet.createKeyringWithKeystone(
|
|
101
|
+
urType,
|
|
102
|
+
urCbor,
|
|
103
|
+
addressType,
|
|
104
|
+
hdPath,
|
|
105
|
+
accountCount,
|
|
106
|
+
filterPubkey,
|
|
107
|
+
connectionType
|
|
108
|
+
)
|
|
109
|
+
dispatch(globalActions.update({ isUnlocked: true }))
|
|
110
|
+
},
|
|
111
|
+
[dispatch, wallet]
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function useCreateColdWalletCallback() {
|
|
116
|
+
const dispatch = useAppDispatch()
|
|
117
|
+
const wallet = useWallet()
|
|
118
|
+
return useCallback(
|
|
119
|
+
async (
|
|
120
|
+
xpub: string,
|
|
121
|
+
addressType: AddressType,
|
|
122
|
+
alianName?: string,
|
|
123
|
+
hdPath?: string,
|
|
124
|
+
accountCount?: number
|
|
125
|
+
) => {
|
|
126
|
+
await wallet.createKeyringWithColdWallet(xpub, addressType, alianName, hdPath, accountCount)
|
|
127
|
+
dispatch(globalActions.update({ isUnlocked: true }))
|
|
128
|
+
},
|
|
129
|
+
[dispatch, wallet]
|
|
130
|
+
)
|
|
131
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
|
|
3
|
+
import { I18nContext } from '../context/I18nContext'
|
|
4
|
+
import { FALLBACK_LOCALE, getCurrentLocaleAsync, LOCALE_NAMES } from '@unisat/i18n'
|
|
5
|
+
|
|
6
|
+
const defaultI18nContext = {
|
|
7
|
+
t: (key: string) => key,
|
|
8
|
+
locale: FALLBACK_LOCALE,
|
|
9
|
+
supportedLocales: [FALLBACK_LOCALE],
|
|
10
|
+
localeNames: LOCALE_NAMES,
|
|
11
|
+
changeLocale: async () => {
|
|
12
|
+
/* empty implementation */
|
|
13
|
+
},
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Use i18n Hook
|
|
18
|
+
* @returns i18n context
|
|
19
|
+
*/
|
|
20
|
+
export const useI18n = () => {
|
|
21
|
+
try {
|
|
22
|
+
const context = useContext(I18nContext)
|
|
23
|
+
|
|
24
|
+
if (!context) {
|
|
25
|
+
console.warn('useI18n must be used within an I18nProvider, using default context instead')
|
|
26
|
+
return defaultI18nContext
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return context as any
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error('Error in useI18n:', error)
|
|
32
|
+
return defaultI18nContext
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get current language
|
|
38
|
+
* @returns current language code
|
|
39
|
+
*/
|
|
40
|
+
export const getCurrentLocale = async (): Promise<string> => {
|
|
41
|
+
return await getCurrentLocaleAsync()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Select special languages for style adaptation
|
|
46
|
+
* @returns { currentLocale: string, isSpecialLocale: boolean }
|
|
47
|
+
*/
|
|
48
|
+
export const getSpecialLocale = async () => {
|
|
49
|
+
const currentLocale = await getCurrentLocale()
|
|
50
|
+
const specialLocales = ['es', 'ru', 'fr', 'ja']
|
|
51
|
+
const isSpecialLocale = specialLocales.includes(currentLocale)
|
|
52
|
+
return { currentLocale, isSpecialLocale }
|
|
53
|
+
}
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
export
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export * from './accounts';
|
|
11
|
-
export * from './transactions';
|
|
12
|
-
export * from './settings';
|
|
13
|
-
export * from './global';
|
|
14
|
-
export * from './keyrings';
|
|
15
|
-
export * from './ui';
|
|
1
|
+
export * from './approval'
|
|
2
|
+
export * from './base'
|
|
3
|
+
export * from './discovery'
|
|
4
|
+
export * from './global'
|
|
5
|
+
export * from './i18n'
|
|
6
|
+
export * from './keyrings'
|
|
7
|
+
export * from './settings'
|
|
8
|
+
export * from './transactions'
|
|
9
|
+
export * from './ui'
|
package/src/hooks/keyrings.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AppState } from '..'
|
|
2
|
+
import { useAppSelector } from './base'
|
|
2
3
|
|
|
3
|
-
export
|
|
4
|
-
return
|
|
5
|
-
}
|
|
4
|
+
export function useKeyringsState(): AppState['keyrings'] {
|
|
5
|
+
return useAppSelector(state => state.keyrings)
|
|
6
|
+
}
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
export function useKeyrings() {
|
|
9
|
+
const keyringsState = useKeyringsState()
|
|
10
|
+
return keyringsState.keyrings
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function useCurrentKeyring() {
|
|
14
|
+
const keyringsState = useKeyringsState()
|
|
15
|
+
return keyringsState.current
|
|
16
|
+
}
|