Back to skills
SkillHub ClubAnalyze Data & AIFull StackData / AI

moralis

Moralis — Web3 data, token prices, wallet history, NFTs, DeFi positions, and blockchain events.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,087
Hot score
99
Updated
March 20, 2026
Overall rating
C4.0
Composite score
4.0
Best-practice grade
B81.2

Install command

npx @skill-hub/cli install openclaw-skills-moralis

Repository

openclaw/skills

Skill path: skills/aiwithabidi/moralis

Moralis — Web3 data, token prices, wallet history, NFTs, DeFi positions, and blockchain events.

Open repository

Best for

Primary workflow: Analyze Data & AI.

Technical facets: Full Stack, Data / AI.

Target audience: everyone.

License: MIT.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install moralis into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding moralis to shared team environments
  • Use moralis for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: moralis
description: "Moralis — Web3 data, token prices, wallet history, NFTs, DeFi positions, and blockchain events."
homepage: https://www.agxntsix.ai
license: MIT
compatibility: Python 3.10+ (stdlib only — no dependencies)
metadata: {"openclaw": {"emoji": "🌐", "requires": {"env": ["MORALIS_API_KEY"]}, "primaryEnv": "MORALIS_API_KEY", "homepage": "https://www.agxntsix.ai"}}
---

# 🌐 Moralis

Moralis — Web3 data, token prices, wallet history, NFTs, DeFi positions, and blockchain events.

## Requirements

| Variable | Required | Description |
|----------|----------|-------------|
| `MORALIS_API_KEY` | ✅ | Moralis API key |


## Quick Start

```bash
# Get native balance
python3 {{baseDir}}/scripts/moralis.py get-native-balance --address <value> --chain "eth"

# Get ERC-20 token balances
python3 {{baseDir}}/scripts/moralis.py get-token-balances --address <value> --chain "eth"

# Get wallet transactions
python3 {{baseDir}}/scripts/moralis.py get-transactions --address <value> --chain "eth"

# Get token price
python3 {{baseDir}}/scripts/moralis.py get-token-price --address <value> --chain "eth"

# Get NFTs for wallet
python3 {{baseDir}}/scripts/moralis.py get-nfts --address <value> --chain "eth"

# Get NFT metadata
python3 {{baseDir}}/scripts/moralis.py get-nft-metadata --address <value> --token-id <value> --chain "eth"

# Get NFT transfers
python3 {{baseDir}}/scripts/moralis.py get-nft-transfers --address <value> --chain "eth"

# Get token transfers
python3 {{baseDir}}/scripts/moralis.py get-token-transfers --address <value> --chain "eth"

# Get DeFi positions
python3 {{baseDir}}/scripts/moralis.py get-defi-positions --address <value> --chain "eth"

# Resolve ENS/Unstoppable domain
python3 {{baseDir}}/scripts/moralis.py resolve-domain --domain <value>

# Search token by symbol
python3 {{baseDir}}/scripts/moralis.py search-token --symbol <value>

# Get block details
python3 {{baseDir}}/scripts/moralis.py get-block --block <value> --chain "eth"
```

## Output Format

All commands output JSON by default.

## Script Reference

| Script | Description |
|--------|-------------|
| `{baseDir}/scripts/moralis.py` | Main CLI — all commands in one tool |

## Credits
Built by [M. Abidi](https://www.linkedin.com/in/mohammad-ali-abidi) | [agxntsix.ai](https://www.agxntsix.ai)
[YouTube](https://youtube.com/@aiwithabidi) | [GitHub](https://github.com/aiwithabidi)
Part of the **AgxntSix Skill Suite** for OpenClaw agents.

📅 **Need help setting up OpenClaw for your business?** [Book a free consultation](https://cal.com/agxntsix/abidi-openclaw)


---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "aiwithabidi",
  "slug": "moralis",
  "displayName": "Moralis",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1772736787157,
    "commit": "https://github.com/openclaw/skills/commit/10687f16dbf763d50a2c2fea163a261a715f06f0"
  },
  "history": []
}

```

### scripts/moralis.py

```python
#!/usr/bin/env python3
"""Moralis CLI — Moralis — Web3 data, token prices, wallet history, NFTs, DeFi positions, and blockchain events.

Zero dependencies beyond Python stdlib.
"""

import argparse
import json
import os
import sys
import urllib.request
import urllib.error
import urllib.parse

API_BASE = "https://deep-index.moralis.io/api/v2.2"


def get_env(name):
    val = os.environ.get(name, "")
    if not val:
        env_path = os.path.join(os.environ.get("WORKSPACE", os.path.expanduser("~/.openclaw/workspace")), ".env")
        if os.path.exists(env_path):
            with open(env_path) as f:
                for line in f:
                    line = line.strip()
                    if line.startswith(name + "="):
                        val = line.split("=", 1)[1].strip().strip('"').strip("'")
                        break
    return val


def req(method, url, data=None, headers=None, timeout=30):
    body = json.dumps(data).encode() if data else None
    r = urllib.request.Request(url, data=body, method=method)
    r.add_header("Content-Type", "application/json")
    if headers:
        for k, v in headers.items():
            r.add_header(k, v)
    try:
        resp = urllib.request.urlopen(r, timeout=timeout)
        raw = resp.read().decode()
        return json.loads(raw) if raw.strip() else {}
    except urllib.error.HTTPError as e:
        err = e.read().decode()
        print(json.dumps({"error": True, "code": e.code, "message": err}), file=sys.stderr)
        sys.exit(1)


def api(method, path, data=None, params=None):
    """Make authenticated API request."""
    base = API_BASE
    token = get_env("MORALIS_API_KEY")
    if not token:
        print("Error: MORALIS_API_KEY not set", file=sys.stderr)
        sys.exit(1)
    headers = {"Authorization": f"Bearer {token}"}
    url = f"{base}{path}"
    if params:
        qs = urllib.parse.urlencode({k: v for k, v in params.items() if v}, doseq=True)
        url = f"{url}{'&' if '?' in url else '?'}{qs}"
    return req(method, url, data=data, headers=headers)


def out(data):
    print(json.dumps(data, indent=2, default=str))


def cmd_get_native_balance(args):
    """Get native balance"""
    path = "/{address}/balance"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_token_balances(args):
    """Get ERC-20 token balances"""
    path = "/{address}/erc20"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_transactions(args):
    """Get wallet transactions"""
    path = "/{address}"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_token_price(args):
    """Get token price"""
    path = "/erc20/{address}/price"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_nfts(args):
    """Get NFTs for wallet"""
    path = "/{address}/nft"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_nft_metadata(args):
    """Get NFT metadata"""
    path = "/nft/{address}/{token_id}"
    path = path.replace("{address}", str(args.address or ""))
    path = path.replace("{token-id}", str(args.token_id or ""))
    params = {}
    if args.token_id:
        params["token-id"] = args.token_id
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_nft_transfers(args):
    """Get NFT transfers"""
    path = "/nft/{address}/transfers"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_token_transfers(args):
    """Get token transfers"""
    path = "/{address}/erc20/transfers"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_get_defi_positions(args):
    """Get DeFi positions"""
    path = "/wallets/{address}/defi/positions"
    path = path.replace("{address}", str(args.address or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)

def cmd_resolve_domain(args):
    """Resolve ENS/Unstoppable domain"""
    path = "/resolve/{domain}"
    path = path.replace("{domain}", str(args.domain or ""))
    result = api("GET", path)
    out(result)

def cmd_search_token(args):
    """Search token by symbol"""
    path = "/erc20/metadata?symbols={symbol}"
    path = path.replace("{symbol}", str(args.symbol or ""))
    result = api("GET", path)
    out(result)

def cmd_get_block(args):
    """Get block details"""
    path = "/block/{block}"
    path = path.replace("{block}", str(args.block or ""))
    params = {}
    if args.chain:
        params["chain"] = args.chain
    result = api("GET", path, params=params)
    out(result)


def main():
    parser = argparse.ArgumentParser(description="Moralis CLI")
    sub = parser.add_subparsers(dest="command")
    sub.required = True

    p_get_native_balance = sub.add_parser("get-native-balance", help="Get native balance")
    p_get_native_balance.add_argument("--address", required=True)
    p_get_native_balance.add_argument("--chain", default="eth")
    p_get_native_balance.set_defaults(func=cmd_get_native_balance)

    p_get_token_balances = sub.add_parser("get-token-balances", help="Get ERC-20 token balances")
    p_get_token_balances.add_argument("--address", required=True)
    p_get_token_balances.add_argument("--chain", default="eth")
    p_get_token_balances.set_defaults(func=cmd_get_token_balances)

    p_get_transactions = sub.add_parser("get-transactions", help="Get wallet transactions")
    p_get_transactions.add_argument("--address", required=True)
    p_get_transactions.add_argument("--chain", default="eth")
    p_get_transactions.set_defaults(func=cmd_get_transactions)

    p_get_token_price = sub.add_parser("get-token-price", help="Get token price")
    p_get_token_price.add_argument("--address", required=True)
    p_get_token_price.add_argument("--chain", default="eth")
    p_get_token_price.set_defaults(func=cmd_get_token_price)

    p_get_nfts = sub.add_parser("get-nfts", help="Get NFTs for wallet")
    p_get_nfts.add_argument("--address", required=True)
    p_get_nfts.add_argument("--chain", default="eth")
    p_get_nfts.set_defaults(func=cmd_get_nfts)

    p_get_nft_metadata = sub.add_parser("get-nft-metadata", help="Get NFT metadata")
    p_get_nft_metadata.add_argument("--address", required=True)
    p_get_nft_metadata.add_argument("--token-id", required=True)
    p_get_nft_metadata.add_argument("--chain", default="eth")
    p_get_nft_metadata.set_defaults(func=cmd_get_nft_metadata)

    p_get_nft_transfers = sub.add_parser("get-nft-transfers", help="Get NFT transfers")
    p_get_nft_transfers.add_argument("--address", required=True)
    p_get_nft_transfers.add_argument("--chain", default="eth")
    p_get_nft_transfers.set_defaults(func=cmd_get_nft_transfers)

    p_get_token_transfers = sub.add_parser("get-token-transfers", help="Get token transfers")
    p_get_token_transfers.add_argument("--address", required=True)
    p_get_token_transfers.add_argument("--chain", default="eth")
    p_get_token_transfers.set_defaults(func=cmd_get_token_transfers)

    p_get_defi_positions = sub.add_parser("get-defi-positions", help="Get DeFi positions")
    p_get_defi_positions.add_argument("--address", required=True)
    p_get_defi_positions.add_argument("--chain", default="eth")
    p_get_defi_positions.set_defaults(func=cmd_get_defi_positions)

    p_resolve_domain = sub.add_parser("resolve-domain", help="Resolve ENS/Unstoppable domain")
    p_resolve_domain.add_argument("--domain", required=True)
    p_resolve_domain.set_defaults(func=cmd_resolve_domain)

    p_search_token = sub.add_parser("search-token", help="Search token by symbol")
    p_search_token.add_argument("--symbol", required=True)
    p_search_token.set_defaults(func=cmd_search_token)

    p_get_block = sub.add_parser("get-block", help="Get block details")
    p_get_block.add_argument("--block", required=True)
    p_get_block.add_argument("--chain", default="eth")
    p_get_block.set_defaults(func=cmd_get_block)

    args = parser.parse_args()
    args.func(args)


if __name__ == "__main__":
    main()

```

moralis | SkillHub