@smartagentkit/cli 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SmartAgentKit Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # smartagentkit
2
+
3
+ CLI tool for managing policy-governed AI agent smart wallets. Create wallets, configure spending limits, manage session keys, and monitor wallet status from the command line.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g smartagentkit
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```bash
14
+ # Initialize configuration
15
+ sak config init
16
+
17
+ # Create a wallet with the defi-trader preset
18
+ sak create --preset defi-trader --owner 0x...
19
+
20
+ # Check wallet status
21
+ sak status 0x...
22
+
23
+ # Add a spending limit policy
24
+ sak policy add --type spending-limit --token 0x... --limit 1000000000000000000 --window 86400
25
+
26
+ # Pause a wallet (emergency)
27
+ sak pause 0x... --guardian-key 0x...
28
+ ```
29
+
30
+ ## Commands
31
+
32
+ - `sak create` - Deploy a new agent wallet
33
+ - `sak status` - Check wallet status and balances
34
+ - `sak fund` - Fund a wallet with ETH
35
+ - `sak policy` - Manage spending limits, allowlists, and pause policies
36
+ - `sak pause` / `sak unpause` - Emergency pause controls
37
+ - `sak session` - Create, list, and revoke session keys
38
+ - `sak config` - Manage CLI configuration
39
+
40
+ ## Documentation
41
+
42
+ See the [main repository](https://github.com/smartagentkit/smartagentkit) for full documentation and examples.
43
+
44
+ ## License
45
+
46
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,745 @@
1
+ #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __esm = (fn, res) => function __init() {
5
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
+ };
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // src/utils/chains.ts
13
+ var chains_exports = {};
14
+ __export(chains_exports, {
15
+ listChains: () => listChains,
16
+ resolveChain: () => resolveChain
17
+ });
18
+ import {
19
+ mainnet,
20
+ sepolia,
21
+ base,
22
+ baseSepolia,
23
+ optimism,
24
+ optimismSepolia,
25
+ arbitrum,
26
+ arbitrumSepolia,
27
+ polygon,
28
+ polygonAmoy
29
+ } from "viem/chains";
30
+ function resolveChain(name) {
31
+ const chain = CHAIN_MAP[name.toLowerCase()];
32
+ if (!chain) {
33
+ const supported = Object.keys(CHAIN_MAP).join(", ");
34
+ throw new Error(
35
+ `Unknown chain "${name}". Supported: ${supported}`
36
+ );
37
+ }
38
+ return chain;
39
+ }
40
+ function listChains() {
41
+ return Object.keys(CHAIN_MAP);
42
+ }
43
+ var CHAIN_MAP;
44
+ var init_chains = __esm({
45
+ "src/utils/chains.ts"() {
46
+ "use strict";
47
+ CHAIN_MAP = {
48
+ "mainnet": mainnet,
49
+ "ethereum": mainnet,
50
+ "sepolia": sepolia,
51
+ "base": base,
52
+ "base-sepolia": baseSepolia,
53
+ "optimism": optimism,
54
+ "optimism-sepolia": optimismSepolia,
55
+ "arbitrum": arbitrum,
56
+ "arbitrum-sepolia": arbitrumSepolia,
57
+ "polygon": polygon,
58
+ "polygon-amoy": polygonAmoy
59
+ };
60
+ }
61
+ });
62
+
63
+ // src/index.ts
64
+ import { Command as Command8 } from "commander";
65
+
66
+ // src/commands/create.ts
67
+ import { Command } from "commander";
68
+ import ora from "ora";
69
+
70
+ // src/utils/client.ts
71
+ import { SmartAgentKitClient } from "@smartagentkit/sdk";
72
+
73
+ // src/utils/config.ts
74
+ import fs from "fs";
75
+ import path from "path";
76
+ import os from "os";
77
+ var CONFIG_DIR = path.join(os.homedir(), ".smartagentkit");
78
+ var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
79
+ var DEFAULT_CONFIG = {
80
+ defaultChain: "base-sepolia"
81
+ };
82
+ function getConfigPath() {
83
+ return CONFIG_FILE;
84
+ }
85
+ function loadConfig() {
86
+ try {
87
+ if (!fs.existsSync(CONFIG_FILE)) {
88
+ return { ...DEFAULT_CONFIG };
89
+ }
90
+ const raw = fs.readFileSync(CONFIG_FILE, "utf-8");
91
+ return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };
92
+ } catch {
93
+ return { ...DEFAULT_CONFIG };
94
+ }
95
+ }
96
+ function saveConfig(config) {
97
+ if (!fs.existsSync(CONFIG_DIR)) {
98
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
99
+ }
100
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n", {
101
+ mode: 384
102
+ });
103
+ }
104
+ function setConfigValue(key, value) {
105
+ const config = loadConfig();
106
+ config[key] = value;
107
+ saveConfig(config);
108
+ }
109
+ function deleteConfigValue(key) {
110
+ const config = loadConfig();
111
+ delete config[key];
112
+ saveConfig(config);
113
+ }
114
+
115
+ // src/utils/client.ts
116
+ init_chains();
117
+ function createSdkClient(options) {
118
+ const config = loadConfig();
119
+ const chainName = options.chain ?? config.defaultChain ?? "base-sepolia";
120
+ const chain = resolveChain(chainName);
121
+ const rpcUrl = options.rpcUrl ?? config.rpcUrl;
122
+ if (!rpcUrl) {
123
+ throw new Error(
124
+ "RPC URL required. Set via --rpc-url flag or `sak config set rpcUrl <url>`"
125
+ );
126
+ }
127
+ const bundlerUrl = options.bundlerUrl ?? config.bundlerUrl;
128
+ if (!bundlerUrl) {
129
+ throw new Error(
130
+ "Bundler URL required. Set via --bundler-url flag or `sak config set bundlerUrl <url>`"
131
+ );
132
+ }
133
+ const moduleAddresses = config.moduleAddresses ? {
134
+ spendingLimitHook: config.moduleAddresses.spendingLimitHook ?? "0x0000000000000000000000000000000000000000",
135
+ allowlistHook: config.moduleAddresses.allowlistHook ?? "0x0000000000000000000000000000000000000000",
136
+ emergencyPauseHook: config.moduleAddresses.emergencyPauseHook ?? "0x0000000000000000000000000000000000000000"
137
+ } : void 0;
138
+ return new SmartAgentKitClient({
139
+ chain,
140
+ rpcUrl,
141
+ bundlerUrl,
142
+ paymasterUrl: config.paymasterUrl,
143
+ moduleAddresses
144
+ });
145
+ }
146
+
147
+ // src/utils/display.ts
148
+ import chalk from "chalk";
149
+ import Table from "cli-table3";
150
+ import { formatEther } from "viem";
151
+ function formatBalance(wei) {
152
+ return `${formatEther(wei)} ETH`;
153
+ }
154
+ function success(message) {
155
+ console.log(chalk.green(`\u2713 ${message}`));
156
+ }
157
+ function error(message) {
158
+ console.error(chalk.red(`\u2717 ${message}`));
159
+ }
160
+ function info(message) {
161
+ console.log(chalk.blue(`i ${message}`));
162
+ }
163
+ function createTable(head) {
164
+ return new Table({
165
+ head: head.map((h) => chalk.cyan(h)),
166
+ style: { head: [], border: [] }
167
+ });
168
+ }
169
+ function printKeyValue(pairs) {
170
+ const maxKeyLen = Math.max(...pairs.map(([k]) => k.length));
171
+ for (const [key, value] of pairs) {
172
+ console.log(` ${chalk.gray(key.padEnd(maxKeyLen))} ${value}`);
173
+ }
174
+ }
175
+
176
+ // src/utils/validation.ts
177
+ import { isAddress, isHex } from "viem";
178
+ function validateAddress(input, label) {
179
+ if (!isAddress(input)) {
180
+ throw new Error(
181
+ `Invalid ${label} address: "${input}". Expected a 0x-prefixed 20-byte hex string.`
182
+ );
183
+ }
184
+ return input;
185
+ }
186
+ function validatePrivateKey(input, label) {
187
+ if (!/^0x[0-9a-fA-F]{64}$/.test(input)) {
188
+ throw new Error(
189
+ `Invalid ${label} private key. Expected a 0x-prefixed 32-byte hex string.`
190
+ );
191
+ }
192
+ return input;
193
+ }
194
+ function validateMnemonic(input, label) {
195
+ const words = input.trim().split(/\s+/);
196
+ if (words.length !== 12 && words.length !== 24) {
197
+ throw new Error(
198
+ `Invalid ${label} mnemonic. Expected 12 or 24 space-separated words.`
199
+ );
200
+ }
201
+ return input.trim();
202
+ }
203
+ function resolveSignerKey(keyValue, mnemonicValue, keyEnvVar, mnemonicEnvVar, label, addressIndex) {
204
+ const rawKey = keyValue ?? process.env[keyEnvVar];
205
+ const rawMnemonic = mnemonicValue ?? process.env[mnemonicEnvVar];
206
+ if (rawKey) {
207
+ return validatePrivateKey(rawKey, label);
208
+ }
209
+ if (rawMnemonic) {
210
+ const mnemonic = validateMnemonic(rawMnemonic, label);
211
+ return { mnemonic, addressIndex: addressIndex ?? 0 };
212
+ }
213
+ throw new Error(
214
+ `No ${label} credential provided. Use --${label}-key <hex>, --${label}-mnemonic <phrase>, or set ${keyEnvVar} / ${mnemonicEnvVar} environment variable.`
215
+ );
216
+ }
217
+ function validateSelector(input, label) {
218
+ if (!/^0x[0-9a-fA-F]{8}$/.test(input)) {
219
+ throw new Error(
220
+ `Invalid ${label} selector: "${input}". Expected a 0x-prefixed 4-byte hex string (e.g., 0xa9059cbb).`
221
+ );
222
+ }
223
+ return input;
224
+ }
225
+ function validateHex(input, label) {
226
+ if (!isHex(input)) {
227
+ throw new Error(
228
+ `Invalid ${label}: "${input}". Expected a 0x-prefixed hex string.`
229
+ );
230
+ }
231
+ return input;
232
+ }
233
+
234
+ // src/commands/create.ts
235
+ var createCommand = new Command("create").description("Create a new agent wallet").requiredOption("--owner <address>", "Owner address").option("--owner-key <hex>", "Owner private key (or set SAK_OWNER_KEY env var)").option("--owner-mnemonic <phrase>", "Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)").option("--address-index <n>", "HD derivation index (default: 0)", "0").option("--preset <name>", "Policy preset (minimal, defi-trader, treasury-agent, payment-agent)").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").option("--salt <number>", "CREATE2 salt for deterministic address").action(async (options) => {
236
+ const spinner = ora("Creating agent wallet...").start();
237
+ try {
238
+ const ownerAddress = validateAddress(options.owner, "owner");
239
+ const ownerKey = resolveSignerKey(
240
+ options.ownerKey,
241
+ options.ownerMnemonic,
242
+ "SAK_OWNER_KEY",
243
+ "SAK_OWNER_MNEMONIC",
244
+ "owner",
245
+ parseInt(options.addressIndex, 10)
246
+ );
247
+ const client = createSdkClient({
248
+ chain: options.chain,
249
+ rpcUrl: options.rpcUrl,
250
+ bundlerUrl: options.bundlerUrl
251
+ });
252
+ const walletParams = {
253
+ owner: ownerAddress,
254
+ preset: options.preset,
255
+ salt: options.salt ? BigInt(options.salt) : void 0
256
+ };
257
+ if (typeof ownerKey === "string") {
258
+ walletParams.ownerPrivateKey = ownerKey;
259
+ } else {
260
+ walletParams.ownerMnemonic = ownerKey.mnemonic;
261
+ walletParams.addressIndex = ownerKey.addressIndex;
262
+ }
263
+ const wallet = await client.createWallet(walletParams);
264
+ spinner.stop();
265
+ success("Agent wallet created!");
266
+ console.log();
267
+ printKeyValue([
268
+ ["Address", wallet.address],
269
+ ["Owner", wallet.owner],
270
+ ["Chain", wallet.chain.name],
271
+ ["Deployed", wallet.isDeployed ? "Yes" : "No (deploy on first tx)"],
272
+ ["Policies", wallet.policies.length.toString()]
273
+ ]);
274
+ if (wallet.policies.length > 0) {
275
+ console.log();
276
+ console.log(" Installed policies:");
277
+ for (const p of wallet.policies) {
278
+ console.log(` - ${p.name} (${p.moduleAddress})`);
279
+ }
280
+ }
281
+ } catch (err) {
282
+ spinner.stop();
283
+ error(err instanceof Error ? err.message : String(err));
284
+ process.exit(1);
285
+ }
286
+ });
287
+
288
+ // src/commands/status.ts
289
+ import { Command as Command2 } from "commander";
290
+ import ora2 from "ora";
291
+ import chalk2 from "chalk";
292
+ var statusCommand = new Command2("status").description("Show wallet status, balances, and policies").requiredOption("--wallet <address>", "Wallet address").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
293
+ const spinner = ora2("Fetching wallet status...").start();
294
+ try {
295
+ const walletAddress = validateAddress(options.wallet, "wallet");
296
+ const client = createSdkClient({
297
+ chain: options.chain,
298
+ rpcUrl: options.rpcUrl,
299
+ bundlerUrl: options.bundlerUrl
300
+ });
301
+ const balances = await client.getBalances(walletAddress);
302
+ spinner.stop();
303
+ console.log();
304
+ console.log(chalk2.bold("Wallet Status"));
305
+ console.log();
306
+ printKeyValue([
307
+ ["Address", walletAddress],
308
+ ["ETH Balance", formatBalance(balances.eth)]
309
+ ]);
310
+ try {
311
+ const paused = await client.isPaused(walletAddress);
312
+ console.log();
313
+ printKeyValue([
314
+ ["Paused", paused ? chalk2.red("Yes") : chalk2.green("No")]
315
+ ]);
316
+ } catch {
317
+ }
318
+ const sessions = client.getActiveSessions(walletAddress);
319
+ if (sessions.length > 0) {
320
+ console.log();
321
+ console.log(chalk2.bold(`Active Sessions (${sessions.length})`));
322
+ for (const s of sessions) {
323
+ const expiresIn = s.expiresAt - Math.floor(Date.now() / 1e3);
324
+ const expiresStr = expiresIn > 0 ? `${Math.floor(expiresIn / 3600)}h ${Math.floor(expiresIn % 3600 / 60)}m` : chalk2.red("Expired");
325
+ printKeyValue([
326
+ [" Session Key", s.sessionKey],
327
+ [" Expires In", expiresStr]
328
+ ]);
329
+ }
330
+ }
331
+ } catch (err) {
332
+ spinner.stop();
333
+ error(err instanceof Error ? err.message : String(err));
334
+ process.exit(1);
335
+ }
336
+ });
337
+
338
+ // src/commands/fund.ts
339
+ import { Command as Command3 } from "commander";
340
+ import chalk3 from "chalk";
341
+ init_chains();
342
+ var fundCommand = new Command3("fund").description("Show how to fund an agent wallet").requiredOption("--wallet <address>", "Wallet address").option("--chain <name>", "Target chain", "base-sepolia").action((options) => {
343
+ const chain = resolveChain(options.chain);
344
+ const walletAddress = validateAddress(options.wallet, "wallet");
345
+ console.log();
346
+ console.log(chalk3.bold("Fund Your Agent Wallet"));
347
+ console.log();
348
+ printKeyValue([
349
+ ["Wallet", walletAddress],
350
+ ["Chain", chain.name]
351
+ ]);
352
+ console.log();
353
+ const faucets = {
354
+ "Base Sepolia": "https://www.coinbase.com/faucets/base-sepolia",
355
+ "Sepolia": "https://sepoliafaucet.com",
356
+ "Optimism Sepolia": "https://www.alchemy.com/faucets/optimism-sepolia",
357
+ "Arbitrum Sepolia": "https://www.alchemy.com/faucets/arbitrum-sepolia"
358
+ };
359
+ const faucetUrl = faucets[chain.name];
360
+ if (faucetUrl) {
361
+ info(`Testnet faucet: ${chalk3.underline(faucetUrl)}`);
362
+ console.log();
363
+ }
364
+ info("Send ETH to the wallet address above to fund it.");
365
+ info("The wallet will be deployed on the first transaction (if not yet deployed).");
366
+ });
367
+
368
+ // src/commands/policy.ts
369
+ import { Command as Command4 } from "commander";
370
+ import chalk4 from "chalk";
371
+ var policyCommand = new Command4("policy").description("Manage policy modules (list/add/remove)");
372
+ policyCommand.command("list").description("List installed policies on a wallet").requiredOption("--wallet <address>", "Wallet address").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
373
+ try {
374
+ const walletAddress = validateAddress(options.wallet, "wallet");
375
+ const client = createSdkClient({
376
+ chain: options.chain,
377
+ rpcUrl: options.rpcUrl,
378
+ bundlerUrl: options.bundlerUrl
379
+ });
380
+ try {
381
+ const remaining = await client.getRemainingAllowance(
382
+ walletAddress,
383
+ "0x0000000000000000000000000000000000000000"
384
+ );
385
+ const table = createTable(["Policy", "Token", "Remaining"]);
386
+ table.push(["SpendingLimit", "ETH (native)", remaining.toString()]);
387
+ console.log();
388
+ console.log(chalk4.bold("Installed Policies"));
389
+ console.log(table.toString());
390
+ } catch {
391
+ info("No policies found or moduleAddresses not configured.");
392
+ info("Use `sak config set moduleAddresses.spendingLimitHook <address>` to configure.");
393
+ }
394
+ try {
395
+ const paused = await client.isPaused(walletAddress);
396
+ console.log();
397
+ info(`Emergency Pause: ${paused ? chalk4.red("PAUSED") : chalk4.green("Active")}`);
398
+ } catch {
399
+ }
400
+ } catch (err) {
401
+ error(err instanceof Error ? err.message : String(err));
402
+ process.exit(1);
403
+ }
404
+ });
405
+ policyCommand.command("add").description("Add a policy to an existing wallet (coming soon)").action(() => {
406
+ info("Policy addition via CLI is coming in a future release.");
407
+ info("Use the SDK directly: client.addPolicy(wallet, policy, ownerKey)");
408
+ });
409
+ policyCommand.command("remove").description("Remove a policy from a wallet (coming soon)").action(() => {
410
+ info("Policy removal via CLI is coming in a future release.");
411
+ info("Use the SDK directly: client.removePolicy(wallet, moduleAddress, ownerKey)");
412
+ });
413
+
414
+ // src/commands/pause.ts
415
+ import { Command as Command5 } from "commander";
416
+ import ora3 from "ora";
417
+ var pauseCommand = new Command5("pause").description("Emergency pause a wallet").requiredOption("--wallet <address>", "Wallet address").option("--guardian-key <hex>", "Guardian private key (or set SAK_GUARDIAN_KEY env var)").option("--guardian-mnemonic <phrase>", "Guardian mnemonic phrase (or set SAK_GUARDIAN_MNEMONIC env var)").option("--address-index <n>", "HD derivation index (default: 0)", "0").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
418
+ const spinner = ora3("Pausing wallet...").start();
419
+ try {
420
+ const walletAddress = validateAddress(options.wallet, "wallet");
421
+ const guardianKey = resolveSignerKey(
422
+ options.guardianKey,
423
+ options.guardianMnemonic,
424
+ "SAK_GUARDIAN_KEY",
425
+ "SAK_GUARDIAN_MNEMONIC",
426
+ "guardian",
427
+ parseInt(options.addressIndex, 10)
428
+ );
429
+ const client = createSdkClient({
430
+ chain: options.chain,
431
+ rpcUrl: options.rpcUrl,
432
+ bundlerUrl: options.bundlerUrl
433
+ });
434
+ const txHash = await client.pause(
435
+ walletAddress,
436
+ guardianKey
437
+ );
438
+ spinner.stop();
439
+ success("Wallet paused!");
440
+ printKeyValue([
441
+ ["Wallet", walletAddress],
442
+ ["Tx Hash", txHash]
443
+ ]);
444
+ } catch (err) {
445
+ spinner.stop();
446
+ error(err instanceof Error ? err.message : String(err));
447
+ process.exit(1);
448
+ }
449
+ });
450
+ var unpauseCommand = new Command5("unpause").description("Unpause a wallet").requiredOption("--wallet <address>", "Wallet address").option("--guardian-key <hex>", "Guardian private key (or set SAK_GUARDIAN_KEY env var)").option("--guardian-mnemonic <phrase>", "Guardian mnemonic phrase (or set SAK_GUARDIAN_MNEMONIC env var)").option("--address-index <n>", "HD derivation index (default: 0)", "0").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
451
+ const spinner = ora3("Unpausing wallet...").start();
452
+ try {
453
+ const walletAddress = validateAddress(options.wallet, "wallet");
454
+ const guardianKey = resolveSignerKey(
455
+ options.guardianKey,
456
+ options.guardianMnemonic,
457
+ "SAK_GUARDIAN_KEY",
458
+ "SAK_GUARDIAN_MNEMONIC",
459
+ "guardian",
460
+ parseInt(options.addressIndex, 10)
461
+ );
462
+ const client = createSdkClient({
463
+ chain: options.chain,
464
+ rpcUrl: options.rpcUrl,
465
+ bundlerUrl: options.bundlerUrl
466
+ });
467
+ const txHash = await client.unpause(
468
+ walletAddress,
469
+ guardianKey
470
+ );
471
+ spinner.stop();
472
+ success("Wallet unpaused!");
473
+ printKeyValue([
474
+ ["Wallet", walletAddress],
475
+ ["Tx Hash", txHash]
476
+ ]);
477
+ } catch (err) {
478
+ spinner.stop();
479
+ error(err instanceof Error ? err.message : String(err));
480
+ process.exit(1);
481
+ }
482
+ });
483
+
484
+ // src/commands/session.ts
485
+ import { Command as Command6 } from "commander";
486
+ import ora4 from "ora";
487
+ import chalk5 from "chalk";
488
+ var sessionCommand = new Command6("session").description("Manage session keys (create/revoke/list)");
489
+ sessionCommand.command("create").description("Create a new session key for an agent").requiredOption("--wallet <address>", "Wallet address").option("--owner-key <hex>", "Owner private key (or set SAK_OWNER_KEY env var)").option("--owner-mnemonic <phrase>", "Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)").option("--address-index <n>", "HD derivation index (default: 0)", "0").requiredOption("--target <address>", "Target contract address").requiredOption("--selector <hex>", "Allowed function selector (e.g., 0xa9059cbb)").option("--expires <seconds>", "Session duration in seconds", "3600").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
490
+ const spinner = ora4("Creating session key...").start();
491
+ try {
492
+ const walletAddress = validateAddress(options.wallet, "wallet");
493
+ const targetAddress = validateAddress(options.target, "target");
494
+ const ownerKey = resolveSignerKey(
495
+ options.ownerKey,
496
+ options.ownerMnemonic,
497
+ "SAK_OWNER_KEY",
498
+ "SAK_OWNER_MNEMONIC",
499
+ "owner",
500
+ parseInt(options.addressIndex, 10)
501
+ );
502
+ const client = createSdkClient({
503
+ chain: options.chain,
504
+ rpcUrl: options.rpcUrl,
505
+ bundlerUrl: options.bundlerUrl
506
+ });
507
+ await client.connectWallet(walletAddress, ownerKey);
508
+ const expiresAt = Math.floor(Date.now() / 1e3) + parseInt(options.expires, 10);
509
+ const result = await client.createSession(
510
+ {
511
+ address: walletAddress,
512
+ owner: walletAddress,
513
+ // Will be resolved from connected wallet
514
+ chain: (await Promise.resolve().then(() => (init_chains(), chains_exports))).resolveChain(
515
+ options.chain ?? "base-sepolia"
516
+ ),
517
+ isDeployed: true,
518
+ policies: [],
519
+ sessions: []
520
+ },
521
+ {
522
+ sessionKey: "0x0000000000000000000000000000000000000000",
523
+ // Will be generated
524
+ actions: [
525
+ {
526
+ target: targetAddress,
527
+ selector: validateSelector(options.selector, "function")
528
+ }
529
+ ],
530
+ expiresAt
531
+ },
532
+ ownerKey
533
+ );
534
+ spinner.stop();
535
+ success("Session key created!");
536
+ console.log();
537
+ console.log(
538
+ chalk5.yellow(
539
+ " WARNING: The private key below grants transaction signing access."
540
+ )
541
+ );
542
+ console.log(
543
+ chalk5.yellow(
544
+ " Store it securely and never share it publicly."
545
+ )
546
+ );
547
+ console.log();
548
+ printKeyValue([
549
+ ["Session Key", result.sessionKey],
550
+ ["Private Key", result.privateKey],
551
+ ["Permission ID", result.permissionId],
552
+ [
553
+ "Expires",
554
+ new Date(expiresAt * 1e3).toISOString()
555
+ ]
556
+ ]);
557
+ console.log();
558
+ info(
559
+ "Save the private key securely \u2014 the agent needs it to sign transactions."
560
+ );
561
+ } catch (err) {
562
+ spinner.stop();
563
+ error(err instanceof Error ? err.message : String(err));
564
+ process.exit(1);
565
+ }
566
+ });
567
+ sessionCommand.command("list").description("List active sessions for a wallet").requiredOption("--wallet <address>", "Wallet address").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
568
+ try {
569
+ const walletAddress = validateAddress(options.wallet, "wallet");
570
+ const client = createSdkClient({
571
+ chain: options.chain,
572
+ rpcUrl: options.rpcUrl,
573
+ bundlerUrl: options.bundlerUrl
574
+ });
575
+ const sessions = client.getActiveSessions(walletAddress);
576
+ if (sessions.length === 0) {
577
+ info("No active sessions found for this wallet.");
578
+ info(
579
+ chalk5.gray(
580
+ "Note: Session data is stored in-memory only and does not persist across CLI invocations."
581
+ )
582
+ );
583
+ return;
584
+ }
585
+ const table = createTable([
586
+ "Session Key",
587
+ "Expires",
588
+ "Actions"
589
+ ]);
590
+ for (const s of sessions) {
591
+ const expiresIn = s.expiresAt - Math.floor(Date.now() / 1e3);
592
+ const expiresStr = expiresIn > 0 ? `${Math.floor(expiresIn / 3600)}h ${Math.floor(expiresIn % 3600 / 60)}m` : chalk5.red("Expired");
593
+ table.push([
594
+ `${s.sessionKey.slice(0, 10)}...`,
595
+ expiresStr,
596
+ s.actions.length.toString()
597
+ ]);
598
+ }
599
+ console.log();
600
+ console.log(chalk5.bold(`Sessions for ${walletAddress}`));
601
+ console.log(table.toString());
602
+ console.log();
603
+ info(
604
+ chalk5.gray(
605
+ "Note: Session data is stored in-memory only and does not persist across CLI invocations."
606
+ )
607
+ );
608
+ } catch (err) {
609
+ error(err instanceof Error ? err.message : String(err));
610
+ process.exit(1);
611
+ }
612
+ });
613
+ sessionCommand.command("revoke").description("Revoke a session key").requiredOption("--wallet <address>", "Wallet address").requiredOption("--permission-id <hex>", "Permission ID to revoke").option("--owner-key <hex>", "Owner private key (or set SAK_OWNER_KEY env var)").option("--owner-mnemonic <phrase>", "Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)").option("--address-index <n>", "HD derivation index (default: 0)", "0").option("--chain <name>", "Target chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action(async (options) => {
614
+ const spinner = ora4("Revoking session...").start();
615
+ try {
616
+ const walletAddress = validateAddress(options.wallet, "wallet");
617
+ const ownerKey = resolveSignerKey(
618
+ options.ownerKey,
619
+ options.ownerMnemonic,
620
+ "SAK_OWNER_KEY",
621
+ "SAK_OWNER_MNEMONIC",
622
+ "owner",
623
+ parseInt(options.addressIndex, 10)
624
+ );
625
+ const client = createSdkClient({
626
+ chain: options.chain,
627
+ rpcUrl: options.rpcUrl,
628
+ bundlerUrl: options.bundlerUrl
629
+ });
630
+ await client.connectWallet(walletAddress, ownerKey);
631
+ await client.revokeSession(
632
+ {
633
+ address: walletAddress,
634
+ owner: walletAddress,
635
+ chain: (await Promise.resolve().then(() => (init_chains(), chains_exports))).resolveChain(
636
+ options.chain ?? "base-sepolia"
637
+ ),
638
+ isDeployed: true,
639
+ policies: [],
640
+ sessions: []
641
+ },
642
+ validateHex(options.permissionId, "permission ID"),
643
+ ownerKey
644
+ );
645
+ spinner.stop();
646
+ success("Session revoked!");
647
+ printKeyValue([
648
+ ["Permission ID", options.permissionId]
649
+ ]);
650
+ } catch (err) {
651
+ spinner.stop();
652
+ error(err instanceof Error ? err.message : String(err));
653
+ process.exit(1);
654
+ }
655
+ });
656
+
657
+ // src/commands/config.ts
658
+ import { Command as Command7 } from "commander";
659
+ import chalk6 from "chalk";
660
+ init_chains();
661
+ var configCommand = new Command7("config").description("Manage CLI configuration");
662
+ configCommand.command("show").description("Show current configuration").action(() => {
663
+ const config = loadConfig();
664
+ console.log();
665
+ console.log(chalk6.bold("Configuration"));
666
+ console.log(chalk6.gray(` File: ${getConfigPath()}`));
667
+ console.log();
668
+ console.log(JSON.stringify(config, null, 2));
669
+ });
670
+ configCommand.command("set").description("Set a configuration value").argument("<key>", "Config key (e.g., rpcUrl, defaultChain)").argument("<value>", "Config value").action((key, value) => {
671
+ if (key.includes(".")) {
672
+ const parts = key.split(".");
673
+ const config = loadConfig();
674
+ let obj = config;
675
+ for (let i = 0; i < parts.length - 1; i++) {
676
+ if (!obj[parts[i]] || typeof obj[parts[i]] !== "object") {
677
+ obj[parts[i]] = {};
678
+ }
679
+ obj = obj[parts[i]];
680
+ }
681
+ obj[parts[parts.length - 1]] = value;
682
+ saveConfig(config);
683
+ } else {
684
+ setConfigValue(key, value);
685
+ }
686
+ success(`Set ${key} = ${value}`);
687
+ });
688
+ configCommand.command("delete").description("Delete a configuration value").argument("<key>", "Config key to delete (supports dot-notation, e.g. moduleAddresses.spendingLimitHook)").action((key) => {
689
+ if (key.includes(".")) {
690
+ const parts = key.split(".");
691
+ const config = loadConfig();
692
+ let obj = config;
693
+ for (let i = 0; i < parts.length - 1; i++) {
694
+ if (!obj[parts[i]] || typeof obj[parts[i]] !== "object") {
695
+ success(`Deleted ${key}`);
696
+ return;
697
+ }
698
+ obj = obj[parts[i]];
699
+ }
700
+ delete obj[parts[parts.length - 1]];
701
+ saveConfig(config);
702
+ } else {
703
+ deleteConfigValue(key);
704
+ }
705
+ success(`Deleted ${key}`);
706
+ });
707
+ configCommand.command("chains").description("List supported chain names").action(() => {
708
+ console.log();
709
+ console.log(chalk6.bold("Supported Chains"));
710
+ console.log();
711
+ for (const name of listChains()) {
712
+ console.log(` ${chalk6.cyan(name)}`);
713
+ }
714
+ });
715
+ configCommand.command("init").description("Initialize configuration interactively").option("--chain <name>", "Default chain", "base-sepolia").option("--rpc-url <url>", "RPC URL").option("--bundler-url <url>", "Bundler URL").action((options) => {
716
+ const config = loadConfig();
717
+ if (options.chain) config.defaultChain = options.chain;
718
+ if (options.rpcUrl) config.rpcUrl = options.rpcUrl;
719
+ if (options.bundlerUrl) config.bundlerUrl = options.bundlerUrl;
720
+ saveConfig(config);
721
+ success("Configuration saved!");
722
+ console.log();
723
+ printKeyValue([
724
+ ["Config file", getConfigPath()],
725
+ ["Default chain", config.defaultChain],
726
+ ["RPC URL", config.rpcUrl ?? "(not set)"],
727
+ ["Bundler URL", config.bundlerUrl ?? "(not set)"]
728
+ ]);
729
+ });
730
+
731
+ // src/index.ts
732
+ var program = new Command8();
733
+ program.name("smartagentkit").description(
734
+ "CLI tool for managing policy-governed AI agent smart wallets"
735
+ ).version(process.env.npm_package_version ?? "0.1.0");
736
+ program.addCommand(createCommand);
737
+ program.addCommand(statusCommand);
738
+ program.addCommand(fundCommand);
739
+ program.addCommand(policyCommand);
740
+ program.addCommand(pauseCommand);
741
+ program.addCommand(unpauseCommand);
742
+ program.addCommand(sessionCommand);
743
+ program.addCommand(configCommand);
744
+ program.parse();
745
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/utils/chains.ts","../src/index.ts","../src/commands/create.ts","../src/utils/client.ts","../src/utils/config.ts","../src/utils/display.ts","../src/utils/validation.ts","../src/commands/status.ts","../src/commands/fund.ts","../src/commands/policy.ts","../src/commands/pause.ts","../src/commands/session.ts","../src/commands/config.ts"],"sourcesContent":["import type { Chain } from \"viem\";\nimport {\n mainnet,\n sepolia,\n base,\n baseSepolia,\n optimism,\n optimismSepolia,\n arbitrum,\n arbitrumSepolia,\n polygon,\n polygonAmoy,\n} from \"viem/chains\";\n\nconst CHAIN_MAP: Record<string, Chain> = {\n \"mainnet\": mainnet,\n \"ethereum\": mainnet,\n \"sepolia\": sepolia,\n \"base\": base,\n \"base-sepolia\": baseSepolia,\n \"optimism\": optimism,\n \"optimism-sepolia\": optimismSepolia,\n \"arbitrum\": arbitrum,\n \"arbitrum-sepolia\": arbitrumSepolia,\n \"polygon\": polygon,\n \"polygon-amoy\": polygonAmoy,\n};\n\nexport function resolveChain(name: string): Chain {\n const chain = CHAIN_MAP[name.toLowerCase()];\n if (!chain) {\n const supported = Object.keys(CHAIN_MAP).join(\", \");\n throw new Error(\n `Unknown chain \"${name}\". Supported: ${supported}`,\n );\n }\n return chain;\n}\n\nexport function listChains(): string[] {\n return Object.keys(CHAIN_MAP);\n}\n","import { Command } from \"commander\";\nimport { createCommand } from \"./commands/create.js\";\nimport { statusCommand } from \"./commands/status.js\";\nimport { fundCommand } from \"./commands/fund.js\";\nimport { policyCommand } from \"./commands/policy.js\";\nimport { pauseCommand, unpauseCommand } from \"./commands/pause.js\";\nimport { sessionCommand } from \"./commands/session.js\";\nimport { configCommand } from \"./commands/config.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"smartagentkit\")\n .description(\n \"CLI tool for managing policy-governed AI agent smart wallets\",\n )\n .version(process.env.npm_package_version ?? \"0.1.0\");\n\nprogram.addCommand(createCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(fundCommand);\nprogram.addCommand(policyCommand);\nprogram.addCommand(pauseCommand);\nprogram.addCommand(unpauseCommand);\nprogram.addCommand(sessionCommand);\nprogram.addCommand(configCommand);\n\nprogram.parse();\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport type { Address } from \"viem\";\nimport type { PresetName } from \"@smartagentkit/sdk\";\nimport { createSdkClient } from \"../utils/client.js\";\nimport { success, error, printKeyValue } from \"../utils/display.js\";\nimport { validateAddress, resolveSignerKey } from \"../utils/validation.js\";\n\nexport const createCommand = new Command(\"create\")\n .description(\"Create a new agent wallet\")\n .requiredOption(\"--owner <address>\", \"Owner address\")\n .option(\"--owner-key <hex>\", \"Owner private key (or set SAK_OWNER_KEY env var)\")\n .option(\"--owner-mnemonic <phrase>\", \"Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)\")\n .option(\"--address-index <n>\", \"HD derivation index (default: 0)\", \"0\")\n .option(\"--preset <name>\", \"Policy preset (minimal, defi-trader, treasury-agent, payment-agent)\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .option(\"--salt <number>\", \"CREATE2 salt for deterministic address\")\n .action(async (options) => {\n const spinner = ora(\"Creating agent wallet...\").start();\n\n try {\n const ownerAddress = validateAddress(options.owner, \"owner\");\n const ownerKey = resolveSignerKey(\n options.ownerKey,\n options.ownerMnemonic,\n \"SAK_OWNER_KEY\",\n \"SAK_OWNER_MNEMONIC\",\n \"owner\",\n parseInt(options.addressIndex, 10),\n );\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n // Build wallet params with either private key or mnemonic\n const walletParams: Parameters<typeof client.createWallet>[0] = {\n owner: ownerAddress,\n preset: options.preset as PresetName | undefined,\n salt: options.salt ? BigInt(options.salt) : undefined,\n };\n if (typeof ownerKey === \"string\") {\n walletParams.ownerPrivateKey = ownerKey;\n } else {\n walletParams.ownerMnemonic = ownerKey.mnemonic;\n walletParams.addressIndex = ownerKey.addressIndex;\n }\n\n const wallet = await client.createWallet(walletParams);\n\n spinner.stop();\n success(\"Agent wallet created!\");\n console.log();\n printKeyValue([\n [\"Address\", wallet.address],\n [\"Owner\", wallet.owner],\n [\"Chain\", wallet.chain.name],\n [\"Deployed\", wallet.isDeployed ? \"Yes\" : \"No (deploy on first tx)\"],\n [\"Policies\", wallet.policies.length.toString()],\n ]);\n\n if (wallet.policies.length > 0) {\n console.log();\n console.log(\" Installed policies:\");\n for (const p of wallet.policies) {\n console.log(` - ${p.name} (${p.moduleAddress})`);\n }\n }\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { SmartAgentKitClient } from \"@smartagentkit/sdk\";\nimport type { Address } from \"viem\";\nimport type { Chain } from \"viem\";\nimport { loadConfig } from \"./config.js\";\nimport { resolveChain } from \"./chains.js\";\n\nexport interface ClientOptions {\n chain?: string;\n rpcUrl?: string;\n bundlerUrl?: string;\n}\n\nexport function createSdkClient(options: ClientOptions): SmartAgentKitClient {\n const config = loadConfig();\n const chainName = options.chain ?? config.defaultChain ?? \"base-sepolia\";\n const chain = resolveChain(chainName);\n\n const rpcUrl = options.rpcUrl ?? config.rpcUrl;\n if (!rpcUrl) {\n throw new Error(\n \"RPC URL required. Set via --rpc-url flag or `sak config set rpcUrl <url>`\",\n );\n }\n\n const bundlerUrl = options.bundlerUrl ?? config.bundlerUrl;\n if (!bundlerUrl) {\n throw new Error(\n \"Bundler URL required. Set via --bundler-url flag or `sak config set bundlerUrl <url>`\",\n );\n }\n\n const moduleAddresses = config.moduleAddresses\n ? {\n spendingLimitHook: (config.moduleAddresses.spendingLimitHook ??\n \"0x0000000000000000000000000000000000000000\") as Address,\n allowlistHook: (config.moduleAddresses.allowlistHook ??\n \"0x0000000000000000000000000000000000000000\") as Address,\n emergencyPauseHook: (config.moduleAddresses.emergencyPauseHook ??\n \"0x0000000000000000000000000000000000000000\") as Address,\n }\n : undefined;\n\n return new SmartAgentKitClient({\n chain,\n rpcUrl,\n bundlerUrl,\n paymasterUrl: config.paymasterUrl,\n moduleAddresses,\n });\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nexport interface CliConfig {\n defaultChain: string;\n rpcUrl?: string;\n bundlerUrl?: string;\n paymasterUrl?: string;\n moduleAddresses?: {\n spendingLimitHook?: string;\n allowlistHook?: string;\n emergencyPauseHook?: string;\n automationExecutor?: string;\n };\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), \".smartagentkit\");\nconst CONFIG_FILE = path.join(CONFIG_DIR, \"config.json\");\n\nconst DEFAULT_CONFIG: CliConfig = {\n defaultChain: \"base-sepolia\",\n};\n\nexport function getConfigDir(): string {\n return CONFIG_DIR;\n}\n\nexport function getConfigPath(): string {\n return CONFIG_FILE;\n}\n\nexport function loadConfig(): CliConfig {\n try {\n if (!fs.existsSync(CONFIG_FILE)) {\n return { ...DEFAULT_CONFIG };\n }\n const raw = fs.readFileSync(CONFIG_FILE, \"utf-8\");\n return { ...DEFAULT_CONFIG, ...JSON.parse(raw) };\n } catch {\n return { ...DEFAULT_CONFIG };\n }\n}\n\nexport function saveConfig(config: CliConfig): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2) + \"\\n\", {\n mode: 0o600,\n });\n}\n\nexport function getConfigValue(key: string): string | undefined {\n const config = loadConfig();\n return (config as unknown as Record<string, unknown>)[key] as string | undefined;\n}\n\nexport function setConfigValue(key: string, value: string): void {\n const config = loadConfig();\n (config as unknown as Record<string, unknown>)[key] = value;\n saveConfig(config);\n}\n\nexport function deleteConfigValue(key: string): void {\n const config = loadConfig();\n delete (config as unknown as Record<string, unknown>)[key];\n saveConfig(config);\n}\n","import chalk from \"chalk\";\nimport Table from \"cli-table3\";\nimport { formatEther } from \"viem\";\n\nexport function formatAddress(address: string): string {\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\nexport function formatBalance(wei: bigint): string {\n return `${formatEther(wei)} ETH`;\n}\n\nexport function success(message: string): void {\n console.log(chalk.green(`\\u2713 ${message}`));\n}\n\nexport function error(message: string): void {\n console.error(chalk.red(`\\u2717 ${message}`));\n}\n\nexport function warn(message: string): void {\n console.log(chalk.yellow(`! ${message}`));\n}\n\nexport function info(message: string): void {\n console.log(chalk.blue(`i ${message}`));\n}\n\nexport function createTable(head: string[]): Table.Table {\n return new Table({\n head: head.map((h) => chalk.cyan(h)),\n style: { head: [], border: [] },\n });\n}\n\nexport function printKeyValue(pairs: [string, string][]): void {\n const maxKeyLen = Math.max(...pairs.map(([k]) => k.length));\n for (const [key, value] of pairs) {\n console.log(` ${chalk.gray(key.padEnd(maxKeyLen))} ${value}`);\n }\n}\n","import { isAddress, isHex } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport type { SignerKey } from \"@smartagentkit/sdk\";\n\n/**\n * Validate and return a checksummed Ethereum address.\n * Throws a descriptive error if the input is not a valid address.\n */\nexport function validateAddress(input: string, label: string): Address {\n if (!isAddress(input)) {\n throw new Error(\n `Invalid ${label} address: \"${input}\". Expected a 0x-prefixed 20-byte hex string.`,\n );\n }\n return input as Address;\n}\n\n/**\n * Validate a hex-encoded private key (64 hex chars after 0x prefix).\n */\nexport function validatePrivateKey(input: string, label: string): Hex {\n if (!/^0x[0-9a-fA-F]{64}$/.test(input)) {\n throw new Error(\n `Invalid ${label} private key. Expected a 0x-prefixed 32-byte hex string.`,\n );\n }\n return input as Hex;\n}\n\n/**\n * Validate a BIP-39 mnemonic phrase (12 or 24 space-separated words).\n */\nexport function validateMnemonic(input: string, label: string): string {\n const words = input.trim().split(/\\s+/);\n if (words.length !== 12 && words.length !== 24) {\n throw new Error(\n `Invalid ${label} mnemonic. Expected 12 or 24 space-separated words.`,\n );\n }\n return input.trim();\n}\n\n/**\n * Resolve a private key from either CLI option or environment variable.\n * @param cliValue - Value from CLI option (may be undefined)\n * @param envVar - Environment variable name to fall back to\n * @param label - Label for error messages (e.g., \"owner\")\n * @returns The validated private key\n */\nexport function resolvePrivateKey(\n cliValue: string | undefined,\n envVar: string,\n label: string,\n): Hex {\n const raw = cliValue ?? process.env[envVar];\n if (!raw) {\n throw new Error(\n `No ${label} private key provided. Use --${label}-key <hex> or set ${envVar} environment variable.`,\n );\n }\n return validatePrivateKey(raw, label);\n}\n\n/**\n * Resolve a signer credential from CLI options and environment variables.\n * Accepts either a private key or a mnemonic phrase.\n *\n * @param keyValue - Private key from CLI option (may be undefined)\n * @param mnemonicValue - Mnemonic from CLI option (may be undefined)\n * @param keyEnvVar - Env var for private key (e.g., \"SAK_OWNER_KEY\")\n * @param mnemonicEnvVar - Env var for mnemonic (e.g., \"SAK_OWNER_MNEMONIC\")\n * @param label - Label for error messages (e.g., \"owner\")\n * @param addressIndex - HD derivation index (default: 0)\n * @returns A SignerKey (Hex or MnemonicCredential)\n */\nexport function resolveSignerKey(\n keyValue: string | undefined,\n mnemonicValue: string | undefined,\n keyEnvVar: string,\n mnemonicEnvVar: string,\n label: string,\n addressIndex?: number,\n): SignerKey {\n const rawKey = keyValue ?? process.env[keyEnvVar];\n const rawMnemonic = mnemonicValue ?? process.env[mnemonicEnvVar];\n\n if (rawKey) {\n return validatePrivateKey(rawKey, label);\n }\n\n if (rawMnemonic) {\n const mnemonic = validateMnemonic(rawMnemonic, label);\n return { mnemonic, addressIndex: addressIndex ?? 0 };\n }\n\n throw new Error(\n `No ${label} credential provided. Use --${label}-key <hex>, --${label}-mnemonic <phrase>, ` +\n `or set ${keyEnvVar} / ${mnemonicEnvVar} environment variable.`,\n );\n}\n\n/**\n * Validate a 4-byte function selector (0x + 8 hex chars).\n */\nexport function validateSelector(input: string, label: string): Hex {\n if (!/^0x[0-9a-fA-F]{8}$/.test(input)) {\n throw new Error(\n `Invalid ${label} selector: \"${input}\". Expected a 0x-prefixed 4-byte hex string (e.g., 0xa9059cbb).`,\n );\n }\n return input as Hex;\n}\n\n/**\n * Validate a generic hex string (0x-prefixed, even length).\n */\nexport function validateHex(input: string, label: string): Hex {\n if (!isHex(input)) {\n throw new Error(\n `Invalid ${label}: \"${input}\". Expected a 0x-prefixed hex string.`,\n );\n }\n return input as Hex;\n}\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport { createSdkClient } from \"../utils/client.js\";\nimport {\n success,\n error,\n printKeyValue,\n formatBalance,\n} from \"../utils/display.js\";\nimport { validateAddress } from \"../utils/validation.js\";\n\nexport const statusCommand = new Command(\"status\")\n .description(\"Show wallet status, balances, and policies\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n const spinner = ora(\"Fetching wallet status...\").start();\n\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n const balances = await client.getBalances(walletAddress);\n\n spinner.stop();\n console.log();\n console.log(chalk.bold(\"Wallet Status\"));\n console.log();\n printKeyValue([\n [\"Address\", walletAddress],\n [\"ETH Balance\", formatBalance(balances.eth)],\n ]);\n\n // Check pause status if module addresses configured\n try {\n const paused = await client.isPaused(walletAddress);\n console.log();\n printKeyValue([\n [\"Paused\", paused ? chalk.red(\"Yes\") : chalk.green(\"No\")],\n ]);\n } catch {\n // moduleAddresses not configured, skip pause check\n }\n\n // Show active sessions\n const sessions = client.getActiveSessions(walletAddress);\n if (sessions.length > 0) {\n console.log();\n console.log(chalk.bold(`Active Sessions (${sessions.length})`));\n for (const s of sessions) {\n const expiresIn = s.expiresAt - Math.floor(Date.now() / 1000);\n const expiresStr =\n expiresIn > 0\n ? `${Math.floor(expiresIn / 3600)}h ${Math.floor((expiresIn % 3600) / 60)}m`\n : chalk.red(\"Expired\");\n printKeyValue([\n [\" Session Key\", s.sessionKey],\n [\" Expires In\", expiresStr],\n ]);\n }\n }\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { info, printKeyValue } from \"../utils/display.js\";\nimport { resolveChain } from \"../utils/chains.js\";\nimport { validateAddress } from \"../utils/validation.js\";\n\nexport const fundCommand = new Command(\"fund\")\n .description(\"Show how to fund an agent wallet\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .action((options) => {\n const chain = resolveChain(options.chain);\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n\n console.log();\n console.log(chalk.bold(\"Fund Your Agent Wallet\"));\n console.log();\n printKeyValue([\n [\"Wallet\", walletAddress],\n [\"Chain\", chain.name],\n ]);\n console.log();\n\n // Show faucet links for testnets\n const faucets: Record<string, string> = {\n \"Base Sepolia\": \"https://www.coinbase.com/faucets/base-sepolia\",\n \"Sepolia\": \"https://sepoliafaucet.com\",\n \"Optimism Sepolia\": \"https://www.alchemy.com/faucets/optimism-sepolia\",\n \"Arbitrum Sepolia\": \"https://www.alchemy.com/faucets/arbitrum-sepolia\",\n };\n\n const faucetUrl = faucets[chain.name];\n if (faucetUrl) {\n info(`Testnet faucet: ${chalk.underline(faucetUrl)}`);\n console.log();\n }\n\n info(\"Send ETH to the wallet address above to fund it.\");\n info(\"The wallet will be deployed on the first transaction (if not yet deployed).\");\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport type { Address } from \"viem\";\nimport { createSdkClient } from \"../utils/client.js\";\nimport {\n success,\n error,\n info,\n createTable,\n} from \"../utils/display.js\";\nimport { validateAddress } from \"../utils/validation.js\";\n\nexport const policyCommand = new Command(\"policy\")\n .description(\"Manage policy modules (list/add/remove)\");\n\npolicyCommand\n .command(\"list\")\n .description(\"List installed policies on a wallet\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n // Check spending limit remaining\n try {\n const remaining = await client.getRemainingAllowance(\n walletAddress,\n \"0x0000000000000000000000000000000000000000\" as Address,\n );\n const table = createTable([\"Policy\", \"Token\", \"Remaining\"]);\n table.push([\"SpendingLimit\", \"ETH (native)\", remaining.toString()]);\n console.log();\n console.log(chalk.bold(\"Installed Policies\"));\n console.log(table.toString());\n } catch {\n info(\"No policies found or moduleAddresses not configured.\");\n info(\"Use `sak config set moduleAddresses.spendingLimitHook <address>` to configure.\");\n }\n\n // Check pause status\n try {\n const paused = await client.isPaused(walletAddress);\n console.log();\n info(`Emergency Pause: ${paused ? chalk.red(\"PAUSED\") : chalk.green(\"Active\")}`);\n } catch {\n // No pause hook configured\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\npolicyCommand\n .command(\"add\")\n .description(\"Add a policy to an existing wallet (coming soon)\")\n .action(() => {\n info(\"Policy addition via CLI is coming in a future release.\");\n info(\"Use the SDK directly: client.addPolicy(wallet, policy, ownerKey)\");\n });\n\npolicyCommand\n .command(\"remove\")\n .description(\"Remove a policy from a wallet (coming soon)\")\n .action(() => {\n info(\"Policy removal via CLI is coming in a future release.\");\n info(\"Use the SDK directly: client.removePolicy(wallet, moduleAddress, ownerKey)\");\n });\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport { createSdkClient } from \"../utils/client.js\";\nimport { success, error, printKeyValue } from \"../utils/display.js\";\nimport { validateAddress, resolveSignerKey } from \"../utils/validation.js\";\n\nexport const pauseCommand = new Command(\"pause\")\n .description(\"Emergency pause a wallet\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--guardian-key <hex>\", \"Guardian private key (or set SAK_GUARDIAN_KEY env var)\")\n .option(\"--guardian-mnemonic <phrase>\", \"Guardian mnemonic phrase (or set SAK_GUARDIAN_MNEMONIC env var)\")\n .option(\"--address-index <n>\", \"HD derivation index (default: 0)\", \"0\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n const spinner = ora(\"Pausing wallet...\").start();\n\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n const guardianKey = resolveSignerKey(\n options.guardianKey,\n options.guardianMnemonic,\n \"SAK_GUARDIAN_KEY\",\n \"SAK_GUARDIAN_MNEMONIC\",\n \"guardian\",\n parseInt(options.addressIndex, 10),\n );\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n const txHash = await client.pause(\n walletAddress,\n guardianKey,\n );\n\n spinner.stop();\n success(\"Wallet paused!\");\n printKeyValue([\n [\"Wallet\", walletAddress],\n [\"Tx Hash\", txHash],\n ]);\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nexport const unpauseCommand = new Command(\"unpause\")\n .description(\"Unpause a wallet\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--guardian-key <hex>\", \"Guardian private key (or set SAK_GUARDIAN_KEY env var)\")\n .option(\"--guardian-mnemonic <phrase>\", \"Guardian mnemonic phrase (or set SAK_GUARDIAN_MNEMONIC env var)\")\n .option(\"--address-index <n>\", \"HD derivation index (default: 0)\", \"0\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n const spinner = ora(\"Unpausing wallet...\").start();\n\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n const guardianKey = resolveSignerKey(\n options.guardianKey,\n options.guardianMnemonic,\n \"SAK_GUARDIAN_KEY\",\n \"SAK_GUARDIAN_MNEMONIC\",\n \"guardian\",\n parseInt(options.addressIndex, 10),\n );\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n const txHash = await client.unpause(\n walletAddress,\n guardianKey,\n );\n\n spinner.stop();\n success(\"Wallet unpaused!\");\n printKeyValue([\n [\"Wallet\", walletAddress],\n [\"Tx Hash\", txHash],\n ]);\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport ora from \"ora\";\nimport chalk from \"chalk\";\nimport type { Address, Hex } from \"viem\";\nimport { createSdkClient } from \"../utils/client.js\";\nimport {\n success,\n error,\n info,\n printKeyValue,\n createTable,\n} from \"../utils/display.js\";\nimport { validateAddress, resolveSignerKey, validateSelector, validateHex } from \"../utils/validation.js\";\n\nexport const sessionCommand = new Command(\"session\")\n .description(\"Manage session keys (create/revoke/list)\");\n\nsessionCommand\n .command(\"create\")\n .description(\"Create a new session key for an agent\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--owner-key <hex>\", \"Owner private key (or set SAK_OWNER_KEY env var)\")\n .option(\"--owner-mnemonic <phrase>\", \"Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)\")\n .option(\"--address-index <n>\", \"HD derivation index (default: 0)\", \"0\")\n .requiredOption(\"--target <address>\", \"Target contract address\")\n .requiredOption(\"--selector <hex>\", \"Allowed function selector (e.g., 0xa9059cbb)\")\n .option(\"--expires <seconds>\", \"Session duration in seconds\", \"3600\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n const spinner = ora(\"Creating session key...\").start();\n\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n const targetAddress = validateAddress(options.target, \"target\");\n const ownerKey = resolveSignerKey(\n options.ownerKey,\n options.ownerMnemonic,\n \"SAK_OWNER_KEY\",\n \"SAK_OWNER_MNEMONIC\",\n \"owner\",\n parseInt(options.addressIndex, 10),\n );\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n // Connect to the wallet first\n await client.connectWallet(walletAddress, ownerKey);\n\n const expiresAt =\n Math.floor(Date.now() / 1000) + parseInt(options.expires, 10);\n\n const result = await client.createSession(\n {\n address: walletAddress,\n owner: walletAddress, // Will be resolved from connected wallet\n chain: (await import(\"../utils/chains.js\")).resolveChain(\n options.chain ?? \"base-sepolia\",\n ),\n isDeployed: true,\n policies: [],\n sessions: [],\n },\n {\n sessionKey: \"0x0000000000000000000000000000000000000000\" as Address, // Will be generated\n actions: [\n {\n target: targetAddress,\n selector: validateSelector(options.selector, \"function\"),\n },\n ],\n expiresAt,\n },\n ownerKey,\n );\n\n spinner.stop();\n success(\"Session key created!\");\n console.log();\n\n // Warn about sensitive key material\n console.log(\n chalk.yellow(\n \" WARNING: The private key below grants transaction signing access.\",\n ),\n );\n console.log(\n chalk.yellow(\n \" Store it securely and never share it publicly.\",\n ),\n );\n console.log();\n\n printKeyValue([\n [\"Session Key\", result.sessionKey],\n [\"Private Key\", result.privateKey],\n [\"Permission ID\", result.permissionId],\n [\n \"Expires\",\n new Date(expiresAt * 1000).toISOString(),\n ],\n ]);\n console.log();\n info(\n \"Save the private key securely — the agent needs it to sign transactions.\",\n );\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nsessionCommand\n .command(\"list\")\n .description(\"List active sessions for a wallet\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n const sessions = client.getActiveSessions(walletAddress);\n\n if (sessions.length === 0) {\n info(\"No active sessions found for this wallet.\");\n info(\n chalk.gray(\n \"Note: Session data is stored in-memory only and does not persist across CLI invocations.\",\n ),\n );\n return;\n }\n\n const table = createTable([\n \"Session Key\",\n \"Expires\",\n \"Actions\",\n ]);\n\n for (const s of sessions) {\n const expiresIn = s.expiresAt - Math.floor(Date.now() / 1000);\n const expiresStr =\n expiresIn > 0\n ? `${Math.floor(expiresIn / 3600)}h ${Math.floor((expiresIn % 3600) / 60)}m`\n : chalk.red(\"Expired\");\n\n table.push([\n `${s.sessionKey.slice(0, 10)}...`,\n expiresStr,\n s.actions.length.toString(),\n ]);\n }\n\n console.log();\n console.log(chalk.bold(`Sessions for ${walletAddress}`));\n console.log(table.toString());\n console.log();\n info(\n chalk.gray(\n \"Note: Session data is stored in-memory only and does not persist across CLI invocations.\",\n ),\n );\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n\nsessionCommand\n .command(\"revoke\")\n .description(\"Revoke a session key\")\n .requiredOption(\"--wallet <address>\", \"Wallet address\")\n .requiredOption(\"--permission-id <hex>\", \"Permission ID to revoke\")\n .option(\"--owner-key <hex>\", \"Owner private key (or set SAK_OWNER_KEY env var)\")\n .option(\"--owner-mnemonic <phrase>\", \"Owner mnemonic phrase (or set SAK_OWNER_MNEMONIC env var)\")\n .option(\"--address-index <n>\", \"HD derivation index (default: 0)\", \"0\")\n .option(\"--chain <name>\", \"Target chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action(async (options) => {\n const spinner = ora(\"Revoking session...\").start();\n\n try {\n const walletAddress = validateAddress(options.wallet, \"wallet\");\n const ownerKey = resolveSignerKey(\n options.ownerKey,\n options.ownerMnemonic,\n \"SAK_OWNER_KEY\",\n \"SAK_OWNER_MNEMONIC\",\n \"owner\",\n parseInt(options.addressIndex, 10),\n );\n\n const client = createSdkClient({\n chain: options.chain,\n rpcUrl: options.rpcUrl,\n bundlerUrl: options.bundlerUrl,\n });\n\n await client.connectWallet(walletAddress, ownerKey);\n\n await client.revokeSession(\n {\n address: walletAddress,\n owner: walletAddress,\n chain: (await import(\"../utils/chains.js\")).resolveChain(\n options.chain ?? \"base-sepolia\",\n ),\n isDeployed: true,\n policies: [],\n sessions: [],\n },\n validateHex(options.permissionId, \"permission ID\"),\n ownerKey,\n );\n\n spinner.stop();\n success(\"Session revoked!\");\n printKeyValue([\n [\"Permission ID\", options.permissionId],\n ]);\n } catch (err) {\n spinner.stop();\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport {\n loadConfig,\n saveConfig,\n getConfigPath,\n setConfigValue,\n deleteConfigValue,\n} from \"../utils/config.js\";\nimport { listChains } from \"../utils/chains.js\";\nimport { success, error, info, printKeyValue } from \"../utils/display.js\";\n\nexport const configCommand = new Command(\"config\")\n .description(\"Manage CLI configuration\");\n\nconfigCommand\n .command(\"show\")\n .description(\"Show current configuration\")\n .action(() => {\n const config = loadConfig();\n console.log();\n console.log(chalk.bold(\"Configuration\"));\n console.log(chalk.gray(` File: ${getConfigPath()}`));\n console.log();\n console.log(JSON.stringify(config, null, 2));\n });\n\nconfigCommand\n .command(\"set\")\n .description(\"Set a configuration value\")\n .argument(\"<key>\", \"Config key (e.g., rpcUrl, defaultChain)\")\n .argument(\"<value>\", \"Config value\")\n .action((key: string, value: string) => {\n // Handle nested keys like moduleAddresses.spendingLimitHook\n if (key.includes(\".\")) {\n const parts = key.split(\".\");\n const config = loadConfig();\n let obj = config as unknown as Record<string, unknown>;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!obj[parts[i]] || typeof obj[parts[i]] !== \"object\") {\n obj[parts[i]] = {};\n }\n obj = obj[parts[i]] as Record<string, unknown>;\n }\n obj[parts[parts.length - 1]] = value;\n saveConfig(config);\n } else {\n setConfigValue(key, value);\n }\n success(`Set ${key} = ${value}`);\n });\n\nconfigCommand\n .command(\"delete\")\n .description(\"Delete a configuration value\")\n .argument(\"<key>\", \"Config key to delete (supports dot-notation, e.g. moduleAddresses.spendingLimitHook)\")\n .action((key: string) => {\n if (key.includes(\".\")) {\n const parts = key.split(\".\");\n const config = loadConfig();\n let obj = config as unknown as Record<string, unknown>;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!obj[parts[i]] || typeof obj[parts[i]] !== \"object\") {\n // Path doesn't exist, nothing to delete\n success(`Deleted ${key}`);\n return;\n }\n obj = obj[parts[i]] as Record<string, unknown>;\n }\n delete obj[parts[parts.length - 1]];\n saveConfig(config);\n } else {\n deleteConfigValue(key);\n }\n success(`Deleted ${key}`);\n });\n\nconfigCommand\n .command(\"chains\")\n .description(\"List supported chain names\")\n .action(() => {\n console.log();\n console.log(chalk.bold(\"Supported Chains\"));\n console.log();\n for (const name of listChains()) {\n console.log(` ${chalk.cyan(name)}`);\n }\n });\n\nconfigCommand\n .command(\"init\")\n .description(\"Initialize configuration interactively\")\n .option(\"--chain <name>\", \"Default chain\", \"base-sepolia\")\n .option(\"--rpc-url <url>\", \"RPC URL\")\n .option(\"--bundler-url <url>\", \"Bundler URL\")\n .action((options) => {\n const config = loadConfig();\n\n if (options.chain) config.defaultChain = options.chain;\n if (options.rpcUrl) config.rpcUrl = options.rpcUrl;\n if (options.bundlerUrl) config.bundlerUrl = options.bundlerUrl;\n\n saveConfig(config);\n success(\"Configuration saved!\");\n console.log();\n printKeyValue([\n [\"Config file\", getConfigPath()],\n [\"Default chain\", config.defaultChain],\n [\"RPC URL\", config.rpcUrl ?? \"(not set)\"],\n [\"Bundler URL\", config.bundlerUrl ?? \"(not set)\"],\n ]);\n });\n"],"mappings":"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","names":["Command","Command","ora","chalk","Command","ora","chalk","Command","chalk","Command","chalk","Command","chalk","Command","chalk","Command","ora","Command","ora","Command","ora","chalk","Command","ora","chalk","Command","chalk","Command","chalk","Command"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@smartagentkit/cli",
3
+ "version": "0.1.2",
4
+ "description": "CLI tool for managing policy-governed AI agent smart wallets",
5
+ "license": "MIT",
6
+ "author": "SmartAgentKit Contributors",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/smartagentkit/smartagentkit.git",
10
+ "directory": "packages/cli"
11
+ },
12
+ "homepage": "https://github.com/smartagentkit/smartagentkit#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/smartagentkit/smartagentkit/issues"
15
+ },
16
+ "keywords": [
17
+ "smart-wallet",
18
+ "ai-agent",
19
+ "cli",
20
+ "erc4337",
21
+ "account-abstraction",
22
+ "policy",
23
+ "ethereum"
24
+ ],
25
+ "type": "module",
26
+ "bin": {
27
+ "smartagentkit": "./dist/index.js",
28
+ "sak": "./dist/index.js"
29
+ },
30
+ "files": [
31
+ "dist"
32
+ ],
33
+ "publishConfig": {
34
+ "access": "public"
35
+ },
36
+ "dependencies": {
37
+ "commander": "^13.1.0",
38
+ "chalk": "^5.4.0",
39
+ "ora": "^8.2.0",
40
+ "cli-table3": "^0.6.5",
41
+ "viem": "^2.46.0",
42
+ "@smartagentkit/sdk": "0.1.2"
43
+ },
44
+ "devDependencies": {
45
+ "@types/node": "^22.0.0",
46
+ "tsup": "^8.4.0",
47
+ "vitest": "^3.0.0",
48
+ "typescript": "^5.7.0"
49
+ },
50
+ "scripts": {
51
+ "build": "tsup",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest",
54
+ "lint": "tsc --noEmit",
55
+ "typecheck": "tsc --noEmit",
56
+ "clean": "rm -rf dist"
57
+ }
58
+ }