跳转到主要内容

将 MetaMask 连接到 Injective EVM Testnet

MetaMask 是一个浏览器钱包扩展,可让你连接到任何 EVM 兼容网络,包括 Injective EVM

如何安装 MetaMask

MetaMask 下载页面 安装官方 MetaMask 扩展。

将 Injective EVM Testnet 添加到 MetaMask

  1. 点击浏览器中的 MetaMask 图标 并解锁你的钱包。
  2. 点击顶部的网络选择器(默认是 “Ethereum Mainnet”)。
  3. 选择 “Add Network”“Add a network manually” 打开自定义网络表单。

Injective EVM Testnet 参数

填写以下详细信息:
Network Name: Injective EVM Testnet
Chain ID: 1439
RPC URL: https://k8s.testnet.json-rpc.injective.network/
Currency Symbol: INJ
Block Explorer URL: https://testnet.blockscout.injective.network/blocks
注意:Block Explorer URL 是可选的,由 BlockScout 提供支持。

切换到 Injective EVM Testnet

添加网络后,使用网络选择器切换到 Injective EVM Testnet

为你的钱包充值(可选)

需要 Testnet INJ?访问 Injective Testnet faucet 资金将在包含在 Testnet 区块后显示。

设置完成!

MetaMask 现在已连接到 Injective EVM Testnet。你可以:
  • 使用 FoundryHardhatRemix 等工具部署智能合约。
  • 与 Testnet dApp 和合约交互。
  • 通过 Blockscout 浏览器检查交易。
提示: 始终仔细检查 RPC URL 和 Chain ID - 准确性对于避免配置错误至关重要。

通过 ethers.js 连接 MetaMask

你也可以使用 ethers 以编程方式连接 MetaMask。

示例代码

import { ethers } from 'ethers';

export const INJECTIVE_EVM_PARAMS = {
  chainId: '0x59f', // 1439 的十六进制
  chainName: 'Injective EVM',
  rpcUrls: ['https://k8s.testnet.json-rpc.injective.network/'],
  nativeCurrency: {
    name: 'Injective',
    symbol: 'INJ',
    decimals: 18,
  },
  blockExplorerUrls: ['https://testnet.blockscout.injective.network/blocks'],
};

export async function connectMetaMask() {
  if (typeof window.ethereum === 'undefined') {
    alert('MetaMask not installed!');
    return;
  }

  const provider = new ethers.providers.Web3Provider(window.ethereum);

  try {
    await window.ethereum.request({
      method: 'wallet_addEthereumChain',
      params: [INJECTIVE_EVM_PARAMS],
    });

    await provider.send('eth_requestAccounts', []);
    const signer = provider.getSigner();
    const address = await signer.getAddress();

    console.log('Connected address:', address);
    return { provider, signer, address };
  } catch (err) {
    console.error('MetaMask connection failed:', err);
  }
}

使用 ethers.js 与智能合约交互

Counter 合约 ABI 示例代码:
// abi/counterAbi.ts
[
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "sender",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "string",
				"name": "reason",
				"type": "string"
			}
		],
		"name": "UserRevert",
		"type": "event"
	},
	{
		"anonymous": false,
		"inputs": [
			{
				"indexed": true,
				"internalType": "address",
				"name": "sender",
				"type": "address"
			},
			{
				"indexed": false,
				"internalType": "uint256",
				"name": "newValue",
				"type": "uint256"
			}
		],
		"name": "ValueSet",
		"type": "event"
	},
	{
		"inputs": [],
		"name": "increment",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [],
		"name": "number",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "",
				"type": "uint256"
			}
		],
		"stateMutability": "view",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "uint256",
				"name": "newNumber",
				"type": "uint256"
			}
		],
		"name": "setNumber",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "string",
				"name": "reason",
				"type": "string"
			}
		],
		"name": "userRevert",
		"outputs": [],
		"stateMutability": "nonpayable",
		"type": "function"
	}
]
import { ethers } from 'ethers'
import { counterAbi } from './abi/counterAbi'
import { INJECTIVE_EVM_PARAMS } from './config' // 从单独的文件

// 替换为你部署的合约地址
const contractAddress = '0xYourContractAddressHere'

async function connectAndInteract() {
  if (!window.ethereum) {
    alert('MetaMask is not installed!')
    return
  }

  // 请求将 Injective EVM 网络添加到 MetaMask
  await window.ethereum.request({
    method: 'wallet_addEthereumChain',
    params: [
      {
        chainId: INJECTIVE_EVM_PARAMS.chainHex,
        chainName: INJECTIVE_EVM_PARAMS.chainName,
        rpcUrls: [INJECTIVE_EVM_PARAMS.rpcUrl],
        nativeCurrency: INJECTIVE_EVM_PARAMS.nativeCurrency,
        blockExplorerUrls: [INJECTIVE_EVM_PARAMS.blockExplorer],
      },
    ],
  })

  const provider = new ethers.providers.Web3Provider(window.ethereum)
  await provider.send('eth_requestAccounts', [])
  const signer = provider.getSigner()
  const userAddress = await signer.getAddress()
  console.log('Connected as:', userAddress)

  // 合约实例
  const contract = new ethers.Contract(contractAddress, counterAbi, signer)

  // 发送交易以增加计数
  const tx = await contract.increment()
  console.log('Transaction sent:', tx.hash)

  const receipt = await tx.wait()
  console.log('Transaction mined in block:', receipt.blockNumber)
}

connectAndInteract().catch(console.error)

使用 viem 与智能合约交互

示例代码
import { counterAbi } from './abi/counterAbi'
import { INJECTIVE_EVM_PARAMS } from './config'
import { createPublicClient, http } from 'viem'
import { createWalletClient, custom, defineChain, formatEther } from 'viem'

// 替换为你部署的合约地址
const contractAddress = '0xYourContractAddressHere'

async function connectAndInteract() {
  if (typeof window === 'undefined' || typeof window.ethereum === 'undefined') {
    alert('MetaMask is not installed!')
    return
  }

  const client = createWalletClient({
    chain: INJECTIVE_EVM_PARAMS,
    transport: custom(window.ethereum),
  })

  // 创建 PublicClient 用于读取合约状态
  const publicClient = createPublicClient({
    chain: injectiveEvm,
    transport: http(),
  })

  const [account] = await client.requestAddresses()
  console.log('Connected account:', account)

  // 使用 wallet client 发送交易以增加计数
  const hash = await client.writeContract({
    address: contractAddress,
    abi: counterAbi,
    functionName: 'increment',
    account,
  })

  console.log('Transaction sent with hash:', hash)
}

connectAndInteract().catch(console.error)