@unisat/wallet-state 1.1.0 → 1.2.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.
Files changed (45) hide show
  1. package/lib/index.d.mts +87 -18
  2. package/lib/index.d.ts +87 -18
  3. package/lib/index.js +516 -175
  4. package/lib/index.js.map +1 -1
  5. package/lib/index.mjs +514 -178
  6. package/lib/index.mjs.map +1 -1
  7. package/lib/types/index.d.mts +6 -2
  8. package/lib/types/index.d.ts +6 -2
  9. package/lib/types/index.js +7 -1
  10. package/lib/types/index.js.map +1 -1
  11. package/lib/types/index.mjs +7 -2
  12. package/lib/types/index.mjs.map +1 -1
  13. package/package.json +4 -4
  14. package/src/context/NavigationContext.tsx +1 -0
  15. package/src/context/WalletContext.tsx +56 -23
  16. package/src/hooks/accounts.ts +7 -2
  17. package/src/hooks/settings.ts +10 -0
  18. package/src/hooks/transactions.ts +75 -10
  19. package/src/hooks/ui.ts +83 -63
  20. package/src/reducers/accounts.ts +3 -0
  21. package/src/reducers/ui.ts +21 -0
  22. package/src/types/ui.ts +6 -1
  23. package/src/ui-hooks/useAddressTypeScreenLogic.ts +22 -8
  24. package/src/ui-hooks/useAlkanesNFTScreenLogic.ts +3 -2
  25. package/src/ui-hooks/useAlkanesTokenScreenLogic.ts +12 -2
  26. package/src/ui-hooks/useBRC20InscribeTransferLogic.ts +30 -10
  27. package/src/ui-hooks/useBRC20ListLogic.ts +6 -2
  28. package/src/ui-hooks/useBRC20ProgListLogic.ts +7 -3
  29. package/src/ui-hooks/useBRC20SendScreenLogic.ts +19 -6
  30. package/src/ui-hooks/useBRC20TokenScreenLogic.ts +48 -25
  31. package/src/ui-hooks/useCAT20TokenScreenLogic.ts +16 -2
  32. package/src/ui-hooks/useCAT721NFTScreenLogic.ts +3 -1
  33. package/src/ui-hooks/useEditAccountNameScreenLogic.ts +4 -4
  34. package/src/ui-hooks/useEditWalletNameScreenLogic.ts +5 -3
  35. package/src/ui-hooks/useOrdinalsInscriptionScreenLogic.ts +3 -2
  36. package/src/ui-hooks/useRunesTokenScreenLogic.ts +11 -2
  37. package/src/ui-hooks/useSendAlkanesNFTScreenLogic.ts +24 -2
  38. package/src/ui-hooks/useSendAlkanesScreenLogic.ts +17 -1
  39. package/src/ui-hooks/useSendOrdinalsInscriptionScreenLogic.ts +17 -5
  40. package/src/ui-hooks/useSendRunesScreenLogic.ts +18 -1
  41. package/src/ui-hooks/useSettingsTabScreenLogic.ts +18 -3
  42. package/src/ui-hooks/useSignMessageLogic.ts +37 -16
  43. package/src/ui-hooks/useSignPsbtLogic.ts +31 -15
  44. package/src/ui-hooks/useSplitOrdinalsInscriptionScreenLogic.ts +15 -1
  45. package/src/ui-hooks/useTxCreateScreenLogic.ts +17 -1
@@ -5,11 +5,13 @@ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
5
5
  import {
6
6
  useChainType,
7
7
  useCurrentAccount,
8
+ useCurrentAccountCapabilities,
8
9
  useOrdinalsWebsite,
9
10
  useResetTxState,
10
11
  useRunesIconInfo,
11
12
  useRunesInscribeUrl,
12
13
  useRunesMarketUrl,
14
+ useRunesTokenInfoExplorerUrl,
13
15
  useTxExplorerUrl,
14
16
  } from 'src/hooks'
15
17
 
@@ -61,6 +63,7 @@ export function useRunesTokenScreenLogic() {
61
63
  const wallet = useWallet()
62
64
 
63
65
  const account = useCurrentAccount()
66
+ const accountCapabilities = useCurrentAccountCapabilities()
64
67
 
65
68
  const [loading, setLoading] = useState(true)
66
69
 
@@ -77,11 +80,11 @@ export function useRunesTokenScreenLogic() {
77
80
 
78
81
  const enableTransfer = useMemo(() => {
79
82
  let enable = false
80
- if (tokenSummary.runeBalance.amount !== '0') {
83
+ if (accountCapabilities.canCreateSigningRequest && tokenSummary.runeBalance.amount !== '0') {
81
84
  enable = true
82
85
  }
83
86
  return enable
84
- }, [tokenSummary])
87
+ }, [accountCapabilities.canCreateSigningRequest, tokenSummary])
85
88
 
86
89
  const tools = useTools()
87
90
 
@@ -106,6 +109,7 @@ export function useRunesTokenScreenLogic() {
106
109
  const iconInfo = useRunesIconInfo(tokenSummary.runeInfo.spacedRune)
107
110
  const inscribeUrl = useRunesInscribeUrl(tokenSummary.runeInfo.rune)
108
111
  const marketPlaceUrl = useRunesMarketUrl(tokenSummary.runeInfo.spacedRune)
112
+ const runesExplorerUrl = useRunesTokenInfoExplorerUrl(tokenSummary.runeInfo.runeid)
109
113
 
110
114
  const onClickMint = () => {
111
115
  nav.navToUrl(inscribeUrl)
@@ -125,6 +129,10 @@ export function useRunesTokenScreenLogic() {
125
129
  }
126
130
  }
127
131
 
132
+ const onClickViewOnExplorer = () => {
133
+ nav.navToUrl(runesExplorerUrl)
134
+ }
135
+
128
136
  return {
129
137
  runeid,
130
138
  tokenSummary,
@@ -145,5 +153,6 @@ export function useRunesTokenScreenLogic() {
145
153
 
146
154
  enableTrade,
147
155
  onClickTrade,
156
+ onClickViewOnExplorer,
148
157
  }
149
158
  }
@@ -1,6 +1,6 @@
1
1
  import { Inscription, SignedData, SignPsbtParams, ToSignData } from '@unisat/wallet-shared'
2
2
  import { useEffect, useRef, useState } from 'react'
3
- import { useI18n, useNavigation, useTools } from 'src/context'
3
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
4
4
  import {
5
5
  useCurrentAccount,
6
6
  useFeeRateBar,
@@ -33,13 +33,21 @@ export function useSendAlkanesNFTScreenLogic() {
33
33
  })
34
34
 
35
35
  const [error, setError] = useState('')
36
+ const [enableRBF, setEnableRBF] = useState(true)
36
37
 
37
38
  const currentAccount = useCurrentAccount()
38
39
 
39
40
  const tools = useTools()
41
+ const wallet = useWallet()
40
42
 
41
43
  const { feeRate } = useFeeRateBar()
42
44
 
45
+ useEffect(() => {
46
+ wallet.getEnableRBF().then(enableRBF => {
47
+ setEnableRBF(enableRBF)
48
+ })
49
+ }, [wallet])
50
+
43
51
  useEffect(() => {
44
52
  setError('')
45
53
  setDisabled(true)
@@ -71,7 +79,14 @@ export function useSendAlkanesNFTScreenLogic() {
71
79
  const onCreateTxHandleConfirm = async () => {
72
80
  tools.showLoading(true)
73
81
  try {
74
- const toSignData = await prepareSendAlkanes(toInfo, alkanesInfo.alkaneid, '1', feeRate, 'nft')
82
+ const toSignData = await prepareSendAlkanes(
83
+ toInfo,
84
+ alkanesInfo.alkaneid,
85
+ '1',
86
+ feeRate,
87
+ 'nft',
88
+ enableRBF
89
+ )
75
90
  if (toSignData) {
76
91
  transferData.current.toSignData = toSignData
77
92
  setStep(1)
@@ -118,14 +133,21 @@ export function useSendAlkanesNFTScreenLogic() {
118
133
  },
119
134
  }
120
135
 
136
+ const onEnableRBFChange = (value: boolean) => {
137
+ setEnableRBF(value)
138
+ wallet.setEnableRBF(value)
139
+ }
140
+
121
141
  return {
122
142
  step,
123
143
  t,
124
144
  alkanesInfo,
125
145
  toInfo,
146
+ enableRBF,
126
147
  disabled,
127
148
  error,
128
149
  setToInfo,
150
+ setEnableRBF: onEnableRBFChange,
129
151
 
130
152
  onCreateTxHandleConfirm,
131
153
  onCreateTxHandleBack,
@@ -39,6 +39,7 @@ export function useSendAlkanesScreenLogic() {
39
39
 
40
40
  const [availableBalance, setAvailableBalance] = useState(tokenBalance.amount)
41
41
  const [error, setError] = useState('')
42
+ const [enableRBF, setEnableRBF] = useState(true)
42
43
 
43
44
  const totalBalanceStr = useMemo(() => {
44
45
  return bnUtils.toDecimalAmount(tokenBalance.amount, tokenBalance.divisibility)
@@ -107,6 +108,12 @@ export function useSendAlkanesScreenLogic() {
107
108
 
108
109
  const wallet = useWallet()
109
110
 
111
+ useEffect(() => {
112
+ wallet.getEnableRBF().then(enableRBF => {
113
+ setEnableRBF(enableRBF)
114
+ })
115
+ }, [wallet])
116
+
110
117
  const prepareSendAlkanes = usePrepareSendAlkanesCallback()
111
118
  const pushBitcoinTx = usePushBitcoinTxCallback()
112
119
 
@@ -122,7 +129,8 @@ export function useSendAlkanesScreenLogic() {
122
129
  tokenBalance.alkaneid,
123
130
  bnUtils.fromDecimalAmount(inputAmount, tokenBalance.divisibility),
124
131
  feeRate,
125
- 'ft'
132
+ 'ft',
133
+ enableRBF
126
134
  )
127
135
  if (toSignData) {
128
136
  transferData.current.toSignData = toSignData
@@ -164,6 +172,12 @@ export function useSendAlkanesScreenLogic() {
164
172
  const onSignPsbtHandleBack = () => {
165
173
  setStep(SendAlkanesScreenStep.CREATE_TX)
166
174
  }
175
+
176
+ const onEnableRBFChange = (value: boolean) => {
177
+ setEnableRBF(value)
178
+ wallet.setEnableRBF(value)
179
+ }
180
+
167
181
  return {
168
182
  step,
169
183
  t,
@@ -174,12 +188,14 @@ export function useSendAlkanesScreenLogic() {
174
188
  availableBalanceStr,
175
189
 
176
190
  inputAmount,
191
+ enableRBF,
177
192
  disabled,
178
193
  error,
179
194
 
180
195
  // actions
181
196
  setToInfo,
182
197
  setInputAmount,
198
+ setEnableRBF: onEnableRBFChange,
183
199
  onClickBack,
184
200
  onClickNext,
185
201
 
@@ -1,15 +1,12 @@
1
1
  import { Inscription } from '@unisat/wallet-shared'
2
2
  import { useEffect, useMemo, useState } from 'react'
3
+ import { useI18n, useNavigation, useTools, useWallet } from '../context'
3
4
  import {
4
5
  useFeeRateBar,
5
6
  useFetchUtxosCallback,
6
- useI18n,
7
- useNavigation,
8
7
  useOrdinalsTx,
9
8
  usePrepareSendOrdinalsInscriptionCallback,
10
- useTools,
11
- useWallet,
12
- } from '..'
9
+ } from '../hooks'
13
10
  import { getAddressUtxoDust, isValidAddress } from '../utils/bitcoin-utils'
14
11
 
15
12
  export function useSendOrdinalsInscriptionScreenLogic() {
@@ -39,15 +36,27 @@ export function useSendOrdinalsInscriptionScreenLogic() {
39
36
  const defaultOutputValue = inscription ? inscription.outputValue : 10000
40
37
 
41
38
  const [outputValue, setOutputValue] = useState(defaultOutputValue)
39
+ const [enableRBF, setEnableRBF] = useState(true)
42
40
  const [inscriptions, setInscriptions] = useState<Inscription[]>([])
43
41
 
44
42
  const wallet = useWallet()
43
+ useEffect(() => {
44
+ wallet.getEnableRBF().then(enableRBF => {
45
+ setEnableRBF(enableRBF)
46
+ })
47
+ }, [wallet])
48
+
45
49
  useEffect(() => {
46
50
  wallet.getInscriptionUtxoDetail(inscription.inscriptionId).then(v => {
47
51
  setInscriptions(v.inscriptions)
48
52
  })
49
53
  }, [])
50
54
 
55
+ const onEnableRBFChange = (value: boolean) => {
56
+ setEnableRBF(value)
57
+ wallet.setEnableRBF(value)
58
+ }
59
+
51
60
  const minOutputValue = useMemo(() => {
52
61
  if (toInfo.address) {
53
62
  return getAddressUtxoDust(toInfo.address)
@@ -110,6 +119,7 @@ export function useSendOrdinalsInscriptionScreenLogic() {
110
119
  inscriptionId: inscription.inscriptionId,
111
120
  feeRate,
112
121
  outputValue,
122
+ enableRBF,
113
123
  })
114
124
  .then(toSignData => {
115
125
  nav.navigate('TxConfirmScreen', { toSignData })
@@ -125,6 +135,8 @@ export function useSendOrdinalsInscriptionScreenLogic() {
125
135
  onAddressInputChange,
126
136
  toInfo,
127
137
  outputValue,
138
+ enableRBF,
139
+ setEnableRBF: onEnableRBFChange,
128
140
  minOutputValue,
129
141
  defaultOutputValue,
130
142
  setOutputValue,
@@ -2,7 +2,7 @@ import { bnUtils } from '@unisat/base-utils'
2
2
  import { Inscription } from '@unisat/wallet-shared'
3
3
  import BigNumber from 'bignumber.js'
4
4
  import { useEffect, useMemo, useState } from 'react'
5
- import { useI18n, useNavigation, useTools } from 'src/context'
5
+ import { useI18n, useNavigation, useTools, useWallet } from 'src/context'
6
6
  import {
7
7
  useCurrentAccount,
8
8
  useFeeRateBar,
@@ -42,6 +42,7 @@ export function useSendRunesScreenLogic() {
42
42
 
43
43
  const currentAccount = useCurrentAccount()
44
44
  const [outputValue, setOutputValue] = useState(defaultOutputValue)
45
+ const [enableRBF, setEnableRBF] = useState(true)
45
46
  const minOutputValue = useMemo(() => {
46
47
  if (toInfo.address) {
47
48
  const dust1 = getAddressUtxoDust(currentAccount.address)
@@ -53,6 +54,7 @@ export function useSendRunesScreenLogic() {
53
54
  }, [toInfo.address, currentAccount.address])
54
55
 
55
56
  const fetchUtxos = useFetchUtxosCallback()
57
+ const wallet = useWallet()
56
58
 
57
59
  const fetchAssetUtxosRunes = useFetchAssetUtxosRunesCallback()
58
60
  const tools = useTools()
@@ -83,6 +85,12 @@ export function useSendRunesScreenLogic() {
83
85
 
84
86
  const { feeRate } = useFeeRateBar()
85
87
 
88
+ useEffect(() => {
89
+ wallet.getEnableRBF().then(enableRBF => {
90
+ setEnableRBF(enableRBF)
91
+ })
92
+ }, [wallet])
93
+
86
94
  useEffect(() => {
87
95
  setError('')
88
96
  setDisabled(true)
@@ -130,6 +138,12 @@ export function useSendRunesScreenLogic() {
130
138
  const onClickBack = () => {
131
139
  nav.goBack()
132
140
  }
141
+
142
+ const onEnableRBFChange = (value: boolean) => {
143
+ setEnableRBF(value)
144
+ wallet.setEnableRBF(value)
145
+ }
146
+
133
147
  const onClickNext = () => {
134
148
  const runeAmount = bnUtils.fromDecimalAmount(inputAmount, runeInfo.divisibility)
135
149
  prepareSendRunes({
@@ -138,6 +152,7 @@ export function useSendRunesScreenLogic() {
138
152
  runeAmount: runeAmount,
139
153
  outputValue: outputValue,
140
154
  feeRate,
155
+ enableRBF,
141
156
  })
142
157
  .then(toSignData => {
143
158
  nav.navigate('TxConfirmScreen', { toSignData })
@@ -163,6 +178,8 @@ export function useSendRunesScreenLogic() {
163
178
  defaultOutputValue,
164
179
  minOutputValue,
165
180
  setOutputValue,
181
+ enableRBF,
182
+ setEnableRBF: onEnableRBFChange,
166
183
  t,
167
184
 
168
185
  // actions
@@ -1,5 +1,11 @@
1
1
  import { KeyringType } from '@unisat/keyring-service/types'
2
- import { ADDRESS_TYPES, FEEDBACK_URL, PlatformEnv } from '@unisat/wallet-shared'
2
+ import {
3
+ ADDRESS_TYPES,
4
+ AccountSignMethod,
5
+ FEEDBACK_URL,
6
+ PlatformEnv,
7
+ getAccountCapabilities,
8
+ } from '@unisat/wallet-shared'
3
9
  import { useMemo, useState } from 'react'
4
10
  import { useDevice, useI18n, useNavigation, useTools, useWallet } from 'src/context'
5
11
  import { useChain, useCurrentAccount, useCurrentKeyring, useVersionInfo } from 'src/hooks'
@@ -36,6 +42,11 @@ export function useSettingsTabScreenLogic() {
36
42
  return currentKeyring.hdPath !== '' && item.hdPath !== currentKeyring.hdPath
37
43
  }, [currentKeyring])
38
44
 
45
+ const currentKeyringCapabilities = useMemo(
46
+ () => getAccountCapabilities({ type: currentKeyring.type }),
47
+ [currentKeyring.type]
48
+ )
49
+
39
50
  const settings_connectedSites: SettingsItemType = useMemo(() => {
40
51
  const value = connected ? t('connected') : t('not_connected')
41
52
  return {
@@ -69,7 +80,11 @@ export function useSettingsTabScreenLogic() {
69
80
  let value = ''
70
81
  const item = ADDRESS_TYPES[currentKeyring.addressType]
71
82
  const hdPath = currentKeyring.hdPath || item.hdPath
72
- if (currentKeyring.type === KeyringType.SimpleKeyring) {
83
+ if (
84
+ currentKeyring.type === KeyringType.SimpleKeyring ||
85
+ currentKeyringCapabilities.signMethod === AccountSignMethod.External ||
86
+ !currentKeyringCapabilities.canChangeAddressType
87
+ ) {
73
88
  value = `${item.name}`
74
89
  } else {
75
90
  value = `${item.name} (${hdPath}/${currentAccount.index})`
@@ -93,7 +108,7 @@ export function useSettingsTabScreenLogic() {
93
108
  nav.navigate('AddressTypeScreen')
94
109
  },
95
110
  }
96
- }, [t, isCustomHdPath])
111
+ }, [t, isCustomHdPath, currentKeyring, currentAccount.index, currentKeyringCapabilities])
97
112
 
98
113
  const settings_advanced = useMemo(() => {
99
114
  return {
@@ -1,9 +1,14 @@
1
- import { KeyringType } from '@unisat/keyring-service/types'
2
- import { SignedMessage, SignState, ToSignMessage, WebsiteResult } from '@unisat/wallet-shared'
1
+ import {
2
+ AccountSignMethod,
3
+ SignedMessage,
4
+ SignState,
5
+ ToSignMessage,
6
+ WebsiteResult,
7
+ } from '@unisat/wallet-shared'
3
8
  import logger from 'loglevel'
4
9
  import { useEffect, useMemo, useRef, useState } from 'react'
5
10
  import { useApproval, useI18n, useTools, useWallet } from 'src/context'
6
- import { useCurrentAccount } from 'src/hooks'
11
+ import { useCurrentAccountCapabilities } from 'src/hooks'
7
12
  import { shortAddress, useAsyncEffect } from 'src/utils/ui-utils'
8
13
  export interface SignMessageProps {
9
14
  header?: React.ReactNode
@@ -36,11 +41,11 @@ export function useSignMessageLogic(props: SignMessageProps) {
36
41
  const [loading, setLoading] = useState(false)
37
42
  const [isKeystoneSigning, setIsKeystoneSigning] = useState(false)
38
43
  const [isColdWalletSigning, setIsColdWalletSigning] = useState(false)
44
+ const [readonlySignature, setReadonlySignature] = useState('')
39
45
 
40
46
  const wallet = useWallet()
41
47
  const tools = useTools()
42
- const currentAccount = useCurrentAccount()
43
- const keyringType = currentAccount.type
48
+ const accountCapabilities = useCurrentAccountCapabilities()
44
49
 
45
50
  const { t } = useI18n()
46
51
 
@@ -65,15 +70,12 @@ export function useSignMessageLogic(props: SignMessageProps) {
65
70
  return
66
71
  }
67
72
 
68
- if (
69
- keyringType === KeyringType.KeystoneKeyring ||
70
- keyringType === KeyringType.ColdWalletKeyring
71
- ) {
73
+ if (accountCapabilities.signMethod !== AccountSignMethod.Local) {
72
74
  return
73
75
  }
74
76
 
75
77
  setAllowQuickMultiSign(websiteResult.allowQuickMultiSign && toSignMessages.length > 1)
76
- }, [websiteResult, keyringType])
78
+ }, [websiteResult, accountCapabilities, toSignMessages.length])
77
79
 
78
80
  useAsyncEffect(async () => {
79
81
  const website = session?.origin
@@ -190,12 +192,28 @@ export function useSignMessageLogic(props: SignMessageProps) {
190
192
  }
191
193
 
192
194
  const onNextStep = () => {
193
- if (keyringType === KeyringType.KeystoneKeyring) {
194
- setIsKeystoneSigning(true)
195
- } else if (keyringType === KeyringType.ColdWalletKeyring) {
196
- setIsColdWalletSigning(true)
197
- } else {
198
- localSign()
195
+ switch (accountCapabilities.signMethod) {
196
+ case AccountSignMethod.Keystone:
197
+ setIsKeystoneSigning(true)
198
+ return
199
+ case AccountSignMethod.ColdWallet:
200
+ setIsColdWalletSigning(true)
201
+ return
202
+ case AccountSignMethod.External:
203
+ if (!readonlySignature) {
204
+ tools.toastError(t('please_enter_your_signature'))
205
+ return
206
+ }
207
+
208
+ onSignedData({ signature: readonlySignature }, signingTxIndex)
209
+ setReadonlySignature('')
210
+ return
211
+ case AccountSignMethod.Local:
212
+ localSign()
213
+ return
214
+ case AccountSignMethod.None:
215
+ default:
216
+ tools.toastError(t('not_supported'))
199
217
  }
200
218
  }
201
219
 
@@ -297,6 +315,9 @@ export function useSignMessageLogic(props: SignMessageProps) {
297
315
  onColdWalletSigningSuccess,
298
316
  onColdWalletSigningBack,
299
317
 
318
+ readonlySignature,
319
+ setReadonlySignature,
320
+
300
321
  onDisclaimerModalClose,
301
322
  }
302
323
  }
@@ -1,6 +1,7 @@
1
1
  import { numUtils } from '@unisat/base-utils'
2
- import { KeyringType, ToSignInput } from '@unisat/keyring-service/types'
2
+ import { ToSignInput } from '@unisat/keyring-service/types'
3
3
  import {
4
+ AccountSignMethod,
4
5
  ApprovalSession,
5
6
  ContractResult,
6
7
  DecodedPsbt,
@@ -14,7 +15,7 @@ import {
14
15
  import logger from 'loglevel'
15
16
  import { useEffect, useMemo, useRef, useState } from 'react'
16
17
  import { useApproval, useI18n, useTools, useWallet } from 'src/context'
17
- import { useCurrentAccount } from 'src/hooks'
18
+ import { useCurrentAccountCapabilities } from 'src/hooks'
18
19
  import { useAsyncEffect } from 'src/utils/ui-utils'
19
20
 
20
21
  interface InscriptionInfo {
@@ -87,13 +88,13 @@ export function useSignPsbtLogic(props: SignPsbtProps) {
87
88
  const [isPsbtRiskPopoverVisible, setIsPsbtRiskPopoverVisible] = useState(false)
88
89
  const [isKeystoneSigning, setIsKeystoneSigning] = useState(false)
89
90
  const [isColdWalletSigning, setIsColdWalletSigning] = useState(false)
91
+ const [readonlySignedPsbtHex, setReadonlySignedPsbtHex] = useState('')
90
92
 
91
93
  const [contractPopoverData, setContractPopoverData] = useState(undefined)
92
94
 
93
95
  const wallet = useWallet()
94
96
  const tools = useTools()
95
- const currentAccount = useCurrentAccount()
96
- const keyringType = currentAccount.type
97
+ const accountCapabilities = useCurrentAccountCapabilities()
97
98
 
98
99
  const { t } = useI18n()
99
100
 
@@ -122,15 +123,12 @@ export function useSignPsbtLogic(props: SignPsbtProps) {
122
123
  return
123
124
  }
124
125
 
125
- if (
126
- keyringType === KeyringType.KeystoneKeyring ||
127
- keyringType === KeyringType.ColdWalletKeyring
128
- ) {
126
+ if (accountCapabilities.signMethod !== AccountSignMethod.Local) {
129
127
  return
130
128
  }
131
129
 
132
130
  setAllowQuickMultiSign(websiteResult.allowQuickMultiSign && toSignDatas.length > 1)
133
- }, [websiteResult, keyringType])
131
+ }, [websiteResult, accountCapabilities])
134
132
 
135
133
  useAsyncEffect(async () => {
136
134
  const website = session?.origin
@@ -374,12 +372,28 @@ export function useSignPsbtLogic(props: SignPsbtProps) {
374
372
  }
375
373
 
376
374
  const onNextStep = () => {
377
- if (keyringType === KeyringType.KeystoneKeyring) {
378
- setIsKeystoneSigning(true)
379
- } else if (keyringType === KeyringType.ColdWalletKeyring) {
380
- setIsColdWalletSigning(true)
381
- } else {
382
- localSign()
375
+ switch (accountCapabilities.signMethod) {
376
+ case AccountSignMethod.Keystone:
377
+ setIsKeystoneSigning(true)
378
+ return
379
+ case AccountSignMethod.ColdWallet:
380
+ setIsColdWalletSigning(true)
381
+ return
382
+ case AccountSignMethod.External:
383
+ if (!readonlySignedPsbtHex) {
384
+ tools.toastError(t('invalid_psbt'))
385
+ return
386
+ }
387
+
388
+ onSignedData({ psbtHex: readonlySignedPsbtHex }, signingTxIndex)
389
+ setReadonlySignedPsbtHex('')
390
+ return
391
+ case AccountSignMethod.Local:
392
+ localSign()
393
+ return
394
+ case AccountSignMethod.None:
395
+ default:
396
+ tools.toastError(t('not_supported'))
383
397
  }
384
398
  }
385
399
 
@@ -481,6 +495,8 @@ export function useSignPsbtLogic(props: SignPsbtProps) {
481
495
  toSignDatas,
482
496
  currentToSignData,
483
497
  currentDecodedPsbt,
498
+ readonlySignedPsbtHex,
499
+ setReadonlySignedPsbtHex,
484
500
 
485
501
  // state
486
502
  networkFee,
@@ -27,6 +27,7 @@ export function useSplitOrdinalsInscriptionScreenLogic() {
27
27
  const account = useCurrentAccount()
28
28
  const minOutputValue = getAddressUtxoDust(account.address)
29
29
  const [outputValue, setOutputValue] = useState(defaultOutputValue)
30
+ const [enableRBF, setEnableRBF] = useState(true)
30
31
 
31
32
  const { feeRate } = useFeeRateBar()
32
33
 
@@ -34,12 +35,23 @@ export function useSplitOrdinalsInscriptionScreenLogic() {
34
35
 
35
36
  const [splitedCount, setSplitedCount] = useState(0)
36
37
  const wallet = useWallet()
38
+ useEffect(() => {
39
+ wallet.getEnableRBF().then(enableRBF => {
40
+ setEnableRBF(enableRBF)
41
+ })
42
+ }, [wallet])
43
+
37
44
  useEffect(() => {
38
45
  wallet.getInscriptionUtxoDetail(props.inscription.inscriptionId).then(v => {
39
46
  setInscriptions(v.inscriptions)
40
47
  })
41
48
  }, [])
42
49
 
50
+ const onEnableRBFChange = (value: boolean) => {
51
+ setEnableRBF(value)
52
+ wallet.setEnableRBF(value)
53
+ }
54
+
43
55
  useEffect(() => {
44
56
  setDisabled(true)
45
57
  setError('')
@@ -71,7 +83,7 @@ export function useSplitOrdinalsInscriptionScreenLogic() {
71
83
  }
72
84
 
73
85
  const onClickNext = () => {
74
- createSplitTx({ inscriptionId: inscription.inscriptionId, feeRate, outputValue })
86
+ createSplitTx({ inscriptionId: inscription.inscriptionId, feeRate, outputValue, enableRBF })
75
87
  .then(toSignData => {
76
88
  nav.navigate('TxConfirmScreen', { toSignData })
77
89
  })
@@ -86,6 +98,8 @@ export function useSplitOrdinalsInscriptionScreenLogic() {
86
98
  inscriptions,
87
99
  minOutputValue,
88
100
  splitedCount,
101
+ enableRBF,
102
+ setEnableRBF: onEnableRBFChange,
89
103
  error,
90
104
  disabled,
91
105
  onOutputValueChange,
@@ -12,6 +12,7 @@ import {
12
12
  useNavigation,
13
13
  usePrepareSendBTCCallback,
14
14
  useTools,
15
+ useWallet,
15
16
  useUiTxCreateScreen,
16
17
  useUpdateUiTxCreateScreen,
17
18
  useWalletConfig,
@@ -32,12 +33,14 @@ export function useTxCreateScreenLogic() {
32
33
 
33
34
  const toInfo = uiState.toInfo
34
35
  const inputAmount = uiState.inputAmount
36
+ const enableRBF = uiState.enableRBF
35
37
  const feeRate = feeRateBarState.feeRate
36
38
 
37
39
  const [error, setError] = useState('')
38
40
 
39
41
  const [autoAdjust, setAutoAdjust] = useState(false)
40
42
  const fetchUtxos = useFetchUtxosCallback()
43
+ const wallet = useWallet()
41
44
 
42
45
  const tools = useTools()
43
46
  useEffect(() => {
@@ -47,6 +50,12 @@ export function useTxCreateScreenLogic() {
47
50
  })
48
51
  }, [])
49
52
 
53
+ useEffect(() => {
54
+ wallet.getEnableRBF().then(enableRBF => {
55
+ setUiState({ enableRBF })
56
+ })
57
+ }, [wallet, setUiState])
58
+
50
59
  const prepareSendBTC = usePrepareSendBTCCallback()
51
60
 
52
61
  const toSatoshis = useMemo(() => {
@@ -118,8 +127,13 @@ export function useTxCreateScreenLogic() {
118
127
  setUiState({ inputAmount: availableAmount.toString() })
119
128
  }
120
129
 
130
+ const onRBFChange = (value: boolean) => {
131
+ setUiState({ enableRBF: value })
132
+ wallet.setEnableRBF(value)
133
+ }
134
+
121
135
  const onClickNext = () => {
122
- prepareSendBTC({ toAddressInfo: toInfo, toAmount: toSatoshis, feeRate })
136
+ prepareSendBTC({ toAddressInfo: toInfo, toAmount: toSatoshis, feeRate, enableRBF })
123
137
  .then(toSignData => {
124
138
  nav.navigate('TxConfirmScreen', {
125
139
  toSignData,
@@ -142,6 +156,8 @@ export function useTxCreateScreenLogic() {
142
156
  inputAmount,
143
157
  onAmountInputChange,
144
158
  onAmountMaxClick,
159
+ enableRBF,
160
+ onRBFChange,
145
161
 
146
162
  showUnavailable,
147
163
  availableAmount,