Skip to content

fix(cycles): icp cycles buy says where an unsettled order stands and how to look in on it - #831

Open
raymondk wants to merge 1 commit into
cycles-buy/06-wait-clockfrom
cycles-buy/07-follow-up
Open

raymondk wants to merge 1 commit into
cycles-buy/06-wait-clockfrom
cycles-buy/07-follow-up

Conversation

@raymondk

@raymondk raymondk commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

When the wait ended with the order unsettled, the command printed one line (Order co-12 stays payable until …) and a fixed hint naming icp cycles balance without the flags the run used, so a user on a named identity or another network pasted a command that looked at the wrong account.

Now the command says once, as the error it ends with, why the wait ended (stopped, the hour, the gateway out of reach), where the order stands (still payable until its deadline while unpaid; paid and being delivered once paid; the order carries on without the command), where its cycles land, and the balance command on a line of its own with the identity, network and environment of the run filled in. The default identity is named, since only the identity that made the order can read it. --no-wait says the same. A refund owed or an order needing review comes with the icp canister call <gateway> order_status --query … '("<order id>")' command that reads the order back, and for CyclePay's gateway a pointer to My purchases. For example, after Ctrl-C as alice on -n ic:

Error: stopped waiting for order co-12-20d30d24771ff92787f41d95b6764a61.

It stays payable until 2026-10-17T22:13:20Z. Once it is paid, its cycles land on your identity's cycles-ledger account. To see them:

    icp cycles balance --identity alice -n ic

Those commands must paste as printed, in every shell icp-cli completes for, so this PR also adds the flag builder they use, commands::args::selection_flags (PasteFlags, shell_word), which was #829 before: the short flag where there is one, --flag=value for a value starting with - (which would otherwise read as a flag), and a value bare when nothing in it is special to any of the POSIX shells, fish, elvish or PowerShell, else single-quoted, else (for a name with ') double-quoted when nothing else in it is special there. A value no quoting carries in all of them is left as <your identity>, with a line asking to fill it in; for one starting with - the placeholder keeps the --flag= form, which #829's review caught. #829 also rewrote the recovery command icp canister create --with-icp prints with this builder; that path is rare enough that it is left as it is.

Code by Josh, from #824 (commit 9cd3e1c, follow-up part, and 11a85d4, the builder): FollowUp, Unsettled, unsettled, look_later. Plain strings and paragraphs, no 80-column wrapping (not wanted). -q is unchanged: the error alone. Not included: the payment-pending state, the gateway note, the refund-under-way rewording.

Tests: an_unsettled_order_is_said_once_where_it_stands, the_follow_up_commands_carry_the_selections; words_are_quoted_only_as_every_shell_needs and selections_become_the_flags_that_select_them pin every quoted word and every flag form; integration cycles_buy_ctrl_c_stops_the_wait_not_the_order asserts the exact ending and cycles_buy_no_wait_says_where_the_cycles_will_show is new (the stand-in fixture now uses a named buyer identity so the flags are assertable).


Part of restacking #824 into small PRs, one fix each, stacked on main in this order: cycles-buy/06-wait-clock → 07-follow-up → 08-json-fields. Each PR targets the one below it; after the one below merges, retarget to main.

🤖 Generated with Claude Code

https://claude.ai/code/session_015aem4tPs4TYVZb8k4LMbJJ

@raymondk
raymondk requested a review from a team as a code owner October 16, 2026 23:01
@raymondk
raymondk added this pull request to stack #835 October 20, 2026 15:44
Copilot AI balanced review requested due to automatic review settings October 20, 2026 15:45
@raymondk
raymondk force-pushed the cycles-buy/07-follow-up branch from 0e96e85 to 015e05d Compare October 20, 2026 15:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Recovery commands replace valid non-ASCII order IDs with a placeholder instead of querying the actual order.

1 open issue
What changed in this PR

Improves icp cycles buy follow-up messages so users can check unsettled orders with the same identity and network selections.

Changes:

  • Explains why waiting ended and where the order stands.
  • Prints selection-aware balance and order-status commands.
  • Adds regression tests and updates documentation.
File Description
docs/​guides/​tokens-and-cycles.md Documents unsettled orders and recovery commands.
crates/​icp-cli/​tests/​cycles_tests.rs Tests interruption and no-wait output with a named identity.
crates/​icp-cli/​src/​commands/​cycles/​buy.rs Builds follow-up messages and selection-aware commands.
CHANGELOG.md Records the improved purchase guidance.

Review effort: Balanced

Comment on lines +328 to +329
let arg = shell_word(&format!("(\"{}\")", id.escape_default()))
.unwrap_or_else(|| "'(\"<order id>\")'".to_owned());
@raymondk
raymondk force-pushed the cycles-buy/07-follow-up branch 2 times, most recently from ecdee75 to c32b2ec Compare October 20, 2026 18:48
…how to look in on it

When the wait ended with the order unsettled (Ctrl-C, the hour, the
gateway out of reach) the command said one line ("Order co-1 stays
payable until ...", "Order co-1 is paid, delivering.") and a fixed hint
naming `icp cycles balance` without the flags the run used, then ended
with a short error of its own; --no-wait said the same hint. An order
an operator handles (a refund owed, or one needing review) said only
"Keep the order id".

Now the command says once, as the error it ends with, why the wait
ended (stopped; an hour passed; the gateway stopped answering), whether
the order stays payable until its deadline, is paid and being delivered,
or is in some other state, where its cycles land, and the
`icp cycles balance` command that shows them, on a line of its own with
the identity (the default named, since only the identity that made an
order can read it), network and environment the run used. --no-wait
says the same. A refund owed and an order needing review come with the
`icp canister call <gateway> order_status --query ... '("<id>")'`
command that reads the order back. Paragraphs are set apart by a blank
line, commands are indented and never wrapped, and a value no quoting
carries in every shell is left as <your identity> with a note. -q keeps
the status alone, as before.

The flags come from a builder this commit adds,
commands::args::selection_flags (PasteFlags, shell_word): the short
flag where there is one, `--flag=value` for a value starting with `-`,
which would otherwise read as a flag, and a value bare when nothing in
it is special to any of the POSIX shells, fish, elvish or PowerShell,
else single-quoted, else (for a name with `'`) double-quoted when
nothing else in it is special there; anything else is a placeholder,
`--flag=<placeholder>` when the value starts with `-`. Unit tests pin
every quoted word and every flag form. The builder was the first commit
of #823 and then #829, where it rewrote the recovery command
`icp canister create --with-icp` prints; that path is rare enough to be
left as it is.

The stand-in gateway's tests buy as a named identity, `buyer`, so the
printed flags can be asserted.

Extracted from PR #824.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015aem4tPs4TYVZb8k4LMbJJ

This branch has not been deployed

No deployments
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.

3 participants