@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,192 @@
1
+ import { bnUtils } from '@unisat/base-utils'
2
+ import { Inscription, SignedData, SignPsbtParams, ToSignData } from '@unisat/wallet-shared'
3
+ import { useEffect, useMemo, useRef, useState } from 'react'
4
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
5
+ import {
6
+ useCurrentAccount,
7
+ useFeeRateBar,
8
+ usePrepareSendAlkanesCallback,
9
+ usePushBitcoinTxCallback,
10
+ } from 'src/hooks'
11
+ import { isValidAddress } from 'src/utils/bitcoin-utils'
12
+
13
+ export enum SendAlkanesScreenStep {
14
+ CREATE_TX = 0,
15
+ SIGN_TX = 1,
16
+ }
17
+
18
+ export function useSendAlkanesScreenLogic() {
19
+ const nav = useNavigation()
20
+ const props = nav.getRouteState<'SendAlkanesScreen'>()
21
+
22
+ const { t } = useI18n()
23
+
24
+ const tokenBalance = props.tokenBalance
25
+
26
+ const tokenInfo = props.tokenInfo
27
+
28
+ const [inputAmount, setInputAmount] = useState('')
29
+ const [disabled, setDisabled] = useState(true)
30
+ const [toInfo, setToInfo] = useState<{
31
+ address: string
32
+ domain: string
33
+ inscription?: Inscription
34
+ }>({
35
+ address: '',
36
+ domain: '',
37
+ inscription: undefined,
38
+ })
39
+
40
+ const [availableBalance, setAvailableBalance] = useState(tokenBalance.amount)
41
+ const [error, setError] = useState('')
42
+
43
+ const totalBalanceStr = useMemo(() => {
44
+ return bnUtils.toDecimalAmount(tokenBalance.amount, tokenBalance.divisibility)
45
+ }, [tokenBalance])
46
+ const availableBalanceStr = useMemo(() => {
47
+ return bnUtils.toDecimalAmount(availableBalance, tokenBalance?.divisibility)
48
+ }, [availableBalance, tokenBalance])
49
+
50
+ const currentAccount = useCurrentAccount()
51
+
52
+ const tools = useTools()
53
+
54
+ const { feeRate } = useFeeRateBar()
55
+
56
+ useEffect(() => {
57
+ const run = async () => {
58
+ const tokenSummary = await wallet.getAddressAlkanesTokenSummary(
59
+ currentAccount.address,
60
+ tokenBalance.alkaneid,
61
+ true
62
+ )
63
+ setAvailableBalance(tokenSummary.tokenBalance.available)
64
+ }
65
+
66
+ run()
67
+ }, [])
68
+
69
+ useEffect(() => {
70
+ setError('')
71
+ setDisabled(true)
72
+
73
+ if (!isValidAddress(toInfo.address)) {
74
+ return
75
+ }
76
+ if (!inputAmount) {
77
+ return
78
+ }
79
+
80
+ if (feeRate <= 0) {
81
+ return
82
+ }
83
+
84
+ const sendingAmount = bnUtils.fromDecimalAmount(inputAmount, tokenBalance.divisibility)
85
+
86
+ if (bnUtils.compareAmount(sendingAmount, '0') <= 0) {
87
+ return
88
+ }
89
+
90
+ if (bnUtils.compareAmount(sendingAmount, availableBalance)! > 0) {
91
+ setError(t('insufficient_balance'))
92
+ return
93
+ }
94
+
95
+ setDisabled(false)
96
+ }, [toInfo, inputAmount, availableBalance, feeRate])
97
+
98
+ const transferData = useRef<{
99
+ id: string
100
+ toSignData: ToSignData
101
+ }>({
102
+ id: '',
103
+ toSignData: null,
104
+ })
105
+
106
+ const [step, setStep] = useState(SendAlkanesScreenStep.CREATE_TX)
107
+
108
+ const wallet = useWallet()
109
+
110
+ const prepareSendAlkanes = usePrepareSendAlkanesCallback()
111
+ const pushBitcoinTx = usePushBitcoinTxCallback()
112
+
113
+ const onClickBack = () => {
114
+ nav.goBack()
115
+ }
116
+
117
+ const onClickNext = async () => {
118
+ tools.showLoading(true)
119
+ try {
120
+ const toSignData = await prepareSendAlkanes(
121
+ toInfo,
122
+ tokenBalance.alkaneid,
123
+ bnUtils.fromDecimalAmount(inputAmount, tokenBalance.divisibility),
124
+ feeRate,
125
+ 'ft'
126
+ )
127
+ if (toSignData) {
128
+ transferData.current.toSignData = toSignData
129
+ setStep(1)
130
+ }
131
+ } catch (e) {
132
+ setError((e as any).message)
133
+ } finally {
134
+ tools.showLoading(false)
135
+ }
136
+ }
137
+
138
+ const signPsbtParams: SignPsbtParams = {
139
+ data: {
140
+ toSignDatas: [transferData.current.toSignData],
141
+ },
142
+ }
143
+
144
+ const onSignPsbtHandleConfirm = async (signedDatas: SignedData[]) => {
145
+ tools.showLoading(true)
146
+ try {
147
+ const { success, txid, error } = await pushBitcoinTx(signedDatas[0].psbtHex)
148
+ if (success) {
149
+ nav.navigate('TxSuccessScreen', { txid })
150
+ } else {
151
+ throw new Error(error)
152
+ }
153
+ } catch (e) {
154
+ nav.navigate('TxFailScreen', { error: (e as any).message })
155
+ } finally {
156
+ tools.showLoading(false)
157
+ }
158
+ }
159
+
160
+ const onSignPsbtHandleCancel = () => {
161
+ setStep(SendAlkanesScreenStep.CREATE_TX)
162
+ }
163
+
164
+ const onSignPsbtHandleBack = () => {
165
+ setStep(SendAlkanesScreenStep.CREATE_TX)
166
+ }
167
+ return {
168
+ step,
169
+ t,
170
+ tokenBalance,
171
+ tokenInfo,
172
+ toInfo,
173
+ totalBalanceStr,
174
+ availableBalanceStr,
175
+
176
+ inputAmount,
177
+ disabled,
178
+ error,
179
+
180
+ // actions
181
+ setToInfo,
182
+ setInputAmount,
183
+ onClickBack,
184
+ onClickNext,
185
+
186
+ // sign psbt actions
187
+ onSignPsbtHandleConfirm,
188
+ onSignPsbtHandleCancel,
189
+ onSignPsbtHandleBack,
190
+ signPsbtParams,
191
+ }
192
+ }
@@ -0,0 +1,297 @@
1
+ import { bnUtils } from '@unisat/base-utils'
2
+ import {
3
+ AddressCAT20UtxoSummary,
4
+ Inscription,
5
+ SignedData,
6
+ SignPsbtParams,
7
+ ToSignData,
8
+ } from '@unisat/wallet-shared'
9
+ import { AddressType } from '@unisat/wallet-types'
10
+ import BigNumber from 'bignumber.js'
11
+ import { useEffect, useMemo, useRef, useState } from 'react'
12
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
13
+ import { useCurrentAccount, useFeeRateBar, useNetworkType } from 'src/hooks'
14
+ import { getAddressType, isValidAddress } from 'src/utils/bitcoin-utils'
15
+
16
+ const MAX_TOKEN_INPUT = 4
17
+
18
+ export enum SendCAT20ScreenStep {
19
+ PREPARE = 0,
20
+ SIGN_COMMIT = 1,
21
+ WAITING = 2,
22
+ SIGN_REVEAL = 3,
23
+ }
24
+
25
+ export function useSendCAT20ScreenLogic() {
26
+ const nav = useNavigation()
27
+ const props = nav.getRouteState<'SendCAT20Screen'>()
28
+
29
+ const cat20Balance = props.cat20Balance
30
+
31
+ const cat20Info = props.cat20Info
32
+
33
+ const wallet = useWallet()
34
+
35
+ const { t } = useI18n()
36
+ const [inputAmount, setInputAmount] = useState('')
37
+ const [disabled, setDisabled] = useState(false)
38
+ const [toInfo, setToInfo] = useState<{
39
+ address: string
40
+ domain: string
41
+ inscription?: Inscription
42
+ }>({
43
+ address: '',
44
+ domain: '',
45
+ inscription: undefined,
46
+ })
47
+
48
+ const [tokenUtxoSummary, setTokenUtxoSummary] = useState<AddressCAT20UtxoSummary>({
49
+ totalUtxoCount: 0,
50
+ availableUtxoCount: 0,
51
+ availableTokenAmounts: [],
52
+ })
53
+ const [error, setError] = useState('')
54
+
55
+ const account = useCurrentAccount()
56
+
57
+ const networkType = useNetworkType()
58
+
59
+ const [showMergeBTCUTXOPopover, setShowMergeBTCUTXOPopover] = useState(false)
60
+ const tools = useTools()
61
+
62
+ useEffect(() => {
63
+ tools.showLoading(true)
64
+ wallet
65
+ .getAddressCAT20UtxoSummary(props.version, account.address, cat20Balance.tokenId)
66
+ .then(data => {
67
+ setTokenUtxoSummary(data)
68
+ })
69
+ .finally(() => {
70
+ tools.showLoading(false)
71
+ })
72
+ }, [])
73
+
74
+ const availableTokenAmount = useMemo(() => {
75
+ let amount = new BigNumber(0)
76
+ for (
77
+ let i = 0;
78
+ i < Math.min(tokenUtxoSummary.availableTokenAmounts.length, MAX_TOKEN_INPUT);
79
+ i++
80
+ ) {
81
+ amount = amount.plus(BigNumber(tokenUtxoSummary.availableTokenAmounts[i]))
82
+ }
83
+ return amount.toString()
84
+ }, [tokenUtxoSummary])
85
+
86
+ const { feeRate } = useFeeRateBar()
87
+
88
+ useEffect(() => {
89
+ setError('')
90
+ setDisabled(true)
91
+
92
+ if (!isValidAddress(toInfo.address)) {
93
+ return
94
+ }
95
+
96
+ const addressType = getAddressType(toInfo.address, networkType)
97
+ if (addressType !== AddressType.P2TR && addressType !== AddressType.P2WPKH) {
98
+ setError(t('the_recipient_must_be_p2tr_or_p2wpkh_address_type'))
99
+ return
100
+ }
101
+
102
+ if (!inputAmount) {
103
+ return
104
+ }
105
+
106
+ if (!feeRate) {
107
+ return
108
+ }
109
+
110
+ const amt = bnUtils.fromDecimalAmount(inputAmount, cat20Balance.decimals)
111
+ if (bnUtils.compareAmount(amt, '0') != 1) {
112
+ return
113
+ }
114
+
115
+ if (bnUtils.compareAmount(amt, availableTokenAmount) > 0) {
116
+ // insufficient balance
117
+ setError(t('insufficient_balance'))
118
+ return
119
+ }
120
+
121
+ setDisabled(false)
122
+ }, [toInfo, inputAmount, feeRate, availableTokenAmount])
123
+
124
+ const transferData = useRef<{
125
+ id: string
126
+ commitToSignData: ToSignData
127
+ revealToSignData: ToSignData
128
+ }>({
129
+ id: '',
130
+ commitToSignData: {
131
+ psbtHex: '',
132
+ toSignInputs: [],
133
+ autoFinalized: false,
134
+ },
135
+ revealToSignData: {
136
+ psbtHex: '',
137
+ toSignInputs: [],
138
+ autoFinalized: false,
139
+ },
140
+ })
141
+ const [step, setStep] = useState<SendCAT20ScreenStep>(SendCAT20ScreenStep.PREPARE)
142
+ const onClickNext = async () => {
143
+ tools.showLoading(true)
144
+ try {
145
+ const cat20Amount = bnUtils.fromDecimalAmount(inputAmount, cat20Balance.decimals)
146
+ const step1 = await wallet.transferCAT20Step1(
147
+ props.version,
148
+ toInfo.address,
149
+ cat20Balance.tokenId,
150
+ cat20Amount,
151
+ feeRate
152
+ )
153
+ if (step1) {
154
+ transferData.current.id = step1.id
155
+ transferData.current.commitToSignData = step1.toSignData
156
+ setStep(1)
157
+ }
158
+ } catch (e) {
159
+ const msg = (e as any).message
160
+ if (msg.includes('-307')) {
161
+ setShowMergeBTCUTXOPopover(true)
162
+ return
163
+ }
164
+ setError((e as any).message)
165
+ } finally {
166
+ tools.showLoading(false)
167
+ }
168
+ }
169
+
170
+ const onClickBack = () => {
171
+ if (step === SendCAT20ScreenStep.PREPARE) {
172
+ nav.goBack()
173
+ return
174
+ } else {
175
+ setStep(SendCAT20ScreenStep.PREPARE)
176
+ }
177
+ }
178
+
179
+ // sign commit psbt
180
+ const signCommitPsbtParams: SignPsbtParams = {
181
+ data: {
182
+ toSignDatas: [transferData.current.commitToSignData],
183
+ },
184
+ }
185
+
186
+ const onSignCommitPsbtHandleConfirm = async (signedDatas: SignedData[]) => {
187
+ try {
188
+ tools.showLoading(true)
189
+ const step2 = await wallet.transferCAT20Step2(
190
+ props.version,
191
+ transferData.current.id,
192
+ signedDatas[0].psbtHex
193
+ )
194
+
195
+ transferData.current.revealToSignData = step2.toSignData
196
+
197
+ setStep(SendCAT20ScreenStep.WAITING)
198
+ setTimeout(() => {
199
+ setStep(SendCAT20ScreenStep.SIGN_REVEAL)
200
+ }, 100)
201
+ } catch (e) {
202
+ console.log(e)
203
+ } finally {
204
+ tools.showLoading(false)
205
+ }
206
+ }
207
+
208
+ const onSignCommitPsbtHandleCancel = () => {
209
+ setStep(SendCAT20ScreenStep.PREPARE)
210
+ }
211
+
212
+ const onSignCommitPsbtHandleBack = () => {
213
+ setStep(SendCAT20ScreenStep.PREPARE)
214
+ }
215
+
216
+ // sign reveal psbt
217
+ const signRevealPsbtParams: SignPsbtParams = {
218
+ data: {
219
+ toSignDatas: [transferData.current.revealToSignData],
220
+ },
221
+ }
222
+
223
+ const onSignRevealPsbtHandleConfirm = async (signedDatas: SignedData[]) => {
224
+ tools.showLoading(true)
225
+ try {
226
+ const step3 = await wallet.transferCAT20Step3(
227
+ props.version,
228
+ transferData.current.id,
229
+ signedDatas[0].psbtHex
230
+ )
231
+ nav.navigate('TxSuccessScreen', { txid: step3.txid })
232
+ } catch (e) {
233
+ // tools.toastError((e as any).message);
234
+ nav.navigate('TxFailScreen', { error: (e as any).message })
235
+ } finally {
236
+ tools.showLoading(false)
237
+ }
238
+ }
239
+
240
+ const onSignRevealPsbtHandleCancel = () => {
241
+ setStep(SendCAT20ScreenStep.PREPARE)
242
+ }
243
+
244
+ const onSignRevealPsbtHandleBack = () => {
245
+ setStep(SendCAT20ScreenStep.PREPARE)
246
+ }
247
+
248
+ // merge UTXO
249
+ const shouldShowMerge = availableTokenAmount !== cat20Balance.amount
250
+
251
+ const onClickMergeUTXO = () => {
252
+ nav.navigate('MergeCAT20Screen', {
253
+ version: props.version,
254
+ cat20Balance: cat20Balance,
255
+ cat20Info: cat20Info,
256
+ })
257
+ }
258
+
259
+ return {
260
+ // info
261
+ cat20Info,
262
+ cat20Balance,
263
+ availableTokenAmount,
264
+ toInfo,
265
+ setToInfo,
266
+ inputAmount,
267
+ setInputAmount,
268
+ error,
269
+ disabled,
270
+ step,
271
+ showMergeBTCUTXOPopover,
272
+ setShowMergeBTCUTXOPopover,
273
+ shouldShowMerge,
274
+
275
+ // actions
276
+ onClickNext,
277
+ onClickBack,
278
+
279
+ // sign commit psbt actions
280
+ onSignCommitPsbtHandleConfirm,
281
+ onSignCommitPsbtHandleCancel,
282
+ onSignCommitPsbtHandleBack,
283
+ signCommitPsbtParams,
284
+
285
+ // sign reveal psbt actions
286
+ onSignRevealPsbtHandleConfirm,
287
+ onSignRevealPsbtHandleCancel,
288
+ onSignRevealPsbtHandleBack,
289
+ signRevealPsbtParams,
290
+
291
+ // merge UTXO action
292
+ onClickMergeUTXO,
293
+
294
+ // tools
295
+ t,
296
+ }
297
+ }
@@ -0,0 +1,205 @@
1
+ import { Inscription, SignedData, SignPsbtParams, ToSignData } from '@unisat/wallet-shared'
2
+ import { AddressType } from '@unisat/wallet-types'
3
+ import { useEffect, useRef, useState } from 'react'
4
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
5
+ import { useFeeRateBar, useNetworkType } from 'src/hooks'
6
+ import { getAddressType, isValidAddress } from 'src/utils/bitcoin-utils'
7
+
8
+ export enum SendCAT721ScreenStep {
9
+ PREPARE = 0,
10
+ SIGN_COMMIT = 1,
11
+ WAITING = 2,
12
+ SIGN_REVEAL = 3,
13
+ }
14
+ export function useSendCAT721ScreenLogic() {
15
+ const nav = useNavigation()
16
+ const { version, localId, collectionInfo } = nav.getRouteState<'SendCAT721Screen'>()
17
+
18
+ const wallet = useWallet()
19
+ const { t } = useI18n()
20
+
21
+ const [disabled, setDisabled] = useState(false)
22
+ const [toInfo, setToInfo] = useState<{
23
+ address: string
24
+ domain: string
25
+ inscription?: Inscription
26
+ }>({
27
+ address: '',
28
+ domain: '',
29
+ inscription: undefined,
30
+ })
31
+
32
+ const [error, setError] = useState('')
33
+
34
+ const networkType = useNetworkType()
35
+
36
+ const [showMergeBTCUTXOPopover, setShowMergeBTCUTXOPopover] = useState(false)
37
+ const tools = useTools()
38
+
39
+ const { feeRate } = useFeeRateBar()
40
+
41
+ useEffect(() => {
42
+ setError('')
43
+ setDisabled(true)
44
+
45
+ if (!isValidAddress(toInfo.address)) {
46
+ return
47
+ }
48
+
49
+ const addressType = getAddressType(toInfo.address, networkType)
50
+ if (addressType !== AddressType.P2TR && addressType !== AddressType.P2WPKH) {
51
+ setError(t('the_recipient_must_be_p2tr_or_p2wpkh_address_type'))
52
+ return
53
+ }
54
+
55
+ setDisabled(false)
56
+ }, [toInfo])
57
+
58
+ const transferData = useRef<{
59
+ id: string
60
+ commitToSignData: ToSignData
61
+ revealToSignData: ToSignData
62
+ }>({
63
+ id: '',
64
+ commitToSignData: {} as ToSignData,
65
+ revealToSignData: {} as ToSignData,
66
+ })
67
+ const [step, setStep] = useState<SendCAT721ScreenStep>(SendCAT721ScreenStep.PREPARE)
68
+ const onClickNext = async () => {
69
+ tools.showLoading(true)
70
+ try {
71
+ const step1 = await wallet.transferCAT721Step1(
72
+ version,
73
+ toInfo.address,
74
+ collectionInfo.collectionId,
75
+ localId,
76
+ feeRate
77
+ )
78
+ if (step1) {
79
+ transferData.current.id = step1.id
80
+ transferData.current.commitToSignData = step1.toSignData
81
+ setStep(1)
82
+ }
83
+ } catch (e) {
84
+ const msg = (e as any).message
85
+ if (msg.includes('-307')) {
86
+ setShowMergeBTCUTXOPopover(true)
87
+ return
88
+ }
89
+ setError((e as any).message)
90
+ } finally {
91
+ tools.showLoading(false)
92
+ }
93
+ }
94
+
95
+ const onClickBack = () => {
96
+ if (step === SendCAT721ScreenStep.PREPARE) {
97
+ nav.goBack()
98
+ return
99
+ } else {
100
+ setStep(SendCAT721ScreenStep.PREPARE)
101
+ }
102
+ }
103
+
104
+ // sign commit psbt
105
+ const signCommitPsbtParams: SignPsbtParams = {
106
+ data: {
107
+ toSignDatas: [transferData.current.commitToSignData],
108
+ },
109
+ }
110
+
111
+ const onSignCommitPsbtHandleConfirm = async (signedDatas: SignedData[]) => {
112
+ try {
113
+ tools.showLoading(true)
114
+ const step2 = await wallet.transferCAT721Step2(
115
+ version,
116
+ transferData.current.id,
117
+ signedDatas[0].psbtHex
118
+ )
119
+
120
+ transferData.current.revealToSignData = step2.toSignData
121
+
122
+ setStep(SendCAT721ScreenStep.WAITING)
123
+ setTimeout(() => {
124
+ setStep(SendCAT721ScreenStep.SIGN_REVEAL)
125
+ }, 100)
126
+ } catch (e) {
127
+ console.log(e)
128
+ } finally {
129
+ tools.showLoading(false)
130
+ }
131
+ }
132
+
133
+ const onSignCommitPsbtHandleCancel = () => {
134
+ setStep(SendCAT721ScreenStep.PREPARE)
135
+ }
136
+
137
+ const onSignCommitPsbtHandleBack = () => {
138
+ setStep(SendCAT721ScreenStep.PREPARE)
139
+ }
140
+
141
+ // sign reveal psbt
142
+ const signRevealPsbtParams: SignPsbtParams = {
143
+ data: {
144
+ toSignDatas: [transferData.current.revealToSignData],
145
+ },
146
+ }
147
+
148
+ const onSignRevealPsbtHandleConfirm = async (signedDatas: SignedData[]) => {
149
+ tools.showLoading(true)
150
+ try {
151
+ const step3 = await wallet.transferCAT721Step3(
152
+ version,
153
+ transferData.current.id,
154
+ signedDatas[0].psbtHex
155
+ )
156
+ nav.navigate('TxSuccessScreen', { txid: step3.txid })
157
+ } catch (e) {
158
+ // tools.toastError((e as any).message);
159
+ nav.navigate('TxFailScreen', { error: (e as any).message })
160
+ } finally {
161
+ tools.showLoading(false)
162
+ }
163
+ }
164
+
165
+ const onSignRevealPsbtHandleCancel = () => {
166
+ setStep(SendCAT721ScreenStep.PREPARE)
167
+ }
168
+
169
+ const onSignRevealPsbtHandleBack = () => {
170
+ setStep(SendCAT721ScreenStep.PREPARE)
171
+ }
172
+
173
+ return {
174
+ // info
175
+ version,
176
+ localId,
177
+ collectionInfo,
178
+ toInfo,
179
+ setToInfo,
180
+ error,
181
+ disabled,
182
+ step,
183
+ showMergeBTCUTXOPopover,
184
+ setShowMergeBTCUTXOPopover,
185
+
186
+ // actions
187
+ onClickNext,
188
+ onClickBack,
189
+
190
+ // sign commit psbt actions
191
+ onSignCommitPsbtHandleConfirm,
192
+ onSignCommitPsbtHandleCancel,
193
+ onSignCommitPsbtHandleBack,
194
+ signCommitPsbtParams,
195
+
196
+ // sign reveal psbt actions
197
+ onSignRevealPsbtHandleConfirm,
198
+ onSignRevealPsbtHandleCancel,
199
+ onSignRevealPsbtHandleBack,
200
+ signRevealPsbtParams,
201
+
202
+ // tools
203
+ t,
204
+ }
205
+ }