@explorins/pers-sdk 1.6.40 → 1.6.41

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/README.md CHANGED
@@ -427,6 +427,117 @@ const statusTokens = await sdk.tokens.getStatusTokens();
427
427
  const token = await sdk.tokens.getTokenByContract('0x123...', 'token-id');
428
428
  ```
429
429
 
430
+ ### User Token Balances (On-Chain)
431
+
432
+ > **Important Architecture Note:** The PERS backend stores **token definitions** (contract addresses, ABIs, metadata), but does **NOT** store user token balances. User balances are queried directly from the blockchain via RPC calls using `sdk.web3.*` methods.
433
+
434
+ **Data Flow:**
435
+ 1. `sdk.tokens.*` → Get token definitions (contract address, ABI, chainId) from PERS backend
436
+ 2. `sdk.auth.getCurrentUser()` → Get user's wallet address
437
+ 3. `sdk.web3.*` → Query blockchain directly for user's token balance
438
+
439
+ #### Points Balance (ERC-20)
440
+
441
+ ```typescript
442
+ // Step 1: Get the credit token definition from PERS backend
443
+ const creditToken = await sdk.tokens.getActiveCreditToken();
444
+
445
+ // Step 2: Get user's wallet address
446
+ const user = await sdk.auth.getCurrentUser();
447
+ const walletAddress = user.wallets?.[0]?.address;
448
+
449
+ // Step 3: Query blockchain directly for balance
450
+ const balance = await sdk.web3.getTokenBalance({
451
+ accountAddress: walletAddress,
452
+ contractAddress: creditToken.contractAddress,
453
+ abi: creditToken.abi, // Raw ABI from backend works directly
454
+ chainId: creditToken.chainId,
455
+ tokenId: '' // Empty for ERC-20
456
+ });
457
+
458
+ console.log('Points balance:', balance.balance);
459
+ console.log('Has balance:', balance.hasBalance);
460
+ ```
461
+
462
+ #### Stamps Collection (ERC-721 / ERC-1155)
463
+
464
+ ```typescript
465
+ // Step 1: Get status token definitions (stamps/achievements)
466
+ const statusTokens = await sdk.tokens.getStatusTokens();
467
+
468
+ // Step 2: Get user's wallet address
469
+ const user = await sdk.auth.getCurrentUser();
470
+ const walletAddress = user.wallets?.[0]?.address;
471
+
472
+ // Step 3: Query blockchain for user's stamp collection
473
+ for (const stampToken of statusTokens) {
474
+ const collection = await sdk.web3.getTokenCollection({
475
+ accountAddress: walletAddress,
476
+ contractAddress: stampToken.contractAddress,
477
+ abi: stampToken.abi, // Raw ABI from backend works directly
478
+ chainId: stampToken.chainId,
479
+ maxTokens: 50 // Optional: limit results
480
+ });
481
+
482
+ // Filter to tokens with balance > 0
483
+ const ownedStamps = collection.tokens.filter(t => t.hasBalance && t.balance > 0);
484
+
485
+ console.log(`Stamps from ${stampToken.symbol}:`, ownedStamps.length);
486
+
487
+ // Each stamp includes metadata (name, description, image, etc.)
488
+ for (const stamp of ownedStamps) {
489
+ console.log(`- Token #${stamp.tokenId}: ${stamp.metadata?.name}`);
490
+ console.log(` Image: ${stamp.metadata?.imageUrl}`);
491
+ }
492
+ }
493
+ ```
494
+
495
+ #### Complete Example: Load All User Balances
496
+
497
+ ```typescript
498
+ async function loadUserTokenBalances(sdk: PersSDK) {
499
+ // Get user wallet
500
+ const user = await sdk.auth.getCurrentUser();
501
+ const walletAddress = user.wallets?.[0]?.address;
502
+ if (!walletAddress) throw new Error('User has no wallet');
503
+
504
+ // Get all token definitions
505
+ const [creditToken, statusTokens, rewardTokens] = await Promise.all([
506
+ sdk.tokens.getActiveCreditToken(),
507
+ sdk.tokens.getStatusTokens(),
508
+ sdk.tokens.getRewardTokens()
509
+ ]);
510
+
511
+ // Query ERC-20 balance (Points)
512
+ const pointsBalance = creditToken ? await sdk.web3.getTokenBalance({
513
+ accountAddress: walletAddress,
514
+ contractAddress: creditToken.contractAddress,
515
+ abi: creditToken.abi,
516
+ chainId: creditToken.chainId,
517
+ tokenId: ''
518
+ }) : null;
519
+
520
+ // Query ERC-721/ERC-1155 collections (Stamps, Rewards)
521
+ const allNftTokens = [...(statusTokens || []), ...(rewardTokens || [])];
522
+ const collections = await Promise.all(
523
+ allNftTokens.map(token =>
524
+ sdk.web3.getTokenCollection({
525
+ accountAddress: walletAddress,
526
+ contractAddress: token.contractAddress,
527
+ abi: token.abi,
528
+ chainId: token.chainId,
529
+ maxTokens: 100
530
+ }).catch(() => null) // Handle individual failures gracefully
531
+ )
532
+ );
533
+
534
+ return {
535
+ points: pointsBalance,
536
+ stamps: collections.filter(Boolean)
537
+ };
538
+ }
539
+ ```
540
+
430
541
  ### Purchase/Payment Processing
431
542
 
432
543
  ```typescript
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorins/pers-sdk",
3
- "version": "1.6.40",
3
+ "version": "1.6.41",
4
4
  "description": "Platform-agnostic SDK for PERS (Phygital Experience Rewards System) - Core business logic and API integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@explorins/pers-sdk",
3
- "version": "1.6.40",
3
+ "version": "1.6.41",
4
4
  "description": "Platform-agnostic SDK for PERS (Phygital Experience Rewards System) - Core business logic and API integration",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",