Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion skills/metamask-agent-wallet/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: metamask-agent-wallet
description: Use when the user asks anything about blockchain wallets, transactions, signing, token transfers, supported chains, wallet balances, perpetual futures trading, prediction markets, token swaps, cross-chain bridges, market data, token discovery, decoding EVM calldata, or authentication via the MetaMask Agentic CLI. Single entry point for all mm CLI operations.
description: Use when the user asks anything about blockchain wallets, transactions, signing, token transfers, supported chains, wallet balances, perpetual futures trading, prediction markets, token swaps, cross-chain bridges, market data, token discovery, decoding EVM calldata, Aave V3 lending and borrowing, or authentication via the MetaMask Agentic CLI. Single entry point for all mm CLI operations.
license: MIT
metadata:
author: metamask
Expand Down Expand Up @@ -121,6 +121,13 @@ CLI behavior lives in `references/`. Repeatable patterns live in `workflows/`. L
| View or cancel Predict orders and positions | [predict-manage-orders.md](workflows/predict-manage-orders.md) |
| View Predict portfolio and redeem winnings | [predict-portfolio.md](workflows/predict-portfolio.md) |
| Token discovery, prices, and market data | [market-data.md](workflows/market-data.md) |
| Supply assets to Aave V3 | [aave-supply.md](workflows/aave-supply.md) |
| Withdraw assets from Aave V3 | [aave-withdraw.md](workflows/aave-withdraw.md) |
| Borrow from Aave V3 | [aave-borrow.md](workflows/aave-borrow.md) |
| Repay Aave V3 debt | [aave-repay.md](workflows/aave-repay.md) |
| Toggle Aave V3 collateral | [aave-collateral.md](workflows/aave-collateral.md) |
| Check Aave V3 positions and health factor | [aave-positions.md](workflows/aave-positions.md) |
| Discover Aave V3 tokens, rates, and liquidity | [aave-markets.md](workflows/aave-markets.md) |

## Global Flags

Expand Down
3 changes: 2 additions & 1 deletion skills/metamask-agent-wallet/references/signing.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ mm wallet sign-typed-data --chain-id <id> --payload '<JSON>' [--wait] [--passwor
| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137) |
| `--payload` | Yes | EIP-712 typed data as a JSON string with `domain`, `types`, `primaryType`, and `message` |
| `--wait` | No | Block until the signature request completes (server-wallet mode only; BYOK returns immediately) |
| `--intent` | No | Human-readable summary of what is being signed, forwarded with the request |
| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] |

### Example

```bash
mm wallet sign-typed-data --chain-id 1 --payload '{"types":...,"primaryType":...,"domain":...,"message":...}'
mm wallet sign-typed-data --chain-id 137 --payload '{"types":...}' --wait
mm wallet sign-typed-data --chain-id 137 --payload '{"types":...}' --wait --intent "Approve 10 USDC"
```

## EIP-712 Typed Data
Expand Down
3 changes: 2 additions & 1 deletion skills/metamask-agent-wallet/references/transaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ mm wallet send-transaction --chain-id <id> --payload '<JSON>' [--wait] [--passwo
| `--chain-id` | Yes | EVM chain ID as a positive integer (e.g. 1, 137) |
| `--payload` | Yes | Transaction as a JSON string with at least a `to` address (e.g. `'{"to":"0x...","value":"0x0"}'}`) |
| `--wait` | No | Block until the transaction completes (server-wallet mode only; BYOK returns immediately) |
| `--intent` | No | Human-readable summary of what the transaction does, forwarded with the request |
| `--password` | No | Password to unlock the BYOK mnemonic (BYOK mode only) [env: `MM_PASSWORD`] |

### Example

```bash
mm wallet send-transaction --chain-id 1 --payload '{"to":"0x742d...","value":"0xde0b6b3a7640000","data":"0x"}'
mm wallet send-transaction --chain-id 1 --payload '{"to":"0x742d...","value":"0xde0b6b3a7640000","data":"0x"}' --intent "Send 1 ETH to 0x742d...f2bD18"
mm wallet send-transaction --chain-id 1 --payload '{"to":"0x...","value":"0x0","data":"0xabcdef"}' --wait
mm wallet send-transaction --chain-id 1 --payload '...' --toon
```
Expand Down
23 changes: 23 additions & 0 deletions skills/metamask-agent-wallet/scripts/amount_to_hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env python3
"""Convert a human-readable token amount to 0x-prefixed hex for EVM calldata.

Usage:
python3 amount_to_hex.py <amount> <decimals>

Examples:
python3 amount_to_hex.py 1.5 18 # 1.5 ETH -> 0x14d1120d7b160000
python3 amount_to_hex.py 100 6 # 100 USDC -> 0x5f5e100
python3 amount_to_hex.py 0.001 8 # 0.001 WBTC -> 0x186a0
"""

import sys
from decimal import Decimal

if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <amount> <decimals>", file=sys.stderr)
sys.exit(1)

decimals = int(sys.argv[2])
value = int(Decimal(sys.argv[1]) * 10 ** decimals)

print(hex(value))
81 changes: 81 additions & 0 deletions skills/metamask-agent-wallet/workflows/aave-borrow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Aave V3 borrow workflow

Use this workflow to borrow assets from Aave V3 against supplied collateral.

## Flow

1. Resolve chain, asset address, and pool address.
2. Check collateral and borrow capacity.
3. Preview health factor impact.
4. Query the Aave API for the borrow transaction and execute.

## Resolve chain and addresses

If the user doesn't specify a chain, ask. Look up the pool address:

| Chain | Chain ID | Pool address |
| --- | --- | --- |
| Ethereum | 1 | `0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2` |
| Polygon | 137 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Arbitrum | 42161 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Optimism | 10 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Avalanche | 43114 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Base | 8453 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |

## Check collateral

Before borrowing, check the user's positions using `aave-positions.md`. Verify the following.

1. The user has supplied collateral. If not, follow `aave-supply.md` to supply assets first.
2. Collateral is enabled on at least one supplied asset (`isCollateral` is `true`). If not, follow `aave-collateral.md` to enable it.
3. Available borrow capacity covers the requested amount.

Query available markets to check the target asset's borrow APY and whether `borrowCapReached` is `true`. See `aave-markets.md`.

## Preview health factor

Preview the health factor impact before borrowing:

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ healthFactorPreview(request: { action: { borrow: { market: \"<POOL_ADDRESS>\", sender: \"<WALLET_ADDRESS>\", chainId: <CHAIN_ID>, amount: { erc20: { currency: \"<ASSET_ADDRESS>\", value: \"<AMOUNT>\" } } } } }) { before after } }"
}'
```

Show the health factor before and after. If the projected health factor (`after`) drops below 1.5, warn about liquidation risk. If it drops below 1.0, stop and tell the user to reduce the borrow amount or repay existing debt.

## Query borrow transaction

Get the wallet address and query the Aave V3 GraphQL API. Don't include `onBehalfOf` when borrowing for the user's own account. It triggers a credit delegation requirement even for self-borrows.

```bash
mm wallet address
```

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ borrow(request: { market: \"<POOL_ADDRESS>\", amount: { erc20: { currency: \"<ASSET_ADDRESS>\", value: \"<AMOUNT>\" } }, sender: \"<WALLET_ADDRESS>\", chainId: <CHAIN_ID> }) { __typename ... on TransactionRequest { to from data value chainId } ... on ApprovalRequired { approval { to from data value chainId } originalTransaction { to from data value chainId } } ... on InsufficientBalanceError { required { value decimals } available { value decimals } } } }"
}'
```

The `value` in the amount is a human-readable decimal string (e.g., `"2"`, `"100"`). The API handles conversion.

## Execute borrow

Confirm the asset, amount, chain, and projected health factor with the user. The `value` field must be `0x`-prefixed hex (typically `"0x0"` for ERC-20 borrows).

```bash
mm wallet send-transaction --chain-id <CHAIN_ID> --payload '{"to":"<TO>","value":"0x0","data":"<DATA>"}' --wait --intent "Borrow <AMOUNT> <SYMBOL> from Aave V3 on <CHAIN_NAME>"
```

If the response is `InsufficientBalanceError`, show the required and available amounts and stop.

## Notes

- After the transaction confirms, use `aave-positions.md` to verify the updated position and health factor.
- The borrowed amount accrues interest over time. Check debt at any time using `aave-positions.md`.
- To repay the borrow, see `aave-repay.md`.
64 changes: 64 additions & 0 deletions skills/metamask-agent-wallet/workflows/aave-collateral.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Aave V3 collateral workflow

Use this workflow to enable or disable an asset as collateral on Aave V3.

## Flow

1. Resolve chain, asset address, and pool address.
2. Check current collateral status and health factor.
3. Query the Aave API for the collateral toggle transaction.
4. Execute toggle.

## Resolve chain and addresses

If the user doesn't specify a chain, ask. Look up the pool address:

| Chain | Chain ID | Pool address |
| --- | --- | --- |
| Ethereum | 1 | `0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2` |
| Polygon | 137 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Arbitrum | 42161 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Optimism | 10 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Avalanche | 43114 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Base | 8453 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |

## Check status

Query the user's positions using `aave-positions.md`. For the target asset, check whether collateral is enabled or disabled (`isCollateral`).

The user must have a non-zero supply of the asset to toggle collateral.

When disabling collateral, check the health factor. If the user has outstanding borrows, disabling collateral lowers the health factor. Show the impact. If the health factor would drop below 1.0, stop and tell the user to repay debt first via `aave-repay.md`.

## Query collateral toggle transaction

Get the wallet address and query the Aave V3 GraphQL API:

```bash
mm wallet address
```

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ collateralToggle(request: { market: \"<POOL_ADDRESS>\", underlyingToken: \"<ASSET_ADDRESS>\", user: \"<WALLET_ADDRESS>\", chainId: <CHAIN_ID> }) { to from data value chainId } }"
}'
```

The API returns a `TransactionRequest` with `{to, from, data, value, chainId}`. The toggle direction is determined automatically based on the current collateral state.

## Execute toggle

Confirm the asset, toggle direction (enabling or disabling), and chain with the user. The `value` field must be `0x`-prefixed hex.

```bash
mm wallet send-transaction --chain-id <CHAIN_ID> --payload '{"to":"<TO>","value":"0x0","data":"<DATA>"}' --wait --intent "Toggle <SYMBOL> as collateral on Aave V3 on <CHAIN_NAME>"
```

## Notes

- Enabling collateral lets the asset back borrows, increasing borrow capacity.
- Disabling collateral removes it from the borrow calculation. This may trigger liquidation if remaining collateral can't cover existing debt.
- Not all assets support collateral usage. If the transaction reverts, the reserve may not be eligible.
- After the transaction confirms, verify the updated status using `aave-positions.md`.
46 changes: 46 additions & 0 deletions skills/metamask-agent-wallet/workflows/aave-markets.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Aave V3 markets workflow

Use this workflow to discover available Aave V3 tokens, supply/borrow rates, and borrowing capacity on a chain.

## Flow

1. Resolve chain.
2. Query available markets.
3. Present results.

## Resolve chain

If the user doesn't specify a chain, ask. Aave V3 is deployed on these chains:

| Chain | Chain ID |
| --- | --- |
| Ethereum | 1 |
| Polygon | 137 |
| Arbitrum | 42161 |
| Optimism | 10 |
| Avalanche | 43114 |
| Base | 8453 |

## Query available markets

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ markets(request: { chainIds: [<CHAIN_ID>] }) { reserves { underlyingToken { symbol decimals } supplyInfo { apy { formatted } } borrowInfo { apy { formatted } availableLiquidity { amount { value } usd } borrowCapReached } isFrozen isPaused } } }"
}'
```

## Present results

Filter out reserves where `isFrozen` or `isPaused` is `true`. For each active reserve, show:

- Token symbol and decimals (`underlyingToken.symbol`, `underlyingToken.decimals`)
- Supply APY (`supplyInfo.apy.formatted`)
- Borrow APY (`borrowInfo.apy.formatted`)
- Available liquidity (`borrowInfo.availableLiquidity.amount.value`, `borrowInfo.availableLiquidity.usd`)
- Borrow cap reached (`borrowInfo.borrowCapReached`)

The `apy.formatted` field returns a percentage directly (e.g., `"2.12"` means 2.12%). No conversion is needed.

If `borrowCapReached` is `true`, tell the user that borrowing isn't available for that asset.
72 changes: 72 additions & 0 deletions skills/metamask-agent-wallet/workflows/aave-positions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Aave V3 positions workflow

Use this workflow to check Aave V3 positions, health factor, interest rates, or reserve data.

## Flow

1. Get wallet address and chain.
2. Query supply and borrow positions via GraphQL.
3. Present summary.

## Resolve chain

Get the wallet address:

```bash
mm wallet address
```

If the user doesn't specify a chain, ask. Aave V3 is deployed on these chains:

| Chain | Chain ID | Pool address |
| --- | --- | --- |
| Ethereum | 1 | `0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2` |
| Polygon | 137 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Arbitrum | 42161 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Optimism | 10 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Avalanche | 43114 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |
| Base | 8453 | `0x794a61358D6845594F94dc1DB02A252b5b4814aD` |

## Query positions

Query supply and borrow positions in a single request:

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ userSupplies(request: { markets: [{ address: \"<POOL_ADDRESS>\", chainId: <CHAIN_ID> }], user: \"<WALLET_ADDRESS>\" }) { currency { symbol decimals } balance { amount { value } usd } apy { formatted } isCollateral } userBorrows(request: { markets: [{ address: \"<POOL_ADDRESS>\", chainId: <CHAIN_ID> }], user: \"<WALLET_ADDRESS>\" }) { currency { symbol decimals } debt { amount { value } usd } apy { formatted } } }"
}'
```

The response contains both `userSupplies` and `userBorrows` arrays.

## Health factor preview

Preview the health factor impact of a planned operation:

```bash
curl -s -X POST https://api.v3.aave.com/graphql \
-H 'Content-Type: application/json' \
-d '{
"query": "{ healthFactorPreview(request: { action: { <OPERATION>: { market: \"<POOL_ADDRESS>\", sender: \"<WALLET_ADDRESS>\", chainId: <CHAIN_ID>, amount: { erc20: { currency: \"<ASSET_ADDRESS>\", value: \"<AMOUNT>\" } } } } }) { before after } }"
}'
```

Replace `<OPERATION>` with `supply`, `borrow`, `withdraw`, or `repay`. All action types require `market`, `sender`, and `chainId`.

## Present summary

Format the data into three sections:

Supplied assets:
- Symbol, balance (`balance.amount.value`), USD value (`balance.usd`), supply APY (`apy.formatted`), used as collateral (`isCollateral`)

Borrowed assets:
- Symbol, debt amount (`debt.amount.value`), USD value (`debt.usd`), borrow APY (`apy.formatted`)

Account summary:
- Total collateral value, total debt value, available borrows, health factor
- Health factor guidance: above 2.0 is safe, 1.5–2.0 is moderate, 1.0–1.5 is risky and approaching liquidation, below 1.0 is liquidatable

The `apy.formatted` field returns a percentage directly (e.g., `"2.12"` means 2.12%). No conversion is needed.
Loading
Loading