base/l2-dev

Base L2 Development

basetechnical-doc🤖 Auto-generatedconfidence highhealth 100%
v1.0.0·by AgentRel Community·Updated 3/20/2026

Overview

Base is an Ethereum Layer 2 network built by Coinbase on top of the OP Stack. It is fully EVM-compatible, but there are several important differences to be aware of. AI models frequently overlook L2-specific gas calculations, cross-chain bridge logic, or use generic Ethereum code that lacks Base-specific functionality.

⚠️ Gotchas (Most Common AI Mistakes)

1. Gas Price: L2 Execution Fee + L1 Data Fee

❌ Wrong (only checking L2 gas price):

const gasPrice = await provider.getGasPrice();
const gasCost = gasLimit * gasPrice; // Inaccurate!

✅ Correct (must account for L1 data fee):

// Base total fee = L2 execution fee + L1 data fee
// L1 data fee is queried via a precompile contract
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';

const client = createPublicClient({ chain: base, transport: http() });

// Use viem's built-in L2 gas estimation
import { estimateTotalFee } from 'viem/op-stack';
const totalFee = await estimateTotalFee(client, { account, to, data });
import { createPublicClient, createWalletClient, http } from 'viem';
import { base, baseSepolia } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

const publicClient = createPublicClient({
  chain: base,
  transport: http('https://mainnet.base.org'),
});

const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY');
const walletClient = createWalletClient({
  account,
  chain: base,
  transport: http('https://mainnet.base.org'),
});

3. Using OnchainKit to Build Base Apps Quickly

import { OnchainKitProvider } from '@coinbase/onchainkit';
import { base } from 'viem/chains';

function App() {
  return (
    <OnchainKitProvider
      apiKey={process.env.NEXT_PUBLIC_ONCHAINKIT_API_KEY}
      chain={base}
    >
      {/* Your app */}
    </OnchainKitProvider>
  );
}

4. Cross-Chain Bridge: Standard Bridge vs Third-Party

// Official Standard Bridge (L1 → L2, ~1-3 minutes)
import { getL2TransactionHashes, publicActionsL1 } from 'viem/op-stack';
import { mainnet } from 'viem/chains';

const l1Client = createPublicClient({ chain: mainnet, transport: http() })
  .extend(publicActionsL1());

// Initiate deposit
const hash = await walletClient.depositTransaction({
  request: {
    to: recipientOnL2,
    value: parseEther('0.01'),
    gas: 21000n,
  },
});

// L2 → L1 withdrawals require a 7-day challenge period (OP Stack security mechanism)
// Use a third-party bridge (e.g. Across, Stargate) to bypass the waiting period

RPC Endpoints

Mainnet: https://mainnet.base.org
Testnet (Sepolia): https://sepolia.base.org
Chainlink: Chain ID 8453 (mainnet), 84532 (testnet)

Base Name Service (Basename)

import { getName } from '@coinbase/onchainkit/identity';

// Resolve the Basename for an address
const name = await getName({
  address: '0x...',
  chain: base,
});
// Returns 'user.base.eth' or null

Installation

npm install viem wagmi @coinbase/onchainkit
# Hardhat configuration
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
// hardhat.config.ts
networks: {
  base: {
    url: 'https://mainnet.base.org',
    accounts: [process.env.PRIVATE_KEY!],
    chainId: 8453,
  },
  baseSepolia: {
    url: 'https://sepolia.base.org',
    accounts: [process.env.PRIVATE_KEY!],
    chainId: 84532,
  },
}

Reference

Feedback

If this skill contains incorrect or outdated information, call:

id: base/l2-dev name: Base L2 Development version: 1.0.0 ecosystem: base type: technical-doc time_sensitivity: evergreen source: official confidence: high maintainer: AgentRel Community last_updated: 2026-03-19 feedback_endpoint: https://agentrel.vercel.app/api/feedback

Overview

Base is an Ethereum Layer 2 network built by Coinbase on top of the OP Stack. It is fully EVM-compatible, but there are several important differences to be aware of. AI models frequently overlook L2-specific gas calculations, cross-chain bridge logic, or use generic Ethereum code that lacks Base-specific functionality.

⚠️ Gotchas (Most Common AI Mistakes)

1. Gas Price: L2 Execution Fee + L1 Data Fee

❌ Wrong (only checking L2 gas price):

const gasPrice = await provider.getGasPrice();
const gasCost = gasLimit * gasPrice; // Inaccurate!

✅ Correct (must account for L1 data fee):

// Base total fee = L2 execution fee + L1 data fee
// L1 data fee is queried via a precompile contract
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';

const client = createPublicClient({ chain: base, transport: http() });

// Use viem's built-in L2 gas estimation
import { estimateTotalFee } from 'viem/op-stack';
const totalFee = await estimateTotalFee(client, { account, to, data });
import { createPublicClient, createWalletClient, http } from 'viem';
import { base, baseSepolia } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

const publicClient = createPublicClient({
  chain: base,
  transport: http('https://mainnet.base.org'),
});

const account = privateKeyToAccount('0xYOUR_PRIVATE_KEY');
const walletClient = createWalletClient({
  account,
  chain: base,
  transport: http('https://mainnet.base.org'),
});

3. Using OnchainKit to Build Base Apps Quickly

import { OnchainKitProvider } from '@coinbase/onchainkit';
import { base } from 'viem/chains';

function App() {
  return (
    <OnchainKitProvider
      apiKey={process.env.NEXT_PUBLIC_ONCHAINKIT_API_KEY}
      chain={base}
    >
      {/* Your app */}
    </OnchainKitProvider>
  );
}

4. Cross-Chain Bridge: Standard Bridge vs Third-Party

// Official Standard Bridge (L1 → L2, ~1-3 minutes)
import { getL2TransactionHashes, publicActionsL1 } from 'viem/op-stack';
import { mainnet } from 'viem/chains';

const l1Client = createPublicClient({ chain: mainnet, transport: http() })
  .extend(publicActionsL1());

// Initiate deposit
const hash = await walletClient.depositTransaction({
  request: {
    to: recipientOnL2,
    value: parseEther('0.01'),
    gas: 21000n,
  },
});

// L2 → L1 withdrawals require a 7-day challenge period (OP Stack security mechanism)
// Use a third-party bridge (e.g. Across, Stargate) to bypass the waiting period

RPC Endpoints

Mainnet: https://mainnet.base.org
Testnet (Sepolia): https://sepolia.base.org
Chainlink: Chain ID 8453 (mainnet), 84532 (testnet)

Base Name Service (Basename)

import { getName } from '@coinbase/onchainkit/identity';

// Resolve the Basename for an address
const name = await getName({
  address: '0x...',
  chain: base,
});
// Returns 'user.base.eth' or null

Installation

npm install viem wagmi @coinbase/onchainkit
# Hardhat configuration
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
// hardhat.config.ts
networks: {
  base: {
    url: 'https://mainnet.base.org',
    accounts: [process.env.PRIVATE_KEY!],
    chainId: 8453,
  },
  baseSepolia: {
    url: 'https://sepolia.base.org',
    accounts: [process.env.PRIVATE_KEY!],
    chainId: 84532,
  },
}

Reference

Feedback

If this skill contains incorrect or outdated information, call: agentrel_feedback(skill="base/l2-dev", issue="<description>", code_snippet="<optional>", error_message="<optional>", fix="<optional>")