Gate Wallet DApp Skill
DApp interaction domain — Connect wallet, sign messages, execute DApp transactions, ERC20 Approve authorization, with mandatory confirmation gating and contract security review. 4 MCP tools + cross-Skill invocation.
Trigger scenarios: User mentions "connect DApp", "sign message", "sign message", "authorize", "approve", "DApp interaction", "NFT mint", "DeFi operation", "add liquidity", "stake", "stake", "claim", "contract call", or when other Skills guide the user to perform DApp-related operations.
Step 0: MCP Server Connection Check (Mandatory)
Before executing any operation, Gate Wallet MCP Server availability must be confirmed. This step cannot be skipped.
Probe invocation:
CallMcpTool(server="gate-wallet", toolName="chain.config", arguments={chain: "eth"})
| Result | Handling |
|---|---|
| Success | MCP Server available, proceed with subsequent steps |
server not found / unknown server | Cursor not configured → Show configuration guide (see below) |
connection refused / timeout | Remote unreachable → Prompt to check URL and network |
401 / unauthorized | API Key authentication failed → Prompt to check auth configuration |
Display when Cursor is not configured
❌ Gate Wallet MCP Server not configured
The MCP Server named "gate-wallet" was not found in Cursor. Please configure it as follows:
Method 1: Configure via Cursor Settings (recommended)
1. Open Cursor → Settings → MCP
2. Click "Add new MCP server"
3. Fill in:
- Name: gate-wallet
- Type: HTTP
- URL: https://your-mcp-server-domain/mcp
4. Save and retry
Method 2: Edit configuration file manually
Edit ~/.cursor/mcp.json and add:
{
"mcpServers": {
"gate-wallet": {
"url": "https://your-mcp-server-domain/mcp"
}
}
}
If you do not have an MCP Server URL yet, please contact your administrator.
Display when remote service is unreachable
⚠️ Gate Wallet MCP Server connection failed
MCP Server configuration was found, but the remote service could not be reached. Please check:
1. Confirm the service URL is correct (is the configured URL accessible)
2. Check network connection (VPN / firewall may affect connectivity)
3. Confirm the remote service is running normally
Display when API Key authentication fails
🔑 Gate Wallet MCP Server authentication failed
MCP Server connected but API Key validation failed. This service has AK/SK authentication enabled (x-api-key header).
Please contact your administrator for a valid API Key and confirm the server configuration is correct.
Authentication
All operations in this Skill require mcp_token. User must be logged in before calling any tool.
- If no
mcp_tokenis present → Guide user togate-dex-mcpauthto complete login, then return. - If
mcp_tokenhas expired (MCP Server returns token expired error) → First tryauth.refresh_tokenfor silent refresh, if that fails then guide user to re-login.
DApp Interaction Scenarios Overview
| Scenario | Description | Core MCP Tools |
|---|---|---|
| Wallet connection | DApp requests wallet address | wallet.get_addresses |
| Message signing | DApp login verification / EIP-712 typed data signing | wallet.sign_message |
| DApp transaction execution | Execute on-chain transactions generated by DApp (mint, stake, claim...) | wallet.sign_transaction → tx.send_raw_transaction |
| ERC20 Approve | Authorize DApp contract to use specified token | wallet.sign_transaction → tx.send_raw_transaction |
MCP Tool Invocation Specification
1. wallet.get_addresses (Cross-Skill) — Get wallet addresses
Get wallet addresses for the account on each chain, for DApp connection. This tool belongs to the gate-dex-mcpwallet domain and is invoked cross-Skill here.
| Field | Description |
|---|---|
| Tool name | wallet.get_addresses |
| Parameters | { account_id: string, mcp_token: string } |
| Return value | { addresses: { [chain: string]: string } } |
Invocation example:
CallMcpTool(
server="gate-wallet",
toolName="wallet.get_addresses",
arguments={ account_id: "acc_12345", mcp_token: "<mcp_token>" }
)
Return example:
{
"addresses": {
"eth": "0xABCdef1234567890ABCdef1234567890ABCdef12",
"bsc": "0xABCdef1234567890ABCdef1234567890ABCdef12",
"sol": "7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"
}
}
Agent behavior: EVM chains share the same address. Provide the target chain address to the DApp to complete wallet connection.
2. wallet.sign_message — Sign message
Sign arbitrary messages using server-hosted private key. Supports personal_sign and EIP-712 typed data signing.
| Field | Description |
|---|---|
| Tool name | wallet.sign_message |
| Parameters | { message: string, chain: string, account_id: string, mcp_token: string } |
| Return value | { signature: string } |
Parameter description:
| Parameter | Required | Description |
|---|---|---|
message | Yes | Message to sign. For personal_sign pass raw text, for EIP-712 pass JSON string |
chain | Yes | Chain identifier (e.g. "eth", "bsc") |
account_id | Yes | User account ID |
mcp_token | Yes | Authentication token |
Invocation example (personal_sign):
CallMcpTool(
server="gate-wallet",
toolName="wallet.sign_message",
arguments={
message: "Welcome to Uniswap! Sign this message to verify your wallet. Nonce: abc123",
chain: "eth",
account_id: "acc_12345",
mcp_token: "<mcp_token>"
}
)
Invocation example (EIP-712):
CallMcpTool(
server="gate-wallet",
toolName="wallet.sign_message",
arguments={
message: "{\"types\":{\"EIP712Domain\":[{\"name\":\"name\",\"type\":\"string\"}],\"Permit\":[{\"name\":\"owner\",\"type\":\"address\"},{\"name\":\"spender\",\"type\":\"address\"},{\"name\":\"value\",\"type\":\"uint256\"}]},\"primaryType\":\"Permit\",\"domain\":{\"name\":\"USDC\"},\"message\":{\"owner\":\"0xABC...\",\"spender\":\"0xDEF...\",\"value\":\"1000000000\"}}",
chain: "eth",
account_id: "acc_12345",
mcp_token: "<mcp_token>"
}
)
Return example:
{
"signature": "0x1234abcd...ef5678"
}
Agent behavior: Before signing, show the user the message content and explain the purpose. After signing, return the signature to the user.
3. wallet.sign_transaction — Sign DApp transaction
Sign unsigned transactions built by DApp using server-hosted private key. Only invoke after user explicitly confirms.
| Field | Description |
|---|---|
| Tool name | wallet.sign_transaction |
| Parameters | { raw_tx: string, chain: string, account_id: string, mcp_token: string } |
| Return value | { signed_tx: string } |
Parameter description:
| Parameter | Required | Description |
|---|---|---|
raw_tx | Yes | Serialized unsigned transaction data (hex format) |
chain | Yes | Chain identifier |
account_id | Yes | User account ID |
mcp_token | Yes | Authentication token |
Invocation example:
CallMcpTool(
server="gate-wallet",
toolName="wallet.sign_transaction",
arguments={
raw_tx: "0x02f8...",
chain: "eth",
account_id: "acc_12345",
mcp_token: "<mcp_token>"
}
)
Return example:
{
"signed_tx": "0x02f8b2...signed..."
}
4. tx.send_raw_transaction — Broadcast signed transaction
Broadcast the signed DApp transaction to the on-chain network.
| Field | Description |
|---|---|
| Tool name | tx.send_raw_transaction |
| Parameters | { signed_tx: string, chain: string, mcp_token: string } |
| Return value | { hash_id: string } |
Parameter description:
| Parameter | Required | Description |
|---|---|---|
signed_tx | Yes | Signed transaction returned by wallet.sign_transaction |
chain | Yes | Chain identifier |
mcp_token | Yes | Authentication token |
Invocation example:
CallMcpTool(
server="gate-wallet",
toolName="tx.send_raw_transaction",
arguments={
signed_tx: "0x02f8b2...signed...",
chain: "eth",
mcp_token: "<mcp_token>"
}
)
Return example:
{
"hash_id": "0xa1b2c3d4e5f6...7890"
}
Supported DApp Interaction Types
| Type | Example scenario | Description |
|---|---|---|
| DeFi liquidity | Uniswap add/remove liquidity | Build Router contract addLiquidity / removeLiquidity call |
| DeFi lending | Aave deposit/borrow/repay | Build Pool contract supply / borrow / repay call |
| DeFi Staking | Lido stake ETH | Build stETH contract submit call |
| NFT Mint | Custom NFT minting | Build mint contract call |
| NFT trading | Buy/sell NFT | Build Marketplace contract call |
| Token Approve | Authorize any contract to use token | Build ERC20 approve(spender, amount) calldata |
| Arbitrary contract call | User provides ABI + parameters | Agent encodes calldata and builds transaction |
| Message signing | DApp login verification | wallet.sign_message, no on-chain transaction needed |
Supported Chains
| Chain ID | Network name | Type | Native Gas token | Block explorer |
|---|---|---|---|---|
eth | Ethereum | EVM | ETH | etherscan.io |
bsc | BNB Smart Chain | EVM | BNB | bscscan.com |
polygon | Polygon | EVM | MATIC | polygonscan.com |
arbitrum | Arbitrum One | EVM | ETH | arbiscan.io |
optimism | Optimism | EVM | ETH | optimistic.etherscan.io |
avax | Avalanche C-Chain | EVM | AVAX | snowtrace.io |
base | Base | EVM | ETH | basescan.org |
sol | Solana | Non-EVM | SOL | solscan.io |
Skill Routing
Based on user intent after DApp operation, route to the corresponding Skill:
| User intent | Route target |
|---|---|
| View updated balance | gate-dex-mcpwallet |
| View transaction details / history | gate-dex-mcpwallet (tx.detail, tx.list) |
| View contract security info | gate-dex-mcpmarket (token_get_risk_info) |
| Transfer tokens | gate-dex-mcptransfer |
| Swap tokens | gate-dex-mcpswap |
| Login / authentication expired | gate-dex-mcpauth |
Operation Flows
Flow A: DApp wallet connection
Step 0: MCP Server connection check
Call chain.config({chain: "eth"}) to probe availability
↓ Success
Step 1: Authentication check
Confirm valid mcp_token and account_id
No token → Guide to gate-dex-mcpauth for login
↓
Step 2: Get wallet address
Call wallet.get_addresses({ account_id, mcp_token })
Extract target chain address
↓
Step 3: Display address
────────────────────────────
🔗 Wallet Connection Info
Chain: {chain_name}
Address: {address}
Use this address for DApp connection.
EVM chains (Ethereum/BSC/Polygon etc.) share the same address.
────────────────────────────
Flow B: Message signing
Step 0: MCP Server connection check
↓ Success
Step 1: Authentication check
↓
Step 2: Intent recognition + parameter collection
Extract signing request from user input:
- message: Content to sign (required)
- chain: Target chain (optional, default eth)
- Signing type: personal_sign or EIP-712 (auto-detect from message format)
↓
Step 3: Display signing content for confirmation
────────────────────────────
✍️ Message Signing Request
Chain: {chain_name}
Signing type: {personal_sign / EIP-712}
Content to sign:
{message_content}
This signature does not create an on-chain transaction and does not consume Gas.
Reply "confirm" to sign, "cancel" to abort.
────────────────────────────
↓ User confirms
Step 4: Execute signing
Call wallet.sign_message({ message, chain, account_id, mcp_token })
↓
Step 5: Display signing result
────────────────────────────
✅ Signing complete
Signature: {signature}
Submit this signature to the DApp to complete verification.
────────────────────────────
Flow C: DApp transaction execution (main flow)
Step 0: MCP Server connection check
Call chain.config({chain: "eth"}) to probe availability
↓ Success
Step 1: Authentication check
Confirm valid mcp_token and account_id
No token → Guide to gate-dex-mcpauth for login
↓
Step 2: Intent recognition + parameter collection
Extract DApp operation intent from user input:
- Operation type (e.g. "add liquidity", "stake ETH", "mint NFT")
- Target protocol/contract (e.g. Uniswap, Aave, Lido)
- Amount and tokens
- Chain (optional, can infer from context)
For missing parameters, ask user one by one:
────────────────────────────
Please provide DApp interaction info:
- Operation: (required, e.g. "add ETH-USDC liquidity on Uniswap")
- Chain: (optional, default Ethereum)
- Amount: (may need multiple amounts depending on operation type)
────────────────────────────
↓ Parameters complete
Step 3: Get wallet info (cross-Skill: gate-dex-mcpwallet)
Call wallet.get_addresses({ account_id, mcp_token }) → Get from_address
Call wallet.get_token_list({ account_id, chain, mcp_token }) → Get balance
↓
Step 4: Security review (recommended step)
Call token_get_risk_info({ chain, address: contract_address }) (cross-Skill: gate-dex-mcpmarket)
Evaluate contract risk level
↓
Step 5: Agent builds transaction
Based on DApp operation type, Agent encodes contract call calldata:
a) Known protocol (Uniswap/Aave/Lido etc.): Encode per protocol ABI
b) User provides ABI + parameters: Agent parses and encodes
c) User provides complete calldata: Use directly
Build transaction parameters:
- to: Contract address
- data: calldata
- value: Amount of native token to send (if any)
↓
Step 6: Determine if Approve is needed
If operation involves ERC20 token (non-native token):
- Check if current allowance is sufficient
- Insufficient → Execute Approve transaction first (see Flow D)
↓
Step 7: Agent balance validation (mandatory)
Validation rules:
a) Operation involves native token: native_balance >= amount + estimated_gas
b) Operation involves ERC20 token: token_balance >= amount AND native_balance >= estimated_gas
c) Gas only: native_balance >= estimated_gas
Validation failed → Abort transaction:
────────────────────────────
❌ Insufficient balance, cannot execute DApp operation
Required {symbol}: {required_amount}
Current balance: {current_balance}
Shortfall: {shortfall}
Suggestions:
- Reduce operation amount
- Deposit tokens to wallet first
────────────────────────────
↓ Validation passed
Step 8: Display DApp transaction confirmation summary (mandatory gate)
Display content see "DApp Transaction Confirmation Template" below.
Must wait for user to explicitly reply "confirm" before proceeding.
↓
User replies "confirm" → Proceed to Step 9
User replies "cancel" → Abort transaction
User requests modification → Return to Step 2
Step 9: Sign transaction
Call wallet.sign_transaction({ raw_tx, chain, account_id, mcp_token })
Get signed_tx
↓
Step 10: Broadcast transaction
Call tx.send_raw_transaction({ signed_tx, chain, mcp_token })
Get hash_id
↓
Step 11: Display result + follow-up suggestions
────────────────────────────
✅ DApp transaction broadcast successful!
Operation: {operation_description}
Transaction Hash: {hash_id}
Block explorer: https://{explorer}/tx/{hash_id}
Transaction submitted to network. Confirmation time depends on network congestion.
You can:
- View updated balance
- View transaction details
- Continue with other operations
────────────────────────────
Flow D: ERC20 Approve authorization
Step 0: MCP Server connection check
↓ Success
Step 1: Authentication check
↓
Step 2: Determine Approve parameters
- token_address: Token contract address to authorize
- spender: Spender contract address (e.g. Uniswap Router)
- amount: Authorization amount
Agent recommends exact amount over unlimited:
────────────────────────────
💡 Authorization amount recommendation
This operation requires authorizing {spender_name} to use your {token_symbol}.
Recommended options:
1. Exact authorization: {exact_amount} {token_symbol} (only for this operation, more secure)
2. Unlimited authorization: unlimited (no need to re-authorize for future operations, but higher risk)
Please choose authorization method, or specify custom amount.
────────────────────────────
↓
Step 3: Build Approve calldata
Encode ERC20 approve(spender, amount) function call:
- function selector: 0x095ea7b3
- spender: Contract address (32 bytes padded)
- amount: Authorization amount (uint256)
↓
Step 4: Display Approve confirmation
────────────────────────────
========== Token Authorization Confirmation ==========
Chain: {chain_name}
Token: {token_symbol} ({token_address})
Authorize to: {spender_name} ({spender_address})
Authorization amount: {amount} {token_symbol}
Estimated Gas: {estimated_gas} {gas_symbol}
===============================
Reply "confirm" to execute authorization, "cancel" to abort.
────────────────────────────
↓ User confirms
Step 5: Sign + broadcast Approve transaction
Call wallet.sign_transaction({ raw_tx: approve_tx, chain, account_id, mcp_token })
Call tx.send_raw_transaction({ signed_tx, chain, mcp_token })
↓
Step 6: Approve success
Display Approve transaction hash, continue with subsequent DApp operation (Flow C Step 9)
Flow E: Arbitrary contract call (user provides ABI)
Step 0: MCP Server connection check
↓ Success
Step 1: Authentication check
↓
Step 2: Collect contract call info
User provides:
- Contract address
- Function name or ABI
- Function parameters
- value (optional, needed when sending native token)
- Chain
↓
Step 3: Agent encodes calldata
Encode function call data based on ABI and parameters
↓
Step 4: Security review + balance validation + confirmation gate
Same as Flow C Steps 4 ~ 8
↓
Step 5: Sign + broadcast
Same as Flow C Steps 9 ~ 11
DApp Transaction Confirmation Template
This confirmation summary must be shown before the user explicitly replies "confirm". Agent must NOT execute signing before that. This is a mandatory gate that cannot be skipped.
Standard DApp transaction confirmation
========== DApp Transaction Confirmation ==========
Chain: {chain_name}
DApp/Protocol: {protocol_name} (e.g. Uniswap V3)
Operation: {operation} (e.g. Add liquidity)
Contract address: {contract_address}
---------- Transaction Details ----------
{operation_specific_details}
(e.g. Token A: 0.5 ETH, Token B: 1000 USDC)
---------- Authorization Info ----------
{approve_info_if_needed}
(e.g. Approve required: USDC → Uniswap Router, amount: 1000 USDC)
(When no approval needed: No additional authorization required)
---------- Balance Info ----------
{token_symbol} balance: {balance} (sufficient ✅ / insufficient ❌)
{gas_symbol} balance (Gas): {gas_balance} (sufficient ✅)
---------- Fee Info ----------
Estimated Gas (Approve): {approve_gas} (if needed)
Estimated Gas (Transaction): {tx_gas} {gas_symbol}
---------- Security Check ----------
Contract security audit: {risk_level} (e.g. audited/low risk/high risk/unknown)
===============================
Reply "confirm" to execute, "cancel" to abort, or specify modifications.
Note: DApp interaction involves smart contract calls. Please confirm contract address and operation are correct.
Unknown contract warning confirmation
When target contract is unaudited or audit result is high risk:
========== ⚠️ DApp Transaction Confirmation (Security Warning) ==========
Chain: {chain_name}
Contract address: {contract_address}
⚠️ Security warning: This contract is unaudited or marked as high risk.
Interacting with unknown contracts may result in asset loss. Please confirm you trust this contract.
---------- Transaction Details ----------
{operation_details}
---------- Balance Info ----------
{balance_info}
---------- Fee Info ----------
{gas_info}
---------- Security Check ----------
Contract audit status: {risk_detail}
=================================================
Reply "confirm" to proceed anyway (at your own risk), "cancel" to abort.
Cross-Skill Workflow
Complete DApp interaction flow (from login to completion)
gate-dex-mcpauth (login, get mcp_token + account_id)
→ gate-dex-mcpwallet (wallet.get_addresses → get address)
→ gate-dex-mcpwallet (wallet.get_token_list → validate balance)
→ gate-dex-mcpmarket (token_get_risk_info → contract security review)
→ gate-dex-mcpdapp (Approve? → confirm → sign → broadcast)
→ gate-dex-mcpwallet (view updated balance)
DApp message signing (no transaction)
gate-dex-mcpauth (login)
→ gate-dex-mcpdapp (wallet.sign_message → return signature result)
Guided by other Skills
| Source Skill | Scenario | Description |
|---|---|---|
gate-dex-mcpwallet | User wants to connect DApp after viewing address | Carries account_id and address info |
gate-dex-mcpmarket | User wants to participate in DeFi after viewing token | Carries token and chain context |
gate-dex-mcpswap | User wants to participate in DeFi after Swap | Carries chain and token context |
Invoking other Skills
| Target Skill | Invocation scenario | Tools used |
|---|---|---|
gate-dex-mcpwallet | Get wallet address for DApp connection | wallet.get_addresses |
gate-dex-mcpwallet | Validate balance before DApp transaction | wallet.get_token_list |
gate-dex-mcpwallet | View updated balance after DApp transaction | wallet.get_token_list |
gate-dex-mcpauth | Not logged in or token expired | auth.refresh_token or full login flow |
gate-dex-mcpmarket | Contract security review | token_get_risk_info |
gate-dex-mcpwallet | View transaction details after DApp transaction | tx.detail, tx.list |
Contract Address Validation Rules
Contract address validation for DApp transactions and Approve:
| Chain type | Format requirement | Validation rule |
|---|---|---|
| EVM (eth/bsc/polygon/...) | Starts with 0x, 40 hex chars (42 chars total) | Regex ^0x[0-9a-fA-F]{40}$, recommend EIP-55 checksum validation |
| Solana | Base58 encoded, 32-44 chars | Regex ^[1-9A-HJ-NP-Za-km-z]{32,44}$ |
When validation fails:
❌ Invalid contract address format
Provided address: {user_input}
Expected format: {expected_format}
Please check the address is correct, complete, and matches the target chain.
ERC20 Approve Calldata Encoding Specification
When building Approve transactions, Agent must encode calldata per the following rules:
Function signature: approve(address spender, uint256 amount)
Selector: 0x095ea7b3
Calldata structure:
0x095ea7b3
+ spender address (32 bytes, left-padded with zeros)
+ amount (32 bytes, uint256)
Example (approve Uniswap Router to use 1000 USDT, 6 decimals):
0x095ea7b3
000000000000000000000000 68b3465833fb72A70ecDF485E0e4C7bD8665Fc45 ← spender
00000000000000000000000000000000000000000000000000000000 3B9ACA00 ← 1000 * 10^6
Exact vs unlimited authorization:
| Method | amount value | Security | Convenience |
|---|---|---|---|
| Exact authorization | Actual amount needed | High (expires when used) | Low (requires re-authorization each time) |
| Unlimited authorization | 2^256 - 1 (0xfff...fff) | Low (contract can transfer tokens anytime) | High (one-time authorization, permanent) |
Recommend exact authorization unless user explicitly requests unlimited.
EIP-712 Signature Data Parsing Specification
When displaying EIP-712 signing requests, Agent must parse JSON structured data into human-readable format:
Parsing points
- Domain info: Extract
name,version,chainId,verifyingContract, display in table format - Primary Type: Clearly label the primary type of signature data (e.g.
Order,Permit,Vote) - Message fields: Display each field; truncate
addresstype for display; try to convertuint256to human-readable values - Known type recognition:
Permit(EIP-2612) → Label "Token authorization permit", highlight spender and valueOrder(DEX order) → Label "Trading order", highlight trading pair and amountVote(governance vote) → Label "Governance vote", highlight vote content
Known EIP-712 signature types
| primaryType | Common source | Risk level | Description |
|---|---|---|---|
Permit | ERC-2612 token | Medium | Off-chain signature authorization, no Gas but grants spender token usage permission |
Order | DEX (e.g. 0x, Seaport) | Medium | Represents trading order, can be executed on-chain after signing |
Vote | Governance protocol (e.g. Compound) | Low | Governance vote |
Delegation | Governance protocol | Low | Voting power delegation |
| Unknown type | Any DApp | High | Additional warning needed for user to carefully review content |
Edge Cases and Error Handling
| Scenario | Handling |
|---|---|
| MCP Server not configured | Abort all operations, show Cursor configuration guide |
| MCP Server unreachable | Abort all operations, show network check prompt |
Not logged in (no mcp_token) | Guide to gate-dex-mcpauth to complete login, then automatically return to continue DApp operation |
mcp_token expired | First try auth.refresh_token for silent refresh, if fails then guide to re-login |
| Insufficient Gas token balance | Abort transaction/Approve, show insufficient Gas info, suggest deposit |
| Token for Approve not in holdings | Prompt user does not hold this token; Approve can execute but has no practical effect. Confirm whether to continue |
| Spender contract is high risk | Strongly warn user, recommend cancel. If user insists, can still proceed (requires re-confirmation) |
| Spender contract is unknown (not indexed) | Show "unknown contract" warning, prompt user to verify contract source |
| Invalid contract address format | Reject transaction, prompt correct address format |
wallet.sign_message failed | Show signing error, possible causes: incorrect message format, account anomaly. Do not auto-retry |
| EIP-712 JSON parse failed | Show raw JSON content, prompt format may be incorrect, ask user to confirm or re-fetch from DApp |
wallet.sign_transaction failed | Show signing error, possible causes: invalid transaction data, account permission issue. Do not auto-retry |
tx.send_raw_transaction failed | Show broadcast error (nonce conflict, insufficient gas, network congestion, etc.), suggest corresponding measures based on error type |
| User cancels confirmation (signing/transaction/Approve) | Abort immediately, do not execute any signing or broadcast. Show cancellation prompt, remain friendly |
tx.gas estimation failed | Show error, possible causes: contract call will revert, incorrect parameters. Suggest checking transaction data |
| Approve amount is 0 | Treat as "revoke authorization" operation, confirm with user if they want to revoke authorization for this spender |
| User requests unlimited authorization | Show high-risk warning template, requires user secondary confirmation |
| Duplicate Approve for same spender | Prompt existing authorization, new Approve will overwrite old. Confirm whether to continue |
| Network disconnect after signing, before broadcast | Prompt signed transaction can still be broadcast later, suggest retry after network recovery |
| DApp-provided raw_tx format abnormal | Reject signing, prompt transaction data format incorrect, suggest re-generate from DApp |
| Unsupported chain identifier | Show supported chain list, ask user to re-select |
| Message signing request chain is Solana | Prompt Solana message signing not supported, EVM chains only |
| Network interruption | Show network error, suggest check network and retry |
Security Rules
mcp_tokenconfidentiality: Never displaymcp_tokenin plain text to user; use placeholder<mcp_token>in invocation examples only.account_idmasking: When displaying to user, only show partial characters (e.g.acc_12...89).- Token auto-refresh: When
mcp_tokenexpires, prefer silent refresh first; only require re-login if refresh fails. - Confirmation required before signing: All signing operations (message signing, transaction signing, Approve) must display full content to user and obtain explicit "confirm" reply before execution. Cannot skip, simplify, or auto-confirm.
- Contract security review: When DApp interaction involves unknown contract, must call
token_get_risk_infofor security review and display result to user. High-risk contracts require additional prominent warning. - Default exact authorization: ERC20 Approve defaults to exact authorization amount. Use unlimited only when user explicitly requests, and must display unlimited authorization risk warning.
- EIP-712 content transparency: EIP-712 signing requests must be fully parsed and displayed in human-readable format to user; cannot omit any key fields (especially
verifyingContract,spender, amount-type fields). - Gas balance validation mandatory: Before DApp transaction and Approve, must validate Gas token balance; prohibit initiating signing and broadcast when balance is insufficient.
- No auto-retry on failed operations: After signing or broadcast fails, clearly show error to user; do not auto-retry in background.
- Prohibit operations when MCP Server not configured or unreachable: If Step 0 connection check fails, abort all subsequent steps.
- MCP Server error transparency: All MCP Server error messages displayed to user as-is; do not hide or alter.
raw_txmust not be leaked: Unsigned transaction raw data flows only between Agent and MCP Server; do not display hex original to user.- Broadcast promptly after signing: After successful signing, broadcast immediately; do not hold signed transaction for long.
- Permit signature risk warning: EIP-2612 Permit signature consumes no Gas but is equivalent to authorization; must remind user to note spender and authorization amount.
- Phishing prevention: Agent does not actively construct transactions or signing requests pointing to unknown contracts. All DApp interaction data should be provided by user or from trusted sources.