Skip to content

Presale versioning and activation

The presale guides describe source in blast-v2-move c96cd0d. They cover current source, rather than asserting that a production app uses that ABI. Start with deployment references.

Publishing the versioned package creates an owned blast_presale_package::Bootstrap. It does not create the shared PackageVersion needed to operate presales.

package_admin::wrap(bootstrap, upgrade_cap) validates the matching fresh native capabilities, seals the Publisher and native UpgradeCap in shared PackageAdmin custody, and shares PackageVersion in the same transaction. The cap’s existing upgrade policy is preserved; the recorded activation uses the compatible policy. A dependent package can be published before activation, but cannot create operational presales without that version object.

Protected state-changing calls take the package’s own &PackageVersion immediately after their first object argument. It is normally a read-only shared input. The examples use PACKAGE_VERSION for its object ID; that is an object, not the numeric generation.

Call family Shape, omitting later arguments
Create through a venue bluefin::new(treasury_cap, package_version, ...) or cetus::new(treasury_cap, package_version, ...)
Configure or finalize set_supply(initializer, package_version, ...), finalize(initializer, package_version, currency)
Open, commit, settle, claim share(presale, package_version, ...), commit_open(presale, package_version, ...), settle(presale, package_version, clock), claim(presale, package_version, participant, clock)
Migrate or pay fees bluefin::migrate(presale, package_version, ...), pay_protocol_fees_with_partner(presale, package_version, ...)
Vaults, policies and rewards Version immediately after the vault, policy, round, or other first object; consult the exact function signature.

Pure value constructors (bps::new, eligibility, recipients, vesting terms, fee splits), getters, and destroy_cap take no version object. A blanket insertion into every Move call is incorrect. The generated presale reference lists every signature.

Historical unversioned deployments take none of these added version arguments. Read their frozen ABI; do not delete an argument from a current-source transaction and assume every other signature is identical.

Each protected mutation checks the active generation before effects. A stale or future generation aborts in blast_admin::operational_version; decode that module’s error as well as presale-local errors.

The presale UpgradeAdmin authorizes an exact package digest through the shared ACL. Upgrade commit and generation advancement happen together through commit_upgrade_and_advance; the successor bytecode must target the exact next generation. After cutover, use the new call target and the canonical version object. Compatible upgrades can change logic; they do not make the package permanently immutable.

The current code has no ordinary pause, commitment withdrawal, or LP withdrawal operation. Administrators’ upgrade authority is a separate trust assumption. Older dependency-only publications have a different restriction; see Safety.

Sources: blast_presale_package.move, package_admin.move, and the activation-test record.