Skip to content

Commit

Permalink
Merge pull request #11 from pawanpaudel93/feat/wao
Browse files Browse the repository at this point in the history
feat: wao integration
  • Loading branch information
pawanpaudel93 authored Dec 22, 2024
2 parents 57c7570 + b573681 commit e4f5f0b
Show file tree
Hide file tree
Showing 23 changed files with 1,062 additions and 707 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Create AO Contract

A CLI tool for scaffolding AO contracts, featuring [Busted](https://luarocks.org/modules/lunarmodules/busted) for testing and seamless deployment via [ao-deploy](https://github.com/pawanpaudel93/ao-deploy).
A CLI tool for scaffolding AO contracts, featuring:

- 🧪 **Testing**: [Busted](https://luarocks.org/modules/lunarmodules/busted) and [WAO](https://github.com/weavedb/wao) for testing
- 🛠️ **Development Tools**: [arweave](https://github.com/crookse/arweave-lua) for testing, formatting and linting
- 📦 **Deployment**: Seamless deployment using [ao-deploy](https://github.com/pawanpaudel93/ao-deploy)

## Table of Contents

Expand Down
5 changes: 4 additions & 1 deletion src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,10 @@ export const runCli = async (): Promise<CliResults> => {
message: "What will your project be called?",
defaultValue: defaultOptions.appName,
placeholder: defaultOptions.appName,
validate: validateAppName,
validate: (value) => {
if (!value) return;
return validateAppName(value);
},
}),
}),
...(cliResults.flags.noGit === defaultOptions.flags.noGit && {
Expand Down
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ const main = async () => {
// Write name to package.json
const pkgJson = fs.readJSONSync(path.join(projectDir, "package.json")) as CPAPackageJSON;
pkgJson.name = scopedAppName;
pkgJson.scripts!.test = pkgJson.scripts?.test?.replace("AOS_PROCESS_PATH", getAosProcessPath());
pkgJson.scripts!["test-lua"] = pkgJson.scripts?.["test-lua"]?.replace("AOS_PROCESS_PATH", getAosProcessPath());
pkgJson.scripts!["test-js"] = pkgJson.scripts?.["test-js"]?.replace("npm", pkgManager);
pkgJson.cacMetadata = { initVersion: getVersion() };

// ? Bun doesn't support this field (yet)
Expand All @@ -71,6 +72,11 @@ const main = async () => {
aodConfig = aodConfig.replaceAll("my_ao_contract", `"${scopedAppName}"`).replaceAll("my-ao-contract", scopedAppName);
fs.writeFileSync(path.join(projectDir, "aod.config.js"), aodConfig);

// Update test/contract_test.js
let testContent = fs.readFileSync(path.join(projectDir, "test", "contract_test.js"), "utf-8");
testContent = testContent.replaceAll("my-ao-contract", scopedAppName);
fs.writeFileSync(path.join(projectDir, "test", "contract_test.js"), testContent);

// Update README.md
let readmeContent = fs.readFileSync(path.join(projectDir, "README.md"), "utf-8");
readmeContent = readmeContent.replaceAll("my-ao-contract", scopedAppName);
Expand Down
5 changes: 4 additions & 1 deletion template/ao/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,7 @@ dist


# Package manager
*.lockb
*.lockb

# ao-deploy
dist
68 changes: 56 additions & 12 deletions template/ao/README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,80 @@
# my-ao-contract

AO contract created using [create-ao-contract](https://github.com/pawanpaudel93/create-ao-contract) featuring [Busted](https://luarocks.org/modules/lunarmodules/busted) for testing and seamless deployment via [ao-deploy](https://github.com/pawanpaudel93/ao-deploy).
AO contract created using [create-ao-contract](https://github.com/pawanpaudel93/create-ao-contract), featuring:

- 🧪 **Testing**: [Busted](https://luarocks.org/modules/lunarmodules/busted) and [WAO](https://github.com/weavedb/wao) for testing
- 🛠️ **Development Tools**: [arweave](https://github.com/crookse/arweave-lua) for testing, formatting and linting
- 📦 **Deployment**: Seamless deployment using [ao-deploy](https://github.com/pawanpaudel93/ao-deploy)

## Prerequisites

1. Make sure you have [Lua](https://www.lua.org/start.html#installing) and [LuaRocks](https://github.com/luarocks/luarocks/wiki/Download) installed.
1. Install [Lua](https://www.lua.org/start.html#installing) and [LuaRocks](https://github.com/luarocks/luarocks/wiki/Download).

2. Install [arweave](https://luarocks.org/modules/crookse/arweave) using LuaRocks for testing purposes.
2. **Install Dependencies**:

```bash
# Install Arweave Lua package
luarocks install arweave

# Install project dependencies
npm install
```

3. **[Recommended]** Install [Lua Language Server](https://luals.github.io/#install) to make development easier, safer, and faster!. On VSCode, install extension: [sumneko.lua](https://marketplace.visualstudio.com/items?itemName=sumneko.lua)
- Install AO & Busted addon using Lua Addon Manager. On VSCode, goto `View > Command Palette > Lua: Open Addon Manager`
**Note**: `arweave` package relies on `busted` for its testing capabilities.

3. **IDE Setup (Recommended)**:
- Install [VSCode](https://code.visualstudio.com/)
- Add the [Lua Language Server](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) extension.
- Install AO & Busted addons via Command Palette (`View > Command Palette > Lua: Open Addon Manager`)

## Usage
## Development

To install dependencies:
To run tests, use:

```bash
npm install
npm run test
```

To run tests:
To deploy the contract, use:

```bash
npm run test
npm run deploy
```

To deploy contract:
To format the code, use:

```bash
npm run deploy
npm run format
```

To lint the code, use:

```bash
npm run lint
```

## Project Structure

```
my-ao-contract/
├── src/ # Contract source code
├── test/ # Test files
├── scripts/ # Utility scripts
├── aod.config.js # ao-deploy configuration
└── package.json # Project configuration
```

## Contributing

If you wish to contribute, please follow these steps:

1. Fork the repository.
2. Create a new branch (`git checkout -b feature-branch`).
3. Commit your changes (`git commit -am 'Add some feature'`).
4. Push to the branch (`git push origin feature-branch`).
5. Create a new Pull Request.

## Acknowledgments

- Created using [create-ao-contract](https://github.com/pawanpaudel93/create-ao-contract)
- Built for [AO](https://ao.arweave.net/)
1 change: 1 addition & 0 deletions template/ao/aod.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ export default defineConfig({
name: "my-ao-contract",
contractPath: "src/contract.lua",
luaPath: "./src/?.lua",
outDir: "./dist",
},
});
11 changes: 9 additions & 2 deletions template/ao/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,17 @@
"license": "MIT",
"scripts": {
"deploy": "ao-deploy aod.config.js",
"test": "arweave test . --lpath='./src/?.lua;./src/?/?.lua;./src/?/init.lua;AOS_PROCESS_PATH/?.lua'"
"build": "ao-deploy aod.config.js --build-only --out-dir ./dist",
"test-lua": "arweave test . --pattern='_test' --lpath='./src/?.lua;./src/?/?.lua;./src/?/init.lua;AOS_PROCESS_PATH/?.lua'",
"test-js": "npm run build && node --experimental-wasm-memory64 --test",
"test": "run-s -c test-lua test-js",
"format": "node scripts/format.js",
"lint": "arweave lint src/**/*.lua"
},
"type": "module",
"dependencies": {
"ao-deploy": "^0.5.0"
"ao-deploy": "^0.6.0",
"npm-run-all": "^4.1.5",
"wao": "^0.6.0"
}
}
50 changes: 50 additions & 0 deletions template/ao/scripts/format.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable no-undef */
import { glob } from "glob";
import { spawn } from "child_process";

// First find all Lua files
const luaFiles = glob.sync("src/**/*.lua");

// Only proceed if we found files to format
if (luaFiles.length === 0) {
console.log("ℹ️ No Lua files found to format");
process.exit(0);
}

// Pass the actual files to the formatter
const formatter = spawn("arweave", ["fmt", ...luaFiles], {
stdio: ["inherit", "inherit", "pipe"],
shell: true,
});

formatter.on("error", (err) => {
console.error("❌ Failed to start formatter:", err.message);
process.exit(1);
});

let hasError = false;

formatter.stderr?.on("data", (data) => {
hasError = true;
console.error(`❌ Formatter error: ${data}`);
});

// Modify exit handler to consider stderr output
formatter.on("exit", (code, signal) => {
if (code === 0 && !hasError) {
console.log("✅ Formatting completed successfully");
} else {
console.error(`❌ Formatter failed with ${signal ? `signal ${signal}` : `code ${code}`}`);
process.exit(1);
}
});

// Modify close handler to be more specific
formatter.on("close", (code, signal) => {
if (code !== 0) {
console.error(
`⚠️ Formatter process closed unexpectedly ${signal ? `with signal ${signal}` : `with code ${code}`}`
);
process.exit(1);
}
});
19 changes: 12 additions & 7 deletions template/ao/src/contract.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,27 @@ local burn = require "src.handlers.burn"
--

-- Info
Handlers.add('Info', Handlers.utils.hasMatchingTag('Action', 'Info'), token.info)
Handlers.add("Info", Handlers.utils.hasMatchingTag("Action", "Info"), token.info)

-- Total Supply
Handlers.add('Total-Supply', Handlers.utils.hasMatchingTag('Action', "Total-Supply"), token.totalSupply)
Handlers.add("Total-Supply",
Handlers.utils.hasMatchingTag("Action", "Total-Supply"),
token.totalSupply)

-- Balance
Handlers.add('Balance', Handlers.utils.hasMatchingTag('Action', 'Balance'), balance.balance)
Handlers.add("Balance", Handlers.utils.hasMatchingTag("Action", "Balance"),
balance.balance)

-- Balances
Handlers.add('Balances', Handlers.utils.hasMatchingTag('Action', 'Balances'), balance.balances)
Handlers.add("Balances", Handlers.utils.hasMatchingTag("Action", "Balances"),
balance.balances)

-- Transfer
Handlers.add('Transfer', Handlers.utils.hasMatchingTag('Action', 'Transfer'), transfer.transfer)
Handlers.add("Transfer", Handlers.utils.hasMatchingTag("Action", "Transfer"),
transfer.transfer)

-- Mint
Handlers.add('Mint', Handlers.utils.hasMatchingTag('Action', 'Mint'), mint.mint)
Handlers.add("Mint", Handlers.utils.hasMatchingTag("Action", "Mint"), mint.mint)

-- Burn
Handlers.add('Burn', Handlers.utils.hasMatchingTag('Action', 'Burn'), burn.burn)
Handlers.add("Burn", Handlers.utils.hasMatchingTag("Action", "Burn"), burn.burn)
52 changes: 35 additions & 17 deletions template/ao/src/handlers/balance.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,52 @@ local json = require "json"

local mod = {}


-- Get target balance
---@type HandlerFunction
function mod.balance(msg)
local bal = '0'
local bal = "0"

-- If not Recipient is provided, then return the Senders balance
if (msg.Tags.Recipient and Balances[msg.Tags.Recipient]) then
bal = Balances[msg.Tags.Recipient]
elseif msg.Tags.Target and Balances[msg.Tags.Target] then
bal = Balances[msg.Tags.Target]
elseif Balances[msg.From] then
bal = Balances[msg.From]
-- If not Recipient is provided, then return the Senders balance
if (msg.Tags.Recipient) then
if (Balances[msg.Tags.Recipient]) then
bal = Balances[msg.Tags.Recipient]
end

ao.send({
Target = msg.From,
Balance = bal,
Ticker = Ticker,
Account = msg.Tags.Recipient or msg.From,
Data = bal
elseif msg.Tags.Target and Balances[msg.Tags.Target] then
bal = Balances[msg.Tags.Target]
elseif Balances[msg.From] then
bal = Balances[msg.From]
end
if msg.reply then
msg.reply({
Balance = bal,
Ticker = Ticker,
Account = msg.Tags.Recipient or msg.From,
Data = bal
})
else
Send({
Target = msg.From,
Balance = bal,
Ticker = Ticker,
Account = msg.Tags.Recipient or msg.From,
Data = bal
})
end
end

-- Get balances
---@type HandlerFunction
function mod.balances(msg)
ao.send({ Target = msg.From, Data = json.encode(Balances) })
if msg.reply then
msg.reply({
Data = json.encode(Balances)
})
else
Send({
Target = msg.From,
Data = json.encode(Balances)
})
end
end

return mod
24 changes: 15 additions & 9 deletions template/ao/src/handlers/burn.lua
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
local bint = require('.bint')(256)
local bint = require(".bint")(256)
local utils = require "src.utils.mod"

local mod = {}

function mod.burn(msg)
assert(type(msg.Quantity) == 'string', 'Quantity is required!')
assert(bint(msg.Quantity) <= bint(Balances[msg.From]), 'Quantity must be less than or equal to the current balance!')
assert(type(msg.Quantity) == "string", "Quantity is required!")
assert(bint(msg.Quantity) <= bint(Balances[msg.From]),
"Quantity must be less than or equal to the current balance!")

Balances[msg.From] = utils.subtract(Balances[msg.From], msg.Quantity)
TotalSupply = utils.subtract(TotalSupply, msg.Quantity)

ao.send({
Target = msg.From,
Data = "Successfully burned " .. msg.Quantity
Balances[msg.From] = utils.subtract(Balances[msg.From], msg.Quantity)
TotalSupply = utils.subtract(TotalSupply, msg.Quantity)
if msg.reply then
msg.reply({
Data = "Successfully burned " .. msg.Quantity
})
else
Send({
Target = msg.From,
Data = "Successfully burned " .. msg.Quantity
})
end
end

return mod
Loading

0 comments on commit e4f5f0b

Please sign in to comment.