@h402/cli 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,8 @@ Browsing, quoting, and free-route calls do not require a local wallet. Wallet cr
37
37
 
38
38
  Calls hit the production backend (`https://h402.hunt.town`) by default — override with `--api-url` or `H402_API_URL` (e.g. `http://localhost:3000` for local dev).
39
39
 
40
+ To select a default local signing wallet, add `"defaultWallet": "agent"` to your existing `~/.h402/config.json`, preserving its other fields. This applies to wallet creation, address, balance, funding instructions, authentication, and paid calls. Explicit `--name` or `--wallet` takes precedence; without this setting, the default remains `h402`. If the selected wallet is missing, the CLI reports an error instead of using another wallet. Existing bonus-credit sessions remain associated with the wallet that authenticated them; changing `defaultWallet` does not switch those sessions.
41
+
40
42
  ## Commands
41
43
 
42
44
  | Command | Description |
@@ -60,7 +62,7 @@ Run `h402 --help`, `h402 <command> --help`, or `h402 wallet <subcommand> --help`
60
62
 
61
63
  | Flag | Applies to | Description |
62
64
  | --- | --- | --- |
63
- | `--name <wallet>` | wallet create/address/balance/fund; auth; call | Wallet to use (default `h402`) |
65
+ | `--name <wallet>` | wallet create/address/balance/fund; auth; call | Wallet to use (default: `defaultWallet` in config, otherwise `h402`) |
64
66
  | `--wallet 0x...` | wallet address/balance/fund; auth; call | Sign with the local wallet that owns this address (must exist locally; must agree with `--name` if both are passed) |
65
67
  | `--api-url <url>` | auth, credits, search, show, quote, call | Backend base URL override (or `H402_API_URL`; default `https://h402.hunt.town`) |
66
68
  | `--json '{...}'` | quote, call | Request body (sets method to POST) |
@@ -148,7 +150,7 @@ Signing needs no flags for the default passphrase-less wallets. Only when a wall
148
150
  | `H402_API_URL` | Backend base URL override (or `--api-url`; default `https://h402.hunt.town`) |
149
151
  | `H402_WALLET_PASSPHRASE` | Passphrase for passphrase-protected wallets (only needed when the wallet was created with one) |
150
152
 
151
- Passphrases are never stored. Wallets are passphrase-less by default; opt in at create time (`--passphrase <s>`, or bare `--passphrase` to be prompted) when a wallet guards meaningful funds. The CLI persists only the backend URL, session tokens, and known wallet addresses in `~/.h402/config.json`.
153
+ Passphrases are never stored. Wallets are passphrase-less by default; opt in at create time (`--passphrase <s>`, or bare `--passphrase` to be prompted) when a wallet guards meaningful funds. The CLI persists the backend URL, session tokens, known wallet addresses, and optional `defaultWallet` and `maxUsd` settings in `~/.h402/config.json`.
152
154
 
153
155
  ## Contributing
154
156
 
package/dist/commands.js CHANGED
@@ -9,8 +9,8 @@ import { promptPassphrase } from "./prompt.js";
9
9
  import { assertConcreteProvider, buildProxyPath, encodeRouteId, flagBoolean, flagString, isRecord, mergeH402, parseJsonFlag, parseQueryFlag, printJson, requireValue, resolveMethod } from "./utils.js";
10
10
  import { createPaymentSignatureHeader, paymentRequiredFromResponse, selectBaseUsdcRequirement, X402_HEADERS } from "./x402.js";
11
11
  const DEFAULT_WALLET_NAME = "h402";
12
- function walletName(args) {
13
- return flagString(args.flags, "name", DEFAULT_WALLET_NAME);
12
+ function walletName(args, config) {
13
+ return flagString(args.flags, "name", config.defaultWallet ?? DEFAULT_WALLET_NAME);
14
14
  }
15
15
  // Explicit passphrase from flags/env. Wallets are passphrase-less by default
16
16
  // (the onboarding default), so this is usually undefined and signing simply
@@ -158,24 +158,7 @@ export async function resolveSigningWallet(args, config) {
158
158
  config ??= await loadConfig();
159
159
  const explicitAddress = flagString(args.flags, "wallet")?.toLowerCase();
160
160
  const explicitName = flagString(args.flags, "name");
161
- if (explicitName) {
162
- const address = config.wallets[explicitName]?.address?.toLowerCase();
163
- if (!address) {
164
- const adopted = await adoptOwsWalletByName(explicitName, config);
165
- if (adopted) {
166
- if (explicitAddress && explicitAddress !== adopted.address) {
167
- throw new Error(`--wallet ${explicitAddress} does not match wallet "${explicitName}" (${adopted.address}). Omit --wallet or pass the wallet that owns this address.`);
168
- }
169
- return adopted;
170
- }
171
- throw new Error(`No address known for wallet "${explicitName}". Run: h402 wallet create --name ${explicitName}, or h402 wallet restore to re-adopt existing OWS wallets.`);
172
- }
173
- if (explicitAddress && explicitAddress !== address) {
174
- throw new Error(`--wallet ${explicitAddress} does not match wallet "${explicitName}" (${address}). Omit --wallet or pass the wallet that owns this address.`);
175
- }
176
- return { name: explicitName, address };
177
- }
178
- if (explicitAddress) {
161
+ if (explicitAddress && !explicitName) {
179
162
  const owner = Object.entries(config.wallets).find(([, wallet]) => wallet.address?.toLowerCase() === explicitAddress);
180
163
  if (!owner) {
181
164
  const adopted = await adoptOwsWalletByAddress(explicitAddress, config);
@@ -185,21 +168,23 @@ export async function resolveSigningWallet(args, config) {
185
168
  }
186
169
  return { name: owner[0], address: explicitAddress };
187
170
  }
188
- const address = config.wallets[DEFAULT_WALLET_NAME]?.address?.toLowerCase();
189
- if (!address) {
190
- const adopted = await adoptOwsWalletByName(DEFAULT_WALLET_NAME, config);
191
- if (adopted)
192
- return adopted;
193
- throw new Error(`No address known for wallet "${DEFAULT_WALLET_NAME}". Run: h402 wallet create --name ${DEFAULT_WALLET_NAME} (or pass --name/--wallet), or h402 wallet restore to re-adopt existing OWS wallets.`);
171
+ const name = walletName(args, config);
172
+ const address = config.wallets[name]?.address?.toLowerCase();
173
+ const resolved = address ? { name, address } : await adoptOwsWalletByName(name, config);
174
+ if (!resolved) {
175
+ throw new Error(`No address known for wallet "${name}". Run: h402 wallet create --name ${name}, or h402 wallet restore to re-adopt existing OWS wallets.`);
176
+ }
177
+ if (explicitAddress && explicitAddress !== resolved.address) {
178
+ throw new Error(`--wallet ${explicitAddress} does not match wallet "${name}" (${resolved.address}). Omit --wallet or pass the wallet that owns this address.`);
194
179
  }
195
- return { name: DEFAULT_WALLET_NAME, address };
180
+ return resolved;
196
181
  }
197
182
  export async function walletCommand(args) {
198
183
  const subcommand = requireValue(args.positional[1], "wallet subcommand is required");
199
184
  rejectExtraPositionals(args, 2, `wallet ${subcommand}`);
200
- const name = walletName(args);
201
185
  const config = await loadConfig();
202
186
  if (subcommand === "create") {
187
+ const name = walletName(args, config);
203
188
  let wallet;
204
189
  try {
205
190
  wallet = await createOwsWallet(name, await createPassphrase(args));
package/dist/config.js CHANGED
@@ -23,6 +23,12 @@ function normalizeConfig(parsed) {
23
23
  if (typeof parsed.maxUsd === "string") {
24
24
  normalized.maxUsd = parsed.maxUsd;
25
25
  }
26
+ if (parsed.defaultWallet !== undefined) {
27
+ if (typeof parsed.defaultWallet !== "string" || !parsed.defaultWallet.trim()) {
28
+ throw new Error("h402 config defaultWallet must be a non-empty wallet name");
29
+ }
30
+ normalized.defaultWallet = parsed.defaultWallet;
31
+ }
26
32
  return normalized;
27
33
  }
28
34
  async function tightenConfigPermissions(file) {
@@ -69,6 +75,9 @@ function cloneConfig(config) {
69
75
  if (config.maxUsd !== undefined) {
70
76
  cloned.maxUsd = config.maxUsd;
71
77
  }
78
+ if (config.defaultWallet !== undefined) {
79
+ cloned.defaultWallet = config.defaultWallet;
80
+ }
72
81
  return cloned;
73
82
  }
74
83
  async function atomicWritePrivateJson(file, config) {
package/dist/help.js CHANGED
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
  // Reusable flag definitions (DRY: declared once, referenced by each command that
5
5
  // accepts them — mirrors the README flags table).
6
6
  const FLAGS = {
7
- name: { name: "name", value: "<wallet>", desc: "Wallet to use (default h402)" },
7
+ name: { name: "name", value: "<wallet>", desc: "Wallet to use (default: config.defaultWallet, otherwise h402)" },
8
8
  wallet: { name: "wallet", value: "0x...", desc: "Local wallet that owns this address (must agree with --name)" },
9
9
  apiUrl: { name: "api-url", value: "<url>", desc: "Backend base URL (or H402_API_URL; default https://h402.hunt.town)" },
10
10
  json: { name: "json", value: "'{...}'", desc: "Request body (sets method to POST)" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h402/cli",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Local, non-custodial CLI for h402 — browse the catalog and pay per call in Base USDC over x402 from a local wallet.",
5
5
  "license": "MIT",
6
6
  "type": "module",