Skip to content

Commit

Permalink
chore(tools): update tooling for aos-ant
Browse files Browse the repository at this point in the history
  • Loading branch information
Atticus committed Jun 14, 2024
1 parent d775991 commit d4dc843
Show file tree
Hide file tree
Showing 14 changed files with 313 additions and 45 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ luacov-html
*.gz
luacov.stats.out
process.wasm
dist
File renamed without changes.
61 changes: 57 additions & 4 deletions ant/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,74 @@ busted .

### Building the AOS code

#### Build

This bundles the ant-aos code and outputs it to `dist` folder. This can then be used to send to the `Eval` method on AOS to load the ANT source code.

```bash
yarn build:aos-ant
```

#### Publish

Ensure that in the `tools` directory you place you Arweave JWK as `key.json`

```bash
yarn publish:aos-ant
```

#### Load

This will load an AOS module into the loader, followed by the bundled aos-ant Lua file to verify that it is a valid build.

```bash
yarn load:aos-ant
```

#### Spawn

this will spawn an aos process and load the bundled lua code into it.

```bash
yarn spawn:aos-ant
```

This will deploy the bundled lua file to arweave as an L1 transaction, so your wallet will need AR to pay the gas.

### Building the custom module

Using the ao-dev-cli.

#### Build

This will compile the standalone ANT module to wasm, as a file named `process.wasm` and loads the module in [AO Loader](https://github.com/permaweb/ao/tree/main/loader) to validate the WASM program is valid.

```bash
yarn build
yarn build:module
```

#### Publish

To publish the module:
Here we are manually setting the values - if you do not, it will not run. Replace the path to your JSON wallet to be relative to your location of it.
Publishes the custom ANT module to arweave - requires you placed your JWK in the `tools` directory. May require AR in the wallet to pay gas.

```sh
ao publish process.wasm -w ../../key.json --tag="Memory-Limit" --value="1-gb" --tag="Compute-Limit" --value="9000000000000"
yarn publish:module
```

#### Load

Loads the module in [AO Loader](https://github.com/permaweb/ao/tree/main/loader) to validate the WASM program is valid.

```bash
yarn load:module
```

Requires `build:module` to have been called so that `process.wasm` exists.

#### Spawn

Spawns a process with the `process.wasm` file.

```bash
yarn spawn:module
```
20 changes: 13 additions & 7 deletions ant/package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
{
"type": "module",
"scripts": {
"build:module": "cd src && ao build && cd .. && yarn load-process",
"publish:module": "cd src && ao publish process.wasm -w ../tools/key.json --tag=\"Memory-Limit\" --value=\"1-gb\" --tag=\"Compute-Limit\" --value=\"9000000000000\" && cd ..",
"load:module": "node tools/load-module.cjs",
"spawn:module": "node tools/spawn-module.cjs",
"build:aos-ant": "node tools/bundle-aos-ant.cjs",
"publish:aos-ant": "node tools/bundle-aos-ant.cjs && node tools/publish-aos-ant.cjs",
"load:aos-ant": "node tools/bundle-aos-ant.cjs && node tools/load-aos-ant.cjs",
"spawn:aos-ant": "node tools/spawn-aos-ant.cjs"
},
"dependencies": {
"@permaweb/ao-loader": "^0.0.35",
"@permaweb/aoconnect": "^0.0.55",
"arweave": "^1.15.1"
},
"type": "module",
"scripts": {
"build": "cd src && ao build && cd .. && yarn load-process",
"deploy": "cd src && ao publish process.wasm -w ../tools/key.json --tag=\"Memory-Limit\" --value=\"1-gb\" --tag=\"Compute-Limit\" --value=\"9000000000000\" && cd ..",
"load-process": "node tools/load-process.cjs",
"spawn": "node tools/spawn-ant.cjs",
"publish:aos-ant": "node tools/bundle-aos-lua.cjs"
"devDependencies": {
"prettier": "^3.3.2"
}
}
24 changes: 24 additions & 0 deletions ant/tools/bundle-aos-ant.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
const path = require('path');
const fs = require('fs');
const { bundle } = require('./lua-bundler.cjs');

async function main() {
console.log('Bundling Lua...');

const bundledLua = bundle(path.join(__dirname, '../src/aos-ant.lua'));

if (!fs.existsSync(path.join(__dirname, '../dist'))) {
fs.mkdirSync(path.join(__dirname, '../dist'));
}

fs.writeFileSync(
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
bundledLua,
);
console.log(
'Bundled Lua written to:',
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
);
}

main();
Binary file not shown.
96 changes: 96 additions & 0 deletions ant/tools/load-aos-ant.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
const AoLoader = require('@permaweb/ao-loader');
const fs = require('fs');
const path = require('path');

const address = ''.padEnd(43, 'a');
/* ao READ-ONLY Env Variables */
const env = {
Process: {
Id: ''.padEnd(43, '1'),
Owner: address,
Tags: [{ name: 'Authority', value: 'XXXXXX' }],
},
Module: {
Id: ''.padEnd(43, '1'),
Tags: [{ name: 'Authority', value: 'YYYYYY' }],
},
};

async function main() {
const wasmBinary = fs.readFileSync(
path.join(
__dirname,
'fixtures/aos-9afQ1PLf2mrshqCTZEzzJTR2gWaC9zNPnYgYEqg1Pt4.wasm',
),
);
// read the lua code from the dist
const luaCode = fs.readFileSync(
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
'utf-8',
);
// for initializing ant state
const initState = JSON.stringify({
balances: { [address]: 1 },
controllers: [address],
name: 'ANT-ARDRIVE',
owner: address,
records: {
'@': {
transactionId: 'UyC5P5qKPZaltMmmZAWdakhlDXsBF6qmyrbWYFchRTk',
ttlSeconds: 3600,
},
},
ticker: 'ANT',
});
// Create the handle function that executes the Wasm
const options = {
format: 'wasm32-unknown-emscripten',
inputEncoding: 'JSON-1',
outputEncoding: 'JSON-1',
memoryLimit: '524288000', // in bytes
computeLimit: (9e12).toString(),
extensions: [],
};

const testCases = [
['Eval', { Module: ''.padEnd(43, '1') }, luaCode],
['Initialize-State', {}, initState],
['Info', {}],
['Get-Records', {}],
['Transfer', { Recipient: 'iKryOeZQMONi2965nKz528htMMN_sBcjlhc-VncoRjA' }],
];

const handle = await AoLoader(wasmBinary, options);
// memory dump of the evaluated program
let programState = undefined;
const defaultHandleOptions = {
Id: ''.padEnd(43, '1'),
['Block-Height']: '1',
// important to set the address so that that `Authority` check passes. Else the `isTrusted` with throw an error.
Owner: address,
Module: 'ANT',
Target: ''.padEnd(43, '1'),
From: address,
};

for (const [method, args, data] of testCases) {
const tags = args
? Object.entries(args).map(([key, value]) => ({ name: key, value }))
: [];
// To spawn a process, pass null as the buffer
const result = await handle(
programState,
{
...defaultHandleOptions,
Tags: [...tags, { name: 'Action', value: method }],
Data: data,
},
env,
);

programState = result.Memory;
console.log(method);
console.dir(result.Messages[0]?.Data, { depth: null });
}
}
main();
File renamed without changes.
24 changes: 3 additions & 21 deletions ant/tools/bundle-aos-lua.cjs → ant/tools/publish-aos-ant.cjs
Original file line number Diff line number Diff line change
@@ -1,36 +1,19 @@
const Arweave = require('arweave');
const path = require('path');
const fs = require('fs');
const Arweave = require('arweave');
const { bundle } = require('./lua-bundler.cjs');

const arweave = Arweave.init({
host: 'arweave.net',
port: 443,
protocol: 'https',
});

async function main() {
console.log('Bundling Lua...');

const bundledLua = bundle(path.join(__dirname, '../src/aos-ant.lua'));

if (!fs.existsSync(path.join(__dirname, '../dist'))) {
fs.mkdirSync(path.join(__dirname, '../dist'));
}

fs.writeFileSync(
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
bundledLua,
);
console.log(
'Bundled Lua written to:',
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
);

const wallet = fs.readFileSync(path.join(__dirname, 'key.json'), 'utf-8');
const jwk = JSON.parse(wallet);
const address = await arweave.wallets.jwkToAddress(jwk);

console.log(`Publish AOS ANT Lua with address ${address}`);

const tx = await arweave.createTransaction({ data: bundledLua }, jwk);
tx.addTag('App-Name', 'AOS-ANT-LUA');
tx.addTag('App-Version', '0.0.1');
Expand All @@ -41,5 +24,4 @@ async function main() {

console.log('Transaction ID:', tx.id);
}

main();
114 changes: 114 additions & 0 deletions ant/tools/spawn-aos-ant.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
const { connect, createDataItemSigner } = require('@permaweb/aoconnect');
const fs = require('fs');
const path = require('path');
const Arweave = require('arweave');

const arweave = Arweave.init({
host: 'arweave.net',
port: 443,
protocol: 'https',
});

const ao = connect({
GATEWAY_URL: 'https://arweave.net',
});
const moduleId = '9afQ1PLf2mrshqCTZEzzJTR2gWaC9zNPnYgYEqg1Pt4';
const scheduler = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';

async function main() {
const luaCode = fs.readFileSync(
path.join(__dirname, '../dist/aos-ant-bundled.lua'),
'utf-8',
);

const wallet = fs.readFileSync(path.join(__dirname, 'key.json'), 'utf-8');
const address = await arweave.wallets.jwkToAddress(JSON.parse(wallet));
const signer = createDataItemSigner(JSON.parse(wallet));

const initState = JSON.stringify({
balances: { [address]: 1 },
controllers: [address],
name: 'ANT-ARDRIVE',
owner: address,
records: {
'@': {
transactionId: 'UyC5P5qKPZaltMmmZAWdakhlDXsBF6qmyrbWYFchRTk',
ttlSeconds: 3600,
},
},
ticker: 'ANT',
});

// const processId = await ao.spawn({
// module: moduleId,
// scheduler,
// signer,
// });
const processId = '-IUtRutnBYxqjcHsgmBQUWeRHYV5knX8Zjgoq3EuEY0';

console.log('Process ID:', processId);
console.log('Waiting 20 seconds to ensure process is readied.');
await new Promise((resolve) => setTimeout(resolve, 20_000));
console.log('Loading ANT Lua code...');

// const messageId = await ao.message({
// process: processId,
// data: luaCode,
// tags: [{ name: 'Action', value: 'Eval' }],
// signer,
// });

// console.log('Eval called. Message ID:', messageId);
// console.log('Running test cases via dryrun');

const testCases = [
['Info', {}],
['Set-Controller', { Controller: ''.padEnd(43, '1') }],
['Remove-Controller', { Controller: ''.padEnd(43, '1') }],
['Set-Name', { Name: 'Test Name' }],
['Set-Ticker', { Ticker: 'TEST' }],
[
'Set-Record',
{
'Transaction-Id': ''.padEnd(43, '1'),
'TTL-Seconds': '1000',
'Sub-Domain': '@',
},
],
[
'Set-Record',
{
'Transaction-Id': ''.padEnd(43, '1'),
'TTL-Seconds': '1000',
'Sub-Domain': 'bob',
},
],
['Remove-Record', { 'Sub-Domain': 'bob' }],
['Balance', {}],
['Balance', { Recipient: address }],
['Balances', {}],
['Get-Controllers', {}],
['Get-Records', {}],
['Get-Record', { 'Sub-Domain': '@' }],
['Initialize-State', {}, initState],
['Transfer', { Recipient: 'ZjmB2vEUlHlJ7-rgJkYP09N5IzLPhJyStVrK5u9dDEo' }],
];

for (const [method, args, data] of testCases) {
const tags = args
? Object.entries(args).map(([key, value]) => ({ name: key, value }))
: [];
const result = await ao.message({
process: processId,
tags: [...tags, { name: 'Action', value: method }],
data,
signer,
// Owner: address,
// From: address,
});

console.dir({ method, result }, { depth: null });
}
}

main();
File renamed without changes.
Loading

0 comments on commit d4dc843

Please sign in to comment.