@reown/appkit-react-native 2.0.1 → 2.0.3

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 (185) hide show
  1. package/lib/commonjs/AppKit.js +20 -6
  2. package/lib/commonjs/AppKit.js.map +1 -1
  3. package/lib/commonjs/hooks/useAccount.js +68 -5
  4. package/lib/commonjs/hooks/useAccount.js.map +1 -1
  5. package/lib/commonjs/hooks/useAppKit.js +41 -9
  6. package/lib/commonjs/hooks/useAppKit.js.map +1 -1
  7. package/lib/commonjs/hooks/useAppKitContext.js +46 -0
  8. package/lib/commonjs/hooks/useAppKitContext.js.map +1 -0
  9. package/lib/commonjs/hooks/useAppKitEvents.js +64 -4
  10. package/lib/commonjs/hooks/useAppKitEvents.js.map +1 -1
  11. package/lib/commonjs/hooks/useAppKitLogs.js +2 -8
  12. package/lib/commonjs/hooks/useAppKitLogs.js.map +1 -1
  13. package/lib/commonjs/hooks/useAppKitState.js +35 -2
  14. package/lib/commonjs/hooks/useAppKitState.js.map +1 -1
  15. package/lib/commonjs/hooks/useAppKitTheme.js +74 -0
  16. package/lib/commonjs/hooks/useAppKitTheme.js.map +1 -0
  17. package/lib/commonjs/hooks/useProvider.js +3 -4
  18. package/lib/commonjs/hooks/useProvider.js.map +1 -1
  19. package/lib/commonjs/hooks/useWalletInfo.js +33 -2
  20. package/lib/commonjs/hooks/useWalletInfo.js.map +1 -1
  21. package/lib/commonjs/index.js +7 -0
  22. package/lib/commonjs/index.js.map +1 -1
  23. package/lib/commonjs/modal/w3m-modal/index.js +7 -7
  24. package/lib/commonjs/modal/w3m-modal/index.js.map +1 -1
  25. package/lib/commonjs/modal/w3m-modal/styles.js +2 -1
  26. package/lib/commonjs/modal/w3m-modal/styles.js.map +1 -1
  27. package/lib/commonjs/partials/w3m-connecting-body/index.js +2 -0
  28. package/lib/commonjs/partials/w3m-connecting-body/index.js.map +1 -1
  29. package/lib/commonjs/partials/w3m-connecting-mobile/components/StoreLink.js +4 -0
  30. package/lib/commonjs/partials/w3m-connecting-mobile/components/StoreLink.js.map +1 -1
  31. package/lib/commonjs/partials/w3m-connecting-qrcode/index.js +5 -1
  32. package/lib/commonjs/partials/w3m-connecting-qrcode/index.js.map +1 -1
  33. package/lib/commonjs/partials/w3m-header/index.js +1 -0
  34. package/lib/commonjs/partials/w3m-header/index.js.map +1 -1
  35. package/lib/commonjs/partials/w3m-header/styles.js +3 -0
  36. package/lib/commonjs/partials/w3m-header/styles.js.map +1 -1
  37. package/lib/commonjs/partials/w3m-send-input-token/index.js +6 -3
  38. package/lib/commonjs/partials/w3m-send-input-token/index.js.map +1 -1
  39. package/lib/commonjs/partials/w3m-swap-input/index.js +6 -3
  40. package/lib/commonjs/partials/w3m-swap-input/index.js.map +1 -1
  41. package/lib/commonjs/views/w3m-account-default-view/index.js +2 -1
  42. package/lib/commonjs/views/w3m-account-default-view/index.js.map +1 -1
  43. package/lib/commonjs/views/w3m-connecting-external-view/index.js +4 -8
  44. package/lib/commonjs/views/w3m-connecting-external-view/index.js.map +1 -1
  45. package/lib/commonjs/views/w3m-connecting-view/index.js +18 -12
  46. package/lib/commonjs/views/w3m-connecting-view/index.js.map +1 -1
  47. package/lib/commonjs/views/w3m-onramp-settings-view/index.js +2 -0
  48. package/lib/commonjs/views/w3m-onramp-settings-view/index.js.map +1 -1
  49. package/lib/commonjs/views/w3m-onramp-view/index.js +3 -2
  50. package/lib/commonjs/views/w3m-onramp-view/index.js.map +1 -1
  51. package/lib/commonjs/views/w3m-swap-view/components/select-token-modal/index.js +2 -1
  52. package/lib/commonjs/views/w3m-swap-view/components/select-token-modal/index.js.map +1 -1
  53. package/lib/commonjs/views/w3m-swap-view/index.js +4 -2
  54. package/lib/commonjs/views/w3m-swap-view/index.js.map +1 -1
  55. package/lib/commonjs/views/w3m-wallet-send-view/index.js +2 -1
  56. package/lib/commonjs/views/w3m-wallet-send-view/index.js.map +1 -1
  57. package/lib/module/AppKit.js +20 -6
  58. package/lib/module/AppKit.js.map +1 -1
  59. package/lib/module/hooks/useAccount.js +69 -5
  60. package/lib/module/hooks/useAccount.js.map +1 -1
  61. package/lib/module/hooks/useAppKit.js +43 -10
  62. package/lib/module/hooks/useAppKit.js.map +1 -1
  63. package/lib/module/hooks/useAppKitContext.js +42 -0
  64. package/lib/module/hooks/useAppKitContext.js.map +1 -0
  65. package/lib/module/hooks/useAppKitEvents.js +65 -4
  66. package/lib/module/hooks/useAppKitEvents.js.map +1 -1
  67. package/lib/module/hooks/useAppKitLogs.js +3 -9
  68. package/lib/module/hooks/useAppKitLogs.js.map +1 -1
  69. package/lib/module/hooks/useAppKitState.js +36 -2
  70. package/lib/module/hooks/useAppKitState.js.map +1 -1
  71. package/lib/module/hooks/useAppKitTheme.js +71 -0
  72. package/lib/module/hooks/useAppKitTheme.js.map +1 -0
  73. package/lib/module/hooks/useProvider.js +3 -4
  74. package/lib/module/hooks/useProvider.js.map +1 -1
  75. package/lib/module/hooks/useWalletInfo.js +34 -2
  76. package/lib/module/hooks/useWalletInfo.js.map +1 -1
  77. package/lib/module/index.js +1 -0
  78. package/lib/module/index.js.map +1 -1
  79. package/lib/module/modal/w3m-modal/index.js +7 -7
  80. package/lib/module/modal/w3m-modal/index.js.map +1 -1
  81. package/lib/module/modal/w3m-modal/styles.js +2 -1
  82. package/lib/module/modal/w3m-modal/styles.js.map +1 -1
  83. package/lib/module/partials/w3m-connecting-body/index.js +2 -0
  84. package/lib/module/partials/w3m-connecting-body/index.js.map +1 -1
  85. package/lib/module/partials/w3m-connecting-mobile/components/StoreLink.js +4 -0
  86. package/lib/module/partials/w3m-connecting-mobile/components/StoreLink.js.map +1 -1
  87. package/lib/module/partials/w3m-connecting-qrcode/index.js +5 -1
  88. package/lib/module/partials/w3m-connecting-qrcode/index.js.map +1 -1
  89. package/lib/module/partials/w3m-header/index.js +1 -0
  90. package/lib/module/partials/w3m-header/index.js.map +1 -1
  91. package/lib/module/partials/w3m-header/styles.js +3 -0
  92. package/lib/module/partials/w3m-header/styles.js.map +1 -1
  93. package/lib/module/partials/w3m-send-input-token/index.js +6 -3
  94. package/lib/module/partials/w3m-send-input-token/index.js.map +1 -1
  95. package/lib/module/partials/w3m-swap-input/index.js +6 -3
  96. package/lib/module/partials/w3m-swap-input/index.js.map +1 -1
  97. package/lib/module/views/w3m-account-default-view/index.js +2 -1
  98. package/lib/module/views/w3m-account-default-view/index.js.map +1 -1
  99. package/lib/module/views/w3m-connecting-external-view/index.js +4 -8
  100. package/lib/module/views/w3m-connecting-external-view/index.js.map +1 -1
  101. package/lib/module/views/w3m-connecting-view/index.js +19 -13
  102. package/lib/module/views/w3m-connecting-view/index.js.map +1 -1
  103. package/lib/module/views/w3m-onramp-settings-view/index.js +2 -0
  104. package/lib/module/views/w3m-onramp-settings-view/index.js.map +1 -1
  105. package/lib/module/views/w3m-onramp-view/index.js +3 -2
  106. package/lib/module/views/w3m-onramp-view/index.js.map +1 -1
  107. package/lib/module/views/w3m-swap-view/components/select-token-modal/index.js +2 -1
  108. package/lib/module/views/w3m-swap-view/components/select-token-modal/index.js.map +1 -1
  109. package/lib/module/views/w3m-swap-view/index.js +4 -2
  110. package/lib/module/views/w3m-swap-view/index.js.map +1 -1
  111. package/lib/module/views/w3m-wallet-send-view/index.js +2 -1
  112. package/lib/module/views/w3m-wallet-send-view/index.js.map +1 -1
  113. package/lib/typescript/AppKit.d.ts +9 -2
  114. package/lib/typescript/AppKit.d.ts.map +1 -1
  115. package/lib/typescript/AppKitContext.d.ts +2 -2
  116. package/lib/typescript/AppKitContext.d.ts.map +1 -1
  117. package/lib/typescript/hooks/useAccount.d.ts +57 -33
  118. package/lib/typescript/hooks/useAccount.d.ts.map +1 -1
  119. package/lib/typescript/hooks/useAppKit.d.ts +42 -0
  120. package/lib/typescript/hooks/useAppKit.d.ts.map +1 -1
  121. package/lib/typescript/hooks/useAppKitContext.d.ts +27 -0
  122. package/lib/typescript/hooks/useAppKitContext.d.ts.map +1 -0
  123. package/lib/typescript/hooks/useAppKitEvents.d.ts +66 -0
  124. package/lib/typescript/hooks/useAppKitEvents.d.ts.map +1 -1
  125. package/lib/typescript/hooks/useAppKitLogs.d.ts.map +1 -1
  126. package/lib/typescript/hooks/useAppKitState.d.ts +32 -0
  127. package/lib/typescript/hooks/useAppKitState.d.ts.map +1 -1
  128. package/lib/typescript/hooks/useAppKitTheme.d.ts +59 -0
  129. package/lib/typescript/hooks/useAppKitTheme.d.ts.map +1 -0
  130. package/lib/typescript/hooks/useProvider.d.ts +1 -4
  131. package/lib/typescript/hooks/useProvider.d.ts.map +1 -1
  132. package/lib/typescript/hooks/useWalletInfo.d.ts +31 -0
  133. package/lib/typescript/hooks/useWalletInfo.d.ts.map +1 -1
  134. package/lib/typescript/index.d.ts +3 -2
  135. package/lib/typescript/index.d.ts.map +1 -1
  136. package/lib/typescript/modal/w3m-modal/index.d.ts +9 -1
  137. package/lib/typescript/modal/w3m-modal/index.d.ts.map +1 -1
  138. package/lib/typescript/modal/w3m-modal/styles.d.ts +1 -0
  139. package/lib/typescript/modal/w3m-modal/styles.d.ts.map +1 -1
  140. package/lib/typescript/partials/w3m-connecting-body/index.d.ts.map +1 -1
  141. package/lib/typescript/partials/w3m-connecting-qrcode/index.d.ts.map +1 -1
  142. package/lib/typescript/partials/w3m-header/index.d.ts.map +1 -1
  143. package/lib/typescript/partials/w3m-header/styles.d.ts +3 -0
  144. package/lib/typescript/partials/w3m-header/styles.d.ts.map +1 -1
  145. package/lib/typescript/partials/w3m-send-input-token/index.d.ts +2 -1
  146. package/lib/typescript/partials/w3m-send-input-token/index.d.ts.map +1 -1
  147. package/lib/typescript/partials/w3m-swap-input/index.d.ts +2 -1
  148. package/lib/typescript/partials/w3m-swap-input/index.d.ts.map +1 -1
  149. package/lib/typescript/views/w3m-account-default-view/index.d.ts.map +1 -1
  150. package/lib/typescript/views/w3m-connecting-external-view/index.d.ts.map +1 -1
  151. package/lib/typescript/views/w3m-connecting-view/index.d.ts.map +1 -1
  152. package/lib/typescript/views/w3m-onramp-settings-view/index.d.ts.map +1 -1
  153. package/lib/typescript/views/w3m-onramp-view/index.d.ts.map +1 -1
  154. package/lib/typescript/views/w3m-swap-view/index.d.ts.map +1 -1
  155. package/lib/typescript/views/w3m-wallet-send-view/index.d.ts.map +1 -1
  156. package/package.json +5 -4
  157. package/src/AppKit.ts +27 -7
  158. package/src/AppKitContext.tsx +1 -1
  159. package/src/hooks/useAccount.ts +93 -5
  160. package/src/hooks/useAppKit.ts +45 -12
  161. package/src/hooks/useAppKitContext.ts +43 -0
  162. package/src/hooks/useAppKitEvents.ts +63 -3
  163. package/src/hooks/useAppKitLogs.ts +3 -11
  164. package/src/hooks/useAppKitState.ts +35 -2
  165. package/src/hooks/useAppKitTheme.ts +82 -0
  166. package/src/hooks/useProvider.ts +3 -4
  167. package/src/hooks/useWalletInfo.ts +33 -2
  168. package/src/index.ts +8 -2
  169. package/src/modal/w3m-modal/index.tsx +16 -7
  170. package/src/modal/w3m-modal/styles.ts +2 -1
  171. package/src/partials/w3m-connecting-body/index.tsx +3 -1
  172. package/src/partials/w3m-connecting-mobile/components/StoreLink.tsx +4 -1
  173. package/src/partials/w3m-connecting-qrcode/index.tsx +10 -1
  174. package/src/partials/w3m-header/index.tsx +6 -1
  175. package/src/partials/w3m-header/styles.ts +3 -0
  176. package/src/partials/w3m-send-input-token/index.tsx +5 -1
  177. package/src/partials/w3m-swap-input/index.tsx +5 -1
  178. package/src/views/w3m-account-default-view/index.tsx +6 -1
  179. package/src/views/w3m-connecting-external-view/index.tsx +4 -8
  180. package/src/views/w3m-connecting-view/index.tsx +24 -14
  181. package/src/views/w3m-onramp-settings-view/index.tsx +7 -1
  182. package/src/views/w3m-onramp-view/index.tsx +3 -2
  183. package/src/views/w3m-swap-view/components/select-token-modal/index.tsx +1 -1
  184. package/src/views/w3m-swap-view/index.tsx +2 -0
  185. package/src/views/w3m-wallet-send-view/index.tsx +1 -0
@@ -1,5 +1,5 @@
1
1
  import { useSnapshot } from 'valtio';
2
- import { useCallback, useEffect } from 'react';
2
+ import { useCallback, useEffect, type ComponentType, type ReactNode } from 'react';
3
3
  import { useColorScheme } from 'react-native';
4
4
  import { Card, Modal, ThemeProvider } from '@reown/appkit-ui-react-native';
5
5
  import {
@@ -18,12 +18,22 @@ import { Snackbar } from '../../partials/w3m-snackbar';
18
18
  import { useInternalAppKit } from '../../AppKitContext';
19
19
  import styles from './styles';
20
20
 
21
- export function AppKit() {
21
+ export interface AppKitModalContentWrapperProps {
22
+ children: ReactNode;
23
+ }
24
+
25
+ export type AppKitModalContentWrapperComponent = ComponentType<AppKitModalContentWrapperProps>;
26
+
27
+ export interface AppKitProps {
28
+ modalContentWrapper?: AppKitModalContentWrapperComponent;
29
+ }
30
+
31
+ export function AppKit({ modalContentWrapper }: AppKitProps) {
22
32
  const theme = useColorScheme();
23
33
  const { bottom, top } = useSafeAreaInsets();
24
34
  const { close } = useInternalAppKit();
25
35
  const { open } = useSnapshot(ModalController.state);
26
- const { themeMode, themeVariables, defaultThemeMode } = useSnapshot(ThemeController.state);
36
+ const { themeMode, themeVariables } = useSnapshot(ThemeController.state);
27
37
  const { projectId } = useSnapshot(OptionsController.state);
28
38
 
29
39
  const handleBackPress = () => {
@@ -35,10 +45,8 @@ export function AppKit() {
35
45
  };
36
46
 
37
47
  useEffect(() => {
38
- if (theme && !defaultThemeMode) {
39
- ThemeController.setThemeMode(theme);
40
- }
41
- }, [theme, defaultThemeMode]);
48
+ ThemeController.setSystemThemeMode(theme ?? undefined);
49
+ }, [theme]);
42
50
 
43
51
  const prefetch = useCallback(async () => {
44
52
  await ApiController.prefetch();
@@ -62,6 +70,7 @@ export function AppKit() {
62
70
  onRequestClose={handleBackPress}
63
71
  onBackdropPress={handleModalClose}
64
72
  testID="w3m-modal"
73
+ contentWrapper={modalContentWrapper}
65
74
  >
66
75
  <Card style={[styles.card, { paddingBottom: bottom, marginTop: top }]}>
67
76
  <Header />
@@ -3,6 +3,7 @@ import { StyleSheet } from 'react-native';
3
3
  export default StyleSheet.create({
4
4
  card: {
5
5
  borderBottomLeftRadius: 0,
6
- borderBottomRightRadius: 0
6
+ borderBottomRightRadius: 0,
7
+ borderWidth: 0
7
8
  }
8
9
  });
@@ -11,7 +11,9 @@ export interface ConnectingBodyProps {
11
11
  export function ConnectingBody({ title, description }: ConnectingBodyProps) {
12
12
  return (
13
13
  <FlexView padding={['3xs', '2xl', '0', '2xl']} alignItems="center" style={styles.textContainer}>
14
- <Text variant="paragraph-500">{title}</Text>
14
+ <Text center numberOfLines={1} variant="paragraph-500">
15
+ {title}
16
+ </Text>
15
17
  {description ? (
16
18
  <Text center variant="small-400" color="fg-200" style={styles.descriptionText}>
17
19
  {description}
@@ -12,7 +12,7 @@ export function StoreLink({ visible, walletName = 'Wallet', onPress }: StoreLink
12
12
 
13
13
  return (
14
14
  <ActionEntry style={styles.storeButton}>
15
- <Text numberOfLines={1} variant="paragraph-500" color="fg-200">
15
+ <Text numberOfLines={1} style={styles.storeText} variant="paragraph-500" color="fg-200">
16
16
  {`Don't have ${walletName}?`}
17
17
  </Text>
18
18
  <Button
@@ -34,5 +34,8 @@ const styles = StyleSheet.create({
34
34
  paddingHorizontal: Spacing.l,
35
35
  marginHorizontal: Spacing.xl,
36
36
  marginTop: Spacing.l
37
+ },
38
+ storeText: {
39
+ flexShrink: 1
37
40
  }
38
41
  });
@@ -20,6 +20,9 @@ import styles from './styles';
20
20
  import { ReownButton } from './components/ReownButton';
21
21
  import { useWindowDimensions } from 'react-native';
22
22
 
23
+ const LOGO_SIZE = 60;
24
+ const LOGO_BORDER_RADIUS = 10;
25
+
23
26
  export function ConnectingQrCode() {
24
27
  const { height, width } = useWindowDimensions();
25
28
  const windowSize = Math.min(height, width);
@@ -65,7 +68,13 @@ export function ConnectingQrCode() {
65
68
  flexDirection={isPortrait ? 'column' : 'row'}
66
69
  padding={['xl', 'xl', 'xs', 'xl']}
67
70
  >
68
- <QrCode size={qrSize} uri={wcUri} testID="qr-code" />
71
+ <QrCode
72
+ size={qrSize}
73
+ uri={wcUri}
74
+ testID="qr-code"
75
+ logoBorderRadius={LOGO_BORDER_RADIUS}
76
+ logoSize={LOGO_SIZE}
77
+ />
69
78
  <FlexView alignItems="center" margin="m">
70
79
  <Text variant="paragraph-500">Scan this QR code with your phone</Text>
71
80
  {showCopy ? (
@@ -100,7 +100,12 @@ export function Header() {
100
100
  padding={['l', 'xl', bottomPadding, 'xl']}
101
101
  >
102
102
  {dynamicButtonTemplate()}
103
- <Text variant="paragraph-600" numberOfLines={1} testID="header-text">
103
+ <Text
104
+ variant="paragraph-600"
105
+ numberOfLines={1}
106
+ style={styles.headerText}
107
+ testID="header-text"
108
+ >
104
109
  {header}
105
110
  </Text>
106
111
  {showClose ? (
@@ -4,5 +4,8 @@ export default StyleSheet.create({
4
4
  iconPlaceholder: {
5
5
  height: 32,
6
6
  width: 32
7
+ },
8
+ headerText: {
9
+ flexShrink: 1
7
10
  }
8
11
  });
@@ -20,6 +20,7 @@ export interface SendInputTokenProps {
20
20
  style?: StyleProp<ViewStyle>;
21
21
  onTokenPress?: () => void;
22
22
  loading?: boolean;
23
+ testID?: string;
23
24
  }
24
25
 
25
26
  export function SendInputToken({
@@ -27,7 +28,8 @@ export function SendInputToken({
27
28
  sendTokenAmount,
28
29
  style,
29
30
  onTokenPress,
30
- loading
31
+ loading,
32
+ testID
31
33
  }: SendInputTokenProps) {
32
34
  const Theme = useTheme();
33
35
  const valueInputRef = useRef<TextInput | null>(null);
@@ -86,12 +88,14 @@ export function SendInputToken({
86
88
  selectTextOnFocus={false}
87
89
  numberOfLines={1}
88
90
  autoFocus={!!token}
91
+ testID={testID}
89
92
  />
90
93
  <TokenButton
91
94
  imageUrl={token?.iconUrl}
92
95
  text={token?.symbol}
93
96
  onPress={onTokenPress}
94
97
  chevron
98
+ testID={testID ? `${testID}-button` : undefined}
95
99
  />
96
100
  </FlexView>
97
101
  {token ? (
@@ -28,6 +28,7 @@ export interface SwapInputProps {
28
28
  marketValue?: number;
29
29
  editable?: boolean;
30
30
  autoFocus?: boolean;
31
+ testID?: string;
31
32
  }
32
33
 
33
34
  const MINIMUM_USD_VALUE_TO_CONVERT = 0.00005;
@@ -43,7 +44,8 @@ export function SwapInput({
43
44
  onChange,
44
45
  marketValue,
45
46
  editable,
46
- autoFocus
47
+ autoFocus,
48
+ testID
47
49
  }: SwapInputProps) {
48
50
  const Theme = useTheme();
49
51
  const valueInputRef = useRef<TextInput | null>(null);
@@ -118,6 +120,7 @@ export function SwapInput({
118
120
  numberOfLines={1}
119
121
  editable={editable}
120
122
  autoFocus={autoFocus}
123
+ testID={testID}
121
124
  />
122
125
  )}
123
126
  <TokenButton
@@ -125,6 +128,7 @@ export function SwapInput({
125
128
  imageUrl={token?.logoUri}
126
129
  onPress={onTokenPress}
127
130
  chevron
131
+ testID={testID ? `${testID}-button` : undefined}
128
132
  />
129
133
  </FlexView>
130
134
  {loadingValues ? (
@@ -186,7 +186,12 @@ export function AccountDefaultView() {
186
186
  return (
187
187
  <>
188
188
  {showBack ? (
189
- <IconLink icon="chevronLeft" style={styles.backIcon} onPress={RouterController.goBack} />
189
+ <IconLink
190
+ icon="chevronLeft"
191
+ style={styles.backIcon}
192
+ onPress={RouterController.goBack}
193
+ testID="header-back"
194
+ />
190
195
  ) : null}
191
196
  <IconLink
192
197
  icon="close"
@@ -26,6 +26,7 @@ import styles from './styles';
26
26
  import { useInternalAppKit } from '../../AppKitContext';
27
27
  import { StoreLink } from '../../partials/w3m-connecting-mobile/components/StoreLink';
28
28
  import { WcHelpersUtil } from '../../utils/HelpersUtil';
29
+ import { ErrorUtil } from '@reown/appkit-common-react-native';
29
30
 
30
31
  export function ConnectingExternalView() {
31
32
  const { data } = useSnapshot(RouterController.state);
@@ -94,16 +95,11 @@ export function ConnectingExternalView() {
94
95
  }
95
96
  } catch (error) {
96
97
  LogController.sendError(error, 'ConnectingExternalView.tsx', 'onConnect');
97
- if (/(Wallet not found)/i.test((error as Error).message)) {
98
- setErrorType('not_installed');
99
- } else if (/(rejected)/i.test((error as Error).message)) {
100
- setErrorType('declined');
101
- } else {
102
- setErrorType('default');
103
- }
98
+ const type = ErrorUtil.categorizeConnectionError(error);
99
+ setErrorType(type);
104
100
  EventsController.sendEvent({
105
101
  type: 'track',
106
- event: 'CONNECT_ERROR',
102
+ event: type === 'declined' ? 'USER_REJECTED' : 'CONNECT_ERROR',
107
103
  properties: { message: (error as Error)?.message ?? 'Unknown' }
108
104
  });
109
105
  }
@@ -1,6 +1,6 @@
1
1
  import { useSnapshot } from 'valtio';
2
- import { useEffect, useLayoutEffect, useState } from 'react';
3
- import { type Platform } from '@reown/appkit-common-react-native';
2
+ import { useEffect, useLayoutEffect, useRef, useState } from 'react';
3
+ import { ErrorUtil, type Platform } from '@reown/appkit-common-react-native';
4
4
  import {
5
5
  WcController,
6
6
  ConstantsUtil,
@@ -22,7 +22,7 @@ export function ConnectingView() {
22
22
  const { connect } = useInternalAppKit();
23
23
  const { installed } = useSnapshot(ApiController.state);
24
24
  const { data } = RouterController.state;
25
- const [lastRetry, setLastRetry] = useState(Date.now());
25
+ const lastRetryRef = useRef<number>(Date.now());
26
26
  const isQr = !data?.wallet;
27
27
  const isInstalled = !!installed?.find(wallet => wallet.id === data?.wallet?.id);
28
28
 
@@ -30,9 +30,8 @@ export function ConnectingView() {
30
30
  const [platforms, setPlatforms] = useState<Platform[]>([]);
31
31
 
32
32
  const onRetry = () => {
33
- if (CoreHelperUtil.isAllowedRetry(lastRetry)) {
34
- setLastRetry(Date.now());
35
- WcController.clearUri();
33
+ if (CoreHelperUtil.isAllowedRetry(lastRetryRef.current)) {
34
+ lastRetryRef.current = Date.now();
36
35
  initializeConnection(true);
37
36
  } else {
38
37
  SnackController.showError('Please wait a second before retrying');
@@ -43,30 +42,41 @@ export function ConnectingView() {
43
42
  try {
44
43
  const { wcPairingExpiry } = WcController.state;
45
44
  const { data: routeData } = RouterController.state;
46
- if (retry || CoreHelperUtil.isPairingExpired(wcPairingExpiry)) {
45
+ const isPairingExpired = CoreHelperUtil.isPairingExpired(wcPairingExpiry);
46
+ if (retry || isPairingExpired) {
47
47
  WcController.setWcError(false);
48
+ WcController.clearUri();
48
49
 
49
50
  const connectPromise = connect({
50
51
  wallet: routeData?.wallet
51
52
  });
52
53
  WcController.setWcPromise(connectPromise);
54
+ await connectPromise;
53
55
  }
54
56
  } catch (error) {
55
57
  LogController.sendError(error, 'ConnectingView.tsx', 'initializeConnection');
56
58
  WcController.setWcError(true);
57
- WcController.clearUri();
58
- SnackController.showError('Declined');
59
- if (isQr && CoreHelperUtil.isAllowedRetry(lastRetry)) {
60
- setLastRetry(Date.now());
61
- initializeConnection(true);
59
+
60
+ const isUserRejected = ErrorUtil.isUserRejectedRequestError(error);
61
+ const isProposalExpired = ErrorUtil.isProposalExpiredError(error);
62
+ if (!isProposalExpired) {
63
+ SnackController.showError(
64
+ isUserRejected ? 'User rejected the request' : 'Something went wrong'
65
+ );
62
66
  }
67
+
63
68
  EventsController.sendEvent({
64
69
  type: 'track',
65
- event: 'CONNECT_ERROR',
70
+ event: isUserRejected ? 'USER_REJECTED' : 'CONNECT_ERROR',
66
71
  properties: {
67
72
  message: (error as Error)?.message ?? 'Unknown'
68
73
  }
69
74
  });
75
+
76
+ if (isQr && CoreHelperUtil.isAllowedRetry(lastRetryRef.current)) {
77
+ lastRetryRef.current = Date.now();
78
+ initializeConnection(true);
79
+ }
70
80
  }
71
81
  };
72
82
 
@@ -95,7 +105,7 @@ export function ConnectingView() {
95
105
  }, [data, isInstalled]);
96
106
 
97
107
  useEffect(() => {
98
- initializeConnection();
108
+ initializeConnection(true);
99
109
  let _interval: NodeJS.Timeout;
100
110
 
101
111
  // Check if the pairing expired every 10 seconds. If expired, it will create a new uri.
@@ -90,6 +90,7 @@ export function OnRampSettingsView() {
90
90
  chevron
91
91
  style={styles.firstItem}
92
92
  contentStyle={styles.listItem}
93
+ testID="button-select-country"
93
94
  >
94
95
  <FlexView
95
96
  alignItems="center"
@@ -111,7 +112,12 @@ export function OnRampSettingsView() {
111
112
  ) : null}
112
113
  </FlexView>
113
114
  </ListItem>
114
- <ListItem onPress={onPaymentCurrencyPress} chevron contentStyle={styles.listItem}>
115
+ <ListItem
116
+ onPress={onPaymentCurrencyPress}
117
+ chevron
118
+ contentStyle={styles.listItem}
119
+ testID="button-select-currency"
120
+ >
115
121
  <FlexView
116
122
  alignItems="center"
117
123
  justifyContent="center"
@@ -61,6 +61,7 @@ export function OnRampView() {
61
61
  const purchaseCurrencyCode =
62
62
  purchaseCurrency?.currencyCode?.split('_')[0] ?? purchaseCurrency?.currencyCode;
63
63
  const networkImage = AssetUtil.getNetworkImage(activeNetwork, networkImages);
64
+ const isContinueDisabled = quotesLoading || loading || !selectedQuote;
64
65
 
65
66
  const getQuotes = useCallback(() => {
66
67
  if (OnRampController.canGenerateQuote()) {
@@ -240,8 +241,8 @@ export function OnRampView() {
240
241
  <Button
241
242
  style={styles.continueButton}
242
243
  onPress={handleContinue}
243
- disabled={quotesLoading || loading || !selectedQuote}
244
- testID="button-continue"
244
+ disabled={isContinueDisabled}
245
+ testID={`button-continue${isContinueDisabled ? '-disabled' : '-enabled'}`}
245
246
  >
246
247
  Continue
247
248
  </Button>
@@ -98,7 +98,7 @@ export function SwapSelectTokenModal({ onClose, type, style, visible }: Props) {
98
98
  alignItems="center"
99
99
  padding={['0', 'm', 'm', 'm']}
100
100
  >
101
- <IconLink icon="chevronLeft" size="md" onPress={onClose} />
101
+ <IconLink icon="chevronLeft" size="md" onPress={onClose} testID="button-back" />
102
102
  <Text variant="paragraph-600">Select token</Text>
103
103
  <View style={styles.iconPlaceholder} />
104
104
  </FlexView>
@@ -174,6 +174,7 @@ export function SwapView() {
174
174
  onChange={onSourceTokenChange}
175
175
  onTokenPress={() => setShowModal('sourceToken')}
176
176
  onMaxPress={onSourceMaxPress}
177
+ testID="swap-input-source"
177
178
  />
178
179
  <FlexView alignItems="center" justifyContent="center" style={styles.bottomInputContainer}>
179
180
  <SwapInput
@@ -186,6 +187,7 @@ export function SwapView() {
186
187
  onChange={onToTokenChange}
187
188
  onTokenPress={() => setShowModal('toToken')}
188
189
  editable={false}
190
+ testID="swap-input-to"
189
191
  />
190
192
  {showSwitch ? (
191
193
  <IconLink
@@ -92,6 +92,7 @@ export function WalletSendView() {
92
92
  style={styles.tokenInput}
93
93
  onTokenPress={() => RouterController.push('WalletSendSelectToken')}
94
94
  loading={isBalanceLoading}
95
+ testID="send-input-token"
95
96
  />
96
97
  <FlexView alignItems="center" justifyContent="center" style={styles.addressContainer}>
97
98
  <SendInputAddress value={receiverProfileName || receiverAddress} />