Chains
EVM (Base, Optimism, Arbitrum)

EVM Chains

Deploy and integrate Veridex on any EVM-compatible blockchain.

Supported EVM Chains

ChainStatusChain IDHub
Base✅ Mainnet8453✓ (Primary)
Base Sepolia✅ Testnet84532✓ (Testnet)
Optimism✅ Mainnet10Spoke
Arbitrum✅ Mainnet42161Spoke
Ethereum🔜 Coming1Spoke
Polygon🔜 Coming137Spoke

Initialize SDK

import { createSDK } from '@veridex/sdk';
 
// Hub chain (Base)
const hubSDK = createSDK('base', {
  network: 'mainnet',
  relayerUrl: 'https://relayer.veridex.network',
});
 
// Spoke chain (Optimism)
const opSDK = createSDK('optimism', {
  network: 'mainnet',
  relayerUrl: 'https://relayer.veridex.network',
});

Hub vs Spoke Chains

Hub Chain (Base)

The hub chain is where the master passkey is registered:

// Register passkey on hub (Base)
const result = await hubSDK.passkey.register('user@example.com', 'My Wallet');
// result.vaultAddress = '0x...' (same on all chains)

Spoke Chains

Spoke chains derive the same vault address:

// Login on spoke chain (Optimism)
await opSDK.passkey.authenticate();
 
// Same vault address as hub!
console.log(opSDK.getVaultAddress()); // 0x...same address

Chain Configuration

RPC URLs

const RPC_URLS = {
  // Mainnets
  base: 'https://mainnet.base.org',
  optimism: 'https://mainnet.optimism.io',
  arbitrum: 'https://arb1.arbitrum.io/rpc',
  
  // Testnets
  'base-sepolia': 'https://sepolia.base.org',
  'optimism-sepolia': 'https://sepolia.optimism.io',
  'arbitrum-sepolia': 'https://sepolia-rollup.arbitrum.io/rpc',
};

Contract Addresses

const CONTRACTS = {
  base: {
    vaultFactory: '0x...',
    paymaster: '0x...',
    entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
  },
  optimism: {
    vaultFactory: '0x...',
    paymaster: '0x...',
    entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
  },
  arbitrum: {
    vaultFactory: '0x...',
    paymaster: '0x...',
    entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
  },
};

Multi-Chain Balances

async function getAllBalances() {
  // Get balances from all chains
  const balances = await hubSDK.getBalances();
  
  // Returns:
  // {
  //   base: { ETH: '1.5', USDC: '100.00' },
  //   optimism: { ETH: '0.5', USDC: '50.00' },
  //   arbitrum: { ETH: '0.2', USDC: '25.00' }
  // }
  
  return balances;
}

Cross-Chain Transfers

Via Wormhole (Fast Path - 5-7s)

import { parseUnits } from 'ethers';
 
async function bridgeUSDC(
  fromChain: 'base' | 'optimism' | 'arbitrum',
  toChain: 'base' | 'optimism' | 'arbitrum',
  amount: string
) {
  const sdk = createSDK(fromChain, { network: 'mainnet' });
  await sdk.passkey.authenticate();
 
  const result = await sdk.crossChainTransfer({
    token: USDC_ADDRESSES[fromChain],
    amount: parseUnits(amount, 6),
    targetChain: toChain,
    recipient: sdk.getVaultAddress(), // Same address on target
    path: 'fast', // CCQ path
  });
 
  return result;
}

Via VAA (Standard Path - ~60s)

async function bridgeUSDCStandard(
  fromChain: 'base' | 'optimism' | 'arbitrum',
  toChain: 'base' | 'optimism' | 'arbitrum',
  amount: string
) {
  const sdk = createSDK(fromChain, { network: 'mainnet' });
  await sdk.passkey.authenticate();
 
  const result = await sdk.crossChainTransfer({
    token: USDC_ADDRESSES[fromChain],
    amount: parseUnits(amount, 6),
    targetChain: toChain,
    recipient: sdk.getVaultAddress(),
    path: 'standard', // VAA path
  });
 
  return result;
}

Chain-Specific Considerations

Base

  • Primary hub chain
  • Lowest gas fees
  • Best for passkey registration
// Recommended: Register on Base
const sdk = createSDK('base', { network: 'mainnet' });
await sdk.passkey.register('user@example.com', 'Wallet');

Optimism

  • L2 with low fees
  • EIP-4844 blob support
  • Superchain compatibility
const sdk = createSDK('optimism', { network: 'mainnet' });
await sdk.passkey.authenticate();
 
// Works identically to Base
await sdk.transferViaRelayer({
  token: OP_USDC,
  recipient: '0x...',
  amount: parseUnits('10', 6),
});

Arbitrum

  • Highest throughput L2
  • Nitro architecture
  • Full EVM equivalence
const sdk = createSDK('arbitrum', { network: 'mainnet' });
await sdk.passkey.authenticate();
 
await sdk.transferViaRelayer({
  token: ARB_USDC,
  recipient: '0x...',
  amount: parseUnits('10', 6),
});

Custom EVM Chain

Add support for any EVM chain:

import { createSDK, registerChain } from '@veridex/sdk';
 
// Register custom chain
registerChain({
  name: 'polygon',
  chainId: 137,
  rpcUrl: 'https://polygon-rpc.com',
  wormholeChainId: 5,
  contracts: {
    vaultFactory: '0x...',
    paymaster: '0x...',
    entryPoint: '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789',
  },
  tokens: {
    USDC: '0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359',
    USDT: '0xc2132D05D31c914a87C6611C10748AEb04B58e8F',
  },
});
 
// Now use it
const polygonSDK = createSDK('polygon', { network: 'mainnet' });

Gas Estimation

async function estimateGas(chain: string, tx: TransactionRequest) {
  const sdk = createSDK(chain, { network: 'mainnet' });
  
  const estimate = await sdk.estimateGas({
    target: tx.to,
    value: tx.value || 0n,
    data: tx.data || '0x',
  });
 
  return {
    gasLimit: estimate.gasLimit,
    gasPrice: estimate.gasPrice,
    maxFeePerGas: estimate.maxFeePerGas,
    maxPriorityFeePerGas: estimate.maxPriorityFeePerGas,
    estimatedCostETH: formatUnits(estimate.totalCost, 18),
    estimatedCostUSD: await getUSDValue(estimate.totalCost),
  };
}

Transaction Monitoring

async function waitForTransaction(chain: string, txHash: string) {
  const provider = new ethers.JsonRpcProvider(RPC_URLS[chain]);
  
  // Wait for confirmation
  const receipt = await provider.waitForTransaction(txHash, 1);
  
  if (receipt?.status === 0) {
    throw new Error('Transaction reverted');
  }
  
  return receipt;
}

Contract Deployment

Deploy Veridex contracts to new EVM chains:

# Clone contracts repo
git clone https://github.com/Veridex-Protocol/contracts
 
# Configure deployment
cp .env.example .env
# Edit .env with chain RPC and deployer key
 
# Deploy
npx hardhat run scripts/deploy.ts --network polygon

Security Notes

  1. Verify contracts - Always verify deployed contracts on block explorer
  2. Test on testnet - Deploy to testnet first
  3. Check gas limits - Some chains have different limits
  4. Monitor finality - Different chains have different finality times
  5. RPC reliability - Use reliable RPC providers for production