Yeaptor provides a small CLI and a Move package that make deterministic, admin‑gated deployments of Move code to Aptos resource ("package") accounts straightforward and repeatable.
Core focus in this repository:
- crates/yeaptor — a CLI that turns a declarative
yeaptor.tomlplan into ready‑to‑run Aptos entry‑function JSON payloads. - packages/resource-account-code-deployment — a Move module that deploys/upgrades packages to package accounts derived from (publisher, seed), with admin control and optional freeze.
- Deterministic package account addresses from (publisher, seed) with domain‑separated seeds
- One‑shot publish/upgrade via entry functions
- Admin‑gated operations using aptos_extensions::manageable
- Optional freeze to lock code and revoke management
- Simple, declarative CLI workflow that outputs JSON payloads for
aptos move run
- CLI:
crates/yeaptor(binary name:yeaptor) - Move package:
packages/resource-account-code-deployment(modulera_code_deployment::ra_code_deployment) - Also available (not the focus here):
packages/object-code-deterministic-deploymentpackages/proxy-account
- You describe deployments in
yeaptor.tomlusing logical publisher aliases, a seed, and a list of packages to deploy under the same package account. - The CLI computes the package account address for each deployment via the module’s
create_package_address(publisher, seed)function (domain‑separated). - During build, the CLI injects named addresses so each package’s
address_nameresolves to that resource account address. - For each package, the CLI emits a JSON payload calling
<yeaptor_address>::ra_code_deployment::deploy(seed, metadata, modules). - You submit the JSON payloads in order with Aptos CLI.
- Rust toolchain (stable)
- Aptos CLI installed and configured (profiles, network, etc.)
- From repo root:
cargo install --path crates/yeaptor - Or run without installing:
cargo run -p yeaptor -- <args>
- Bootstrap or reference the
ra_code_deploymentmodule on‑chain- Either publish
packages/resource-account-code-deploymentonce to an address you control, or reuse an existing deployment. Note that the CLI needs this address asyeaptor_addressto invoke thedeploy/batch_deployentry functions.
- Either publish
- Create
yeaptor.toml- Start from
yeaptor.toml.exampleand set:yeaptor_addressto the on‑chain address hostingra_code_deployment.[publishers]mapping for your logical names to addresses.[[deployments]]with a UTF‑8seedand package list.
- Start from
- Generate publish payloads
yeaptor deployment build --config ./yeaptor.toml --out-dir ./deployments
- Submit payloads in order
aptos move run --profile <profile> --json-file ./deployments/<n>-<pkg>.package.json
Keys:
- format_version: Schema version. Use
1. - yeaptor_address: On‑chain address where
ra_code_deploymentis published. - [publishers]: Map of alias -> on‑chain address. Referenced by
deployments.publisher. - [named-addresses] (optional): Extra Move named addresses shared across packages.
- [[deployments]]: Ordered list. Each defines one resource account derived from
(publisher + seed)and its ordered packages.- publisher: Alias from
[publishers]or a literal address string. - seed: UTF‑8 text used to deterministically derive the resource account.
- packages: Array of
{ address_name, path }where:- address_name: Named address used by the package (will resolve to the derived resource account).
- path: Filesystem path to the Move package (containing
Move.toml).
- publisher: Alias from
Example:
format_version = 1
yeaptor_address = "0x<address-hosting-ra_code_deployment>"
[publishers]
yeap-multisig = "0x10"
[named-addresses]
# std = "0x1"
[[deployments]]
publisher = "yeap-multisig"
seed = "core-v1" # UTF-8 only
packages = [
{ address_name = "ra_code_deployment", path = "packages/resource-account-code-deployment" },
{ address_name = "proxy_account", path = "packages/proxy-account" },
]
Generated outputs
- Files are written to
--out-dirin deployment order:<index>-<package>.package.json. - If
--with-eventis provided todeployment build, event files are written under--out-dir/events/<package>.event.json. - An
addresses.tomlwith resolved named addresses is also written to--out-dir. - Each publish file calls:
{
"function_id": "0x<yeaptor_address>::ra_code_deployment::deploy",
"type_args": [],
"args": [
{ "type": "hex", "value": "0x<seed-bytes>" },
{ "type": "hex", "value": "0x<metadata-bcs>" },
{ "type": "hex", "value": ["0x<module-1>", "0x<module-2>", ...] }
]
}Notes
- Order matters: deployments and the packages within them are processed sequentially.
seedmust be UTF‑8 text (not hex). The module applies domain separation internally for deterministic address derivation.address_namemust match the named address used in the package’sMove.toml.yeaptor_addressmust be the on‑chain address hosting thera_code_deploymentmodule.
Turn a declarative yeaptor.toml plan into ready‑to‑run Aptos entry‑function JSON payloads.
- Command
yeaptor deployment build --config ./yeaptor.toml --out-dir ./deployments- Build one package only: add
--package-dir <path/to/package> - Include event definitions alongside payloads: add
--with-event(writes to<out-dir>/events/)
- Outputs
<out-dir>/<index>-<package>.package.jsonper package<out-dir>/events/<package>.event.json(when--with-event)<out-dir>/addresses.tomlresolved named addresses
- Submit payloads
aptos move run --profile <profile> --json-file <out-dir>/<index>-<package>.package.json
Generate per‑package event definition JSON files from compiled Move packages.
- Command
- All from config:
yeaptor event generate --config ./yeaptor.toml --out-dir ./events - Single package:
yeaptor event generate --config ./yeaptor.toml --out-dir ./events --package-dir ./packages/<pkg>
- All from config:
- Output
./events/<package>.event.jsonfiles (array of event definitions with fields/types)
Generate, don’t run, a processor configuration YAML that can be used by a no‑code/indexer pipeline.
- Command
yeaptor processor generate --starting-version <u64> \ --events-dir ./events \ --db_schema ./db_schema.csv \ --event_mapping ./event_mappings.csv \ --output-file ./processor_config.yaml
- Inputs
- Event definitions directory (
--events-dir), typically from “Event generation” ordeployment build --with-event - Database schema CSV (
--db_schema) - Event‑to‑table mapping CSV (
--event_mapping)
- Event definitions directory (
- Output
processor_config.yamlwith:custom_config.db_schema: tables/columnscustom_config.events: event→table/column mappingcustom_config.transaction_metadataandcustom_config.event_metadata
- Notes
- This doesn’t run an indexer; it only produces the config for downstream use.
Deterministic deployment and upgrade of Move packages to package accounts using a publisher‑provided seed (with domain‑separated seeds).
Concepts
- Deterministic address (domain‑separated):
create_package_address(publisher, seed). - Admin model: Uses
aptos_extensions::manageableto gate publish/upgrade to admins. - Capability storage:
PublishPackageCap(stored under the package account) holds theSignerCapabilityto sign upgrades.
Public API
#[view] create_package_address(publisher: address, seed: vector<u8>): address- Deterministically derives the package account address from
(publisher, seed)with domain separation.
- Deterministically derives the package account address from
entry fun create_package_account(publisher: &signer, seed: vector<u8>)- Creates the package account; stores
PublishPackageCapand initializes manageable admin withpublisheras admin.
- Creates the package account; stores
entry fun deploy(publisher: &signer, seed: vector<u8>, metadata_serialized: vector<u8>, code: vector<vector<u8>>)acquiresPublishPackageCap- Ensures the package account exists, then publishes the package to that account (upgrade if already published).
entry fun publish(admin: &signer, metadata_serialized: vector<u8>, code: vector<vector<u8>>, resource_address: address)acquiresPublishPackageCap- Requires admin; publishes/upgrades using the stored capability.
entry fun freeze_package_account(admin: &signer, resource_address: address)acquiresPublishPackageCap- Admin‑gated. Revokes management and removes the stored capability to prevent further publishes/upgrades.
Storage under the package account
PublishPackageCap { cap: SignerCapability }- Manageable admin resource (via
aptos_extensions::manageable)
- Protocol‑owned modules at a stable, pre‑known address per
(publisher, seed) - Managed admin‑gated upgrades during rollout; freeze when finalized
- Multi‑package deployments to a shared resource account
Targets the Aptos mainnet framework specified by each Move.toml. Review, testing, and audits are recommended before production use.
Issues and PRs are welcome. Please include clear repro steps and tests where possible.
Apache‑2.0. See LICENSE.