Skip to content

feat(buy-cycles): skill for buying cycles with a card as the CLI identity - #416

Draft
raymondk wants to merge 1 commit into
mainfrom
feat/buy-cycles-skill
Draft

raymondk wants to merge 1 commit into
mainfrom
feat/buy-cycles-skill

Conversation

@raymondk

@raymondk raymondk commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

What

A new buy-cycles skill: an agent drives a card purchase of cycles for the CLI's own identity through an on-chain cycles gateway, hands the Stripe Checkout URL to the human, waits for delivery, and continues the deploy as the same identity. No Internet Identity sign-in, no icp identity link web.

It documents the icp cycles buy command proposed in dfinity/icp-cli#812 as the primary path, and the equivalent icp canister call sequence against the CyclePay gateway (saz2a-riaaa-aaaay-aadha-cai) for CLIs that predate it. That fallback was run end to end on 2026-10-07 against a local gateway with a real Stripe sandbox: PEM identity → create_order → hosted Checkout → webhook → icrc1_transfer → cycles on the PEM principal's cycles-ledger account.

Why

Today a developer with a card and no ICP buys in a browser as an Internet Identity principal and then has to link the CLI to it (id.ai CLI access toggle, icp identity link web --app, set default, verify). With the CLI identity as the buyer all of that disappears, and an agent can do the whole thing except the payment itself.

Status

Draft. Open until:

npm run validate passes for the new skill.

Evaluation results
━━━ paid and needsReview states ━━━

  Running WITH skill...
  Running WITHOUT skill...
  Judging WITH skill...
  Judging WITHOUT skill...

  WITH skill: 3/3 passed
    ✅ Says no for `paid`: the card was charged and the gateway is retrying the ledger transfer
    ✅ Says `needsReview` needs a gateway operator; report the order id and the charge, do not retry
    ✅ Does not suggest creating a replacement order in either case

  WITHOUT skill: 1/3 passed
    ❌ Says no for `paid`: the card was charged and the gateway is retrying the ledger transfer
       → It says no, but describes `paid` as generic processing time and never says the card was charged or that the gateway is retrying the ledger transfer; it also admits it doesn't know the semantics.
    ❌ Says `needsReview` needs a gateway operator; report the order id and the charge, do not retry
       → It says to contact support with the order ID and not re-order, but it never mentions reporting the charge and never names a gateway operator, so the match is only partial.
    ✅ Does not suggest creating a replacement order in either case

━━━ Simulation allow-list ━━━

  Running WITH skill...
  Running WITHOUT skill...
  Judging WITH skill...
  Judging WITHOUT skill...

  WITH skill: 2/2 passed
    ✅ Explains the gateway is in simulation mode and sells only to allow-listed principals
    ✅ Says the buyer cannot fix it; a gateway controller must allow-list the principal, which the agent should name

  WITHOUT skill: 0/2 passed
    ❌ Explains the gateway is in simulation mode and sells only to allow-listed principals
       → The output never mentions simulation mode and only speculates about a generic allowlist or eligibility rule, while stating it doesn't recognize the error.
    ❌ Says the buyer cannot fix it; a gateway controller must allow-list the principal, which the agent should name
       → It says the buyer probably can't fix it and that the seller or gateway operator would need to approve the buyer ID, but it never names a gateway controller or the principal allow-listing, and it hedges as speculation.

━━━ Trigger Evals ━━━

  Running trigger evaluation...

  Should trigger: 7/7 correct
    ✅ "I have no ICP, how do I pay for cycles with a credit card?"
    ✅ "icp deploy says insufficient cycles and I don't have a wallet. Can I just buy some?"
    ✅ "Buy $20 of cycles for my icp identity with Stripe"
    ✅ "What does icp cycles buy do?"
    ✅ "Fund my CLI identity with cycles using a card so the agent can deploy"
    ✅ "How do I get cycles without an exchange account?"
    ✅ "The cycles gateway returned quoteChanged, what now?"

  Should NOT trigger: 7/7 correct
    ✅ "Convert 2 ICP to cycles with icp cycles mint"
    ✅ "Top up my canister from my existing cycles balance"
    ✅ "How do I check my canister's cycle balance?"
    ✅ "Add Stripe payments to my own dapp's frontend"
    ✅ "Sign in to the NNS dapp from the terminal with Internet Identity"
    ✅ "Set a freezing threshold on my canister"
    ✅ "Transfer cycles between two of my identities"

━━━ Summary ━━━

  Output evals:
    Core purchase flow: WITH 4/4 | WITHOUT 1/4
    Fallback destination and pin: WITH 4/4 | WITHOUT 0/4
    URL parsing pitfall: WITH 3/3 | WITHOUT 0/3
    tooManyOpenOrders handling: WITH 2/2 | WITHOUT 0/2
    paid and needsReview states: WITH 3/3 | WITHOUT 1/3
    Simulation allow-list: WITH 2/2 | WITHOUT 0/2
  Trigger evals: should-trigger 7/7 | should-not-trigger 7/7

🤖 Generated with Claude Code

https://claude.ai/code/session_01Twxau844tMTwyHpQJEbmBo

…I identity

Documents the `icp cycles buy` flow proposed in dfinity/icp-cli#812 and the
equivalent `icp canister call` sequence against the CyclePay gateway
(saz2a-riaaa-aaaay-aadha-cai) for CLIs that predate the subcommand. The CLI
identity is the buyer, so the cycles land on the account that runs
`icp deploy`; no Internet Identity sign-in or identity linking is involved.

Pitfalls come from an end-to-end run on 2026-10-07 against a local gateway
and a real Stripe sandbox: own-account destination, Candid underscore
stripping corrupting the checkout URL, one open order per principal,
quoteChanged as a refusal, paid/needsReview handling, same identity for buy
and deploy, the 35-minute session, and the 100 M ledger deposit fee.

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

github-actions Bot commented Oct 7, 2026

Copy link
Copy Markdown

Skill Validation Report

Validating skill: /home/runner/work/icskills/icskills/skills/buy-cycles

Structure

  • Pass: SKILL.md found

Frontmatter

  • Pass: name: "buy-cycles" (valid)
  • Pass: description: (506 chars)
  • Pass: license: "Apache-2.0"
  • Pass: compatibility: (129 chars)
  • Pass: metadata: (2 entries)

Markdown

  • Pass: no unclosed code fences found

Tokens

File Tokens
SKILL.md body 2,245
Total 2,245

Content Analysis

Metric Value
Word count 1,455
Code block ratio 0.21
Imperative ratio 0.16
Information density 0.19
Instruction specificity 0.88
Sections 7
List items 20
Code blocks 4

Contamination Analysis

Metric Value
Contamination level medium
Contamination score 0.30
Primary language category shell
Scope breadth 1
  • Multi-interface tool detected: stripe

Result: passed

Project Checks


✓ Project checks passed for 1 skills (0 warnings)

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.

1 participant