MetaMask là cổng truy cập Ethereum mặc định cho hàng chục triệu người dùng. Nếu bạn xây dựng dApp, MetaMask API là cầu nối giữa frontend và khóa ký của người dùng. "MetaMask API" thực chất gồm hai phần: nhà cung cấp window.ethereum (chuẩn EIP-1193) được inject vào trình duyệt, và MetaMask SDK mở rộng cho mobile, React Native, Node.js. Nắm chắc provider này, bạn đã kiểm soát được 80% tích hợp ví trên web.
Bài này hướng dẫn bạn phát hiện provider, yêu cầu tài khoản, đọc chain hiện tại, ký message với personal_sign và EIP-712, gửi transaction, thêm/chuyển chain, và sử dụng MetaMask SDK ngoài browser extension. Ngoài ra, bạn sẽ thấy ethers.js v6, viem đóng vai trò wrapper như thế nào, và Apidog hỗ trợ kiểm thử JSON-RPC mà không cần viết code frontend một lần.
Nếu làm việc với ví, hãy bookmark hướng dẫn API ví tiền điện tử tốt nhất để tổng quan hơn về các provider.
TL;DR (Tóm tắt)
- MetaMask API là EIP-1193 provider ở
window.ethereum+ MetaMask SDK cho mobile/Node. - Khởi đầu với
eth_requestAccountsđể kết nối, sau đó lắng ngheaccountsChangedvàchainChanged. - Ký message với
personal_sign; ký dữ liệu cấu trúc vớieth_signTypedData_v4(EIP-712). - Chuyển network bằng
wallet_switchEthereumChain(EIP-3326), thêm chain mới vớiwallet_addEthereumChain(EIP-3085). - ethers.js v6, viem và wagmi là wrapper cấp cao; Snaps mở rộng MetaMask.
- Sử dụng Apidog để test endpoint JSON-RPC, mô phỏng transaction & debug signature trước khi production.
MetaMask API là gì?
MetaMask API cung cấp interface để web/app tương tác với Ethereum hoặc bất kỳ chuỗi EVM nào. Extension sẽ inject object window.ethereum tuân thủ EIP-1193. Mọi dApp tuân EIP-1193 sẽ chạy với MetaMask, Coinbase Wallet, Rabby, Frame v.v mà không cần thay đổi code.
Với mobile, backend, desktop, MetaMask SDK cung cấp provider tương tự cho React Native, Node.js, Electron, script server-side. SDK xử lý deep-link và quy trình QR để ví MetaMask mobile ký các request từ desktop/backend. Tất cả vẫn nói EIP-1193 nên code không đổi.
MetaMask cũng có Snaps, hệ plugin mở rộng ví với chain mới, RPC custom, loại tài khoản mới. Snaps ngoài phạm vi bài này, nhưng rất hữu ích nếu bạn cần hỗ trợ non-EVM chain hoặc custom signing flow.
Xác thực và thiết lập
Không cần API key cho provider. Xác thực dựa vào user approve từng request trên giao diện ví. Bạn cần: cách phát hiện provider và lắng nghe events.
Phát hiện provider:
Dùng helper @metamask/detect-provider hoặc kiểm tra trực tiếp.
// Phát hiện MetaMask với Vanilla JS
import detectEthereumProvider from '@metamask/detect-provider';
const provider = await detectEthereumProvider({ mustBeMetaMask: true });
if (!provider) {
alert('Vui lòng cài đặt MetaMask');
} else {
console.log('Đã phát hiện MetaMask');
}
Lắng nghe sự kiện:
Luôn set listener cho accountsChanged và chainChanged trước bất kỳ request nào.
window.ethereum.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
console.log('Người dùng đã ngắt kết nối');
} else {
console.log('Tài khoản đang hoạt động:', accounts[0]);
}
});
window.ethereum.on('chainChanged', (chainId) => {
// Best practice: reload lại app khi chain đổi
window.location.reload();
});
Nếu dùng React, wagmi sẽ tự động nhận diện MetaMask qua injected connector.
Các điểm cuối cốt lõi
Toàn bộ lệnh gọi qua window.ethereum.request({ method, params }). Dưới đây là các call phổ biến nhất.
Yêu cầu tài khoản và đọc chuỗi
// Nhắc user connect ví
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts',
});
const account = accounts[0];
// Đọc chain hiện tại
const chainId = await window.ethereum.request({
method: 'eth_chainId',
});
console.log(account, chainId); // '0x...' '0x1'
Ví dụ gọi thô qua curl:
curl https://mainnet.infura.io/v3/YOUR_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'
Lưu ý: call chỉ-read có thể dùng node provider như Alchemy/Infura, không cần MetaMask. Xem hướng dẫn Alchemy API để biết thêm.
Ký message đơn giản
personal_sign là dạng ký phổ biến, an toàn hơn so với eth_sign.
const message = 'Đăng nhập vào Apidog vào lúc ' + new Date().toISOString();
const signature = await window.ethereum.request({
method: 'personal_sign',
params: [message, account],
});
Ký dữ liệu cấu trúc (EIP-712)
Sử dụng eth_signTypedData_v4 để ký structured data.
const typedData = {
domain: { name: 'Apidog Demo', version: '1', chainId: 1 },
types: {
EIP712Domain: [
{ name: 'name', type: 'string' },
{ name: 'version', type: 'string' },
{ name: 'chainId', type: 'uint256' },
],
Login: [
{ name: 'wallet', type: 'address' },
{ name: 'nonce', type: 'uint256' },
],
},
primaryType: 'Login',
message: { wallet: account, nonce: 42 },
};
const sig = await window.ethereum.request({
method: 'eth_signTypedData_v4',
params: [account, JSON.stringify(typedData)],
});
Gửi transaction
MetaMask tự estimate gas và nonce.
const txHash = await window.ethereum.request({
method: 'eth_sendTransaction',
params: [{
from: account,
to: '0xRecipientAddressHere',
value: '0x38d7ea4c68000', // 0.001 ETH (wei, hex)
}],
});
Chuyển đổi/Thêm chain
EIP-3326/EIP-3085 cho phép chuyển chain hoặc thêm chain mới.
// Chuyển sang Polygon (chainId 137 = 0x89)
try {
await window.ethereum.request({
method: 'wallet_switchEthereumChain',
params: [{ chainId: '0x89' }],
});
} catch (err) {
if (err.code === 4902) {
// Chain chưa được thêm
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x89',
chainName: 'Polygon',
rpcUrls: ['https://polygon-rpc.com'],
nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
}],
});
}
}
Tích hợp React với MetaMask SDK
SDK hoạt động tốt trên React khi bạn muốn support extension, deep link mobile, hoặc in-app browser.
import { MetaMaskProvider, useSDK } from '@metamask/sdk-react';
function Connect() {
const { sdk, connected, account } = useSDK();
return (
<button onClick={() => sdk?.connect()}>
{connected ? account : 'Kết nối MetaMask'}
</button>
);
}
export default function App() {
return (
<MetaMaskProvider sdkOptions={{ dappMetadata: { name: 'dApp của tôi' } }}>
<Connect />
</MetaMaskProvider>
);
}
Sản xuất nên wrap provider với ethers.js v6 hoặc viem để có contract type, decode ABI, thông báo lỗi tốt hơn. Nếu cần đăng nhập email/social fallback, có thể kết hợp MetaMask với embedded wallet, xem hướng dẫn Privy API.
Lỗi phổ biến & giới hạn tỷ lệ
MetaMask trả về mã lỗi JSON-RPC tiêu chuẩn:
-
4001: User từ chối request. Không tự động retry. -
4100: Chưa ủy quyền. Gọieth_requestAccountstrước. -
4200: Method không hỗ trợ. Xác nhận đúng ví MetaMask. -
4902: Chain chưa được thêm. Gọiwallet_addEthereumChain. -
-32002: Request đang chờ xử lý. Debounce phía frontend.
Provider không giới hạn rate, nhưng RPC (Infura/Alchemy) có hạn mức tùy gói. Đổi sang fiat như ETH-USD, hãy xem API on/off ramp fiat.
Giá của MetaMask API
MetaMask Extension + SDK đều miễn phí, không tính phí kết nối, ký hay transaction. MetaMask thu phí qua swap và thẻ MetaMask Card, không thu từ developer.
Bạn chỉ cần trả phí cho node RPC (Infura/Alchemy). Gói free đủ cho app nhỏ; production dApp thường tốn 49–299 USD/tháng tùy thông lượng.
Kiểm tra MetaMask API với Apidog
Ký trình duyệt rất khó debug do request đi qua extension, web, và có thể cả deep-link mobile. Apidog giúp bạn test endpoint JSON-RPC thô, xác nhận eth_chainId hoặc eth_getBalance trả đúng, và lưu trữ toàn bộ flow thành test collection.
Chỉ cần import đặc tả Ethereum JSON-RPC, set URL node thành biến môi trường là bạn có collection dùng lại cho mọi EVM chain. Apidog mô phỏng response, cho phép frontend dev build trên eth_sendTransaction giả trong khi smart contract đang audit. CI có thể chạy bộ test từ CLI và fail nếu response shape đổi. Nếu bạn từng struggle với Postman collection sync, đọc hướng dẫn kiểm thử API không cần Postman 2026 để hiểu vì sao Apidog phù hợp test dApp đa giao thức.
Tải xuống Apidog để bắt đầu.
Câu hỏi thường gặp
MetaMask API có dùng trên mobile được không?
Có. Dùng MetaMask SDK để deep link sang app mobile. Provider interface y hệt extension nên code không thay đổi. Đọc thêm so sánh SDK ví mobile tại API ví tiền điện tử tốt nhất.
Phân biệt eth_sign, personal_sign và eth_signTypedData_v4?
eth_sign ký byte thô, nguy hiểm – MetaMask cảnh báo mạnh. personal_sign ký message có tiền tố dễ đọc. eth_signTypedData_v4 ký structured data EIP-712, hiển thị field rõ ràng cho user trên UI. Dùng hai cái sau, tránh eth_sign.
Có cần API key riêng của MetaMask không?
Không. Provider miễn phí, không cần key. Đọc dữ liệu ngoài ví thì cần RPC provider như Infura/Alchemy (có key riêng).
ethers.js hoặc viem dùng với MetaMask được không?
Được, cả hai đều wrap window.ethereum. Ethers v6 dùng BrowserProvider(window.ethereum), viem dùng createWalletClient({ transport: custom(window.ethereum) }). Production dApp nên dùng.
Nếu user cài nhiều ví thì sao?
MetaMask hỗ trợ EIP-6963 giúp dApp phát hiện toàn bộ ví đã cài thay vì tranh chấp window.ethereum. Wagmi, RainbowKit xử lý tự động.
MetaMask Snaps đã production ready chưa?
Có, đã phát hành rộng 2024. Phần lớn dùng cho non-EVM chain, custom transaction info, tích hợp ví phần cứng.
Top comments (0)