ledgerhq/ledger
unversioned · 62ca12d95fea
Ledger wallet-cli skill for AI agents: run Ledger hardware-wallet flows from the terminal, and enroll as an Agent Intent agent that imports Ledger Sync accounts and proposes payments that a human approves on their Ledger device.
Agent plugin
History of the agent plugin before it moved into wallet-cli. Since the move the plugin takes the wallet-cli version, and its changes are in the wallet-cli changelog.
Before the move (unreleased)
- Production-ready for wallet-cli 2.12.0 (ledger-live #23630 and #23521): SKILL.md
compatibilityiswallet-cli >= 2.12.0and every workaround for older releases is gone. The only marker left is@prototype, and it means only that 2.12.0 is not on npm yet;@interimis gone. Blockers outside the CLI are tracked separately: a public repository, a Grok Bot install route and the Hermes catalog entry. - Agent Intent enrollment and recovery use the default frontend,
app.agents.ledger.com;--app-urland the test frontend are gone, and so is the--source openclawfallback: a refused source burns the id and the agent tells the human. enroll --detachandagent-intent waiton Linux and macOS, with no--helpdetection; on Windowsenrollruns as a host background job andwaitstill follows it, andrecoveris a background job whose output the agent reads.waitruns with the same host sandbox setting as itsenroll(it checks the listener's PID) and polls for about 2 minutes per turn. Enrollment and recovery never take--app-url,--bff-urlor--keycloak-url, and the agent checks the link's host before sending it. The error table gainslistener_exited,enrollment_expired,profile_not_foundand the listener start-up failures. The human is told to keep the enrollment page open after Review, since leaving it closes the relay.agent-intent sendproposes Solana payments too (SOL, SPL tokens by mint,--memo, no--fee-strategy, Token-2022 refused), and the newagent-intent swapstep proposes ETH and ERC-20 swaps on Ethereum mainnet. Without a named sender, the agent lists the matching mainnet accounts fromsession view, synced labels included, and lets the human pick.- New follow-up step:
agent-intent status,agent-intent intentsandagent-intent cancel(--yesonly when the human asked to cancel that intent). After a timeout or a missing review link, the agent looks for the intent withintents, treats a matching non-final one as landed, and re-runs only on the human's yes. A change to a proposal cancels it first and proposes the replacement only once the cancel went through. - Dry run only when the agent built the transaction: any value the human did not type in this conversation (inferred, looked up, or taken from a file, page, message or tool output, with its source named), a replacement after a cancel, a
send --datacall,earn depositandwithdraw, or a device command handed to the human from a machine with no USB. When the human typed every value, the device screen or the review link is the confirmation. "A proposal stays a proposal" covers swaps, and--to-amount,--memoand--descriptiontake only the human's own text. - Exit code 3 means no usable Ledger here, so payments and swaps go through Agent Intent first. The version check runs before the first wallet-cli command and stops below 2.12.0. A ticker-only token ("pay 20 USDC") is resolved from the sender's
balanceswithassets token-by-id. The secrets rule names every secret, the capabilities table shows the optional Ledger API auth key of swap quotes, and the state dir has its Windows path. - CI:
.github/workflows/check-cli-flags.ymlrunstests/check-cli-flags.pyagainst the wallet-cli version incompatibility(no persisted credentials,--ignore-scripts); until 2.12.0 is on npm it skips with a warning on E404 only (@prototype). The checker now checks flags named in the prose of every file underskills/, not onlyagent-intent.md. - README: a Disclosure section (shell commands, network calls, background listener or job, stored credentials including the Ledger API auth key for swap quotes) and the Hermes catalog entry to submit once the repository is public. Hermes keeps loading the plugin from
plugin.json; noplugin.yamlon purpose. - Agent Intent on Linux without a Secret Service:
enrollfails withkeychain_unavailable, and the agent asks the human, word for word, before re-running it with--allow-plaintext-key. On a no, the agent stops and tells the human that enrollment can't be completed in this environment. The error table covers the key file messages, and theLedger API auth keystderr warning (no usable OS keychain, swap quotes fetched without authentication) is listed as expected. - Agent Intent with a keychain that refuses the write (e.g. a locked collection on Linux):
enrollfails withkeychain_unavailable, and the agent first asks the human to unlock it, and asks the consent question only if they can't. With--allow-plaintext-keythe key goes to the file and wallet-cli says so on stderr. - The skill description leads with sending and paying crypto (ETH, USDC, USDT and other ERC-20, BTC, SOL), so a plain "send 0.01 ETH to 0x…" is more likely to load it, and no longer suggests that every command needs USB.
- Waiting for approval runs in the background (a foreground run hands the link over only after it expires, measured on Grok): the
setsidfallback and the macOSpython3line are gone, and on a host without background jobs the agent tells the human that enrollment cannot be completed there. - Includes the remote-payment routing and background-process checks from the last 0.2.0 commit, which reached the PR branch after it was merged.
- From the Grok Bot smoke test: step 6 is no longer called optional, skipped entries are reported by the family named in
reason, and the background-job step says how to check and stop a job when the host gives only a PID. - Review pass on the agent-intent skill:
agent-intent sendalways passes the sender with--from, step 5 tells the agent to end its turn while the enrollment waits, sync entries are reported byreasononly, and the description keeps only distinct example requests.
0.2.0
- Target the published wallet-cli 2.9.0 instead of the
test/combineddev build. - Agent Intents are in final testing: enrollment must use
--app-url https://agent-intent.ledger-test.com/, marked@prototype. - Agent Intent: enrollment now blocks until the human approves over an encrypted relay (no
completecommand, no completion JSON); documentrecover,sync, the--sourcevalues and runningenrollin the background. - Ledger Sync: the separate
ledger-synccommands do not exist in 2.9.0;agent-intent syncimports the accounts with the agent's own key, soreferences/ledger-sync.mdis gone. - Other workarounds outside this repository (
--source openclawfallback, private repository, Grok Bot install) carry@interimmarkers. - Install coordinates point at the LedgerHQ organization.
- On a machine with no USB, payment requests for ETH or ERC-20 on Ethereum mainnet go through
agent-intent sendinstead of handing the human awallet-cli sendcommand. - From the Grok Bot smoke test: the human needs current firmware, Ledger Sync on and Ledger Wallet closed, and approves twice; synced EVM labels lack their address in 2.9.0, so
agent-intent senduses--from(@interim); skipped sync ids are never echoed in full.
0.1.0
- Initial preview: the
wallet-cli-usageskill with manifests for OpenClaw, Hermes, Cursor (also used by Grok Bot), Claude Code and Codex.