11import { useMutation , useQuery , useQueryClient } from "@tanstack/react-query" ;
2+ import type {
3+ ListUserWalletsData ,
4+ ListUserWalletsResponses ,
5+ } from "@thirdweb-dev/api" ;
6+ import { configure , listUserWallets } from "@thirdweb-dev/api" ;
27import { useActiveAccount } from "thirdweb/react" ;
38import type { WalletUser } from "thirdweb/wallets" ;
4- import { THIRDWEB_EWS_API_HOST } from "@/constants/urls" ;
9+ import { THIRDWEB_API_HOST } from "@/constants/urls" ;
510import { embeddedWalletsKeys } from "../query-keys/cache-keys" ;
611
12+ // Configure the API client to use the correct base URL
13+ configure ( {
14+ override : {
15+ baseUrl : THIRDWEB_API_HOST ,
16+ } ,
17+ } ) ;
18+
19+ // Extract types from the generated API
20+ type APIWallet = ListUserWalletsResponses [ 200 ] [ "result" ] [ "wallets" ] [ 0 ] ;
21+ type APIProfile = APIWallet [ "profiles" ] [ 0 ] ;
22+
723const fetchAccountList = ( {
824 jwt,
925 clientId,
@@ -18,37 +34,104 @@ const fetchAccountList = ({
1834 pageNumber : number ;
1935} ) => {
2036 return async ( ) => {
21- const url = new URL ( `${ THIRDWEB_EWS_API_HOST } /api/2024-05-05/account/list` ) ;
37+ try {
38+ // Prepare query parameters for the new API
39+ const queryParams : ListUserWalletsData [ "query" ] = {
40+ page : pageNumber ,
41+ limit : 50 , // Keep the same page size
42+ } ;
2243
23- // Add clientId or ecosystemSlug parameter
24- if ( ecosystemSlug ) {
25- url . searchParams . append ( "ecosystemSlug" , `ecosystem.${ ecosystemSlug } ` ) ;
26- } else if ( clientId ) {
27- url . searchParams . append ( "clientId" , clientId ) ;
28- }
44+ // Use the generated API function with Bearer authentication
45+ const response = await listUserWallets ( {
46+ query : queryParams ,
47+ headers : {
48+ Authorization : `Bearer ${ jwt } ` ,
49+ "Content-Type" : "application/json" ,
50+ "x-thirdweb-team-id" : teamId ,
51+ ...( clientId && { "x-client-id" : clientId } ) ,
52+ ...( ecosystemSlug && {
53+ "x-ecosystem-id" : `ecosystem.${ ecosystemSlug } ` ,
54+ } ) ,
55+ } ,
56+ } ) ;
2957
30- url . searchParams . append ( "page" , pageNumber . toString ( ) ) ;
31-
32- const res = await fetch ( url . href , {
33- headers : {
34- Authorization : `Bearer ${ jwt } ` ,
35- "Content-Type" : "application/json" ,
36- "x-thirdweb-team-id" : teamId ,
37- ...( clientId && { "x-client-id" : clientId } ) ,
38- } ,
39- method : "GET" ,
40- } ) ;
41- if ( ! res . ok ) {
42- throw new Error ( `Failed to fetch wallets: ${ await res . text ( ) } ` ) ;
43- }
58+ // Handle response
59+ if ( response . error || ! response . data ) {
60+ const errorMessage =
61+ typeof response . error === "string"
62+ ? response . error
63+ : "No data returned" ;
64+ throw new Error ( errorMessage ) ;
65+ }
4466
45- const json = await res . json ( ) ;
46- return json as {
47- users : WalletUser [ ] ;
48- } ;
67+ // Transform the response to match the expected format
68+ return {
69+ users : response . data . result . wallets . map ( transformToWalletUser ) ,
70+ hasMore : response . data . result . pagination . hasMore ?? false ,
71+ } ;
72+ } catch ( error ) {
73+ console . error ( "Failed to fetch wallets:" , error ) ;
74+ throw error ;
75+ }
4976 } ;
5077} ;
5178
79+ // Transform API response to match existing WalletUser format
80+ function transformToWalletUser ( apiWallet : APIWallet ) : WalletUser {
81+ return {
82+ id : getProfileId ( apiWallet . profiles [ 0 ] ) || "" ,
83+ linkedAccounts : apiWallet . profiles . map ( ( profile ) => {
84+ // Create details object based on the profile data
85+ let details :
86+ | { email : string ; [ key : string ] : string }
87+ | { phone : string ; [ key : string ] : string }
88+ | { address : string ; [ key : string ] : string }
89+ | { id : string ; [ key : string ] : string } ;
90+
91+ const profileId = getProfileId ( profile ) ;
92+
93+ if ( "email" in profile && profile . email ) {
94+ details = { email : profile . email , id : profileId } ;
95+ } else if ( "phone" in profile && profile . phone ) {
96+ details = { phone : profile . phone , id : profileId } ;
97+ } else if ( "walletAddress" in profile && profile . walletAddress ) {
98+ details = { address : profile . walletAddress , id : profileId } ;
99+ } else {
100+ details = { id : profileId } ;
101+ }
102+
103+ return {
104+ type : profile . type ,
105+ details,
106+ } ;
107+ } ) ,
108+ wallets : apiWallet . address
109+ ? [
110+ {
111+ address : apiWallet . address ,
112+ createdAt : apiWallet . createdAt || new Date ( ) . toISOString ( ) ,
113+ type : "enclave" as const ,
114+ } ,
115+ ]
116+ : [ ] ,
117+ } ;
118+ }
119+
120+ // Helper function to safely get ID from any profile type
121+ function getProfileId ( profile : APIProfile | undefined ) : string {
122+ if ( ! profile ) return "" ;
123+
124+ if ( "id" in profile ) {
125+ return profile . id ;
126+ } else if ( "credentialId" in profile ) {
127+ return profile . credentialId ;
128+ } else if ( "identifier" in profile ) {
129+ return profile . identifier ;
130+ }
131+
132+ return "" ;
133+ }
134+
52135export function useEmbeddedWallets ( params : {
53136 clientId ?: string ;
54137 ecosystemSlug ?: string ;
@@ -98,6 +181,7 @@ export function useAllEmbeddedWallets(params: { authToken: string }) {
98181 while ( true ) {
99182 const res = await queryClient . fetchQuery < {
100183 users : WalletUser [ ] ;
184+ hasMore : boolean ;
101185 } > ( {
102186 queryFn : fetchAccountList ( {
103187 clientId,
@@ -113,12 +197,13 @@ export function useAllEmbeddedWallets(params: { authToken: string }) {
113197 ) ,
114198 } ) ;
115199
116- if ( res . users . length === 0 ) {
200+ responses . push ( ...res . users ) ;
201+
202+ if ( ! res . hasMore ) {
117203 break ;
118204 }
119205
120206 page ++ ;
121- responses . push ( ...res . users ) ;
122207 }
123208
124209 return responses ;
0 commit comments