Caution
This repository has been archived. The AR.IO smart contracts have migrated from AO to Solana. All smart contract code now lives at ar-io/ar-io-solana-contracts.
The AR.IO Marketplace is a decentralized protocol built on AO for trustless exchange of ARIO tokens and ANT (Arweave Name Tokens). The marketplace supports three order types:
- Fixed Price Orders - Immediate buy/sell at a set price
- Dutch Auction Orders - Price decreases over time until filled
- English Auction Orders - Competitive bidding with settlement period
- Unidirectional Orderbook - Only ANT sell orders sit in the orderbook; ARIO buy orders match immediately (see ADR-000)
- ARIO Internal Ledger - All ARIO operations use an internal balance system (deposit → trade → withdraw)
- ANT Intent-Based System - ANT transfers are tracked through parent/child intent relationships
- Multiple Order Types - Fixed price, Dutch auctions, and English auctions
- Listing Fees - Duration-based fees (1 ARIO per hour) charged from internal balance
- Transaction Fees - 5% fee on all trades (0.5% treasury, 4.5% marketplace)
# Install dependencies
npm install @permaweb/aoconnect
# Interact with the marketplace
import { message, result } from '@permaweb/aoconnect';The marketplace has an asymmetric orderbook (see ADR-000):
- Selling ANT (ANT-dominant orders): Your ANT listing sits in the orderbook and waits for buyers
- Buying ANT (ARIO-dominant orders): Your buy order matches immediately against existing listings or fails
This is similar to NFT marketplaces (OpenSea, Rarible) where only "listings" sit in the orderbook, and buyers execute instant purchases.
- Create Intent - Create a listing intent (charges listing fee from ARIO balance)
- Transfer ANT - Send ANT to marketplace with
X-Intent-Idtag - Marketplace Receives -
Credit-Noticeactivates the order - Order Added to Orderbook - Your ANT listing appears for buyers to purchase
- Wait for Buyer - Order sits until matched, cancelled, or expired
- Settlement - When bought, marketplace transfers ANT to buyer (tracked via child intent)
- Deposit ARIO - Transfer ARIO to marketplace via
Credit-NoticewithX-Action: Deposit - Browse Listings - Use
Get-Ordersto find ANTs for sale - Create Buy Order - Specify which ANT to buy via
Swap-Token(ANT process ID) - Immediate Match - Order fills instantly if listing still available
- Receive ANT - Marketplace transfers ANT to you immediately
- Withdraw - Withdraw remaining ARIO balance anytime
All handlers return a notice to the sender with the action result. Successful operations return {Action}-Notice (e.g., Info-Notice), while errors return Invalid-{Action}-Notice.
Get marketplace process information.
Parameters: None
Response:
{
"Name": "AR.IO Marketplace",
"Version": "0.1.0",
"Owner": "process-owner-address",
"Treasury": "treasury-address",
"['ARIO-Token-Process-Id']": "ario-process-id",
"['Accrued-Fees']": "fee-amount-in-mARIO"
}Example (aoconnect):
import { message, result } from '@permaweb/aoconnect';
const messageId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [{ name: 'Action', value: 'Info' }],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: messageId,
process: MARKETPLACE_PROCESS_ID,
});
const info = JSON.parse(Messages[0].Data);
console.log('Marketplace:', info);Query orders with flexible filtering and pagination.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Status |
string | No | Filter by status: active, executed, cancelled, expired, listed, completed, all |
Ids |
JSON array | No | Filter by specific order IDs: ["id1", "id2"] |
Dominant-Token |
string | No | Filter by dominant token (token being offered) |
Swap-Token |
string | No | Filter by swap token (token requested) |
Cursor |
string | No | Pagination cursor from previous response |
Limit |
number | No | Items per page (default: 100, max: 1000) |
Sort-By |
string | No | Field to sort by (default: CreatedAt) |
Sort-Order |
string | No | asc or desc (default: desc) |
Response:
{
"items": [/* array of orders */],
"limit": 100,
"totalItems": 250,
"sortBy": "CreatedAt",
"sortOrder": "desc",
"hasMore": true,
"nextCursor": "cursor-string"
}Example (aoconnect):
// Get all active orders
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Get-Orders' },
{ name: 'Status', value: 'active' },
{ name: 'Limit', value: '50' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const orders = JSON.parse(Messages[0].Data);
console.log(`Found ${orders.totalItems} active orders`);Get a single order by ID.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Order-Id |
string | Yes | The order ID to retrieve |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Get-Order' },
{ name: 'Order-Id', value: 'order-message-id' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const order = JSON.parse(Messages[0].Data);Create an ARIO buy order using internal balance. This order matches immediately against existing ANT listings.
Important: This handler is for buying ANTs with ARIO (ARIO-dominant orders). To sell ANTs for ARIO (ANT-dominant orders), use the Intent system (see Intent Management). See ADR-000 for details on order directionality.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Swap-Token |
string | Yes | ANT process ID you want to buy |
Quantity |
string | Yes | Amount of ARIO to offer (in mARIO) |
Order-Type |
string | Yes | Type of the sell order you're buying (fixed, dutch, or english) |
Note: When buying ANT, you do NOT specify a price - you accept the seller's asking price. The
Swap-Token(ANT process ID) uniquely identifies which ANT to buy, as each ANT can only have one active sell order at a time.
Example (aoconnect):
// Buy a specific ANT listing
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Order' },
{ name: 'Swap-Token', value: ANT_PROCESS_ID }, // Which ANT to buy
{ name: 'Quantity', value: '10000000000' }, // 10 ARIO (must be >= asking price)
{ name: 'Order-Type', value: 'fixed' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
console.log('Purchase result:', JSON.parse(Messages[0].Data));Cancel an active order and unlock funds.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Order-Id |
string | Yes | The order ID to cancel |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Cancel-Order' },
{ name: 'Order-Id', value: 'order-message-id' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});ANT listings use an intent-based workflow to ensure atomic transfers. ANT sell orders are added to the orderbook and wait for buyers, unlike ARIO buy orders which match immediately (see ADR-000).
Create a listing intent for ANT orders. This charges a listing fee from your internal ARIO balance.
Listing Fee: 1 ARIO per hour (calculated based on X-Intent-Expiration-Time)
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
X-Intent-Quantity |
string | Yes | Amount to trade (usually 1 for ANT) |
X-Intent-Price |
string | Yes | Price per unit (for fixed/dutch), or starting bid (for english) |
X-Intent-Order-Type |
string | No | fixed, dutch, or english (default: fixed) |
X-Intent-Expiration-Time |
number | Yes | Unix timestamp (min 1 hour, max 30 days, fee rounded up to nearest hour) |
X-Intent-Minimum-Price |
string | No* | Minimum price floor (dutch auctions only) |
X-Intent-Decrease-Interval |
string | No* | Price decrease interval in ms (dutch auctions only) |
*Required only for dutch auction orders
Note: This handler is only for ANT sell orders (
Create-Orderaction is assumed, always swaps ANT for ARIO). ARIO buy orders don't use intents - they callCreate-Orderdirectly.
Response:
{
"Intent-Id": "intent-id",
"Status": "Success"
}Example (aoconnect) - Create ANT Listing:
// Step 1: Create intent (charges listing fee)
const intentMsgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Intent' },
{ name: 'X-Intent-Quantity', value: '1' }, // 1 ANT
{ name: 'X-Intent-Order-Type', value: 'fixed' },
{ name: 'X-Intent-Price', value: '10000000000' }, // 10 ARIO
{ name: 'X-Intent-Expiration-Time', value: String(Date.now() + 604800000) }, // 7 days
],
signer: createDataItemSigner(wallet),
});
const { Messages: intentMessages } = await result({
message: intentMsgId,
process: MARKETPLACE_PROCESS_ID,
});
const intentData = JSON.parse(intentMessages[0].Data);
const intentId = intentData['Intent-Id'];
console.log('Intent created:', intentId);
// Step 2: Transfer ANT to marketplace with intent ID
// Order parameters come from the intent created in Step 1
const transferMsgId = await message({
process: ANT_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Transfer' },
{ name: 'Recipient', value: MARKETPLACE_PROCESS_ID },
{ name: 'Quantity', value: '1' },
{ name: 'X-Intent-Id', value: intentId },
{ name: 'X-Order-Action', value: 'Create-Order' },
],
signer: createDataItemSigner(wallet),
});
console.log('ANT transferred, order will be created automatically');Query intents with filtering and pagination.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Cursor |
string | No | Pagination cursor |
Limit |
number | No | Items per page (default: 100, max: 1000) |
Sort-By |
string | No | Field to sort by |
Sort-Order |
string | No | asc or desc |
Filters |
JSON object | No | Filter by: { "initiator": "address", "status": "pending", "type": "parent" } |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Get-Paginated-Intents' },
{ name: 'Filters', value: JSON.stringify({ status: 'active' }) },
{ name: 'Limit', value: '50' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const intents = JSON.parse(Messages[0].Data);Get a specific intent with all child intents.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Intent-Id |
string | Yes | The intent ID to retrieve |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Get-Intent-By-Id' },
{ name: 'Intent-Id', value: intentId },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const intent = JSON.parse(Messages[0].Data);
console.log('Intent status:', intent.status);
console.log('Child intents:', Object.keys(intent.children || {}).length);Manually trigger ANT ownership verification for an intent.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
X-Intent-Id |
string | Yes | Intent ID to resolve |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Push-ANT-Intent-Resolution' },
{ name: 'X-Intent-Id', value: intentId },
],
signer: createDataItemSigner(wallet),
});All ARIO trading uses an internal balance system for efficiency and atomic operations.
Get your ARIO balance in the marketplace.
Parameters: None
Response:
{
"address": "your-address",
"balance": "1000000000", // Available balance in mARIO
"totalBalance": "5000000000", // Available + locked
"lockedBalance": "4000000000", // Locked in orders
"orders": {
"order-id-1": "2000000000",
"order-id-2": "2000000000"
}
}Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [{ name: 'Action', value: 'Get-Balance' }],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const balance = JSON.parse(Messages[0].Data);
console.log(`Available: ${balance.balance} mARIO`);
console.log(`Locked in orders: ${balance.lockedBalance} mARIO`);Get all marketplace balances with pagination (admin/analytics).
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Cursor |
string | No | Pagination cursor from previous response |
Limit |
number | No | Items per page (default: 100, max: 1000) |
Sort-By |
string | No | Field to sort by (default: balance) |
Sort-Order |
string | No | asc or desc (default: desc) |
Response:
{
"items": [
{
"address": "user-address-1",
"balance": "5000000000", // Available balance in mARIO
"lockedBalance": "2000000000", // Locked in orders
"totalBalance": "7000000000", // Available + locked
"orders": {
"order-id-1": "1000000000",
"order-id-2": "1000000000"
}
}
],
"limit": 100,
"totalItems": 250,
"sortBy": "balance",
"sortOrder": "desc",
"hasMore": true,
"nextCursor": "cursor-string"
}Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Get-Paginated-Balances' },
{ name: 'Limit', value: '100' },
{ name: 'Sort-By', value: 'totalBalance' },
{ name: 'Sort-Order', value: 'desc' },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
const balances = JSON.parse(Messages[0].Data);
console.log(`Found ${balances.totalItems} accounts`);
balances.items.forEach(account => {
console.log(`${account.address}: ${account.totalBalance} mARIO`);
});Deposit ARIO into your marketplace balance via Credit-Notice.
Example (aoconnect):
// Transfer ARIO to marketplace
const msgId = await message({
process: ARIO_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Transfer' },
{ name: 'Recipient', value: MARKETPLACE_PROCESS_ID },
{ name: 'Quantity', value: '10000000000' }, // 10 ARIO
{ name: 'X-Action', value: 'Deposit' }, // Important: marks as deposit
],
signer: createDataItemSigner(wallet),
});
console.log('ARIO deposited to marketplace');Withdraw ARIO from your marketplace balance.
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Quantity |
string | Yes | Amount to withdraw in mARIO |
Recipient |
string | No | Recipient address (default: sender) |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Withdraw-Ario' },
{ name: 'Quantity', value: '5000000000' }, // 5 ARIO
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
console.log('Withdrawal initiated');Place or update a bid on an English auction.
Minimum Increment: 1 ARIO (1000000000 mARIO)
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Order-Id |
string | Yes | Auction order ID |
Bid-Amount |
string | Yes | Your total bid amount in mARIO |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Bid-On-English-Auction' },
{ name: 'Order-Id', value: auctionOrderId },
{ name: 'Bid-Amount', value: '15000000000' }, // 15 ARIO
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: msgId,
process: MARKETPLACE_PROCESS_ID,
});
console.log('Bid placed successfully');Settle an expired English auction (anyone can trigger).
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Order-Id |
string | Yes | Auction order ID to settle |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Settle-Auction' },
{ name: 'Order-Id', value: auctionOrderId },
],
signer: createDataItemSigner(wallet),
});Withdraw accrued marketplace fees (treasury only).
Parameters:
| Tag | Type | Required | Description |
|---|---|---|---|
Quantity |
string | Yes | Amount to withdraw in mARIO |
Recipient |
string | No | Recipient address (default: treasury) |
Example (aoconnect):
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Withdraw-Fees' },
{ name: 'Quantity', value: '1000000000' }, // 1 ARIO
],
signer: createDataItemSigner(treasuryWallet),
});These handlers are triggered automatically by the system and should not be called directly by users.
Handles incoming token transfers (deposits and ANT orders). Automatically called by token processes.
Confirms transfer completion and resolves child intents. Automatically called by token processes.
Handles transfer failures and cascades intent failures. Automatically called by token processes.
Resolves ANT ownership verification for intents. Called in response to Push-ANT-Intent-Resolution.
Immediate buy/sell at a specified price.
Use Case: Quick trades at known prices
Example: Sell 1 ANT for 10 ARIO
Price decreases over time until someone buys.
Use Case: Price discovery for unique ANTs
Parameters:
Price: Starting priceMinimum-Price: Floor priceDecrease-Interval: Time between decreases (ms)
Example: Start at 100 ARIO, decrease by 1 ARIO every hour, minimum 50 ARIO
Competitive bidding with a settlement period.
Use Case: Maximum price discovery through competitive bidding
Flow:
- Seller creates auction with expiration time
- Bidders place/update bids (minimum 1 ARIO increment)
- Auction expires
- Anyone calls
Settle-Auctionto finalize - Winner receives ANT, losing bids refunded
import { message, result, createDataItemSigner } from '@permaweb/aoconnect';
// 1. Deposit ARIO to marketplace
await message({
process: ARIO_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Transfer' },
{ name: 'Recipient', value: MARKETPLACE_PROCESS_ID },
{ name: 'Quantity', value: '20000000000' }, // 20 ARIO
{ name: 'X-Action', value: 'Deposit' },
],
signer: createDataItemSigner(wallet),
});
// 2. Create buy order (must specify which ANT to buy)
const msgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Order' },
{ name: 'Swap-Token', value: ANT_PROCESS_ID }, // Which ANT to buy
{ name: 'Quantity', value: '10000000000' }, // Offer 10 ARIO
{ name: 'Order-Type', value: 'fixed' },
],
signer: createDataItemSigner(wallet),
});
// Order matches immediately if the specified sell order is still available// 1. Ensure you have ARIO balance for listing fee
await message({
process: ARIO_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Transfer' },
{ name: 'Recipient', value: MARKETPLACE_PROCESS_ID },
{ name: 'Quantity', value: '2000000000' }, // 2 ARIO for fees
{ name: 'X-Action', value: 'Deposit' },
],
signer: createDataItemSigner(wallet),
});
// 2. Create listing intent
const intentMsgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Intent' },
{ name: 'X-Intent-Quantity', value: '1' },
{ name: 'X-Intent-Order-Type', value: 'fixed' },
{ name: 'X-Intent-Price', value: '15000000000' }, // 15 ARIO
{ name: 'X-Intent-Expiration-Time', value: String(Date.now() + 604800000) },
],
signer: createDataItemSigner(wallet),
});
const { Messages } = await result({
message: intentMsgId,
process: MARKETPLACE_PROCESS_ID,
});
const intentId = JSON.parse(Messages[0].Data)['Intent-Id'];
// 3. Transfer ANT with intent ID
// Order parameters come from the intent created in Step 2
await message({
process: ANT_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Transfer' },
{ name: 'Recipient', value: MARKETPLACE_PROCESS_ID },
{ name: 'Quantity', value: '1' },
{ name: 'X-Intent-Id', value: intentId },
{ name: 'X-Order-Action', value: 'Create-Order' },
],
signer: createDataItemSigner(wallet),
});
console.log('ANT listing created!');// Create Dutch auction that starts at 50 ARIO, decreases by 1 ARIO every hour
const intentMsgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Intent' },
{ name: 'X-Intent-Quantity', value: '1' },
{ name: 'X-Intent-Order-Type', value: 'dutch' },
{ name: 'X-Intent-Price', value: '50000000000' }, // Start: 50 ARIO
{ name: 'X-Intent-Minimum-Price', value: '10000000000' }, // Floor: 10 ARIO
{ name: 'X-Intent-Decrease-Interval', value: '3600000' }, // 1 hour
{ name: 'X-Intent-Expiration-Time', value: String(Date.now() + 604800000) },
],
signer: createDataItemSigner(wallet),
});
// Then get intent ID and transfer ANT
// (see Example 2 for complete ANT transfer code - only need X-Intent-Id and X-Order-Action)// Seller creates auction
const intentMsgId = await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Create-Intent' },
{ name: 'X-Intent-Quantity', value: '1' },
{ name: 'X-Intent-Order-Type', value: 'english' },
{ name: 'X-Intent-Price', value: '10000000000' }, // Starting bid: 10 ARIO
{ name: 'X-Intent-Expiration-Time', value: String(Date.now() + 86400000) }, // 24 hours
],
signer: createDataItemSigner(wallet),
});
// Then get intent ID and transfer ANT
// (see Example 2 for complete ANT transfer code - only need X-Intent-Id and X-Order-Action)
// Bidders place bids (must increment by at least 1 ARIO)
await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Bid-On-English-Auction' },
{ name: 'Order-Id', value: auctionOrderId },
{ name: 'Bid-Amount', value: '15000000000' }, // 15 ARIO
],
signer: createDataItemSigner(bidderWallet),
});
// After expiration, anyone can settle
await message({
process: MARKETPLACE_PROCESS_ID,
tags: [
{ name: 'Action', value: 'Settle-Auction' },
{ name: 'Order-Id', value: auctionOrderId },
],
signer: createDataItemSigner(wallet),
});Before running the tests, ensure you have the following installed:
- Lua 5.3 and LuaRocks: Use the provided installation script
This script automatically installs Lua 5.3.1 and LuaRocks 3.9.1 for your operating system (macOS, Linux, or Windows via MSYS2).
./scripts/install-lua-deps.sh
The test suite consists of unit tests (Lua) and integration tests (TypeScript):
Unit Tests (Lua with busted):
pnpm test:unitIntegration Tests (TypeScript with ao-loader):
pnpm test:integrationAll Tests:
pnpm testEnd-to-end tests using ao-localnet are planned but not yet implemented. The ao-localnet tool requires additional configuration and setup work before it can be reliably integrated for automated E2E testing.
Current Status: E2E infrastructure removed pending ao-localnet improvements
What's Needed:
- ao-localnet configuration and stability improvements
- Test wallet and process bootstrapping
- Full marketplace workflow tests (deposit → trade → settle)
To test the process.lua in a real AO environment:
- Start the AO process:
aos your_process_name [--wallet /path/to/wallet.json] - Deploy a token blueprint for ARIO:
.load-blueprint token - Deploy the marketplace process:
.load src/process.lua - Send messages to test handlers (see API Reference above)
- Check ao.link for debugging and message results
Before deploying, ensure you have:
-
AO SDK installed: Install the AO command line tools
npm i -g https://get_ao.g8way.io
-
Wallet file: An Arweave wallet JSON file for deployment. You can generate one simply by running
aosin terminal. It should be created in~/.aos.json.
-
Start CLI:
aos --wallet /path/to/your/wallet.json
-
Deploy the code:
user@aos-2.0.4[Inbox:1]> .load src/process.luaIf the code is correct, the CLI will show the standard prompt.
- Use
src/process.luawhich is a self-contained version with all dependencies.
This project consists of several components organized into different directories:
-
process.lua- Main entry point for the ARnS Marketplace process. Handles message routing, validation, and core marketplace functionality including order creation, credit notices, and basic process operations. -
ucm.lua- ANT Marketplace core logic. Contains the main marketplace functions including order book management, pair indexing, order creation, and error handling. This is the heart of the marketplace functionality. -
utils.lua- Utility functions used throughout the project. Includes address validation, amount validation, JSON message decoding, pair data validation, fee calculations, and table printing utilities.
unit/- Lua unit tests with busted (426 tests, 83% coverage)integration/- TypeScript integration tests with ao-loader (69 tests)utils/- Test utilities and helpers
adr/- Architecture Decision Records (ADRs) documenting key design decisions:- ADR-000: Orderbook Architecture - Foundational design explaining unidirectional orderbook and order directionality
- ADR-001: Module Whitelist for ANT Trading
- ADR-002: Credit-Notice Pattern
- ADR-003: ARIO Internal Ledger
- ADR-004: Intent-Based Workflow
- ADR-005: Class Type Pattern
- ADR-006: Lazy Module Loading
- ADR-007: Handler Hooks Pattern