@openfort/cli 0.1.4 → 0.1.5

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.
Files changed (3) hide show
  1. package/README.md +75 -58
  2. package/dist/cli.js +108 -85
  3. package/package.json +6 -2
package/README.md CHANGED
@@ -1,40 +1,17 @@
1
- ![Illustration_02](https://github.com/user-attachments/assets/7733bc34-9fa7-4e43-bde0-bbbf5518738c)
2
-
3
-
4
- <div align="center">
5
- <h4>
6
- <a href="https://www.openfort.io/">
7
- Website
8
- </a>
9
- <span> | </span>
10
- <a href="https://www.openfort.io/docs/overview/building-with-cli">
11
- Documentation
12
- </a>
13
- <span> | </span>
14
- <a href="https://x.com/openfort_hq">
15
- X
16
- </a>
17
- </h4>
18
- </div>
19
-
20
1
  # Openfort CLI
21
2
 
22
- [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
23
- [![Documentation](https://img.shields.io/badge/docs-openfort.io-blue)](https://www.openfort.io/docs/overview/building-with-cli)
24
- [![Version](https://img.shields.io/npm/v/@openfort/cli.svg)](https://www.npmjs.org/package/@openfort/cli)
3
+ The official CLI for [Openfort](https://openfort.io).
25
4
 
26
- **Manage wallets, policies, and transactions from the terminal.** CLI for Openfort's wallet infrastructure.
5
+ Built for humans, AI agents, and CI/CD pipelines.
27
6
 
28
- ## Features
29
- - 💼 **Account Management** create and list smart accounts
30
- - 📜 **Contracts** — register and manage on-chain contracts
31
- - ⚡ **Transactions** — send and estimate transactions
32
- - 🔐 **Session Keys** — create and manage session keys
33
- - 💸 **Gas Sponsorship** — configure policies and sponsorship rules
34
- - 👥 **Users** — manage users and wallet keys
35
- - 🔒 **Shield** — wallet encryption and recovery
36
- - 🔔 **Subscriptions** — set up webhooks and event subscriptions
37
- - 🤖 **AI-friendly** — works as an MCP tool for LLM agents
7
+ ```
8
+ ██████╗ ██████╗ ███████╗███╗ ██╗███████╗ ██████╗ ██████╗ ████████╗
9
+ ██╔═══██╗██╔══██╗██╔════╝████╗ ██║██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝
10
+ ██║ ██║██████╔╝█████╗ ██╔██╗ ██║█████╗ ██║ ██║██████╔╝ ██║
11
+ ██║ ██║██╔═══╝ ██╔══╝ ██║╚██╗██║██╔══╝ ██║ ██║██╔══██╗ ██║
12
+ ╚██████╔╝██║ ███████╗██║ ╚████║██║ ╚██████╔╝██║ ██║ ██║
13
+ ╚═════╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
14
+ ```
38
15
 
39
16
  ## Quick Start
40
17
 
@@ -48,46 +25,86 @@ npm install -g @openfort/cli
48
25
  openfort login
49
26
  ```
50
27
 
51
- ### 3. Use
28
+ ### 3. Set up backend wallet signing keys
29
+ ```bash
30
+ openfort backend-wallet setup
31
+ ```
32
+
33
+ ### 4. Use
52
34
  ```bash
53
- # List accounts
35
+ # List all accounts across chains
54
36
  openfort accounts list
55
37
 
56
- # Create a backend wallet
57
- openfort accounts create --chainId 80002
38
+ # Create an EVM backend wallet
39
+ openfort accounts evm create
40
+
41
+ # Create a Solana backend wallet
42
+ openfort accounts solana create
58
43
 
59
44
  # List policies
60
45
  openfort policies list
61
46
 
62
47
  # Send a transaction
63
- openfort transactions create --policy <policy_id> --interactions '[...]'
48
+ openfort transactions create --account acc_1a2b3c4d --chainId 137 --interactions '[{"to":"0x...","value":"0"}]'
49
+
50
+ # Estimate gas cost
51
+ openfort transactions estimate --account acc_1a2b3c4d --chainId 137 --interactions '[{"to":"0x...","value":"0"}]'
52
+ ```
53
+
54
+ ## AI Agent Integration
55
+
56
+ ### MCP (Model Context Protocol)
57
+
58
+ Register the CLI as an MCP server for your AI agent:
59
+
60
+ ```bash
61
+ openfort mcp add
62
+ ```
63
+
64
+ This registers Openfort tools in Claude Code, Cursor, and Amp. Agents can then call any CLI command as a tool.
65
+
66
+ ### Skills
67
+
68
+ Install agent skill files for discovery:
69
+
70
+ ```bash
71
+ openfort skills add
64
72
  ```
65
73
 
66
74
  ## Environment Variables
67
75
 
68
- | Variable | Description |
69
- |---|---|
70
- | `OPENFORT_API_KEY` | Secret API key (`sk_test_...` or `sk_live_...`) |
71
- | `OPENFORT_WALLET_SECRET` | Wallet encryption secret |
72
- | `OPENFORT_PUBLISHABLE_KEY` | Publishable key for client-side ops |
73
- | `OPENFORT_BASE_URL` | Custom API base URL |
76
+ | Variable | Description |
77
+ | -------------------------- | ----------------------------------------------- |
78
+ | `OPENFORT_API_KEY` | Secret API key (`sk_test_...` or `sk_live_...`) |
79
+ | `OPENFORT_WALLET_SECRET` | Wallet encryption secret |
80
+ | `OPENFORT_PUBLISHABLE_KEY` | Publishable key for client-side ops |
81
+ | `OPENFORT_BASE_URL` | Custom API base URL |
74
82
 
75
83
  ## Commands
76
84
 
77
- | Command | Description |
78
- |---|---|
79
- | `login` | Authenticate with your Openfort API key |
80
- | `accounts` | Create and manage smart accounts |
81
- | `contracts` | Register and manage contracts |
82
- | `paymasters` | Manage paymasters |
83
- | `policies` | Configure gas policies |
84
- | `sponsorship` | Set up gas sponsorship rules |
85
- | `sessions` | Manage session keys |
86
- | `subscriptions` | Set up webhooks and subscriptions |
87
- | `transactions` | Send and estimate transactions |
88
- | `users` | Manage users |
89
- | `wallet-keys` | Manage wallet keys |
90
- | `shield` | Wallet encryption and recovery |
85
+ | Command | Description |
86
+ | ----------------- | ------------------------------------------------------------------- |
87
+ | `login` | Log in to Openfort via browser and save your API key |
88
+ | `accounts` | Manage wallets and accounts (EVM and Solana subcommands) |
89
+ | `contracts` | Manage smart contracts |
90
+ | `paymasters` | Manage ERC-4337 paymasters |
91
+ | `policies` | Manage rules and conditions for backend wallets and fee sponsorship |
92
+ | `sponsorship` | Manage fee sponsorship strategies linked to policies |
93
+ | `sessions` | Manage session keys |
94
+ | `subscriptions` | Manage webhook subscriptions and triggers |
95
+ | `transactions` | Manage transaction intents |
96
+ | `users` | Manage authenticated users |
97
+ | `backend-wallet` | Configure backend wallet signing keys |
98
+ | `embedded-wallet` | Configure embedded wallet (Shield) API keys |
99
+ | `message` | Message utilities (e.g. keccak256 hashing) |
100
+
101
+ ## Alias
102
+
103
+ The CLI is also available as `of`:
104
+
105
+ ```bash
106
+ of accounts list
107
+ ```
91
108
 
92
109
  ## Documentation
93
110
 
package/dist/cli.js CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  } from "./chunk-QJGHQ7ID.js";
6
6
 
7
7
  // src/cli.ts
8
+ import { readFileSync as readFileSync2 } from "fs";
8
9
  import { Cli as Cli13, z as z15, Errors as Errors4 } from "incur";
9
10
  import Openfort from "@openfort/openfort-node";
10
11
 
@@ -198,10 +199,12 @@ var loginConfig = {
198
199
  const authUrl = new URL(`${AUTH_PAGE_URL}/oauth/consent`);
199
200
  authUrl.searchParams.set("redirect_uri", redirectUri);
200
201
  authUrl.searchParams.set("state", state);
201
- console.log("\nOpen this URL in your browser to log in:\n");
202
- console.log(` ${authUrl.toString()}
202
+ if (!c.agent) {
203
+ console.log("\nOpen this URL in your browser to log in:\n");
204
+ console.log(` ${authUrl.toString()}
203
205
  `);
204
- console.log("Waiting for authentication...\n");
206
+ console.log("Waiting for authentication...\n");
207
+ }
205
208
  const { apiKey, publishableKey, projectId, project } = await waitForCallback(port, state);
206
209
  ensureConfigDir();
207
210
  writeEnvKey(CREDENTIALS_PATH, "OPENFORT_API_KEY", apiKey);
@@ -211,14 +214,16 @@ var loginConfig = {
211
214
  if (projectId) {
212
215
  writeEnvKey(CREDENTIALS_PATH, "OPENFORT_PROJECT_ID", projectId);
213
216
  }
214
- console.log(`Saved API key for project "${project}" to ${CREDENTIALS_PATH}`);
217
+ if (!c.agent) {
218
+ console.log(`Saved API key for project "${project}" to ${CREDENTIALS_PATH}`);
219
+ }
215
220
  return c.ok(
216
221
  { apiKey, project, credentialsPath: CREDENTIALS_PATH },
217
222
  {
218
223
  cta: {
219
224
  description: "Next steps:",
220
225
  commands: [
221
- { command: `wallet-keys create`, description: "Create and save wallet keys necessary for backend wallet creation" }
226
+ { command: `backend-wallet setup`, description: "Set up signing keys for backend wallets" }
222
227
  ]
223
228
  }
224
229
  }
@@ -227,19 +232,23 @@ var loginConfig = {
227
232
  };
228
233
 
229
234
  // src/commands/accounts.ts
230
- import { Cli, z as z3, Errors } from "incur";
231
- function requireWalletCredentials() {
235
+ import { Cli, z as z3, middleware } from "incur";
236
+ var requireWallet = middleware((c, next) => {
232
237
  const missing = [];
233
238
  if (!process.env.OPENFORT_WALLET_SECRET) missing.push("OPENFORT_WALLET_SECRET");
234
239
  if (!process.env.OPENFORT_PUBLISHABLE_KEY) missing.push("OPENFORT_PUBLISHABLE_KEY");
235
240
  if (missing.length > 0) {
236
- throw new Errors.IncurError({
241
+ return c.error({
237
242
  code: "MISSING_CREDENTIALS",
238
243
  message: `Missing required credentials: ${missing.join(", ")}`,
239
- hint: "Run: openfort wallet-keys create"
244
+ cta: {
245
+ description: "Set up wallet credentials:",
246
+ commands: [{ command: "backend-wallet setup", description: "Set up signing keys for backend wallets" }]
247
+ }
240
248
  });
241
249
  }
242
- }
250
+ return next();
251
+ });
243
252
  var evm = Cli.create("evm", {
244
253
  description: "EVM wallet management.",
245
254
  vars: varsSchema
@@ -247,15 +256,16 @@ var evm = Cli.create("evm", {
247
256
  evm.command("create", {
248
257
  description: "Create a new EVM backend wallet.",
249
258
  examples: [
250
- { description: "Create a new EVM wallet" }
259
+ { description: "Create a new EVM backend wallet (developer custody)" }
251
260
  ],
261
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
262
+ middleware: [requireWallet],
252
263
  output: z3.object({
253
264
  id: z3.string().describe("Account ID"),
254
265
  address: z3.string().describe("Wallet address"),
255
266
  custody: z3.string().describe("Custody type")
256
267
  }),
257
268
  async run(c) {
258
- requireWalletCredentials();
259
269
  const account = await c.var.openfort.accounts.evm.backend.create();
260
270
  return c.ok(
261
271
  { id: account.id, address: account.address, custody: account.custody },
@@ -421,7 +431,7 @@ evm.command("update", {
421
431
  }),
422
432
  options: z3.object({
423
433
  chainId: z3.number().describe("Chain ID to deploy on"),
424
- implementationType: z3.string().describe("Smart account implementation type we will update to")
434
+ implementationType: z3.string().describe("Target implementation type (e.g. CaliburV9)")
425
435
  }),
426
436
  examples: [
427
437
  { args: { id: "acc_1a2b3c4d" }, options: { chainId: 8453, implementationType: "CaliburV9" }, description: "Upgrade to delegated account on Base" }
@@ -453,7 +463,7 @@ evm.command("update", {
453
463
  cta: {
454
464
  description: "Next steps:",
455
465
  commands: [
456
- { command: `accounts evm list-delegated`, description: "To see all accounts which were updated to delegated ones" }
466
+ { command: `accounts evm list-delegated`, description: "List all delegated accounts" }
457
467
  ]
458
468
  }
459
469
  }
@@ -471,11 +481,12 @@ evm.command("sign", {
471
481
  examples: [
472
482
  { args: { id: "acc_1a2b3c4d" }, options: { data: "0xdeadbeef" }, description: "Sign a message hash" }
473
483
  ],
484
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
485
+ middleware: [requireWallet],
474
486
  output: z3.object({
475
487
  signature: z3.string()
476
488
  }),
477
489
  async run(c) {
478
- requireWalletCredentials();
479
490
  const signature = await c.var.openfort.accounts.evm.backend.sign({
480
491
  id: c.args.id,
481
492
  data: c.options.data
@@ -491,13 +502,14 @@ evm.command("import", {
491
502
  examples: [
492
503
  { options: { privateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" }, description: "Import a private key" }
493
504
  ],
505
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
506
+ middleware: [requireWallet],
494
507
  output: z3.object({
495
508
  id: z3.string(),
496
509
  address: z3.string(),
497
510
  custody: z3.string()
498
511
  }),
499
512
  async run(c) {
500
- requireWalletCredentials();
501
513
  const account = await c.var.openfort.accounts.evm.backend.import({
502
514
  privateKey: c.options.privateKey
503
515
  });
@@ -516,11 +528,11 @@ evm.command("export", {
516
528
  examples: [
517
529
  { args: { id: "acc_1a2b3c4d" }, description: "Export private key" }
518
530
  ],
531
+ middleware: [requireWallet],
519
532
  output: z3.object({
520
533
  privateKey: z3.string()
521
534
  }),
522
535
  async run(c) {
523
- requireWalletCredentials();
524
536
  const privateKey = await c.var.openfort.accounts.evm.backend.export({
525
537
  id: c.args.id
526
538
  });
@@ -535,7 +547,7 @@ evm.command("send-transaction", {
535
547
  options: z3.object({
536
548
  chainId: z3.number().describe("Chain ID"),
537
549
  interactions: z3.string().describe('Interactions as JSON: [{"to":"0x...","data":"0x...","value":"0"}]'),
538
- policy: z3.string().optional().describe("Policy ID for gas sponsorship (pol_...)")
550
+ policy: z3.string().optional().describe("Fee sponsorship ID (pol_...)")
539
551
  }),
540
552
  examples: [
541
553
  {
@@ -547,6 +559,7 @@ evm.command("send-transaction", {
547
559
  description: "Send a gasless transaction on Base"
548
560
  }
549
561
  ],
562
+ middleware: [requireWallet],
550
563
  output: z3.object({
551
564
  id: z3.string(),
552
565
  chainId: z3.number(),
@@ -575,15 +588,16 @@ var solana = Cli.create("solana", {
575
588
  solana.command("create", {
576
589
  description: "Create a new Solana backend wallet.",
577
590
  examples: [
578
- { description: "Create a new Solana wallet" }
591
+ { description: "Create a new Solana backend wallet (developer custody)" }
579
592
  ],
593
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
594
+ middleware: [requireWallet],
580
595
  output: z3.object({
581
596
  id: z3.string().describe("Account ID"),
582
597
  address: z3.string().describe("Wallet address"),
583
598
  custody: z3.string().describe("Custody type")
584
599
  }),
585
600
  async run(c) {
586
- requireWalletCredentials();
587
601
  const account = await c.var.openfort.accounts.solana.backend.create();
588
602
  return c.ok(
589
603
  { id: account.id, address: account.address, custody: account.custody },
@@ -662,6 +676,8 @@ solana.command("sign", {
662
676
  data: z3.string().describe("Data to sign (base64-encoded)")
663
677
  }),
664
678
  alias: { data: "d" },
679
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
680
+ middleware: [requireWallet],
665
681
  output: z3.object({
666
682
  account: z3.string(),
667
683
  signature: z3.string()
@@ -674,7 +690,6 @@ solana.command("sign", {
674
690
  }
675
691
  ],
676
692
  async run(c) {
677
- requireWalletCredentials();
678
693
  const signature = await c.var.openfort.accounts.solana.backend.sign(c.args.id, c.options.data);
679
694
  return c.ok({ account: c.args.id, signature });
680
695
  }
@@ -696,26 +711,6 @@ solana.command("delete", {
696
711
  return c.ok({ id: res.id, deleted: res.deleted });
697
712
  }
698
713
  });
699
- solana.command("sign", {
700
- description: "Sign data with a Solana backend wallet.",
701
- args: z3.object({
702
- id: z3.string().describe("Account ID (acc_...)")
703
- }),
704
- options: z3.object({
705
- data: z3.string().describe("Data to sign")
706
- }),
707
- examples: [
708
- { args: { id: "acc_1a2b3c4d" }, options: { data: "hello" }, description: "Sign a message" }
709
- ],
710
- output: z3.object({
711
- signature: z3.string()
712
- }),
713
- async run(c) {
714
- requireWalletCredentials();
715
- const signature = await c.var.openfort.accounts.solana.backend.sign(c.args.id, c.options.data);
716
- return c.ok({ signature });
717
- }
718
- });
719
714
  solana.command("import", {
720
715
  description: "Import a private key as a Solana backend wallet.",
721
716
  options: z3.object({
@@ -724,13 +719,14 @@ solana.command("import", {
724
719
  examples: [
725
720
  { options: { privateKey: "abc123..." }, description: "Import a Solana private key" }
726
721
  ],
722
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
723
+ middleware: [requireWallet],
727
724
  output: z3.object({
728
725
  id: z3.string(),
729
726
  address: z3.string(),
730
727
  custody: z3.string()
731
728
  }),
732
729
  async run(c) {
733
- requireWalletCredentials();
734
730
  const account = await c.var.openfort.accounts.solana.backend.import({
735
731
  privateKey: c.options.privateKey
736
732
  });
@@ -749,11 +745,11 @@ solana.command("export", {
749
745
  examples: [
750
746
  { args: { id: "acc_1a2b3c4d" }, description: "Export private key" }
751
747
  ],
748
+ middleware: [requireWallet],
752
749
  output: z3.object({
753
750
  privateKey: z3.string()
754
751
  }),
755
752
  async run(c) {
756
- requireWalletCredentials();
757
753
  const privateKey = await c.var.openfort.accounts.solana.backend.export({
758
754
  id: c.args.id
759
755
  });
@@ -783,6 +779,7 @@ solana.command("transfer", {
783
779
  description: "Transfer 1 USDC on devnet"
784
780
  }
785
781
  ],
782
+ middleware: [requireWallet],
786
783
  output: z3.object({
787
784
  signature: z3.string()
788
785
  }),
@@ -924,7 +921,7 @@ contracts.command("create", {
924
921
  description: "Register USDC on Polygon"
925
922
  },
926
923
  {
927
- options: { name: "My NFT", address: "0x1234...", chainId: 1, abi: '[{"type":"function","name":"mint",...}]' },
924
+ options: { name: "My Token", address: "0x1234...", chainId: 1, abi: '[{"type":"function","name":"mint","inputs":[],"outputs":[],"stateMutability":"nonpayable"}]' },
928
925
  description: "Register contract with ABI"
929
926
  }
930
927
  ],
@@ -1109,7 +1106,7 @@ paymasters.command("update", {
1109
1106
  id: z5.string().describe("Paymaster ID (pay_...)")
1110
1107
  }),
1111
1108
  options: z5.object({
1112
- address: z5.string().describe("Paymaster address"),
1109
+ address: z5.string().optional().describe("Paymaster address"),
1113
1110
  name: z5.string().optional().describe("New name"),
1114
1111
  url: z5.string().optional().describe("New URL")
1115
1112
  }),
@@ -1154,7 +1151,7 @@ paymasters.command("delete", {
1154
1151
  import { Cli as Cli4, z as z6 } from "incur";
1155
1152
  var policyScopes = ["project", "account", "transaction"];
1156
1153
  var policies = Cli4.create("policies", {
1157
- description: "Manage access-control policies.",
1154
+ description: "Manage rules and conditions for backend wallets and fee sponsorship.",
1158
1155
  vars: varsSchema
1159
1156
  });
1160
1157
  policies.command("list", {
@@ -1227,6 +1224,14 @@ policies.command("create", {
1227
1224
  rules: '[{"action":"accept","operation":"sponsorEvmTransaction","criteria":[{"type":"evmNetwork","operator":"in","chainIds":[137]}]}]'
1228
1225
  },
1229
1226
  description: "Create a policy to sponsor transactions on Polygon"
1227
+ },
1228
+ {
1229
+ options: {
1230
+ scope: "account",
1231
+ description: "Allow signing for a specific account",
1232
+ rules: '[{"action":"accept","operation":"signEvmTransaction"}]'
1233
+ },
1234
+ description: "Allow EVM transaction signing"
1230
1235
  }
1231
1236
  ],
1232
1237
  async run(c) {
@@ -1401,7 +1406,7 @@ var sponsorshipItem = z7.object({
1401
1406
  policyId: z7.string().nullable()
1402
1407
  });
1403
1408
  var sponsorship = Cli5.create("sponsorship", {
1404
- description: "Manage fee sponsorships for gas costs.",
1409
+ description: "Manage fee sponsorship strategies linked to policies.",
1405
1410
  vars: varsSchema
1406
1411
  });
1407
1412
  sponsorship.command("list", {
@@ -1937,7 +1942,7 @@ sessions.command("create", {
1937
1942
  player: z9.string().optional().describe("Player ID (pla_...)"),
1938
1943
  account: z9.string().optional().describe("Account ID (acc_...)"),
1939
1944
  limit: z9.number().optional().describe("Max session uses"),
1940
- policy: z9.string().optional().describe("Policy ID for gas sponsorship (pol_...)"),
1945
+ policy: z9.string().optional().describe("Policy ID (ply_...) for gas sponsorship"),
1941
1946
  whitelist: z9.string().optional().describe("Whitelisted contract addresses as JSON array")
1942
1947
  }),
1943
1948
  examples: [
@@ -2018,7 +2023,7 @@ sessions.command("revoke", {
2018
2023
  address: z9.string().describe("Session key address to revoke"),
2019
2024
  chainId: z9.number().describe("Chain ID"),
2020
2025
  player: z9.string().optional().describe("Player ID (pla_...)"),
2021
- policy: z9.string().optional().describe("Policy ID (pol_...)")
2026
+ policy: z9.string().optional().describe("Policy ID (ply_...) for gas sponsorship")
2022
2027
  }),
2023
2028
  examples: [
2024
2029
  { options: { address: "0x1234...", chainId: 137 }, description: "Revoke a session key" }
@@ -2153,7 +2158,7 @@ transactions.command("create", {
2153
2158
  account: z10.string().describe("Account ID (acc_...)"),
2154
2159
  chainId: z10.number().describe("Chain ID"),
2155
2160
  interactions: z10.string().describe('Interactions as JSON: [{"to":"0x...","data":"0x...","value":"0"}]'),
2156
- policy: z10.string().optional().describe("Policy ID for gas sponsorship"),
2161
+ policy: z10.string().optional().describe("Policy ID (ply_...) for gas sponsorship"),
2157
2162
  signedAuthorization: z10.string().optional().describe("Signed EIP-7702 authorization hex (for delegated accounts)")
2158
2163
  }),
2159
2164
  output: transactionIntentItem,
@@ -2171,9 +2176,9 @@ transactions.command("create", {
2171
2176
  account: "acc_1a2b3c4d",
2172
2177
  chainId: 137,
2173
2178
  interactions: '[{"to":"0x742d35Cc6634C0532925a3b844Bc9e7595f92cD5","value":"1000000000000000000"}]',
2174
- policy: "ply_1a2b3c4d"
2179
+ policy: "pol_1a2b3c4d"
2175
2180
  },
2176
- description: "Send 1 MATIC with gas sponsorship"
2181
+ description: "Send 1 POL with gas sponsorship"
2177
2182
  }
2178
2183
  ],
2179
2184
  async run(c) {
@@ -2280,7 +2285,7 @@ transactions.command("estimate", {
2280
2285
  account: z10.string().describe("Account ID (acc_...)"),
2281
2286
  chainId: z10.number().describe("Chain ID"),
2282
2287
  interactions: z10.string().describe("Interactions as JSON"),
2283
- policy: z10.string().optional().describe("Policy ID for gas sponsorship")
2288
+ policy: z10.string().optional().describe("Fee sponsorship ID (pol_...) for gas sponsorship")
2284
2289
  }),
2285
2290
  examples: [
2286
2291
  {
@@ -2313,15 +2318,15 @@ transactions.command("estimate", {
2313
2318
  }
2314
2319
  });
2315
2320
 
2316
- // src/commands/shield.ts
2321
+ // src/commands/embedded-wallet.ts
2317
2322
  import { Cli as Cli9, z as z11, Errors as Errors2 } from "incur";
2318
2323
  var SHIELD_API_URL = OPENFORT_SHIELD_URL;
2319
- var shield = Cli9.create("shield", {
2320
- description: "Manage Shield (embedded wallet) API keys.",
2324
+ var embeddedWallet = Cli9.create("embedded-wallet", {
2325
+ description: "Configure embedded wallet (Shield) API keys.",
2321
2326
  vars: varsSchema
2322
2327
  });
2323
- shield.command("create", {
2324
- description: "Create Shield API keys for embedded wallets.",
2328
+ embeddedWallet.command("setup", {
2329
+ description: "Generate and register embedded wallet (Shield) API keys.",
2325
2330
  options: z11.object({
2326
2331
  project: z11.string().optional().describe("Project ID (pro_...). Defaults to OPENFORT_PROJECT_ID env var.")
2327
2332
  }),
@@ -2333,9 +2338,10 @@ shield.command("create", {
2333
2338
  examples: [
2334
2339
  {
2335
2340
  options: { project: "pro_abc123" },
2336
- description: "Create Shield keys for a project"
2341
+ description: "Set up embedded wallet keys for a project"
2337
2342
  }
2338
2343
  ],
2344
+ hint: 'Requires OPENFORT_PUBLISHABLE_KEY and OPENFORT_PROJECT_ID. Run "openfort login" first.',
2339
2345
  async run(c) {
2340
2346
  const publishableKey = process.env.OPENFORT_PUBLISHABLE_KEY;
2341
2347
  if (!publishableKey) {
@@ -2371,7 +2377,8 @@ shield.command("create", {
2371
2377
  const text = await registerRes.text();
2372
2378
  throw new Errors2.IncurError({
2373
2379
  code: "SHIELD_REGISTER_FAILED",
2374
- message: `Shield registration failed: ${text}`
2380
+ message: `Shield registration failed: ${text}`,
2381
+ retryable: true
2375
2382
  });
2376
2383
  }
2377
2384
  const shieldData = await registerRes.json();
@@ -2394,7 +2401,8 @@ shield.command("create", {
2394
2401
  const text = await res.text();
2395
2402
  throw new Errors2.IncurError({
2396
2403
  code: "PERSIST_KEY_FAILED",
2397
- message: `Failed to persist ${type} key: ${text}`
2404
+ message: `Failed to persist ${type} key: ${text}`,
2405
+ retryable: true
2398
2406
  });
2399
2407
  }
2400
2408
  };
@@ -2421,7 +2429,8 @@ shield.command("create", {
2421
2429
  const text = await linkRes.text();
2422
2430
  throw new Errors2.IncurError({
2423
2431
  code: "SHIELD_LINK_FAILED",
2424
- message: `Failed to link Openfort provider to Shield: ${text}`
2432
+ message: `Failed to link Openfort provider to Shield: ${text}`,
2433
+ retryable: true
2425
2434
  });
2426
2435
  }
2427
2436
  ensureConfigDir();
@@ -2429,7 +2438,7 @@ shield.command("create", {
2429
2438
  writeEnvKey(CREDENTIALS_PATH, "SHIELD_SECRET_KEY", shieldData.api_secret);
2430
2439
  writeEnvKey(CREDENTIALS_PATH, "SHIELD_ENCRYPTION_SHARE", shieldData.encryption_part);
2431
2440
  return c.ok(
2432
- { message: `Shield keys were created and saved to ${CREDENTIALS_PATH}`, credentialsPath: CREDENTIALS_PATH },
2441
+ { message: `Embedded wallet keys were created and saved to ${CREDENTIALS_PATH}`, credentialsPath: CREDENTIALS_PATH },
2433
2442
  {
2434
2443
  cta: {
2435
2444
  description: "Next steps:",
@@ -2551,7 +2560,7 @@ users.command("delete", {
2551
2560
  }
2552
2561
  });
2553
2562
 
2554
- // src/commands/wallet-keys.ts
2563
+ // src/commands/backend-wallet.ts
2555
2564
  import { randomBytes as randomBytes2, subtle } from "crypto";
2556
2565
  import { Cli as Cli11, z as z13, Errors as Errors3 } from "incur";
2557
2566
  function arrayBufferToBase64(buffer) {
@@ -2623,21 +2632,22 @@ async function signWalletAuthJwt(privateKey, method, path, body) {
2623
2632
  );
2624
2633
  return `${signingInput}.${arrayBufferToBase64Url(signature)}`;
2625
2634
  }
2626
- var walletKeys = Cli11.create("wallet-keys", {
2627
- description: "Manage backend wallet keys.",
2635
+ var backendWallet = Cli11.create("backend-wallet", {
2636
+ description: "Configure backend wallet signing keys.",
2628
2637
  vars: varsSchema
2629
2638
  });
2630
- walletKeys.command("create", {
2631
- description: "Create backend wallet keys (ECDSA P-256).",
2639
+ backendWallet.command("setup", {
2640
+ description: "Generate and register backend wallet signing keys (ECDSA P-256).",
2632
2641
  output: z13.object({
2633
2642
  message: z13.string(),
2634
2643
  credentialsPath: z13.string()
2635
2644
  }),
2636
2645
  examples: [
2637
2646
  {
2638
- description: "Create backend wallet keys and save to credentials"
2647
+ description: "Set up backend wallet signing keys and save to credentials"
2639
2648
  }
2640
2649
  ],
2650
+ hint: 'Requires OPENFORT_API_KEY. Run "openfort login" first.',
2641
2651
  async run(c) {
2642
2652
  const apiKey = process.env.OPENFORT_API_KEY;
2643
2653
  const { publicKey, privateKey, privateKeyCrypto } = await generateKeyPair();
@@ -2663,7 +2673,8 @@ ${publicKey}
2663
2673
  const text = await registerRes.text();
2664
2674
  throw new Errors3.IncurError({
2665
2675
  code: "REGISTER_SECRET_FAILED",
2666
- message: `Failed to register wallet secret: ${text}`
2676
+ message: `Failed to register wallet secret: ${text}`,
2677
+ retryable: true
2667
2678
  });
2668
2679
  }
2669
2680
  const storeRes = await fetch(`${API_BASE_URL}/v1/project/apikey`, {
@@ -2678,7 +2689,8 @@ ${publicKey}
2678
2689
  const text = await storeRes.text();
2679
2690
  throw new Errors3.IncurError({
2680
2691
  code: "STORE_KEY_FAILED",
2681
- message: `Failed to store wallet key reference: ${text}`
2692
+ message: `Failed to store wallet key reference: ${text}`,
2693
+ retryable: true
2682
2694
  });
2683
2695
  }
2684
2696
  ensureConfigDir();
@@ -2691,15 +2703,15 @@ ${publicKey}
2691
2703
  cta: {
2692
2704
  description: "Next steps:",
2693
2705
  commands: [
2694
- { command: `shield create`, description: "Create and save Shield API keys" }
2706
+ { command: `embedded-wallet setup`, description: "Set up embedded wallet keys" }
2695
2707
  ]
2696
2708
  }
2697
2709
  }
2698
2710
  );
2699
2711
  }
2700
2712
  });
2701
- walletKeys.command("revoke", {
2702
- description: "Revoke the current backend wallet secret.",
2713
+ backendWallet.command("revoke", {
2714
+ description: "Revoke the current backend wallet signing secret.",
2703
2715
  output: z13.object({
2704
2716
  keyId: z13.string(),
2705
2717
  revoked: z13.boolean(),
@@ -2710,6 +2722,7 @@ walletKeys.command("revoke", {
2710
2722
  description: "Revoke the current wallet secret"
2711
2723
  }
2712
2724
  ],
2725
+ hint: 'Requires OPENFORT_WALLET_KEY_ID and OPENFORT_WALLET_SECRET. Run "openfort backend-wallet setup" first.',
2713
2726
  async run(c) {
2714
2727
  const apiKey = process.env.OPENFORT_API_KEY;
2715
2728
  const keyId = process.env.OPENFORT_WALLET_KEY_ID;
@@ -2717,7 +2730,8 @@ walletKeys.command("revoke", {
2717
2730
  if (!keyId || !privateKeyBase64) {
2718
2731
  throw new Errors3.IncurError({
2719
2732
  code: "MISSING_WALLET_KEY",
2720
- message: "OPENFORT_WALLET_KEY_ID and OPENFORT_WALLET_SECRET must be set. Create a wallet secret first with `wallet-keys create`."
2733
+ message: "OPENFORT_WALLET_KEY_ID and OPENFORT_WALLET_SECRET must be set. Run `backend-wallet setup` first.",
2734
+ hint: "Run: openfort backend-wallet setup"
2721
2735
  });
2722
2736
  }
2723
2737
  const privateKeyCrypto = await importPrivateKey(privateKeyBase64);
@@ -2737,15 +2751,16 @@ walletKeys.command("revoke", {
2737
2751
  const text = await res.text();
2738
2752
  throw new Errors3.IncurError({
2739
2753
  code: "REVOKE_SECRET_FAILED",
2740
- message: `Failed to revoke wallet secret: ${text}`
2754
+ message: `Failed to revoke wallet secret: ${text}`,
2755
+ retryable: true
2741
2756
  });
2742
2757
  }
2743
2758
  const data = await res.json();
2744
2759
  return c.ok(data);
2745
2760
  }
2746
2761
  });
2747
- walletKeys.command("rotate", {
2748
- description: "Rotate backend wallet secret (generates new ECDSA P-256 key pair).",
2762
+ backendWallet.command("rotate", {
2763
+ description: "Rotate backend wallet signing secret (generates new ECDSA P-256 key pair).",
2749
2764
  output: z13.object({
2750
2765
  message: z13.string(),
2751
2766
  credentialsPath: z13.string()
@@ -2755,6 +2770,7 @@ walletKeys.command("rotate", {
2755
2770
  description: "Rotate wallet secret and save new keys to credentials"
2756
2771
  }
2757
2772
  ],
2773
+ hint: 'Requires OPENFORT_API_KEY. Run "openfort login" first.',
2758
2774
  async run(c) {
2759
2775
  const apiKey = process.env.OPENFORT_API_KEY;
2760
2776
  const { publicKey, privateKey, privateKeyCrypto } = await generateKeyPair();
@@ -2780,7 +2796,8 @@ ${publicKey}
2780
2796
  const text = await rotateRes.text();
2781
2797
  throw new Errors3.IncurError({
2782
2798
  code: "ROTATE_SECRET_FAILED",
2783
- message: `Failed to rotate wallet secret: ${text}`
2799
+ message: `Failed to rotate wallet secret: ${text}`,
2800
+ retryable: true
2784
2801
  });
2785
2802
  }
2786
2803
  const storeRes = await fetch(`${API_BASE_URL}/v1/project/apikey`, {
@@ -2795,7 +2812,8 @@ ${publicKey}
2795
2812
  const text = await storeRes.text();
2796
2813
  throw new Errors3.IncurError({
2797
2814
  code: "STORE_KEY_FAILED",
2798
- message: `Failed to store rotated wallet key reference: ${text}`
2815
+ message: `Failed to store rotated wallet key reference: ${text}`,
2816
+ retryable: true
2799
2817
  });
2800
2818
  }
2801
2819
  ensureConfigDir();
@@ -2831,9 +2849,11 @@ message.command("hash", {
2831
2849
  });
2832
2850
 
2833
2851
  // src/cli.ts
2852
+ var pkg = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf-8"));
2834
2853
  var cli = Cli13.create("openfort", {
2835
- version: "0.1.0",
2836
- description: "Openfort CLI \u2014 manage wallets, policies, and transactions. If you are LLM read this doc first https://www.openfort.io/docs/overview/building-with-cli",
2854
+ version: pkg.version,
2855
+ aliases: ["of"],
2856
+ description: "Openfort CLI \u2014 manage wallets, policies, and transactions from the terminal.",
2837
2857
  vars: varsSchema,
2838
2858
  env: z15.object({
2839
2859
  OPENFORT_API_KEY: z15.string().optional().describe("Openfort secret API key (sk_test_... or sk_live_...)"),
@@ -2843,14 +2863,17 @@ var cli = Cli13.create("openfort", {
2843
2863
  }),
2844
2864
  sync: {
2845
2865
  depth: 2,
2846
- include: ["accounts", "transactions", "policies", "sponsorship", "contracts", "users", "sessions", "subscriptions"],
2866
+ include: ["_root", "accounts", "transactions", "policies", "sponsorship", "contracts", "users", "sessions", "subscriptions", "backend-wallet", "embedded-wallet"],
2847
2867
  suggestions: [
2848
2868
  "create an EVM backend wallet",
2849
2869
  "list all accounts",
2850
- "create a gas sponsorship policy",
2870
+ "create a policy for gas sponsorship",
2851
2871
  "list users",
2852
2872
  "estimate transaction gas cost"
2853
2873
  ]
2874
+ },
2875
+ mcp: {
2876
+ agents: ["claude-code", "cursor", "amp"]
2854
2877
  }
2855
2878
  });
2856
2879
  cli.command("login", loginConfig);
@@ -2875,7 +2898,7 @@ cli.use(async (c, next) => {
2875
2898
  }));
2876
2899
  await next();
2877
2900
  });
2878
- cli.command(accounts).command(contracts).command(paymasters).command(policies).command(shield).command(sponsorship).command(sessions).command(subscriptions).command(transactions).command(users).command(walletKeys).command(message);
2901
+ cli.command(accounts).command(contracts).command(paymasters).command(policies).command(embeddedWallet).command(sponsorship).command(sessions).command(subscriptions).command(transactions).command(users).command(backendWallet).command(message);
2879
2902
  var cli_default = cli;
2880
2903
  export {
2881
2904
  cli_default as default
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@openfort/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Openfort CLI — manage wallets, policies, and transactions from the terminal.",
5
5
  "author": "Openfort (https://www.openfort.io)",
6
6
  "bugs": "https://github.com/openfort-xyz/cli/issues",
7
7
  "homepage": "https://github.com/openfort-xyz/cli#readme",
8
- "repository": "github.com/openfort-xyz/cli.git",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "https://github.com/openfort-xyz/cli"
11
+ },
9
12
  "type": "module",
10
13
  "bin": {
11
14
  "openfort": "./dist/bin.js",
@@ -31,6 +34,7 @@
31
34
  "scripts": {
32
35
  "dev": "node --import tsx src/bin.ts",
33
36
  "build": "tsup",
37
+ "gen": "pnpm build && incur gen --entry ./dist/cli.js",
34
38
  "openfort": "node --import tsx src/bin.ts",
35
39
  "skills": "pnpm openfort skills add",
36
40
  "changeset": "changeset",