@jaw.id/cli 0.0.6 → 0.0.8
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 +24 -24
- package/dist/base-command.js +2 -6
- package/dist/base-command.js.map +1 -1
- package/dist/commands/config/set.js +10 -32
- package/dist/commands/config/set.js.map +1 -1
- package/dist/commands/config/show.js +3 -10
- package/dist/commands/config/show.js.map +1 -1
- package/dist/commands/disconnect.js +13 -49
- package/dist/commands/disconnect.js.map +1 -1
- package/dist/commands/mcp/index.js +42 -118
- package/dist/commands/mcp/index.js.map +1 -1
- package/dist/commands/rpc/call.js +15 -57
- package/dist/commands/rpc/call.js.map +1 -1
- package/dist/commands/version.js +2 -6
- package/dist/commands/version.js.map +1 -1
- package/dist/index.js +14 -54
- package/dist/index.js.map +1 -1
- package/dist/lib/bridge-singleton.js +12 -48
- package/dist/lib/bridge-singleton.js.map +1 -1
- package/dist/lib/config.js +2 -6
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/crypto.js +3 -15
- package/dist/lib/crypto.js.map +1 -1
- package/dist/lib/output.js +2 -6
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/paths.js.map +1 -1
- package/dist/lib/session-store.js.map +1 -1
- package/dist/lib/validation.js.map +1 -1
- package/dist/lib/ws-bridge.js +11 -43
- package/dist/lib/ws-bridge.js.map +1 -1
- package/dist/mcp/handlers/config.js +14 -27
- package/dist/mcp/handlers/config.js.map +1 -1
- package/dist/mcp/handlers/daemon.js +13 -72
- package/dist/mcp/handlers/daemon.js.map +1 -1
- package/dist/mcp/handlers/resources.js +1 -3
- package/dist/mcp/handlers/resources.js.map +1 -1
- package/dist/mcp/handlers/rpc.js +27 -85
- package/dist/mcp/handlers/rpc.js.map +1 -1
- package/dist/mcp/helpers.js.map +1 -1
- package/dist/mcp/server.js +41 -115
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.js +2 -4
- package/dist/mcp/tools.js.map +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -75,14 +75,14 @@ jaw rpc call wallet_getAssets
|
|
|
75
75
|
jaw rpc call eth_chainId
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
| Flag
|
|
79
|
-
|
|
80
|
-
| `-o, --output`
|
|
81
|
-
| `-c, --chain`
|
|
82
|
-
| `--api-key`
|
|
83
|
-
| `-t, --timeout` | Request timeout (seconds)
|
|
84
|
-
| `-y, --yes`
|
|
85
|
-
| `-q, --quiet`
|
|
78
|
+
| Flag | Description | Default |
|
|
79
|
+
| --------------- | -------------------------------- | -------------- |
|
|
80
|
+
| `-o, --output` | Output format: `json` or `human` | `human` |
|
|
81
|
+
| `-c, --chain` | Chain ID | config default |
|
|
82
|
+
| `--api-key` | JAW API key | config/env |
|
|
83
|
+
| `-t, --timeout` | Request timeout (seconds) | `120` |
|
|
84
|
+
| `-y, --yes` | Skip confirmations | `false` |
|
|
85
|
+
| `-q, --quiet` | Suppress non-essential output | `false` |
|
|
86
86
|
|
|
87
87
|
### `jaw config show`
|
|
88
88
|
|
|
@@ -194,11 +194,11 @@ jaw mcp
|
|
|
194
194
|
|
|
195
195
|
### MCP Tools
|
|
196
196
|
|
|
197
|
-
| Tool
|
|
198
|
-
|
|
199
|
-
| `jaw_rpc`
|
|
200
|
-
| `jaw_config_show` | Show current CLI configuration (API key redacted).
|
|
201
|
-
| `jaw_config_set`
|
|
197
|
+
| Tool | Description |
|
|
198
|
+
| ----------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
199
|
+
| `jaw_rpc` | Execute any JAW.id wallet RPC method. Supports all EIP-1193 methods. Opens browser for passkey signing when needed. |
|
|
200
|
+
| `jaw_config_show` | Show current CLI configuration (API key redacted). |
|
|
201
|
+
| `jaw_config_set` | Set a CLI configuration value. |
|
|
202
202
|
|
|
203
203
|
### Example Agent Usage
|
|
204
204
|
|
|
@@ -209,11 +209,11 @@ Agent: jaw_rpc({ method: "wallet_sendCalls", params: { calls: [{ to: "0x...", va
|
|
|
209
209
|
|
|
210
210
|
## Environment Variables
|
|
211
211
|
|
|
212
|
-
| Variable
|
|
213
|
-
|
|
214
|
-
| `JAW_API_KEY`
|
|
215
|
-
| `JAW_CHAIN_ID` | Default chain ID
|
|
216
|
-
| `JAW_OUTPUT`
|
|
212
|
+
| Variable | Description |
|
|
213
|
+
| -------------- | --------------------------------- |
|
|
214
|
+
| `JAW_API_KEY` | JAW API key |
|
|
215
|
+
| `JAW_CHAIN_ID` | Default chain ID |
|
|
216
|
+
| `JAW_OUTPUT` | Output format (`json` or `human`) |
|
|
217
217
|
|
|
218
218
|
## Configuration
|
|
219
219
|
|
|
@@ -231,9 +231,9 @@ Config file: `~/.jaw/config.json`
|
|
|
231
231
|
|
|
232
232
|
The daemon also writes runtime state to `~/.jaw/`:
|
|
233
233
|
|
|
234
|
-
| File
|
|
235
|
-
|
|
236
|
-
| `config.json`
|
|
237
|
-
| `bridge.json`
|
|
238
|
-
| `session.json` | Cached session state
|
|
239
|
-
| `daemon.log`
|
|
234
|
+
| File | Purpose |
|
|
235
|
+
| -------------- | ------------------------------------------------ |
|
|
236
|
+
| `config.json` | User configuration (mode 0600) |
|
|
237
|
+
| `bridge.json` | Active daemon connection info (port, token, pid) |
|
|
238
|
+
| `session.json` | Cached session state |
|
|
239
|
+
| `daemon.log` | Daemon stdout/stderr for debugging |
|
package/dist/base-command.js
CHANGED
|
@@ -97,18 +97,14 @@ var BaseCommand = class extends Command {
|
|
|
97
97
|
resolveApiKey(flags) {
|
|
98
98
|
const apiKey = flags["api-key"] ?? loadConfig().apiKey;
|
|
99
99
|
if (!apiKey) {
|
|
100
|
-
this.error(
|
|
101
|
-
"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`"
|
|
102
|
-
);
|
|
100
|
+
this.error("API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`");
|
|
103
101
|
}
|
|
104
102
|
return apiKey;
|
|
105
103
|
}
|
|
106
104
|
resolveChainId(flags) {
|
|
107
105
|
const chainId = flags.chain ?? loadConfig().defaultChain;
|
|
108
106
|
if (!chainId) {
|
|
109
|
-
this.error(
|
|
110
|
-
"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`"
|
|
111
|
-
);
|
|
107
|
+
this.error("Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`");
|
|
112
108
|
}
|
|
113
109
|
return chainId;
|
|
114
110
|
}
|
package/dist/base-command.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/paths.ts","../src/lib/config.ts","../src/lib/output.ts","../src/base-command.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../src/lib/paths.ts","../src/lib/config.ts","../src/lib/output.ts","../src/base-command.ts"],"names":[],"mappings":"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","file":"base-command.js","sourcesContent":["import * as path from 'node:path';\nimport * as os from 'node:os';\n\nconst JAW_DIR = path.join(os.homedir(), '.jaw');\n\nexport const PATHS = {\n root: JAW_DIR,\n config: path.join(JAW_DIR, 'config.json'),\n session: path.join(JAW_DIR, 'session.json'),\n relay: path.join(JAW_DIR, 'relay.json'),\n} as const;\n","import * as fs from 'node:fs';\nimport { PATHS } from './paths.js';\nimport type { JawConfig } from './types.js';\nimport { isValidKeysUrl, isValidRelayUrl } from './validation.js';\n\nexport function ensureDir(dir: string): void {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n fs.chmodSync(dir, 0o700);\n}\n\nexport function loadConfig(): JawConfig {\n if (!fs.existsSync(PATHS.config)) {\n return {};\n }\n const raw = fs.readFileSync(PATHS.config, 'utf-8');\n try {\n return JSON.parse(raw) as JawConfig;\n } catch {\n throw new Error(\n `Config file at ${PATHS.config} is not valid JSON. Run \\`jaw config set apiKey=<key>\\` to reset it.`\n );\n }\n}\n\nexport function saveConfig(config: JawConfig): void {\n ensureDir(PATHS.root);\n fs.writeFileSync(PATHS.config, JSON.stringify(config, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n}\n\nexport function redactConfig(config: JawConfig): Record<string, unknown> {\n return {\n ...config,\n apiKey: config.apiKey ? `${config.apiKey.slice(0, 8)}...` : undefined,\n };\n}\n\nexport function getConfigValue(key: keyof JawConfig): string | number | undefined {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue(key: keyof JawConfig, value: string | number): void {\n if (key === 'keysUrl' && typeof value === 'string' && !isValidKeysUrl(value)) {\n throw new Error(`Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`);\n }\n if (key === 'relayUrl' && typeof value === 'string' && !isValidRelayUrl(value)) {\n throw new Error(`Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`);\n }\n const config = loadConfig();\n const updated = { ...config, [key]: value };\n saveConfig(updated);\n}\n","import type { OutputFormat } from './types.js';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, replaceBigInt, 2);\n }\n return formatHuman(data);\n}\n\nfunction replaceBigInt(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n}\n\nfunction formatHuman(data: unknown, indent = 0): string {\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'bigint') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '(empty)';\n return data.map((item, i) => `${i + 1}. ${formatHuman(item, indent + 2)}`).join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '(empty)';\n const pad = ' '.repeat(indent);\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n return entries\n .map(([key, val]) => {\n const paddedKey = key.padEnd(maxKeyLen);\n const valStr = typeof val === 'object' && val !== null ? '\\n' + formatHuman(val, indent + 2) : String(val);\n return `${pad}${paddedKey} ${valStr}`;\n })\n .join('\\n');\n }\n\n return String(data);\n}\n\nexport function printTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return '(no results)';\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? '').length)));\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(' ');\n const separator = widths.map((w) => '-'.repeat(w)).join(' ');\n const body = rows.map((r) => keys.map((k, i) => String(r[k] ?? '').padEnd(widths[i])).join(' ')).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n","import { Command, Flags } from '@oclif/core';\nimport type { OutputFormat } from './lib/types.js';\nimport { loadConfig } from './lib/config.js';\nimport { formatOutput } from './lib/output.js';\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n output: Flags.string({\n char: 'o',\n description: 'Output format',\n options: ['json', 'human'],\n default: 'human',\n env: 'JAW_OUTPUT',\n }),\n chain: Flags.integer({\n char: 'c',\n description: 'Chain ID',\n env: 'JAW_CHAIN_ID',\n }),\n 'api-key': Flags.string({\n description: 'JAW API key',\n env: 'JAW_API_KEY',\n }),\n yes: Flags.boolean({\n char: 'y',\n description: 'Skip confirmations (for AI agents)',\n default: false,\n }),\n quiet: Flags.boolean({\n char: 'q',\n description: 'Suppress non-essential output',\n default: false,\n }),\n };\n\n protected resolveApiKey(flags: { 'api-key'?: string }): string {\n const apiKey = flags['api-key'] ?? loadConfig().apiKey;\n if (!apiKey) {\n this.error('API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`');\n }\n return apiKey;\n }\n\n protected resolveChainId(flags: { chain?: number }): number {\n const chainId = flags.chain ?? loadConfig().defaultChain;\n if (!chainId) {\n this.error('Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`');\n }\n return chainId;\n }\n\n protected outputResult(data: unknown, format: OutputFormat): void {\n const output = formatOutput(data, format);\n this.log(output);\n }\n}\n"]}
|
|
@@ -62,14 +62,10 @@ function saveConfig(config) {
|
|
|
62
62
|
}
|
|
63
63
|
function setConfigValue(key, value) {
|
|
64
64
|
if (key === "keysUrl" && typeof value === "string" && !isValidKeysUrl(value)) {
|
|
65
|
-
throw new Error(
|
|
66
|
-
`Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`
|
|
67
|
-
);
|
|
65
|
+
throw new Error(`Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`);
|
|
68
66
|
}
|
|
69
67
|
if (key === "relayUrl" && typeof value === "string" && !isValidRelayUrl(value)) {
|
|
70
|
-
throw new Error(
|
|
71
|
-
`Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`
|
|
72
|
-
);
|
|
68
|
+
throw new Error(`Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`);
|
|
73
69
|
}
|
|
74
70
|
const config = loadConfig();
|
|
75
71
|
const updated = { ...config, [key]: value };
|
|
@@ -147,18 +143,14 @@ var BaseCommand = class extends Command {
|
|
|
147
143
|
resolveApiKey(flags) {
|
|
148
144
|
const apiKey = flags["api-key"] ?? loadConfig().apiKey;
|
|
149
145
|
if (!apiKey) {
|
|
150
|
-
this.error(
|
|
151
|
-
"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`"
|
|
152
|
-
);
|
|
146
|
+
this.error("API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`");
|
|
153
147
|
}
|
|
154
148
|
return apiKey;
|
|
155
149
|
}
|
|
156
150
|
resolveChainId(flags) {
|
|
157
151
|
const chainId = flags.chain ?? loadConfig().defaultChain;
|
|
158
152
|
if (!chainId) {
|
|
159
|
-
this.error(
|
|
160
|
-
"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`"
|
|
161
|
-
);
|
|
153
|
+
this.error("Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`");
|
|
162
154
|
}
|
|
163
155
|
return chainId;
|
|
164
156
|
}
|
|
@@ -169,14 +161,7 @@ var BaseCommand = class extends Command {
|
|
|
169
161
|
};
|
|
170
162
|
|
|
171
163
|
// src/commands/config/set.ts
|
|
172
|
-
var VALID_KEYS = [
|
|
173
|
-
"apiKey",
|
|
174
|
-
"defaultChain",
|
|
175
|
-
"keysUrl",
|
|
176
|
-
"paymasterUrl",
|
|
177
|
-
"ens",
|
|
178
|
-
"relayUrl"
|
|
179
|
-
];
|
|
164
|
+
var VALID_KEYS = ["apiKey", "defaultChain", "keysUrl", "paymasterUrl", "ens", "relayUrl"];
|
|
180
165
|
function isValidKey(key) {
|
|
181
166
|
return VALID_KEYS.includes(key);
|
|
182
167
|
}
|
|
@@ -214,10 +199,7 @@ Usage: jaw config set key=value [key=value ...]`
|
|
|
214
199
|
results.push({ key, value: displayValue });
|
|
215
200
|
}
|
|
216
201
|
if (flags.output === "json") {
|
|
217
|
-
this.outputResult(
|
|
218
|
-
results.length === 1 ? results[0] : results,
|
|
219
|
-
"json"
|
|
220
|
-
);
|
|
202
|
+
this.outputResult(results.length === 1 ? results[0] : results, "json");
|
|
221
203
|
} else {
|
|
222
204
|
for (const { key, value } of results) {
|
|
223
205
|
this.log(`Set ${key} = ${value}`);
|
|
@@ -234,10 +216,8 @@ Usage: jaw config set key=value [key=value ...]`
|
|
|
234
216
|
const key = arg.slice(0, eqIndex);
|
|
235
217
|
const value = arg.slice(eqIndex + 1);
|
|
236
218
|
if (!isValidKey(key)) {
|
|
237
|
-
this.error(
|
|
238
|
-
|
|
239
|
-
Valid keys: ${VALID_KEYS.join(", ")}`
|
|
240
|
-
);
|
|
219
|
+
this.error(`Invalid config key: ${key}
|
|
220
|
+
Valid keys: ${VALID_KEYS.join(", ")}`);
|
|
241
221
|
}
|
|
242
222
|
entries.push({ key, value });
|
|
243
223
|
i++;
|
|
@@ -245,10 +225,8 @@ Valid keys: ${VALID_KEYS.join(", ")}`
|
|
|
245
225
|
entries.push({ key: arg, value: rawArgs[i + 1] });
|
|
246
226
|
i += 2;
|
|
247
227
|
} else {
|
|
248
|
-
this.error(
|
|
249
|
-
|
|
250
|
-
Usage: jaw config set key=value [key=value ...]`
|
|
251
|
-
);
|
|
228
|
+
this.error(`Unexpected argument: ${arg}
|
|
229
|
+
Usage: jaw config set key=value [key=value ...]`);
|
|
252
230
|
}
|
|
253
231
|
}
|
|
254
232
|
return entries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/paths.ts","../../../src/lib/validation.ts","../../../src/lib/config.ts","../../../src/lib/output.ts","../../../src/base-command.ts","../../../src/commands/config/set.ts"],"names":[],"mappings":"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","file":"set.js","sourcesContent":["import * as path from \"node:path\";\nimport * as os from \"node:os\";\n\nconst JAW_DIR = path.join(os.homedir(), \".jaw\");\n\nexport const PATHS = {\n root: JAW_DIR,\n config: path.join(JAW_DIR, \"config.json\"),\n session: path.join(JAW_DIR, \"session.json\"),\n relay: path.join(JAW_DIR, \"relay.json\"),\n} as const;\n","export function isValidAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(value);\n}\n\nexport function isValidHex(value: string): boolean {\n return /^0x[0-9a-fA-F]*$/.test(value);\n}\n\nexport function isValidChainId(value: string | number): boolean {\n const num = typeof value === \"string\" ? parseInt(value, 10) : value;\n return Number.isInteger(num) && num > 0;\n}\n\nexport function parseChainId(value: string): number {\n const num = parseInt(value, 10);\n if (!isValidChainId(num)) {\n throw new Error(`Invalid chain ID: ${value}`);\n }\n return num;\n}\n\nexport function assertAddress(value: string, label = \"address\"): `0x${string}` {\n if (!isValidAddress(value)) {\n throw new Error(`Invalid ${label}: ${value}`);\n }\n return value as `0x${string}`;\n}\n\nexport function parseWei(raw: string, label = \"value\"): bigint {\n try {\n return BigInt(raw);\n } catch {\n throw new Error(`Invalid ${label}: \"${raw}\" is not a valid wei amount`);\n }\n}\n\nexport function isValidKeysUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isTrustedHost =\n parsed.hostname.endsWith(\".jaw.id\") ||\n parsed.hostname === \"jaw.id\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"127.0.0.1\";\n const isSecure =\n parsed.protocol === \"https:\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"127.0.0.1\";\n return isTrustedHost && isSecure;\n } catch {\n return false;\n }\n}\n\nexport function isValidRelayUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isTrustedHost =\n parsed.hostname.endsWith(\".jaw.id\") ||\n parsed.hostname === \"jaw.id\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"127.0.0.1\";\n const isSecure =\n parsed.protocol === \"wss:\" ||\n parsed.hostname === \"localhost\" ||\n parsed.hostname === \"127.0.0.1\";\n const isWebSocket =\n parsed.protocol === \"wss:\" || parsed.protocol === \"ws:\";\n return isTrustedHost && isSecure && isWebSocket;\n } catch {\n return false;\n }\n}\n","import * as fs from \"node:fs\";\nimport { PATHS } from \"./paths.js\";\nimport type { JawConfig } from \"./types.js\";\nimport { isValidKeysUrl, isValidRelayUrl } from \"./validation.js\";\n\nexport function ensureDir(dir: string): void {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n fs.chmodSync(dir, 0o700);\n}\n\nexport function loadConfig(): JawConfig {\n if (!fs.existsSync(PATHS.config)) {\n return {};\n }\n const raw = fs.readFileSync(PATHS.config, \"utf-8\");\n try {\n return JSON.parse(raw) as JawConfig;\n } catch {\n throw new Error(\n `Config file at ${PATHS.config} is not valid JSON. Run \\`jaw config set apiKey=<key>\\` to reset it.`,\n );\n }\n}\n\nexport function saveConfig(config: JawConfig): void {\n ensureDir(PATHS.root);\n fs.writeFileSync(PATHS.config, JSON.stringify(config, null, 2) + \"\\n\", {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n}\n\nexport function redactConfig(config: JawConfig): Record<string, unknown> {\n return {\n ...config,\n apiKey: config.apiKey ? `${config.apiKey.slice(0, 8)}...` : undefined,\n };\n}\n\nexport function getConfigValue(\n key: keyof JawConfig,\n): string | number | undefined {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue(\n key: keyof JawConfig,\n value: string | number,\n): void {\n if (\n key === \"keysUrl\" &&\n typeof value === \"string\" &&\n !isValidKeysUrl(value)\n ) {\n throw new Error(\n `Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`,\n );\n }\n if (\n key === \"relayUrl\" &&\n typeof value === \"string\" &&\n !isValidRelayUrl(value)\n ) {\n throw new Error(\n `Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`,\n );\n }\n const config = loadConfig();\n const updated = { ...config, [key]: value };\n saveConfig(updated);\n}\n","import type { OutputFormat } from './types.js';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, replaceBigInt, 2);\n }\n return formatHuman(data);\n}\n\nfunction replaceBigInt(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n}\n\nfunction formatHuman(data: unknown, indent = 0): string {\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'bigint') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '(empty)';\n return data.map((item, i) => `${i + 1}. ${formatHuman(item, indent + 2)}`).join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '(empty)';\n const pad = ' '.repeat(indent);\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n return entries\n .map(([key, val]) => {\n const paddedKey = key.padEnd(maxKeyLen);\n const valStr = typeof val === 'object' && val !== null\n ? '\\n' + formatHuman(val, indent + 2)\n : String(val);\n return `${pad}${paddedKey} ${valStr}`;\n })\n .join('\\n');\n }\n\n return String(data);\n}\n\nexport function printTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return '(no results)';\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map(k =>\n Math.max(k.length, ...rows.map(r => String(r[k] ?? '').length))\n );\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(' ');\n const separator = widths.map(w => '-'.repeat(w)).join(' ');\n const body = rows.map(r =>\n keys.map((k, i) => String(r[k] ?? '').padEnd(widths[i])).join(' ')\n ).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport type { OutputFormat } from \"./lib/types.js\";\nimport { loadConfig } from \"./lib/config.js\";\nimport { formatOutput } from \"./lib/output.js\";\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n output: Flags.string({\n char: \"o\",\n description: \"Output format\",\n options: [\"json\", \"human\"],\n default: \"human\",\n env: \"JAW_OUTPUT\",\n }),\n chain: Flags.integer({\n char: \"c\",\n description: \"Chain ID\",\n env: \"JAW_CHAIN_ID\",\n }),\n \"api-key\": Flags.string({\n description: \"JAW API key\",\n env: \"JAW_API_KEY\",\n }),\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmations (for AI agents)\",\n default: false,\n }),\n quiet: Flags.boolean({\n char: \"q\",\n description: \"Suppress non-essential output\",\n default: false,\n }),\n };\n\n protected resolveApiKey(flags: { \"api-key\"?: string }): string {\n const apiKey = flags[\"api-key\"] ?? loadConfig().apiKey;\n if (!apiKey) {\n this.error(\n \"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`\",\n );\n }\n return apiKey;\n }\n\n protected resolveChainId(flags: { chain?: number }): number {\n const chainId = flags.chain ?? loadConfig().defaultChain;\n if (!chainId) {\n this.error(\n \"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`\",\n );\n }\n return chainId;\n }\n\n protected outputResult(data: unknown, format: OutputFormat): void {\n const output = formatOutput(data, format);\n this.log(output);\n }\n}\n","import { BaseCommand } from \"../../base-command.js\";\nimport { setConfigValue } from \"../../lib/config.js\";\n\nconst VALID_KEYS = [\n \"apiKey\",\n \"defaultChain\",\n \"keysUrl\",\n \"paymasterUrl\",\n \"ens\",\n \"relayUrl\",\n] as const;\n\ntype ValidKey = (typeof VALID_KEYS)[number];\n\nfunction isValidKey(key: string): key is ValidKey {\n return VALID_KEYS.includes(key as ValidKey);\n}\n\nexport default class ConfigSet extends BaseCommand {\n static override description =\n \"Set one or more configuration values. Accepts key=value pairs or a single key value.\";\n\n static override examples = [\n \"<%= config.bin %> config set apiKey=your-api-key defaultChain=8453\",\n \"<%= config.bin %> config set ens=yourdomain.eth paymasterUrl=https://your-paymaster.com\",\n \"<%= config.bin %> config set apiKey your-api-key\",\n ];\n\n static override strict = false;\n\n static override args = {};\n\n static override flags = {\n ...BaseCommand.baseFlags,\n };\n\n async run(): Promise<void> {\n const { argv, flags } = await this.parse(ConfigSet);\n const rawArgs = argv as string[];\n\n // Parse key=value pairs from all args\n const entries = this.parseEntries(rawArgs);\n\n if (entries.length === 0) {\n this.error(\n `No valid key=value pairs provided.\\nValid keys: ${VALID_KEYS.join(\", \")}\\nUsage: jaw config set key=value [key=value ...]`,\n );\n }\n\n const results: { key: string; value: string | number }[] = [];\n\n for (const { key, value } of entries) {\n const parsed = key === \"defaultChain\" ? parseInt(value, 10) : value;\n\n if (key === \"defaultChain\" && isNaN(parsed as number)) {\n this.error(`Invalid chain ID: ${value}`);\n }\n\n setConfigValue(key, parsed as string | number);\n\n const displayValue =\n key === \"apiKey\" && typeof value === \"string\"\n ? `${value.slice(0, 8)}...`\n : parsed;\n\n results.push({ key, value: displayValue });\n }\n\n if (flags.output === \"json\") {\n this.outputResult(\n results.length === 1 ? results[0] : results,\n \"json\",\n );\n } else {\n for (const { key, value } of results) {\n this.log(`Set ${key} = ${value}`);\n }\n }\n }\n\n private parseEntries(\n rawArgs: string[],\n ): { key: ValidKey; value: string }[] {\n const entries: { key: ValidKey; value: string }[] = [];\n\n let i = 0;\n while (i < rawArgs.length) {\n const arg = rawArgs[i];\n\n if (arg.includes(\"=\")) {\n // key=value syntax\n const eqIndex = arg.indexOf(\"=\");\n const key = arg.slice(0, eqIndex);\n const value = arg.slice(eqIndex + 1);\n\n if (!isValidKey(key)) {\n this.error(\n `Invalid config key: ${key}\\nValid keys: ${VALID_KEYS.join(\", \")}`,\n );\n }\n entries.push({ key, value });\n i++;\n } else if (isValidKey(arg) && i + 1 < rawArgs.length) {\n // key value syntax (legacy)\n entries.push({ key: arg, value: rawArgs[i + 1] });\n i += 2;\n } else {\n this.error(\n `Unexpected argument: ${arg}\\nUsage: jaw config set key=value [key=value ...]`,\n );\n }\n }\n\n return entries;\n }\n}"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/paths.ts","../../../src/lib/validation.ts","../../../src/lib/config.ts","../../../src/lib/output.ts","../../../src/base-command.ts","../../../src/commands/config/set.ts"],"names":[],"mappings":"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","file":"set.js","sourcesContent":["import * as path from 'node:path';\nimport * as os from 'node:os';\n\nconst JAW_DIR = path.join(os.homedir(), '.jaw');\n\nexport const PATHS = {\n root: JAW_DIR,\n config: path.join(JAW_DIR, 'config.json'),\n session: path.join(JAW_DIR, 'session.json'),\n relay: path.join(JAW_DIR, 'relay.json'),\n} as const;\n","export function isValidAddress(value: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(value);\n}\n\nexport function isValidHex(value: string): boolean {\n return /^0x[0-9a-fA-F]*$/.test(value);\n}\n\nexport function isValidChainId(value: string | number): boolean {\n const num = typeof value === 'string' ? parseInt(value, 10) : value;\n return Number.isInteger(num) && num > 0;\n}\n\nexport function parseChainId(value: string): number {\n const num = parseInt(value, 10);\n if (!isValidChainId(num)) {\n throw new Error(`Invalid chain ID: ${value}`);\n }\n return num;\n}\n\nexport function assertAddress(value: string, label = 'address'): `0x${string}` {\n if (!isValidAddress(value)) {\n throw new Error(`Invalid ${label}: ${value}`);\n }\n return value as `0x${string}`;\n}\n\nexport function parseWei(raw: string, label = 'value'): bigint {\n try {\n return BigInt(raw);\n } catch {\n throw new Error(`Invalid ${label}: \"${raw}\" is not a valid wei amount`);\n }\n}\n\nexport function isValidKeysUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isTrustedHost =\n parsed.hostname.endsWith('.jaw.id') ||\n parsed.hostname === 'jaw.id' ||\n parsed.hostname === 'localhost' ||\n parsed.hostname === '127.0.0.1';\n const isSecure = parsed.protocol === 'https:' || parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n return isTrustedHost && isSecure;\n } catch {\n return false;\n }\n}\n\nexport function isValidRelayUrl(url: string): boolean {\n try {\n const parsed = new URL(url);\n const isTrustedHost =\n parsed.hostname.endsWith('.jaw.id') ||\n parsed.hostname === 'jaw.id' ||\n parsed.hostname === 'localhost' ||\n parsed.hostname === '127.0.0.1';\n const isSecure = parsed.protocol === 'wss:' || parsed.hostname === 'localhost' || parsed.hostname === '127.0.0.1';\n const isWebSocket = parsed.protocol === 'wss:' || parsed.protocol === 'ws:';\n return isTrustedHost && isSecure && isWebSocket;\n } catch {\n return false;\n }\n}\n","import * as fs from 'node:fs';\nimport { PATHS } from './paths.js';\nimport type { JawConfig } from './types.js';\nimport { isValidKeysUrl, isValidRelayUrl } from './validation.js';\n\nexport function ensureDir(dir: string): void {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n fs.chmodSync(dir, 0o700);\n}\n\nexport function loadConfig(): JawConfig {\n if (!fs.existsSync(PATHS.config)) {\n return {};\n }\n const raw = fs.readFileSync(PATHS.config, 'utf-8');\n try {\n return JSON.parse(raw) as JawConfig;\n } catch {\n throw new Error(\n `Config file at ${PATHS.config} is not valid JSON. Run \\`jaw config set apiKey=<key>\\` to reset it.`\n );\n }\n}\n\nexport function saveConfig(config: JawConfig): void {\n ensureDir(PATHS.root);\n fs.writeFileSync(PATHS.config, JSON.stringify(config, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n}\n\nexport function redactConfig(config: JawConfig): Record<string, unknown> {\n return {\n ...config,\n apiKey: config.apiKey ? `${config.apiKey.slice(0, 8)}...` : undefined,\n };\n}\n\nexport function getConfigValue(key: keyof JawConfig): string | number | undefined {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue(key: keyof JawConfig, value: string | number): void {\n if (key === 'keysUrl' && typeof value === 'string' && !isValidKeysUrl(value)) {\n throw new Error(`Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`);\n }\n if (key === 'relayUrl' && typeof value === 'string' && !isValidRelayUrl(value)) {\n throw new Error(`Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`);\n }\n const config = loadConfig();\n const updated = { ...config, [key]: value };\n saveConfig(updated);\n}\n","import type { OutputFormat } from './types.js';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, replaceBigInt, 2);\n }\n return formatHuman(data);\n}\n\nfunction replaceBigInt(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n}\n\nfunction formatHuman(data: unknown, indent = 0): string {\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'bigint') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '(empty)';\n return data.map((item, i) => `${i + 1}. ${formatHuman(item, indent + 2)}`).join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '(empty)';\n const pad = ' '.repeat(indent);\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n return entries\n .map(([key, val]) => {\n const paddedKey = key.padEnd(maxKeyLen);\n const valStr = typeof val === 'object' && val !== null ? '\\n' + formatHuman(val, indent + 2) : String(val);\n return `${pad}${paddedKey} ${valStr}`;\n })\n .join('\\n');\n }\n\n return String(data);\n}\n\nexport function printTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return '(no results)';\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? '').length)));\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(' ');\n const separator = widths.map((w) => '-'.repeat(w)).join(' ');\n const body = rows.map((r) => keys.map((k, i) => String(r[k] ?? '').padEnd(widths[i])).join(' ')).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n","import { Command, Flags } from '@oclif/core';\nimport type { OutputFormat } from './lib/types.js';\nimport { loadConfig } from './lib/config.js';\nimport { formatOutput } from './lib/output.js';\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n output: Flags.string({\n char: 'o',\n description: 'Output format',\n options: ['json', 'human'],\n default: 'human',\n env: 'JAW_OUTPUT',\n }),\n chain: Flags.integer({\n char: 'c',\n description: 'Chain ID',\n env: 'JAW_CHAIN_ID',\n }),\n 'api-key': Flags.string({\n description: 'JAW API key',\n env: 'JAW_API_KEY',\n }),\n yes: Flags.boolean({\n char: 'y',\n description: 'Skip confirmations (for AI agents)',\n default: false,\n }),\n quiet: Flags.boolean({\n char: 'q',\n description: 'Suppress non-essential output',\n default: false,\n }),\n };\n\n protected resolveApiKey(flags: { 'api-key'?: string }): string {\n const apiKey = flags['api-key'] ?? loadConfig().apiKey;\n if (!apiKey) {\n this.error('API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`');\n }\n return apiKey;\n }\n\n protected resolveChainId(flags: { chain?: number }): number {\n const chainId = flags.chain ?? loadConfig().defaultChain;\n if (!chainId) {\n this.error('Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`');\n }\n return chainId;\n }\n\n protected outputResult(data: unknown, format: OutputFormat): void {\n const output = formatOutput(data, format);\n this.log(output);\n }\n}\n","import { BaseCommand } from '../../base-command.js';\nimport { setConfigValue } from '../../lib/config.js';\n\nconst VALID_KEYS = ['apiKey', 'defaultChain', 'keysUrl', 'paymasterUrl', 'ens', 'relayUrl'] as const;\n\ntype ValidKey = (typeof VALID_KEYS)[number];\n\nfunction isValidKey(key: string): key is ValidKey {\n return VALID_KEYS.includes(key as ValidKey);\n}\n\nexport default class ConfigSet extends BaseCommand {\n static override description = 'Set one or more configuration values. Accepts key=value pairs or a single key value.';\n\n static override examples = [\n '<%= config.bin %> config set apiKey=your-api-key defaultChain=8453',\n '<%= config.bin %> config set ens=yourdomain.eth paymasterUrl=https://your-paymaster.com',\n '<%= config.bin %> config set apiKey your-api-key',\n ];\n\n static override strict = false;\n\n static override args = {};\n\n static override flags = {\n ...BaseCommand.baseFlags,\n };\n\n async run(): Promise<void> {\n const { argv, flags } = await this.parse(ConfigSet);\n const rawArgs = argv as string[];\n\n // Parse key=value pairs from all args\n const entries = this.parseEntries(rawArgs);\n\n if (entries.length === 0) {\n this.error(\n `No valid key=value pairs provided.\\nValid keys: ${VALID_KEYS.join(', ')}\\nUsage: jaw config set key=value [key=value ...]`\n );\n }\n\n const results: { key: string; value: string | number }[] = [];\n\n for (const { key, value } of entries) {\n const parsed = key === 'defaultChain' ? parseInt(value, 10) : value;\n\n if (key === 'defaultChain' && isNaN(parsed as number)) {\n this.error(`Invalid chain ID: ${value}`);\n }\n\n setConfigValue(key, parsed as string | number);\n\n const displayValue = key === 'apiKey' && typeof value === 'string' ? `${value.slice(0, 8)}...` : parsed;\n\n results.push({ key, value: displayValue });\n }\n\n if (flags.output === 'json') {\n this.outputResult(results.length === 1 ? results[0] : results, 'json');\n } else {\n for (const { key, value } of results) {\n this.log(`Set ${key} = ${value}`);\n }\n }\n }\n\n private parseEntries(rawArgs: string[]): { key: ValidKey; value: string }[] {\n const entries: { key: ValidKey; value: string }[] = [];\n\n let i = 0;\n while (i < rawArgs.length) {\n const arg = rawArgs[i];\n\n if (arg.includes('=')) {\n // key=value syntax\n const eqIndex = arg.indexOf('=');\n const key = arg.slice(0, eqIndex);\n const value = arg.slice(eqIndex + 1);\n\n if (!isValidKey(key)) {\n this.error(`Invalid config key: ${key}\\nValid keys: ${VALID_KEYS.join(', ')}`);\n }\n entries.push({ key, value });\n i++;\n } else if (isValidKey(arg) && i + 1 < rawArgs.length) {\n // key value syntax (legacy)\n entries.push({ key: arg, value: rawArgs[i + 1] });\n i += 2;\n } else {\n this.error(`Unexpected argument: ${arg}\\nUsage: jaw config set key=value [key=value ...]`);\n }\n }\n\n return entries;\n }\n}\n"]}
|
|
@@ -103,18 +103,14 @@ var BaseCommand = class extends Command {
|
|
|
103
103
|
resolveApiKey(flags) {
|
|
104
104
|
const apiKey = flags["api-key"] ?? loadConfig().apiKey;
|
|
105
105
|
if (!apiKey) {
|
|
106
|
-
this.error(
|
|
107
|
-
"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`"
|
|
108
|
-
);
|
|
106
|
+
this.error("API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`");
|
|
109
107
|
}
|
|
110
108
|
return apiKey;
|
|
111
109
|
}
|
|
112
110
|
resolveChainId(flags) {
|
|
113
111
|
const chainId = flags.chain ?? loadConfig().defaultChain;
|
|
114
112
|
if (!chainId) {
|
|
115
|
-
this.error(
|
|
116
|
-
"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`"
|
|
117
|
-
);
|
|
113
|
+
this.error("Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`");
|
|
118
114
|
}
|
|
119
115
|
return chainId;
|
|
120
116
|
}
|
|
@@ -127,10 +123,7 @@ var BaseCommand = class extends Command {
|
|
|
127
123
|
// src/commands/config/show.ts
|
|
128
124
|
var ConfigShow = class _ConfigShow extends BaseCommand {
|
|
129
125
|
static description = "Show current CLI configuration";
|
|
130
|
-
static examples = [
|
|
131
|
-
"<%= config.bin %> config show",
|
|
132
|
-
"<%= config.bin %> config show --output json"
|
|
133
|
-
];
|
|
126
|
+
static examples = ["<%= config.bin %> config show", "<%= config.bin %> config show --output json"];
|
|
134
127
|
static flags = {
|
|
135
128
|
...BaseCommand.baseFlags
|
|
136
129
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/lib/paths.ts","../../../src/lib/config.ts","../../../src/lib/output.ts","../../../src/base-command.ts","../../../src/commands/config/show.ts"],"names":[],"mappings":"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","file":"show.js","sourcesContent":["import * as path from \"node:path\";\nimport * as os from \"node:os\";\n\nconst JAW_DIR = path.join(os.homedir(), \".jaw\");\n\nexport const PATHS = {\n root: JAW_DIR,\n config: path.join(JAW_DIR, \"config.json\"),\n session: path.join(JAW_DIR, \"session.json\"),\n relay: path.join(JAW_DIR, \"relay.json\"),\n} as const;\n","import * as fs from \"node:fs\";\nimport { PATHS } from \"./paths.js\";\nimport type { JawConfig } from \"./types.js\";\nimport { isValidKeysUrl, isValidRelayUrl } from \"./validation.js\";\n\nexport function ensureDir(dir: string): void {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n fs.chmodSync(dir, 0o700);\n}\n\nexport function loadConfig(): JawConfig {\n if (!fs.existsSync(PATHS.config)) {\n return {};\n }\n const raw = fs.readFileSync(PATHS.config, \"utf-8\");\n try {\n return JSON.parse(raw) as JawConfig;\n } catch {\n throw new Error(\n `Config file at ${PATHS.config} is not valid JSON. Run \\`jaw config set apiKey=<key>\\` to reset it.`,\n );\n }\n}\n\nexport function saveConfig(config: JawConfig): void {\n ensureDir(PATHS.root);\n fs.writeFileSync(PATHS.config, JSON.stringify(config, null, 2) + \"\\n\", {\n encoding: \"utf-8\",\n mode: 0o600,\n });\n}\n\nexport function redactConfig(config: JawConfig): Record<string, unknown> {\n return {\n ...config,\n apiKey: config.apiKey ? `${config.apiKey.slice(0, 8)}...` : undefined,\n };\n}\n\nexport function getConfigValue(\n key: keyof JawConfig,\n): string | number | undefined {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue(\n key: keyof JawConfig,\n value: string | number,\n): void {\n if (\n key === \"keysUrl\" &&\n typeof value === \"string\" &&\n !isValidKeysUrl(value)\n ) {\n throw new Error(\n `Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`,\n );\n }\n if (\n key === \"relayUrl\" &&\n typeof value === \"string\" &&\n !isValidRelayUrl(value)\n ) {\n throw new Error(\n `Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`,\n );\n }\n const config = loadConfig();\n const updated = { ...config, [key]: value };\n saveConfig(updated);\n}\n","import type { OutputFormat } from './types.js';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, replaceBigInt, 2);\n }\n return formatHuman(data);\n}\n\nfunction replaceBigInt(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n}\n\nfunction formatHuman(data: unknown, indent = 0): string {\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'bigint') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '(empty)';\n return data.map((item, i) => `${i + 1}. ${formatHuman(item, indent + 2)}`).join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '(empty)';\n const pad = ' '.repeat(indent);\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n return entries\n .map(([key, val]) => {\n const paddedKey = key.padEnd(maxKeyLen);\n const valStr = typeof val === 'object' && val !== null\n ? '\\n' + formatHuman(val, indent + 2)\n : String(val);\n return `${pad}${paddedKey} ${valStr}`;\n })\n .join('\\n');\n }\n\n return String(data);\n}\n\nexport function printTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return '(no results)';\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map(k =>\n Math.max(k.length, ...rows.map(r => String(r[k] ?? '').length))\n );\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(' ');\n const separator = widths.map(w => '-'.repeat(w)).join(' ');\n const body = rows.map(r =>\n keys.map((k, i) => String(r[k] ?? '').padEnd(widths[i])).join(' ')\n ).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n","import { Command, Flags } from \"@oclif/core\";\nimport type { OutputFormat } from \"./lib/types.js\";\nimport { loadConfig } from \"./lib/config.js\";\nimport { formatOutput } from \"./lib/output.js\";\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n output: Flags.string({\n char: \"o\",\n description: \"Output format\",\n options: [\"json\", \"human\"],\n default: \"human\",\n env: \"JAW_OUTPUT\",\n }),\n chain: Flags.integer({\n char: \"c\",\n description: \"Chain ID\",\n env: \"JAW_CHAIN_ID\",\n }),\n \"api-key\": Flags.string({\n description: \"JAW API key\",\n env: \"JAW_API_KEY\",\n }),\n yes: Flags.boolean({\n char: \"y\",\n description: \"Skip confirmations (for AI agents)\",\n default: false,\n }),\n quiet: Flags.boolean({\n char: \"q\",\n description: \"Suppress non-essential output\",\n default: false,\n }),\n };\n\n protected resolveApiKey(flags: { \"api-key\"?: string }): string {\n const apiKey = flags[\"api-key\"] ?? loadConfig().apiKey;\n if (!apiKey) {\n this.error(\n \"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`\",\n );\n }\n return apiKey;\n }\n\n protected resolveChainId(flags: { chain?: number }): number {\n const chainId = flags.chain ?? loadConfig().defaultChain;\n if (!chainId) {\n this.error(\n \"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`\",\n );\n }\n return chainId;\n }\n\n protected outputResult(data: unknown, format: OutputFormat): void {\n const output = formatOutput(data, format);\n this.log(output);\n }\n}\n","import { BaseCommand } from \"../../base-command.js\";\nimport { loadConfig, redactConfig } from \"../../lib/config.js\";\n\nexport default class ConfigShow extends BaseCommand {\n static override description = \"Show current CLI configuration\";\n\n static override examples = [\n \"<%= config.bin %> config show\",\n \"<%= config.bin %> config show --output json\",\n ];\n\n static override flags = {\n ...BaseCommand.baseFlags,\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(ConfigShow);\n const config = loadConfig();\n this.outputResult(redactConfig(config), flags.output as \"json\" | \"human\");\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/paths.ts","../../../src/lib/config.ts","../../../src/lib/output.ts","../../../src/base-command.ts","../../../src/commands/config/show.ts"],"names":[],"mappings":"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","file":"show.js","sourcesContent":["import * as path from 'node:path';\nimport * as os from 'node:os';\n\nconst JAW_DIR = path.join(os.homedir(), '.jaw');\n\nexport const PATHS = {\n root: JAW_DIR,\n config: path.join(JAW_DIR, 'config.json'),\n session: path.join(JAW_DIR, 'session.json'),\n relay: path.join(JAW_DIR, 'relay.json'),\n} as const;\n","import * as fs from 'node:fs';\nimport { PATHS } from './paths.js';\nimport type { JawConfig } from './types.js';\nimport { isValidKeysUrl, isValidRelayUrl } from './validation.js';\n\nexport function ensureDir(dir: string): void {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n fs.chmodSync(dir, 0o700);\n}\n\nexport function loadConfig(): JawConfig {\n if (!fs.existsSync(PATHS.config)) {\n return {};\n }\n const raw = fs.readFileSync(PATHS.config, 'utf-8');\n try {\n return JSON.parse(raw) as JawConfig;\n } catch {\n throw new Error(\n `Config file at ${PATHS.config} is not valid JSON. Run \\`jaw config set apiKey=<key>\\` to reset it.`\n );\n }\n}\n\nexport function saveConfig(config: JawConfig): void {\n ensureDir(PATHS.root);\n fs.writeFileSync(PATHS.config, JSON.stringify(config, null, 2) + '\\n', {\n encoding: 'utf-8',\n mode: 0o600,\n });\n}\n\nexport function redactConfig(config: JawConfig): Record<string, unknown> {\n return {\n ...config,\n apiKey: config.apiKey ? `${config.apiKey.slice(0, 8)}...` : undefined,\n };\n}\n\nexport function getConfigValue(key: keyof JawConfig): string | number | undefined {\n const config = loadConfig();\n return config[key];\n}\n\nexport function setConfigValue(key: keyof JawConfig, value: string | number): void {\n if (key === 'keysUrl' && typeof value === 'string' && !isValidKeysUrl(value)) {\n throw new Error(`Untrusted keysUrl: ${value}. Must be a *.jaw.id domain (HTTPS) or localhost.`);\n }\n if (key === 'relayUrl' && typeof value === 'string' && !isValidRelayUrl(value)) {\n throw new Error(`Untrusted relayUrl: ${value}. Must be wss://*.jaw.id or ws://localhost.`);\n }\n const config = loadConfig();\n const updated = { ...config, [key]: value };\n saveConfig(updated);\n}\n","import type { OutputFormat } from './types.js';\n\nexport function formatOutput(data: unknown, format: OutputFormat): string {\n if (format === 'json') {\n return JSON.stringify(data, replaceBigInt, 2);\n }\n return formatHuman(data);\n}\n\nfunction replaceBigInt(_key: string, value: unknown): unknown {\n if (typeof value === 'bigint') {\n return value.toString();\n }\n return value;\n}\n\nfunction formatHuman(data: unknown, indent = 0): string {\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string' || typeof data === 'number' || typeof data === 'boolean' || typeof data === 'bigint') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '(empty)';\n return data.map((item, i) => `${i + 1}. ${formatHuman(item, indent + 2)}`).join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '(empty)';\n const pad = ' '.repeat(indent);\n const maxKeyLen = Math.max(...entries.map(([k]) => k.length));\n return entries\n .map(([key, val]) => {\n const paddedKey = key.padEnd(maxKeyLen);\n const valStr = typeof val === 'object' && val !== null ? '\\n' + formatHuman(val, indent + 2) : String(val);\n return `${pad}${paddedKey} ${valStr}`;\n })\n .join('\\n');\n }\n\n return String(data);\n}\n\nexport function printTable(rows: Record<string, unknown>[]): string {\n if (rows.length === 0) return '(no results)';\n\n const keys = Object.keys(rows[0]);\n const widths = keys.map((k) => Math.max(k.length, ...rows.map((r) => String(r[k] ?? '').length)));\n\n const header = keys.map((k, i) => k.padEnd(widths[i])).join(' ');\n const separator = widths.map((w) => '-'.repeat(w)).join(' ');\n const body = rows.map((r) => keys.map((k, i) => String(r[k] ?? '').padEnd(widths[i])).join(' ')).join('\\n');\n\n return `${header}\\n${separator}\\n${body}`;\n}\n","import { Command, Flags } from '@oclif/core';\nimport type { OutputFormat } from './lib/types.js';\nimport { loadConfig } from './lib/config.js';\nimport { formatOutput } from './lib/output.js';\n\nexport abstract class BaseCommand extends Command {\n static override baseFlags = {\n output: Flags.string({\n char: 'o',\n description: 'Output format',\n options: ['json', 'human'],\n default: 'human',\n env: 'JAW_OUTPUT',\n }),\n chain: Flags.integer({\n char: 'c',\n description: 'Chain ID',\n env: 'JAW_CHAIN_ID',\n }),\n 'api-key': Flags.string({\n description: 'JAW API key',\n env: 'JAW_API_KEY',\n }),\n yes: Flags.boolean({\n char: 'y',\n description: 'Skip confirmations (for AI agents)',\n default: false,\n }),\n quiet: Flags.boolean({\n char: 'q',\n description: 'Suppress non-essential output',\n default: false,\n }),\n };\n\n protected resolveApiKey(flags: { 'api-key'?: string }): string {\n const apiKey = flags['api-key'] ?? loadConfig().apiKey;\n if (!apiKey) {\n this.error('API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`');\n }\n return apiKey;\n }\n\n protected resolveChainId(flags: { chain?: number }): number {\n const chainId = flags.chain ?? loadConfig().defaultChain;\n if (!chainId) {\n this.error('Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`');\n }\n return chainId;\n }\n\n protected outputResult(data: unknown, format: OutputFormat): void {\n const output = formatOutput(data, format);\n this.log(output);\n }\n}\n","import { BaseCommand } from '../../base-command.js';\nimport { loadConfig, redactConfig } from '../../lib/config.js';\n\nexport default class ConfigShow extends BaseCommand {\n static override description = 'Show current CLI configuration';\n\n static override examples = ['<%= config.bin %> config show', '<%= config.bin %> config show --output json'];\n\n static override flags = {\n ...BaseCommand.baseFlags,\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(ConfigShow);\n const config = loadConfig();\n this.outputResult(redactConfig(config), flags.output as 'json' | 'human');\n }\n}\n"]}
|
|
@@ -100,18 +100,14 @@ var BaseCommand = class extends Command {
|
|
|
100
100
|
resolveApiKey(flags) {
|
|
101
101
|
const apiKey = flags["api-key"] ?? loadConfig().apiKey;
|
|
102
102
|
if (!apiKey) {
|
|
103
|
-
this.error(
|
|
104
|
-
"API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`"
|
|
105
|
-
);
|
|
103
|
+
this.error("API key required. Set via --api-key, JAW_API_KEY env, or `jaw config set apiKey <key>`");
|
|
106
104
|
}
|
|
107
105
|
return apiKey;
|
|
108
106
|
}
|
|
109
107
|
resolveChainId(flags) {
|
|
110
108
|
const chainId = flags.chain ?? loadConfig().defaultChain;
|
|
111
109
|
if (!chainId) {
|
|
112
|
-
this.error(
|
|
113
|
-
"Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`"
|
|
114
|
-
);
|
|
110
|
+
this.error("Chain ID required. Set via --chain, JAW_CHAIN_ID env, or `jaw config set defaultChain <id>`");
|
|
115
111
|
}
|
|
116
112
|
return chainId;
|
|
117
113
|
}
|
|
@@ -135,11 +131,7 @@ async function deriveSharedSecret(privateKey, peerPublicKey) {
|
|
|
135
131
|
async function encryptMessage(sharedSecret, payload) {
|
|
136
132
|
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
|
|
137
133
|
const plaintext = new TextEncoder().encode(JSON.stringify(payload));
|
|
138
|
-
const cipherBuf = await subtle.encrypt(
|
|
139
|
-
{ name: "AES-GCM", iv },
|
|
140
|
-
sharedSecret,
|
|
141
|
-
plaintext
|
|
142
|
-
);
|
|
134
|
+
const cipherBuf = await subtle.encrypt({ name: "AES-GCM", iv }, sharedSecret, plaintext);
|
|
143
135
|
return {
|
|
144
136
|
iv: bufferToBase64(iv),
|
|
145
137
|
ciphertext: bufferToBase64(new Uint8Array(cipherBuf))
|
|
@@ -148,11 +140,7 @@ async function encryptMessage(sharedSecret, payload) {
|
|
|
148
140
|
async function decryptMessage(sharedSecret, envelope) {
|
|
149
141
|
const iv = Buffer.from(envelope.iv, "base64");
|
|
150
142
|
const ciphertext = Buffer.from(envelope.ciphertext, "base64");
|
|
151
|
-
const plainBuf = await subtle.decrypt(
|
|
152
|
-
{ name: "AES-GCM", iv },
|
|
153
|
-
sharedSecret,
|
|
154
|
-
ciphertext
|
|
155
|
-
);
|
|
143
|
+
const plainBuf = await subtle.decrypt({ name: "AES-GCM", iv }, sharedSecret, ciphertext);
|
|
156
144
|
return JSON.parse(new TextDecoder().decode(plainBuf));
|
|
157
145
|
}
|
|
158
146
|
async function importKeyFromHex(type, hex) {
|
|
@@ -236,11 +224,7 @@ var WSBridge = class {
|
|
|
236
224
|
let expectingKeyExchange = !this.peerPublicKeyHex;
|
|
237
225
|
const timer = setTimeout(() => {
|
|
238
226
|
ws.close();
|
|
239
|
-
reject(
|
|
240
|
-
new Error(
|
|
241
|
-
"Browser did not connect in time.\nRun `jaw disconnect` then try again."
|
|
242
|
-
)
|
|
243
|
-
);
|
|
227
|
+
reject(new Error("Browser did not connect in time.\nRun `jaw disconnect` then try again."));
|
|
244
228
|
}, 3e4);
|
|
245
229
|
const sendEncryptedInit = async () => {
|
|
246
230
|
if (!this.sharedSecret) return;
|
|
@@ -263,10 +247,7 @@ var WSBridge = class {
|
|
|
263
247
|
if (!msg) return;
|
|
264
248
|
if (msg.type === "encrypted" && this.sharedSecret) {
|
|
265
249
|
try {
|
|
266
|
-
const inner = await decryptMessage(
|
|
267
|
-
this.sharedSecret,
|
|
268
|
-
msg
|
|
269
|
-
);
|
|
250
|
+
const inner = await decryptMessage(this.sharedSecret, msg);
|
|
270
251
|
if (inner.type === "ready") {
|
|
271
252
|
clearTimeout(readyTimer);
|
|
272
253
|
ws.off("message", onMsg);
|
|
@@ -353,9 +334,7 @@ var WSBridge = class {
|
|
|
353
334
|
return new Promise((resolve, reject) => {
|
|
354
335
|
const timer = setTimeout(() => {
|
|
355
336
|
reject(
|
|
356
|
-
new Error(
|
|
357
|
-
`Request timed out after ${this.timeout / 1e3}s. Did you complete the action in the browser?`
|
|
358
|
-
)
|
|
337
|
+
new Error(`Request timed out after ${this.timeout / 1e3}s. Did you complete the action in the browser?`)
|
|
359
338
|
);
|
|
360
339
|
this.close();
|
|
361
340
|
}, this.timeout);
|
|
@@ -363,10 +342,7 @@ var WSBridge = class {
|
|
|
363
342
|
const msg = safeParse(data);
|
|
364
343
|
if (!msg || msg.type !== "encrypted" || !this.sharedSecret) return;
|
|
365
344
|
try {
|
|
366
|
-
const inner = await decryptMessage(
|
|
367
|
-
this.sharedSecret,
|
|
368
|
-
msg
|
|
369
|
-
);
|
|
345
|
+
const inner = await decryptMessage(this.sharedSecret, msg);
|
|
370
346
|
if (inner.type === "rpc_response" && inner.id === id) {
|
|
371
347
|
clearTimeout(timer);
|
|
372
348
|
ws.off("message", onMessage);
|
|
@@ -374,11 +350,7 @@ var WSBridge = class {
|
|
|
374
350
|
resolve(inner.data);
|
|
375
351
|
} else {
|
|
376
352
|
const err = inner.error;
|
|
377
|
-
reject(
|
|
378
|
-
new Error(
|
|
379
|
-
err ? `[${err.code}] ${err.message}` : "Request failed"
|
|
380
|
-
)
|
|
381
|
-
);
|
|
353
|
+
reject(new Error(err ? `[${err.code}] ${err.message}` : "Request failed"));
|
|
382
354
|
}
|
|
383
355
|
}
|
|
384
356
|
} catch {
|
|
@@ -398,10 +370,7 @@ var WSBridge = class {
|
|
|
398
370
|
const envelope = await encryptMessage(this.sharedSecret, {
|
|
399
371
|
type: "shutdown"
|
|
400
372
|
});
|
|
401
|
-
this.sendRaw(
|
|
402
|
-
this.ws,
|
|
403
|
-
JSON.stringify({ type: "encrypted", ...envelope })
|
|
404
|
-
);
|
|
373
|
+
this.sendRaw(this.ws, JSON.stringify({ type: "encrypted", ...envelope }));
|
|
405
374
|
} catch {
|
|
406
375
|
}
|
|
407
376
|
}
|
|
@@ -479,10 +448,8 @@ var WSBridge = class {
|
|
|
479
448
|
this.reconnectAttempts++;
|
|
480
449
|
setTimeout(() => {
|
|
481
450
|
if (this.disposed) return;
|
|
482
|
-
this.connectInternal(this.onBrowserNeeded, this.onPeerKeyChanged).catch(
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
);
|
|
451
|
+
this.connectInternal(this.onBrowserNeeded, this.onPeerKeyChanged).catch(() => {
|
|
452
|
+
});
|
|
486
453
|
}, delay);
|
|
487
454
|
}
|
|
488
455
|
/** Send a raw string over the WebSocket, enforcing message size limits. */
|
|
@@ -492,10 +459,7 @@ var WSBridge = class {
|
|
|
492
459
|
async deriveSecret() {
|
|
493
460
|
if (!this.peerPublicKeyHex) return;
|
|
494
461
|
const privateKey = await importKeyFromHex("private", this.privateKeyHex);
|
|
495
|
-
const peerPublicKey = await importKeyFromHex(
|
|
496
|
-
"public",
|
|
497
|
-
this.peerPublicKeyHex
|
|
498
|
-
);
|
|
462
|
+
const peerPublicKey = await importKeyFromHex("public", this.peerPublicKeyHex);
|
|
499
463
|
this.sharedSecret = await deriveSharedSecret(privateKey, peerPublicKey);
|
|
500
464
|
}
|
|
501
465
|
};
|