Moralis Data Api

TotalClaw 作者 MoralisWeb3 v1.3.1

从 Moralis API 查询 Web3 区块链数据。当用户询问钱包数据(余额、代币、NFT、交易历史、盈利能力、净值)、代币数据(价格、元数据、DEX 对、分析、安全评分)、NFT 数据(元数据、转账、特征、稀有性、底价)、DeFi 头寸、交易所和基金的实体/标签数据或区块和交易数据时使用。支持EVM链(以太坊、Polygon、BSC、Arbitrum、Base、Optimism、Avalanche等)和Solana。不适用于实时流 - 请改用moralis-streams-api。

源码 ↗

安装 / 下载方式

TotalClaw CLI推荐
totalclaw install totalclaw:novnski~moralis-data-api
cURL直接下载,无需登录
curl -fsSL https://skills.taituai.com/api/skills/totalclaw%3Anovnski~moralis-data-api/file -o moralis-data-api.md
Git 仓库获取源码
git clone https://github.com/openclaw/skills/commit/1f19bebff717f0d3fc2ee4b8a41fb16f06dca46a
## 概述(中文)

从 Moralis API 查询 Web3 区块链数据。当用户询问钱包数据(余额、代币、NFT、交易历史、盈利能力、净值)、代币数据(价格、元数据、DEX 对、分析、安全评分)、NFT 数据(元数据、转账、特征、稀有性、底价)、DeFi 头寸、交易所和基金的实体/标签数据或区块和交易数据时使用。支持EVM链(以太坊、Polygon、BSC、Arbitrum、Base、Optimism、Avalanche等)和Solana。不适用于实时流 - 请改用moralis-streams-api。

## 原文

## CRITICAL: Read Rule Files Before Implementing

**The #1 cause of bugs is not reading the endpoint rule file before writing code.**

For EVERY endpoint:

1. Read `rules/{EndpointName}.md`
2. Find "Example Response" section
3. Copy the EXACT JSON structure
4. Note field names (snake_case), data types, HTTP method, path, wrapper structure

**Reading Order:**

1. This SKILL.md (core patterns)
2. Endpoint rule file in `rules/`
3. Pattern references in `references/` (for edge cases only)

---

## Setup

### API Key (optional)

**Never ask the user to paste their API key into the chat.** Instead:

1. Check if `MORALIS_API_KEY` is set in the environment (try running `[ -n "$MORALIS_API_KEY" ] && echo "API key is set" || echo "API key is NOT set"`).
2. If not set, offer to create the `.env` file with an empty placeholder: `MORALIS_API_KEY=`
3. Tell the user to open the `.env` file and paste their key there themselves.
4. Let them know: without the key, you won't be able to test or call the Moralis API on their behalf.

If they don't have a key yet, point them to [admin.moralis.com/register](https://admin.moralis.com/register) (free, no credit card).

### Environment Variable Discovery

The `.env` file location depends on how skills are installed:

Create the `.env` file in the project root (same directory the user runs Claude Code from). Make sure `.env` is in `.gitignore`.

### Verify Your Key

```bash
curl "https://deep-index.moralis.io/api/v2.2/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/balance?chain=0x1" \
  -H "X-API-Key: $MORALIS_API_KEY"
```

---

## Base URLs

| API    | Base URL                                 |
| ------ | ---------------------------------------- |
| EVM    | `https://deep-index.moralis.io/api/v2.2` |
| Solana | `https://solana-gateway.moralis.io`      |

## Authentication

All requests require: `X-API-Key: $MORALIS_API_KEY`

---

## Quick Reference: Most Common Patterns

### Data Type Rules

| Field          | Reality                          | NOT               |
| -------------- | -------------------------------- | ----------------- |
| `block_number` | Decimal `12386788`               | Hex `0xf2b5a4`    |
| `timestamp`    | ISO `"2021-05-07T11:08:35.000Z"` | Unix `1620394115` |
| `balance`      | String `"1000000000000000000"`   | Number            |
| `decimals`     | String or number                 | Always number     |

### Block Numbers (always decimal)

```typescript
block_number: 12386788; // number - use directly
block_number: "12386788"; // string - parseInt(block_number, 10)
```

### Timestamps (usually ISO strings)

```typescript
"2021-05-07T11:08:35.000Z"; // → new Date(timestamp).getTime()
```

### Balances (always strings unless its a property named "formatted" eg. balanceFormatted, BigInt)

```typescript
balance: "1000000000000000000";
// → (Number(BigInt(balance)) / 1e18).toFixed(6)
```

### Response Patterns

| Pattern                              | Example Endpoints                             |
| ------------------------------------ | --------------------------------------------- |
| Direct array `[...]`                 | getWalletTokenBalancesPrice, getTokenMetadata |
| Wrapped `{ result: [] }`             | getWalletNFTs, getWalletTransactions          |
| Paginated `{ page, cursor, result }` | getWalletHistory, getNFTTransfers             |

```typescript
// Safe extraction
const data = Array.isArray(response) ? response : response.result || [];
```

### Common Field Mappings

```typescript
token_address → tokenAddress
from_address_label → fromAddressLabel
block_number → blockNumber
receipt_status: "1" → success, "0" → failed
possible_spam: "true"/"false" → boolean check
```

---

## Common Pitfalls (Top 5)

1. **Block numbers are decimal, not hex** - Use `parseInt(x, 10)`, not `parseInt(x, 16)`
2. **Timestamps are ISO strings** - Use `new Date(timestamp).getTime()`
3. **Balances are strings** - Use `BigInt(balance)` for math
4. **Response may be wrapped** - Check for `.result` before `.map()`
5. **Path inconsistencies** - Some use `/wallets/{address}/...`, others `/{address}/...`

See [references/CommonPitfalls.md](references/CommonPitfalls.md) for complete reference.

---

## Pagination

Many endpoints use cursor-based pagination:

```bash
# First request
curl "...?limit=100" -H "X-API-Key: $KEY"

# Next page
curl "...?limit=100&cursor=<cursor_from_response>" -H "X-API-Key: $KEY"
```

See [references/Pagination.md](references/Pagination.md) for details.

---

## Testing Endpoints

```bash
ADDRESS="0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
CHAIN="0x1"

# Wallet Balance
curl "https://deep-index.moralis.io/api/v2.2/${ADDRESS}/balance?chain=${CHAIN}" \
  -H "X-API-Key: $MORALIS_API_KEY"

# Token Price
curl "https://deep-index.moralis.io/api/v2.2/erc20/0x6B175474E89094C44Da98b954EedeAC495271d0F/price?chain=${CHAIN}" \
  -H "X-API-Key: $MORALIS_API_KEY"

# Wallet Transactions (note result wrapper)
curl "https://deep-index.moralis.io/api/v2.2/${ADDRESS}?chain=${CHAIN}&limit=5" \
  -H "X-API-Key: $MORALIS_API_KEY" | jq '.result'
```

---

## Quick Troubleshooting

| Issue                     | Cause                  | Solution                            |
| ------------------------- | ---------------------- | ----------------------------------- |
| "Property does not exist" | Field name mismatch    | Check snake_case in rule file       |
| "Cannot read undefined"   | Missing optional field | Use `?.` optional chaining          |
| "blockNumber is NaN"      | Parsing decimal as hex | Use radix 10: `parseInt(x, 10)`     |
| "Wrong timestamp"         | Parsing ISO as number  | Use `new Date(timestamp).getTime()` |
| "404 Not Found"           | Wrong endpoint path    | Verify path in rule file            |

---

## Performance & Timeouts

Most endpoints respond quickly under normal conditions. Response times can vary based on wallet activity volume, chain, and query complexity.

**Recommended client timeouts:**
- Simple queries (balance, price, metadata): 10s
- Complex queries (wallet history, DeFi positions): 30s

Large wallets with extensive transaction histories may take longer — use pagination with reasonable `limit` values.

See [references/PerformanceAndLatency.md](references/PerformanceAndLatency.md) for optimization tips.

---

## Default Chain Behavior

**EVM addresses (`0x...`):** Default to Ethereum (`chain=0x1`) unless specified.

**Solana addresses (base58):** Auto-detected and routed to Solana API.

---

## Supported Chains

**EVM (40+ chains):** Ethereum (0x1), Polygon (0x89), BSC (0x38), Arbitrum (0xa4b1), Optimism (0xa), Base (0x2105), Avalanche (0xa86a), and more.

**Solana:** Mainnet, Devnet

See [references/SupportedApisAndChains.md](references/SupportedApisAndChains.md) for full list.

---

## Endpoint Catalog

Complete list of all 136 endpoints (102 EVM + 34 Solana) organized by category.

### Wallet

Balances, tokens, NFTs, transaction history, profitability, and net worth data.

| Endpoint | Description |
|----------|-------------|
| [getNativeBalance](rules/getNativeBalance.md) | Get native balance by wallet |
| [getNativeBalancesForAddresses](rules/getNativeBalancesForAddresses.md) | Get native balance for a set of wallets |
| [getWalletActiveChains](rules/getWalletActiveChains.md) | Get active chains by wallet address |
| [getWalletApprovals](rules/getWalletApprovals.md) | Get ERC20 approvals by wallet |
| [getWalletHistory](rules/getWalletHistory.md) | Get the complete decoded transaction history of a wallet |
| [getWalletInsight](rules/getWalletInsight.md) | Get wallet insight metrics |
| [getWalletNetWorth](rules/getWalletNetWorth.md) | Get wallet net worth |
| [getWalletNFTCollections](rules/getWalletNFTCollections.md)