wallet-cli-usage について
Bitcoin、Ethereum、Solana のネットワークに対応する Ledger ウォレット操作用 USB コマンドラインスキルです。アカウントや取引、ステーキング、交換、暗号化、Agent の意図提案を扱い、デバイスの安全規則を示します。
主な機能
- 01Ledger ウォレットのセッションとアカウント管理
- 02残高と取引履歴の確認
- 03資産の送受信、交換、ステーキング
- 04Ledger Key Ring によるデータ暗号化
- 05承認用 Agent 意図の提案
活用シーン
- 01ウォレット残高と利用状況の確認
- 02対応資産の送金や交換
- 03ステーキングポジションの管理
- 04Ledger デバイスでの機密情報の暗号化
- 05Agent の送金や交換の承認依頼
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ ledgerhq/ agent-skills --skill wallet-cli-usageインストール後、Claude Code で/wallet-cli-usageを入力して読み込まれたか確認します。
同梱ファイルreferences/business-logic.md
詳細
wallet-cli
Ledger ウォレットの操作に対応する USB ベースの CLI です。ネットワーク:bitcoin、ethereum、solana(メインネット+テストネット)。
お好みのパッケージマネージャーでグローバルにインストールします — npm i -g @ledgerhq/wallet-cli、pnpm add -g @ledgerhq/wallet-cli、yarn global add @ledgerhq/wallet-cli、または bun add -g @ledgerhq/wallet-cli。実行:wallet-cli [flags]。
概念と背景: コマンドがそのように動作する_理由_を知りたい場合や、このスキルで簡潔に記述されている安全ルール(真正性チェック、受取アドレスの検証、セッション、サンドボックス、デバイスの競合)を確認したい場合は、
references/business-logic.mdをお読みください。
まずセッションを確認: 特定のタスクを指定せずに呼び出された場合は、直ちに
session viewを実行してください — 最初にユーザーへ何をするか尋ねてはいけません。結果を表示してから、次に何をするか尋ねてください。ラベルが存在する場合は、account discoverを省略してください。
サンドボックス:
account discover、receive(--no-verifyを指定しない場合)、send(--dry-runを指定しない場合)、genuine-check、swap execute、earn deposit(--dry-runを指定しない場合)、earn withdraw(--dry-runを指定しない場合)、ring initは、dangerouslyDisableSandbox: trueを必ず使用してください — これらは USB 経由でデバイスを開く(node-webusb DMK トランスポートを使用する)ため、USB の制限によってブロックされます。ring encrypt、ring decrypt、ring destroy、agent-intent enroll、agent-intent recover、agent-intent sync、agent-intent sendとagent-intent swap(--dry-runを指定しない場合)、agent-intent intents、agent-intent status、agent-intent cancelはデバイスを開きませんが、同じくバイパスが必要です — OS のキーチェーンアクセス制限によってブロックされます(agent-intent enroll/recoverは Trustchain リレーへの WebSocket 接続も維持します)。ring keysはどちらも必要なく、agent-intent list/showも同様です。これらはローカルのセッションファイルを読み取るだけなので、バイパスなしで実行できます。
デバイスの競合: デバイスを操作するコマンドを並列で実行してはいけません —
[object Object]または文字化けした APDU が発生して失敗します。順番に実行してください。
デバイスの準備: デバイスを操作するコマンドを実行する前に、これから行うことを簡潔に説明してください。CLI がデバイス操作を促します — コマンドをタイムアウトさせたり、強制終了したりしないでください。例外:
genuine-checkは、通貨アプリが開いている場合、直ちに終了します([✖] Wrong app. Open Ledger dashboard., 終了コード 4)。他のデバイス操作コマンドとは異なり、ダッシュボードを対象としており、自動起動の経路がありません。実行前にデバイスがダッシュボード画面になっていることを確認してください。終了した場合は、ユーザーにダッシュボード画面へ戻ってから再実行するよう依頼してください。
曖昧な依頼 — 推測せず、確認してください。 必須パラメーターが不足している、または不明確な場合(
sendの受取人がない、account discoverのネットワークがない、ティッカーのない金額など)は、処理を中断して確認してください。ハードウェアウォレットの操作で誤った推測をすると、資金を取り戻せなくなるおそれがあります。
意図の対応表
口語的な表現をコマンドに対応付けます。アカウント参照にはセッションラベル(例:ethereum-1)を使用します。
| ユーザーの発言 | コマンド |
|---|---|
| 「ウォレットを見せて」、「何を持っているか教えて」、「始めましょう」、具体的なタスクがない | session view(何かを尋ねる前に、_直ちに_実行します) |
| 「アカウントを探して」、「ウォレットをスキャンして」、「ウォレットをインポートして」、「Ethereum/Bitcoinを設定して」 | account discover <network> |
| 「資金はどこに送ればいいですか」、「自分のアドレスを教えて」、「入金アドレス」 | receive <account> |
| 「いくら持っていますか」、「残高」、「ETHの残高はいくらですか」 | balances <account> |
| 「何を送金しましたか」、「取引履歴」、「最近のアクティビティ」 | operations <account> |
| 「XをYに送って」、「送金」、「支払い」、「取引所に出金」 | send <account> --to <address> --amount '<amount> <ticker>' |
| 「AをBにスワップ」、「変換」、「ETHをBTCに交換」、「取引」 | swap quote -> swap execute -> swap status |
| 「どこで運用できますか」、「ステーキングの利率」、「利回り/APY」、「ETH/SOLで最も高いリターン」 | earn yields [-n <network>] |
| 「何をステーキングしていますか」、「自分のステーキングポジション」、「運用残高」 | earn positions <account> |
| 「SOLをステーキングして」、「ボルトに預け入れて」、「USDCで利回りを得て」、「委任して」 | earn deposit <account> --product <id> --amount '<amount>' |
| 「ステーキングを解除して」、「ステーキング資産を引き出して」、「ボルトから償還して」、「運用を停止して」 | earn withdraw <account> … |
| 「これは本物のLedgerですか」、「真贋を確認して」、「eBayで購入しました」 | genuine-check |
| 「このファイル/環境変数を暗号化して/トークンを公開して」、「GPGの代替」、「シークレットマネージャー」、「Ledgerを使ってどこでも復号して」 | ring init -> ring encrypt --key <name> / ring decrypt --key <name> |
| 「リングにどんなキーがありますか」、「暗号化に使用したドメイン/プロジェクトを一覧表示して」 | ring keys |
| 「キーリングを消去して」、「リングを破棄して」、「LKRPメンバーシップを解除して」 | ring destroy |
| 「このエージェントを登録して」、「エージェントにインテントを提案させて」、「ボット用にAgent Intentを設定して」 | agent-intent enroll --profile <id> --name <name> --source <runtime>(デバイス不要。承認されるまで待機します) |
| 「このエージェントを復旧して」、「エージェントをトラストチェーンに再登録して」 | agent-intent recover --profile <id>(デバイス不要。承認されるまで待機します) |
| 「登録済みのエージェントは」、「エージェントのプロファイルを一覧表示して」 | agent-intent list |
| 「そのエージェントのプロファイルを見せて」、「このエージェントのフィンガープリントは何ですか」 | agent-intent show --profile <id> |
| 「同期したアカウントを取得して」、「Ledger Syncからインポートして」、「エージェントのアカウントを同期して」 | agent-intent sync --profile <id>(デバイス不要) |
| 「エージェントに支払いをリクエストさせて」、「承認用にXをYへ送金する提案をして」 | agent-intent send --profile <id> --account <label> --to <address> --amount '<amount> <ticker>'(デバイス不要、ブロードキャストは行いません) |
| 「エージェントにスワップを提案させて」、「承認用にX ETHをUSDCに交換する提案をして」 | agent-intent swap --profile <id> --account <label> --from ethereum --to <currency id> --amount <amount>(デバイス不要、ブロードキャストは行いません) |
| 「エージェントは何を提案しましたか」、「エージェントのインテントを一覧表示して」 | agent-intent intents --profile <id>(デバイス不要。次のページには--status signed,broadcast、--cursorを使用します) |
| 「自分のインテントは承認されましたか」、「インテントXのステータスは」、「署名されるまで待って」 | agent-intent status --profile <id> --intent <id>(デバイス不要。JSONのintent.statusをポーリングして状態を確認し、最終状態はterminalで確認します) |
| 「インテントXをキャンセルして」、「提案を取り下げて」、「エージェントの考えが変わりました」 | agent-intent cancel --profile <id> --intent <id> --yes(デバイス不要。ユーザーが署名する前に限ります。取り消し不可です) |
| 「最初からやり直して」、「セッションをクリアして」、「デバイスを切り替えました」 | session reset |
対応範囲外 — できないことはできないと伝え、推測で対応しない
ユーザーから以下のいずれかを求められた場合、コマンドを組み立てるのではなく、wallet-cli はまだ対応していないことを伝えてください。
- NFT(ミント、送信、表示)。
- OpenPGP 互換の出力、または鍵共有/複数の受信者向けの暗号化(
ringコマンドでは、共有可能な鍵ではなく、ユーザーごとの Ledger Key Ring を使って暗号化します)。 - テストネットおよびレイヤー 2(例:Base)での
send、receive、operations、swap execute。 - 上記の Networks の行に記載されていないカスタムチェーン。
セッションとラベル
account discover はアカウントを永続化します。各アカウントには、<network>[-derivation][-env]-<n> 形式のラベルが付与されます(例:ethereum-1、bitcoin-native-1、ethereum-sepolia-1)。
すべての --account フラグは、セッションラベル(例:ethereum-1)を受け付けます。セッションにアカウントを登録するには、最初に account discover を実行してください。
Commands
| Command | Device | Sandbox | TTY† | Network |
|---|---|---|---|---|
session view | No | No | No | No |
session reset | No | No | No | No |
account discover | Yes | Required | No | Yes |
receive | Yes* | Required | No | No |
send | Yes* | Required | No | Yes |
genuine-check | Yes | Required | No | Yes |
balances | No | No | No | Yes |
operations | No | No | No | Yes |
swap quote | No | No | No | Yes |
swap execute | Yes | Required | No | Yes |
swap status | No | No | No | Yes |
assets token | No | No | No | No |
assets token-by-id | No | No | No | No |
earn yields | No | No | No | Yes |
earn positions | No | No | No | Yes |
earn deposit | Yes* | Required | No | Yes |
earn withdraw | Yes* | Required | No | Yes |
ring init | Yes | Required | Required‡ | Yes |
ring encrypt | No | Required | No | Yes |
ring decrypt | No | Required | No | Yes |
ring keys | No | No | No | No |
ring destroy | No | Required | Required‡‡ | Yes |
agent-intent enroll | No | Required | No | Yes |
agent-intent recover | No | Required | No | Yes |
agent-intent list | No | No | No | No |
agent-intent show | No | No | No | No |
agent-intent sync | No | Required | No | Yes |
agent-intent intents | No | Required | No | Yes |
agent-intent status | No | Required | No | Yes |
agent-intent cancel | No | Required | No§§ | Yes |
*receive with --no-verify, send with --dry-run, and earn deposit/earn withdraw with --dry-run need no device and no sandbox bypass.
†TTY: コマンドでユーザー入力用の対話型端末が必要かどうかを示します。
§§agent-intent cancel は端末上で確認を求めます。端末がない場合(スクリプト、AI エージェント)は --yes が必要です。
‡ring init では、リングを保護するためのパスワードが必要です。コマンドの実行前に、開発者/ユーザーが環境内で WALLET_PASS を設定しておく必要があります。エージェントが設定したり注入したりすることはありません(詳しくは Non-TTY password injection を参照)。
‡‡ring destroy は入力による確認("destroy")を求めます。非対話型シェルでは、パイプで入力してください:echo "destroy" | wallet-cli ring destroy。パスワードが設定されている場合、開発者が設定した WALLET_PASS が環境内にすでに存在している必要があります。エージェントが設定することはありません。
session view / reset
wallet-cli session view
wallet-cli session reset
account discover
wallet-cli account discover ethereum
wallet-cli account discover bitcoin
wallet-cli account discover ethereum:sepolia
ネットワーク:bitcoin(mainnet)、ethereum、solana、ethereum:sepolia、bitcoin:testnet、solana:devnet。
receive
wallet-cli receive ethereum-1
wallet-cli receive ethereum-1 --no-verify # skip device confirmation
**画面上のアドレスが端末のアドレスと異なる場合:**そのアドレスを共有または使用しないでください。ユーザーにデバイスを切断してもらい、再試行する前に genuine-check を実行してください。詳しくは references/business-logic.md の「Receive-address verification」を参照してください。
genuine-check
wallet-cli genuine-check
wallet-cli genuine-check --output json # only if a downstream caller needs to parse the result
**前提条件:**デバイスのロックが解除され、ダッシュボードが表示されていること(開いているアプリがあれば終了してください)。ホストがインターネットに接続できること(セキュアチャネルはLedgerのバックエンドに接続します。オフラインでは失敗します)。
balances
wallet-cli balances ethereum-1
wallet-cli balances ethereum-1 --output json
操作
wallet-cli operations ethereum-1
wallet-cli operations ethereum-1 --limit 20 --cursor <cursor>
ページネーション:次のカーソルは標準エラー出力(人間向け)または JSON の nextCursor に表示されます。
送信
wallet-cli send ethereum-1 --to 0xDEF... --amount '0.5 ETH'
wallet-cli send ethereum-1 --to 0xDEF... --amount '100 USDT' # ERC-20
wallet-cli send bitcoin-native-1 --to bc1q... --amount '0.001 BTC' --fee-per-byte 15 --rbf
wallet-cli send ethereum-1 --to 0xDEF... --amount '0.5 ETH' --dry-run
--amount ではティッカーが必須です。--token フラグはありません。アセットの解決にはティッカーを使用します。
Bitcoin のフラグ: --fee-per-byte <sats>、--rbf
Solana のフラグ: --mode send|stake.createAccount|stake.delegate|stake.undelegate|stake.withdraw、--validator <addr>、--stake-account <addr>、--memo <text>
EVM のフラグ: --data <hex> — コントラクト呼び出し用の生の calldata(0x で始まる 16 進数、桁数は偶数)。CLI に専用コマンドがないコントラクト操作(下記の WETH のラップ/アンラップなど)に使用します。通常のネイティブアセット/トークンの送金では省略します。
--data によるコントラクト呼び出し(ラップ/アンラップの例)
標準的なパターンは WETH のラップ/アンラップです。deposit()(引数なしで ETH を WETH にラップ)はセレクター 0xd0e30db0 で、ETH の値を --amount に指定して送信します。withdraw(uint256)(1 つの uint256 引数=wei 単位の金額で WETH を ETH にアンラップ)は、セレクター 0x2e1a7d4d の後に、32 バイトになるよう左側をゼロ埋めした金額を続けます。
# wrap 0.5 ETH into WETH
wallet-cli send ethereum-1 --to <WETH_CONTRACT_ADDRESS> --amount '0.5 ETH' --data 0xd0e30db0
# unwrap 0.5 WETH back to ETH (0.5 ETH = 500000000000000000 wei = 6f05b59d3b20000 hex, padded to 32 bytes)
wallet-cli send ethereum-1 --to <WETH_CONTRACT_ADDRESS> --amount '0 ETH' --data 0x2e1a7d4d00000000000000000000000000000000000000000000000006f05b59d3b20000
署名する前に、必ず最初に --dry-run を実行して calldata を検証してください。CLI は手動で指定した --data の意味的な正しさを検証できません。最後の防衛線はデバイス画面です。承認する前に、デバイス上でデコードされた呼び出し内容を確認してください。
スワップ見積もり
組み込みのプロバイダーリストから並列に見積もりを取得します(デバイスは不要です。アドレスはセッションアカウントから解決されます)。
通貨: --from/-f と --to/-t は Ledger の通貨 IDです。ネイティブアセット(例:ethereum、bitcoin、solana)または、親チェーンがサポート対象のネイティブスワップ通貨である場合のトークン ID(CLI がスワップに使用できるものと同じ ID)を指定します。セッションアカウントのラベルではありません。アカウントには --from-account/--to-account を使用してください。
swap quote がデフォルトで照会し、swap execute で使用できるプロバイダー: changelly、changelly_v2、cic、cic_v2、exodus、lifi、nearintents、okx、oneinch、swapsxyz、uniswap、velora。一部は、従来の Exchange アプリのパイプラインで実行される CEX/アグリゲーターです。DEX プロバイダー(uniswap、oneinch、velora、okx)は、パートナーの組み込みコインアプリで実行されます。詳しくはswap execute — DEX プロバイダーを参照してください。
アカウント: --from-account と --to-account はセッションラベルのみを受け付けます。CLI は、receive と同様に、アカウントから新しい受取アドレスを解決します。
wallet-cli swap quote --from ethereum --to bitcoin --amount 0.1 --from-account ethereum-1 --to-account bitcoin-native-1
wallet-cli swap quote -f ethereum -t bitcoin --amount 0.1 --from-account ethereum-1 --to-account bitcoin-native-1 --output json
必須項目:--from、--to、--from-account、--to-account、--amount。
swap execute
通貨: --from / -f および --to / -t は Ledger の 通貨 ID です(swap quote と同じです)。許可された親チェーン上のネイティブ資産または トークン を指定します。指定した ID は、それぞれ送信元の --account と --to-account の資産と一致している必要があります。
プロバイダー: --provider に指定できる値は changelly、changelly_v2、cic、cic_v2、exodus、lifi、nearintents、okx、oneinch、swapsxyz、uniswap、velora です。エイリアス:changelly → changelly_v2、1inch → oneinch。swap quote で選択した見積もり行に表示されるプロバイダー ID を使用してください。
DEX プロバイダー(uniswap、oneinch、velora、okx): これらは従来の Exchange アプリではなく、デバイス上のパートナーの組み込みコインアプリで、最初から最後まで実行されます(Device Intent Executor 経由)。このフローでは選択したプロバイダーの見積もりを再取得し、その後、デバイス上で承認とスワップの一連の処理(sign-approval / sign-permit2 / sign-swap / broadcast)を実行します。必要に応じてデバイスのアプリを切り替えるため、デバイスに表示される各 Open <app> と署名プロンプトを確認してください。
- EVM のみです。 DEX の実行には EVM の送信元アカウント(例:
ethereum)が必要です。EVM 以外の--accountを指定すると、従来のパイプラインに移行します。 - RFQ 見積もりは CLI ではサポートされていません。 選択した見積もりが RFQ プラン(
rfq-order/approval-then-rfq-order)に解決される場合、組み込みフローはスキップされ、実行は従来の Exchange アプリのパイプラインにフォールバックします(進行状況の行にfalling back to legacy Exchange-app pipelineと表示されます)。
その他のすべてのプロバイダー(changelly、cic、exodus、nearintents、swapsxyz、lifi、…)は、従来の Exchange アプリのパイプライン(nonce → payload → complete exchange → sign/broadcast)で実行されます。
手数料戦略: --fee-strategy には slow、medium(デフォルト)、または fast を指定できます。従来のパイプラインでは、返金チェーンのトランザクション手数料を設定します。
wallet-cli swap execute --from ethereum --to bitcoin --account ethereum-1 --to-account bitcoin-native-1 --provider changelly --amount 0.1
wallet-cli swap execute -f ethereum -t bitcoin --account ethereum-1 --to-account bitcoin-native-1 --provider changelly --amount 0.1 --fee-strategy fast
wallet-cli swap execute --from ethereum --to bitcoin --account ethereum-1 --to-account bitcoin-native-1 --provider changelly --amount 0.1 --output json
# DEX (embedded coin app): EVM-only, source and destination on an EVM chain
wallet-cli swap execute --from ethereum --to ethereum/erc20/usd_tether__erc20_ --account ethereum-1 --to-account ethereum-1 --provider uniswap --amount 0.1
必須フラグ:--from、--to、--account、--to-account、--provider、--amount。swap quote で選択した見積もり行のプロバイダー ID と一致する値を --provider に指定してください。
swap status
wallet-cli swap status --swap-id <swapId> --provider changelly
wallet-cli swap status --swap-id <swapId> --provider changelly --output json
必須フラグ:--swap-id、--provider
assets token / token-by-id
cryptoassets ストアからトークンのメタデータを解決します。デバイスもセッションも不要です。
wallet-cli assets token ethereum 0xdac17f958d2ee523a2206206994597c13d831ec7
wallet-cli assets token-by-id ethereum/erc20/usd_tether__erc20_
コントラクトアドレスがある場合は token を、ID がある場合は token-by-id を使用してください。見つからない場合はゼロ以外の終了コードを返します。
EVM 以外のチェーンでは --identifier を指定してください。
ここに表示される id は、swap quote --from / --to および swap execute --from / --to で使用できる ID と同じです。
ring — Ledger Key Ring (LKRP)
ファイルやテキストをハードウェアにルートを置いて、信頼不要で暗号化します。キーリングは Ledger Sync アプリを使って Ledger 上で一度だけプロビジョニングします。その後はデバイスなしで encrypt/decrypt を実行できます。キーは LKRP で共有されたルートから HKDF-SHA256 を使って決定論的に導出され、AES-256-GCM の外部に出ることはありません。encrypt/decrypt は呼び出しごとに信頼チェーンを復元するため、引き続き LKRP バックエンドを呼び出します。そのため、ネットワークアクセスが必要です。新しいマシンでも、シードからキーリングを復元できます。
# One-time provisioning (device required). Password comes from WALLET_PASS in the environment (see below); name the machine with --name.
wallet-cli ring init
wallet-cli ring init --name my-laptop
# File round-trip (no device after init):
wallet-cli ring encrypt --key my-oss-project -i .publish-tokens -o .publish-tokens.enc
wallet-cli ring decrypt --key my-oss-project -i .publish-tokens.enc -o .publish-tokens
# Text via stdin/stdout (clipboard pattern):
pbpaste | wallet-cli ring encrypt --key personal-notes | pbcopy
pbpaste | wallet-cli ring decrypt --key personal-notes | pbcopy
# List the keys this machine has used; tear down the ring:
wallet-cli ring keys
wallet-cli ring destroy
必ずパスワードを設定してプロビジョニングしてください。 キーリングはパスワードで保護する必要があります。
ring initの実行前に、ユーザーが環境変数WALLET_PASSを使ってパスワードを設定します(非TTYでのパスワードの渡し方を参照)。エージェントがパスワードなしでキーリングをプロビジョニングすることはありません。
復号された出力は機密情報です。
ring decryptは秘密情報を出力します。復号された内容はエージェントのトランスクリプト、ログ、スクロールバックに残るため、決してターミナルに表示したり、復号されたファイルに対してcatを実行したり、その他の方法で復号された内容を表面化させたりしないでください。decryptの出力は、上記の例のように保存先(-oを使ったファイル、別のプロセス、クリップボード)へ直接パイプするか、環境変数に格納してください。内容を再表示するおそれのある--outputやログ出力先は避けてください。
--key <name> は名前ごとの AES-256-GCM キーを導出します。復号時には一致する名前が必須です。名前は自由に指定できます(最大 253 文字、空白なし)。一般的なパターンとして、プロジェクトのスラッグ(my-oss-project)、環境タグ(openClaw-prod)、ノートブック(personal-notes)などがあります。
非TTY(CI/エージェント実行時)でのパスワードの渡し方: TTY がない場合、ring コマンドは環境変数 WALLET_PASS からパスワードを読み取ります。パスワードそのものは、開発者/ユーザーが設定する必要があります(環境にエクスポートするか、OS のキーチェーンに保存します)。エージェントがシークレットの値を選択、入力、その他の方法で扱うことはありません。エージェントは、ユーザーがすでに設定した値を参照するだけです。
- パスワードをコマンド内にそのまま書かないでください(例:
WALLET_PASS=hunter2 wallet-cli …、またはフラグを使う方法)。そのまま書くと、シェルの履歴、psの出力、CI ログ、そしてエージェントがコマンドを実行した場合はエージェントのトランスクリプトにも漏れます。一時的なパスワードやテスト用パスワードにも当てはまります。同じ形式のコマンドを実際のシークレットにも使うため、常にこの習慣を守ってください。 - コマンド置換を使って必ず渡してください。 これにより、入力するコマンド文字列にシークレットが現れなくなります。
- macOS :
WALLET_PASS=$(security find-generic-password -a default -s ledger-wallet-cli -w) wallet-cli ring encrypt … - Linux :
WALLET_PASS=$(secret-tool lookup service ledger-wallet-cli account default) wallet-cli ring encrypt …
- macOS :
- エージェントはシークレットを一切扱ってはいけません。 まずユーザーに OS のキーチェーンへパスワードを一度保存してもらい、その後は
$(…)による置換だけを参照してください。テストやring initでパスワードが必要な場合は、先にキーチェーンへ使い捨ての値を保存し(security add-generic-password -a default -s ledger-wallet-cli -w)、同じ方法で渡してください。ツール呼び出しに値をそのまま入力してはいけません。 - コマンド置換を使っても、値は子プロセスの環境に存在します(同じユーザーから
ps ewwで読み取り可能です)。これは許容されますが、キーチェーンを使う方法を優先し、値が再表示されるおそれのある--output jsonの出力先やログは避けてください。
ローテーションに関する制限: ドメインキーはリングのウォレット同期暗号化キーから導出されます。このキーは、リングメンバーが削除されると LKRP プロトコルによってローテーションされます。ローテーション後は、それ以前に暗号化されたデータを復号できなくなります(復号に失敗すると、「wrong key name, corrupted data, or the Ledger Key Ring rotated」というエラーが発生し、CLI は ⚠ Ledger Key Ring rotated という警告を表示します)。メンバーを削除した後は、影響を受けるデータを新しいリングで再暗号化してください。間違ったパスワードを入力すると ring destroy は中止され、変更は行われません。また、WALLET_PASS が設定されていても値が空の場合(キーチェーンの検索に失敗した場合)も同様です。これはスキップではなく入力ミスとして扱われるため、リモートリングが孤立することはありません。リモート側の削除を意図的にスキップし、ローカルの認証情報だけを消去するには、対話型のパスワードプロンプトで Enter キーを押してください。
Agent Intent
ringとは異なる信頼モデルです。 エージェントはソフトウェアのみで動作する LKRP メンバーです。独自の Agent Intent(App-18)Trustchain に参加し、ユーザーの Ledger Sync(App-16)ストリームへのアクセス権を付与されますが、デバイスを開くことはなく、ringの(App-17)ドメインキーを受け取ることもありません。
Agent Intent は、リモートエージェント(人間による確認のためにトランザクションの意図を提案するボット)を、このマシン上のソフトウェア ID として登録します。登録・復旧・一覧表示・詳細表示・同期にデバイスは不要です。各プロファイルにはそれぞれ独自の secp256k1 キーペアが割り当てられます。秘密鍵が OS のキーチェーンの外に出ることはなく、画面への表示、ログへの記録、コマンド出力(人間向け、--output json のいずれも)への出力もありません。
# Create a pending profile, print its signed enrollment URL + fingerprint, then BLOCK until the
# human approves in the Agent Intent frontend (default environment: production):
wallet-cli agent-intent enroll --profile my-bot --name "My Bot" --source claude-code
wallet-cli agent-intent enroll --profile my-bot --name "My Bot" --source other \
--environment staging --expires-in 2h
# Re-enroll an enrolled profile's existing key into its previous Trustchain, then
# BLOCK until approved (environment/keycloak come from the profile):
wallet-cli agent-intent recover --profile my-bot
# List/inspect local profiles (never reveals the secret key):
wallet-cli agent-intent list
wallet-cli agent-intent show --profile my-bot
# Import the Ledger Sync accounts the agent was granted into the session (explicit, never automatic):
wallet-cli agent-intent sync --profile my-bot
wallet-cli agent-intent sync --profile my-bot --output json
常に --source を指定してください。 これはエージェントの実行環境またはハーネスを指し、モデルプロバイダーではありません。指定できる値は openclaw、hermes、claude-code、codex、cursor、muse、grok-bot、またはいずれにも該当しない場合の other です。省略すると other が既定値になります。フロントエンドにはエージェントのソースとして表示されます。このリストにない値は指定しないでください。
ブロッキングコマンドは 1 つだけ。コピー&ペーストは不要です。 enroll はまず URL を出力し(--output json の場合は enrollment-pending NDJSON イベント)、その後、署名済みリクエストにバインドされた暗号化 Trustchain リレーチャネルで待機します。フロントエンドはこのチャネル経由で完了通知を送信します。complete コマンドも、JSON を手動で入力する方法もありません。最終的な enrolled 結果が出力されるまでプロセスを実行したままにしてください(json では status: "success"、enrolled: true、trustchainId、accountAccessEnvironment)。待機時間は --expires-in で制限されます(既定値は 30m)。
リレーからの情報だけを信頼することはありません。 保存する前に、enroll は完了通知の正当性を証明します。エージェントの鍵で、申告された Trustchain の App-18 アクセストークン(Keycloak)を取得できること、および申告された App-16 ストリームに対して、期待される権限のみで認証できることを確認します。確認が完了して初めて、trustchainId と(秘密ではない)accountAccess の参照情報がプロファイルに書き込まれます。
タイムアウト、Ctrl+C、または確認の失敗時は、プロファイルは pending(その後 expired)のままになり、再開できません。新しい --profile ID を指定して、新たに登録してください。
復旧では同じ鍵を再利用します。 recover --profile <id> は、プロファイルに既存の鍵と Trustchain の復旧リクエストに署名します(新しい鍵は作成せず、accountAccess も変更しません)。その後、enroll と同じようにリレーで待機します(json では recovery-pending イベントに続いて status: "success"、recovered: true、trustchainId が出力されます)。記録された公開鍵と一致するキーチェーン鍵を持つ登録済みプロファイルであれば、--source の値にかかわらず復旧できます。完了通知には、同じエージェント鍵、同じ署名済みリクエスト、同じ Trustchain が指定されていなければなりません。また、エージェントの鍵でその Trustchain の App-18 トークンを取得できなければなりません(App-16 は再確認されません)。待機中は list/show に recovering と表示されます。タイムアウト、Ctrl+C、または確認の失敗時はマーカーがクリアされ、以前のデータを保持したままプロファイルは enrolled の状態になります。再試行するには recover を再実行してください。
フィンガープリントで安全性を確認します。 enroll は登録 URL とともに公開鍵のフィンガープリントを出力し、その後も show はすべてのプロファイルについて同じフィンガープリントを出力します。承認する前に、Agent Intent のフロントエンド/デバイスに表示されるものと照合してください。フィンガープリントが一致しない場合、登録リクエストが改ざんされたか、誤ったエージェントに送信されています。
重複防止: enroll は、セッションにすでに記録されている --profile ID の再利用を拒否します。また、その ID のキーチェーンエントリが存在するのに対応するセッション記録がない場合も拒否します(この不整合な状態を解消しない限り、同じ ID で再登録することはできません)。
キーチェーンが必要です: enroll には、動作する OS キーチェーンが必要です。macOS Keychain、Windows Credential
Manager、または Linux では、ロック解除されたコレクションを持つ稼働中の Secret Service プロバイダー(gnome-keyring や KeePassXC など)が必要です。キーチェーンがない場合(ヘッドレス Linux、コンテナー、一部の CI ランナーなど)、enroll は
Could not store the agent's secret key in the OS keychain (…) というエラーで失敗し、何も保存されません。キーチェーンを修正して同じコマンドを再実行してください。設計上、ファイルへのフォールバックはありません。
環境の分離: 各プロファイルには、登録時の環境(staging/production)が記録されます。accountAccess.environment が一致しない完了応答は拒否されるため、staging 用に登録されたプロファイルが production の Trustchain ID を保持することはありません。--bff-url と --keycloak-url で、その環境のデフォルト値を上書きできます(http(s) のみ。user:pass@ は不可)。
ステータスは保存されず、導出されます: list/show は、trustchainId、enrollmentExpiresAt、および有効期限内のリカバリーマーカーから pending/enrolled/recovering/
expired を算出し、登録後は許可されたアカウントアクセス(環境 +
App-16 アプリケーションパス)を表示します。
Ledger Sync アカウントの同期
agent-intent sync --profile <id> は、他の Ledger Wallet インスタンス(デスクトップ、モバイル)から同期されたアカウントをインポートし、ラベルで参照できるようにします。認証には、フロントエンドが登録時に App-16 ストリームへ追加したエージェント自身のキー(OS キーチェーンから取得)を使用します。デバイスを開くことはなく、別途 Ledger Sync に登録する必要もありません。環境はプロファイルの accountAccess から取得します。
- 登録済みプロファイルが必要です:
pending/expiredプロファイル(accountAccessなし)またはキーチェーンキーが見つからない場合は、明確なエラーで失敗します。 - アクセス喪失は報告されますが、修復はされません: エージェントが Ledger Sync から削除されている場合、
syncは「Ledger Sync へのアクセスがなくなりました」と報告し、何も削除しません。 - キーのローテーションに追従します: Ledger Sync がキーをローテーションした場合(メンバーが削除された場合)、プロファイルの
accountAccessは新しいアプリケーションパスに更新され、同期が続行されます。 - 追加型で冪等です: セッションアカウントを削除または再ラベル付けすることはなく、何もアップロードしません。再実行すると、
unchangedのエントリーまたは「Up to date」が報告されます。 - 未対応または不正な形式のエントリーは個別に処理されます: wallet-cli が対応していない通貨ファミリーのウォレット(bitcoin/evm/solana のみ)のアカウントは
skipped、不正な形式のアカウントはinvalidとなります。残りのインポートは続行され、invalidのエントリーがある場合、次回の同期でデータが最新と判定されません。
支払いの提案(agent-intent send)
agent-intent send は、人が確認するために Ethereum または Solana への送金を提案します。署名やブロードキャストは一切行わず、デバイスも必要ありません。プロファイルのキーで提案に署名して Agent Intent サービスに送信し、確認用リンクを出力します。支払いが実行されるのは、人がそのリンクを開き、Ledger デバイスで承認した場合のみです。
# Native ETH, sender from a session label:
wallet-cli agent-intent send --profile my-bot --account ethereum-1 \
--to 0xRecipient --amount '0.01 ETH' --description "Invoice #42"
# ERC-20: pass the token contract; the ticker in --amount must match it:
wallet-cli agent-intent send --profile my-bot --from 0xSender \
--to 0xRecipient --amount '25 USDC' --token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
# Native SOL: the 'SOL' ticker makes it a Solana send; base58 addresses, optional on-chain memo:
wallet-cli agent-intent send --profile my-bot --account solana-1 \
--to RecipientBase58 --amount '0.5 SOL' --memo "Invoice 42"
# SPL token: a base58 --token is the mint, so the send is on Solana:
wallet-cli agent-intent send --profile my-bot --account solana-1 \
--to RecipientBase58 --amount '25 USDC' --token EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
# Validate everything and print the proposal without submitting (no keychain, no sign-in):
wallet-cli agent-intent send --profile my-bot --account ethereum-1 \
--to 0xRecipient --amount '0.01 ETH' --dry-run
- 登録済みプロファイルのみ(
agent-intent enrollの承認が完了していること)。プロファイルの環境と、登録時に記録された BFF および Keycloak の URL を使用します(そのため、登録時の--bff-url/--keycloak-urlの上書き設定は引き継がれます)。キーは OS のキーチェーンから取得します。 - メインネットのみ: ETH および ERC-20 には Ethereum、SOL および SPL トークンには Solana を使用します。
--tokenの形式に基づいてネットワークが選択されます(0xで始まるコントラクト → Ethereum、base58 のミントアドレス → Solana)。指定しない場合は、SOL→ Solana、それ以外のティッカー → Ethereum になります。--accountラベルは、そのネットワークのメインネットアカウントである必要があります。Agent Intent SDK にはテストネットがないため、ステージングプロファイルでもメインネットへの送金を提案します。 - アドレス: Ethereum では、
--from、--to、--tokenは0xと 40 桁の 16 進数で構成されている必要があります。また、大文字と小文字が混在する入力は EIP-55 チェックサムに合格する必要があります。これにより、コピーしたアドレスの入力ミスを検出できます。Solana では、--fromと--toは正規形式の base58 32 バイトアドレスである必要があります。 - トークンは CAL(
assets token ethereum|solana <address>)で検索され、--amountのティッカーと一致している必要があります。Agent Intent はまだ Token-2022 ミントを送信できないため、これらは拒否されます。 - Solana ではサービスが優先手数料を設定するため、
--fee-strategyは指定できません。--memo(1~280 文字。絵文字は 2 文字として数えます。Solana のみ)は、送金とともにオンチェーンに記録されます。 - 金額は正確に扱われ、丸められることはありません。 アセットの小数桁数を超える値、ゼロ、または uint256(Solana では u64 lamports)を超える金額はエラーになります。JSON 出力では、
amountは基準単位(wei、トークン単位、または lamports)で文字列として示され、エンベロープのnetworkはethereum:mainまたはsolana:mainになります。 --fee-strategy slow|medium|fast(Ethereum のみ。デフォルトはmedium)は、人が承認を求められる手数料レベルです。wallet-cli は送信者の残高を確認しません。インテントを確認する人が残高を確認する責任を負います。- やみくもに再試行しないでください。 サービスがリクエストを受け付けた場合(タイムアウトや、リンクを読み取れない場合など)、インテントがすでに作成されている可能性があります。再実行する前にフロントエンドを確認してください。確認しないと、重複した提案を作成することになります。サービスからの拒否理由には、次の手順(発行者の不一致がある場合は再登録するなど)が説明されます。
スワップの提案(agent-intent swap)
agent-intent swap は、agent-intent send と同様に、人が確認できるよう Ethereum のスワップを提案します。署名やブロードキャストは行わず、デバイスも不要で、確認用リンクを出力します。まず Swap API に見積もりをリクエストし、その後、Agent Intent フロントエンドで準備できる最良の見積もりについて、ペア、金額、プロバイダーに署名します。人がリンクを開くと、フロントエンドが新しい見積もりを取得し、トランザクションを作成します。
# Sell 0.5 ETH for USDC at the best quote (currency ids, as in `swap quote`):
wallet-cli agent-intent swap --profile my-bot --account ethereum-1 \
--from ethereum --to ethereum/erc20/usd__coin --amount 0.5 --description "Rebalance"
# Quote one provider only:
wallet-cli agent-intent swap --profile my-bot --sender 0xSender \
--from ethereum/erc20/usd__coin --to ethereum --amount 1000 --provider oneinch
# Quote and validate without submitting (doesn't read the agent key or sign in):
wallet-cli agent-intent swap --profile my-bot --account ethereum-1 \
--from ethereum --to ethereum/erc20/usd__coin --amount 0.5 --dry-run
- 登録済みプロフィールのみが対象です。
agent-intent sendと同様です。Ethereum メインネットのみに対応しています。--fromと--toにはethereumまたは Ethereum ERC-20 の通貨 ID を指定します(assets token ethereum <contract>で確認できます)。送信者には--accountのラベルまたは--senderのアドレスを指定します。 - 金額は人が使う単位(
0.5ETH、1000USDC)で指定し、丸め処理は行いません。アセットの精度を超える小数、ゼロ、符号、指数表記を指定するとエラーになります。受取額の見積もりは、購入するアセットの精度で切り捨てられます。JSON 出力では、fromAmountとtoAmountは文字列になります。 - プロバイダー: 現時点でフロントエンドがトランザクションに変換できる
oneinch、velora、okx、lifiのみです(oneinchの代わりに1inchも指定できます)。トークンの承認または Permit2 の署名が必要な見積もりはスキップされます。フロントエンドではまだ準備できないため、インテントが確認待ちのままになるためです。 --to-amountを指定すると、見積もり額ではなく、自分で指定した受取希望額に署名します。スワップの見積もり自体は行われるため、プロバイダーは常にフロントエンドが準備できるものになります。- むやみに再試行しないでください。
agent-intent sendと同様、サービスがリクエストを受け付けている場合、インテントがすでに作成されている可能性があります。
エージェントのインテント一覧(agent-intent intents)
agent-intent intents は、登録済みプロフィールが提案したインテントを新しい順に一覧表示します。send と同じようにプロフィールの鍵でサインインします。サービスから返されるのは、そのエージェント自身のインテントのみで、同じ Trustchain 上であっても、ほかのエージェントのインテントは返されません。
wallet-cli agent-intent intents --profile my-bot
wallet-cli agent-intent intents --profile my-bot --status signed,broadcast --page-size 50
# Next page: pass the previous page's nextCursor (filters and page size carry over):
wallet-cli agent-intent intents --profile my-bot --cursor <nextCursor> --output json
- 実行ごとに 1 ページです。
--page-sizeには 1、5、10、50、100 を指定します(既定値は 10 です)。インテントがさらにある場合、JSON にはnextCursorが含まれます(人向けの出力では次のページを取得するコマンドが表示されます)。最後のページではnullになります。--cursorを指定すると、--statusと--page-sizeは無視されます。 --statusには、カンマ区切りで状態を指定します:created、crafted、signed、broadcast、success、failed、rejected、cancelled、expired。不明な状態を指定すると、サインイン前に拒否されます。- JSON(
--output json):profileId、count、nextCursor、およびid、status、type、network、sender、recipient、amount(正確な最小単位の金額を示す文字列)、displayAmount(例:"0.01 ETH"。アセットが不明な場合はnull)、asset、feeStrategy、description、failureReason、createdAt、updatedAtを含むintents[]。結果がないページも成功として扱われ、count: 0になります。 - 読み取り専用: 作成、承認、キャンセルは一切行わないため、失敗しても安全に再実行できます。
インテントの確認(agent-intent status)
agent-intent status は、agent-intent send が出力した(または agent-intent intents に表示される)ID を使って、プロフィールが提案した 1 件のインテントの現在の状態と詳細を取得します。
ID=0192f7a4-0000-7000-8000-000000000001
wallet-cli agent-intent status --profile my-bot --intent "$ID"
# Poll while the intent is known to be in progress; stop on a final state (terminal: true),
# an unknown one (terminal: null) or an error, then read the status:
while wallet-cli agent-intent status --profile my-bot --intent "$ID" --output json | jq -e '.terminal == false' >/dev/null; do sleep 30; done
# To wait for one state, e.g. until the user signs, poll intent.status instead (signed is not final):
while wallet-cli agent-intent status --profile my-bot --intent "$ID" --output json | jq -e '.intent.status == "created" or .intent.status == "crafted"' >/dev/null; do sleep 30; done
- 状態:
created、crafted、signed、broadcastは進行中(terminal: false)です。success、failed、rejected、cancelled、expiredは最終状態(terminal: true)です。この wallet-cli バージョンが認識しない状態は、そのまま表示され、terminal: nullになります。最終状態やエラーとして扱わないでください。 - JSON(
--output json):profileId、terminal、およびagent-intent intentsの項目と同じフィールドを含むintent(正確な最小単位のamountを示す文字列、displayAmount、インテントが失敗した場合のfailureReason、タイムスタンプ)。 - 見つからない場合: 不明な ID と別のエージェントのインテントには同じ応答が返されるため、エラーから両者を区別することはできません。不正な形式の ID はサインイン前に拒否されます。
- エージェントが単一のインテントを読み取れるサービスが必要です。古いサービスではその旨が表示され、
agent-intent intentsを使うよう案内されます。
インテントのキャンセル(agent-intent cancel)
agent-intent cancel は、プロファイルが提案したインテントを、ユーザーがまだ署名していない場合に取り消します。インテントは編集できません。ユーザーが署名する前に提案を変更するには、いったんキャンセルして新しいインテントを送信してください。
wallet-cli agent-intent cancel --profile my-bot --intent 0192f7a4-0000-7000-8000-000000000001 --yes
- 実行条件: キャンセルできるのは、状態が
createdまたはcraftedのインテントだけです。この wallet-cli バージョンが認識しない状態はサービスに送られ、サービス側で判断されます。それ以外の既知の状態(トランザクションがまだオンチェーンに反映される可能性があるため、signedも含む)では、現在の状態を示して失敗し、何も変更しません。キャンセルは取り消せません。 - 確認: ターミナルでは、インテントを表示して stderr に
[y/N]と確認を求めます。ターミナルがない場合(スクリプト、AI エージェント、パイプ入力)は、--yesが指定されていない限り、署名インを行う前に拒否します。エージェントとして、ユーザーがこのインテントのキャンセルを依頼した場合に限り、--yesを渡してください。 - 再実行: すでにキャンセル済みのインテントをキャンセルしても成功し、
alreadyCancelled: trueが報告されます。別のキャンセル処理が先に完了した場合も同様です。その間にユーザーが署名していた場合、コマンドは失敗し、新しい状態を報告します。 - JSON(
--output json):profileId、cancelled: true、alreadyCancelled、readBack、およびキャンセル後にサービスが報告した状態のintent(agent-intent statusと同じフィールド)を返します。readBack: falseは読み取りに失敗したことを意味します。この場合、intentはキャンセル済みとしてマークされた直前の読み取り結果です。確認プロンプトでキャンセルを拒否すると、intentIdとともにcancelled: falseおよびdeclined: trueが出力されます(cancelled: trueがプロンプトでの拒否を意味するring destroyとは異なります)。 - 見つからない場合: 不明な ID と、別のエージェントのインテントには、
agent-intent statusと同じ応答が返されます。
earn(ステーキングと DeFi の利回り)
Earn には、Ethereum の ERC-4626 DeFi ボルト(入金/償還)と、Solana のネイティブステーキング(委任/委任解除)という 2 つのフローがあります。yields と positions は読み取り専用(デバイス不要)です。deposit と withdraw ではデバイス上で署名します。
deposit/withdrawに対応しているのは ethereum と solana のみです。その他のネットワークはearn yieldsに表示されます(情報提供のみ)が、CLI から入金することはできません。
earn yields
利回りの機会を一覧表示します(デバイス不要)。--network を指定しない場合は、すべてのネットワークの代表利率を表示します。-n ethereum または -n solana を指定すると、具体的な入金先も表示されます。各入金先の末尾には、earn deposit に渡す正確な → --product <id> の値が示されます。
- ethereum → ERC-4626 ボルト ID(例:
1_0x7daeba3f217614e409f85d3014d33923a6b03630)。 - solana → バリデーターの投票アカウント。CLI では、推奨先として Ledger が運営するバリデーター(「Ledger by Figment」、「Ledger by Bitwise」)が表示されます。その他の有効な投票アカウントも
--productとして使用できます。
wallet-cli earn yields
wallet-cli earn yields -n solana
wallet-cli earn yields -n ethereum --output json
バリデーター/ボルトを一覧表示する専用コマンドはありません。有効な --product を確認するには、earn yields -n <network> を使用します。JSON では、各行の vaultId(ETH)または validator(SOL)フィールドがその値です。
earn positions
アカウントの有効な Earn ポジションを一覧表示します(デバイス不要)。アカウントベースのネットワーク(solana、ethereum)のみが対象です。
wallet-cli earn positions solana-1
wallet-cli earn positions solana-1 --fresh # request a background refresh
--fresh は、古い行を非同期のバックエンド更新対象としてマークします。更新後のデータは再実行時に表示され、同じ応答には反映されません。(stale) マーカーに注意してください。
Solana のステークアカウント: Solana アカウントの場合、このコマンドはオンチェーンのステークアカウントも読み取り、それぞれについて → --stake-account <address>、state(active/inactive/activating/deactivating)、残高、バリデーターを表示します。earn withdraw に渡す --stake-account の値はここで確認できます。 JSON では、positions と並ぶトップレベルの stakes[] 配列に格納されます(各エントリには stakeAccount、validator、state、stakeBalance、withdrawable が含まれます)。該当するものがない場合、stakes キーは省略されます。バックエンドのスナップショットがまだ空でも、入金の直後からステークアカウントはここに表示されます。(チェーンの同期が必要です。接続できない場合は警告とともにバックエンドのスナップショットが表示されます。)
earn deposit
Solana でステーキングするか、Ethereum でボールトに預け入れます。署名のためにデバイスにアクセスするため、サンドボックスをバイパスします。--product は earn yields -n <network> から取得します(上記を参照)。--amount にはティッカーが必要です。
# Solana: --product is a validator vote account
wallet-cli earn deposit solana-1 --product 26pV97Ce83ZQ6Kz9XT4td8tdoUFPTng8Fb8gPyc53dJx --amount '1.5 SOL'
# Ethereum: --product is a vault id
wallet-cli earn deposit ethereum-1 --product 1_0x7daeba3f217614e409f85d3014d33923a6b03630 --amount '100 USDC'
# Validate without signing (no device, no sandbox bypass)
wallet-cli earn deposit solana-1 --product 26pV97… --amount '1.5 SOL' --dry-run
Solana の stake.createAccount は、1 回のトランザクションでステークアカウントを作成し、委任します。Ethereum の預け入れでは、2 回のトランザクション(ERC-20 の approve の後に deposit)が実行される場合があります。
初回の ETH ボールトへの預け入れでは、ドライランで預け入れ処理を検証できません。 これまで利用したことのないボールトへの初回の預け入れは approve → deposit の順に行われ、オンチェーンにゼロ以外のアローワンスが存在しないと、預け入れ処理を構築できません。--dry-run では何もブロードキャストされないため、まだ approve が必要な場合、CLI は approve を検証し、バックエンドの不明瞭な 500 エラーを表示する代わりに、預け入れ処理の構築をスキップします(ステータスは not-simulated …、全体の結果は dry-run: approve validated; deposit needs an on-chain allowance to simulate)。これは想定どおりの動作であり、残高エラーではありません。預け入れ処理を検証する唯一の方法は、実際に実行することです(approve をブロードキャストし、確認を待ってから deposit を実行します)。ここでドライランが問題なく完了しても、「approve は問題なし」と判断してください。オンデバイスでの署名は取り消せないため、実行前にユーザーに確認してください。アローワンスが存在すれば、--dry-run を再実行することで、通常どおり預け入れ処理をシミュレートできます。
earn withdraw
ステーキングを解除するか(Solana)、ボールトから償還します(Ethereum)。デバイスにアクセスするため、サンドボックスをバイパスします。
- Ethereum:
--product <vault-id>は必須で、--amountは省略可能です。金額はボールトの資産単位です(例:'50 USDC')。ティッカーを指定する場合は、ボールトの資産と一致する必要があります。全額を引き出す場合は--amountを省略してください。 CLI はamount:"max"を送信し、バックエンドはシェア残高全体を償還するため、端数は残りません(シェアから資産へのレートは変動するため、全額を引き出す場合に資産額を自分で計算しないでください)。 - Solana:
--stake-account <address>は必須です。2 段階で行います。 まず 1 回実行してundelegate(非アクティブ化)し、非アクティブ化のエポック境界(約 2〜3 日)まで待ってから、再度--finalizeを指定して実行し、非アクティブになったラムポートをメインアカウントに引き出します。coin-solana は引き出し可能な金額をオンチェーンで計算するため、finalize 時の--amountは無視されます。
# Ethereum vault redeem
wallet-cli earn withdraw ethereum-1 --product 1_0x7daeba3f… --amount '50 USDC'
# Solana phase 1: deactivate
wallet-cli earn withdraw solana-1 --stake-account <stakeAccountAddr>
# Solana phase 2 (after ~2–3 days): withdraw
wallet-cli earn withdraw solana-1 --stake-account <stakeAccountAddr> --finalize
Solana の --stake-account アドレスは、earn positions <account> の出力から取得してください(stakes[] / → --stake-account の行)。これは、以前に earn deposit で作成されたステークアカウントです。
よくあるエラー
| エラー | 原因 | 対処 |
|---|---|---|
Amount must include a ticker | --amount にティッカーがありません | どの資産を指しているのか、ユーザーに確認します — 推測してはいけません。その後、--amount '0.5 ETH' のようにティッカーをインラインで渡します。 |
Ticker UNKN not found in account | そのティッカーはアカウント残高にありません | balances <account> を実行し、このアカウントが保有するティッカーをユーザーに提示します。使用するティッカー、または別のアカウントを指しているのかをユーザーに確認します — 別のティッカーに黙って置き換えてはいけません。 |
[✖] Wrong app. Open Ledger dashboard. (exit code 4) | 通貨アプリが開いている状態で genuine-check が呼び出されました。他のデバイスコマンドとは異なり、genuine-check はダッシュボードを対象としており、自動起動する方法がありません。 | デバイス上で前面に表示されているアプリを終了するようユーザーに依頼します(アプリのメイン画面で両方のボタンを短く押し、Quit が表示されたら確定します)。その後、genuine-check を再実行します。他のデバイスコマンド(account discover、receive、send、swap execute)ではこの問題は発生しません — 正しいアプリの起動を自動的に促すためです。 |
[✖] Rejected on device. No action taken. | ユーザーがデバイス上で署名リクエストを拒否しました | 拒否は意図的な操作です。再試行するか中止するか、ユーザーに確認します — 自動で再試行してはいけません。再試行する場合は、承認する前にデバイス画面で金額、送信先、手数料を確認してもらいます。 |
[✖] Rejected on device. App was not opened. | ユーザーがデバイス上でアプリ起動の確認を拒否しました | デバイス上でアプリ起動の確認をするようユーザーに依頼し、コマンドを再実行します。 |
[✖] Timed out talking to the Ledger over USB. The device may be busy or locked. Retry the command. | サンドボックスが USB をブロックしているか、デバイスがビジーまたはロックされています | コマンドの実行には dangerouslyDisableSandbox: true が必要であることをユーザーに伝え、バイパスを使って再実行する前に確認を求めます。デバイスコマンド(account discover、receive、send、genuine-check、swap execute、earn deposit、earn withdraw、ring init)ではバイパスが想定されています。このエラーがそれ以外のコマンドで発生した場合は、反射的にサンドボックスを無効にせず、バイパスする前に原因を調査します。 |
[object Object] または文字化けした APDU 出力 | 2 つのデバイスコマンドが並列で実行されました(競合) | デバイスにアクセスするコマンドは順番に実行します — ツール呼び出しを並列にしてはいけません。 |
[✖] Ledger not detected. Plug in, unlock, retry. (exit code 3) | デバイスの電源がオフか、接続されていません | デバイスの電源を入れてロックを解除し、USB で接続してからコマンドを再実行するようユーザーに依頼します。 |
device-state … awaiting_approval … reason: unlock (JSON stream) | デバイスがロックされています | コマンドを実行したままにします — ロック解除後、CLI が自動的に再開します。PIN を使ってデバイスのロックを解除するようユーザーに依頼します。 |