Skip to main content

Frequently Asked Questions

Common questions and solutions for build issues, authentication, transactions, and debugging with the TypeScript SDK.

Build & Bundler Issues

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',
  },
});
Ensure tsconfig.json uses modern module resolution:
{
  "compilerOptions": {
    "moduleResolution": "bundler", // or "node16"
    "esModuleInterop": true
  }
}
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.

Authentication

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.
Verify the following:
  1. clientId matches your Hub configuration
  2. You’re using the correct environment (Sandbox vs Production)
  3. publishableKey is set correctly
Ensure loginCallback() is called on your redirect URI page:
// app/callback/page.tsx
useEffect(() => {
  auth.loginCallback()
    .then(() => router.push('/'))
    .catch(console.error);
}, []);
Passport is globally available, except for OFAC-sanctioned regions. Users in sanctioned regions will be blocked from authentication.See Magic’s supported regions for details.

Transactions

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;
}
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',
});

Performance

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.

Debugging

Enable debug logs in the browser console:
// In browser console
localStorage.setItem('debug', 'imtbl:*');
Then refresh the page to see SDK debug output.
SDK calls go to:
  • Sandbox: api.sandbox.immutable.com
  • Production: api.immutable.com
Check the browser Network tab for failed requests and error responses.
CodeMeaningSolution
401UnauthorizedCheck API key or access token
403ForbiddenCheck permissions in Hub
429Rate limitedImplement exponential backoff
500Server errorRetry with backoff, contact support if persistent

Still Need Help?