Web3 (Thirdweb / Moralis)
IntelliVerseX Web3 SDK — Wallet auth (MetaMask / WalletConnect), NFT rewards, token gating, and on-chain leaderboards backed by Nakama + Hiro.
Requirements
Installation
npm install @intelliversex/sdk-web3 @heroiclabs/nakama-js ethers
Quick Start
import { IVXWeb3Manager } from '@intelliversex/sdk-web3';
const ivx = IVXWeb3Manager.getInstance();
ivx.on('walletConnected', (info) => console.log('Wallet:', info.address));
ivx.on('authSuccess', (userId) => console.log('Authenticated:', userId));
ivx.initialize({
nakamaHost: '127.0.0.1',
nakamaPort: 7350,
chainId: 137, // Polygon
enableDebugLogs: true,
});
// Connect MetaMask
const wallet = await ivx.connectWallet();
// Authenticate via wallet signature
await ivx.authenticateWallet();
// Query NFTs owned by this wallet
const nfts = await ivx.fetchNfts('0xContractAddress');
// Token-gated content check
const hasAccess = await ivx.checkTokenGate('0xContractAddress', '1');
// Standard game features
const profile = await ivx.fetchProfile();
await ivx.submitScore('weekly_leaderboard', 2500);
API Surface
IVXWeb3Manager is a TypeScript singleton that follows the same Nakama-backed IVX manager pattern as Unity’s IntelliVerseX managers: one coordinator for auth, economy hooks, leaderboards, storage, and RPC. It does not literally extend a shared IVXManager class in TypeScript (there is no shared base class in npm); behavior and naming are aligned with the Unity IVX surface.
| Area | Symbol | Description |
| Type | IVXWeb3Manager | getInstance(), resetInstance() (tests) |
| Lifecycle | initialize(config) | Builds nakama-js Client, validates IVXWeb3Config |
| State | client, session, isInitialized, hasValidSession, userId, username | Mirrors standard IVX session model |
| Wallet info | walletInfo, walletAddress, isWalletConnected | Populated after connectWallet() |
Wallet methods
| Method / member | Notes |
connectWallet() | EIP-1193 (window.ethereum), BrowserProvider, requests accounts, emits walletConnected |
disconnectWallet() | Clears provider/signer/local wallet state only (no chain revoke) |
getWalletAddress | Use walletAddress getter (or walletInfo?.address) |
signMessage | Not a public API. Signing runs inside authenticateWallet() (signer.signMessage with the IntelliVerseX auth payload). For custom messages, use ethers with the same EIP-1193 provider after connectWallet() |
NFT methods
| Method | Notes |
fetchNfts(contractAddress?) | RPC ivx_web3_fetch_nfts — server may use Moralis / Alchemy / Thirdweb |
checkTokenGate(contractAddress, minBalance?) | RPC ivx_web3_check_gate — server-side balance / ownership check |
Token methods
| Method | Notes |
fetchTokenBalances() | RPC ivx_web3_fetch_tokens — ERC-20 style balances for connected wallet |
transferToken | Not built-in. Use callRpc() with your game’s Nakama RPC (e.g. intent to transfer, relayed tx), or Hiro economy RPCs such as grantCurrency / hiro_economy_* — never move user funds from the SDK without explicit wallet transactions |
Standard IVX-style methods (Nakama session)
| Method | Notes |
authenticateWallet() | Custom auth path + ivx_web3_verify_wallet RPC |
authenticateDevice(deviceId?) | Device fallback when Web3 is optional |
clearSession() | Clears Nakama session locally |
fetchProfile, updateProfile | Account API |
fetchWallet, grantCurrency | Hiro economy via RPC |
submitScore, fetchLeaderboard | Leaderboards |
writeStorage, readStorage | User storage |
callRpc(rpcId, payload) | Generic Nakama RPC |
Events (on / off)
initialized, walletConnected, walletDisconnected, authSuccess, authError, profileLoaded, walletUpdated, leaderboardFetched, nftsFetched, tokenBalanceFetched, storageRead, rpcResponse, error — see IVXWeb3EventMap in the package typings.
Configuration (IVXWeb3Config)
| Field | Purpose |
gameId | IntelliVerseX title id from the developer dashboard (warns if empty) |
nakamaHost / nakamaPort / nakamaServerKey / useSSL | Nakama REST endpoint |
chainId | Default EVM chain for metadata and server hints (e.g. 137 Polygon) |
thirdwebClientId | Optional Thirdweb dashboard client id for server/indexer integrations |
moralisApiKey | Optional Moralis key — use only on the server; the field exists for BFF/RPC wiring |
enableAnalytics / enableDebugLogs / verboseLogging | Telemetry and console verbosity |
Defaults favor the hosted IntelliVerseX Nakama endpoint; override for local development as in Quick Start.
Feature Coverage
Legend: Y = included in this Web3 npm SDK, - = not in scope for the Web3 JS client, S = stub / use another IntelliVerseX SDK or host platform (e.g. Unity) for full support.
| Capability | Web3 |
| SDK init | Y |
| Device auth | Y |
| Custom auth (wallet signature) | Y |
| Profile | Y |
| Wallet / economy (Hiro RPC) | Y |
| Leaderboards | Y |
| Storage | Y |
| Nakama RPC | Y |
| Email auth | - |
| Google / Apple auth | - |
| Session restore (stored refresh flows) | - |
| Real-time socket | - |
| AI init | Y |
| AI voice / LLM | S |
| Game modes | S |
| Lobby / matchmaking | S |
| Hiro (live ops economy) | Y |
| Discord | S |
| Satori | S |
| Web3 / NFT gating | Y |
| WebGL / browser target | Y |
Web3-Specific Features
| Feature | Status |
| Wallet Connection (MetaMask / EIP-1193) |  |
| Wallet Signature Auth |  |
| NFT Ownership Queries |  |
| ERC-20 Token Balances |  |
| Token Gating |  |
| Thirdweb Integration | Config Ready |
| Moralis Integration | Config Ready |
Standard Features
All standard IntelliVerseX features are included: Device Auth, Profile, Wallet/Economy, Leaderboards, Storage, RPC.
Architecture
Your Game / dApp
|
v
+----------------------------------------------+
| IntelliVerseX Web3 SDK (IVXWeb3Manager) |
| Wallet | Auth | NFT | Tokens | Gate | RPC |
+----------------------------------------------+
| |
v v
+------------------+ +------------------+
| Nakama Client | | ethers.js |
| (nakama-js) | | (EIP-1193) |
+------------------+ +------------------+
| |
v v
+------------------+ +------------------+
| Nakama Server | | EVM Blockchain |
| + Hiro + Satori | | (via RPC nodes) |
+------------------+ +------------------+
Smart Contract Integration
How token gating works
- The browser wallet connects with
connectWallet(); the SDK knows walletAddress and chainId. checkTokenGate(contract, minBalance) sends a Nakama RPC (ivx_web3_check_gate) with that address, chain, contract, and threshold. - Your server implementation (Lua/Go in Nakama) should call an indexer or RPC node (Thirdweb, Moralis, Alchemy, etc.), verify balance or NFT ownership, and return
{ granted: true | false }. - The client never trusts itself for gate results; it only displays what the server authorizes.
NFT reward flow
fetchNfts() triggers ivx_web3_fetch_nfts, again server-side, so API keys for Moralis/Alchemy stay off the client. - To grant an NFT or off-chain reward, use a dedicated RPC that mints, queues airdrop, or credits Hiro currency after verifying eligibility (quest complete, tournament rank, etc.).
- Keep mint/transfer authority in custodial or contract-admin flows; the SDK surfaces reads and auth, not private keys.
On-chain leaderboard verification
- Default path:
submitScore / fetchLeaderboard use Nakama leaderboards (authoritative game scores). - On-chain verification: Implement an RPC that (a) accepts a score or proof payload, (b) verifies signatures or zk/state roots on the server, then © writes the Nakama leaderboard record only if valid. The Web3 SDK’s
callRpc is the extension point for that custom pipeline.
Security Model
Wallet signature auth flow
- After
connectWallet(), authenticateWallet() builds a deterministic message (wallet address + nonce). - The user signs with their wallet (
eth_sign / personal_sign via ethers). - The client calls
authenticateCustom with the wallet id and then ivx_web3_verify_wallet with { address, message, signature, chainId }. - The server must recover the signer from the signature, compare to
address, enforce nonce/replay rules, and only then treat the session as bound to that wallet.
Server-side verification
- All gating, NFT lists, and token balances intended for security decisions must be validated on Nakama (or your BFF), not by trusting client-side
ethers reads alone (users can spoof devtools). - Rate-limit verification RPCs and tie them to the authenticated Nakama user.
Never store private keys
- The SDK never asks for seed phrases or private keys. Only public addresses and signatures in transit.
- Do not log full signatures in production analytics.
Supported Chains
Any EVM-compatible chain: Ethereum (1), Polygon (137), Arbitrum (42161), Optimism (10), BSC (56), Avalanche (43114), Base (8453), and more.
Advanced Examples
NFT-gated tournament entry
await ivx.connectWallet();
await ivx.authenticateWallet();
const PASS_CONTRACT = '0xYourTournamentPass';
const canEnter = await ivx.checkTokenGate(PASS_CONTRACT, '1');
if (!canEnter) {
throw new Error('Tournament requires NFT pass');
}
const ok = await ivx.callRpc('tournament_register', JSON.stringify({ bracketId: 'spring-2026' }));
Token reward on achievement
// After server-side achievement validation (recommended pattern):
const result = await ivx.callRpc('grant_achievement_token', JSON.stringify({
achievementId: 'first_win',
walletAddress: ivx.walletAddress,
}));
// Server credits Hiro currency, queues ERC-20 transfer, or records claimable reward
await ivx.fetchWallet();
Multi-chain setup
- Instantiate one
IVXWeb3Manager per app shell; chainId in initialize() is the default expectation for your backend. - If users may switch chains in MetaMask, re-read
walletInfo.chainId after connectWallet() and pass chainId into every RPC payload so the server queries the correct network. - For multiple environments (Polygon + Base), use separate Nakama RPC implementations keyed by
chainId, or separate gameId/namespace per chain.
Troubleshooting
| Symptom | What to check |
| MetaMask not detected | window.ethereum undefined — extension disabled, or non-browser context. WalletConnect support is configuration-level; ensure you are not running inside a locked iframe without wallet injection. |
| Wrong chain ID | User switched network after connect. Compare ivx.walletInfo.chainId to your initialize({ chainId }) default and prompt wallet_switchEthereumChain via your own code if needed. |
| Transaction failed | On-chain sends are not handled by IVXWeb3Manager directly. Inspect gas, nonce, and contract reverts in the wallet; for game economy prefer server-mediated RPCs. |
| CORS with RPC nodes | Browser cannot call some JSON-RPC URLs directly due to CORS. Proxy reads through your Nakama RPC or a same-origin backend. |
| ethers version mismatch | Package expects ethers v6 (BrowserProvider, JsonRpcSigner). If another dependency pulls v5, dedupe or align versions in package.json / overrides. |
Further Reading
Source
SDKs/web3/