paritytech / paritytech/polkadot-cli
feat: add `--wait` polling flag to `dot query`
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 10
- Forks
- 2
- Avg merge
- 12h 35m
- Merged PRs (30d)
- 4
Description
Context
On-chain workflows often require waiting for state transitions before proceeding to the next step. For example:
- After
ProofOfInk.apply(), wait untilCandidates(account)becomesApplied - After
ProofOfInk.submit_evidence(), poll until candidacy transitions toProven - After
allocate_full(), wait for bulletin authorization bytes to reach a threshold
Currently, an agent or script must implement its own polling loop by repeatedly calling dot query and parsing the output. This is slow (each call reconnects), wasteful, and error-prone.
Proposal
Add a --wait flag to dot query that polls the storage item until a condition is met or a timeout is reached:
Basic Usage - Wait for Value to Exist
# Wait until candidacy exists (any value)
dot query ProofOfInk.Candidates <account> --chain people --wait
Wait for Specific Value (JSONPath-like condition)
# Wait until candidacy status is "Proven"
dot query ProofOfInk.Candidates <account> --chain people \
--wait --match 'type=Proven'
# Wait until allocation type is "Full"
dot query ProofOfInk.Candidates <account> --chain people \
--wait --match 'value.allocation.type=Full'
# Wait until authorization bytes >= threshold
dot query TransactionStorage.Authorizations <account> --chain bulletin \
--wait --match 'extent.bytes>=2100000'
Timeout and Interval
# Poll every 12s (one block), timeout after 5 minutes
dot query ProofOfInk.Candidates <account> --chain people \
--wait --interval 12 --timeout 300
# Quick polling for fast-finality chains
dot query ... --wait --interval 2 --timeout 60
Output Behavior
- While waiting: show a spinner with elapsed time and last-seen value summary
- On match: print the matching value (same format as normal
dot query) - On timeout: exit with non-zero exit code and print last-seen value
Waiting for ProofOfInk.Candidates to match type=Proven...
12s: type=Selected (allocation=Full, judging=active)
24s: type=Selected (allocation=Full, judging=active)
36s: type=Proven
With --output json:
{
"matched": true,
"elapsed": 36,
"polls": 3,
"value": { "type": "Proven" }
}
Design Options for --match Syntax
Option A: Simple Key=Value (Recommended for v1)
--match 'type=Proven'
--match 'value.allocation.type=Full'
--match 'extent.bytes>=500000'
Supported operators: =, !=, >=, <=, >, <
Dot notation for nested access. Simple to implement and understand.
Option B: JSONPath Expression
--match '$.type == "Proven"'
More powerful but adds dependency and complexity. Could be a v2 enhancement.
Option C: jq-style Filter
--match '.type == "Proven"'
Familiar to CLI users but requires a jq parser/evaluator.
Recommendation: Start with Option A. It covers 90% of use cases with minimal complexity.
Implementation Notes
Connection Reuse
- Keep the WebSocket/light-client connection open during polling (don't reconnect each poll)
- Use
client.getUnsafeApi()and re-query on each interval
Subscription Alternative
For chains that support storage subscriptions, consider using watchEntries instead of polling:
// Instead of polling every N seconds, subscribe to changes
storageApi.watchValue(key).subscribe(value => {
if (matchesCondition(value)) { /* done */ }
});
This would be more efficient and faster-reacting than polling.
Defaults
--interval: 6 seconds (approximate block time for Polkadot relay chain)--timeout: 120 seconds (reasonable for most state transitions)
Exit Codes
0: condition matched1: timeout reached2: error (connection failed, invalid query, etc.)
Structured exit codes enable scripted workflows:
dot query ProofOfInk.Candidates <acct> --chain people --wait --match 'type=Proven' && \
echo "Candidate is proven!"
Why This Matters for Agent Workflows
The DIM1 runbook has multiple "poll until state changes" steps:
- Step B verify: Wait for
Applied - Step C verify: Wait for
Selected - Step D gate: Wait for authorization bytes >= threshold
- Step H: Poll until
Proven
Without --wait, each poll requires a separate tool call from the AI agent (expensive, slow, ~5-10 seconds per round trip). With --wait, each becomes a single command that blocks until satisfied. This turns a 30+ tool-call workflow into ~10 tool calls.
Labels
enhancement, agent-readiness
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the dot query command entry point and trace how it creates and queries the WebSocket/light-client connection. Compare the proposed polling approach using client.getUnsafeApi() with the watchEntries subscription alternative, then define the v1 matching, timeout, output, and exit-code behavior. Done means the documented examples work, including JSON output and timeout handling.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100