Documentation Index Fetch the complete documentation index at: https://docs.immutable.com/llms.txt
Use this file to discover all available pages before exploring further.
Frequently Asked Questions
Common questions and solutions for build issues, authentication, transactions, and debugging with the TypeScript SDK.
Build & Environment
"Buffer is not defined" or "process is not defined"
Modern bundlers don’t include Node.js polyfills by default. Vite: npm install vite-plugin-node-polyfills
// vite.config.ts
import { nodePolyfills } from 'vite-plugin-node-polyfills' ;
export default defineConfig ({
plugins: [
nodePolyfills ({
include: [ 'buffer' , 'crypto' , 'stream' , 'util' ],
}),
] ,
}) ;
Next.js / Create React App: // Add to top of your entry file
import { Buffer } from 'buffer' ;
if ( typeof window !== 'undefined' ) {
window . Buffer = Buffer ;
}
Add global polyfill to your bundler config: // vite.config.ts
export default defineConfig ({
define: {
global: 'globalThis' ,
} ,
}) ;
Module resolution issues or type errors
Ensure tsconfig.json uses modern module resolution: {
"compilerOptions" : {
"moduleResolution" : "bundler" , // or "node16"
"esModuleInterop" : true
}
}
Next.js: "Cannot find module" or ESM errors
Import from modular packages instead of the umbrella SDK: // ❌ May cause issues with App Router
import { config , auth } from '@imtbl/sdk' ;
// ✅ Works correctly - use modular packages
import { Auth } from '@imtbl/auth' ;
import { connectWallet } from '@imtbl/wallet' ;
import { Environment } from '@imtbl/config' ;
If you see elliptic package errors, add to next.config.js: const nextConfig = {
experimental: {
esmExternals: false ,
},
};
Import modular packages instead of the umbrella package: // ❌ Imports everything
import { auth , orderbook } from '@imtbl/sdk' ;
// ✅ Imports only what you need
import { Auth } from '@imtbl/auth' ;
import { Orderbook } from '@imtbl/orderbook' ;
Using modular packages can significantly reduce your bundle size by importing only what you need.
Module resolution errors, dependency conflicts, or build failures
Clear your cache and reinstall dependencies: # Remove node_modules and package lock
rm -rf node_modules package-lock.json
# Clear npm cache
npm cache clean --force
# Reinstall dependencies
npm install
For Vite projects: rm -rf node_modules .vite package-lock.json
npm cache clean --force
npm install
For Next.js projects: rm -rf node_modules .next package-lock.json
npm cache clean --force
npm install
For framework-specific bundler configuration, see the Framework Setup tabs in the overview.
Regional Support
What regions are supported?
The Immutable Game SDK supports only the regions that Immutable Passport supports. Passport is a globally available product. However, our wallet infrastructure is subject to the regulation of the US Department of the Treasury’s Office of Foreign Assets Control (“OFAC”). OFAC administers and enforces comprehensive and targeted economic and trade sanctions programs on multiple countries and regions. Users attempting to access Passport in any of the regions under OFAC sanction will have their access blocked and will be unable to use our product. Additionally, components of Passport’s infrastructure also rely on technology provided by Magic , which maintains further details regarding unsupported regions on their website here .
Authentication
"Redirect URI mismatch" error
The redirectUri in your code must exactly match what’s configured in Hub . Common mismatches:
http vs https
Trailing slash (/callback vs /callback/)
Port number differences
Different paths
// ❌ Wrong - trailing slash mismatch
redirectUri : 'http://localhost:3000/callback/'
// ✅ Correct - matches Hub config exactly
redirectUri : 'http://localhost:3000/callback'
The redirect URI must match exactly including trailing slashes and port numbers.
"Invalid client_id" error
Verify the following:
clientId matches your Hub configuration
You’re using the correct environment (Sandbox vs Production)
publishableKey is set correctly
"Popup blocked" when logging in
Callback page shows error or nothing happens
Ensure loginCallback() is called on your redirect URI page: // app/callback/page.tsx
useEffect (() => {
auth . loginCallback ()
. then (() => router . push ( '/' ))
. catch ( console . error );
}, []);
Transactions
"User rejected the request"
User cancelled the transaction in the Passport popup. Handle this gracefully: try {
await walletClient . sendTransaction ({ to , value });
} catch ( error ) {
if ( error . name === 'UserRejectedRequestError' ) {
// User cancelled - show friendly message
return ;
}
throw error ;
}
"Insufficient funds" error
The user doesn’t have enough IMX for the transaction + gas fees. import { formatEther } from 'viem' ;
const balance = await publicClient . getBalance ({ address });
console . log ( 'Balance:' , formatEther ( balance ), 'IMX' );
Direct users to fund their wallet via the Checkout widgets .
Usually caused by pending transactions. Wait for pending transactions to confirm: const pendingNonce = await publicClient . getTransactionCount ({
address ,
blockTag: 'pending' ,
});
Initialize once and reuse the instance: // ❌ Wrong - creates new instance every call
function getAuth () {
return new Auth ({ ... });
}
// ✅ Correct - singleton pattern
let auth : Auth | null = null ;
function getAuth () {
if ( ! auth ) {
auth = new Auth ({ ... });
}
return auth ;
}
Use the singleton pattern to initialize SDK instances once and reuse them throughout your application.
How do I enable SDK debug logs?
Enable debug logs in the browser console: // In browser console
localStorage . setItem ( 'debug' , 'imtbl:*' );
Then refresh the page to see SDK debug output.
How do I inspect SDK network calls?
SDK calls go to:
Sandbox : api.sandbox.immutable.com
Production : api.immutable.com
Check the browser Network tab for failed requests and error responses.
Code Meaning Solution 401 Unauthorized Check API key or access token 403 Forbidden Check permissions in Hub 429 Rate limited Implement exponential backoff 500 Server error Retry with backoff, contact support if persistent
Integration & Usage
How do I use the SDK with viem?
viem has built-in Immutable Chain support: import { createWalletClient , createPublicClient , custom , http } from 'viem' ;
import { immutableZkEvm , immutableZkEvmTestnet } from 'viem/chains' ;
import { connectWallet } from '@imtbl/wallet' ;
const provider = await connectWallet ({ auth });
const walletClient = createWalletClient ({
chain: immutableZkEvmTestnet ,
transport: custom ( provider ),
});
const publicClient = createPublicClient ({
chain: immutableZkEvmTestnet ,
transport: http (),
});
const [ address ] = await walletClient . getAddresses ();
const hash = await walletClient . sendTransaction ({
to: '0x...' ,
value: parseEther ( '0.1' ),
});
How do I validate webhooks?
Use @imtbl/webhook to verify incoming webhooks from Immutable: import { validateWebhook } from '@imtbl/webhook' ;
app . post ( '/webhook' , ( req , res ) => {
const signature = req . headers [ 'x-immutable-signature' ] as string ;
const rawBody = req . body ; // Must be raw body, not parsed JSON
const isValid = validateWebhook (
rawBody ,
signature ,
process . env . WEBHOOK_SECRET !
);
if ( ! isValid ) {
return res . status ( 403 ). send ( 'Invalid signature' );
}
res . status ( 200 ). send ( 'OK' );
});
Can I use the SDK via CDN?
For browser-only applications without a build step: < script src = "https://cdn.jsdelivr.net/npm/@imtbl/sdk" ></ script >
< script >
const passport = new window . immutable . passport . Passport ({
clientId: 'YOUR_CLIENT_ID' ,
redirectUri: 'https://your-app.com/callback' ,
logoutRedirectUri: 'https://your-app.com' ,
audience: 'platform_api' ,
scope: 'openid offline_access email transact'
});
passport . login ();
</ script >
CDN deployment is useful for quick prototypes and static sites. For production applications, use npm packages with proper bundling.
How do I enable code splitting?
Requires TypeScript 5.0+ with moduleResolution: "bundler" in tsconfig.json. // ✅ Correct - imports only the module you need
import { Passport } from '@imtbl/sdk/passport' ;
import { Orderbook } from '@imtbl/sdk/orderbook' ;
import { BlockchainData } from '@imtbl/sdk/blockchain-data' ;
// ❌ Avoid - imports entire SDK
import { Passport , Orderbook } from '@imtbl/sdk' ;
Breaking Change : V2 SDK uses Ethers.js v6 (upgraded from v5). If your application uses Ethers.js, you must migrate. Key changes:
WrappedBrowserProvider for Checkout SDK
passport.connectEvm() is now async — must await before passing to Checkout
See Ethers.js v6 migration guide for details
Still Need Help?
TypeScript SDK Complete TypeScript SDK documentation
GitHub Issues Report TypeScript SDK issues
Support Contact support team
Documentation Browse all documentation