diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..8c2c3dc --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,30 @@ +name: Deploy AOS Process + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: ⬇️ Checkout repo + uses: actions/checkout@v4 + + - name: ⎔ Setup node + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: 📥 Download deps + working-directory: deploy + run: | + npm i + + - name: Deploy AOS Process + working-directory: deploy + run: node index.js + env: + KEYFILE: ${{ secrets.KEYFILE }} + AOS: ${{ secrets.AOS }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/AOS-SQLITE.wasm b/AOS-SQLITE.wasm new file mode 100644 index 0000000..858a5c0 Binary files /dev/null and b/AOS-SQLITE.wasm differ diff --git a/AOS.wasm b/AOS.wasm new file mode 100644 index 0000000..df6cd1e Binary files /dev/null and b/AOS.wasm differ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ddd03a3 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 permaweb + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..af5545f --- /dev/null +++ b/README.md @@ -0,0 +1,52 @@ +# AOS Test Kit Template + +This is a simple github template repo that can be used to build and maintain AOS processes. +It is setup to test locally out of the box, deploy when using trunk-based deployment. + +## How it works? + +You can create a new repo with this template and then utilize TDD to construct your AOS process, +step by step, test by test. This workflow gives you a nice developer experience and an extremely +easy way to test and publish your code. + +## First Test + +In test/main.test.js after the load source test, create a test that designs a prompt function. + +```js +test('create a prompt', async () => { + const result = await Send({Action: 'Eval', Data: 'Prompt = function () return "hi> " end' }) + assert.equal(result.prompt, 'hi> ') +}) +``` + +Save then run `npm t` + +More Examples coming soon... + +## Manually Deploy + +``` +npm i --no-fund -g https://get_ao.g8way.io +aos --load src/main.lua +``` + +## Deploy Setup + +In you github repo, you need to setup a few secrets: + +* Your Process Identifier `AOS` +* Your Deployment Key `KEYFILE` (you want to base64 encode it) + +> NOTE: Don't have a deployment key, use `~/.aos.json` + +## CONTRIBUTIONS + +If you like this approach to building AOS processes, and have suggestions to make improves please +submit issues or PRs. But lets keep it simple and easy to use. + +### Principles + +* Should be easy to use +* Should emulate typing commands in the aos console +* Should make testing fun with AOS \ No newline at end of file diff --git a/deploy/publish.js b/deploy/publish.js new file mode 100644 index 0000000..fed875e --- /dev/null +++ b/deploy/publish.js @@ -0,0 +1,35 @@ +// Deploy to AO +import { connect, createDataItemSigner } from '@permaweb/aoconnect' +import fs from 'fs' + +const AOS = process.env.AOS +const lua = fs.readFileSync('../src/main.lua', 'utf-8') +const keyfile = process.env.KEYFILE +const jwk = JSON.parse(atob(keyfile)) + + +async function main() { + const { message, result } = connect() + + const messageId = await message({ + process: AOS, + signer: createDataItemSigner(jwk), + tags: [ + { name: 'Action', value: 'Eval' } + ], + data: lua + }) + + const res = await result({ + process: AOS, + message: messageId + }) + + if (res?.Output?.data) { + console.log('Successfully published AOS process ', messageId) + } else { + console.error(res?.Error || 'Unknown error occured deploying AOS') + } +} + +main() \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..ffc7cc3 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "ao-test-kit", + "type": "module", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "node --test test" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@permaweb/ao-loader": "^0.0.26" + } +} diff --git a/src/main.lua b/src/main.lua new file mode 100644 index 0000000..1a5a117 --- /dev/null +++ b/src/main.lua @@ -0,0 +1 @@ +1 + 1 \ No newline at end of file diff --git a/test/aos.helper.js b/test/aos.helper.js new file mode 100644 index 0000000..04eced6 --- /dev/null +++ b/test/aos.helper.js @@ -0,0 +1,64 @@ +import AoLoader from '@permaweb/ao-loader' +import fs from 'fs' + +const aos = fs.readFileSync(process.env.WASM || './AOS.wasm') +const format = 'wasm32-unknown-emscripten' +let memory = null + +export async function Send(DataItem) { + + const msg = Object.keys(DataItem).reduce(function (di, k) { + if (di[k]) { + di[k] = DataItem[k] + } else { + di.Tags = di.Tags.concat([{ name: k, value: DataItem[k] }]) + } + return di + }, createMsg()) + + const handle = await AoLoader(aos, { format }) + const env = createEnv() + + const result = await handle(memory, msg, env) + if (result.Error) { + return 'ERROR: ' + JSON.stringify(result.Error) + } + memory = result.Memory + + return { Messages: result.Messages, Spawns: result.Spawns, Output: result.Output, Assignments: result.Assignments } +} + +function createMsg() { + return { + Id: '1234', + Target: 'AOS', + Owner: 'OWNER', + From: 'OWNER', + Data: '1984', + Tags: [], + 'Block-Height': '1', + Timestamp: Date.now(), + Module: '4567' + } +} + +function createEnv() { + return { + Process: { + Id: '9876', + Tags: [ + { name: 'Data-Protocol', value: 'ao' }, + { name: 'Variant', value: 'ao.TN.1' }, + { name: 'Type', value: 'Process' } + ] + }, + Module: { + Id: '4567', + Tags: [ + { name: 'Data-Protocol', value: 'ao' }, + { name: 'Variant', value: 'ao.TN.1' }, + { name: 'Type', value: 'Module' } + ] + } + } +} \ No newline at end of file diff --git a/test/main.test.js b/test/main.test.js new file mode 100644 index 0000000..aa01fbe --- /dev/null +++ b/test/main.test.js @@ -0,0 +1,12 @@ +import { test } from 'node:test' +import * as assert from 'node:assert' +import { Send } from './aos.helper.js' +import fs from 'node:fs' + +test('load source', async () => { + const code = fs.readFileSync('./src/main.lua', 'utf-8') + const result = await Send({ Action: "Eval", Data: code }) + + assert.equal(result.Output.data.output, 2) + +})