Subctl: Looking for feedback on a new CLI tool

Hi everyone,

I’d like to share a CLI tool I’ve been building called subctl. I made it primarily for myself to manage my own stake on Kusama, but I think it might be useful to others in the ecosystem.

Why I built this

As someone who prefers working in the terminal, I found the existing options frustrating:

  • Polkadot.js Apps is browser-only and can be unreliable (and is now being deprecated)
  • There wasn’t a good CLI tool for stakers and validators
  • GUIs, while great for casual users, aren’t always the most efficient for those of us working regularly in the ecosystem

So I started building subctl in December 2025, as a solo developer assisted by AI.

What it does

  • Wallet management (encrypted locally with AES-256-GCM)
  • Hardware wallet support (Ledger)
  • Transfers, including XCM teleports
  • Staking operations (bond, nominate, claim rewards)
  • Nomination pools
  • Governance (vote, delegate)
  • Pre-submission validation (catches errors before you pay fees)

It works with Polkadot, Kusama, and their Asset Hubs out of the box, but can be configured for any Substrate-based chain.

Web3 values

I’ve tried to align with decentralization principles:

  • Hosted on Codeberg, not GitHub
  • Not published to crates.io—while it’s a great resource, it’s a permissioned registry, which feels at odds with web3 values. Perhaps this is something the ecosystem should think about: how do we distribute and verify Rust tooling in a more decentralized way?
  • Pure Rust with no OpenSSL dependencies
  • Planning to implement signed releases for verification

Important disclaimer

This tool deals with real tokens, which means real risk—both for users and for my reputation if something goes wrong. I’m developing this on a best-effort basis as a solo developer. If you use it, please understand the risks. And if you can build something better, please do—the ecosystem needs good CLI tooling.

Seeking guidance on a security audit

Because subctl handles private keys and transaction signing, I believe a security audit would benefit the community. I’ve prepared a threat model documenting the security-critical code paths.

I’d like the community’s guidance on:

  1. Who could perform this audit? I want the process to be transparent.
  2. What scope makes sense? Focused on key management and signing, or more comprehensive?
  3. Which treasury? I’m personally focused on Kusama, but subctl serves both ecosystems. Kusama and Polkadot have different characters yet strengthen each other—I’d appreciate input on where a proposal would fit best.

Once we have answers, I’d submit a proposal for stakeholders to decide.

Links

Thanks for reading. I welcome any feedback, criticism, or suggestions.

5 Likes

Hello @hantoniu-codeberg !

This looks like a very welcome addition to the tooling landscape. I always thought the ecosystem has been missing such a “Swiss Army Knife” for the terminal, something like what cast (from Foundry) is for Ethereum, but tailored to Polkadot’s specific architecture (or maybe there was one that I missed). And tbh, having something like this definitely simplifies things. Instead of writing throwaway scripts requiring dev dependencies, a small runbook or set of CLI commands could do the job.

Standard disclaimer for everyone reading: I haven’t audited the source code, so I cannot vouch for the security of the wallet generation, encryption, or signing logic. As the OP noted, exercise appropriate caution with private keys and new software.

That said, looking at the documentation and feature set, the design choices seem to tackle the exact things I like:

  • Having a CLI that abstracts the Polkadot network topology away is valuable and I like it (teleport, etc)
  • Hardware support is very cool if you don’t want to load a hot wallet.
  • Integrating Polkadot Vault QR codes for transaction signing could be pretty sweet, to allow submitting transaction even if the CLI is on a server, far away somewhere… :slight_smile:

Regarding your questions on a security audit:

  • I’m not sure I’m qualified to chime in on this piece, so perhaps someone else will reach out with a more informed take.
  • Otherwise, adding read-only keys and signing exclusively from another device should do the job and not require a critical audit, as the CLI won’t be managing keys at all.

I’ve also taken your code and with a small tweak added a generic extrinsic builder using JSON arguments. Since this is for power users I believe this isn’t very controversial (always verify what you sign) :blush:

➜  subctl git:(master) ✗ ./target/release/subctl inspect storage -p System -c westend
westend::System storage (19 items)

  Account
  ExtrinsicCount
  InherentsApplied
  BlockWeight
  AllExtrinsicsLen
  BlockHash
  ExtrinsicData
  Number
  ParentHash
  Digest
  Events
  EventCount
  EventTopics
  LastRuntimeUpgrade
  UpgradedToU32RefCount
  UpgradedToTripleRefCount
  ExecutionPhase
  AuthorizedUpgrade
  ExtrinsicWeightReclaimed
➜  subctl git:(master) ✗ ./target/release/subctl query -p System -s Number -c westend --json
{
  "key": "[]",
  "pallet": "System",
  "storage": "Number",
  "value": 13429414
}
➜  subctl git:(master) ✗

I second the move to host on Codeberg and avoiding crates.io. I personally started hosting my stuff using fossil-scm, but I have a Codeberg account too. Perhaps a good way would still be to setup a GitHub mirror (with no issues, PRs, etc) like what the team at garage is doing, but it isn’t required at all.

Let me know if you’re open to PRs and I send the above.

Good luck with the development.

Thanks Karim — really appreciate the detailed feedback and the comparison to cast, that’s exactly the niche I’m aiming for.

Polkadot Vault — Love this idea. Displaying QR in terminal is straightforward, but scanning the signed response back is the tricky part — camera access doesn’t work in many CLI environments (SSH, headless). Multiframe animated QR for larger payloads adds another layer of complexity. Likely approach: QR display + hex paste fallback. Definitely on the radar, just need to figure out a solution that works universally.

Generic extrinsic builder — Great suggestion, and yes absolutely open to a PR. A subxt 0.50 refactor is coming once it hits stable — I’ll post here when that’s done, would love to collaborate after that.

GitHub mirror — Appreciate the suggestion. Staying Codeberg-only for now as part of the decentralization ethos, but may revisit.

1 Like