npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ao-deploy

v0.10.1

Published

A package for deploying AO contracts. Supports both Node.js and web environments.

Downloads

371

Readme

ao-deploy

npm version npm downloads JSDocs License

A package for deploying AO contracts with support for both Node.js and web environments.

Table of Contents

Features

  • 🚀 Build and deploy contracts with ease
  • 🌐 Cross-platform support
  • 🔐 Browser wallet support (Wander or other compatible wallet) for secure signing
  • 🔧 Custom LUA_PATH support
  • 📦 LuaRocks package support
  • ⚙️ Flexible deployment configuration
  • 🔄 Concurrent deployments with retry options
  • 📝 Contract minification and transformation
  • 🧩 Blueprint support
  • 🛠️ CLI and API interfaces

Installation

Install Locally

npm install ao-deploy --save-dev
pnpm add ao-deploy --save-dev
yarn add ao-deploy --dev
bun add ao-deploy --dev

Use without installation

You can use ao-deploy without installing it locally by using package runners:

Using npx (npm):

npx ao-deploy process.lua -n tictactoe -w wallet.json

Using bunx (bun):

bunx ao-deploy process.lua -n tictactoe -w wallet.json

Using pnpm dlx (pnpm):

pnpm dlx ao-deploy process.lua -n tictactoe -w wallet.json

Using yarn dlx (yarn):

yarn dlx ao-deploy process.lua -n tictactoe -w wallet.json

Optional Dependencies

If you plan to use the --minify option, you'll need to install lua-format:

npm install lua-format --save-dev   # npm
pnpm add lua-format --save-dev      # pnpm
yarn add lua-format --dev           # yarn
bun add lua-format --dev           # bun

Usage

CLI

[!Note] The CLI is only available in Node.js environments. For web environments, use the API directly.

Usage: ao-deploy [options] <contractOrConfigPath>

Deploy AO contracts using a CLI.

Arguments:
  contractOrConfigPath          Path to the main contract file or deployment configuration.

Options:
  -V, --version                 output the version number
  -n, --name [name]             Specify the process name. (default: "default")
  -w, --wallet [wallet]         Path to the wallet JWK file. (Autogenerated if not passed)
  --use-browser-wallet          Use browser wallet (Wander or other compatible wallet) for signing transactions.
  --browser [browser]           Browser to use for signing transactions. (default: "system default")
  --browser-profile [profile]   Browser profile to use for signing transactions.
  -l, --lua-path [luaPath]      Specify the Lua modules path seperated by semicolon.
  -d, --deploy [deploy]         List of deployment configuration names, separated by commas.
  -b, --build [build]           List of deployment configuration names, separated by commas.
  -s, --scheduler [scheduler]   Scheduler to be used for the process. (default: "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA")
  -m, --module [module]         Module source for spawning the process.
  -c, --cron [interval]         Cron interval for the process (e.g. 1-minute, 5-minutes).
  -t, --tags [tags...]          Additional tags for spawning the process.
  -p, --process-id [processId]  Specify process Id of existing process.
  --build-only                  Bundle the contract into a single file and store it in the process-dist directory.
  --out-dir [outDir]            Used with --build-only to output the single bundle contract file to a specified directory.
  --gateway-url [url]           Custom Gateway URL to connect to. (default: "https://arweave.net")
  --cu-url [url]                Custom Compute Unit (CU) URL to connect to. (default: "https://cu.ao-testnet.xyz")
  --mu-url [url]                Custom Messenger Unit (MU) URL to connect to. (default: "https://mu.ao-testnet.xyz")
  --concurrency [limit]         Concurrency limit for deploying multiple processes. (default: 5)
  --sqlite                      Use sqlite aos module when spawning new process.
  --retry-count [count]         Number of retries for deploying contract. (default: 3)
  --retry-delay [delay]         Delay between retries in milliseconds. (default: 1000)
  --minify                      Reduce the size of the contract before deployment. (default: false)
  --on-boot                     Load contract when process is spawned. (default: false)
  --blueprints [blueprints...]  Blueprints to use for the contract.
  --force-spawn                 Force spawning a new process without checking for existing ones. (default: false)
  -h, --help                    display help for command

Basic Deployment

ao-deploy process.lua -n tictactoe -w wallet.json --tags name1:value1 name2:value2

Advanced Options

Minify Contract

[!Note] Make sure to install lua-format as mentioned in Optional Dependencies section.

ao-deploy process.lua -n tictactoe -w wallet.json --tags name1:value1 name2:value2 --minify
Deploy with On-Boot
ao-deploy process.lua -n tictactoe -w wallet.json --tags name1:value1 name2:value2 --on-boot
Deploy Blueprints
ao-deploy -n tictactoe -w wallet.json --blueprints arns token

Browser Wallet

[!Important] When deploying multiple contracts with browser wallets, the first browser configuration found in the deployment configs will be used for all browser deployments. This ensures a single browser session is shared across all deployments.

Use your browser wallet for secure transaction signing:

ao-deploy process.lua --use-browser-wallet -n MyProcess
Advanced Browser Configuration
# Use specific browser
ao-deploy process.lua --use-browser-wallet --browser firefox -n MyProcess

# Use specific browser profile
ao-deploy process.lua --use-browser-wallet --browser chrome --browser-profile "Profile 1" -n MyProcess
Using a Configuration File
export default defineConfig({
  main: {
    name: "my-process",
    contractPath: "./src/main.lua",
    wallet: "browser", // Use browser wallet for signing
    browserConfig: {
      browser: "chrome", // Optional: specify browser (chrome, firefox, edge, brave, safari, opera, zen, vivaldi)
      browserProfile: "Profile 1" // Optional: specify browser profile
    }
  },
});

Then deploy with:

ao-deploy ao.config.ts

Configuration File

[!Note] Configuration files are only supported in Node.js environments. For web environments, use the API directly with individual contract configurations.

Deploy multiple contracts using a configuration file:

// aod.config.ts
import { defineConfig } from "ao-deploy";

const wallet = "wallet.json";
const luaPath = "./?.lua;./src/?.lua";

const config = defineConfig({
  contract_1: {
    luaPath,
    name: `contract-1`,
    contractPath: "contract-1.lua",
    wallet,
    minify: true // Minify the contract before deployment
  },
  contract_2: {
    luaPath,
    name: `contract-2`,
    contractPath: "contract-2.lua",
    wallet: "browser", // Use browser wallet
    browserConfig: {
      browser: "brave", // Use Brave browser
      browserProfile: "Work" // Use profile 1
    },
    // Custom source transformer function
    contractTransformer: (source) => {
      // Example: Remove all comments from the source code
      return source.replace(/\s*--.*\n/g, "");
    }
  },
  contract_3: {
    luaPath,
    name: `contract-3`,
    contractPath: "contract-3.lua",
    wallet
  }
});

export default config;

Deploy all specified contracts:

ao-deploy aod.config.ts

Deploy specific contracts:

ao-deploy aod.config.ts --deploy=contract_1,contract_3

Build Contracts

[!Note] Contract building is only available in Node.js environments. For web environments, you need to bundle your contracts using your own build process.

Build to Default Directory
aod src/process.lua -n my-process --build-only
Build to Custom Directory
aod src/process.lua -n my-process --build-only --out-dir <PATH>
aod src/process.lua -n my-process --build-only --out-dir ./dist
Build Using Configuration File

[!Note] Configuration-based building is only available in Node.js environments.

To Build contracts using config, take a look at below provided example

Here is an example using a deployment configuration:

// aod.config.ts
import { defineConfig } from "ao-deploy";

const luaPath = "./?.lua;./src/?.lua";

const config = defineConfig({
  contract_1: {
    luaPath,
    name: `contract-1`,
    contractPath: "contract-1.lua",
    outDir: "./dist"
  },
  contract_2: {
    luaPath,
    name: `contract-2`,
    contractPath: "contract-2.lua",
    outDir: "./dist"
  },
  contract_3: {
    luaPath,
    name: `contract-3`,
    contractPath: "contract-3.lua",
    outDir: "./dist"
  }
});

export default config;

Build all specified contracts:

ao-deploy aod.config.ts --build-only

Build specific contracts:

ao-deploy aod.config.ts --build=contract_1,contract_3 --build-only

[!Note] A wallet is generated and saved if not passed.

Retrieve the generated wallet path:

node -e "const path = require('path'); const os = require('os'); console.log(path.resolve(os.homedir(), '.aos.json'));"

API Usage

deployContract

Deploy a single contract using the deployContract function.

Basic Deployment (Node.js)
import { deployContract } from "ao-deploy";

async function main() {
  try {
    const { messageId, processId } = await deployContract({
      name: "demo",
      wallet: "wallet.json",
      contractPath: "process.lua",
      tags: [{ name: "Custom", value: "Tag" }],
      retry: {
        count: 10,
        delay: 3000
      }
    });
    const processUrl = `https://www.ao.link/#/entity/${processId}`;
    console.log(`Deployed Process: ${processUrl}`);
    if (messageId) {
      const messageUrl = `https://www.ao.link/#/message/${messageId}`;
      console.log(`Deployment Message: ${messageUrl}`);
    }
  } catch (error: any) {
    console.log(
      `Deployment failed!: ${error?.message ?? "Failed to deploy contract!"}\n`
    );
  }
}

main();
Browser Wallet (Node.js)
import { deployContract } from "ao-deploy";

async function main() {
  try {
    const { messageId, processId } = await deployContract({
      name: "demo",
      wallet: "browser", // Use browser wallet
      contractPath: "process.lua",
      browserConfig: {
        browser: "chrome", // Optional: specify browser
        browserProfile: "Profile 1" // Optional: specify browser profile
      },
      tags: [{ name: "Custom", value: "Tag" }],
      retry: {
        count: 10,
        delay: 3000
      }
    });
    const processUrl = `https://www.ao.link/#/entity/${processId}`;
    console.log(`Deployed Process: ${processUrl}`);
    if (messageId) {
      const messageUrl = `https://www.ao.link/#/message/${messageId}`;
      console.log(`Deployment Message: ${messageUrl}`);
    }
  } catch (error: any) {
    console.log(
      `Deployment failed!: ${error?.message ?? "Failed to deploy contract!"}\n`
    );
  }
}

main();
Web Deployment

[!Note] For web/browser environments, you need to provide the contract source directly since file system access is not available.

import { deployContract } from "ao-deploy/web";

async function main() {
  try {
    // Contract source as a string (loaded from your build process, CDN, etc.)
    // Simple AO process that responds to ping messages with "pong"
    const contractSrc = `
Handlers.add("ping", function(msg)
  return ao.send({
    Action = "Pong",
    Target = msg.From,
    Data = "pong"
  })
end)
    `;

    const { messageId, processId } = await deployContract({
      name: "web-demo",
      contractSrc: contractSrc,
      tags: [{ name: "Environment", value: "Web" }],
      retry: {
        count: 5,
        delay: 2000
      }
    });
    
    const processUrl = `https://www.ao.link/#/entity/${processId}`;
    console.log(`Deployed Process: ${processUrl}`);
    if (messageId) {
      const messageUrl = `https://www.ao.link/#/message/${messageId}`;
      console.log(`Deployment Message: ${messageUrl}`);
    }
  } catch (error: any) {
    console.log(
      `Deployment failed!: ${error?.message ?? "Failed to deploy contract!"}\n`
    );
  }
}

main();
Parameters Reference

The deployContract function accepts the following parameters within the DeployArgs object:

Common Parameters (Node.js & Web):

  • name (optional): The process name to spawn. Defaults to "default".
  • contractSrc (optional): The contract source code as a string. Required for web environments.
  • module (optional): The module source to use. Defaults to fetching from the AOS's GitHub repository.
  • scheduler (optional): The scheduler to use for the process. Defaults to _GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA.
  • tags (optional): Additional tags to use for spawning the process.
  • cron (optional): The cron interval for the process, e.g., "1-minute", "5-minutes". Use format interval-(second, seconds, minute, minutes, hour, hours, day, days, month, months, year, years, block, blocks, Second, Seconds, Minute, Minutes, Hour, Hours, Day, Days, Month, Months, Year, Years, Block, Blocks)
  • retry (optional): Retry options with count and delay properties. By default, it will retry up to 3 times with a 1000 milliseconds delay between attempts.
  • processId (optional): The process id of existing process.
  • minify (optional): Reduce the size of the contract before deployment.
  • contractTransformer (optional): Custom function to transform source code before deployment.
  • onBoot (optional): Load contract when process is spawned. (default: false)
  • silent (optional): Disable logging to console. (default: false)
  • blueprints (optional): Blueprints to use for the contract.
  • forceSpawn (optional): Force spawning a new process without checking for existing ones. (default: false)

Node.js Only Parameters:

  • contractPath: The path to the contract's main file. Required for Node.js when contractSrc is not provided.
  • wallet (optional): The wallet path, JWK itself, or "browser" to use browser wallet (Autogenerated if not passed).
  • luaPath (optional): The path to the Lua modules seperated by semicolon.
  • browserConfig (optional): Browser configuration for browser wallet usage.
    • browser (optional): Browser to use ("chrome", "firefox", "edge", "brave", "safari", "opera", "zen", "vivaldi", or custom string).
    • browserProfile (optional): Browser profile to use for signing transactions.

[!Note] In web environments, you must provide contractSrc directly as a string. The contractPath, wallet, and luaPath parameters are not supported in web environments.

deployContracts

Deploy multiple contracts concurrently using the deployContracts function.

Multiple Contracts (Node.js)
import { deployContracts } from "ao-deploy";

async function main() {
  try {
    const results = await deployContracts(
      [
        {
          name: "demo1",
          wallet: "wallet.json",
          contractPath: "process1.lua",
          tags: [{ name: "Custom", value: "Tag" }],
          retry: {
            count: 10,
            delay: 3000
          }
        },
        {
          name: "demo2",
          wallet: "wallet.json",
          contractPath: "process2.lua",
          tags: [{ name: "Custom", value: "Tag" }],
          retry: {
            count: 10,
            delay: 3000
          }
        }
      ],
      2
    );
    results.forEach((result, idx) => {
      if (result.status === "fulfilled") {
        const { processId, messageId } = result.value;
        const processUrl = `https://www.ao.link/#/entity/${processId}`;
        console.log(`Deployed Process: ${processUrl}`);
        if (messageId) {
          const messageUrl = `https://www.ao.link/#/message/${messageId}`;
          console.log(`Deployment Message: ${messageUrl}`);
        }
      } else {
        console.log(`Failed to deploy contract!: ${result.reason}\n`);
      }
    });
  } catch (error: any) {
    console.log(
      `Deployment failed!: ${error?.message ?? "Failed to deploy contract!"}\n`
    );
  }
}

main();
Multiple Contracts (Web)

[!Note] For web/browser environments, you need to provide the contract source directly since file system access is not available.

import { deployContracts } from "ao-deploy/web";

async function main() {
  try {
    const contract1Src = `
-- Simple counter process
local count = 0

Handlers.add("increment", function(msg)
  count = count + 1
  return ao.send({
    Action = "Count",
    Target = msg.From,
    Data = tostring(count)
  })
end)
    `;
    
    const contract2Src = `
-- Simple echo process
Handlers.add("echo", function(msg)
  return ao.send({
    Action = "Echo",
    Target = msg.From,
    Data = msg.Data or "No data provided"
  })
end)
    `;

    const results = await deployContracts(
      [
        {
          name: "web-demo1",
          contractSrc: contract1Src,
          tags: [{ name: "Environment", value: "Web" }],
          retry: {
            count: 5,
            delay: 2000
          }
        },
        {
          name: "web-demo2", 
          contractSrc: contract2Src,
          tags: [{ name: "Environment", value: "Web" }],
          retry: {
            count: 5,
            delay: 2000
          }
        }
      ],
      2
    );
    
    results.forEach((result, idx) => {
      if (result.status === "fulfilled") {
        const { processId, messageId } = result.value;
        const processUrl = `https://www.ao.link/#/entity/${processId}`;
        console.log(`Deployed Process ${idx + 1}: ${processUrl}`);
        if (messageId) {
          const messageUrl = `https://www.ao.link/#/message/${messageId}`;
          console.log(`Deployment Message: ${messageUrl}`);
        }
      } else {
        console.log(`Failed to deploy contract ${idx + 1}!: ${result.reason}\n`);
      }
    });
  } catch (error: any) {
    console.log(
      `Deployment failed!: ${error?.message ?? "Failed to deploy contract!"}\n`
    );
  }
}

main();

Related

Author

👤 Pawan Paudel

🤝 Contributing

Contributions, issues and feature requests are welcome! \ Feel free to check issues page.

Show your support

Give a ⭐️ if this project helped you!

Copyright © 2024 Pawan Paudel.