@reown/appkit-react-native 2.0.0-alpha.6 → 2.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.
Files changed (164) hide show
  1. package/lib/commonjs/AppKit.js +107 -15
  2. package/lib/commonjs/AppKit.js.map +1 -1
  3. package/lib/commonjs/hooks/useAppKit.js.map +1 -1
  4. package/lib/commonjs/hooks/useAppKitLogs.js +88 -0
  5. package/lib/commonjs/hooks/useAppKitLogs.js.map +1 -0
  6. package/lib/commonjs/hooks/useProvider.js +20 -8
  7. package/lib/commonjs/hooks/useProvider.js.map +1 -1
  8. package/lib/commonjs/index.js +8 -0
  9. package/lib/commonjs/index.js.map +1 -1
  10. package/lib/commonjs/partials/w3m-account-wallet-features/index.js +1 -1
  11. package/lib/commonjs/partials/w3m-account-wallet-features/index.js.map +1 -1
  12. package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletItem.js +2 -1
  13. package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletItem.js.map +1 -1
  14. package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletList.js +62 -23
  15. package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletList.js.map +1 -1
  16. package/lib/commonjs/partials/w3m-all-wallets-list/index.js +2 -1
  17. package/lib/commonjs/partials/w3m-all-wallets-list/index.js.map +1 -1
  18. package/lib/commonjs/partials/w3m-all-wallets-search/index.js +2 -0
  19. package/lib/commonjs/partials/w3m-all-wallets-search/index.js.map +1 -1
  20. package/lib/commonjs/partials/w3m-connecting-mobile/index.js +21 -1
  21. package/lib/commonjs/partials/w3m-connecting-mobile/index.js.map +1 -1
  22. package/lib/commonjs/partials/w3m-connecting-qrcode/index.js +5 -1
  23. package/lib/commonjs/partials/w3m-connecting-qrcode/index.js.map +1 -1
  24. package/lib/commonjs/partials/w3m-connecting-web/index.js +8 -2
  25. package/lib/commonjs/partials/w3m-connecting-web/index.js.map +1 -1
  26. package/lib/commonjs/utils/SIWXUtil.js +4 -8
  27. package/lib/commonjs/utils/SIWXUtil.js.map +1 -1
  28. package/lib/commonjs/views/w3m-account-default-view/index.js +3 -2
  29. package/lib/commonjs/views/w3m-account-default-view/index.js.map +1 -1
  30. package/lib/commonjs/views/w3m-all-wallets-view/index.js +5 -2
  31. package/lib/commonjs/views/w3m-all-wallets-view/index.js.map +1 -1
  32. package/lib/commonjs/views/w3m-connect-view/components/all-wallet-list.js +33 -6
  33. package/lib/commonjs/views/w3m-connect-view/components/all-wallet-list.js.map +1 -1
  34. package/lib/commonjs/views/w3m-connect-view/index.js +5 -2
  35. package/lib/commonjs/views/w3m-connect-view/index.js.map +1 -1
  36. package/lib/commonjs/views/w3m-connecting-external-view/index.js +21 -1
  37. package/lib/commonjs/views/w3m-connecting-external-view/index.js.map +1 -1
  38. package/lib/commonjs/views/w3m-connecting-social-view/index.js +1 -0
  39. package/lib/commonjs/views/w3m-connecting-social-view/index.js.map +1 -1
  40. package/lib/commonjs/views/w3m-connecting-view/index.js +1 -0
  41. package/lib/commonjs/views/w3m-connecting-view/index.js.map +1 -1
  42. package/lib/commonjs/views/w3m-network-switch-view/index.js +1 -0
  43. package/lib/commonjs/views/w3m-network-switch-view/index.js.map +1 -1
  44. package/lib/commonjs/views/w3m-siwx-sign-view/index.js +1 -0
  45. package/lib/commonjs/views/w3m-siwx-sign-view/index.js.map +1 -1
  46. package/lib/commonjs/views/w3m-swap-view/index.js +1 -1
  47. package/lib/commonjs/views/w3m-swap-view/index.js.map +1 -1
  48. package/lib/commonjs/views/w3m-what-is-a-wallet-view/index.js +1 -1
  49. package/lib/commonjs/views/w3m-what-is-a-wallet-view/index.js.map +1 -1
  50. package/lib/module/AppKit.js +108 -16
  51. package/lib/module/AppKit.js.map +1 -1
  52. package/lib/module/hooks/useAppKit.js.map +1 -1
  53. package/lib/module/hooks/useAppKitLogs.js +83 -0
  54. package/lib/module/hooks/useAppKitLogs.js.map +1 -0
  55. package/lib/module/hooks/useProvider.js +21 -9
  56. package/lib/module/hooks/useProvider.js.map +1 -1
  57. package/lib/module/index.js +3 -0
  58. package/lib/module/index.js.map +1 -1
  59. package/lib/module/partials/w3m-account-wallet-features/index.js +1 -1
  60. package/lib/module/partials/w3m-account-wallet-features/index.js.map +1 -1
  61. package/lib/module/partials/w3m-all-wallets-list/components/WalletItem.js +2 -1
  62. package/lib/module/partials/w3m-all-wallets-list/components/WalletItem.js.map +1 -1
  63. package/lib/module/partials/w3m-all-wallets-list/components/WalletList.js +63 -24
  64. package/lib/module/partials/w3m-all-wallets-list/components/WalletList.js.map +1 -1
  65. package/lib/module/partials/w3m-all-wallets-list/index.js +3 -2
  66. package/lib/module/partials/w3m-all-wallets-list/index.js.map +1 -1
  67. package/lib/module/partials/w3m-all-wallets-search/index.js +3 -1
  68. package/lib/module/partials/w3m-all-wallets-search/index.js.map +1 -1
  69. package/lib/module/partials/w3m-connecting-mobile/index.js +22 -2
  70. package/lib/module/partials/w3m-connecting-mobile/index.js.map +1 -1
  71. package/lib/module/partials/w3m-connecting-qrcode/index.js +6 -2
  72. package/lib/module/partials/w3m-connecting-qrcode/index.js.map +1 -1
  73. package/lib/module/partials/w3m-connecting-web/index.js +9 -3
  74. package/lib/module/partials/w3m-connecting-web/index.js.map +1 -1
  75. package/lib/module/utils/SIWXUtil.js +5 -9
  76. package/lib/module/utils/SIWXUtil.js.map +1 -1
  77. package/lib/module/views/w3m-account-default-view/index.js +4 -3
  78. package/lib/module/views/w3m-account-default-view/index.js.map +1 -1
  79. package/lib/module/views/w3m-all-wallets-view/index.js +5 -2
  80. package/lib/module/views/w3m-all-wallets-view/index.js.map +1 -1
  81. package/lib/module/views/w3m-connect-view/components/all-wallet-list.js +34 -7
  82. package/lib/module/views/w3m-connect-view/components/all-wallet-list.js.map +1 -1
  83. package/lib/module/views/w3m-connect-view/index.js +5 -2
  84. package/lib/module/views/w3m-connect-view/index.js.map +1 -1
  85. package/lib/module/views/w3m-connecting-external-view/index.js +22 -2
  86. package/lib/module/views/w3m-connecting-external-view/index.js.map +1 -1
  87. package/lib/module/views/w3m-connecting-social-view/index.js +2 -1
  88. package/lib/module/views/w3m-connecting-social-view/index.js.map +1 -1
  89. package/lib/module/views/w3m-connecting-view/index.js +2 -1
  90. package/lib/module/views/w3m-connecting-view/index.js.map +1 -1
  91. package/lib/module/views/w3m-network-switch-view/index.js +2 -1
  92. package/lib/module/views/w3m-network-switch-view/index.js.map +1 -1
  93. package/lib/module/views/w3m-siwx-sign-view/index.js +2 -1
  94. package/lib/module/views/w3m-siwx-sign-view/index.js.map +1 -1
  95. package/lib/module/views/w3m-swap-view/index.js +1 -1
  96. package/lib/module/views/w3m-swap-view/index.js.map +1 -1
  97. package/lib/module/views/w3m-what-is-a-wallet-view/index.js +1 -1
  98. package/lib/module/views/w3m-what-is-a-wallet-view/index.js.map +1 -1
  99. package/lib/typescript/AppKit.d.ts +13 -2
  100. package/lib/typescript/AppKit.d.ts.map +1 -1
  101. package/lib/typescript/AppKitContext.d.ts +1 -1
  102. package/lib/typescript/hooks/useAccount.d.ts +1 -1
  103. package/lib/typescript/hooks/useAppKit.d.ts +2 -1
  104. package/lib/typescript/hooks/useAppKit.d.ts.map +1 -1
  105. package/lib/typescript/hooks/useAppKitEvents.d.ts +82 -17
  106. package/lib/typescript/hooks/useAppKitEvents.d.ts.map +1 -1
  107. package/lib/typescript/hooks/useAppKitLogs.d.ts +57 -0
  108. package/lib/typescript/hooks/useAppKitLogs.d.ts.map +1 -0
  109. package/lib/typescript/hooks/useAppKitState.d.ts +1 -1
  110. package/lib/typescript/hooks/useProvider.d.ts.map +1 -1
  111. package/lib/typescript/index.d.ts +2 -0
  112. package/lib/typescript/index.d.ts.map +1 -1
  113. package/lib/typescript/partials/w3m-all-wallets-list/components/WalletItem.d.ts +3 -2
  114. package/lib/typescript/partials/w3m-all-wallets-list/components/WalletItem.d.ts.map +1 -1
  115. package/lib/typescript/partials/w3m-all-wallets-list/components/WalletList.d.ts +3 -2
  116. package/lib/typescript/partials/w3m-all-wallets-list/components/WalletList.d.ts.map +1 -1
  117. package/lib/typescript/partials/w3m-all-wallets-list/index.d.ts +1 -1
  118. package/lib/typescript/partials/w3m-all-wallets-list/index.d.ts.map +1 -1
  119. package/lib/typescript/partials/w3m-all-wallets-search/index.d.ts +1 -1
  120. package/lib/typescript/partials/w3m-all-wallets-search/index.d.ts.map +1 -1
  121. package/lib/typescript/partials/w3m-connecting-mobile/index.d.ts.map +1 -1
  122. package/lib/typescript/partials/w3m-connecting-qrcode/index.d.ts.map +1 -1
  123. package/lib/typescript/partials/w3m-connecting-web/index.d.ts.map +1 -1
  124. package/lib/typescript/types.d.ts +1 -0
  125. package/lib/typescript/types.d.ts.map +1 -1
  126. package/lib/typescript/utils/SIWXUtil.d.ts +1 -1
  127. package/lib/typescript/utils/SIWXUtil.d.ts.map +1 -1
  128. package/lib/typescript/views/w3m-account-default-view/index.d.ts.map +1 -1
  129. package/lib/typescript/views/w3m-all-wallets-view/index.d.ts.map +1 -1
  130. package/lib/typescript/views/w3m-connect-view/components/all-wallet-list.d.ts +1 -1
  131. package/lib/typescript/views/w3m-connect-view/components/all-wallet-list.d.ts.map +1 -1
  132. package/lib/typescript/views/w3m-connect-view/index.d.ts.map +1 -1
  133. package/lib/typescript/views/w3m-connecting-external-view/index.d.ts.map +1 -1
  134. package/lib/typescript/views/w3m-connecting-social-view/index.d.ts.map +1 -1
  135. package/lib/typescript/views/w3m-connecting-view/index.d.ts.map +1 -1
  136. package/lib/typescript/views/w3m-network-switch-view/index.d.ts.map +1 -1
  137. package/lib/typescript/views/w3m-siwx-sign-view/index.d.ts.map +1 -1
  138. package/package.json +5 -5
  139. package/src/AppKit.ts +125 -15
  140. package/src/hooks/useAppKit.ts +3 -2
  141. package/src/hooks/useAppKitLogs.ts +129 -0
  142. package/src/hooks/useProvider.ts +15 -6
  143. package/src/index.ts +3 -0
  144. package/src/partials/w3m-account-wallet-features/index.tsx +1 -1
  145. package/src/partials/w3m-all-wallets-list/components/WalletItem.tsx +11 -3
  146. package/src/partials/w3m-all-wallets-list/components/WalletList.tsx +74 -25
  147. package/src/partials/w3m-all-wallets-list/index.tsx +4 -2
  148. package/src/partials/w3m-all-wallets-search/index.tsx +16 -3
  149. package/src/partials/w3m-connecting-mobile/index.tsx +24 -2
  150. package/src/partials/w3m-connecting-qrcode/index.tsx +8 -2
  151. package/src/partials/w3m-connecting-web/index.tsx +11 -3
  152. package/src/types.ts +1 -0
  153. package/src/utils/SIWXUtil.ts +6 -11
  154. package/src/views/w3m-account-default-view/index.tsx +5 -3
  155. package/src/views/w3m-all-wallets-view/index.tsx +9 -2
  156. package/src/views/w3m-connect-view/components/all-wallet-list.tsx +46 -15
  157. package/src/views/w3m-connect-view/index.tsx +5 -2
  158. package/src/views/w3m-connecting-external-view/index.tsx +24 -2
  159. package/src/views/w3m-connecting-social-view/index.tsx +3 -1
  160. package/src/views/w3m-connecting-view/index.tsx +3 -1
  161. package/src/views/w3m-network-switch-view/index.tsx +2 -0
  162. package/src/views/w3m-siwx-sign-view/index.tsx +2 -0
  163. package/src/views/w3m-swap-view/index.tsx +1 -1
  164. package/src/views/w3m-what-is-a-wallet-view/index.tsx +1 -1
@@ -1,4 +1,4 @@
1
- import { FlatList, StyleSheet, type StyleProp, type ViewStyle } from 'react-native';
1
+ import { FlatList, StyleSheet, type StyleProp, type ViewStyle, type ViewToken } from 'react-native';
2
2
  import { WalletItem } from './WalletItem';
3
3
  import {
4
4
  CardSelectHeight,
@@ -7,8 +7,9 @@ import {
7
7
  CardSelectLoader,
8
8
  CardSelectWidth
9
9
  } from '@reown/appkit-ui-react-native';
10
- import { ApiController } from '@reown/appkit-core-react-native';
10
+ import { ApiController, EventsController } from '@reown/appkit-core-react-native';
11
11
  import type { WcWallet } from '@reown/appkit-common-react-native';
12
+ import { useCallback, useRef } from 'react';
12
13
 
13
14
  const imageHeaders = ApiController._getApiHeaders();
14
15
 
@@ -18,13 +19,14 @@ const ITEM_HEIGHT_WITH_GAP = ITEM_HEIGHT + Spacing['3xs'];
18
19
 
19
20
  interface Props {
20
21
  data: WcWallet[];
21
- onItemPress: (wallet: WcWallet) => void;
22
+ onItemPress: (wallet: WcWallet, displayIndex: number) => void;
22
23
  onEndReached?: () => void;
23
24
  onEndReachedThreshold?: number;
24
25
  isLoading?: boolean;
25
26
  loadingItems?: number;
26
27
  style?: StyleProp<ViewStyle>;
27
28
  testIDKey?: string;
29
+ searchQuery?: string;
28
30
  }
29
31
 
30
32
  export function WalletList({
@@ -35,15 +37,77 @@ export function WalletList({
35
37
  isLoading = false,
36
38
  loadingItems = 20,
37
39
  testIDKey,
38
- style
40
+ style,
41
+ searchQuery
39
42
  }: Props) {
40
43
  const { padding, maxHeight } = useCustomDimensions();
44
+ const viewedWalletsRef = useRef<Set<string>>(new Set());
41
45
 
42
46
  // Create loading data if isLoading is true
43
47
  const displayData = isLoading
44
48
  ? Array.from({ length: loadingItems }, (_, index) => ({ id: `loading-${index}` }) as WcWallet)
45
49
  : data;
46
50
 
51
+ const keyExtractor = useCallback(
52
+ (item: WcWallet, index: number) => item?.id ?? `item-${index}`,
53
+ []
54
+ );
55
+
56
+ const getItemLayout = useCallback((_: any, index: number) => {
57
+ return {
58
+ length: ITEM_HEIGHT_WITH_GAP,
59
+ offset: ITEM_HEIGHT_WITH_GAP * index,
60
+ index
61
+ };
62
+ }, []);
63
+
64
+ const renderItem = useCallback(
65
+ ({ item, index }: { item: WcWallet; index: number }) => {
66
+ if (isLoading) {
67
+ return <CardSelectLoader style={styles.itemContainer} />;
68
+ }
69
+
70
+ return (
71
+ <WalletItem
72
+ item={item}
73
+ imageHeaders={imageHeaders}
74
+ displayIndex={index}
75
+ onItemPress={onItemPress}
76
+ style={styles.itemContainer}
77
+ testID={testIDKey ? `${testIDKey}-${item?.id}` : undefined}
78
+ />
79
+ );
80
+ },
81
+ [isLoading, onItemPress, testIDKey]
82
+ );
83
+
84
+ const onViewableItemsChanged = useCallback(
85
+ ({ viewableItems }: { viewableItems: ViewToken[] }) => {
86
+ if (isLoading) return;
87
+
88
+ viewableItems.forEach(({ item }, index) => {
89
+ const wallet = item as WcWallet;
90
+ if (wallet?.id && !viewedWalletsRef.current.has(wallet.id)) {
91
+ viewedWalletsRef.current.add(wallet.id);
92
+ const isInstalled = !!ApiController.state.installed.find(w => w?.id === item?.id);
93
+ EventsController.trackWalletImpression({
94
+ wallet,
95
+ view: 'AllWallets',
96
+ displayIndex: index,
97
+ query: searchQuery,
98
+ installed: isInstalled
99
+ });
100
+ }
101
+ });
102
+ },
103
+ [isLoading, searchQuery]
104
+ );
105
+
106
+ const viewabilityConfig = useRef({
107
+ itemVisiblePercentThreshold: 50, // Item is considered visible when 50% is visible
108
+ minimumViewTime: 100 // Must be visible for at least 100ms
109
+ }).current;
110
+
47
111
  return (
48
112
  <FlatList
49
113
  fadingEdgeLength={20}
@@ -52,33 +116,18 @@ export function WalletList({
52
116
  data={displayData}
53
117
  style={[styles.list, { height: maxHeight }, style]}
54
118
  columnWrapperStyle={styles.columnWrapperStyle}
55
- renderItem={({ item }) => {
56
- if (isLoading) {
57
- return <CardSelectLoader style={styles.itemContainer} />;
58
- }
59
-
60
- return (
61
- <WalletItem
62
- item={item}
63
- imageHeaders={imageHeaders}
64
- onItemPress={onItemPress}
65
- style={styles.itemContainer}
66
- testID={testIDKey ? `${testIDKey}-${item?.id}` : undefined}
67
- />
68
- );
69
- }}
119
+ renderItem={renderItem}
70
120
  contentContainerStyle={[styles.contentContainer, { paddingHorizontal: padding }]}
71
121
  initialNumToRender={32}
72
122
  maxToRenderPerBatch={12}
73
123
  windowSize={10}
74
124
  onEndReached={onEndReached}
75
125
  onEndReachedThreshold={onEndReachedThreshold}
76
- keyExtractor={(item, index) => item?.id ?? `item-${index}`}
77
- getItemLayout={(_, index) => ({
78
- length: ITEM_HEIGHT_WITH_GAP,
79
- offset: ITEM_HEIGHT_WITH_GAP * index,
80
- index
81
- })}
126
+ keyExtractor={keyExtractor}
127
+ removeClippedSubviews={true}
128
+ getItemLayout={getItemLayout}
129
+ onViewableItemsChanged={onViewableItemsChanged}
130
+ viewabilityConfig={viewabilityConfig}
82
131
  />
83
132
  );
84
133
  }
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react';
2
2
  import { useSnapshot } from 'valtio';
3
3
  import {
4
4
  ApiController,
5
+ LogController,
5
6
  OptionsController,
6
7
  SnackController,
7
8
  type OptionsControllerState
@@ -14,7 +15,7 @@ import { Loading } from './components/Loading';
14
15
  import { WalletList } from './components/WalletList';
15
16
 
16
17
  interface AllWalletsListProps {
17
- onItemPress: (wallet: WcWallet) => void;
18
+ onItemPress: (wallet: WcWallet, displayIndex: number) => void;
18
19
  headerHeight?: number;
19
20
  }
20
21
 
@@ -61,6 +62,7 @@ export function AllWalletsList({ onItemPress }: AllWalletsListProps) {
61
62
  await ApiController.fetchWallets({ page: 1 });
62
63
  setLoading(false);
63
64
  } catch (error) {
65
+ LogController.sendError(error, 'AllWalletsList.tsx', 'initialFetch');
64
66
  SnackController.showError('Failed to load wallets');
65
67
  setLoading(false);
66
68
  setLoadingError(true);
@@ -114,7 +116,7 @@ export function AllWalletsList({ onItemPress }: AllWalletsListProps) {
114
116
  <WalletList
115
117
  data={walletList}
116
118
  onEndReached={fetchNextPage}
117
- onEndReachedThreshold={2}
119
+ onEndReachedThreshold={0.5}
118
120
  onItemPress={onItemPress}
119
121
  />
120
122
  );
@@ -1,6 +1,11 @@
1
1
  import { useSnapshot } from 'valtio';
2
2
  import { useCallback, useEffect, useState } from 'react';
3
- import { ApiController, OptionsController, SnackController } from '@reown/appkit-core-react-native';
3
+ import {
4
+ ApiController,
5
+ LogController,
6
+ OptionsController,
7
+ SnackController
8
+ } from '@reown/appkit-core-react-native';
4
9
  import { type WcWallet } from '@reown/appkit-common-react-native';
5
10
  import { useCustomDimensions } from '@reown/appkit-ui-react-native';
6
11
  import { Placeholder } from '../w3m-placeholder';
@@ -10,7 +15,7 @@ import { Loading } from '../w3m-all-wallets-list/components/Loading';
10
15
  import { WalletList } from '../w3m-all-wallets-list/components/WalletList';
11
16
 
12
17
  export interface AllWalletsSearchProps {
13
- onItemPress: (wallet: WcWallet) => void;
18
+ onItemPress: (wallet: WcWallet, displayIndex: number) => void;
14
19
  searchQuery?: string;
15
20
  }
16
21
 
@@ -36,6 +41,7 @@ export function AllWalletsSearch({ searchQuery, onItemPress }: AllWalletsSearchP
36
41
  await ApiController.searchWallet({ search: searchQuery });
37
42
  setLoading(false);
38
43
  } catch (error) {
44
+ LogController.sendError(error, 'AllWalletsSearch.tsx', 'searchFetch');
39
45
  SnackController.showError('Failed to load wallets');
40
46
  setLoading(false);
41
47
  setLoadingError(true);
@@ -78,5 +84,12 @@ export function AllWalletsSearch({ searchQuery, onItemPress }: AllWalletsSearchP
78
84
  );
79
85
  }
80
86
 
81
- return <WalletList onItemPress={onItemPress} data={results} testIDKey="wallet-search-item" />;
87
+ return (
88
+ <WalletList
89
+ onItemPress={onItemPress}
90
+ searchQuery={searchQuery}
91
+ data={results}
92
+ testIDKey="wallet-search-item"
93
+ />
94
+ );
82
95
  }
@@ -10,7 +10,9 @@ import {
10
10
  OptionsController,
11
11
  EventsController,
12
12
  ConstantsUtil,
13
- AssetController
13
+ AssetController,
14
+ LogController,
15
+ ConnectionsController
14
16
  } from '@reown/appkit-core-react-native';
15
17
  import {
16
18
  Button,
@@ -60,6 +62,21 @@ export function ConnectingMobile({ onRetry, onCopyUri, isInstalled }: Props) {
60
62
  const onStorePress = () => {
61
63
  if (storeUrl) {
62
64
  CoreHelperUtil.openLink(storeUrl);
65
+ EventsController.sendEvent({
66
+ type: 'track',
67
+ event: 'GET_WALLET',
68
+ properties: {
69
+ name: data?.wallet?.name ?? 'Unknown',
70
+ link: storeUrl,
71
+ linkType: Platform.select({
72
+ ios: 'appstore',
73
+ android: 'playstore',
74
+ default: undefined
75
+ }),
76
+ explorerId: data?.wallet?.id,
77
+ walletRank: data?.wallet?.order
78
+ }
79
+ });
63
80
  }
64
81
  };
65
82
 
@@ -74,17 +91,22 @@ export function ConnectingMobile({ onRetry, onCopyUri, isInstalled }: Props) {
74
91
  await CoreHelperUtil.openLink(redirect);
75
92
  await WcController.state.wcPromise;
76
93
  WcController.setConnectedWallet(wcLinking, data?.wallet);
94
+ const address = ConnectionsController.state.activeAddress;
95
+ const caipNetworkId = ConnectionsController.state.activeNetwork?.caipNetworkId;
77
96
  EventsController.sendEvent({
78
97
  type: 'track',
79
98
  event: 'CONNECT_SUCCESS',
99
+ address: CoreHelperUtil.getPlainAddress(address),
80
100
  properties: {
81
101
  method: 'mobile',
82
102
  name: data?.wallet?.name ?? 'Unknown',
83
- explorer_id: data?.wallet?.id
103
+ explorerId: data?.wallet?.id,
104
+ caipNetworkId
84
105
  }
85
106
  });
86
107
  }
87
108
  } catch (error: any) {
109
+ LogController.sendError(error, 'ConnectingMobile.tsx', 'onConnect');
88
110
  if (error.message.includes(ConstantsUtil.LINKING_ERROR)) {
89
111
  setErrorType('not_installed');
90
112
  } else {
@@ -4,7 +4,9 @@ import {
4
4
  WcController,
5
5
  EventsController,
6
6
  OptionsController,
7
- SnackController
7
+ SnackController,
8
+ ConnectionsController,
9
+ CoreHelperUtil
8
10
  } from '@reown/appkit-core-react-native';
9
11
  import {
10
12
  FlexView,
@@ -35,13 +37,17 @@ export function ConnectingQrCode() {
35
37
 
36
38
  const onConnect = async () => {
37
39
  await WcController.state.wcPromise;
40
+ const address = ConnectionsController.state.activeAddress;
41
+ const caipNetworkId = ConnectionsController.state.activeNetwork?.caipNetworkId;
38
42
 
39
43
  EventsController.sendEvent({
40
44
  type: 'track',
41
45
  event: 'CONNECT_SUCCESS',
46
+ address: CoreHelperUtil.getPlainAddress(address),
42
47
  properties: {
43
48
  method: 'qrcode',
44
- name: 'WalletConnect'
49
+ name: 'WalletConnect',
50
+ caipNetworkId
45
51
  }
46
52
  });
47
53
  };
@@ -9,7 +9,9 @@ import {
9
9
  CoreHelperUtil,
10
10
  OptionsController,
11
11
  EventsController,
12
- AssetController
12
+ AssetController,
13
+ LogController,
14
+ ConnectionsController
13
15
  } from '@reown/appkit-core-react-native';
14
16
  import {
15
17
  Button,
@@ -50,18 +52,24 @@ export function ConnectingWeb({ onCopyUri }: ConnectingWebProps) {
50
52
  await Linking.openURL(redirect);
51
53
  await WcController.state.wcPromise;
52
54
  WcController.setConnectedWallet(wcLinking, data?.wallet);
55
+ const address = ConnectionsController.state.activeAddress;
56
+ const caipNetworkId = ConnectionsController.state.activeNetwork?.caipNetworkId;
53
57
 
54
58
  EventsController.sendEvent({
55
59
  type: 'track',
56
60
  event: 'CONNECT_SUCCESS',
61
+ address: CoreHelperUtil.getPlainAddress(address),
57
62
  properties: {
58
63
  method: 'web',
59
64
  name: data?.wallet?.name ?? 'Unknown',
60
- explorer_id: data?.wallet?.id
65
+ explorerId: data?.wallet?.id,
66
+ caipNetworkId
61
67
  }
62
68
  });
63
69
  }
64
- } catch {}
70
+ } catch (error) {
71
+ LogController.sendError(error, 'ConnectingWeb.tsx', 'onConnect');
72
+ }
65
73
  }, [data?.wallet, wcUri]);
66
74
 
67
75
  return (
package/src/types.ts CHANGED
@@ -129,6 +129,7 @@ export interface AppKitConfig {
129
129
  /**
130
130
  * Optional flag to enable debug mode.
131
131
  * When enabled, additional logging and debugging information will be output.
132
+ * Only enabled in development mode.
132
133
  *
133
134
  * @see {@link https://docs.reown.com/appkit/react-native/core/options#debug | Debug Documentation}
134
135
  * @default false
@@ -13,9 +13,9 @@ import {
13
13
  SnackController,
14
14
  CoreHelperUtil,
15
15
  ConnectionsController,
16
- EventsController
16
+ EventsController,
17
+ LogController
17
18
  } from '@reown/appkit-core-react-native';
18
- import { Alert } from 'react-native';
19
19
 
20
20
  /**
21
21
  * SIWXUtil holds the methods to interact with the SIWX plugin and must be called internally on AppKit.
@@ -74,8 +74,7 @@ export const SIWXUtil = {
74
74
  ModalController.open({ view: 'SIWXSignMessage' });
75
75
  }
76
76
  } catch (error: unknown) {
77
- // eslint-disable-next-line no-console
78
- console.error('SIWXUtil:initializeIfEnabled error', error);
77
+ LogController.sendError(error, 'SIWXUtil.ts', 'initializeIfEnabled');
79
78
 
80
79
  EventsController.sendEvent({
81
80
  type: 'track',
@@ -153,10 +152,7 @@ export const SIWXUtil = {
153
152
  view: 'SIWXSignMessage'
154
153
  });
155
154
  }
156
-
157
- // @ts-ignore
158
- Alert.alert('Error signing message', error?.message ?? error);
159
-
155
+ SnackController.hide();
160
156
  SnackController.showError('Error signing message');
161
157
  EventsController.sendEvent({
162
158
  type: 'track',
@@ -293,8 +289,6 @@ export const SIWXUtil = {
293
289
  universalLink
294
290
  );
295
291
 
296
- SnackController.showLoading('Authenticating...', true);
297
-
298
292
  if (result?.auths?.length) {
299
293
  const sessions = result.auths.map<SIWXSession>(cacao => {
300
294
  const message = universalProvider.client.formatAuthMessage({
@@ -320,6 +314,7 @@ export const SIWXUtil = {
320
314
  });
321
315
 
322
316
  try {
317
+ SnackController.showLoading('Authenticating...', true);
323
318
  await siwx.setSessions(sessions);
324
319
 
325
320
  EventsController.sendEvent({
@@ -349,7 +344,7 @@ export const SIWXUtil = {
349
344
  },
350
345
  getSIWXEventProperties(error?: unknown) {
351
346
  return {
352
- network: ConnectionsController.state.activeNetwork?.caipNetworkId || '',
347
+ network: ConnectionsController.state.activeNetwork?.caipNetworkId,
353
348
  isSmartAccount: ConnectionsController.state.accountType === 'smartAccount',
354
349
  message: error ? CoreHelperUtil.parseError(error) : undefined
355
350
  };
@@ -14,7 +14,8 @@ import {
14
14
  OnRampController,
15
15
  ConnectionsController,
16
16
  AssetController,
17
- AssetUtil
17
+ AssetUtil,
18
+ LogController
18
19
  } from '@reown/appkit-core-react-native';
19
20
  // import { ConstantsUtil as CommonConstantsUtil } from '@reown/appkit-common-react-native';
20
21
  import {
@@ -94,6 +95,7 @@ export function AccountDefaultView() {
94
95
  switchAccountType(namespace, newType, network);
95
96
  }
96
97
  } catch (error) {
98
+ LogController.sendError(error, 'AccountDefaultView.tsx', 'onSwitchAccountType');
97
99
  SnackController.showError('Error switching account type');
98
100
  }
99
101
  };
@@ -120,7 +122,7 @@ export function AccountDefaultView() {
120
122
  type: 'track',
121
123
  event: 'OPEN_SWAP',
122
124
  properties: {
123
- network: ConnectionsController.state.activeNetwork?.caipNetworkId || '',
125
+ network: ConnectionsController.state.activeNetwork?.caipNetworkId,
124
126
  isSmartAccount: false
125
127
  }
126
128
  });
@@ -156,7 +158,7 @@ export function AccountDefaultView() {
156
158
  };
157
159
 
158
160
  const onSendPress = () => {
159
- const network = ConnectionsController.state.activeNetwork?.caipNetworkId || '';
161
+ const network = ConnectionsController.state.activeNetwork?.caipNetworkId;
160
162
  const isSmartAccount = ConnectionsController.state.accountType === 'smartAccount';
161
163
 
162
164
  EventsController.sendEvent({
@@ -22,7 +22,7 @@ export function AllWalletsView() {
22
22
 
23
23
  const { debouncedCallback: onInputChange } = useDebounceCallback({ callback: setSearchQuery });
24
24
 
25
- const onWalletPress = (wallet: WcWallet) => {
25
+ const onWalletPress = (wallet: WcWallet, displayIndex: number) => {
26
26
  const isExternal = WcHelpersUtil.isExternalWallet(wallet);
27
27
  if (isExternal) {
28
28
  RouterController.push('ConnectingExternal', { wallet });
@@ -33,7 +33,14 @@ export function AllWalletsView() {
33
33
  EventsController.sendEvent({
34
34
  type: 'track',
35
35
  event: 'SELECT_WALLET',
36
- properties: { name: wallet.name ?? 'Unknown', platform: 'mobile', explorer_id: wallet.id }
36
+ properties: {
37
+ name: wallet.name ?? 'Unknown',
38
+ platform: 'mobile',
39
+ explorerId: wallet.id,
40
+ walletRank: wallet.order,
41
+ displayIndex,
42
+ view: 'AllWallets'
43
+ }
37
44
  });
38
45
  };
39
46
 
@@ -4,6 +4,7 @@ import {
4
4
  ApiController,
5
5
  AssetController,
6
6
  AssetUtil,
7
+ EventsController,
7
8
  OptionsController,
8
9
  WcController,
9
10
  type WcControllerState
@@ -11,10 +12,11 @@ import {
11
12
  import { type WcWallet } from '@reown/appkit-common-react-native';
12
13
  import { ListItemLoader, ListWallet } from '@reown/appkit-ui-react-native';
13
14
  import { UiUtil } from '../../../utils/UiUtil';
15
+ import { useEffect, useMemo, useRef } from 'react';
14
16
 
15
17
  interface Props {
16
18
  itemStyle: StyleProp<ViewStyle>;
17
- onWalletPress: (wallet: WcWallet) => void;
19
+ onWalletPress: (wallet: WcWallet, displayIndex: number, isInstalled?: boolean) => void;
18
20
  }
19
21
 
20
22
  export function AllWalletList({ itemStyle, onWalletPress }: Props) {
@@ -24,18 +26,45 @@ export function AllWalletList({ itemStyle, onWalletPress }: Props) {
24
26
  const { walletImages } = useSnapshot(AssetController.state);
25
27
  const imageHeaders = ApiController._getApiHeaders();
26
28
 
27
- const combinedWallets = [
28
- ...(recentWallets?.slice(0, 1) ?? []),
29
- ...installed,
30
- ...featured,
31
- ...recommended,
32
- ...(customWallets ?? [])
33
- ];
29
+ // Track which wallets have been tracked to prevent duplicates
30
+ const trackedWalletsRef = useRef<Set<string>>(new Set());
34
31
 
35
- // Deduplicate by wallet ID
36
- const list = Array.from(
37
- new Map(combinedWallets.map(wallet => [wallet.id, wallet])).values()
38
- ).slice(0, UiUtil.TOTAL_VISIBLE_WALLETS);
32
+ const list = useMemo(() => {
33
+ const combinedWallets = [
34
+ ...(recentWallets?.slice(0, 1) ?? []),
35
+ ...installed,
36
+ ...featured,
37
+ ...recommended,
38
+ ...(customWallets ?? [])
39
+ ];
40
+
41
+ // Deduplicate by wallet ID
42
+ return Array.from(new Map(combinedWallets.map(wallet => [wallet.id, wallet])).values()).slice(
43
+ 0,
44
+ UiUtil.TOTAL_VISIBLE_WALLETS
45
+ );
46
+ }, [recentWallets, installed, featured, recommended, customWallets]);
47
+
48
+ // Track impressions once when the list stabilizes
49
+ useEffect(() => {
50
+ if (!prefetchLoading && list.length > 0) {
51
+ list.forEach((wallet, index) => {
52
+ if (!trackedWalletsRef.current.has(wallet.id)) {
53
+ trackedWalletsRef.current.add(wallet.id);
54
+ const isInstalled = !!ApiController.state.installed.find(
55
+ installedWallet => installedWallet.id === wallet.id
56
+ );
57
+ EventsController.trackWalletImpression({
58
+ wallet,
59
+ view: 'Connect',
60
+ displayIndex: index,
61
+ // eslint-disable-next-line valtio/state-snapshot-rule
62
+ installed: isInstalled
63
+ });
64
+ }
65
+ });
66
+ }
67
+ }, [prefetchLoading, list]);
39
68
 
40
69
  if (!list?.length) {
41
70
  return null;
@@ -47,8 +76,10 @@ export function AllWalletList({ itemStyle, onWalletPress }: Props) {
47
76
  <ListItemLoader style={itemStyle} />
48
77
  </>
49
78
  ) : (
50
- list.map(wallet => {
79
+ list.map((wallet, index) => {
51
80
  const isRecent = recentWallets?.some(recentWallet => recentWallet.id === wallet.id);
81
+ //eslint-disable-next-line valtio/state-snapshot-rule
82
+ const isInstalled = !!installed.find(installedWallet => installedWallet.id === wallet.id);
52
83
 
53
84
  return (
54
85
  <ListWallet
@@ -56,11 +87,11 @@ export function AllWalletList({ itemStyle, onWalletPress }: Props) {
56
87
  imageSrc={AssetUtil.getWalletImage(wallet, walletImages)}
57
88
  imageHeaders={imageHeaders}
58
89
  name={wallet?.name ?? 'Unknown'}
59
- onPress={() => onWalletPress(wallet)}
90
+ onPress={() => onWalletPress(wallet, index, isInstalled)}
60
91
  tagLabel={isRecent ? 'Recent' : undefined}
61
92
  tagVariant={isRecent ? 'shade' : undefined}
62
93
  style={itemStyle}
63
- installed={!!installed.find(installedWallet => installedWallet.id === wallet.id)}
94
+ installed={isInstalled}
64
95
  />
65
96
  );
66
97
  })
@@ -33,7 +33,7 @@ export function ConnectView() {
33
33
  const showLoadingError = !showConnectWalletsButton && prefetchError;
34
34
  const showList = !showConnectWalletsButton && !showLoadingError;
35
35
 
36
- const onWalletPress = (wallet: WcWallet, isInstalled?: boolean) => {
36
+ const onWalletPress = (wallet: WcWallet, displayIndex: number, isInstalled?: boolean) => {
37
37
  const isExternal = WcHelpersUtil.isExternalWallet(wallet);
38
38
  if (isExternal) {
39
39
  RouterController.push('ConnectingExternal', { wallet });
@@ -48,7 +48,10 @@ export function ConnectView() {
48
48
  properties: {
49
49
  name: wallet.name ?? 'Unknown',
50
50
  platform,
51
- explorer_id: wallet.id
51
+ explorerId: wallet.id,
52
+ walletRank: wallet.order,
53
+ displayIndex,
54
+ view: 'Connect'
52
55
  }
53
56
  });
54
57
  };
@@ -8,7 +8,9 @@ import {
8
8
  WcController,
9
9
  AssetUtil,
10
10
  AssetController,
11
- CoreHelperUtil
11
+ CoreHelperUtil,
12
+ LogController,
13
+ ConnectionsController
12
14
  } from '@reown/appkit-core-react-native';
13
15
  import {
14
16
  Button,
@@ -41,6 +43,21 @@ export function ConnectingExternalView() {
41
43
  const onStorePress = () => {
42
44
  if (storeUrl) {
43
45
  CoreHelperUtil.openLink(storeUrl);
46
+ EventsController.sendEvent({
47
+ type: 'track',
48
+ event: 'GET_WALLET',
49
+ properties: {
50
+ name: RouterController.state.data?.wallet?.name ?? 'Unknown',
51
+ link: storeUrl,
52
+ linkType: Platform.select({
53
+ ios: 'appstore',
54
+ android: 'playstore',
55
+ default: undefined
56
+ }),
57
+ explorerId: RouterController.state.data?.wallet?.id,
58
+ walletRank: RouterController.state.data?.wallet?.order
59
+ }
60
+ });
44
61
  }
45
62
  };
46
63
 
@@ -61,17 +78,22 @@ export function ConnectingExternalView() {
61
78
  }
62
79
  WcController.addRecentWallet(wallet);
63
80
  WcController.setPressedWallet(wallet);
81
+ const address = ConnectionsController.state.activeAddress;
82
+ const caipNetworkId = ConnectionsController.state.activeNetwork?.caipNetworkId;
64
83
  EventsController.sendEvent({
65
84
  type: 'track',
66
85
  event: 'CONNECT_SUCCESS',
86
+ address: CoreHelperUtil.getPlainAddress(address),
67
87
  properties: {
68
88
  name: wallet?.name ?? 'Unknown',
69
89
  method: 'mobile',
70
- explorer_id: wallet?.id
90
+ caipNetworkId,
91
+ explorerId: wallet?.id
71
92
  }
72
93
  });
73
94
  }
74
95
  } catch (error) {
96
+ LogController.sendError(error, 'ConnectingExternalView.tsx', 'onConnect');
75
97
  if (/(Wallet not found)/i.test((error as Error).message)) {
76
98
  setErrorType('not_installed');
77
99
  } else if (/(rejected)/i.test((error as Error).message)) {
@@ -5,7 +5,8 @@ import {
5
5
  CoreHelperUtil,
6
6
  EventsController,
7
7
  RouterController,
8
- SnackController
8
+ SnackController,
9
+ LogController
9
10
  } from '@reown/appkit-core-react-native';
10
11
  import {
11
12
  FlexView,
@@ -48,6 +49,7 @@ export function ConnectingSocialView() {
48
49
  });
49
50
  }
50
51
  } catch (e) {
52
+ LogController.sendError(e, 'ConnectingSocialView.tsx', 'onConnect');
51
53
  EventsController.sendEvent({
52
54
  type: 'track',
53
55
  event: 'SOCIAL_LOGIN_ERROR',