aoconnect
AOConnect Skill
A command-line interface for interacting with AO processes using the @permaweb/aoconnect library.
Phrase Mappings
| User Request | Command |
|---|---|
| "use aoconnect to spawn" | spawn |
| "use aoconnect to message" | message |
| "use aoconnect to read result" | result |
| "use aoconnect to dryrun" | dryrun |
| "use aoconnect to monitor" | monitor |
| "use aoconnect to connect" | connect |
Installation
Install the aoconnect skill and its dependency:
npx skills add https://github.com/permaweb/skills --skill aoconnect
npm install --save @permaweb/aoconnect
Or manually:
cd skills/aoconnect
npm install @permaweb/aoconnect
Prerequisites
- Node.js 18+
- @permaweb/aoconnect package installed
- Arweave wallet (JWK format) for signing messages
Available Functions
Spawn an AO Process
node skills/aoconnect/index.mjs spawn \
--wallet ./wallet.json \
--module <module-txid> \
--scheduler <scheduler-address>
Options:
--wallet <path>- Path to Arweave wallet JSON--module <txid>- The arweave TxID of the ao Module--scheduler <address>- The Arweave wallet address of a Scheduler Unit--data <string>- Optional data to include in spawn message
Example:
node skills/aoconnect/index.mjs spawn \
--wallet ./wallet.json \
--module "l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc" \
--scheduler "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA"
Output:
{
"messageId": "l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc",
"processId": "5SGJUlPwlenkyuG9-xWh0Rcf0azm8XEd5RBTiutgWAg",
"height": 587540,
"tags": [
{ "name": "App-Process", "value": "l3hbt..." },
{ "name": "App-Name", "value": "arweave-ao" }
]
}
Send a Message to an AO Process
node skills/aoconnect/index.mjs message \
--wallet ./wallet.json \
--process <process-id> \
--data=<message-data> \
--tags Name=Value,Another=Tag
Options:
--wallet <path>- Path to Arweave wallet JSON (required)--process <id>- The ao Process ID (required)--data <string>- Message data (optional, random string if not provided)--tags <name=value,another=value>- Message tags (optional)
Example:
node skills/aoconnect/index.mjs message \
--wallet ./wallet.json \
--process "5SGJUlPwlenkyuG9-xWh0Rcf0azm8XEd5RBTiutgWAg" \
--data="Hello from AO!" \
--tags "Action=greet", "User=Rakis"
Output:
{
"messageId": "l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc",
"height": 587540,
"tags": [
{ "name": "Action", "value": "greet" },
{ "name": "User", "value": "Rakis" },
{ "name": "Original-Message", "value": "l3hbt..." }
]
}
Read the Result of an AO Message Evaluation
node skills/aoconnect/index.mjs result \
--message=<message-id> \
--process=<process-id>
Options:
--message=<id>- The ao message ID to evaluate (required)--process=<id>- The ao Process ID (required)
Example:
node skills/aoconnect/index.mjs result \
--message="l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc" \
--process="5SGJUlPwlenkyuG9-xWh0Rcf0azm8XEd5RBTiutgWAg"
Output:
{
"messages": [
{
"messageId": "l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc",
"tags": [
{ "name": "Action", "value": "greet" },
{ "name": "User", "value": "Rakis" }
],
"data": "Hello from AO!"
}
],
"spawns": [],
"output": {
"messages": [
{
"from": "address",
"to": "process-id",
"target": "process-id",
"tags": [
{ "name": "Response", "value": "Hello from AO!" }
],
"data": "",
"height": 587541
}
],
"size": 256
},
"error": null
}
Dry Run a Message (No Memory Commit)
node skills/aoconnect/index.mjs dryrun \
--message=<message-id> \
--process=<process-id>
Options:
--message=<id>- The ao message ID to dry run (required)--process=<id>- The ao Process ID (required)
Example:
node skills/aoconnect/index.mjs dryrun \
--message="l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc" \
--process="5SGJUlPwlenkyuG9-xWh0Rcf0azm8XEd5RBTiutgWAg"
Output:
{
"messages": [
{
"messageId": "l3hbt-rIJ_dr9at-eQ3EVajHWMnxPNm9eBtXpzsFWZc",
"tags": [
{ "name": "Action", "value": "greet" }
]
}
],
"spawns": [],
"output": {
"messages": [
{
"from": "address",
"to": "process-id",
"target": "process-id",
"tags": [
{ "name": "Response", "value": "Hello from AO!" }
],
"height": 587541
}
],
"size": 256
},
"error": null
}
Note: Dry run evaluates the message but doesn't save it to memory. Perfect for testing without committing to the chain.
Monitor Messages
node skills/aoconnect/index.mjs monitor \
--process <process-id> \
--on-message "<callback>"
Options:
--process <id>- The ao Process ID to monitor (required)--on-message "<function>"- JavaScript function to call for each new message (required)
Example:
node skills/aoconnect/index.mjs monitor \
--process "5SGJUlPwlenkyuG9-xWh0Rcf0azm8XEd5RBTiutgWAg" \
--on-message 'return { tags: msg.tags, data: msg.data }'
Note: In chat interface, use this pattern:
node skills/aoconnect/index.mjs monitor --process <id> --on-message "{console.log(msg.tags)}"
Connect to Custom Nodes
node skills/aoconnect/index.mjs connect --mu <url> --cu <url> --gateway <url>
Options:
--mu <url>- Message Unit URL (optional)--cu <url>- Compute Unit URL (optional)--gateway <url>- Arweave gateway URL (optional)
Example:
node skills/aoconnect/index.mjs connect \
--mu "https://mu.ao-testnet.xyz" \
--cu "https://cu.ao-testnet.xyz" \
--gateway "https://arweave.net"
Usage with AI Tools
Claude Code / OpenCode will automatically invoke the aoconnect skill when you:
use aoconnect to spawn <process>
use aoconnect to message <process> --data=<string>
use aoconnect to read result --message=<id>
use aoconnect to dryrun --message=<id>
The skill will prompt for wallet path if not configured.
Common Use Cases
Send a Transfer Message
node skills/aoconnect/index.mjs message \
--wallet ./wallet.json \
--process "ao-token-demo-AOe5Hdg4UQhOiE0ZYvRjB_8YDhROi3pA0YCEhPzb_KQ" \
--data=<raw-balance-value> \
--tags "Action=Transfer", "Recipient=<address>"
Dry Run Before Committing
Always dry run first to verify your message works:
node skills/aoconnect/index.mjs message \
--wallet ./wallet.json \
--process <process-id> \
--data="test"
node skills/aoconnect/index.mjs dryrun \
--message=<message-id> \
--process=<process-id>
Monitor Active Process
node skills/aoconnect/index.mjs monitor \
--process "<active-process-id>" \
--on-message "{console.log('New message:', msg.tags)}"
Error Handling
Missing Wallet
Error: walletPath is required. Please provide a path to your Arweave wallet JSON file.
Solution: Provide a wallet path:
--wallet ./wallet.json
Invalid Process ID
Error: Failed to send message: Invalid process ID
Solution: Verify the process ID is correct and valid.
Authentication Failures
Error: Failed to send message: Unauthorized
Solution: Ensure your wallet has sufficient balance and proper permissions.
API Reference
messageAo(processId, options)
Send a message to an ao Process.
Parameters:
processId(string): The ao Process IDoptions(Object): Message optionsdata(string): Message datatags(Array): Message tagswalletPath(string): Path to wallet JSON
Returns: Promise - Message result
resultAo(options)
Read the result of an ao message evaluation.
Parameters:
options(Object)message(string): The message IDprocess(string): The Process ID
Returns: Promise - Result object
dryrunAo(options)
Dry run a message without committing to memory.
Parameters:
options(Object)message(string): The message IDprocess(string): The Process ID
Returns: Promise - Dry run result
spawnAo(options)
Spawn an ao Process.
Parameters:
options(Object)module(string): Module TxIDscheduler(string): Scheduler addresswalletPath(string): Path to wallet JSONtags(Array): Tags for spawn message
Returns: Promise - Spawn result
monitorAo(options)
Monitor messages from a Process.
Parameters:
options(Object)process(string): Process IDonMessage(Function): Callback for new messages
Returns: string - Monitor ID
unmonitorAo(monitorId)
Stop monitoring messages.
Parameters:
monitorId(string): Monitor ID
connectAo(config)
Connect to ao nodes with custom configuration.
Parameters:
config(Object)MU_URL(string): Message Unit URLCU_URL(string): Compute Unit URLGATEWAY_URL(string): Arweave gateway URL
Returns: Object - aoconnect functions
getConnection(config)
Get connected aoconnect functions.
Parameters:
config(Object): Connection config
Returns: Object - aoconnect functions
Node.js vs Browser
This skill works in both Node.js and browser environments.
Node.js
import { messageAo, createDataItemSigner } from "./index.mjs";
import { readFileSync } from "node:fs";
const wallet = JSON.parse(readFileSync("./wallet.json", "utf-8"));
const result = await messageAo("process-id", {
walletPath: "./wallet.json",
data: "Hello AO!",
tags: [{ name: "Action", value: "greet" }]
});
Browser
import { messageAo, createDataItemSigner } from "./index.mjs";
const result = await messageAo("process-id", {
walletPath: "/path/to/wallet.json", // or loaded from localStorage
data: "Hello AO!",
tags: [{ name: "Action", value: "greet" }]
});