@reown/appkit-react-native 0.0.0-chore-added-import-20251002170458 → 0.0.0-develop-20251008155354
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/AppKit.js +12 -11
- package/lib/commonjs/AppKit.js.map +1 -1
- package/lib/commonjs/hooks/useProvider.js +20 -8
- package/lib/commonjs/hooks/useProvider.js.map +1 -1
- package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletList.js +62 -25
- package/lib/commonjs/partials/w3m-all-wallets-list/components/WalletList.js.map +1 -1
- package/lib/commonjs/partials/w3m-all-wallets-list/index.js +1 -1
- package/lib/commonjs/partials/w3m-all-wallets-list/index.js.map +1 -1
- package/lib/commonjs/partials/w3m-all-wallets-search/index.js +1 -0
- package/lib/commonjs/partials/w3m-all-wallets-search/index.js.map +1 -1
- package/lib/commonjs/views/w3m-connect-view/components/all-wallet-list.js +28 -3
- package/lib/commonjs/views/w3m-connect-view/components/all-wallet-list.js.map +1 -1
- package/lib/module/AppKit.js +12 -11
- package/lib/module/AppKit.js.map +1 -1
- package/lib/module/hooks/useProvider.js +21 -9
- package/lib/module/hooks/useProvider.js.map +1 -1
- package/lib/module/partials/w3m-all-wallets-list/components/WalletList.js +63 -26
- package/lib/module/partials/w3m-all-wallets-list/components/WalletList.js.map +1 -1
- package/lib/module/partials/w3m-all-wallets-list/index.js +1 -1
- package/lib/module/partials/w3m-all-wallets-list/index.js.map +1 -1
- package/lib/module/partials/w3m-all-wallets-search/index.js +1 -0
- package/lib/module/partials/w3m-all-wallets-search/index.js.map +1 -1
- package/lib/module/views/w3m-connect-view/components/all-wallet-list.js +29 -4
- package/lib/module/views/w3m-connect-view/components/all-wallet-list.js.map +1 -1
- package/lib/typescript/AppKit.d.ts +1 -1
- package/lib/typescript/AppKit.d.ts.map +1 -1
- package/lib/typescript/hooks/useAppKitEvents.d.ts +13 -0
- package/lib/typescript/hooks/useAppKitEvents.d.ts.map +1 -1
- package/lib/typescript/hooks/useProvider.d.ts.map +1 -1
- package/lib/typescript/partials/w3m-all-wallets-list/components/WalletList.d.ts +2 -1
- package/lib/typescript/partials/w3m-all-wallets-list/components/WalletList.d.ts.map +1 -1
- package/lib/typescript/partials/w3m-all-wallets-search/index.d.ts.map +1 -1
- package/lib/typescript/views/w3m-connect-view/components/all-wallet-list.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/AppKit.ts +13 -11
- package/src/hooks/useProvider.ts +15 -6
- package/src/partials/w3m-all-wallets-list/components/WalletList.tsx +73 -25
- package/src/partials/w3m-all-wallets-list/index.tsx +1 -1
- package/src/partials/w3m-all-wallets-search/index.tsx +8 -1
- package/src/views/w3m-connect-view/components/all-wallet-list.tsx +40 -11
package/src/AppKit.ts
CHANGED
|
@@ -214,6 +214,7 @@ export class AppKit {
|
|
|
214
214
|
SendController.resetState();
|
|
215
215
|
OnRampController.resetState();
|
|
216
216
|
WcController.resetState();
|
|
217
|
+
EventsController.resetState();
|
|
217
218
|
|
|
218
219
|
if (ConnectionsController.state.activeNamespace === undefined) {
|
|
219
220
|
ConnectionsController.setActiveNamespace(
|
|
@@ -244,7 +245,7 @@ export class AppKit {
|
|
|
244
245
|
/**
|
|
245
246
|
* Returns the provider for a given namespace.
|
|
246
247
|
* @param namespace - The namespace to get the provider for.
|
|
247
|
-
* @returns The provider for the given namespace.
|
|
248
|
+
* @returns The provider for the given namespace, or null if not available or not yet initialized.
|
|
248
249
|
*/
|
|
249
250
|
getProvider<T extends Provider>(namespace?: string): T | null {
|
|
250
251
|
const activeNamespace = namespace ?? ConnectionsController.state.activeNamespace;
|
|
@@ -255,7 +256,15 @@ export class AppKit {
|
|
|
255
256
|
);
|
|
256
257
|
if (!connection || !connection.adapter || !connection.adapter.connector) return null;
|
|
257
258
|
|
|
258
|
-
|
|
259
|
+
try {
|
|
260
|
+
return connection.adapter.connector.getProvider() as T | null;
|
|
261
|
+
} catch (error) {
|
|
262
|
+
// Provider not initialized yet during session restoration
|
|
263
|
+
// This can happen on app restart when restoring a previous connection
|
|
264
|
+
LogController.sendError(error, 'AppKit.ts', 'getProvider');
|
|
265
|
+
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
259
268
|
}
|
|
260
269
|
|
|
261
270
|
getNetworks() {
|
|
@@ -308,6 +317,7 @@ export class AppKit {
|
|
|
308
317
|
|
|
309
318
|
RouterUtil.checkOnRampBack();
|
|
310
319
|
RouterUtil.checkSocialLoginBack();
|
|
320
|
+
EventsController.sendWalletImpressions();
|
|
311
321
|
}
|
|
312
322
|
|
|
313
323
|
back() {
|
|
@@ -634,12 +644,6 @@ export class AppKit {
|
|
|
634
644
|
const namespace = adapter.getSupportedNamespace();
|
|
635
645
|
const chain = `${namespace}:${chainId}` as CaipNetworkId;
|
|
636
646
|
|
|
637
|
-
const activeNetwork = ConnectionsController.getActiveNetworkId(namespace);
|
|
638
|
-
if (activeNetwork === chain) {
|
|
639
|
-
// No need to update the active network
|
|
640
|
-
return;
|
|
641
|
-
}
|
|
642
|
-
|
|
643
647
|
ConnectionsController.setActiveNetwork(namespace, chain);
|
|
644
648
|
|
|
645
649
|
const connection = ConnectionsController.state.connections.get(namespace);
|
|
@@ -692,10 +696,8 @@ export class AppKit {
|
|
|
692
696
|
this.setCustomWallets(options);
|
|
693
697
|
OptionsController.setFeaturedWalletIds(options.featuredWalletIds);
|
|
694
698
|
OptionsController.setEnableAnalytics(options.enableAnalytics);
|
|
695
|
-
OptionsController.setDebug(options.debug
|
|
699
|
+
OptionsController.setDebug(options.debug);
|
|
696
700
|
|
|
697
|
-
// Initialize LogController after debug option is set
|
|
698
|
-
LogController.initialize();
|
|
699
701
|
LogController.sendInfo('AppKit initialization started', 'AppKit.ts', 'initControllers', {
|
|
700
702
|
projectId: options.projectId,
|
|
701
703
|
adapters: this.adapters.map(a => a.constructor.name),
|
package/src/hooks/useProvider.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable valtio/state-snapshot-rule */
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { useSnapshot } from 'valtio';
|
|
4
|
-
import { ConnectionsController } from '@reown/appkit-core-react-native';
|
|
4
|
+
import { ConnectionsController, LogController } from '@reown/appkit-core-react-native';
|
|
5
5
|
import type { Provider, ChainNamespace } from '@reown/appkit-common-react-native';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -40,12 +40,21 @@ export function useProvider(): ProviderResult {
|
|
|
40
40
|
const { connection } = useSnapshot(ConnectionsController.state);
|
|
41
41
|
|
|
42
42
|
const returnValue = useMemo(() => {
|
|
43
|
-
if (!connection)
|
|
43
|
+
if (!connection || !connection.adapter) {
|
|
44
|
+
return { provider: undefined, providerType: undefined };
|
|
45
|
+
}
|
|
44
46
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
try {
|
|
48
|
+
return {
|
|
49
|
+
provider: connection.adapter.getProvider(),
|
|
50
|
+
providerType: connection.adapter.getSupportedNamespace()
|
|
51
|
+
};
|
|
52
|
+
} catch (error) {
|
|
53
|
+
LogController.sendError(error, 'useProvider', 'useProvider');
|
|
54
|
+
|
|
55
|
+
// Provider not initialized yet during session restoration
|
|
56
|
+
return { provider: undefined, providerType: undefined };
|
|
57
|
+
}
|
|
49
58
|
}, [connection]);
|
|
50
59
|
|
|
51
60
|
return returnValue;
|
|
@@ -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
|
|
|
@@ -25,6 +26,7 @@ interface Props {
|
|
|
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,34 +116,18 @@ export function WalletList({
|
|
|
52
116
|
data={displayData}
|
|
53
117
|
style={[styles.list, { height: maxHeight }, style]}
|
|
54
118
|
columnWrapperStyle={styles.columnWrapperStyle}
|
|
55
|
-
renderItem={
|
|
56
|
-
if (isLoading) {
|
|
57
|
-
return <CardSelectLoader style={styles.itemContainer} />;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return (
|
|
61
|
-
<WalletItem
|
|
62
|
-
item={item}
|
|
63
|
-
imageHeaders={imageHeaders}
|
|
64
|
-
displayIndex={index}
|
|
65
|
-
onItemPress={onItemPress}
|
|
66
|
-
style={styles.itemContainer}
|
|
67
|
-
testID={testIDKey ? `${testIDKey}-${item?.id}` : undefined}
|
|
68
|
-
/>
|
|
69
|
-
);
|
|
70
|
-
}}
|
|
119
|
+
renderItem={renderItem}
|
|
71
120
|
contentContainerStyle={[styles.contentContainer, { paddingHorizontal: padding }]}
|
|
72
121
|
initialNumToRender={32}
|
|
73
122
|
maxToRenderPerBatch={12}
|
|
74
123
|
windowSize={10}
|
|
75
124
|
onEndReached={onEndReached}
|
|
76
125
|
onEndReachedThreshold={onEndReachedThreshold}
|
|
77
|
-
keyExtractor={
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
})}
|
|
126
|
+
keyExtractor={keyExtractor}
|
|
127
|
+
removeClippedSubviews={true}
|
|
128
|
+
getItemLayout={getItemLayout}
|
|
129
|
+
onViewableItemsChanged={onViewableItemsChanged}
|
|
130
|
+
viewabilityConfig={viewabilityConfig}
|
|
83
131
|
/>
|
|
84
132
|
);
|
|
85
133
|
}
|
|
@@ -84,5 +84,12 @@ export function AllWalletsSearch({ searchQuery, onItemPress }: AllWalletsSearchP
|
|
|
84
84
|
);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
-
return
|
|
87
|
+
return (
|
|
88
|
+
<WalletList
|
|
89
|
+
onItemPress={onItemPress}
|
|
90
|
+
searchQuery={searchQuery}
|
|
91
|
+
data={results}
|
|
92
|
+
testIDKey="wallet-search-item"
|
|
93
|
+
/>
|
|
94
|
+
);
|
|
88
95
|
}
|
|
@@ -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,6 +12,7 @@ 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>;
|
|
@@ -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
|
-
|
|
28
|
-
|
|
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
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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;
|