@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 +111 -0
- package/dist/package.json +1 -1
- package/package.json +1 -1
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
package/package.json
CHANGED