@openfort/cli 0.1.3 → 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 +139 -121
  3. package/package.json +8 -3
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,7 +5,8 @@ import {
5
5
  } from "./chunk-QJGHQ7ID.js";
6
6
 
7
7
  // src/cli.ts
8
- import { Cli as Cli12, z as z14, Errors as Errors4 } from "incur";
8
+ import { readFileSync as readFileSync2 } from "fs";
9
+ import { Cli as Cli13, z as z15, Errors as Errors4 } from "incur";
9
10
  import Openfort from "@openfort/openfort-node";
10
11
 
11
12
  // src/vars.ts
@@ -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 },
@@ -397,35 +407,6 @@ evm.command("get", {
397
407
  });
398
408
  }
399
409
  });
400
- evm.command("sign", {
401
- description: "Sign data with an EVM backend wallet.",
402
- args: z3.object({
403
- id: z3.string().describe("Account ID (acc_...)")
404
- }),
405
- options: z3.object({
406
- data: z3.string().describe("Data to sign (hex-encoded)")
407
- }),
408
- alias: { data: "d" },
409
- output: z3.object({
410
- account: z3.string(),
411
- signature: z3.string()
412
- }),
413
- examples: [
414
- {
415
- args: { id: "acc_abc123" },
416
- options: { data: "0x1234abcd" },
417
- description: "Sign a message hash with a backend wallet"
418
- }
419
- ],
420
- async run(c) {
421
- requireWalletCredentials();
422
- const signature = await c.var.openfort.accounts.evm.backend.sign({
423
- id: c.args.id,
424
- data: c.options.data
425
- });
426
- return c.ok({ account: c.args.id, signature });
427
- }
428
- });
429
410
  evm.command("delete", {
430
411
  description: "Delete an EVM backend wallet.",
431
412
  args: z3.object({
@@ -450,7 +431,7 @@ evm.command("update", {
450
431
  }),
451
432
  options: z3.object({
452
433
  chainId: z3.number().describe("Chain ID to deploy on"),
453
- implementationType: z3.string().describe("Smart account implementation type we will update to")
434
+ implementationType: z3.string().describe("Target implementation type (e.g. CaliburV9)")
454
435
  }),
455
436
  examples: [
456
437
  { args: { id: "acc_1a2b3c4d" }, options: { chainId: 8453, implementationType: "CaliburV9" }, description: "Upgrade to delegated account on Base" }
@@ -482,7 +463,7 @@ evm.command("update", {
482
463
  cta: {
483
464
  description: "Next steps:",
484
465
  commands: [
485
- { 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" }
486
467
  ]
487
468
  }
488
469
  }
@@ -500,11 +481,12 @@ evm.command("sign", {
500
481
  examples: [
501
482
  { args: { id: "acc_1a2b3c4d" }, options: { data: "0xdeadbeef" }, description: "Sign a message hash" }
502
483
  ],
484
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
485
+ middleware: [requireWallet],
503
486
  output: z3.object({
504
487
  signature: z3.string()
505
488
  }),
506
489
  async run(c) {
507
- requireWalletCredentials();
508
490
  const signature = await c.var.openfort.accounts.evm.backend.sign({
509
491
  id: c.args.id,
510
492
  data: c.options.data
@@ -520,13 +502,14 @@ evm.command("import", {
520
502
  examples: [
521
503
  { options: { privateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" }, description: "Import a private key" }
522
504
  ],
505
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
506
+ middleware: [requireWallet],
523
507
  output: z3.object({
524
508
  id: z3.string(),
525
509
  address: z3.string(),
526
510
  custody: z3.string()
527
511
  }),
528
512
  async run(c) {
529
- requireWalletCredentials();
530
513
  const account = await c.var.openfort.accounts.evm.backend.import({
531
514
  privateKey: c.options.privateKey
532
515
  });
@@ -545,11 +528,11 @@ evm.command("export", {
545
528
  examples: [
546
529
  { args: { id: "acc_1a2b3c4d" }, description: "Export private key" }
547
530
  ],
531
+ middleware: [requireWallet],
548
532
  output: z3.object({
549
533
  privateKey: z3.string()
550
534
  }),
551
535
  async run(c) {
552
- requireWalletCredentials();
553
536
  const privateKey = await c.var.openfort.accounts.evm.backend.export({
554
537
  id: c.args.id
555
538
  });
@@ -564,7 +547,7 @@ evm.command("send-transaction", {
564
547
  options: z3.object({
565
548
  chainId: z3.number().describe("Chain ID"),
566
549
  interactions: z3.string().describe('Interactions as JSON: [{"to":"0x...","data":"0x...","value":"0"}]'),
567
- policy: z3.string().optional().describe("Policy ID for gas sponsorship (pol_...)")
550
+ policy: z3.string().optional().describe("Fee sponsorship ID (pol_...)")
568
551
  }),
569
552
  examples: [
570
553
  {
@@ -576,6 +559,7 @@ evm.command("send-transaction", {
576
559
  description: "Send a gasless transaction on Base"
577
560
  }
578
561
  ],
562
+ middleware: [requireWallet],
579
563
  output: z3.object({
580
564
  id: z3.string(),
581
565
  chainId: z3.number(),
@@ -604,15 +588,16 @@ var solana = Cli.create("solana", {
604
588
  solana.command("create", {
605
589
  description: "Create a new Solana backend wallet.",
606
590
  examples: [
607
- { description: "Create a new Solana wallet" }
591
+ { description: "Create a new Solana backend wallet (developer custody)" }
608
592
  ],
593
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
594
+ middleware: [requireWallet],
609
595
  output: z3.object({
610
596
  id: z3.string().describe("Account ID"),
611
597
  address: z3.string().describe("Wallet address"),
612
598
  custody: z3.string().describe("Custody type")
613
599
  }),
614
600
  async run(c) {
615
- requireWalletCredentials();
616
601
  const account = await c.var.openfort.accounts.solana.backend.create();
617
602
  return c.ok(
618
603
  { id: account.id, address: account.address, custody: account.custody },
@@ -691,6 +676,8 @@ solana.command("sign", {
691
676
  data: z3.string().describe("Data to sign (base64-encoded)")
692
677
  }),
693
678
  alias: { data: "d" },
679
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
680
+ middleware: [requireWallet],
694
681
  output: z3.object({
695
682
  account: z3.string(),
696
683
  signature: z3.string()
@@ -703,7 +690,6 @@ solana.command("sign", {
703
690
  }
704
691
  ],
705
692
  async run(c) {
706
- requireWalletCredentials();
707
693
  const signature = await c.var.openfort.accounts.solana.backend.sign(c.args.id, c.options.data);
708
694
  return c.ok({ account: c.args.id, signature });
709
695
  }
@@ -725,26 +711,6 @@ solana.command("delete", {
725
711
  return c.ok({ id: res.id, deleted: res.deleted });
726
712
  }
727
713
  });
728
- solana.command("sign", {
729
- description: "Sign data with a Solana backend wallet.",
730
- args: z3.object({
731
- id: z3.string().describe("Account ID (acc_...)")
732
- }),
733
- options: z3.object({
734
- data: z3.string().describe("Data to sign")
735
- }),
736
- examples: [
737
- { args: { id: "acc_1a2b3c4d" }, options: { data: "hello" }, description: "Sign a message" }
738
- ],
739
- output: z3.object({
740
- signature: z3.string()
741
- }),
742
- async run(c) {
743
- requireWalletCredentials();
744
- const signature = await c.var.openfort.accounts.solana.backend.sign(c.args.id, c.options.data);
745
- return c.ok({ signature });
746
- }
747
- });
748
714
  solana.command("import", {
749
715
  description: "Import a private key as a Solana backend wallet.",
750
716
  options: z3.object({
@@ -753,13 +719,14 @@ solana.command("import", {
753
719
  examples: [
754
720
  { options: { privateKey: "abc123..." }, description: "Import a Solana private key" }
755
721
  ],
722
+ hint: "Requires OPENFORT_WALLET_SECRET and OPENFORT_PUBLISHABLE_KEY.",
723
+ middleware: [requireWallet],
756
724
  output: z3.object({
757
725
  id: z3.string(),
758
726
  address: z3.string(),
759
727
  custody: z3.string()
760
728
  }),
761
729
  async run(c) {
762
- requireWalletCredentials();
763
730
  const account = await c.var.openfort.accounts.solana.backend.import({
764
731
  privateKey: c.options.privateKey
765
732
  });
@@ -778,11 +745,11 @@ solana.command("export", {
778
745
  examples: [
779
746
  { args: { id: "acc_1a2b3c4d" }, description: "Export private key" }
780
747
  ],
748
+ middleware: [requireWallet],
781
749
  output: z3.object({
782
750
  privateKey: z3.string()
783
751
  }),
784
752
  async run(c) {
785
- requireWalletCredentials();
786
753
  const privateKey = await c.var.openfort.accounts.solana.backend.export({
787
754
  id: c.args.id
788
755
  });
@@ -812,6 +779,7 @@ solana.command("transfer", {
812
779
  description: "Transfer 1 USDC on devnet"
813
780
  }
814
781
  ],
782
+ middleware: [requireWallet],
815
783
  output: z3.object({
816
784
  signature: z3.string()
817
785
  }),
@@ -953,7 +921,7 @@ contracts.command("create", {
953
921
  description: "Register USDC on Polygon"
954
922
  },
955
923
  {
956
- 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"}]' },
957
925
  description: "Register contract with ABI"
958
926
  }
959
927
  ],
@@ -1138,7 +1106,7 @@ paymasters.command("update", {
1138
1106
  id: z5.string().describe("Paymaster ID (pay_...)")
1139
1107
  }),
1140
1108
  options: z5.object({
1141
- address: z5.string().describe("Paymaster address"),
1109
+ address: z5.string().optional().describe("Paymaster address"),
1142
1110
  name: z5.string().optional().describe("New name"),
1143
1111
  url: z5.string().optional().describe("New URL")
1144
1112
  }),
@@ -1183,7 +1151,7 @@ paymasters.command("delete", {
1183
1151
  import { Cli as Cli4, z as z6 } from "incur";
1184
1152
  var policyScopes = ["project", "account", "transaction"];
1185
1153
  var policies = Cli4.create("policies", {
1186
- description: "Manage access-control policies.",
1154
+ description: "Manage rules and conditions for backend wallets and fee sponsorship.",
1187
1155
  vars: varsSchema
1188
1156
  });
1189
1157
  policies.command("list", {
@@ -1256,6 +1224,14 @@ policies.command("create", {
1256
1224
  rules: '[{"action":"accept","operation":"sponsorEvmTransaction","criteria":[{"type":"evmNetwork","operator":"in","chainIds":[137]}]}]'
1257
1225
  },
1258
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"
1259
1235
  }
1260
1236
  ],
1261
1237
  async run(c) {
@@ -1430,7 +1406,7 @@ var sponsorshipItem = z7.object({
1430
1406
  policyId: z7.string().nullable()
1431
1407
  });
1432
1408
  var sponsorship = Cli5.create("sponsorship", {
1433
- description: "Manage fee sponsorships for gas costs.",
1409
+ description: "Manage fee sponsorship strategies linked to policies.",
1434
1410
  vars: varsSchema
1435
1411
  });
1436
1412
  sponsorship.command("list", {
@@ -1966,7 +1942,7 @@ sessions.command("create", {
1966
1942
  player: z9.string().optional().describe("Player ID (pla_...)"),
1967
1943
  account: z9.string().optional().describe("Account ID (acc_...)"),
1968
1944
  limit: z9.number().optional().describe("Max session uses"),
1969
- policy: z9.string().optional().describe("Policy ID for gas sponsorship (pol_...)"),
1945
+ policy: z9.string().optional().describe("Policy ID (ply_...) for gas sponsorship"),
1970
1946
  whitelist: z9.string().optional().describe("Whitelisted contract addresses as JSON array")
1971
1947
  }),
1972
1948
  examples: [
@@ -2047,7 +2023,7 @@ sessions.command("revoke", {
2047
2023
  address: z9.string().describe("Session key address to revoke"),
2048
2024
  chainId: z9.number().describe("Chain ID"),
2049
2025
  player: z9.string().optional().describe("Player ID (pla_...)"),
2050
- policy: z9.string().optional().describe("Policy ID (pol_...)")
2026
+ policy: z9.string().optional().describe("Policy ID (ply_...) for gas sponsorship")
2051
2027
  }),
2052
2028
  examples: [
2053
2029
  { options: { address: "0x1234...", chainId: 137 }, description: "Revoke a session key" }
@@ -2182,7 +2158,7 @@ transactions.command("create", {
2182
2158
  account: z10.string().describe("Account ID (acc_...)"),
2183
2159
  chainId: z10.number().describe("Chain ID"),
2184
2160
  interactions: z10.string().describe('Interactions as JSON: [{"to":"0x...","data":"0x...","value":"0"}]'),
2185
- policy: z10.string().optional().describe("Policy ID for gas sponsorship"),
2161
+ policy: z10.string().optional().describe("Policy ID (ply_...) for gas sponsorship"),
2186
2162
  signedAuthorization: z10.string().optional().describe("Signed EIP-7702 authorization hex (for delegated accounts)")
2187
2163
  }),
2188
2164
  output: transactionIntentItem,
@@ -2200,9 +2176,9 @@ transactions.command("create", {
2200
2176
  account: "acc_1a2b3c4d",
2201
2177
  chainId: 137,
2202
2178
  interactions: '[{"to":"0x742d35Cc6634C0532925a3b844Bc9e7595f92cD5","value":"1000000000000000000"}]',
2203
- policy: "ply_1a2b3c4d"
2179
+ policy: "pol_1a2b3c4d"
2204
2180
  },
2205
- description: "Send 1 MATIC with gas sponsorship"
2181
+ description: "Send 1 POL with gas sponsorship"
2206
2182
  }
2207
2183
  ],
2208
2184
  async run(c) {
@@ -2309,7 +2285,7 @@ transactions.command("estimate", {
2309
2285
  account: z10.string().describe("Account ID (acc_...)"),
2310
2286
  chainId: z10.number().describe("Chain ID"),
2311
2287
  interactions: z10.string().describe("Interactions as JSON"),
2312
- policy: z10.string().optional().describe("Policy ID for gas sponsorship")
2288
+ policy: z10.string().optional().describe("Fee sponsorship ID (pol_...) for gas sponsorship")
2313
2289
  }),
2314
2290
  examples: [
2315
2291
  {
@@ -2342,15 +2318,15 @@ transactions.command("estimate", {
2342
2318
  }
2343
2319
  });
2344
2320
 
2345
- // src/commands/shield.ts
2321
+ // src/commands/embedded-wallet.ts
2346
2322
  import { Cli as Cli9, z as z11, Errors as Errors2 } from "incur";
2347
2323
  var SHIELD_API_URL = OPENFORT_SHIELD_URL;
2348
- var shield = Cli9.create("shield", {
2349
- description: "Manage Shield (embedded wallet) API keys.",
2324
+ var embeddedWallet = Cli9.create("embedded-wallet", {
2325
+ description: "Configure embedded wallet (Shield) API keys.",
2350
2326
  vars: varsSchema
2351
2327
  });
2352
- shield.command("create", {
2353
- description: "Create Shield API keys for embedded wallets.",
2328
+ embeddedWallet.command("setup", {
2329
+ description: "Generate and register embedded wallet (Shield) API keys.",
2354
2330
  options: z11.object({
2355
2331
  project: z11.string().optional().describe("Project ID (pro_...). Defaults to OPENFORT_PROJECT_ID env var.")
2356
2332
  }),
@@ -2362,9 +2338,10 @@ shield.command("create", {
2362
2338
  examples: [
2363
2339
  {
2364
2340
  options: { project: "pro_abc123" },
2365
- description: "Create Shield keys for a project"
2341
+ description: "Set up embedded wallet keys for a project"
2366
2342
  }
2367
2343
  ],
2344
+ hint: 'Requires OPENFORT_PUBLISHABLE_KEY and OPENFORT_PROJECT_ID. Run "openfort login" first.',
2368
2345
  async run(c) {
2369
2346
  const publishableKey = process.env.OPENFORT_PUBLISHABLE_KEY;
2370
2347
  if (!publishableKey) {
@@ -2400,7 +2377,8 @@ shield.command("create", {
2400
2377
  const text = await registerRes.text();
2401
2378
  throw new Errors2.IncurError({
2402
2379
  code: "SHIELD_REGISTER_FAILED",
2403
- message: `Shield registration failed: ${text}`
2380
+ message: `Shield registration failed: ${text}`,
2381
+ retryable: true
2404
2382
  });
2405
2383
  }
2406
2384
  const shieldData = await registerRes.json();
@@ -2423,7 +2401,8 @@ shield.command("create", {
2423
2401
  const text = await res.text();
2424
2402
  throw new Errors2.IncurError({
2425
2403
  code: "PERSIST_KEY_FAILED",
2426
- message: `Failed to persist ${type} key: ${text}`
2404
+ message: `Failed to persist ${type} key: ${text}`,
2405
+ retryable: true
2427
2406
  });
2428
2407
  }
2429
2408
  };
@@ -2450,7 +2429,8 @@ shield.command("create", {
2450
2429
  const text = await linkRes.text();
2451
2430
  throw new Errors2.IncurError({
2452
2431
  code: "SHIELD_LINK_FAILED",
2453
- message: `Failed to link Openfort provider to Shield: ${text}`
2432
+ message: `Failed to link Openfort provider to Shield: ${text}`,
2433
+ retryable: true
2454
2434
  });
2455
2435
  }
2456
2436
  ensureConfigDir();
@@ -2458,7 +2438,7 @@ shield.command("create", {
2458
2438
  writeEnvKey(CREDENTIALS_PATH, "SHIELD_SECRET_KEY", shieldData.api_secret);
2459
2439
  writeEnvKey(CREDENTIALS_PATH, "SHIELD_ENCRYPTION_SHARE", shieldData.encryption_part);
2460
2440
  return c.ok(
2461
- { 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 },
2462
2442
  {
2463
2443
  cta: {
2464
2444
  description: "Next steps:",
@@ -2580,7 +2560,7 @@ users.command("delete", {
2580
2560
  }
2581
2561
  });
2582
2562
 
2583
- // src/commands/wallet-keys.ts
2563
+ // src/commands/backend-wallet.ts
2584
2564
  import { randomBytes as randomBytes2, subtle } from "crypto";
2585
2565
  import { Cli as Cli11, z as z13, Errors as Errors3 } from "incur";
2586
2566
  function arrayBufferToBase64(buffer) {
@@ -2652,21 +2632,22 @@ async function signWalletAuthJwt(privateKey, method, path, body) {
2652
2632
  );
2653
2633
  return `${signingInput}.${arrayBufferToBase64Url(signature)}`;
2654
2634
  }
2655
- var walletKeys = Cli11.create("wallet-keys", {
2656
- description: "Manage backend wallet keys.",
2635
+ var backendWallet = Cli11.create("backend-wallet", {
2636
+ description: "Configure backend wallet signing keys.",
2657
2637
  vars: varsSchema
2658
2638
  });
2659
- walletKeys.command("create", {
2660
- description: "Create backend wallet keys (ECDSA P-256).",
2639
+ backendWallet.command("setup", {
2640
+ description: "Generate and register backend wallet signing keys (ECDSA P-256).",
2661
2641
  output: z13.object({
2662
2642
  message: z13.string(),
2663
2643
  credentialsPath: z13.string()
2664
2644
  }),
2665
2645
  examples: [
2666
2646
  {
2667
- description: "Create backend wallet keys and save to credentials"
2647
+ description: "Set up backend wallet signing keys and save to credentials"
2668
2648
  }
2669
2649
  ],
2650
+ hint: 'Requires OPENFORT_API_KEY. Run "openfort login" first.',
2670
2651
  async run(c) {
2671
2652
  const apiKey = process.env.OPENFORT_API_KEY;
2672
2653
  const { publicKey, privateKey, privateKeyCrypto } = await generateKeyPair();
@@ -2692,7 +2673,8 @@ ${publicKey}
2692
2673
  const text = await registerRes.text();
2693
2674
  throw new Errors3.IncurError({
2694
2675
  code: "REGISTER_SECRET_FAILED",
2695
- message: `Failed to register wallet secret: ${text}`
2676
+ message: `Failed to register wallet secret: ${text}`,
2677
+ retryable: true
2696
2678
  });
2697
2679
  }
2698
2680
  const storeRes = await fetch(`${API_BASE_URL}/v1/project/apikey`, {
@@ -2707,7 +2689,8 @@ ${publicKey}
2707
2689
  const text = await storeRes.text();
2708
2690
  throw new Errors3.IncurError({
2709
2691
  code: "STORE_KEY_FAILED",
2710
- message: `Failed to store wallet key reference: ${text}`
2692
+ message: `Failed to store wallet key reference: ${text}`,
2693
+ retryable: true
2711
2694
  });
2712
2695
  }
2713
2696
  ensureConfigDir();
@@ -2720,15 +2703,15 @@ ${publicKey}
2720
2703
  cta: {
2721
2704
  description: "Next steps:",
2722
2705
  commands: [
2723
- { command: `shield create`, description: "Create and save Shield API keys" }
2706
+ { command: `embedded-wallet setup`, description: "Set up embedded wallet keys" }
2724
2707
  ]
2725
2708
  }
2726
2709
  }
2727
2710
  );
2728
2711
  }
2729
2712
  });
2730
- walletKeys.command("revoke", {
2731
- description: "Revoke the current backend wallet secret.",
2713
+ backendWallet.command("revoke", {
2714
+ description: "Revoke the current backend wallet signing secret.",
2732
2715
  output: z13.object({
2733
2716
  keyId: z13.string(),
2734
2717
  revoked: z13.boolean(),
@@ -2739,6 +2722,7 @@ walletKeys.command("revoke", {
2739
2722
  description: "Revoke the current wallet secret"
2740
2723
  }
2741
2724
  ],
2725
+ hint: 'Requires OPENFORT_WALLET_KEY_ID and OPENFORT_WALLET_SECRET. Run "openfort backend-wallet setup" first.',
2742
2726
  async run(c) {
2743
2727
  const apiKey = process.env.OPENFORT_API_KEY;
2744
2728
  const keyId = process.env.OPENFORT_WALLET_KEY_ID;
@@ -2746,7 +2730,8 @@ walletKeys.command("revoke", {
2746
2730
  if (!keyId || !privateKeyBase64) {
2747
2731
  throw new Errors3.IncurError({
2748
2732
  code: "MISSING_WALLET_KEY",
2749
- 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"
2750
2735
  });
2751
2736
  }
2752
2737
  const privateKeyCrypto = await importPrivateKey(privateKeyBase64);
@@ -2766,15 +2751,16 @@ walletKeys.command("revoke", {
2766
2751
  const text = await res.text();
2767
2752
  throw new Errors3.IncurError({
2768
2753
  code: "REVOKE_SECRET_FAILED",
2769
- message: `Failed to revoke wallet secret: ${text}`
2754
+ message: `Failed to revoke wallet secret: ${text}`,
2755
+ retryable: true
2770
2756
  });
2771
2757
  }
2772
2758
  const data = await res.json();
2773
2759
  return c.ok(data);
2774
2760
  }
2775
2761
  });
2776
- walletKeys.command("rotate", {
2777
- 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).",
2778
2764
  output: z13.object({
2779
2765
  message: z13.string(),
2780
2766
  credentialsPath: z13.string()
@@ -2784,6 +2770,7 @@ walletKeys.command("rotate", {
2784
2770
  description: "Rotate wallet secret and save new keys to credentials"
2785
2771
  }
2786
2772
  ],
2773
+ hint: 'Requires OPENFORT_API_KEY. Run "openfort login" first.',
2787
2774
  async run(c) {
2788
2775
  const apiKey = process.env.OPENFORT_API_KEY;
2789
2776
  const { publicKey, privateKey, privateKeyCrypto } = await generateKeyPair();
@@ -2809,7 +2796,8 @@ ${publicKey}
2809
2796
  const text = await rotateRes.text();
2810
2797
  throw new Errors3.IncurError({
2811
2798
  code: "ROTATE_SECRET_FAILED",
2812
- message: `Failed to rotate wallet secret: ${text}`
2799
+ message: `Failed to rotate wallet secret: ${text}`,
2800
+ retryable: true
2813
2801
  });
2814
2802
  }
2815
2803
  const storeRes = await fetch(`${API_BASE_URL}/v1/project/apikey`, {
@@ -2824,7 +2812,8 @@ ${publicKey}
2824
2812
  const text = await storeRes.text();
2825
2813
  throw new Errors3.IncurError({
2826
2814
  code: "STORE_KEY_FAILED",
2827
- message: `Failed to store rotated wallet key reference: ${text}`
2815
+ message: `Failed to store rotated wallet key reference: ${text}`,
2816
+ retryable: true
2828
2817
  });
2829
2818
  }
2830
2819
  ensureConfigDir();
@@ -2835,27 +2824,56 @@ ${publicKey}
2835
2824
  }
2836
2825
  });
2837
2826
 
2827
+ // src/commands/message.ts
2828
+ import { Cli as Cli12, z as z14 } from "incur";
2829
+ import { keccak256, toBytes } from "viem";
2830
+ var message = Cli12.create("message", {
2831
+ description: "Message utilities.",
2832
+ vars: varsSchema
2833
+ });
2834
+ message.command("hash", {
2835
+ description: "Hash a message using keccak256.",
2836
+ args: z14.object({
2837
+ message: z14.string().describe("The message to hash")
2838
+ }),
2839
+ examples: [
2840
+ { args: { message: "Hello World" }, description: "Hash a message" }
2841
+ ],
2842
+ output: z14.object({
2843
+ hash: z14.string()
2844
+ }),
2845
+ async run(c) {
2846
+ const hash = keccak256(toBytes(c.args.message));
2847
+ return c.ok({ hash });
2848
+ }
2849
+ });
2850
+
2838
2851
  // src/cli.ts
2839
- var cli = Cli12.create("openfort", {
2840
- version: "0.1.0",
2841
- 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",
2852
+ var pkg = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf-8"));
2853
+ var cli = Cli13.create("openfort", {
2854
+ version: pkg.version,
2855
+ aliases: ["of"],
2856
+ description: "Openfort CLI \u2014 manage wallets, policies, and transactions from the terminal.",
2842
2857
  vars: varsSchema,
2843
- env: z14.object({
2844
- OPENFORT_API_KEY: z14.string().optional().describe("Openfort secret API key (sk_test_... or sk_live_...)"),
2845
- OPENFORT_WALLET_SECRET: z14.string().optional().describe("Wallet encryption secret"),
2846
- OPENFORT_PUBLISHABLE_KEY: z14.string().optional().describe("Publishable key for client-side ops"),
2847
- OPENFORT_BASE_URL: z14.string().optional().describe("Custom API base URL")
2858
+ env: z15.object({
2859
+ OPENFORT_API_KEY: z15.string().optional().describe("Openfort secret API key (sk_test_... or sk_live_...)"),
2860
+ OPENFORT_WALLET_SECRET: z15.string().optional().describe("Wallet encryption secret"),
2861
+ OPENFORT_PUBLISHABLE_KEY: z15.string().optional().describe("Publishable key for client-side ops"),
2862
+ OPENFORT_BASE_URL: z15.string().optional().describe("Custom API base URL")
2848
2863
  }),
2849
2864
  sync: {
2850
2865
  depth: 2,
2851
- include: ["accounts", "transactions", "policies", "sponsorship", "contracts", "users", "sessions", "subscriptions"],
2866
+ include: ["_root", "accounts", "transactions", "policies", "sponsorship", "contracts", "users", "sessions", "subscriptions", "backend-wallet", "embedded-wallet"],
2852
2867
  suggestions: [
2853
2868
  "create an EVM backend wallet",
2854
2869
  "list all accounts",
2855
- "create a gas sponsorship policy",
2870
+ "create a policy for gas sponsorship",
2856
2871
  "list users",
2857
2872
  "estimate transaction gas cost"
2858
2873
  ]
2874
+ },
2875
+ mcp: {
2876
+ agents: ["claude-code", "cursor", "amp"]
2859
2877
  }
2860
2878
  });
2861
2879
  cli.command("login", loginConfig);
@@ -2880,7 +2898,7 @@ cli.use(async (c, next) => {
2880
2898
  }));
2881
2899
  await next();
2882
2900
  });
2883
- cli.command(accounts).command(contracts).command(paymasters).command(policies).command(shield).command(sponsorship).command(sessions).command(subscriptions).command(transactions).command(users).command(walletKeys);
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);
2884
2902
  var cli_default = cli;
2885
2903
  export {
2886
2904
  cli_default as default
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "@openfort/cli",
3
- "version": "0.1.3",
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",
@@ -17,7 +20,8 @@
17
20
  "main": "./dist/cli.js",
18
21
  "dependencies": {
19
22
  "@openfort/openfort-node": "^0.10.2",
20
- "incur": "^0.3.2"
23
+ "incur": "^0.3.2",
24
+ "viem": "^2.47.2"
21
25
  },
22
26
  "devDependencies": {
23
27
  "@changesets/changelog-github": "^0.5.1",
@@ -30,6 +34,7 @@
30
34
  "scripts": {
31
35
  "dev": "node --import tsx src/bin.ts",
32
36
  "build": "tsup",
37
+ "gen": "pnpm build && incur gen --entry ./dist/cli.js",
33
38
  "openfort": "node --import tsx src/bin.ts",
34
39
  "skills": "pnpm openfort skills add",
35
40
  "changeset": "changeset",