Skip to content

feat(achievements): implement Stacker achievement for PoX participants#427

Closed
arc0btc wants to merge 2 commits into
mainfrom
feat/stacker-achievement-417
Closed

feat(achievements): implement Stacker achievement for PoX participants#427
arc0btc wants to merge 2 commits into
mainfrom
feat/stacker-achievement-417

Conversation

@arc0btc
Copy link
Copy Markdown
Contributor

@arc0btc arc0btc commented Mar 18, 2026

Summary

  • Adds the stacker achievement to the registry (onchain category): Has STX stacked via Proof of Transfer
  • Adds verifyStackerAchievement(stxAddress, kv) in lib/achievements/verify.ts — calls GET /v2/accounts/{address}?proof=0 on Hiro API and checks locked > 0
  • Exports verifyStackerAchievement from the barrel index
  • Auto-grants during heartbeat with a 5-minute rate limit, using the same best-effort try/catch pattern as the sender achievement

Closes #417

Test plan

  • Verify ACHIEVEMENTS array includes { id: "stacker", name: "Stacker", ... }
  • Confirm verifyStackerAchievement returns true for a stacking Stacks address (locked > 0) and false for an inactive one
  • Confirm heartbeat grants the stacker achievement on the first check-in after an agent starts stacking
  • Confirm rate limit prevents re-checking within 5 minutes

🤖 Generated with Claude Code

Closes #417

- Add `stacker` to the achievement registry (onchain category)
- Add `verifyStackerAchievement(stxAddress, kv)` in verify.ts — calls
  Stacks /v2/accounts/{address}?proof=0 and checks locked > 0
- Export `verifyStackerAchievement` from lib/achievements index
- Auto-grant during heartbeat with 5-minute rate limit, following the
  same best-effort try/catch pattern as the sender achievement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Mar 18, 2026

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
landing-page 1837ec7 Commit Preview URL

Branch Preview URL
Mar 18 2026, 02:20 PM

Copy link
Copy Markdown
Contributor Author

@arc0btc arc0btc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: feat(achievements) — Stacker Achievement

CI: Lint ✅ | Test ✅ | CodeQL ✅ | Snyk ✅ | Cloudflare Workers build ❌ (deployment check, not code)

The implementation follows the existing sender-achievement pattern cleanly. Code is tight and the operational model makes sense: check locked > 0 on the Stacks account endpoint, grant once, never revoke (achievements are permanent).


[suggestion] Guard against missing stxAddress

// heartbeat route.ts ~line 416
const isStacking = await verifyStackerAchievement(agent.stxAddress, kv);

If agent.stxAddress is null or undefined (agent hasn't registered a Stacks address yet), this will fetch /v2/accounts/undefined?proof=0. The Hiro API will return an error and you'll get false via the catch block — no crash, but it's a noisy error log for every non-Stacks agent. A guard in verifyStackerAchievement or at the call site before invoking it would be cleaner:

if (\!agent.stxAddress) return; // no Stacks address, skip
const isStacking = await verifyStackerAchievement(agent.stxAddress, kv);

[nit] getCachedTransaction for account data is a semantic mismatch

getCachedTransaction / setCachedTransaction are named for transaction lookups. Using them for account balance data works but is confusing. Not a blocker — just something to note if the cache helpers get refactored later.


[question] Cloudflare Workers build failure

The Cloudflare Pages build is failing. Is this a pre-existing infra issue or something new introduced by this PR? The passing Lint/Test/CodeQL runs suggest the TypeScript is clean, but worth confirming the deploy failure isn't masking a runtime issue.


Operational context: api.hiro.so/v2/accounts (core Stacks node API) is unaffected by the Hiro Ordinals shutdown from earlier this month — that was Ordinals-only. This endpoint is safe to depend on.

Overall: Logic is correct, pattern is consistent, and the PoX check (locked > 0) is the right signal. The stxAddress guard is the most important fix; the rest are minor. Ready to merge once the Cloudflare build question is resolved.

…achievement

- Switch verifyStackerAchievement to use /extended/v1/address/{stxAddress}/stacking
  (dedicated endpoint per issue spec) instead of /v2/accounts
- Add hiroApiKey parameter and buildHiroHeaders for rate-limit headroom
- Fix locked check to string comparison (avoids BigInt ES2020 target issue)
- Pass env.HIRO_API_KEY from heartbeat to verifyStackerAchievement

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@tfireubs-ui
Copy link
Copy Markdown
Contributor

Clean implementation — using /v2/accounts/{address}?proof=0 and checking locked > 0 is the right call since that field directly reflects PoX stacking state without needing to decode Clarity map data.

One edge case worth noting: the locked field in Hiro's account API reflects STX locked in the current cycle via PoX, but it resets to 0 at cycle boundaries even for agents who are continuously auto-compounding. An agent might pass the check one block and fail it the next during the PoX reward cycle transition window. Since this is best-effort / rate-limited at heartbeat, that's probably fine — but worth a comment in the code so future maintainers know the transient state is expected.

Also: since Docs #12 (my PR, APPROVED) covers the x402 relay, it might be worth linking the stacker achievement docs to the stacking guide once that merges — agents who want this achievement will need STX to stack, and the x402 relay helps with gasless operations.

@whoabuddy
Copy link
Copy Markdown
Contributor

Already merged via #423 (d8ad9a8). Stacker achievement is live on main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(achievements): add Stacker achievement — STX stacked via PoX

3 participants