@explorins/pers-sdk-react-native 1.5.34 → 1.5.35

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.
@@ -15,4 +15,5 @@ export { useAnalytics } from './useAnalytics';
15
15
  export { useDonations } from './useDonations';
16
16
  export type { RawUserData } from './useAuth';
17
17
  export type { TransactionSignerHook, SubmissionResult, AuthenticatedUser, TransactionSigningResult, StatusUpdateData, OnStatusUpdateFn, SigningStatus as SigningStatusType } from './useTransactionSigner';
18
+ export type { UserOwnedTokensResult, Web3Hook } from './useWeb3';
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC"}
@@ -1,5 +1,17 @@
1
1
  import type { TokenBalance, TokenBalanceRequest, TokenCollectionRequest, TokenCollection, TokenMetadata } from '@explorins/pers-sdk/web3';
2
2
  import type { ChainData } from '@explorins/pers-sdk/web3-chain';
3
+ import type { TokenDTO } from '@explorins/pers-shared';
4
+ /**
5
+ * Result of getting user's owned tokens from a contract
6
+ */
7
+ export interface UserOwnedTokensResult {
8
+ /** The token definition (contains contract info, ABI, metadata definitions) */
9
+ token: TokenDTO;
10
+ /** Array of token balances the user owns (filtered to hasBalance: true) */
11
+ ownedTokens: readonly TokenBalance[];
12
+ /** Total count of owned tokens */
13
+ totalOwned: number;
14
+ }
3
15
  /**
4
16
  * React hook for Web3 operations in the PERS SDK
5
17
  *
@@ -9,9 +21,48 @@ import type { ChainData } from '@explorins/pers-sdk/web3-chain';
9
21
  *
10
22
  * Note: Wallet addresses should be obtained from `user.wallets` via `usePersSDK()`.
11
23
  *
24
+ * ## ERC-1155 Token Handling
25
+ *
26
+ * **IMPORTANT**: ERC-1155 tokens require specific `tokenIds` to query balances.
27
+ * Unlike ERC-721, you cannot enumerate owned tokens - you must know which tokenId to check.
28
+ *
29
+ * The tokenIds come from `TokenDTO.metadata[].tokenMetadataIncrementalId`.
30
+ *
31
+ * ### Option 1: Use the helper method (Recommended)
32
+ * ```typescript
33
+ * const { getUserOwnedTokensFromContract } = useWeb3();
34
+ * const { getRewardTokens } = useTokens();
35
+ *
36
+ * const rewardTokens = await getRewardTokens();
37
+ * const result = await getUserOwnedTokensFromContract(walletAddress, rewardTokens[0]);
38
+ * console.log('Owned rewards:', result.ownedTokens);
39
+ * ```
40
+ *
41
+ * ### Option 2: Manual tokenIds extraction
42
+ * ```typescript
43
+ * const { getTokenCollection, extractTokenIds } = useWeb3();
44
+ * const { getRewardTokens } = useTokens();
45
+ *
46
+ * const rewardTokens = await getRewardTokens();
47
+ * const rewardToken = rewardTokens[0];
48
+ *
49
+ * // Extract tokenIds for ERC-1155
50
+ * const tokenIds = extractTokenIds(rewardToken);
51
+ *
52
+ * const collection = await getTokenCollection({
53
+ * accountAddress: walletAddress,
54
+ * contractAddress: rewardToken.contractAddress,
55
+ * abi: rewardToken.abi,
56
+ * chainId: rewardToken.chainId,
57
+ * tokenIds: tokenIds // Required for ERC-1155!
58
+ * });
59
+ *
60
+ * const ownedTokens = collection.tokens.filter(t => t.hasBalance);
61
+ * ```
62
+ *
12
63
  * @returns Web3 hook with methods for blockchain operations
13
64
  *
14
- * @example
65
+ * @example Basic Usage
15
66
  * ```typescript
16
67
  * function Web3Component() {
17
68
  * const { user } = usePersSDK();
@@ -58,6 +109,9 @@ export declare const useWeb3: () => {
58
109
  fetchAndProcessMetadata: (tokenUri: string, chainId: number) => Promise<TokenMetadata | null>;
59
110
  getChainDataById: (chainId: number) => Promise<ChainData | null>;
60
111
  getExplorerUrl: (chainId: number, address: string, type: 'address' | 'tx') => Promise<string>;
112
+ extractTokenIds: (token: TokenDTO) => string[] | undefined;
113
+ getUserOwnedTokensFromContract: (walletAddress: string, token: TokenDTO, maxTokens?: number) => Promise<UserOwnedTokensResult>;
114
+ buildCollectionRequest: (walletAddress: string, token: TokenDTO, maxTokens?: number) => TokenCollectionRequest;
61
115
  isAvailable: boolean;
62
116
  };
63
117
  export type Web3Hook = ReturnType<typeof useWeb3>;
@@ -1 +1 @@
1
- {"version":3,"file":"useWeb3.d.ts","sourceRoot":"","sources":["../../src/hooks/useWeb3.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,eAAO,MAAM,OAAO;+BA0BkC,mBAAmB,KAAG,QAAQ,YAAY,CAAC;gCAiC1C,mBAAmB,KAAG,QAAQ,aAAa,GAAG,IAAI,CAAC;kCAcjD,sBAAsB,KAAG,QAAQ,eAAe,CAAC;0BAczD,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC;wCAc3B,MAAM,WAAW,MAAM,KAAG,QAAQ,aAAa,GAAG,IAAI,CAAC;gCAc/D,MAAM,KAAG,QAAQ,SAAS,GAAG,IAAI,CAAC;8BAcpC,MAAM,WAAW,MAAM,QAAQ,SAAS,GAAG,IAAI,KAAG,QAAQ,MAAM,CAAC;;CAwBrH,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC"}
1
+ {"version":3,"file":"useWeb3.d.ts","sourceRoot":"","sources":["../../src/hooks/useWeb3.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,aAAa,EACd,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAGvD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+EAA+E;IAC/E,KAAK,EAAE,QAAQ,CAAC;IAChB,2EAA2E;IAC3E,WAAW,EAAE,SAAS,YAAY,EAAE,CAAC;IACrC,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwFG;AACH,eAAO,MAAM,OAAO;+BA0BkC,mBAAmB,KAAG,QAAQ,YAAY,CAAC;gCAiC1C,mBAAmB,KAAG,QAAQ,aAAa,GAAG,IAAI,CAAC;kCAcjD,sBAAsB,KAAG,QAAQ,eAAe,CAAC;0BAgKzD,MAAM,WAAW,MAAM,KAAG,QAAQ,MAAM,CAAC;wCAc3B,MAAM,WAAW,MAAM,KAAG,QAAQ,aAAa,GAAG,IAAI,CAAC;gCAc/D,MAAM,KAAG,QAAQ,SAAS,GAAG,IAAI,CAAC;8BAcpC,MAAM,WAAW,MAAM,QAAQ,SAAS,GAAG,IAAI,KAAG,QAAQ,MAAM,CAAC;6BAhKxE,QAAQ,KAAG,MAAM,EAAE,GAAG,SAAS;oDA6C1D,MAAM,SACd,QAAQ,cACJ,MAAM,KAChB,QAAQ,qBAAqB,CAAC;4CAwDhB,MAAM,SACd,QAAQ,cACJ,MAAM,KAChB,sBAAsB;;CAmF1B,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,OAAO,CAAC,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from 'react';
2
2
  import { usePersSDK } from '../providers/PersSDKProvider';
3
+ import { NativeTokenTypes } from '@explorins/pers-shared';
3
4
  /**
4
5
  * React hook for Web3 operations in the PERS SDK
5
6
  *
@@ -9,9 +10,48 @@ import { usePersSDK } from '../providers/PersSDKProvider';
9
10
  *
10
11
  * Note: Wallet addresses should be obtained from `user.wallets` via `usePersSDK()`.
11
12
  *
13
+ * ## ERC-1155 Token Handling
14
+ *
15
+ * **IMPORTANT**: ERC-1155 tokens require specific `tokenIds` to query balances.
16
+ * Unlike ERC-721, you cannot enumerate owned tokens - you must know which tokenId to check.
17
+ *
18
+ * The tokenIds come from `TokenDTO.metadata[].tokenMetadataIncrementalId`.
19
+ *
20
+ * ### Option 1: Use the helper method (Recommended)
21
+ * ```typescript
22
+ * const { getUserOwnedTokensFromContract } = useWeb3();
23
+ * const { getRewardTokens } = useTokens();
24
+ *
25
+ * const rewardTokens = await getRewardTokens();
26
+ * const result = await getUserOwnedTokensFromContract(walletAddress, rewardTokens[0]);
27
+ * console.log('Owned rewards:', result.ownedTokens);
28
+ * ```
29
+ *
30
+ * ### Option 2: Manual tokenIds extraction
31
+ * ```typescript
32
+ * const { getTokenCollection, extractTokenIds } = useWeb3();
33
+ * const { getRewardTokens } = useTokens();
34
+ *
35
+ * const rewardTokens = await getRewardTokens();
36
+ * const rewardToken = rewardTokens[0];
37
+ *
38
+ * // Extract tokenIds for ERC-1155
39
+ * const tokenIds = extractTokenIds(rewardToken);
40
+ *
41
+ * const collection = await getTokenCollection({
42
+ * accountAddress: walletAddress,
43
+ * contractAddress: rewardToken.contractAddress,
44
+ * abi: rewardToken.abi,
45
+ * chainId: rewardToken.chainId,
46
+ * tokenIds: tokenIds // Required for ERC-1155!
47
+ * });
48
+ *
49
+ * const ownedTokens = collection.tokens.filter(t => t.hasBalance);
50
+ * ```
51
+ *
12
52
  * @returns Web3 hook with methods for blockchain operations
13
53
  *
14
- * @example
54
+ * @example Basic Usage
15
55
  * ```typescript
16
56
  * function Web3Component() {
17
57
  * const { user } = usePersSDK();
@@ -132,6 +172,138 @@ export const useWeb3 = () => {
132
172
  throw error;
133
173
  }
134
174
  }, [sdk, isInitialized]);
175
+ /**
176
+ * Extract tokenIds from a TokenDTO for use with ERC-1155 contracts.
177
+ *
178
+ * ERC-1155 tokens require specific tokenIds to query balances. This helper
179
+ * extracts the `tokenMetadataIncrementalId` from each metadata entry.
180
+ *
181
+ * @param token - Token definition containing metadata array
182
+ * @returns Array of tokenId strings, or undefined if no metadata
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const { extractTokenIds, getTokenCollection } = useWeb3();
187
+ * const { getRewardTokens } = useTokens();
188
+ *
189
+ * const rewardToken = (await getRewardTokens())[0];
190
+ * const tokenIds = extractTokenIds(rewardToken);
191
+ *
192
+ * if (tokenIds) {
193
+ * const collection = await getTokenCollection({
194
+ * accountAddress: walletAddress,
195
+ * contractAddress: rewardToken.contractAddress,
196
+ * abi: rewardToken.abi,
197
+ * chainId: rewardToken.chainId,
198
+ * tokenIds: tokenIds
199
+ * });
200
+ * }
201
+ * ```
202
+ */
203
+ const extractTokenIds = useCallback((token) => {
204
+ if (!token.metadata || token.metadata.length === 0) {
205
+ return undefined;
206
+ }
207
+ return token.metadata.map(meta => meta.tokenMetadataIncrementalId.toString());
208
+ }, []);
209
+ /**
210
+ * Get user's owned tokens from a specific token contract.
211
+ *
212
+ * This is a convenience method that automatically handles:
213
+ * - ERC-1155 tokenId extraction from metadata
214
+ * - Building the collection request
215
+ * - Filtering to only tokens with balance > 0
216
+ *
217
+ * **This is the recommended way to get user's owned reward/status tokens.**
218
+ *
219
+ * @param walletAddress - User's wallet address
220
+ * @param token - Token definition (from getRewardTokens, getStatusTokens, etc.)
221
+ * @param maxTokens - Maximum tokens to retrieve (default: 50)
222
+ * @returns Promise resolving to result with owned tokens
223
+ * @throws Error if SDK is not initialized
224
+ *
225
+ * @example Get User's Owned Rewards
226
+ * ```typescript
227
+ * const { user } = usePersSDK();
228
+ * const { getRewardTokens } = useTokens();
229
+ * const { getUserOwnedTokensFromContract } = useWeb3();
230
+ *
231
+ * const walletAddress = user?.wallets?.[0]?.address;
232
+ * const rewardTokens = await getRewardTokens();
233
+ *
234
+ * for (const token of rewardTokens) {
235
+ * const result = await getUserOwnedTokensFromContract(walletAddress, token);
236
+ *
237
+ * console.log(`${token.name}: ${result.totalOwned} owned`);
238
+ * result.ownedTokens.forEach(owned => {
239
+ * console.log(` - TokenId ${owned.tokenId}: ${owned.balance}`);
240
+ * console.log(` Name: ${owned.metadata?.name}`);
241
+ * console.log(` Image: ${owned.metadata?.imageUrl}`);
242
+ * });
243
+ * }
244
+ * ```
245
+ */
246
+ const getUserOwnedTokensFromContract = useCallback(async (walletAddress, token, maxTokens = 50) => {
247
+ if (!isInitialized || !sdk) {
248
+ throw new Error('SDK not initialized. Call initialize() first.');
249
+ }
250
+ try {
251
+ // For ERC-1155, extract tokenIds from metadata
252
+ const tokenIds = token.type === NativeTokenTypes.ERC1155 ? extractTokenIds(token) : undefined;
253
+ const collection = await sdk.web3.getTokenCollection({
254
+ accountAddress: walletAddress,
255
+ contractAddress: token.contractAddress,
256
+ abi: token.abi,
257
+ chainId: token.chainId,
258
+ tokenIds,
259
+ maxTokens
260
+ });
261
+ // Filter to only owned tokens (hasBalance: true)
262
+ // For ERC721, include all since they're enumerated
263
+ const ownedTokens = token.type === NativeTokenTypes.ERC721
264
+ ? collection.tokens
265
+ : collection.tokens.filter(t => t.hasBalance);
266
+ return {
267
+ token,
268
+ ownedTokens,
269
+ totalOwned: ownedTokens.length
270
+ };
271
+ }
272
+ catch (error) {
273
+ console.error('Failed to get user owned tokens:', error);
274
+ throw error;
275
+ }
276
+ }, [sdk, isInitialized, extractTokenIds]);
277
+ /**
278
+ * Build a TokenCollectionRequest from a TokenDTO.
279
+ *
280
+ * Automatically handles ERC-1155 tokenId extraction from metadata.
281
+ * Use this when you need more control over the request than
282
+ * `getUserOwnedTokensFromContract` provides.
283
+ *
284
+ * @param walletAddress - User's wallet address
285
+ * @param token - Token definition
286
+ * @param maxTokens - Maximum tokens to retrieve (default: 50)
287
+ * @returns TokenCollectionRequest ready for getTokenCollection()
288
+ *
289
+ * @example
290
+ * ```typescript
291
+ * const { buildCollectionRequest, getTokenCollection } = useWeb3();
292
+ *
293
+ * const request = buildCollectionRequest(walletAddress, rewardToken);
294
+ * const collection = await getTokenCollection(request);
295
+ * ```
296
+ */
297
+ const buildCollectionRequest = useCallback((walletAddress, token, maxTokens = 50) => {
298
+ return {
299
+ accountAddress: walletAddress,
300
+ contractAddress: token.contractAddress,
301
+ abi: token.abi,
302
+ chainId: token.chainId,
303
+ tokenIds: token.type === NativeTokenTypes.ERC1155 ? extractTokenIds(token) : undefined,
304
+ maxTokens
305
+ };
306
+ }, [extractTokenIds]);
135
307
  const resolveIPFSUrl = useCallback(async (url, chainId) => {
136
308
  if (!isInitialized || !sdk) {
137
309
  throw new Error('SDK not initialized. Call initialize() first.');
@@ -185,6 +357,7 @@ export const useWeb3 = () => {
185
357
  }
186
358
  }, [sdk, isInitialized]);
187
359
  return {
360
+ // Core methods
188
361
  getTokenBalance,
189
362
  getTokenMetadata,
190
363
  getTokenCollection,
@@ -192,6 +365,11 @@ export const useWeb3 = () => {
192
365
  fetchAndProcessMetadata,
193
366
  getChainDataById,
194
367
  getExplorerUrl,
368
+ // Helper methods for ERC-1155 tokens
369
+ extractTokenIds,
370
+ getUserOwnedTokensFromContract,
371
+ buildCollectionRequest,
372
+ // State
195
373
  isAvailable: isInitialized && !!sdk?.web3,
196
374
  };
197
375
  };
package/dist/index.js CHANGED
@@ -2629,6 +2629,8 @@ exports.ApiKeyType = void 0;
2629
2629
  ApiKeyType["ADMIN_JWT_REFRESH_TOKEN"] = "ADMIN_JWT_REFRESH_TOKEN";
2630
2630
  ApiKeyType["USER_JWT_ACCESS_TOKEN"] = "USER_JWT_ACCESS_TOKEN";
2631
2631
  ApiKeyType["USER_JWT_REFRESH_TOKEN"] = "USER_JWT_REFRESH_TOKEN";
2632
+ ApiKeyType["BUSINESS_JWT_ACCESS_TOKEN"] = "BUSINESS_JWT_ACCESS_TOKEN";
2633
+ ApiKeyType["BUSINESS_JWT_REFRESH_TOKEN"] = "BUSINESS_JWT_REFRESH_TOKEN";
2632
2634
  ApiKeyType["BLOCKCHAIN_WRITER_JWT"] = "BLOCKCHAIN_WRITER_JWT";
2633
2635
  ApiKeyType["BLOCKCHAIN_READER_JWT"] = "BLOCKCHAIN_READER_JWT";
2634
2636
  ApiKeyType["TRANSACTION_JWT_ACCESS_TOKEN"] = "TRANSACTION_JWT_ACCESS_TOKEN";
@@ -34454,9 +34456,48 @@ const useRedemptions = () => {
34454
34456
  *
34455
34457
  * Note: Wallet addresses should be obtained from `user.wallets` via `usePersSDK()`.
34456
34458
  *
34459
+ * ## ERC-1155 Token Handling
34460
+ *
34461
+ * **IMPORTANT**: ERC-1155 tokens require specific `tokenIds` to query balances.
34462
+ * Unlike ERC-721, you cannot enumerate owned tokens - you must know which tokenId to check.
34463
+ *
34464
+ * The tokenIds come from `TokenDTO.metadata[].tokenMetadataIncrementalId`.
34465
+ *
34466
+ * ### Option 1: Use the helper method (Recommended)
34467
+ * ```typescript
34468
+ * const { getUserOwnedTokensFromContract } = useWeb3();
34469
+ * const { getRewardTokens } = useTokens();
34470
+ *
34471
+ * const rewardTokens = await getRewardTokens();
34472
+ * const result = await getUserOwnedTokensFromContract(walletAddress, rewardTokens[0]);
34473
+ * console.log('Owned rewards:', result.ownedTokens);
34474
+ * ```
34475
+ *
34476
+ * ### Option 2: Manual tokenIds extraction
34477
+ * ```typescript
34478
+ * const { getTokenCollection, extractTokenIds } = useWeb3();
34479
+ * const { getRewardTokens } = useTokens();
34480
+ *
34481
+ * const rewardTokens = await getRewardTokens();
34482
+ * const rewardToken = rewardTokens[0];
34483
+ *
34484
+ * // Extract tokenIds for ERC-1155
34485
+ * const tokenIds = extractTokenIds(rewardToken);
34486
+ *
34487
+ * const collection = await getTokenCollection({
34488
+ * accountAddress: walletAddress,
34489
+ * contractAddress: rewardToken.contractAddress,
34490
+ * abi: rewardToken.abi,
34491
+ * chainId: rewardToken.chainId,
34492
+ * tokenIds: tokenIds // Required for ERC-1155!
34493
+ * });
34494
+ *
34495
+ * const ownedTokens = collection.tokens.filter(t => t.hasBalance);
34496
+ * ```
34497
+ *
34457
34498
  * @returns Web3 hook with methods for blockchain operations
34458
34499
  *
34459
- * @example
34500
+ * @example Basic Usage
34460
34501
  * ```typescript
34461
34502
  * function Web3Component() {
34462
34503
  * const { user } = usePersSDK();
@@ -34577,6 +34618,138 @@ const useWeb3 = () => {
34577
34618
  throw error;
34578
34619
  }
34579
34620
  }, [sdk, isInitialized]);
34621
+ /**
34622
+ * Extract tokenIds from a TokenDTO for use with ERC-1155 contracts.
34623
+ *
34624
+ * ERC-1155 tokens require specific tokenIds to query balances. This helper
34625
+ * extracts the `tokenMetadataIncrementalId` from each metadata entry.
34626
+ *
34627
+ * @param token - Token definition containing metadata array
34628
+ * @returns Array of tokenId strings, or undefined if no metadata
34629
+ *
34630
+ * @example
34631
+ * ```typescript
34632
+ * const { extractTokenIds, getTokenCollection } = useWeb3();
34633
+ * const { getRewardTokens } = useTokens();
34634
+ *
34635
+ * const rewardToken = (await getRewardTokens())[0];
34636
+ * const tokenIds = extractTokenIds(rewardToken);
34637
+ *
34638
+ * if (tokenIds) {
34639
+ * const collection = await getTokenCollection({
34640
+ * accountAddress: walletAddress,
34641
+ * contractAddress: rewardToken.contractAddress,
34642
+ * abi: rewardToken.abi,
34643
+ * chainId: rewardToken.chainId,
34644
+ * tokenIds: tokenIds
34645
+ * });
34646
+ * }
34647
+ * ```
34648
+ */
34649
+ const extractTokenIds = react.useCallback((token) => {
34650
+ if (!token.metadata || token.metadata.length === 0) {
34651
+ return undefined;
34652
+ }
34653
+ return token.metadata.map(meta => meta.tokenMetadataIncrementalId.toString());
34654
+ }, []);
34655
+ /**
34656
+ * Get user's owned tokens from a specific token contract.
34657
+ *
34658
+ * This is a convenience method that automatically handles:
34659
+ * - ERC-1155 tokenId extraction from metadata
34660
+ * - Building the collection request
34661
+ * - Filtering to only tokens with balance > 0
34662
+ *
34663
+ * **This is the recommended way to get user's owned reward/status tokens.**
34664
+ *
34665
+ * @param walletAddress - User's wallet address
34666
+ * @param token - Token definition (from getRewardTokens, getStatusTokens, etc.)
34667
+ * @param maxTokens - Maximum tokens to retrieve (default: 50)
34668
+ * @returns Promise resolving to result with owned tokens
34669
+ * @throws Error if SDK is not initialized
34670
+ *
34671
+ * @example Get User's Owned Rewards
34672
+ * ```typescript
34673
+ * const { user } = usePersSDK();
34674
+ * const { getRewardTokens } = useTokens();
34675
+ * const { getUserOwnedTokensFromContract } = useWeb3();
34676
+ *
34677
+ * const walletAddress = user?.wallets?.[0]?.address;
34678
+ * const rewardTokens = await getRewardTokens();
34679
+ *
34680
+ * for (const token of rewardTokens) {
34681
+ * const result = await getUserOwnedTokensFromContract(walletAddress, token);
34682
+ *
34683
+ * console.log(`${token.name}: ${result.totalOwned} owned`);
34684
+ * result.ownedTokens.forEach(owned => {
34685
+ * console.log(` - TokenId ${owned.tokenId}: ${owned.balance}`);
34686
+ * console.log(` Name: ${owned.metadata?.name}`);
34687
+ * console.log(` Image: ${owned.metadata?.imageUrl}`);
34688
+ * });
34689
+ * }
34690
+ * ```
34691
+ */
34692
+ const getUserOwnedTokensFromContract = react.useCallback(async (walletAddress, token, maxTokens = 50) => {
34693
+ if (!isInitialized || !sdk) {
34694
+ throw new Error('SDK not initialized. Call initialize() first.');
34695
+ }
34696
+ try {
34697
+ // For ERC-1155, extract tokenIds from metadata
34698
+ const tokenIds = token.type === NativeTokenTypes.ERC1155 ? extractTokenIds(token) : undefined;
34699
+ const collection = await sdk.web3.getTokenCollection({
34700
+ accountAddress: walletAddress,
34701
+ contractAddress: token.contractAddress,
34702
+ abi: token.abi,
34703
+ chainId: token.chainId,
34704
+ tokenIds,
34705
+ maxTokens
34706
+ });
34707
+ // Filter to only owned tokens (hasBalance: true)
34708
+ // For ERC721, include all since they're enumerated
34709
+ const ownedTokens = token.type === NativeTokenTypes.ERC721
34710
+ ? collection.tokens
34711
+ : collection.tokens.filter(t => t.hasBalance);
34712
+ return {
34713
+ token,
34714
+ ownedTokens,
34715
+ totalOwned: ownedTokens.length
34716
+ };
34717
+ }
34718
+ catch (error) {
34719
+ console.error('Failed to get user owned tokens:', error);
34720
+ throw error;
34721
+ }
34722
+ }, [sdk, isInitialized, extractTokenIds]);
34723
+ /**
34724
+ * Build a TokenCollectionRequest from a TokenDTO.
34725
+ *
34726
+ * Automatically handles ERC-1155 tokenId extraction from metadata.
34727
+ * Use this when you need more control over the request than
34728
+ * `getUserOwnedTokensFromContract` provides.
34729
+ *
34730
+ * @param walletAddress - User's wallet address
34731
+ * @param token - Token definition
34732
+ * @param maxTokens - Maximum tokens to retrieve (default: 50)
34733
+ * @returns TokenCollectionRequest ready for getTokenCollection()
34734
+ *
34735
+ * @example
34736
+ * ```typescript
34737
+ * const { buildCollectionRequest, getTokenCollection } = useWeb3();
34738
+ *
34739
+ * const request = buildCollectionRequest(walletAddress, rewardToken);
34740
+ * const collection = await getTokenCollection(request);
34741
+ * ```
34742
+ */
34743
+ const buildCollectionRequest = react.useCallback((walletAddress, token, maxTokens = 50) => {
34744
+ return {
34745
+ accountAddress: walletAddress,
34746
+ contractAddress: token.contractAddress,
34747
+ abi: token.abi,
34748
+ chainId: token.chainId,
34749
+ tokenIds: token.type === NativeTokenTypes.ERC1155 ? extractTokenIds(token) : undefined,
34750
+ maxTokens
34751
+ };
34752
+ }, [extractTokenIds]);
34580
34753
  const resolveIPFSUrl = react.useCallback(async (url, chainId) => {
34581
34754
  if (!isInitialized || !sdk) {
34582
34755
  throw new Error('SDK not initialized. Call initialize() first.');
@@ -34630,6 +34803,7 @@ const useWeb3 = () => {
34630
34803
  }
34631
34804
  }, [sdk, isInitialized]);
34632
34805
  return {
34806
+ // Core methods
34633
34807
  getTokenBalance,
34634
34808
  getTokenMetadata,
34635
34809
  getTokenCollection,
@@ -34637,6 +34811,11 @@ const useWeb3 = () => {
34637
34811
  fetchAndProcessMetadata,
34638
34812
  getChainDataById,
34639
34813
  getExplorerUrl,
34814
+ // Helper methods for ERC-1155 tokens
34815
+ extractTokenIds,
34816
+ getUserOwnedTokensFromContract,
34817
+ buildCollectionRequest,
34818
+ // State
34640
34819
  isAvailable: isInitialized && !!sdk?.web3,
34641
34820
  };
34642
34821
  };