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
26 changes: 26 additions & 0 deletions .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: E2E Tests

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- name: Install dependencies
run: pnpm install

- name: Run e2e tests
run: pnpm test:e2e
91 changes: 53 additions & 38 deletions coinfello/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: coinfello
description: 'Interact with CoinFello using the openclaw CLI to create MetaMask smart accounts, manage delegations, send prompts with ERC-20 token subdelegations, and check transaction status. Use when the user wants to send crypto transactions via natural language prompts, manage smart account delegations, or check CoinFello transaction results.'
description: 'Interact with CoinFello using the openclaw CLI to create MetaMask smart accounts, sign in with SIWE, manage delegations, send prompts with server-driven ERC-20 token subdelegations, and check transaction status. Use when the user wants to send crypto transactions via natural language prompts, manage smart account delegations, or check CoinFello transaction results.'
compatibility: Requires Node.js 20+ and pnpm.
metadata:
{
Expand All @@ -11,7 +11,7 @@ metadata:

# CoinFello CLI Skill

Use the `openclaw` CLI to interact with CoinFello through MetaMask Smart Accounts. The CLI handles smart account creation, delegation management, prompt-based ERC-20 token transactions, and transaction status checks.
Use the `openclaw` CLI to interact with CoinFello through MetaMask Smart Accounts. The CLI handles smart account creation, SIWE authentication, delegation management, prompt-based transactions, and transaction status checks.

## Prerequisites

Expand All @@ -27,13 +27,13 @@ The CLI binary is available at `./dist/index.js` after building, or as `openclaw
# 1. Create a smart account on a chain (generates a new private key automatically)
openclaw create_account sepolia

# 2. Send a prompt with token subdelegation
openclaw send_prompt "swap 5 USDC for ETH" \
--token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
--amount 5 \
--decimals 6
# 2. Sign in to CoinFello with your smart account (SIWE)
openclaw sign_in

# 3. Check transaction status
# 3. Send a natural language prompt — the server will request a delegation if needed
openclaw send_prompt "send 5 USDC to 0xRecipient..."

# 4. Check transaction status
openclaw get_transaction_status <txn_id>
```

Expand Down Expand Up @@ -63,6 +63,20 @@ openclaw get_account
- Prints the stored `smart_account_address`
- Exits with an error if no account has been created yet

### sign_in

Authenticates with CoinFello using Sign-In with Ethereum (SIWE) and your smart account. Saves the session token to local config.

```bash
openclaw sign_in [--base-url <url>]
```

- `--base-url <url>` — Auth server base URL (default: `https://app.coinfello.com/api/auth`)
- Signs in using the private key stored in config
- Saves the session token to `~/.clawdbot/skills/coinfello/config.json`
- The session token is loaded automatically for subsequent `send_prompt` calls
- Must be run after `create_account` and before `send_prompt` for authenticated flows

### set_delegation

Stores a signed parent delegation (JSON) in local config for use with redelegation flows.
Expand All @@ -76,34 +90,28 @@ openclaw set_delegation '<delegation-json>'

### send_prompt

Sends a natural language prompt to CoinFello with a locally-created and signed ERC-20 token subdelegation.
Sends a natural language prompt to CoinFello. If the server requires a delegation to execute the action, the CLI creates and signs a subdelegation automatically based on the server's requested scope and chain.

```bash
openclaw send_prompt "<prompt>" \
--token-address <erc20-address> \
--amount <amount> \
[--decimals <n>] \
[--use-redelegation]
openclaw send_prompt "<prompt>" [--use-redelegation]
```

**Required options:**

- `--token-address <address>` — ERC-20 token contract address for the subdelegation scope
- `--amount <amount>` — Maximum token amount in human-readable form (e.g. `5`, `100.5`)

**Optional:**

- `--decimals <n>` — Token decimals for parsing `--amount` (default: `18`)
- `--use-redelegation` — Create a redelegation from a stored parent delegation (requires `set_delegation` first)
- `--use-redelegation` — Create a redelegation from a stored parent delegation instead of a fresh subdelegation (requires `set_delegation` first)

**What happens internally:**

1. Fetches CoinFello's delegate address from the API
2. Rebuilds the smart account from the stored private key and chain in config
3. Creates a subdelegation scoped to `erc20TransferAmount` with the specified token and max amount
4. Signs the subdelegation with the smart account
5. Sends the prompt + signed subdelegation to CoinFello's conversation endpoint
6. Returns a `txn_id` for tracking
1. Sends the prompt to CoinFello's conversation endpoint
2. If the server returns a read-only response (no transaction needed) → prints the response text and exits
3. If the server returns a `txn_id` directly → prints it and exits
4. If the server sends an `ask_for_delegation` tool call with a `chainId` and `scope`:
- Fetches CoinFello's delegate address
- Rebuilds the smart account using the chain ID from the tool call
- Parses the server-provided scope (supports ERC-20, native token, ERC-721, and function call scopes)
- Creates and signs a subdelegation
- Sends the signed delegation back to the conversation endpoint
- Returns a `txn_id` for tracking

### get_transaction_status

Expand All @@ -117,22 +125,30 @@ openclaw get_transaction_status <txn_id>

## Common Workflows

### Basic: Send a Token Transfer Prompt
### Basic: Send a Prompt (Server-Driven Delegation)

```bash
# Create account if not already done
openclaw create_account sepolia

# Send prompt to transfer up to 10 USDC
openclaw send_prompt "send 5 USDC to 0xRecipient..." \
--token-address 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
--amount 10 \
--decimals 6
# Sign in (required for delegation flows)
openclaw sign_in

# Send a natural language prompt — delegation is handled automatically
openclaw send_prompt "send 5 USDC to 0xRecipient..."

# Check the result
openclaw get_transaction_status <txn_id-from-above>
```

### Read-Only Prompt

Some prompts don't require a transaction. The CLI detects this automatically and just prints the response.

```bash
openclaw send_prompt "what is the chain ID for Base?"
```

### With Redelegation

Use this when you have a parent delegation from another delegator and want to create a subdelegation chain.
Expand All @@ -142,20 +158,19 @@ Use this when you have a parent delegation from another delegator and want to cr
openclaw set_delegation '{"delegate":"0x...","delegator":"0x...","authority":"0x...","caveats":[],"salt":"0x...","signature":"0x..."}'

# Send with redelegation
openclaw send_prompt "swap tokens" \
--token-address 0xTokenAddress \
--amount 100 \
--use-redelegation
openclaw send_prompt "swap tokens" --use-redelegation
```

## Edge Cases

- **No smart account**: Run `create_account` before `send_prompt`. The CLI checks for a saved private key and address in config.
- **Not signed in**: Run `sign_in` before `send_prompt` if the server requires authentication.
- **Invalid chain name**: The CLI throws an error listing valid viem chain names.
- **Missing parent delegation with --use-redelegation**: The CLI exits with an error. Run `set_delegation` first.
- **Read-only response**: If the server returns a text response with no transaction, the CLI prints it and exits without creating a delegation.

## Reference

See [references/REFERENCE.md](references/REFERENCE.md) for the full config schema, supported chains, API details, and troubleshooting.
See [references/REFERENCE.md](references/REFERENCE.md) for the full config schema, supported chains, API details, scope types, and troubleshooting.

See [scripts/setup-and-send.sh](scripts/setup-and-send.sh) for an end-to-end automation script.
152 changes: 114 additions & 38 deletions coinfello/references/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Created automatically by `create_account`. Schema:
"private_key": "0xabc123...def",
"smart_account_address": "0x1234...abcd",
"chain": "sepolia",
"session_token": "...",
"delegation": {
"delegate": "0x...",
"delegator": "0x...",
Expand All @@ -22,12 +23,13 @@ Created automatically by `create_account`. Schema:
}
```

| Field | Type | Set by | Description |
| ----------------------- | -------- | ---------------- | ------------------------------------------- |
| `private_key` | `string` | `create_account` | Auto-generated hex private key |
| `smart_account_address` | `string` | `create_account` | Counterfactual address of the smart account |
| `chain` | `string` | `create_account` | viem chain name used for account creation |
| `delegation` | `object` | `set_delegation` | Optional parent delegation for redelegation |
| Field | Type | Set by | Description |
| ----------------------- | -------- | ---------------- | ---------------------------------------------- |
| `private_key` | `string` | `create_account` | Auto-generated hex private key |
| `smart_account_address` | `string` | `create_account` | Counterfactual address of the smart account |
| `chain` | `string` | `create_account` | viem chain name used for account creation |
| `session_token` | `string` | `sign_in` | SIWE session token for authenticated API calls |
| `delegation` | `object` | `set_delegation` | Optional parent delegation for redelegation |

## Command Reference

Expand All @@ -51,6 +53,18 @@ openclaw get_account

No parameters. Prints the stored smart account address from config. Exits with an error if no account has been created.

### openclaw sign_in

```
openclaw sign_in [--base-url <url>]
```

| Parameter | Type | Required | Default | Description |
| ------------ | -------- | -------- | ------------------------------------ | -------------------- |
| `--base-url` | `string` | No | `https://app.coinfello.com/api/auth` | Auth server base URL |

Performs a Sign-In with Ethereum (SIWE) flow using the private key from config. Saves the `session_token` to config on success. The session token is automatically injected as a cookie for subsequent API calls.

### openclaw set_delegation

```
Expand All @@ -64,18 +78,15 @@ openclaw set_delegation <delegation>
### openclaw send_prompt

```
openclaw send_prompt <prompt> --token-address <addr> --amount <amt> [--decimals <n>] [--use-redelegation]
openclaw send_prompt <prompt> [--use-redelegation]
```

| Parameter | Type | Required | Default | Description |
| -------------------- | --------- | -------- | ------- | --------------------------------------------- |
| `prompt` | `string` | Yes | — | Natural language prompt to send to CoinFello |
| `--token-address` | `string` | Yes | — | ERC-20 token contract address |
| `--amount` | `string` | Yes | — | Max token amount (human-readable, e.g. `"5"`) |
| `--decimals` | `string` | No | `"18"` | Token decimals for parsing amount |
| `--use-redelegation` | `boolean` | No | `false` | Use stored parent delegation for redelegation |
| Parameter | Type | Required | Default | Description |
| -------------------- | --------- | -------- | ------- | ----------------------------------------------------------- |
| `prompt` | `string` | Yes | — | Natural language prompt to send to CoinFello |
| `--use-redelegation` | `boolean` | No | `false` | Use stored parent delegation to create a redelegation chain |

Uses the private key and chain stored in config (from `create_account`).
The server determines whether a delegation is needed and, if so, what scope and chain to use. The client creates and signs the subdelegation based on the server's `ask_for_delegation` tool call response.

### openclaw get_transaction_status

Expand Down Expand Up @@ -104,39 +115,104 @@ Any chain exported by `viem/chains`. Common examples:

## API Endpoints

Base URL: `https://app.coinfello.com/api/v1`
Base URL: `https://app.coinfello.com`

| Endpoint | Method | Description |
| ---------------------------------------- | ------ | ------------------------------------------------- |
| `/api/v1/automation/coinfello-address` | GET | Returns CoinFello's delegate address |
| `/api/v1/automation/coinfello-agents` | GET | Returns available CoinFello agents |
| `/api/conversation` | POST | Submits prompt (and optionally signed delegation) |
| `/api/v1/transaction_status?txn_id=<id>` | GET | Returns transaction status |

### POST /api/conversation body

Initial request (prompt only):

```json
{
"inputMessage": "send 5 USDC to 0xRecipient...",
"agentId": 1,
"stream": false
}
```

Follow-up request (with signed delegation):

```json
{
"inputMessage": "send 5 USDC to 0xRecipient...",
"agentId": 1,
"stream": false,
"signed_subdelegation": { "...delegation object with signature..." }
}
```

### POST /api/conversation response

Read-only response:

```json
{
"responseText": "The chain ID for Base is 8453."
}
```

Delegation request (server asks client to sign):

| Endpoint | Method | Description |
| --------------------------------- | ------ | ------------------------------------- |
| `/coinfello-address` | GET | Returns CoinFello's delegate address |
| `/conversation` | POST | Submits prompt + signed subdelegation |
| `/transaction_status?txn_id=<id>` | GET | Returns transaction status |
```json
{
"toolCalls": [
{
"type": "function_call",
"name": "ask_for_delegation",
"callId": "...",
"arguments": "{\"chainId\": 8453, \"scope\": {\"type\": \"erc20TransferAmount\", \"tokenAddress\": \"0x...\", \"maxAmount\": \"5000000\"}}"
}
]
}
```

### POST /conversation body
Final response (after delegation submitted):

```json
{
"prompt": "swap 5 USDC for ETH",
"signed_subdelegation": { "...delegation object with signature..." },
"smart_account_address": "0x..."
"txn_id": "abc123..."
}
```

## Delegation Scope Types

The server may request any of the following scope types via `ask_for_delegation`. The CLI parses and creates the appropriate delegation caveat automatically.

| Scope Type | Fields |
| --------------------------- | ---------------------------------------------------------------------------- |
| `erc20TransferAmount` | `tokenAddress`, `maxAmount` |
| `erc20PeriodTransfer` | `tokenAddress`, `periodAmount`, `periodDuration`, `startDate` |
| `erc20Streaming` | `tokenAddress`, `initialAmount`, `maxAmount`, `amountPerSecond`, `startTime` |
| `nativeTokenTransferAmount` | `maxAmount` |
| `nativeTokenPeriodTransfer` | `periodAmount`, `periodDuration`, `startDate` |
| `nativeTokenStreaming` | `initialAmount`, `maxAmount`, `amountPerSecond`, `startTime` |
| `erc721Transfer` | `tokenAddress`, `tokenId` |
| `functionCall` | `targets`, `selectors` |

All `amount` fields are in the token's smallest unit (e.g. `5000000` for 5 USDC with 6 decimals).

## Common Token Decimals

| Token | Decimals | Note |
| ----- | -------- | ------------------------------- |
| USDC | 6 | Use `--decimals 6` |
| USDT | 6 | Use `--decimals 6` |
| DAI | 18 | Default, no `--decimals` needed |
| WETH | 18 | Default, no `--decimals` needed |
| Token | Decimals | Note |
| ----- | -------- | ----------------------------- |
| USDC | 6 | amounts use 6 decimal places |
| USDT | 6 | amounts use 6 decimal places |
| DAI | 18 | amounts use 18 decimal places |
| WETH | 18 | amounts use 18 decimal places |

## Error Messages

| Error | Cause | Fix |
| ------------------------------------------------------------------------------ | ------------------------------- | -------------------------------------- |
| `Unknown chain "<name>"` | Invalid chain name | Use a valid viem chain name |
| `No private key found in config. Run 'create_account' first.` | Missing private key in config | Run `openclaw create_account <chain>` |
| `No smart account found. Run 'create_account' first.` | Missing smart account in config | Run `openclaw create_account <chain>` |
| `No chain found in config. Run 'create_account' first.` | Missing chain in config | Run `openclaw create_account <chain>` |
| `--use-redelegation requires a parent delegation. Run 'set_delegation' first.` | No stored delegation | Run `openclaw set_delegation '<json>'` |
| Error | Cause | Fix |
| ------------------------------------------------------------------------------ | ----------------------------------- | -------------------------------------- |
| `Unknown chain "<name>"` | Invalid chain name | Use a valid viem chain name |
| `No private key found in config. Run 'create_account' first.` | Missing private key in config | Run `openclaw create_account <chain>` |
| `No smart account found. Run 'create_account' first.` | Missing smart account in config | Run `openclaw create_account <chain>` |
| `No chain found in config. Run 'create_account' first.` | Missing chain in config | Run `openclaw create_account <chain>` |
| `--use-redelegation requires a parent delegation. Run 'set_delegation' first.` | No stored delegation | Run `openclaw set_delegation '<json>'` |
| `No delegation request received from the server.` | Server returned unexpected response | Check the full response JSON printed |
Loading