From aptos-agent-skills
Safely deploys Move contracts to Aptos devnet, testnet, or mainnet with pre-deployment checklist for security audits, tests, code quality, and config.
npx claudepluginhub aptos-labs/aptos-agent-skills --plugin aptos-agent-skillsThis skill uses the workspace's default tool permissions.
This skill guides safe deployment of Move contracts to Aptos networks. **Always deploy to testnet before mainnet.**
Generates secure Aptos Move V2 smart contracts with Object model, Digital Asset NFT integration, security patterns, and storage type guidance for collections, marketplaces, DAOs, staking.
Develops secure smart contracts by integrating OpenZeppelin libraries for ERC tokens, access control, pausability, governance, and accounts. Supports Solidity, Cairo, Stylus, Stellar.
Deploys, imports, interacts with, and monitors smart contracts using Circle SCP SDKs. Supports bytecode, ERC-20/721/1155/Airdrop templates, ABI read/write calls, and webhook events.
Share bugs, ideas, or general feedback.
This skill guides safe deployment of Move contracts to Aptos networks. Always deploy to testnet before mainnet.
Before deploying, verify ALL items:
security-audit skill)aptos move test --coverageaptos move testaptos move compilemy_addr = "_"There are TWO ways to deploy contracts. For modern object-based contracts, use deploy-object:
✅ CORRECT: Object Deployment (Modern Pattern)
aptos move deploy-object \
--address-name my_addr \
--profile devnet \
--assume-yes
What this does:
❌ WRONG: Using Regular Publish for Object Contracts
# ❌ Don't use this for object-based contracts
aptos move publish \
--named-addresses my_addr=<address>
When to use each:
deploy-object: Modern contracts using objects (RECOMMENDED)publish: Legacy account-based deployment (older pattern)How to tell if you need object deployment:
init_moduleobject::create_named_object()Option 1: deploy-object (Recommended - Simplest)
aptos move deploy-object --address-name my_addr --profile devnet
Option 2: create-object-and-publish-package (Advanced)
aptos move create-object-and-publish-package \
--address-name my_addr \
--named-addresses my_addr=default
Recommendation: Always use deploy-object unless you have a specific reason to use the alternative.
# Ensure all tests pass
aptos move test
# Verify 100% coverage
aptos move test --coverage
aptos move coverage summary
# Expected output: "coverage: 100.0%"
# Compile contract
aptos move compile --named-addresses my_addr=<your_address>
# Verify compilation succeeds
echo $?
# Expected: 0 (success)
Devnet is for quick testing and experimentation. Account is auto-funded on aptos init.
Check if a profile exists before initializing:
# Check if default profile exists (look for "default" in output)
aptos config show-profiles
# If no profile exists, initialize one (auto-funds on devnet)
aptos init --network devnet --assume-yes
# Deploy as object (modern pattern)
aptos move deploy-object \
--address-name my_addr \
--profile default \
--assume-yes
# Save the object address from output for future upgrades
# Output: "Code was successfully deployed to object address 0x..."
# Verify deployment
aptos account list --account <object_address> --profile default
Testnet is for final testing before mainnet.
Check if a profile exists before initializing:
# Check if default profile exists
aptos config show-profiles
# If no profile exists, initialize one
aptos init --network testnet --assume-yes
Fund your account via web faucet (required — testnet faucet needs Google login):
aptos config show-profileshttps://aptos.dev/network/faucet?address=<your_address># Verify balance
aptos account balance --profile default
# Deploy to testnet as object (modern pattern)
aptos move deploy-object \
--address-name my_addr \
--profile default \
--assume-yes
# IMPORTANT: Save the object address from output
# You'll need it for upgrades and function calls
# Output: "Code was successfully deployed to object address 0x..."
# Run entry functions to verify deployment
aptos move run \
--profile default \
--function-id <deployed_address>::<module>::<function> \
--args ...
# Test multiple scenarios
# - Happy paths
# - Error cases (should abort with correct error codes)
# - Access control
# - Edge cases
# Verify using explorer
# https://explorer.aptoslabs.com/?network=testnet
Only deploy to mainnet after thorough testnet testing.
Check if a profile exists before initializing:
# Check if default profile exists
aptos config show-profiles
# If no profile exists, initialize one
# IMPORTANT: Warn user that this generates a private key — store it securely
aptos init --network mainnet --assume-yes
Fund your account: Transfer real APT to your account address from an exchange or wallet.
# Verify balance
aptos account balance --profile default
# Deploy to mainnet as object (modern pattern)
aptos move deploy-object \
--address-name my_addr \
--profile default \
--max-gas 20000 # Optional: set gas limit
# Review prompts carefully before confirming:
# 1. Gas confirmation: Review gas costs
# 2. Object address: Note the object address for future reference
# OR use --assume-yes to auto-confirm (only if you're confident)
aptos move deploy-object \
--address-name my_addr \
--profile default \
--assume-yes
# SAVE THE OBJECT ADDRESS from output
# You'll need it for upgrades and documentation
# Confirm deployment
# Review transaction in explorer:
# https://explorer.aptoslabs.com/?network=mainnet
# Check module is published
aptos account list --account <deployed_address> --profile default
# Look for your module in the output
# "0x...::my_module": { ... }
# Run view function to verify
aptos move view \
--profile default \
--function-id <deployed_address>::<module>::<view_function> \
--args ...
Create deployment record:
# Deployment Record
**Date:** 2026-01-23 **Network:** Mainnet **Module:** my_module **Address:** 0x123abc... **Transaction:** 0x456def...
## Verification
- [x] Deployed successfully
- [x] Module visible in explorer
- [x] View functions working
- [x] Entry functions tested
## Links
- Explorer: https://explorer.aptoslabs.com/account/0x123abc...?network=mainnet
- Transaction: https://explorer.aptoslabs.com/txn/0x456def...?network=mainnet
## Notes
- All security checks passed
- 100% test coverage verified
- Tested on testnet for 1 week before mainnet
Object-deployed modules are upgradeable by default for the deployer.
# Upgrade existing object deployment
aptos move upgrade-object \
--address-name my_addr \
--object-address <object_address_from_initial_deploy> \
--profile mainnet
# Upgrade with auto-confirm
aptos move upgrade-object \
--address-name my_addr \
--object-address <object_address> \
--profile mainnet \
--assume-yes
# Verify upgrade
aptos account list --account <object_address> --profile mainnet
IMPORTANT: Save the object address from your initial deploy-object output - you need it for upgrades.
Upgrade Compatibility Rules:
To prevent future upgrades:
// In your module
fun init_module(account: &signer) {
// After deployment, burn upgrade capability
// (implementation depends on your setup)
}
# Typical deployment costs:
# - Small module: ~500-1000 gas units
# - Medium module: ~1000-5000 gas units
# - Large module: ~5000-20000 gas units
# When you run deploy-object, the CLI shows gas estimate before confirming
# Use --assume-yes only after you've verified costs on testnet first
Gas costs are paid in APT:
Option 1: Single package (Recommended)
project/
├── Move.toml
└── sources/
├── module1.move
├── module2.move
└── module3.move
# Deploys all modules at once as a single object
aptos move deploy-object --address-name my_addr --profile testnet
Option 2: Separate packages with dependencies
# Deploy dependency package first
cd dependency-package
aptos move deploy-object --address-name dep_addr --profile testnet
# Note the object address from output
# Update main package Move.toml to reference dependency address
# Then deploy main package
cd ../main-package
aptos move deploy-object --address-name main_addr --profile testnet
Devnet: Auto-funded on aptos init. If needed, run:
aptos account fund-with-faucet --account default --amount 100000000 --profile default
Testnet: Use the web faucet (requires Google login):
aptos config show-profileshttps://aptos.dev/network/faucet?address=<your_address>aptos account balance --profile defaultMainnet: Transfer real APT to your account from an exchange or wallet.
# Use upgrade-object with the original object address
aptos move upgrade-object \
--address-name my_addr \
--object-address <object_address_from_initial_deploy> \
--profile testnet
# Fix compilation errors first
aptos move compile
# Fix all errors shown, then retry deployment
# Increase max gas
aptos move deploy-object \
--address-name my_addr \
--profile testnet \
--max-gas 50000
Before Deployment:
During Deployment:
After Deployment:
When calling entry or view functions via the CLI, use these type prefixes:
--args u64:1000 # u8, u16, u32, u64, u128, u256
--args bool:true # boolean
--args address:0x1 # address
--args string:"Hello World" # UTF-8 string
--args hex:0x48656c6c6f # raw bytes
--args "u64:[1,2,3,4,5]" # vector<u64>
--args "string:[\"one\",\"two\",\"three\"]" # vector<String>
# For Object<T> parameters, pass the object address
--args address:0x123abc...
security-audit skill)deploy-object (NOT resource_account::create_resource_account() which is legacy)~/.aptos/config.yaml or .env files (contain private keys)"0x..." placeholderscat ~/.aptos/config.yaml, echo $VITE_MODULE_PUBLISHER_ACCOUNT_PRIVATE_KEY, or similar commandsgit add . or git add -A without confirming .env is in .gitignoreOfficial Documentation:
Explorers:
Related Skills:
security-audit - Audit before deploymentgenerate-tests - Ensure tests existRemember: Security audit → 100% tests → Testnet → Thorough testing → Mainnet. Never skip testnet.