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
56 changes: 19 additions & 37 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, 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.'
description: 'Interact with CoinFello using the @coinfello/agent-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,30 +11,30 @@ metadata:

# CoinFello CLI Skill

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.
Use the `npx @coinfello/agent-cli` 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

- Node.js 20 or later
- pnpm package manager
- Build the CLI before first use: `pnpm build`

The CLI binary is available at `./dist/index.js` after building, or as `openclaw` if installed globally.
The CLI is available via `npx @coinfello/agent-cli`.

## Quick Start

```bash
# 1. Create a smart account on a chain (generates a new private key automatically)
openclaw create_account sepolia
npx @coinfello/agent-cli create_account sepolia

# 2. Sign in to CoinFello with your smart account (SIWE)
openclaw sign_in
npx @coinfello/agent-cli sign_in

# 3. Send a natural language prompt — the server will request a delegation if needed
openclaw send_prompt "send 5 USDC to 0xRecipient..."
npx @coinfello/agent-cli send_prompt "send 5 USDC to 0xRecipient..."

# 4. Check transaction status
openclaw get_transaction_status <txn_id>
npx @coinfello/agent-cli get_transaction_status <txn_id>
```

## Commands
Expand All @@ -44,7 +44,7 @@ openclaw get_transaction_status <txn_id>
Creates a MetaMask Hybrid smart account with an auto-generated private key and saves it to local config.

```bash
openclaw create_account <chain>
npx @coinfello/agent-cli create_account <chain>
```

- `<chain>` — A viem chain name: `sepolia`, `mainnet`, `polygon`, `arbitrum`, `optimism`, `base`, etc.
Expand All @@ -57,7 +57,7 @@ openclaw create_account <chain>
Displays the current smart account address from local config.

```bash
openclaw get_account
npx @coinfello/agent-cli get_account
```

- Prints the stored `smart_account_address`
Expand All @@ -68,7 +68,7 @@ openclaw get_account
Authenticates with CoinFello using Sign-In with Ethereum (SIWE) and your smart account. Saves the session token to local config.

```bash
openclaw sign_in
npx @coinfello/agent-cli sign_in
```

- Signs in using the private key stored in config
Expand All @@ -78,27 +78,22 @@ openclaw sign_in

### set_delegation

Stores a signed parent delegation (JSON) in local config for use with redelegation flows.
Stores a signed parent delegation (JSON) in local config.

```bash
openclaw set_delegation '<delegation-json>'
npx @coinfello/agent-cli set_delegation '<delegation-json>'
```

- `<delegation-json>` — A JSON string representing a `Delegation` object from MetaMask Smart Accounts Kit
- Only needed if you plan to use `--use-redelegation` with `send_prompt`

### send_prompt

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>" [--use-redelegation]
npx @coinfello/agent-cli send_prompt "<prompt>"
```

**Optional:**

- `--use-redelegation` — Create a redelegation from a stored parent delegation instead of a fresh subdelegation (requires `set_delegation` first)

**What happens internally:**

1. Fetches available agents from `/api/v1/automation/coinfello-agents` and sends the prompt to CoinFello's conversation endpoint
Expand All @@ -117,7 +112,7 @@ openclaw send_prompt "<prompt>" [--use-redelegation]
Checks the status of a previously submitted transaction.

```bash
openclaw get_transaction_status <txn_id>
npx @coinfello/agent-cli get_transaction_status <txn_id>
```

- Returns a JSON object with the current transaction status
Expand All @@ -128,44 +123,31 @@ openclaw get_transaction_status <txn_id>

```bash
# Create account if not already done
openclaw create_account sepolia
npx @coinfello/agent-cli create_account sepolia

# Sign in (required for delegation flows)
openclaw sign_in
npx @coinfello/agent-cli sign_in

# Send a natural language prompt — delegation is handled automatically
openclaw send_prompt "send 5 USDC to 0xRecipient..."
npx @coinfello/agent-cli send_prompt "send 5 USDC to 0xRecipient..."

# Check the result
openclaw get_transaction_status <txn_id-from-above>
npx @coinfello/agent-cli 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.

```bash
# Store the parent delegation
openclaw set_delegation '{"delegate":"0x...","delegator":"0x...","authority":"0x...","caveats":[],"salt":"0x...","signature":"0x..."}'

# Send with redelegation
openclaw send_prompt "swap tokens" --use-redelegation
npx @coinfello/agent-cli send_prompt "what is the chain ID for Base?"
```

## 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
Expand Down
50 changes: 24 additions & 26 deletions coinfello/references/REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ Created automatically by `create_account`. Schema:
| `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 |
| `delegation` | `object` | `set_delegation` | Optional stored delegation |

## Command Reference

### openclaw create_account
### npx @coinfello/agent-cli create_account

```
openclaw create_account <chain>
npx @coinfello/agent-cli create_account <chain>
```

| Parameter | Type | Required | Description |
Expand All @@ -45,18 +45,18 @@ openclaw create_account <chain>

Generates a new private key automatically and saves it along with the smart account address and chain to config.

### openclaw get_account
### npx @coinfello/agent-cli get_account

```
openclaw get_account
npx @coinfello/agent-cli 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
### npx @coinfello/agent-cli sign_in

```
openclaw sign_in [--base-url <url>]
npx @coinfello/agent-cli sign_in [--base-url <url>]
```

| Parameter | Type | Required | Default | Description |
Expand All @@ -67,35 +67,34 @@ The default resolves using the `COINFELLO_BASE_URL` environment variable (defaul

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
### npx @coinfello/agent-cli set_delegation

```
openclaw set_delegation <delegation>
npx @coinfello/agent-cli set_delegation <delegation>
```

| Parameter | Type | Required | Description |
| ------------ | -------- | -------- | --------------------------------------------------------------- |
| `delegation` | `string` | Yes | JSON-encoded Delegation object from MetaMask Smart Accounts Kit |

### openclaw send_prompt
### npx @coinfello/agent-cli send_prompt

```
openclaw send_prompt <prompt> [--use-redelegation]
npx @coinfello/agent-cli send_prompt <prompt>
```

| 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 |
| Parameter | Type | Required | Default | Description |
| --------- | -------- | -------- | ------- | -------------------------------------------- |
| `prompt` | `string` | Yes | — | Natural language prompt to send to CoinFello |

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` client tool call response.
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` client tool call response. Each subdelegation is created with a unique random salt to ensure delegation uniqueness.

**ERC-6492 signature wrapping**: If the smart account has not yet been deployed on-chain, the CLI wraps the delegation signature using ERC-6492 (`serializeErc6492Signature`) with the account's factory address and factory data. This allows the delegation to be verified even before the account contract exists.

### openclaw get_transaction_status
### npx @coinfello/agent-cli get_transaction_status

```
openclaw get_transaction_status <txn_id>
npx @coinfello/agent-cli get_transaction_status <txn_id>
```

| Parameter | Type | Required | Description |
Expand Down Expand Up @@ -223,11 +222,10 @@ All `amount` fields are in the token's smallest unit (e.g. `5000000` for 5 USDC

## 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>'` |
| `No delegation request received from the server.` | Server returned unexpected response | Check the full response JSON printed |
| 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 `npx @coinfello/agent-cli create_account <chain>` |
| `No smart account found. Run 'create_account' first.` | Missing smart account in config | Run `npx @coinfello/agent-cli create_account <chain>` |
| `No chain found in config. Run 'create_account' first.` | Missing chain in config | Run `npx @coinfello/agent-cli create_account <chain>` |
| `No delegation request received from the server.` | Server returned unexpected response | Check the full response JSON printed |
8 changes: 4 additions & 4 deletions coinfello/scripts/setup-and-send.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ CHAIN="${1:?Usage: $0 <chain> <prompt>}"
PROMPT="${2:?Missing prompt}"

echo "==> Creating smart account on ${CHAIN}..."
openclaw create_account "$CHAIN"
npx @coinfello/agent-cli create_account "$CHAIN"

echo ""
echo "==> Signing in..."
openclaw sign_in
npx @coinfello/agent-cli sign_in

echo ""
echo "==> Sending prompt..."
OUTPUT=$(openclaw send_prompt "$PROMPT")
OUTPUT=$(npx @coinfello/agent-cli send_prompt "$PROMPT")

echo "$OUTPUT"

Expand All @@ -31,5 +31,5 @@ TXN_ID=$(echo "$OUTPUT" | grep -oP 'Transaction ID: \K.*')
if [ -n "$TXN_ID" ]; then
echo ""
echo "==> Checking transaction status..."
openclaw get_transaction_status "$TXN_ID"
npx @coinfello/agent-cli get_transaction_status "$TXN_ID"
fi
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@coinfello/agent-cli",
"version": "0.1.0",
"version": "0.1.1",
"description": "",
"type": "module",
"main": "dist/index.js",
Expand Down
2 changes: 2 additions & 0 deletions src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { PrivateKeyAccount, privateKeyToAccount } from 'viem/accounts'
import { createPublicClient, http, type Hex, type Chain } from 'viem'
import * as chains from 'viem/chains'
import { randomBytes } from 'node:crypto'

export type HybridSmartAccount = ToMetaMaskSmartAccountReturnType<Implementation.Hybrid>
export type DelegationScope = CreateDelegationOptions['scope']
Expand Down Expand Up @@ -90,5 +91,6 @@ export function createSubdelegation({
from: smartAccount.address,
parentDelegation,
environment: smartAccount.environment,
salt: `0x${randomBytes(32).toString('hex')}` as Hex,
})
}
Loading