mcpField
S
stacking

stacking

github.com/aibtcdevOther11162 installsUpdated 1d ago
Repository

About stacking

A command-line skill for managing STX staking under PoX-5. It provides read-only network and staking queries alongside wallet-backed operations for staking, updates, unstaking, and sBTC reward claims.

Key features

  1. 01Read PoX-5 and staking status
  2. 02List signer managers
  3. 03Stake, extend, or unstake STX
  4. 04Check and claim sBTC rewards
  5. 05Validate network state before signing

Use cases

  1. 01Check a wallet's active STX stake
  2. 02Compare signer managers for a reward cycle
  3. 03Change a stake or its payout settings
  4. 04Estimate and claim cycle rewards

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/aibtcdev/skills --skill stacking

After installing, type/stackingin Claude Code to confirm it loaded.

Bundled filesAGENT.mdstacking.ts

Details

From the project README

Stacking Skill

STX staking on PoX-5 (active on mainnet since reward cycle 141). PoX-5 is not a rename of pox-4:

  • Every stake names a signer manager, a contract implementing pox-5's signer-manager-trait. There is no pool delegation (delegate-stx) and no reward address on the stake itself; the manager decides who may join and reads any payout preferences from optional signer calldata.
  • Rewards are paid in sBTC to the signer manager. A staker is paid when the manager pulls its share from pox-5 (claim-rewards) and then pays the staker (claim-staker-rewards). Managers implement that second step differently, and some pay off-chain.
  • stake, stake-update and unstake are refused during the prepare phase (the last 100 blocks of each cycle).
  • Locks are not transfers: transactions carry pox-5's own post-conditions (a staking lock amount, or "performs PoX") in Deny mode.

Every write first confirms pox-5 is still the network's active PoX contract and refuses before signing otherwise.

  • get-pox-info, get-stacking-status, list-signers, get-rewards — read-only, no wallet required (status and rewards default to the active wallet's address).
  • stack-stx, extend-stacking, unstake-stx, claim-rewards — write operations, require an unlocked wallet.

Usage

bun run stacking/stacking.ts <subcommand> [options]

Subcommands

get-pox-info

Current PoX-5 state.

bun run stacking/stacking.ts get-pox-info

Output:

{
  "network": "mainnet",
  "contract": "SP000000000000000000002Q6VF78.pox-5",
  "burnHeight": 967284,
  "rewardCycle": 143,
  "nextCycleStartHeight": 968450,
  "preparePhaseStartHeight": 968350,
  "inPreparePhase": false,
  "firstBurnHeight": 666050,
  "rewardCycleLength": 2100,
  "prepareCycleLength": 100,
  "signerSetMinUstx": "50000000000",
  "totalLiquidSupplyUstx": "1867006091924579"
}

signerSetMinUstx is the minimum a signer needs delegated to join the signer set, not a per-staker minimum.

get-stacking-status
bun run stacking/stacking.ts get-stacking-status [--address <addr>]

Output:

{
  "address": "SP1PSZZYFH9H5M81KGBV2XTFQBR3HQ17HJW7Y4ZK2",
  "network": "mainnet",
  "staking": true,
  "stake": {
    "signerManager": "SP8HK160YD5GHXP69VGA0TC7AQJ1X4CDW3XVERSE.xverse-signer-manager-2",
    "amountUstx": "500000000",
    "amount": "500.000000 STX",
    "firstRewardCycle": 144,
    "numCycles": 96,
    "unlockCycle": 240,
    "unlockBurnHeight": 1170050
  },
  "bond": null,
  "balance": {
    "totalUstx": "560494462",
    "lockedUstx": "500000000",
    "unlockedUstx": "60494462",
    "burnchainUnlockHeight": 1170050
  },
  "pox": { "contract": "SP000000000000000000002Q6VF78.pox-5", "burnHeight": 967284, "rewardCycle": 143, "nextCycleStartHeight": 968450, "preparePhaseStartHeight": 968350, "inPreparePhase": false }
}

bond is set when the address is in a pox-5 protocol bond (bondIndex, amountUstx, amountSats, isL1Lock, signerManager).

list-signers

Signer managers in the signer set for a reward cycle (default: the next cycle, which a new stake joins), sorted by delegated STX.

bun run stacking/stacking.ts list-signers [--reward-cycle <cycle>] [--with-payout-info]

Options:

  • --reward-cycle (optional) — cycle to list
  • --with-payout-info (optional) — also read each manager's staker-claim style: staker-arg / caller (on-chain claim works) or none (pays off-chain). One extra request per signer.

Output (truncated):

{
  "network": "mainnet",
  "rewardCycle": 144,
  "count": 26,
  "signers": [
    { "signerManager": "SP1N8F8BBBC60XF6HJBNJHKPRGJ7WZBRGNDJX4YDR.signer-manager", "delegatedUstx": "85815090000000", "delegated": "85815090.000000 STX" }
  ],
  "note": "Managers can restrict who may stake ..."
}

Only signers at or above the signer-set minimum appear. Other registered managers can still be staked with by contract id.

stack-stx

Lock STX with a signer manager. The lock starts next reward cycle.

bun run stacking/stacking.ts stack-stx \
  --signer-manager <contractId> \
  --amount <microStx> \
  --num-cycles <1-96> \
  [--btc-reward-address <address> [--max-withdrawal-fee-sats <sats>] | --signer-calldata-hex <hex>]

Options:

  • --signer-manager (required) — signer manager contract id (see list-signers)
  • --amount (required) — micro-STX to lock (1 STX = 1,000,000 micro-STX)
  • --num-cycles (required) — reward cycles to lock, 1–96 (one cycle ≈ 2 weeks)
  • --btc-reward-address (optional) — Bitcoin address for rewards, encoded as { pox-addr, max-fee } calldata, the shape reference managers (e.g. Xverse, Fast Pool) use to pay via an sBTC withdrawal. Some managers require it, some ignore it.
  • --max-withdrawal-fee-sats (optional) — max sBTC withdrawal fee per payout with --btc-reward-address (default 3000)
  • --signer-calldata-hex (optional) — raw calldata (≤500 bytes) for managers with a custom format; not combinable with --btc-reward-address

Refused before signing when: in the prepare phase (or within 3 burn blocks of it), already staking (use extend-stacking), the manager is not a registered pox-5 signer, or the amount exceeds the address's STX balance.

Output:

{
  "success": true,
  "txid": "0x...",
  "explorerUrl": "https://explorer.hiro.so/txid/0x...?chain=mainnet",
  "staker": "SP...",
  "signerManager": "SP8HK160YD5GHXP69VGA0TC7AQJ1X4CDW3XVERSE.xverse-signer-manager-2",
  "amountUstx": "2780000000",
  "amount": "2780.000000 STX",
  "firstRewardCycle": 144,
  "numCycles": 96,
  "unlockCycle": 240,
  "unlockBurnHeight": 1170050,
  "rewardPayout": "sBTC (if the manager supports it)",
  "network": "mainnet"
}
extend-stacking

Update an existing stake (stake-update): extend, add STX, switch signer manager, or change payout calldata, in any combination.

bun run stacking/stacking.ts extend-stacking \
  [--cycles-to-extend <cycles>] [--amount-increase <microStx>] [--signer-manager <contractId>] \
  (--btc-reward-address <address> [--max-withdrawal-fee-sats <sats>] | --signer-calldata-hex <hex> | --sbtc-payout)

A payout choice is required on every update. pox-5 passes stake-update's calldata to the manager's validate-stake! each time, and reference managers (Xverse, Fast Pool) treat no calldata as "delete the stored BTC payout address"; others reject it. To keep a BTC payout, pass the same --btc-reward-address again. --sbtc-payout sends no calldata on purpose.

Refused when no payout choice is given, when not staking, in the prepare phase, nothing would change, the increase exceeds the unlocked balance, the new manager is not registered, or the lock would run more than 96 cycles past the next cycle.

Output: txid, explorerUrl, previous (the stake before), signerManager, newAmountUstx, newAmount, unlockCycle, unlockBurnHeight.

unstake-stx

Stop a stake early (unstake). STX stays locked through the current cycle and unlocks at the start of the next.

bun run stacking/stacking.ts unstake-stx

Refused when not staking, in the prepare phase, or when the stake already unlocks next cycle.

Output: txid, explorerUrl, previous, unlockCycle, unlockBurnHeight.

get-rewards

sBTC claimable from a signer manager for one cycle. pox-5's get-earned-staker-rewards only catches up when the manager pulls the cycle's rewards, so this projects the amount the staker can claim after that pull (pox-5's own compute-earned-rewards over the cycle's global rewards-per-token).

bun run stacking/stacking.ts get-rewards --reward-cycle <cycle> [--address <addr>] [--signer-manager <contractId>]

Output:

{
  "address": "SP...",
  "network": "mainnet",
  "rewardCycle": 143,
  "signerManager": "SP8HK160YD5GHXP69VGA0TC7AQJ1X4CDW3XVERSE.xverse-signer-manager-2",
  "unclaimedSatsBeforeFees": "0",
  "managerUnpulledSats": "0",
  "stakerClaim": "staker-arg",
  "next": "Nothing to claim for this cycle."
}
claim-rewards

Claim one cycle's sBTC rewards through the signer manager. If the manager has not pulled that cycle's rewards from pox-5 yet, this first sends the manager's permissionless claim-rewards (a second transaction paid by this wallet), then the staker claim.

bun run stacking/stacking.ts claim-rewards --reward-cycle <cycle> [--signer-manager <contractId>]

Refused when the manager has no on-chain staker claim or nothing is claimable (projected as in get-rewards, so rewards the manager has not pulled yet still count). When two transactions are sent they use consecutive explicit nonces. The sBTC post-conditions use the token pox-5 reports in /v2/pox (pox_5_sbtc_contract), which differs from the default sBTC on testnet. Post-conditions allow sBTC only out of pox-5 (the pull) and the manager (the payout); nothing may leave the caller.

Output: txid, explorerUrl, unclaimedSatsBeforeFees, managerPull ({ txid, explorerUrl } or null), and a note when two transactions were sent.

Notes

  • Ported from the aibtc MCP server's pox-5 stacking tools (aibtcdev/aibtc-mcp-server#682); the transaction arguments and post-conditions match mainnet stake, stake-update and unstake transactions.
  • Managers can restrict who may stake (allowlists, minimums, required calldata). A stake the manager refuses aborts on chain and still costs the fee, so check the manager's terms first.
  • Wallet operations require an unlocked wallet (bun run wallet/wallet.ts unlock).
  • Pillar's direct-stack-stx --pool fast-pool and direct-revoke-fast-pool go through pox-4 in the Pillar wallet contract and are refused while pox-4 is not active; use this skill for PoX-5 staking.

Comments

Markdown supported