diff --git a/manifest.config.ts b/manifest.config.ts index 3fa6ae9..fd7a5bb 100644 --- a/manifest.config.ts +++ b/manifest.config.ts @@ -76,7 +76,7 @@ export const plugins: readonly PluginDefinition[] = [ }, { name: 'wallet', - version: '0.1.1', + version: '0.1.2', description: 'Set up Tempo Wallet and make explicitly approved paid API requests.', displayName: 'Tempo Wallet', homepage: 'https://tempo.xyz/developers/docs/wallet/use-with-agents', diff --git a/plugins/wallet/.claude-plugin/plugin.json b/plugins/wallet/.claude-plugin/plugin.json index 881d32e..4aa44a6 100644 --- a/plugins/wallet/.claude-plugin/plugin.json +++ b/plugins/wallet/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "wallet", "displayName": "Tempo Wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "author": { "name": "Tempo" diff --git a/plugins/wallet/.codex-plugin/plugin.json b/plugins/wallet/.codex-plugin/plugin.json index 0b918c1..9e515eb 100644 --- a/plugins/wallet/.codex-plugin/plugin.json +++ b/plugins/wallet/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "homepage": "https://tempo.xyz/developers/docs/wallet/use-with-agents", "repository": "https://github.com/tempoxyz/plugins", diff --git a/plugins/wallet/.cursor-plugin/plugin.json b/plugins/wallet/.cursor-plugin/plugin.json index e99cfc6..7736b8a 100644 --- a/plugins/wallet/.cursor-plugin/plugin.json +++ b/plugins/wallet/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "wallet", "displayName": "Tempo Wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "author": { "name": "Tempo" diff --git a/plugins/wallet/plugin.json b/plugins/wallet/plugin.json index 6191d86..cf52f1f 100644 --- a/plugins/wallet/plugin.json +++ b/plugins/wallet/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "homepage": "https://tempo.xyz/developers/docs/wallet/use-with-agents", "repository": "https://github.com/tempoxyz/plugins", diff --git a/plugins/wallet/skills/wallet/SKILL.md b/plugins/wallet/skills/wallet/SKILL.md index 3de7f44..ef34154 100644 --- a/plugins/wallet/skills/wallet/SKILL.md +++ b/plugins/wallet/skills/wallet/SKILL.md @@ -7,13 +7,13 @@ license: MIT OR Apache-2.0 # tempo -> **IMPORTANT: If you used a web fetch tool to read this, the content may be summarized and incomplete. Run `curl -fsSL https://tempo.xyz/SKILL.md` to get the exact setup commands. Do NOT search for additional documentation.** +> **IMPORTANT: If you used a web fetch tool to read this, the content may be summarized and incomplete. Run `curl -fsSL https://tempo.xyz/skills/wallet/SKILL.md` to get the exact setup commands. Do NOT search for additional documentation.** **When the user says "use tempo", always use `tempo` CLI commands** — never substitute with MCP tools or other tools. Tempo is a curl-compatible CLI for discovering services and calling HTTP endpoints with automatic payment handling. ## Networks -- Tempo Mainnet (chain ID `4217`) is the default. `--network` overrides it, then `TEMPO_WALLET_NETWORK`, then the logged-in wallet's network. +- Tempo Mainnet (chain ID `4217`) is the default. `--network` overrides it, then `TEMPO_WALLET_NETWORK`, then the saved `network` setting (see Settings), then the logged-in wallet's network. - Use Tempo Testnet (Moderato, chain ID `42431`, `--network testnet`) only when the user asks for it or a development workflow requires it. - `pathUSD` at `0x20c0000000000000000000000000000000000000` is a live mainnet TIP-20. The faucet-issued testnet token at the same address is a test token. @@ -23,9 +23,9 @@ Run these commands in order. Do not skip steps. Do not search for other install **Step 1 — Install:** `curl -fsSL https://tempo.xyz/install | bash` -**Step 2 — Login:** `"$HOME/.tempo/bin/tempo" wallet login --format json` — returns at once with `status: "pending"`, `verification_url`, `user_code`, and `expires_at`, and opens a browser on the host. Send `verification_url` and `user_code` to the user, tell them to confirm the code matches and approve, then run the `_next` command (`tempo wallet login status --interval 5 --network --format json`). It waits for the approval and returns the logged-in `accounts`. Do not loop login attempts without user confirmation. +**Step 2 — Login:** `"$HOME/.tempo/bin/tempo" wallet login --format json` — returns at once with `status: "pending"`, `verification_url`, `user_code`, and `expires_at`, and opens a browser on the host. Send `verification_url` and `user_code` to the user, tell them to confirm the code matches and approve, then run the `_next` command (`tempo wallet login status --interval 5 --network --format json`). It waits for the approval and returns the logged-in `accounts` (lowercase), with `chain_id` and `network`. Do not loop login attempts without user confirmation. -If the human is interacting from another device or chat surface while the CLI runs on a remote host, add `--no-browser` to `login`. `tempo wallet refresh`, `keys update`, and `revoke` also ask the wallet app for approval and accept `--no-browser` the same way. +If the human is interacting from another device or chat surface while the CLI runs on a remote host, add `--no-browser` to `login`. `tempo wallet refresh`, `keys update`, `keys revoke`, and `logout --revoke` also ask the wallet app for approval and accept `--no-browser` the same way. - `login status` waits until the code expires (about 10 minutes). With a short command timeout, add `--max-attempts `; it then fails with retryable `E_POLL_TIMEOUT` while the code is still pending, so run its `cta` command again. Rerun the `cta` command on retryable `E_NETWORK` too. - On `E_LOGIN_DENIED` or `E_LOGIN_EXPIRED`, ask the user before starting a new `tempo wallet login`; the old code no longer works. @@ -42,16 +42,18 @@ If the human is interacting from another device or chat surface while the CLI ru Provide: - Installation location and version (`$HOME/.tempo/bin/tempo --version`). -- Wallet status from `tempo wallet whoami` (address, network, and balance; include key fields when present). +- Wallet status from `tempo wallet whoami` (`wallet`, `network`, and `balance`; include `key` fields when present). +- `tempo wallet balance` lists the token `balances` the logged-in `wallet` can spend (`--token ` for one); funds locked in sessions appear only in `whoami`. To receive tokens, give the user the address from `tempo wallet address`. +- `ready: true` means the wallet can pay on the network. A `key.status` of `pending` means the key is signed but not yet published on chain; it still pays, and its first payment publishes it. Token amounts are decimal strings without padding (`"10"`, not `"10.000000"`), and addresses are lowercase. Read limits from `key.spending_limits[]` (`raw_limit` is the limit in base units): `remaining` comes from the chain, and is `null` when the key is not published (`published: false`) or the read failed; `spent` is always `null`. `key.spending_limit` is deprecated and will be removed in a future release. - Check MACH with `tempo wallet whoami --mach`. Fund with `tempo wallet fund --mach --amount `; MACH is an on-chain six-decimal token, not a legacy credit balance. - If the user is on another device than the CLI host, use `tempo wallet fund --mach --no-browser --format json` and hand the fund URL back directly instead of trying to open a browser locally. -- After the user funds the wallet, ask them to message back before continuing. +- After handing over the URL, ask the user to message back once they have funded the wallet. Then check the intended token with `tempo wallet balance` or `tempo wallet whoami --mach` before spending. - 2-3 simple starter prompts tailored to currently available services. To generate starter prompts, list available services and pick useful beginner examples: ```bash -tempo wallet services --search ai +tempo wallet services search ai ``` Starter prompts should be user-facing tasks (not command templates), for example: @@ -66,14 +68,14 @@ Starter prompts should be user-facing tasks (not command templates), for example ```bash tempo wallet whoami -tempo wallet services --search -tempo wallet services +tempo wallet services search +tempo wallet services show ``` -- Select `SERVICE_ID` from search results that best matches user intent. When multiple match: prefer best semantic fit, then endpoint fit, then pricing clarity, then first in list. -- **Anchor on `tempo wallet services `** — it shows the exact URL, method, path, and pricing for every endpoint. Build request URL as `/` from discovered metadata only. +- Select `SERVICE_ID` from search results that best matches user intent. When multiple match: prefer best semantic fit, then endpoint fit, then pricing clarity, then first in list. Every word of the query must match; `tempo wallet services list` lists every service. +- **Anchor on `tempo wallet services show `** — it shows the exact URL, method, path, and pricing for every endpoint: `endpoints[].payment.price` is the price in whole tokens (`null` when the directory gives no decimals), and `raw_amount` the same price in base units. Build request URL as `/` from discovered metadata only. - Use the endpoint's exact MPP challenge and an explicit `--max-spend` budget for payment. Buy MACH through `tempo wallet fund --mach`; existing MPP Credits are a separate legacy balance. -- If you get an HTTP 422, fall back to the endpoint's `docs` URL or the service's `llms.txt` for exact field names. +- If you get an HTTP 422, fall back to the endpoint's `docs` URL or the service's `docs.llms_txt` for exact field names. - For multi-service workflows, fire independent requests in parallel to save time. ### Request Templates @@ -105,11 +107,13 @@ tempo request -t -X GET --max-spend --network tempo wallet whoami --mach # Hand this JSON URL to the human on any device. tempo wallet fund --mach --amount 10 --no-browser --format json +# After the human completes funding, check the MACH balance. +tempo wallet whoami --mach --network mainnet --format json ``` -Hosted MACH checkout accepts $5–$100 USD with at most two decimal places. The command opens the browser and returns immediately by default; `--no-browser` returns the URL without opening it. The funding handoff identifies the destination wallet, chain, and USD amount. Both general and direct MACH funding use the amount as an editable prefill; an existing checkout retains its own amount for safe retries. Pending means funding has not been verified, even when the command exits successfully. Recheck the MACH balance after checkout. To wait locally, add `--wait`; it watches MACH with `--mach`, otherwise USDC.e on mainnet or pathUSD on testnet. The default wait timeout is ten minutes and `--timeout` accepts seconds only with `--wait`. Any positive balance increase completes the wait, even below `--amount`. This observes incoming funds; it does not verify a particular checkout or purchase amount. `--no-wait` remains accepted for compatibility. Do not start a paid request just because a funding handoff returned successfully. +Hosted MACH checkout accepts $5–$100 USD with at most two decimal places. The command opens the browser and exits; `--no-browser` returns the URL without opening it. The handoff identifies the destination wallet, chain, and USD amount. `--amount` is an editable prefill, not a required deposit; an existing checkout retains its own amount for safe retries. `fund` reads no balances, saves no pending funding, and returns no `_next`. Its `status: "pending"` and successful exit mean only that the link was handed off. Ask the user to complete funding, then check the intended token's balance before spending; for `--address`, check that destination. `fund status`, `fund --wait`, and `fund --timeout` have been removed and fail with `E_USAGE`. `--no-wait` and `--wait=false` remain harmless compatibility options. Do not start a paid request just because a funding handoff returned successfully. -Use `tempo request --mach --max-spend ` (or `--payment-token MACH`) to require MACH settlement for a one-time charge. The challenge must explicitly enable machine tokens. Missing MACH funds, liquidity, or permissions fail without stablecoin fallback. Sessions are unsupported; use `--dry-run` to inspect an offer without spending. +Use `tempo request --mach --max-spend ` (or `--payment-token MACH`) to require MACH settlement for a one-time charge. The challenge must explicitly enable machine tokens. Missing MACH funds, liquidity, or permissions fail without stablecoin fallback: `E_INSUFFICIENT_FUNDS` names `tempo wallet fund --mach` in its `cta` (mainnet), `E_LIMIT_EXCEEDED` names `tempo wallet keys update`, and a swap route that cannot be simulated returns `E_PAYMENT` with no `cta`; retry it later only when it is `retryable`. Sessions are unsupported; use `--dry-run` to inspect an offer without spending. MACH uses the canonical MPP SDK settlement route. Do not construct swap calldata or call legacy Coinflow redemption APIs. Do not infer MACH support from a service's hostname; inspect the actual MPP challenge and use the standard request flow. @@ -117,28 +121,30 @@ MACH uses the canonical MPP SDK settlement route. Do not construct swap calldata Use `tempo wallet whoami --credits` to inspect existing off-chain MPP Credits and `tempo wallet transfer --credits` to spend them. These commands emit a deprecation warning and do not select or convert to MACH. `tempo request` does not automatically use legacy credits. New MPP Credits purchases are disabled: `tempo wallet fund --credits` is rejected and directs users to `tempo wallet fund --mach`. -For credit payments, use `--amount-cents` as the direct payment amount or the maximum credit debit for an MPP challenge, including quoted gas fees; `TEMPO_MAX_SPEND` also caps the total debit in USD. Challenge spending requires one of those caps; `--dry-run` does not. Do not use positional transfer arguments with `--credits`, or combine `--to`, `--data`, or `--value` with `--mpp-challenge` or `--mpp-challenge-file`. Review the destination and calldata in `--dry-run` output before spending. Split-payment challenges are unsupported. Coinflow remains trusted to execute the submitted transaction; its legacy permit authorizes a credit debit rather than a specific recipient. +For credit payments, use `--amount-cents` as the direct payment amount or the maximum credit debit for an MPP challenge, including quoted gas fees; `TEMPO_MAX_SPEND` also caps the total debit in USD. Challenge spending requires one of those caps; `--dry-run` does not. Do not use positional transfer arguments with `--credits`, or combine `--to`, `--data`, or `--value` with `--mpp-challenge` or `--mpp-challenge-file`. Review the destination and calldata in `--dry-run` output (`status: "dry_run"`) before spending; a sent payment returns `status: "success"` with its `tx_hash`. Split-payment challenges are unsupported. Coinflow remains trusted to execute the submitted transaction; its legacy permit authorizes a credit debit rather than a specific recipient. ### Response Handling - Return result payload to user directly when request succeeds. - If response contains a file URL (e.g., image generation), download it locally: `curl -fsSL "" -o `. -- If response is a usage/auth readiness error, run `tempo wallet login`, finish it with its `_next` `login status` as in Setup, and retry once. When a wallet command returns `E_NOT_AUTHENTICATED`, `E_KEY_EXPIRED`, or `E_AUTH_REFRESH_REQUIRED`, run the `tempo wallet login` or `tempo wallet refresh` command in its `cta` instead; it keeps the command's `--network`. `transfer` and `swap` need a usable access key; `keys update`, `revoke`, and `sessions close` need only the login. +- If response is a usage/auth readiness error, run `tempo wallet login`, finish it with its `_next` `login status` as in Setup, and retry once. When `tempo request` or a wallet command returns `E_NOT_AUTHENTICATED`, `E_KEY_EXPIRED`, or `E_AUTH_REFRESH_REQUIRED`, run the `tempo wallet login` or `tempo wallet refresh` command in its `cta` instead; it keeps the command's `--network`. `tempo request` never logs in by itself: it needs a login and usable access key only to pay a 402, and a `--dry-run` quote the wallet cannot pay names that command in `_next`. `send` and `swap` need a usable access key; `keys update`, `keys revoke`, `sessions close`, `balance`, and `address` need only the login. - If response indicates payment/funding limit issues, report clearly and stop. Check `tempo wallet whoami --mach` and offer `tempo wallet fund --mach --no-browser --format json` to fund from another device. Review token-specific access-key limits before retrying. - When a wallet, key, or RPC problem is unclear, run `tempo wallet doctor --format json` and report its `fail` and `warn` checks; it exits 0 even when unhealthy and never shows secrets. `tempo wallet debug` is a deprecated alias of it. -- After multi-request workflows, check remaining balance with `tempo wallet whoami`. +- After multi-request workflows, check the remaining spendable balance with `tempo wallet balance`; `tempo wallet whoami` also shows deposits locked in sessions. - Wallet results with a follow-up step include `instruction` and `_next`. Run `_next.argv` as given (`_next.command` is the shell-quoted form), but only after the user approves any spend, transfer, or revocation it performs. -- Revocation cannot be undone. Run `tempo wallet revoke --dry-run` to show the key, wallet, network, limits, and expiry, then run its `_next` (which adds `--yes`) only after the user approves. Without `--yes`, an agent run returns `E_USAGE` with that command as its `cta`. Only the logged-in wallet's keys on the selected network can be revoked: keys stored on this host, or keys from another device that the chain shows authorized for the wallet. Any other address returns `E_USAGE` listing the wallet's stored keys. If it returns `E_NETWORK` because the chain does not show the key revoked, the local key is kept; report it to the user before retrying. +- Revocation cannot be undone. Run `tempo wallet keys revoke --dry-run` to show the key, wallet, network, limits, and expiry, then run its `_next` (which adds `--yes`) only after the user approves. Without `--yes`, an agent run returns `E_USAGE` with that command as its `cta`. Only the logged-in wallet's keys on the selected network can be revoked: keys stored on this host, or keys from another device that the chain shows authorized for the wallet. Any other address returns `E_USAGE` listing the wallet's stored keys. If it returns `E_NETWORK` because the chain does not show the key revoked, the local key is kept; report it to the user before retrying. +- `tempo wallet logout` logs out of every network unless `--network` names one. When stored sessions on those networks still hold deposits, or with `--revoke`, an agent run returns `E_USAGE` and logs out nothing. Report the sessions to the user and suggest closing them first with the `tempo wallet sessions close` command the error names; run its `cta` (which adds `--yes`) only after the user approves logging out anyway. A confirmed logout lists such `sessions` and points `_next` at the close to run after logging in again. Without `--revoke`, removed keys stay authorized on-chain until they expire; `--revoke` revokes them first, on every network the logout covers, and cannot be undone. A retryable `E_USAGE` saying the wallet changed during logout means another login or refresh ran meanwhile, so the wallet may now hold keys the user has not seen. Report it and rerun the logout only after the user approves again; its command keeps `--yes`, so a rerun logs out, and with `--revoke` revokes, the wallet as it now is without asking. If a key is not revoked, logout fails and keeps it with the wallet; report it before retrying. +- Closing a session cannot be undone, and a closed session can no longer pay for requests. Run `tempo wallet sessions close --dry-run` (or with `--all`, `--orphaned`, `--finalize`, or `--cooperative`) to list the sessions it selects as `targets[]`, each with its `channel_id`, `origin`, and `status` (`not_found` when nothing matches), then run its `_next` (which adds `--yes`) only after the user approves. Without `--yes`, an agent run returns `E_USAGE` with that command as its `cta`. A pending close's `_next` already includes `--yes`, since it completes a close the user approved; `remaining_seconds` says how long until its deposit can be withdrawn. ### Rules - Always discover URL/path before request; never guess endpoint paths. - `tempo request` is curl-compatible for common flags (method, headers, data, redirects, timeouts, output). -- TOON is the default output format (`-t` selects it explicitly); use another format flag only when needed. -- Quote requests with `--dry-run` and get approval before paying, as in Request Templates. The quote reports the per-call `amount`, the session `deposit` the payment would lock (for `session: "reuse"`, only a top-up the voucher needs), the wallet `balance` and access key `access_key_limit` for the debited token, the effective `max_spend` (the default 10 when no cap is set), and `within_budget` against it. `null` means unknown or, for a subscription offer, that no cap applies. `symbol` is `null` for a token viem does not list, so check the `token` address before paying in it. +- Piped output is structured: TOON by default (`-t` selects it explicitly), or JSON with `--format json`. A `tempo wallet` run whose stdout is a terminal, with no format flag, prints a human-readable view instead, so read results from piped output or pass `--format json`. +- Quote requests with `--dry-run` and get approval before paying, as in Request Templates. The quote reports the per-call `amount` (`raw_amount` in base units), the session `deposit` the payment would lock (`raw_deposit`) (for `session: "reuse"`, only a top-up the voucher needs), the wallet `balance` and access key `access_key_limit` for the advertised settlement token, the effective `max_spend` (the default 10 when no cap is set), and `within_budget` against it. Eligible nonzero MACH-enabled charges also report `mach.balance` and `mach.access_key_limit` separately, including when `--mach` is selected. `null` means unknown or, for a subscription offer, that no cap applies. `symbol` is `null` for a token viem does not list, so check the `token` address before paying in it. - If the user gives a spend cap in natural language (for example "do X for $5", "don't spend more than $10", or "budget is 2 USDC"), include `--max-spend ` on `tempo request` commands. For non-CLI contexts, use `TEMPO_MAX_SPEND`. -- Without `--max-spend` or `TEMPO_MAX_SPEND`, `tempo request` caps each charge, session deposit, and session's cumulative spend at 10 token units. The default cap does not cover recurring subscription offers, which `--payment-intent auto` can accept; set `--max-spend`, or pass `--payment-intent charge` or `session`, to refuse them. A payment over the cap fails with `E_LIMIT_EXCEEDED` before anything is signed; report the required amount, and run the `cta` command (the same request with `--max-spend `) only after the user approves that spend, replacing any `` credential with its original value. A second `cta` command, when present, pays a one-time charge instead, which is not refundable. -- A successful paid request prints a short receipt on stderr, and `--write-meta ` adds it as `payment`: the `amount` paid in `token` (`symbol`), the `tx_hash` when the server reports one, the `payer`, and for a session its `session` (`open` or `reuse`), `channel_id`, `deposit_locked`, and `cumulative` (the total of its signed vouchers, not confirmed spend). A `subscription` (`period`, `expires`) means the wallet authorized `amount` every period until it expires, not a one-time payment, and a `tx_hash` means the first period was already paid; tell the user. With `-j` or `--format`, stderr stays empty, so pass `--write-meta` to read the receipt. A receipt with `outcome: "unknown"` belongs to an `E_PAYMENT_OUTCOME_UNKNOWN` failure: treat the payment as unconfirmed and check with the provider before retrying. A newly opened session keeps its deposit locked until closed: report it, and when you are done with that service, run the receipt's `_next` (`tempo wallet sessions close `) to request the close, then follow that command's `_next` after the grace period to withdraw the unspent deposit. +- Without `--max-spend`, `TEMPO_MAX_SPEND`, or a saved `max-spend`, `tempo request` caps each charge, session deposit, and session's cumulative spend at 10 token units. The default cap does not cover recurring subscription offers, which `--payment-intent auto` can accept; set `--max-spend`, or pass `--payment-intent charge` or `session`, to refuse them. A payment over the cap fails with `E_LIMIT_EXCEEDED` before anything is signed; report the required amount, and run the `cta` command (the same request with `--max-spend `) only after the user approves that spend, replacing any `` credential with its original value. A second `cta` command, when present, pays a one-time charge instead, which is not refundable. +- A successful paid request prints a short receipt on stderr, and `--write-meta ` adds it as `payment`: the `amount` paid in `token` (`symbol`), the `tx_hash` when the server reports one, the `payer`, and for a session its `session` (`open` or `reuse`), `channel_id`, `deposit_locked`, and `cumulative` (the total of its signed vouchers, not confirmed spend). A `subscription` (`period`, `expires`) means the wallet authorized `amount` every period until it expires, not a one-time payment, and a `tx_hash` means the first period was already paid; tell the user. With `-j` or `--format`, stderr stays empty, so pass `--write-meta` to read the receipt. A receipt with `outcome: "unknown"` belongs to an `E_PAYMENT_OUTCOME_UNKNOWN` failure: treat the payment as unconfirmed and check with the provider before retrying. A newly opened session keeps its deposit locked until closed: report it, and when you are done with that service and the user approves closing it, run the receipt's `_next` (`tempo wallet sessions close `) with `--yes` to request the close, then follow that command's `_next` after the grace period to withdraw the unspent deposit. - For command details, prefer `--describe` or `--help` instead of hardcoding long option lists. ## Swap Tokens @@ -150,7 +156,7 @@ Use the first-party wallet CLI for Tempo token swaps. Do not discover or sign in tempo wallet swap --dry-run # Submit only after the user approves the quote, token addresses, and bounds. -tempo wallet swap --min-amount-out --yes +tempo wallet swap --min-amount-out --idempotency-key --yes ``` - The amount is exact input by default. Add `--exact-out` to request an exact output amount. @@ -160,28 +166,97 @@ tempo wallet swap --min-amount-out ` `cta`; run it, then rerun the swap. - Always run `--dry-run` first and preserve full token addresses in the approval request. -## Transfer Tokens +## Send Tokens ```bash # Review only: the fee estimate, the sender's balance, and whether it covers the transfer. -tempo wallet transfer --dry-run +tempo wallet send --dry-run # Send only after the user approves the amount, token address, recipient, and fee. -tempo wallet transfer --yes +tempo wallet send --idempotency-key --yes ``` - Without `--yes`, an agent run sends nothing and returns `E_USAGE`; the dry run's `_next` already includes `--yes` and pins the reviewed `fee_token` with `--fee-token`. - `fee_estimate` is in `fee_token` units. `sufficient_balance` checks `balance` against the amount and `fee_token_balance` against the fee. `fee_token`, `fee_estimate`, `balance`, `fee_token_balance`, and `sufficient_balance` are `null` when unknown; treat `null` as unknown, not as sufficient. - If `sufficient_balance` is false, report the shortfall and stop; offer `tempo wallet fund`. +- A send goes out only on the network the wallet is logged in on. On another `--network`, it returns `E_USAGE` with a `tempo wallet login --network ` `cta`; run it, then rerun the send. - Always run `--dry-run` first and preserve full token and recipient addresses in the approval request. +- Use `send` for every token transfer. `tempo wallet transfer` is for `--mach` and `--credits` payments only; its token form is a deprecated alias of `send`. + +## Retrying Transfers and Swaps + +- Pass `--idempotency-key ` (`idempotency-key` over MCP) on every `send` and `swap` you submit: a new unique key, such as a UUID, for each send the user approves. Pass it on the dry run too, and its `_next` carries it. +- When a send times out, errors, or you are unsure it ran, retry the same command with the same key. The CLI never sends twice for one key on a wallet and network: a send that already went through returns its recorded result with `idempotent_replay: true` and the transaction's current `status` (`success`, `reverted`, `pending`, or `not_found`); report it instead of sending again. +- Never reuse a key for a different send. Changed arguments with a used key return `E_USAGE` naming what differs. +- `E_PAYMENT_OUTCOME_UNKNOWN` means the transaction may have been sent. Do not send again, with or without a new key, until you have checked: run its `cta` (`tempo wallet tx status ` when the hash is known, otherwise `tempo wallet whoami` to check balances), report the result, and get the user's approval for any new send. +- `tempo wallet tx status ` only reads. While it reports `pending`, rerun its `_next` until `status` changes; `not_found` means the network does not know the transaction. + +## Settings + +`tempo wallet config get` shows the `network`, `rpc-url`, and `max-spend` that commands use, each with its `source` (`flag`, `env`, `config`, `login`, or `default`). The first match wins: + +- `network`: `--network`, then `TEMPO_WALLET_NETWORK`, then the saved `network`, then the logged-in wallet's network, then mainnet. A saved `network` does not narrow `keys list` or `logout`. +- `rpc-url`, saved per network: `TEMPO_RPC_URL` (every network), then the saved `rpc-url` for that network, then the network's default RPC. +- `max-spend`: `--max-spend`, then `TEMPO_MAX_SPEND`, then the saved `max-spend`, then 10. + +A saved setting applies to every later command, including the user's own: + +- Change a setting only when the user asks for a lasting change; for one task, pass `--network` or `--max-spend` instead. +- `tempo wallet config set ` and `tempo wallet config unset ` change what later payments and RPC calls use. Without `--yes`, an agent run changes nothing and returns `E_USAGE` showing the value before and after, with the confirming command as its `cta`; run it only after the user approves. A `` in that `cta` stands for the full URL, left out because it can carry a credential. +- `rpc-url` is set for `--network`, else the network commands use, and only once the URL answers that network's chain ID; otherwise `config set` returns `E_USAGE` and saves nothing. +- With `TEMPO_RPC_URL` or a saved `rpc-url`, `sessions close`, `sessions sync`, `keys revoke`, `logout --revoke`, and a `tempo request` that reuses a session return `E_USAGE` with a `tempo wallet config get rpc-url` `cta` when the endpoint is on another chain, and change nothing. Report it to the user instead of changing the setting. ## MCP Tools When the wallet is connected as an MCP server (`tempo wallet --mcp`), each tool's annotations say what it does: -- `readOnlyHint: true` (`whoami`, `keys_list`, `services`, `doctor`) only reads. -- `destructiveHint: true` (`transfer`, `swap`, `sessions_close`, `sessions_sync`, `keys_update`, `revoke`, `logout`, `login`, `login_status`, `refresh`) moves funds, changes or revokes a key, closes a session, deletes stored sessions, or replaces or deletes the stored wallet or its network. Get the user's approval before every call, after a `dry-run: true` call where the tool offers one. -- `transfer`, `swap`, and `revoke` refuse to submit without `yes: true`; pass it only after the user approves the reviewed dry run. + + +| Tool | `readOnlyHint` | `destructiveHint` | `idempotentHint` | `openWorldHint` | +| ----------------- | -------------- | ----------------- | ---------------- | --------------- | +| `address` | true | false | true | false | +| `balance` | true | false | true | true | +| `completions` | true | false | true | false | +| `config_get` | true | false | true | false | +| `config_set` | false | true | true | false | +| `config_unset` | false | true | true | false | +| `debug` | true | false | true | true | +| `doctor` | true | false | true | true | +| `fund` | false | false | false | true | +| `keys_list` | true | false | true | true | +| `keys_revoke` | false | true | true | true | +| `keys_update` | false | true | false | true | +| `login` | false | true | false | true | +| `login_status` | false | true | true | true | +| `logout` | false | true | true | true | +| `refresh` | false | true | false | true | +| `revoke` | false | true | true | true | +| `send` | false | true | false | true | +| `services` | true | false | true | true | +| `services_list` | true | false | true | true | +| `services_search` | true | false | true | true | +| `services_show` | true | false | true | true | +| `sessions_close` | false | true | false | true | +| `sessions_list` | false | false | true | true | +| `sessions_sync` | false | true | true | true | +| `swap` | false | true | false | true | +| `transfer` | false | true | false | true | +| `tx_status` | true | false | true | true | +| `whoami` | true | false | true | true | + + + +- `readOnlyHint: true` only reads. +- `destructiveHint: true` moves funds, changes or revokes a key, closes a session, deletes stored sessions, replaces or deletes the stored wallet or its network, or changes a saved setting. Get the user's approval before every call, after a `dry-run: true` call where the tool offers one. +- These tools refuse to act without `yes: true` and return `E_USAGE`; pass it only after the user approves the reviewed dry run or change: + - `send`, and `transfer` when it sends tokens (without `mach` or `credits`) + - `swap` + - `keys_revoke` + - `sessions_close`, when it selects a session to close + - `config_set` and `config_unset`, when they change the saved value + - `logout`, when it would revoke keys, or stored sessions on the networks it logs out of hold deposits or cannot be read +- Tools take positional arguments under kebab-case keys, like options: `access-key` (`keys_update`, `keys_revoke`), `token-in` and `token-out` (`swap`), `tx-hash` (`tx_status`), `service-id` (`services_show`), and `target` (`sessions_close`). +- Call `send` for token transfers and keep `transfer` for `mach` and `credits` payments; call `keys_revoke`, not the deprecated `revoke`, and `services_list`, `services_search`, or `services_show`, not the deprecated `services`. ## Common Issues @@ -190,9 +265,9 @@ When the wallet is connected as an MCP server (`tempo wallet --mcp`), each tool' | `tempo: command not found` | CLI not installed | Run `curl -fsSL https://tempo.xyz/install \| bash`, then retry using `"$HOME/.tempo/bin/tempo" ...`. | | "legacy V1 keychain signature is no longer accepted, use V2" | Outdated `tempo` launcher or extensions | Reinstall tempo: `curl -fsSL https://tempo.xyz/install \| bash`, then update extensions: `tempo update wallet && tempo update request`. Log out and back in: `tempo wallet logout --yes && tempo wallet login`. | | "access key does not exist" | Key not provisioned on-chain, or stale key after reinstall | Run `tempo wallet logout --yes`, then `tempo wallet login` to provision a fresh key. | -| `ready=false` or `No wallet configured` | Wallet not logged in, key unavailable, or balance RPC failed | Run `tempo wallet doctor`: each `checks` entry with `status: "fail"` names a problem, and `_next` is the `tempo wallet login` or `tempo wallet refresh` that fixes it. Wait for the user to complete it, then rerun `tempo wallet whoami`. An `rpc` failure means checking connectivity and `TEMPO_RPC_URL`. | -| HTTP 422 on first request to a service | Wrong request schema — field names vary across services | Check `tempo wallet services ` for endpoint details, then fetch the endpoint's `docs` URL or the service's `llms.txt` for exact field names and types. | -| Balance is 0, insufficient funds, or spending limit exceeded | Wallet needs funding or limit hit | For a limit hit, run `tempo wallet keys update --limit ` with user approval. For insufficient funds, suggest `tempo wallet fund` or the wallet dashboard. Check the on-chain MACH balance with `tempo wallet whoami --mach`; use `tempo wallet fund --mach --no-browser --format json` for remote funding. | -| Service not found for query | Search terms too narrow | Broaden search terms with `tempo wallet services --search `, then inspect candidate details. | -| Endpoint returns usage/path error | Wrong URL or method | Re-open service details with `tempo wallet services ` and use discovered method/path exactly. | +| `ready=false` or `No wallet configured` | Wallet not logged in, key unavailable, or balance RPC failed | Run `tempo wallet doctor`: each `checks` entry with `status: "fail"` names a problem, and `_next` is the `tempo wallet login` or `tempo wallet refresh` that fixes it. Wait for the user to complete it, then rerun `tempo wallet whoami`. For `rpc`, check connectivity and `tempo wallet config get rpc-url`. | +| HTTP 422 on first request to a service | Wrong request schema — field names vary across services | Check `tempo wallet services show ` for endpoint details, then fetch the endpoint's `docs` URL or the service's `llms.txt` for exact field names and types. | +| Balance is 0, insufficient funds, or spending limit exceeded | Wallet needs funding or limit hit | For a limit hit, have the wallet owner approve the `keys update` in the error's `cta`. For insufficient funds, run the `cta` or else suggest `tempo wallet fund`. Check the on-chain MACH balance with `tempo wallet whoami --mach`; use `tempo wallet fund --mach --no-browser --format json` for remote funding. | +| Service not found for query | Search terms too narrow | Broaden search terms with `tempo wallet services search `, then inspect candidate details. | +| Endpoint returns usage/path error | Wrong URL or method | Re-open service details with `tempo wallet services show ` and use discovered method/path exactly. | | Timeout/network error | Network issue or slow endpoint | Retry request and optionally increase timeout with `-m `. | diff --git a/skills.lock.json b/skills.lock.json index c3ae5ae..3f61aaa 100644 --- a/skills.lock.json +++ b/skills.lock.json @@ -37,8 +37,8 @@ "repo": "tempoxyz/wallet-cli", "path": "SKILL.md", "ref": "release", - "commit": "225ad5d7993df063008e26c2a8e1a40424b21b83", - "digest": "sha256:9843b8b6cf10e961450f4f58a79a315720dbd7c65fa6f91786c237bb2205c024", + "commit": "62d30c963c373eb4ffb2fc2c4146b1bb828f94bf", + "digest": "sha256:30cb1f2bc8598f8914c4ee7717739e95b2b00e9d553a8730fd74390a7421a57c", "dest": "plugins/wallet/skills/wallet" } ] diff --git a/test/fixtures/golden/gemini/wallet/gemini-extension.json b/test/fixtures/golden/gemini/wallet/gemini-extension.json index 8c046c3..23fef24 100644 --- a/test/fixtures/golden/gemini/wallet/gemini-extension.json +++ b/test/fixtures/golden/gemini/wallet/gemini-extension.json @@ -1,5 +1,5 @@ { "name": "wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests." } diff --git a/test/fixtures/golden/manifests/plugins/wallet/.claude-plugin/plugin.json b/test/fixtures/golden/manifests/plugins/wallet/.claude-plugin/plugin.json index 881d32e..4aa44a6 100644 --- a/test/fixtures/golden/manifests/plugins/wallet/.claude-plugin/plugin.json +++ b/test/fixtures/golden/manifests/plugins/wallet/.claude-plugin/plugin.json @@ -2,7 +2,7 @@ "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", "name": "wallet", "displayName": "Tempo Wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "author": { "name": "Tempo" diff --git a/test/fixtures/golden/manifests/plugins/wallet/.codex-plugin/plugin.json b/test/fixtures/golden/manifests/plugins/wallet/.codex-plugin/plugin.json index 0b918c1..9e515eb 100644 --- a/test/fixtures/golden/manifests/plugins/wallet/.codex-plugin/plugin.json +++ b/test/fixtures/golden/manifests/plugins/wallet/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "homepage": "https://tempo.xyz/developers/docs/wallet/use-with-agents", "repository": "https://github.com/tempoxyz/plugins", diff --git a/test/fixtures/golden/manifests/plugins/wallet/.cursor-plugin/plugin.json b/test/fixtures/golden/manifests/plugins/wallet/.cursor-plugin/plugin.json index e99cfc6..7736b8a 100644 --- a/test/fixtures/golden/manifests/plugins/wallet/.cursor-plugin/plugin.json +++ b/test/fixtures/golden/manifests/plugins/wallet/.cursor-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "wallet", "displayName": "Tempo Wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "author": { "name": "Tempo" diff --git a/test/fixtures/golden/manifests/plugins/wallet/plugin.json b/test/fixtures/golden/manifests/plugins/wallet/plugin.json index 6191d86..cf52f1f 100644 --- a/test/fixtures/golden/manifests/plugins/wallet/plugin.json +++ b/test/fixtures/golden/manifests/plugins/wallet/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "wallet", - "version": "0.1.1", + "version": "0.1.2", "description": "Set up Tempo Wallet and make explicitly approved paid API requests.", "homepage": "https://tempo.xyz/developers/docs/wallet/use-with-agents", "repository": "https://github.com/tempoxyz/plugins",