# AO Technical 101 Workshop
## Introduction to AO
**AO** is a compute layer built on top of **Arweave**. It provides **hyper parallel computing**, which means you can easily create and run an arbitrary number of independent computational processes — similar to creating containers in AWS, but decentralized. Currently, each **process** is a lightweight, scriptable container that runs Lua code.

</br>
## Two Ways to Interact with AO
1. **AOS**: Command Line Interface
2. **AOConnect**: JavaScript Library

</br>
## Getting Started with AOS
### Installation
To install **AOS**, simply run:
```bash
npm i -g https://get_ao.g8way.io
```
After installing, launch **AOS** by running:
```bash
aos
```
### Difference Between `aos` and `aos process_name`
- Running `aos` starts a **default AO terminal**.
- Running `aos process_name` creates a **new process** with the given name and opens a Lua terminal for that process.
This is the equivalent of setting up a container on AWS but so much simpler. In just two commands, we’ve created an AO process that is ready for computations.
### Process IDs and Wallets
- Each **AO process** is associated with a **process ID**.
- By default, every process has a wallet stored at `~/.aos.json`, similar to Arweave keyfiles.
- You can replace this wallet with your custom keyfile, if needed.
To retrieve your **process ID**:
```lua
ao.id
```
The **process ID** can be used in messages, functions, and interactions with other processes.
## AO Terminal Basics
The **AOS terminal** is a Lua environment with some AO-specific enhancements.
- **Simple Math**: Perform simple calculations:
```lua
> 5 * 5
25
```
- **Storing Variables**: Assign values to variables:
```lua
> count = 10
> count = count + 5 -- Now count is 15
```
- **Inline Functions**: You can define functions:
```lua
> function greet(name) return "Hello, " .. name end
> greet("Alice")
"Hello, Alice"
```
- **Multi-Line Code**: To write multi-line code, use:
```lua
.editor
```
Example:
```lua
while num < 50 do
num = num + 1 -- Note: Lua doesn’t have `++` or `+=` syntax
end
```
### Using `.pad` Editor
If you need a more powerful editor, `.pad` gives a **Vim-like editor** for working with code, which is handy for power users.
---
## Messaging Between Processes in AO
In AO, processes **communicate via messages**. Let’s send a simple message to ourselves:
```lua
Send({ Target = ao.id, Data = "ping" })
```
This message is added to the **Inbox** of the process. Inbox is a default table that every process has. To read incoming messages:
```lua
> Inbox[#Inbox]
```
## Creating Multiple Processes and Messaging
1. Create a second process:
```bash
aos process_two
```
2. Send a message from the new process:
```lua
Send({ Target = "process_id_of_first_process", Data = "Hello from process_two" })
```
3. Read the message in the first process:
```lua
> Inbox[#Inbox]
```
---
## Using Handlers in AO
**Handlers** are special instructions that enable auto-execution of functions when certain conditions or patterns are met.

</br>
Example: Let’s create a **ping-pong handler**:
```lua
Handlers.add(
"pingpong",
Handlers.utils.hasMatchingData("ping"),
Handlers.utils.reply("pong")
)
```
This handler listens for any message containing `"ping"` and replies with `"pong"`.
### Additional Handler Features
- **`Handlers.once`**: This will create a handler that removes itself after running once.
- **Specifying Max Runs (Optional)**: You can also specify the number of times a handler should run before it removes itself:
```lua
Handlers.add(
"pingpong",
Handlers.utils.hasMatchingData("ping"),
Handlers.utils.reply("pong"),
3 -- Maximum number of runs
)
```
## BetterIDEa IDE
Writing multi-line code can be cumbersome in the AOS terminal. For a better experience, use **BetterIDEa IDE**:
- Head to **[https://ide.betteridea.dev/](https://ide.betteridea.dev/)**
- The IDE provides:
- **Syntax highlighting**
- **Line navigation** and **editing tools**
- **Auto-completions**
- **Easy installation of blueprints** and **dependencies**
---
## Building a Mini Utility: Chatroom
Let’s build a simple chatroom in AO.
### Step 1: Initialize Members List
First, we initialize a list to track participants:
```lua
Members = Members or {}
```
### Step 2: Add a Register Handler
To allow processes to join the chatroom:
```lua
Handlers.add(
"Register",
{ Action = "Register" },
function(msg)
table.insert(Members, msg.From)
print(msg.From .. " Registered")
msg.reply({ Data = "Registered." })
end
)
```
- This handler adds the sender process to the members list and replies to confirm registration.
### Step 3: Register Yourself to the Chatroom
Send a message to register:
```lua
Send({ Target = ao.id, Action = "Register" })
```
Check the members list:
```lua
Members -- You should see your process ID listed
```
### Step 4: Add a Broadcast Handler
Now, let’s create a handler that broadcasts messages to all members:
```lua
Handlers.add(
"Broadcast",
{ Action = "Broadcast" },
function(msg)
for _, recipient in ipairs(Members) do
ao.send({ Target = recipient, Data = msg.Data })
end
msg.reply({ Data = "Broadcasted." })
end
)
```
Test broadcasting:
```lua
Send({ Target = ao.id, Action = "Broadcast", Data = "Hello Members!" }).receive().Data
```
## Using Blueprints for Common Utilities
AOS provides **blueprints** for common utilities like chatrooms:
```lua
.load-blueprint chatroom
```
This installs a pre-configured chatroom handler for you to use directly.
---
## AOS 2.0 Updates
- **`.forward`**: Every message can be forwarded to another process:
```lua
msg.forward(msg['Some-Address'], {})
```
- **`.reply`**: Send a response to the original sender:
```lua
msg.reply({ Test = "Successful message receipt", Status = "Success" })
```
- **`.onReply`**: Set up an action that should happen when a reply is received:
```lua
Send({
Target = target,
Test = "1"
}).onReply(printMsg('Test'))
```
- **`.receive`**: This is similar to the `async/await` function in JavaScript:
```lua
Send({
Target = target,
Action = "Get-Reply"
}).receive()
```
- **`.dryrun`**: DryRun sends a message to a specific process and gets the result without saving the state. Useful for read operations like checking balances.
---
## Handling Larger Datasets with SQLite
The basic setup is great for lightweight operations, but for larger datasets, we need structured storage. This is where **SQLite** comes in.
### SQLite with AO
**DbAdmin** is a module that makes SQLite interactions easier within AO.
## Building a Database Utility Using DbAdmin
### Step 1: Set Up SQLite and DbAdmin
```lua
local sqlite3 = require("lsqlite3")
local dbAdmin = require("@rakis/DbAdmin")
-- Open an in-memory database
db = sqlite3.open_memory()
-- Create a DbAdmin instance
admin = dbAdmin.new(db)
```
### Step 2: Create a Table
```lua
admin:exec[[
CREATE TABLE leaderboard (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
score INTEGER DEFAULT 0,
profile_image TEXT
);
]]
```
### Step 3: Insert Records
```lua
admin:apply('INSERT INTO leaderboard (name, score, profile_image) VALUES (?, ?, ?);', { "Alice", 10, "image_url_1" })
admin:apply('INSERT INTO leaderboard (name, score, profile_image) VALUES (?, ?, ?);', { "Bob", 15, "image_url_2" })
```
### Step 4: Update and Delete Records
You can also update or delete records using the `apply` method:
```lua
-- Update a user's score
admin:apply('UPDATE leaderboard SET score = ? WHERE name = ?;', { 20, "Alice" })
```
### Step 5: Query Records
To retrieve records from the database:
```lua
local results = admin:select('SELECT * FROM leaderboard WHERE name = ?;', { "Alice" })
```
---
## Using Bazaar Profiles APM Package
For managing user profiles, you can use the Bazaar Profiles APM Package.
Install the package:
```lua
APM.install("@ankush/bazar")
```
Fetch user profiles:
```lua
bazarProfiles = require("@ankush/bazar")
res = bazarProfiles.GetProfile(wallet_address)
print(res)
```
---
## Summary
In this workshop, we covered:
- AO Basics: Understanding AO and hyper parallel computing.
- AOS CLI: Installation, process creation, and messaging.
- Handlers: Automating responses to messages.
- BetterIDEa IDE: A better development experience for AO.
- Chatroom Utility: Building and managing chatrooms in AO.
- SQLite with DbAdmin: Handling larger datasets in AO.
- APM Packages: Leveraging existing modules for complex functionality.