Best for
- Use this skill when the user needs to publish a package, upgrade a published package, deploy to multiple networks, serialize transactions for multisig signing, run a local Sui network (localnet), prepare for Mainnet lau…
mission69b/t2000/.claude/skills/sui-publish/SKILL.md
Publishing, upgrading, and deploying Sui Move packages. Use this skill when the user needs to publish a package, upgrade a published package, deploy to multiple networks, serialize transactions for multisig signing, run a local Sui network (localnet), prepare for Mainnet launch, monitor production deployments, or debug dry run failures. Also use when the user asks about sui client publish, sui client upgrade, UpgradeCap, upgrade policies, Published.toml, --serialize-output, localnet, mainnet lau
Decision brief
MCP tool: When available in your environment, also query the Sui documentation MCP server (https://sui.mcp.kapa.ai) for up-to-date answers. Use it for verification and for details not covered by these reference files.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/mission69b/t2000 --skill ".claude/skills/sui-publish"Inspect the Agent Skill "sui-publish" from https://github.com/mission69b/t2000/blob/d05c3ebbaba298d6c2b1d8f9f352c065c6e94ce3/.claude/skills/sui-publish/SKILL.md at commit d05c3ebbaba298d6c2b1d8f9f352c065c6e94ce3. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Before executing the publish transaction on Mainnet:
Use gRPC streaming subscriptions for real-time monitoring:
For the full-stack starter, publish the existing hello-world package only:
For the full-stack starter, publish the existing hello-world package only:
1. Verify your active environment: sui client active-env 2. Verify you have SUI tokens: sui client balance 3. Build successfully: sui move build
Permission review
The documentation asks the agent to create, modify, or delete local files.
Use the package ID from the publish output to update `sui-stack-hello-world/ui/src/constants.ts` (`TESTNET_HELLO_WORLD_PACKAGE_ID`). Do not publish a separate counter package, and do not create a second project directory.Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 97/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
MCP tool: When available in your environment, also query the Sui documentation MCP server (
https://sui.mcp.kapa.ai) for up-to-date answers. Use it for verification and for details not covered by these reference files.
Source constraint: All information sourced exclusively from docs.sui.io and MystenLabs/sui-stack-hello-world.
For the full-stack starter, publish the existing hello-world package only:
cd sui-stack-hello-world/move/hello-world
sui move build
sui client publish
Use the package ID from the publish output to update sui-stack-hello-world/ui/src/constants.ts (TESTNET_HELLO_WORLD_PACKAGE_ID). Do not publish a separate counter package, and do not create a second project directory.
sui client active-envsui client balancesui move buildsui client publish
This deploys the package to the active network and returns:
init functionsUse sui client test-publish to publish a package to an ephemeral environment for testing without persisting state to a real network:
sui client test-publish
This publishes the package, runs init functions, and returns the same output as sui client publish (package ID, UpgradeCap, created objects), but the deployment is not permanent. Use it to:
init functions execute correctly before committing to a real publishtest-publish respects --build-env for multi-environment packages:
sui client test-publish --build-env testnet
The publish transaction output lists the package ID under the created objects section (alongside the UpgradeCap and any objects created by init functions). The published-at field is also automatically added to your Published.toml. To interact with the published package:
# Call a function
sui client call --package <PACKAGE_ID> --module greeting --function new
# Query an object
sui client object <OBJECT_ID>
If you see this error when running sui client publish, it means Published.toml already has an entry for your active environment. This happens when iterating on a package during development.
sui client switch --env <ENV> and run sui client publish again. The toolchain tracks published addresses per environment in Published.toml automatically — do not delete Published.toml.sui client upgrade (see below).Published packages are immutable, but you can upgrade by publishing a new version linked to the original. The UpgradeCap object controls upgrade authority. Important: you can restrict the UpgradeCap in the same PTB as the publish command — for example, publishing and immediately calling sui::package::only_additive_upgrades in one atomic transaction. You can also destroy it entirely to make the package permanently immutable (see upgrade policies below).
sui client upgrade --upgrade-capability <CAP_ID>
The UpgradeCap object ID is needed for every upgrade. There are several ways to find it:
Published.toml under the upgrade-capability field for each environment.UpgradeCap objects owned by the publish address:
sui client objects --type 0x2::package::UpgradeCap
sui client publish output includes the UpgradeCap object ID in the created objects list.suivision.xyz) or Suiscan (suiscan.xyz) and filter owned objects by type 0x2::package::UpgradeCap.Upgrade policies restrict what can change:
Restricting the UpgradeCap in the same PTB as publish: You can restrict the UpgradeCap in the same programmable transaction block as the publish command itself — for example, calling sui::package::only_additive_upgrades on the UpgradeCap immediately after publishing, all within a single atomic transaction. This is the recommended approach for locking down upgrade policy from the start. Once restricted, you cannot widen the policy.
Other UpgradeCap options:
sui::package::make_immutable, which consumes and destroys the UpgradeCap object. Once the cap is destroyed, no one can ever upgrade the package again — this is irreversible.Under the compatible policy, these changes are allowed:
These changes break compatibility and will be rejected:
key, store, copy, drop)Before upgrading, review your diff against these rules. The sui client upgrade command will reject incompatible changes at build time with a descriptive error.
Struct types are permanently anchored to the original package ID where they were first published. After an upgrade, the new package gets a new ID, but all objects created by the upgraded code still have their type rooted in the original package ID.
This has critical implications:
listOwnedObjects with a type filter) must use the original package ID.moveCall must use the upgraded (latest) package ID.ORIGINAL_PACKAGE_ID for type queries and PACKAGE_ID for function calls.// Original publish → package ID 0x1234...
// After upgrade → package ID 0x5678...
// Query: use ORIGINAL package ID
client.core.listOwnedObjects({
owner: addr,
type: '0x1234...::module::MyObject', // ✅ original ID
});
// Call: use UPGRADED package ID
tx.moveCall({
target: '0x5678...::module::my_function', // ✅ upgraded ID
});
To publish to a different network (for example, from Testnet to Devnet), switch environments and publish again. Each network gives the package a different ID. The Published.toml file tracks published addresses per environment.
Before publishing to a new network, ensure you have tokens for that network:
faucet.sui.io, Discord (!faucet <ADDRESS> in #testnet-faucet), or the TypeScript SDK (requestSuiFromFaucetV2()). sui client faucet does not work on Testnet.sui client faucet, the web faucet at faucet.sui.io, Discord (!faucet <ADDRESS> in #devnet-faucet), or the TypeScript SDK.sui client faucet or the local faucet at 127.0.0.1:5003/gas or 127.0.0.1:9123/gas (started with sui start --with-faucet --force-regenesis).To generate transaction bytes for signing by another party (for example, a multisig):
sui client publish --serialize-output
This outputs base64 transaction bytes instead of executing.
Localnet runs a full Sui network on your machine for offline development and rapid iteration. Start it with:
sui start --with-faucet --force-regenesis
The --force-regenesis flag resets all on-chain state each time the network starts, giving you a clean environment on every restart. The --with-faucet flag starts a local faucet so you can fund addresses.
To connect the CLI to your localnet:
sui client switch --env localnet
Get local tokens via sui client faucet or by hitting the local faucet endpoint directly at 127.0.0.1:5003/gas or 127.0.0.1:9123/gas.
Localnet is useful for:
init functions and object creation before deploying to a shared networkUse this checklist when preparing a package for Mainnet publishing. Every item should be verified before executing the publish transaction.
Run the full test suite and confirm all tests pass:
sui move test
For coverage reporting (if your project requires a threshold):
sui move test --coverage
sui move coverage summary
Fix any failing tests before proceeding. Do not publish untested code to Mainnet.
Move.toml uses edition = "2024" and has no legacy [addresses] section or git-based Sui framework dependency.[environments] includes a mainnet entry with the correct chain ID.{ r.mvr = "@org/package" }), verify they resolve on Mainnet.sui move build to confirm clean compilation with no warnings.Decide your upgrade policy before publishing — you cannot widen it later:
| Policy | What you can change | When to use |
|---|---|---|
| Compatible (default) | Add functions, add modules, update implementations. Cannot remove functions or change struct layouts. | Most packages — gives flexibility for bug fixes while preserving type safety. |
| Additive | Add new modules only. Existing modules are frozen. | Packages where you want to extend functionality but guarantee existing code never changes. |
| Dependency-only | Only update dependency versions. | Nearly-finalized packages that should only track framework updates. |
| Immutable | Nothing. Package is permanently frozen. | Fully audited packages where immutability is a trust guarantee (e.g., token contracts). |
To restrict the policy in the same transaction as publish, include a moveCall to sui::package::only_additive_upgrades, only_dep_upgrades, or make_immutable on the UpgradeCap in your publish PTB.
Mainnet SUI has real monetary value. Estimate gas before publishing:
sui client publish --dry-run
The dry-run output includes computationCost, storageCost, and storageRebate. The total gas required is computationCost + storageCost - storageRebate. Ensure your address holds enough SUI to cover this amount plus a margin.
Decide who controls the publish address and the UpgradeCap:
UpgradeCap. Suitable for personal projects or early-stage development.--serialize-output, and have the required signers sign offline. Transfer the UpgradeCap to the multisig address in the same PTB as publish.UpgradeCap in the publish PTB (sui::package::make_immutable). This removes custody concerns entirely.For multisig publishing:
# Generate unsigned transaction bytes
sui client publish --serialize-output
# Each signer signs the bytes, then combine and execute
Before executing the publish transaction on Mainnet:
sui client active-env returns mainnetsui client balance shows sufficient SUI for gas (check dry-run estimate)sui move build succeeds with no warningssui move test passes with all tests greenMove.toml has correct edition, no legacy formatA dry run simulates a transaction without submitting it to the network. Use dry runs to:
Wallets (like Slush) automatically perform dry runs before presenting a transaction for signing. If a dry run fails, the wallet shows an error instead of prompting.
From the TypeScript SDK, use devInspectTransactionBlock to dry-run a transaction programmatically. From the CLI, the --dry-run flag simulates execution.
When debugging a dry run failure: check that all object IDs are correct, the object versions are current, the sender has sufficient gas, the function arguments match the expected types, and the active environment (sui client active-env) matches the network where the package is published.
Sui packages are immutable once published, so monitoring is critical — you cannot hotfix a live contract, only publish an upgrade.
| Signal | How | Why |
|---|---|---|
| Failed transactions involving your package | Subscribe to transaction effects via gRPC streaming, filter by package ID | Detects Move aborts, gas failures, or unexpected reverts in production |
| Gas spend | Track gasUsed from transaction effects | Catch unexpectedly expensive operations or gas drain attacks |
| Event emission | Subscribe to events by type ({packageId}::module::EventName) via gRPC streaming | Core business telemetry — mints, transfers, admin actions, deny list changes |
| Object creation/deletion rates | Query or subscribe to object changes filtered by your types | Detect abnormal activity (mass minting, object spam) |
| Admin/cap usage | Filter events for capability-gated actions | Detect unauthorized or unexpected admin operations |
| Shared object contention | Monitor transaction latency for shared-object transactions | High contention degrades UX; may need object sharding |
Use gRPC streaming subscriptions for real-time monitoring:
for await (const event of client.subscriptionService.subscribeEvents({
filter: { MoveEventModule: { package: PACKAGE_ID, module: 'my_module' } },
})) {
// Forward to your monitoring stack (Grafana, Datadog, PagerDuty, etc.)
}
For historical analysis, run a custom indexer (sui-indexer-alt) that writes relevant events and transaction effects to your own database. See the accessing-data skill's indexers.md.
Emit events for every security-critical action in your Move code — admin changes, configuration updates, deny list modifications, object deletions. Events are the only way offchain systems can observe these actions.
Sui packages cannot be rolled back. Published bytecode is immutable. There is no revert or rollback command. Recovery means publishing a forward-fix upgrade.
sui client upgrade on Mainnet. The new package ID replaces the old one for all future calls.PACKAGE_IDS to the new (fixed) package ID. Type queries still use ORIGINAL_PACKAGE_IDS.An attacker with the UpgradeCap can publish arbitrary code under your package. Mitigation:
only_dep_upgrades or make_immutable) to prevent further malicious upgrades.UpgradeCap matters for production packages.A buggy function may write invalid state to a shared object. Since shared objects are mutable by any transaction:
AdminCap.UpgradeCap held by multisig or restricted to additive / dep_onlyAlternatives
ok-helloworld/vibe-pentest
Race condition and TOCTOU testing for web apps. Use when testing one-time operations, concurrent HTTP abuse, rate-limit bypass, Turbo Intruder gates, HTTP/2 single-packet attacks, and CWE-362-style synchronization gaps.
K-Dense-AI/scientific-agent-skills
Build, inspect, test, and analyze bounded process-based discrete-event simulations with SimPy, including events, resources, interrupts, monitoring, replications, warm-up, and reproducible output analysis.
huggingface/skills
Create a SageMaker endpoint (real-time, real-time scale-to-zero, or async) with autoscaling, CloudWatch alarms, and tagging enabled by default. Use this skill whenever about to create a SageMaker endpoint, write deployment code that calls `create_endpoint`, or finalize a deployment after the image URI and IAM role are known. Provides deploy.py for real-time endpoints, deploy_ic.py for real-time endpoints that scale to zero instances via inference components, and deploy_async.py for async endpoin
aAAaqwq/AGI-Super-Team
Build and test Polymarket prediction market trading strategies for YES/NO token trading. Provides 6 tools: get_all_prediction_events (browse markets, $0.001), get_prediction_market_data (analyze price history, $0.001), create_prediction_market_strategy (generate code, $1-$4.50), run_prediction_market_backtest (test performance, $0.001). Trade on real-world events (politics, economics, sports, crypto). Currently simulation only (live deployment coming soon).