Skip to content

Add wallet_staking_status: read-only query RPC for headless staking - #43

Open
br33zybail wants to merge 1 commit into
ShieldedLabs:s1_devfrom
br33zybail:staking-status-query-rpc
Open

Add wallet_staking_status: read-only query RPC for headless staking#43
br33zybail wants to merge 1 commit into
ShieldedLabs:s1_devfrom
br33zybail:staking-status-query-rpc

Conversation

@br33zybail

@br33zybail br33zybail commented Jul 18, 2026

Copy link
Copy Markdown

Adds wallet_staking_status, a read-only query RPC that complements wallet_staking_action
(26a6564). Additive - one new method, touches none of the existing staking code.

Why

wallet_staking_action lets a headless operator submit staking actions, but there's no
headless way to read staking state, which bonds exist, their targets and amounts, the
staked/withdrawable balances, or the wallet's sync height. Today that needs the GUI. Driving an
autostaker over wallet_staking_action makes the gap obvious: to size a bond, confirm one
landed, or drive an unbond/claim, you first have to see your bonds. This adds that read side.

What

One method, wallet_staking_status (no args), returning a JSON object:

{ "wallet_is_init": true, "sync_height": 233408, "tip_height": 233410,
  "user_address": "utest1…", "user_ufvk": "uview1…", "own_finalizer_pubkey": "45833df6…cb91",
  "user_unshielded_zats": 132998795002, "user_shielded_spendable_zats": 0, "user_shielded_pending_zats": 0,
  "staked_zats": 521830000000, "withdrawable_zats": 0,
  "bonded":   [ { "bond_key": "744b9031…", "target_finalizer": "45833df6…", "initial_zats": 100000000000 }, ],
  "unbonded": [ ] }

How

Read-only, no coupling to the write path. The headless wallet already keeps its live
WalletState (balances, stake_positions_bonded/unbonded, sync height) behind an
Arc<Mutex<…>>. wallet_main publishes a clone of that handle to a STAKING_STATUS_HANDLE
global (same idiom as USER_UFVK_STRING), and the RPC serialises a snapshot. Plumbing mirrors
wallet_staking_action exactly: a TFLServiceRequest/Response variant, a one-line service
handler, a methods.rs method with the same error shape. Fails closed, no wallet
(disable_the_headless_wallet) ⇒ explicit error, never a misleading empty-but-ok response.

Four files, additive; with the method uncalled, behaviour is byte-identical to s1_dev.

Addresses the earlier #40 review

  • Structured surface - a documented JSON object with typed fields, not a free-form string.
  • No policy in the node - pure mechanism (a query); scheduling/auto-staking stays external.
  • Additive - composes with wallet_staking_action; changes none of the existing staking code.
  • Zero config surface, zero new consensus constants.

Testing

  • Builds clean on current s1_dev (cargo build --release -p zebrad).
  • Ran the built binary headless: wallet_staking_status is registered and reachable, and fails
    closed
    with the wallet disabled:
    wallet_staking_status failed: headless wallet is not running (is disable_the_headless_wallet set?).
  • The bond/balance fields it surfaces are the ones the wallet already tracks, exercised end-to-end
    by a real headless run: a full up-and-down denomination ladder of self-bonds
    (0.01 → 10 → 100 → 1000, then 1000→100 as budget drained), each independently confirmed
    consensus-active on canonical blocks.

Note - live state this RPC surfaces. From a production headless node (fully synced), the
underlying wallet state which wallet_staking_status serialises currently holds 10
self-bonds
across the ladder rungs, all accruing PoS issuance: 0.01, 10, 100 (×2),
1000 (×5) and a tail bond, finalizer 45833df6…. That node predates this method (it used an
earlier string-command status path); the values are the exact WalletState fields
wallet_staking_status reads. A runtime capture of the new method returning this populated JSON
is available on request (it needs a synced wallet; a fresh sync is required to reproduce).

@br33zybail
br33zybail changed the base branch from main to s1_dev July 18, 2026 02:16
wallet_staking_action lets a headless operator submit staking actions, but
there's no headless way to read staking state — which bonds exist, their
targets/amounts, staked/withdrawable balances, or sync height. This adds that.

wallet_main publishes a clone of its live Arc<Mutex<WalletState>> to a
STAKING_STATUS_HANDLE global (same idiom as USER_UFVK_STRING); the new
wallet_staking_status RPC serialises a snapshot as a JSON object (bonds with
key/target/amount, balances, staked/withdrawable, sync/tip height, own
finalizer key). Read-only, mirrors wallet_staking_action's plumbing, fails
closed when no wallet is running.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Hfv59KmT627YnkA3BhhqgD
@br33zybail
br33zybail force-pushed the staking-status-query-rpc branch from b639fbb to 2d00a4e Compare July 18, 2026 02:35
@br33zybail br33zybail changed the title Headless CLI staking: fix Send bug in wallet_staking_action, add wallet_staking_status Add wallet_staking_status: read-only query RPC for headless staking Jul 18, 2026
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.

1 participant