🌐 API Endpoints Configuration

Monitor and understand which API endpoints are being used for each feature.

⚠️ CRITICAL: LIVE vs CACHED Consistency

Problem: Mixing LIVE blockchain RPC and CACHED API endpoints causes errors like "You have 0 but you just claimed it!"

Rule: ALL wallet ownership checks (eligibility, claim, blend, unpack) MUST use the same source.

Current Standard: Use getUserAssetsLive() everywhere for real-time blockchain data.

🟢 LIVE Blockchain RPC Endpoints (Real-Time)

Direct blockchain queries via RPC - no cache, instant updates after transactions.

getUserAssetsLive()
LIVE RPC
Purpose: Get user's assets directly from blockchain atomicassets contract
Primary RPC: https://api.wax.alohaeos.com
Fallbacks: wax.greymass.com, api.waxsweden.org, wax.eosphere.io
Method: POST /v1/chain/get_table_rows
Table Query: atomicassets.assets (scope: user account)
Cache Lag: 0 seconds (instant)
Used By:
✅ /api/user/eligibility (server.js:164)
✅ /api/user/claim (server.js:481)
✅ /api/assets/:account (server.js:2443) - FOR BLEND SELECTION
✅ /api/user/assets-rpc/:account/:template_id (server.js:1555)
Unpack RPC Query
LIVE RPC
Purpose: Query atomicpacksx contract for unpacked pack rolls
Contract: atomicpacksx
Tables: unboxassets, unboxpacks, packs
Used By:
✅ /api/pack/unboxed-rolls/:packAssetId (server.js:1719)
✅ story.js doUnpack() function (frontend)
Blend RPC Query
LIVE RPC
Purpose: Query blenderizerx contract for blend configuration
Contract: blenderizerx
Table: blends
Used By:
✅ admin-workflow.js queryBlendFromChain() (URL auto-fetch)
✅ story.js executeBlendArray() (frontend)

🟡 CACHED API Endpoints (Template Metadata Only)

AtomicAssets API - used ONLY for template images/metadata. Has 30-120 second cache lag.

AtomicAssets API
CACHED
Purpose: Fetch template images, names, and metadata for display purposes ONLY
Primary: https://aa-wax-public1.neftyblocks.com
Fallbacks: wax-aa.eosdac.io, atomic-wax-mainnet.wecan.dev, wax-atomic-api.eosphere.io
Cache Lag: 30-120 seconds
Safe Uses (metadata only):
✅ /api/templates/:template_id (server.js:2413) - Get template image/name
✅ story.js fetchUnpackedAssetDetails() - Get asset images for modal
✅ eligibility.js - Get template images for display

❌ NEVER use for:
❌ Wallet ownership checks
❌ Claim verification
❌ Blend ingredient checking
❌ Unpack eligibility

🔵 Application API Endpoints

Internal backend endpoints - check which data source they use.

/api/user/eligibility
LIVE RPC
Purpose: Check which NFTs user owns and can claim rewards for
Backend Method: wax.getUserAssetsLive()
File: server.js:164
/api/user/claim
LIVE RPC
Purpose: Verify user owns NFT before minting reward
Backend Method: wax.getUserAssetsLive()
File: server.js:481
✅ CORRECT: Uses same LIVE source as eligibility check
/api/assets/:account
LIVE RPC
Purpose: Fetch user's assets for blend/unpack ingredient selection
Backend Method: wax.getUserAssetsLive()
File: server.js:2443
Status: ✅ FIXED - Now uses LIVE RPC
Recent Fix: Changed from getUserAssets() (cached) to getUserAssetsLive() (live)
Commit: 122a37f - Fix blend asset selection to use LIVE blockchain RPC
/api/user/assets-rpc/:account/:template_id
LIVE RPC
Purpose: Check if user owns specific template (for pack unpack eligibility)
Query Method: Direct atomicassets RPC query
File: server.js:1555
/api/pack/unboxed-rolls/:packAssetId
LIVE RPC
Purpose: Check if pack has been unpacked and get roll IDs
Contract Query: atomicpacksx.unboxassets
File: server.js:1719

📋 Best Practices & Guidelines

When to Use LIVE RPC:

When to Use CACHED API:

How NeftyBlocks Does It:

NeftyBlocks likely uses:
1. Direct database access to their own indexed blockchain data
2. Real-time WebSocket subscriptions to blockchain events
3. Their own API infrastructure with sub-second indexing
4. Cached layers for metadata but LIVE queries for ownership

We use:
- Public RPC nodes (alohaeos, greymass, etc.) for LIVE data
- Public AtomicAssets APIs for metadata only
- This is standard for independent dApps without custom infrastructure

Common Mistakes:

❌ NEVER DO THIS:

// Checking eligibility with LIVE:
const eligibleAssets = await wax.getUserAssetsLive(account);

// Then verifying claim with CACHED:
const verifyAssets = await wax.getUserAssets(account); // ❌ WRONG!

✅ ALWAYS DO THIS:

// Use same source for everything:
const eligibleAssets = await wax.getUserAssetsLive(account);
const verifyAssets = await wax.getUserAssetsLive(account); // ✅ CORRECT!