# 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. ![image](https://hackmd.io/_uploads/rkcS50vlyl.png) </br> ## Two Ways to Interact with AO 1. **AOS**: Command Line Interface 2. **AOConnect**: JavaScript Library ![image](https://hackmd.io/_uploads/B1udqCvgkl.png) </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. ![image](https://hackmd.io/_uploads/Bk_q5CDlyl.png) </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.