@fased/fased 0.1.68 → 0.1.69

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 (103) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +20 -22
  3. package/config/sat-runtime.env +6 -2
  4. package/config/signer-protocol-v2.json +6 -0
  5. package/dist/agents/tools/wallet-action-tool.js +2 -0
  6. package/dist/agents/tools/wallet-tool.js +5 -3
  7. package/dist/brand.js +1 -1
  8. package/dist/build-info.json +3 -3
  9. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  10. package/dist/cli/program/register.wallet.js +88 -5
  11. package/dist/commands/wallet.js +842 -57
  12. package/dist/config/sat-runtime-ids.js +6 -1
  13. package/dist/control-ui/assets/{app-DyPTS0oM.js → app-BLFLoFPk.js} +8 -8
  14. package/dist/control-ui/assets/{federation-DgA9e-Pn.js → federation-SGMAnM_8.js} +2 -2
  15. package/dist/control-ui/assets/{index-Cu13yYHr.js → index-S88kp5ZQ.js} +3 -3
  16. package/dist/control-ui/assets/{mining-Dg-3ll0F.js → mining-ClI8RW4u.js} +2 -2
  17. package/dist/control-ui/assets/{wallet-ByKBcYhm.js → wallet-CRIhDQbW.js} +201 -116
  18. package/dist/control-ui/index.html +1 -1
  19. package/dist/control-ui/version.json +1 -1
  20. package/dist/gateway/server-http.js +46 -9
  21. package/dist/mining/mainnet-sync.js +67 -5
  22. package/dist/operator/operator-readiness.js +1 -1
  23. package/dist/plugin-sdk/{audio-preflight-_FVQjR1r.js → audio-preflight-CS7Q_7-R.js} +2 -2
  24. package/dist/plugin-sdk/channel-plugin-common.d.ts +2 -2
  25. package/dist/plugin-sdk/{chunk-items-LH4uKSnh.js → chunk-items-BLBZNORg.js} +1 -1
  26. package/dist/plugin-sdk/command-status.js +2 -2
  27. package/dist/plugin-sdk/{config-schema-DjU_uD-6.js → config-schema-BiBOUW89.js} +255 -47
  28. package/dist/plugin-sdk/device-pair.d.ts +1 -1
  29. package/dist/plugin-sdk/discord.d.ts +4 -4
  30. package/dist/plugin-sdk/index.d.ts +16 -16
  31. package/dist/plugin-sdk/index.js +2 -2
  32. package/dist/plugin-sdk/{monitor-DUMMbG4h.js → monitor-WXdn4mR-.js} +4 -4
  33. package/dist/plugin-sdk/{monitor-DXIM16Hj.js → monitor-xzVAPbg2.js} +6 -6
  34. package/dist/plugin-sdk/{openresponses-http-C8lKwta1.js → openresponses-http-DnI1LFgq.js} +2 -2
  35. package/dist/plugin-sdk/{pairing-message-mKO92L-M.d.ts → pairing-message-CiTcdD6m.d.ts} +1 -1
  36. package/dist/plugin-sdk/provider-web-search-config-contract.d.ts +1 -1
  37. package/dist/plugin-sdk/{pw-ai-DJ_gTc4M.js → pw-ai-DZYLDC-S.js} +1 -1
  38. package/dist/plugin-sdk/{runtime-dependency-nup8niQL.js → runtime-dependency-DczkvPxn.js} +9 -9
  39. package/dist/plugin-sdk/sat-runtime.d.ts +89 -10
  40. package/dist/plugin-sdk/sat-runtime.js +2 -2
  41. package/dist/plugin-sdk/{slack-B-nOOLM0.js → slack-CkIRVDUK.js} +4 -4
  42. package/dist/plugin-sdk/slack.d.ts +4 -4
  43. package/dist/plugin-sdk/{sticker-cache-BLiId8Em.js → sticker-cache-Dpap5ce_.js} +2 -2
  44. package/dist/plugin-sdk/{telegram-actions-1X9A32Dn.js → telegram-actions-Cewdga8H.js} +3 -3
  45. package/dist/plugin-sdk/telegram.d.ts +4 -4
  46. package/dist/plugin-sdk/{tmp-fased-dir-BkpWlGUe.d.ts → tmp-fased-dir-BSEHc8MQ.d.ts} +2 -2
  47. package/dist/plugin-sdk/{types-DtCOO_hW.d.ts → types-BakzIzGN.d.ts} +1 -1
  48. package/dist/plugin-sdk/{types-B-zL9gSv.d.ts → types-CzF0YQqK.d.ts} +2 -2
  49. package/dist/plugin-sdk/{web-BvjNyYBz.js → web-DGWi7i3B.js} +2 -2
  50. package/dist/plugin-sdk/whatsapp.d.ts +9 -9
  51. package/dist/plugin-sdk/{zod-schema.providers-core-BCDlgtls.d.ts → zod-schema.providers-core-CIzCjXH9.d.ts} +63 -63
  52. package/dist/wallet/local-socket-signer-lifecycle.js +79 -3
  53. package/dist/wallet/local-socket-signer-protocol.js +70 -10
  54. package/dist/wallet/mining-wallet-retirement.js +256 -0
  55. package/dist/wallet/providers/local-socket-signer-adapter.js +2 -0
  56. package/dist/wallet/signer-protocol-v2.generated.js +6 -0
  57. package/dist/wallet/wallet-agent-selection.js +6 -10
  58. package/dist/wallet/wallet-provider-registry.js +70 -29
  59. package/dist/wallet/wallet-send-approvals.js +6 -2
  60. package/dist/wallet/wallet-status.js +56 -1
  61. package/dist/wizard/onboarding.js +32 -30
  62. package/dist/wizard/onboarding.wallet.js +10 -1
  63. package/extensions/acpx/package.json +1 -1
  64. package/extensions/bluebubbles/package.json +1 -1
  65. package/extensions/copilot-proxy/package.json +1 -1
  66. package/extensions/diagnostics-otel/package.json +1 -1
  67. package/extensions/fased-federation/package.json +1 -1
  68. package/extensions/google-gemini-cli-auth/package.json +1 -1
  69. package/extensions/imessage/package.json +1 -1
  70. package/extensions/irc/package.json +1 -1
  71. package/extensions/line/package.json +1 -1
  72. package/extensions/llm-task/package.json +1 -1
  73. package/extensions/lobster/package.json +1 -1
  74. package/extensions/matrix/CHANGELOG.md +6 -0
  75. package/extensions/matrix/package.json +1 -1
  76. package/extensions/mattermost/package.json +1 -1
  77. package/extensions/memory-core/package.json +2 -2
  78. package/extensions/memory-lancedb/package.json +1 -1
  79. package/extensions/minimax-portal-auth/package.json +1 -1
  80. package/extensions/msteams/CHANGELOG.md +6 -0
  81. package/extensions/msteams/package.json +1 -1
  82. package/extensions/nextcloud-talk/package.json +1 -1
  83. package/extensions/nostr/CHANGELOG.md +6 -0
  84. package/extensions/nostr/package.json +1 -1
  85. package/extensions/open-prose/package.json +1 -1
  86. package/extensions/sat-mining/package.json +1 -1
  87. package/extensions/signal/package.json +1 -1
  88. package/extensions/synology-chat/package.json +1 -1
  89. package/extensions/tlon/package.json +1 -1
  90. package/extensions/twitch/CHANGELOG.md +6 -0
  91. package/extensions/twitch/package.json +1 -1
  92. package/extensions/voice-call/CHANGELOG.md +6 -0
  93. package/extensions/voice-call/package.json +1 -1
  94. package/extensions/zalo/CHANGELOG.md +6 -0
  95. package/extensions/zalo/package.json +1 -1
  96. package/extensions/zalouser/CHANGELOG.md +6 -0
  97. package/extensions/zalouser/package.json +1 -1
  98. package/install.sh +276 -103
  99. package/package.json +4 -3
  100. package/scripts/install-fased-signerd.sh +4 -8
  101. package/scripts/install-runtime-profile.sh +27 -0
  102. package/scripts/start-managed.sh +13 -1
  103. package/scripts/fased-signer-wallet-import-hosting.sh +0 -78
package/CHANGELOG.md CHANGED
@@ -4,6 +4,21 @@ This changelog starts with the public Fased Agent release line. Required
4
4
  third-party and copied-code notices are kept in [LICENSE](./LICENSE) and
5
5
  [THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md).
6
6
 
7
+ ## 0.1.69
8
+
9
+ - Make new signer-owned Agent, Mining, and Vault wallets role-ready with one
10
+ verified RPC; preserve legacy deny-all wallets until explicit activation.
11
+ - Make Agent wallet routing explicit, then skill-specific, Agent-specific, and
12
+ finally optional Default Agent fallback; creation never selects a fallback.
13
+ - Separate the Hosting operator, Gateway, and signer identities; provide the
14
+ same native wallet lifecycle on Local and Hosting without ordinary root
15
+ helper commands.
16
+ - Add signer-tombstoned, resumable Mining retirement and a distinct role-ready
17
+ successor.
18
+ - Restore the exact fresh streamed Hosting command with verified tagged
19
+ handoff, retain exact-tag-only repair, and reset English/Chinese install and
20
+ wallet documentation around the tested behavior.
21
+
7
22
  ## 0.1.68
8
23
 
9
24
  - Unify signer-owned Agent, Mining, and Vault creation around one explicit role
package/README.md CHANGED
@@ -33,10 +33,10 @@ Public install is repo-backed:
33
33
 
34
34
  ### Local vs VPS Hosting
35
35
 
36
- | Path | Best for | Security posture | Access dependency |
37
- | ------------- | -------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
38
- | Local install | Your own computer: macOS Terminal, Windows with WSL2 Ubuntu, Linux desktop, or dev box | Lowest setup risk. Gateway stays on your machine; a home router usually does not expose it to the public internet. Tailscale is optional. | Your local OS login. |
39
- | VPS Hosting | Always-on cloud node | Higher exposure by default because a VPS is internet-reachable. Hosted setup closes public admin ports and requires Tailscale for private dashboard/SSH access. | Your Tailscale account plus the VPS provider console for emergency recovery. |
36
+ | Path | Runs where | Private access | Normal operator |
37
+ | ----------- | ------------------------------------- | ---------------------------------------- | ------------------------------------------ |
38
+ | Local | macOS, Linux, or WSL2 Ubuntu | Your local OS; Tailscale optional | Your OS account |
39
+ | VPS Hosting | Ubuntu/Fedora/RHEL-family systemd VPS | Tailscale plus provider-console recovery | `app`; Gateway isolated as `fased-gateway` |
40
40
 
41
41
  If you lose access to the Tailscale account used for a hosted VPS, normal
42
42
  dashboard and SSH access can be lost. Recovery then depends on the VPS
@@ -151,8 +151,8 @@ curl -fsSL https://raw.githubusercontent.com/fased-ai/fased/main/install.sh \
151
151
 
152
152
  It selects the stable release and verifies the tagged Hosting artifacts before
153
153
  privileged Fased installation. The
154
- [VPS Hosting guide](https://docs.fased.ai/install/vps#advanced-verify-the-bootstrap-first)
155
- also keeps an advanced procedure for verifying `install.sh` before it runs.
154
+ [Advanced installer](https://docs.fased.ai/install/installer#exact-tag-pre-execution-verification)
155
+ keeps the exact-tag procedure for verifying `install.sh` before it runs.
156
156
 
157
157
  The Fased installer bootstraps the attested hosted runtime itself. A fresh VPS
158
158
  does not need `git clone`; the installer installs the supported system tools and
@@ -161,16 +161,15 @@ exact tagged runtime instead of building an app-owned source checkout.
161
161
  If a minimal VPS image does not have `curl`, use the OS tab in the install docs
162
162
  to install only the downloader first, then rerun the same hosted command.
163
163
 
164
- If an earlier install stopped before creating the `app` runtime, repeat the
165
- same verified tagged bootstrap from the provider root console. Use the
166
- documented `--repair-hosting` path for an existing installation; do not repair
167
- Hosting from a moving `main` checkout.
164
+ If an earlier install stopped before persistent Fased installer state was
165
+ created, fix the reported prerequisite and repeat the same command. Use the
166
+ documented exact-tag `--repair-hosting` path for an existing installation; do
167
+ not repair Hosting from moving `main`.
168
168
 
169
- If you SSH into a fresh VPS as `root`, the installer creates a non-root `app`
170
- user, copies/clones the repo to `/home/app/fased`, and continues there. The
171
- temporary root checkout is removed after successful hosted onboarding. During
172
- Tailscale setup, copy the login URL printed in SSH and open it in your local
173
- computer's browser.
169
+ If you SSH into a fresh VPS as `root`, the installer creates a human `app`
170
+ operator, an isolated `fased-gateway` service account, and an isolated
171
+ `fased-signer` service account. During Tailscale setup, copy the login URL
172
+ printed in SSH and open it in your local computer's browser.
174
173
 
175
174
  The installer adds the VPS to the same Tailscale tailnet before onboarding can
176
175
  finish safely. When Fased prints a Tailscale login URL in the SSH terminal,
@@ -242,9 +241,9 @@ fased dashboard
242
241
  The `app` shell is a full Linux shell on the VPS and is configured to start in
243
242
  `/home/app/fased`.
244
243
 
245
- Hosted VPS setup uses the root-managed `fased-gateway.service`, and that
246
- service runs as the non-root `app` user. It should not ask for the `app`
247
- password to run `sudo loginctl enable-linger app`.
244
+ Hosted VPS setup uses root-managed services. `fased-gateway.service` runs as
245
+ the non-login `fased-gateway` account; the `app` operator uses a separate,
246
+ restricted signer lifecycle socket and does not need broad sudo.
248
247
 
249
248
  `http://localhost:18789` is only the advanced SSH tunnel fallback. It works on
250
249
  your local computer after you start the tunnel shown by onboarding and leave
@@ -319,10 +318,9 @@ git pull --ff-only origin main
319
318
  ./install.sh
320
319
  ```
321
320
 
322
- On a hosted VPS, run that same development checkout flow as `app` from
323
- `/home/app/fased` and use `./install.sh --hosting`. Use
324
- `./install.sh --no-git-update` only when testing local changes that should not
325
- be replaced by Git.
321
+ Privileged Hosting does not install from a mutable developer checkout. Test
322
+ source changes as Local, or build a tagged Hosting artifact through the release
323
+ workflow.
326
324
 
327
325
  Telegram, WhatsApp, Discord, and Slack install as official add-ons only when
328
326
  selected from **Agent > Channels**, onboarding, or `fased channels add`. Local
@@ -2,9 +2,13 @@
2
2
  # Fased Agent writes this file after Mining Sync verifies the signed mainnet
3
3
  # manifest from https://satcoin.app/.well-known/sat-mainnet-addresses.json.
4
4
  #
5
- # For explicit local/devnet testing, set all four values through env or this
6
- # file. Public pre-launch installs intentionally ship without active SAT IDs.
5
+ # Mining role baselines also require the verified manifest, detached signature,
6
+ # and SHA-256 fields written by Mining Sync. Public pre-launch installs
7
+ # intentionally ship without active SAT IDs or manifest authority.
7
8
  FASED_SAT_PROGRAM_ID=
8
9
  FASED_SAT_BOND_PROGRAM_ID=
9
10
  FASED_SAT_MINT_ADDRESS=
10
11
  FASED_SAT_MINT_PROGRAM_ID=
12
+ FASED_SAT_RUNTIME_MANIFEST_PATH=
13
+ FASED_SAT_RUNTIME_MANIFEST_SHA256=
14
+ FASED_SAT_RUNTIME_MANIFEST_SIGNATURE_PATH=
@@ -24,12 +24,16 @@
24
24
  "atomicIdempotency",
25
25
  "ambiguousBroadcastReconciliation",
26
26
  "signerOwnedKeys",
27
+ "signerOwnedRoleBaselines",
28
+ "liveWalletReadiness",
27
29
  "signerOwnedSuccessorRotation",
30
+ "signerOwnedMiningRetirementEvidence",
28
31
  "permanentRetiredWalletPolicies",
29
32
  "signerOwnedRPC",
30
33
  "applicationNetworkBootstrap",
31
34
  "signerOwnedEncryptedRecovery",
32
35
  "signerOwnedRawExport",
36
+ "restrictedOperatorLifecycle",
33
37
  "typedSolanaTransactions",
34
38
  "typedA2aPaymentMemos",
35
39
  "typedA2aRefundMemos",
@@ -65,6 +69,8 @@
65
69
  "atomicIdempotency",
66
70
  "ambiguousBroadcastReconciliation",
67
71
  "signerOwnedKeys",
72
+ "signerOwnedRoleBaselines",
73
+ "liveWalletReadiness",
68
74
  "signerOwnedRPC",
69
75
  "applicationNetworkBootstrap",
70
76
  "typedSolanaTransactions",
@@ -227,11 +227,13 @@ function createWalletActionTool(opts) {
227
227
  const scheduled = action === "schedule_plan";
228
228
  const requesterSkillId = opts?.requesterSkillId?.trim() || null;
229
229
  const permissions = readSkillWalletActionPermissions(cfg, requesterSkillId);
230
+ const skillWalletId = permissions?.walletIds?.length === 1 ? permissions.walletIds[0] : undefined;
230
231
  const selection = resolveAgentWalletSelection({
231
232
  config: cfg,
232
233
  walletHandle,
233
234
  walletId,
234
235
  agentId: requesterAgentId ?? ownerAgentId ?? undefined,
236
+ skillWalletId,
235
237
  env: process.env
236
238
  });
237
239
  const rpcUrl = resolveScopedRpcUrlForWallet({
@@ -348,7 +348,7 @@ function createWalletTool(opts) {
348
348
  return {
349
349
  label: "Wallet",
350
350
  name: "wallet",
351
- description: "Query wallet status/list/balance/assets/address and prepare/send policy-limited Solana transactions via configured wallet provider. If the user asks for one exact @wallet handle or one external Solana address, call only that exact read action; do not also call balances/list. Use action=\"list\" to list local wallets with handles and action=\"balances\" only when the user asks for every/all local wallet balances. Use walletHandle=\"@wallet:<walletId>\" to select exact local wallets for read-only balance/assets/status/address and risky actions. Use action=\"assets\" for all visible Solana native and SPL balances, or address=\"<solana-address>\" for read-only external Solana balance/assets. For address/balance reads, omit chain when the user does not specify it; the tool returns the available Solana address or balance set. Risky prepare/send actions require an Agent wallet via walletHandle, structured walletId, or default Agent wallet. For normal SOL amounts such as 0.1, pass amountFormat=\"human\"; decimal amounts without amountFormat are treated as human units. Destination wallet handles like @wallet:vault are resolved to receive addresses.",
351
+ description: "Query wallet status/list/balance/assets/address and prepare/send policy-limited Solana transactions via configured wallet provider. If the user asks for one exact @wallet handle or one external Solana address, call only that exact read action; do not also call balances/list. Use action=\"list\" to list local wallets with handles and action=\"balances\" only when the user asks for every/all local wallet balances. Use walletHandle=\"@wallet:<walletId>\" to select exact local wallets for read-only balance/assets/status/address and risky actions. Use action=\"assets\" for all visible Solana native and SPL balances, or address=\"<solana-address>\" for read-only external Solana balance/assets. For address/balance reads, omit chain when the user does not specify it; the tool returns the available Solana address or balance set. Risky prepare/send actions use explicit wallet, skill override, Agent assignment, then the optional Default Agent wallet fallback. For normal SOL amounts such as 0.1, pass amountFormat=\"human\"; decimal amounts without amountFormat are treated as human units. Destination wallet handles like @wallet:vault are resolved to receive addresses.",
352
352
  parameters: WalletToolSchema,
353
353
  execute: async (_toolCallId, args) => {
354
354
  if (!access.ok) {
@@ -377,6 +377,9 @@ function createWalletTool(opts) {
377
377
  const walletIdFromHandle = explicitWalletHandle ? parseWalletHandle(explicitWalletHandle) : undefined;
378
378
  const selectedWalletId = walletIdFromHandle ?? explicitWalletId;
379
379
  const explicitWalletName = readStringParam(params, "walletName");
380
+ const requesterSkillId = opts?.requesterSkillId?.trim() || null;
381
+ const permissions = readSkillWalletActionPermissions(cfg, requesterSkillId);
382
+ const skillWalletId = permissions?.walletIds?.length === 1 ? permissions.walletIds[0] : undefined;
380
383
  const walletSelection = riskyWalletAction ? resolveAgentWalletSelection({
381
384
  config: cfg,
382
385
  providerId: explicitProviderId,
@@ -384,6 +387,7 @@ function createWalletTool(opts) {
384
387
  walletId: explicitWalletId,
385
388
  walletName: explicitWalletName,
386
389
  agentId: requesterAgentId ?? ownerAgentId ?? undefined,
390
+ skillWalletId,
387
391
  env: process.env
388
392
  }) : resolveWalletSelection({
389
393
  providerId: explicitProviderId,
@@ -639,8 +643,6 @@ function createWalletTool(opts) {
639
643
  if (chain === "solana" && payload.program) {
640
644
  assertValidSolanaAddress(payload.program, "SPL mint address");
641
645
  }
642
- const requesterSkillId = opts?.requesterSkillId?.trim() || null;
643
- const permissions = readSkillWalletActionPermissions(cfg, requesterSkillId);
644
646
  await enforceWalletSkillPolicy({
645
647
  cfg,
646
648
  permissions,
package/dist/brand.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const FASED_BRAND_NAME = "Fased";
3
3
  const FASED_AGENT_NAME = "Fased Agent";
4
4
  const FASED_CONTROL_NAME = "Fased Control";
5
- const FASED_PRODUCT_VERSION = "0.1.68";
5
+ const FASED_PRODUCT_VERSION = "0.1.69";
6
6
  const FASED_DISPLAY_VERSION = `v${FASED_PRODUCT_VERSION}`;
7
7
  function formatFasedDisplayLine() {
8
8
  return `${FASED_AGENT_NAME} ${FASED_DISPLAY_VERSION}`;
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.68",
3
- "commit": "ad0d395fdae5c0fbbbda8ad932b32276558b2cf2",
4
- "builtAt": "2026-07-20T01:36:18.679Z"
2
+ "version": "0.1.69",
3
+ "commit": "a0ff463531b83e6c6040a0d5f88542fa962c668c",
4
+ "builtAt": "2026-07-20T20:47:15.486Z"
5
5
  }
@@ -1 +1 @@
1
- eb11c388af36ee3609b0db82a4da72350ca90ba7a06fec9f82f02a1db6307bfd
1
+ 55def76543727f5f2382ec4651338f60eda04013d15e65d1b8817b7444a13a6c
@@ -1,6 +1,7 @@
1
1
  import { defaultRuntime } from "../../runtime.js";
2
2
  import { runCommandWithRuntime } from "../cli-utils.js";
3
- import { walletCanaryCommand, walletInboundListCommand, walletInboundPollCommand, walletInboundReconcileCommand, walletLegacyMigrationFinalizeCommand, walletLimitOrdersConfigureCommand, walletMigrateCommand, walletPolicyProfileApplyCommand, walletProviderConfigureCommand, walletRawExportCommand, walletRecoveryExportCommand, walletRecoveryImportCommand, walletRoleSetCommand, walletRotateKeysCommand, walletSetupCommand, walletSignerDoctorCommand, walletSignerServeCommand, walletStatusCommand } from "../../commands/wallet.js";
3
+ import { walletCanaryCommand, walletInboundListCommand, walletInboundPollCommand, walletInboundReconcileCommand, walletLegacyMigrationFinalizeCommand, walletLimitOrdersConfigureCommand, walletMigrateCommand, walletPolicyActivateRoleBaselineCommand, walletPolicyProfileApplyCommand, walletProviderConfigureCommand, walletRawExportCommand, walletRecoveryExportCommand, walletRecoveryImportCommand, walletRetireCommand, walletRoleSetCommand, walletRotateKeysCommand, walletRpcSetCommand, walletSetupCommand, walletSignerDoctorCommand, walletSignerServeCommand, walletStatusCommand } from "../../commands/wallet.js";
4
+ import { addGatewayClientOptions, callGatewayFromCli } from "../gateway-rpc.js";
4
5
 
5
6
  //#region src/cli/program/register.wallet.ts
6
7
  function resolvePublicWalletSetupChain(raw) {
@@ -26,7 +27,7 @@ function registerWalletCommands(program) {
26
27
  });
27
28
  });
28
29
  });
29
- recovery.command("import").description("Restore an encrypted signer recovery package into a new Local wallet").requiredOption("--wallet-id <id>", "New registered signer-owned wallet id").requiredOption("--wallet-name <name>", "Wallet display name").requiredOption("--role <role>", "Permanent signer role: agent|mining|vault").requiredOption("--file <absolute-path>", "Owner-only encrypted recovery package").requiredOption("--rpc-url <url>", "One primary Solana RPC URL").action(async (opts) => {
30
+ recovery.command("restore").alias("import").description("Restore an encrypted signer recovery package into a new signer-owned wallet").requiredOption("--wallet-id <id>", "New registered signer-owned wallet id").requiredOption("--wallet-name <name>", "Wallet display name").requiredOption("--role <role>", "Permanent signer role: agent|mining|vault").requiredOption("--file <absolute-path>", "Owner-only encrypted recovery package").requiredOption("--rpc-url <url>", "One primary Solana RPC URL").action(async (opts) => {
30
31
  await runCommandWithRuntime(defaultRuntime, async () => {
31
32
  await walletRecoveryImportCommand(defaultRuntime, {
32
33
  walletId: String(opts.walletId),
@@ -46,6 +47,75 @@ function registerWalletCommands(program) {
46
47
  });
47
48
  });
48
49
  });
50
+ wallet.command("export-raw").description("Advanced: export a raw Solana keypair and reduce signer custody protection").requiredOption("--wallet-id <id>", "Registered signer-owned wallet id").requiredOption("--output <absolute-path>", "New owner-only raw keypair path").requiredOption("--acknowledge-custody-reduction", "Confirm that raw export makes the wallet key portable").action(async (opts) => {
51
+ await runCommandWithRuntime(defaultRuntime, async () => {
52
+ await walletRawExportCommand(defaultRuntime, {
53
+ walletId: String(opts.walletId),
54
+ output: String(opts.output),
55
+ acknowledgeCustodyReduction: Boolean(opts.acknowledgeCustodyReduction)
56
+ });
57
+ });
58
+ });
59
+ wallet.command("create").description("Create a role-ready signer-owned Solana wallet").option("--wallet-id <id>", "Named wallet id").option("--wallet-name <name>", "Wallet display name").option("--role <role>", "Permanent signer role: agent|mining|vault").option("--rpc-url <url>", "One primary Solana RPC URL").option("--force", "Resume only the same existing signer wallet and role", false).option("--non-interactive", "Do not prompt; require all inputs", false).option("--json", "Print JSON output", false).action(async (opts) => {
60
+ await runCommandWithRuntime(defaultRuntime, async () => {
61
+ await walletSetupCommand(defaultRuntime, {
62
+ mode: "local-signer-create",
63
+ chain: "solana",
64
+ walletId: typeof opts.walletId === "string" ? opts.walletId : undefined,
65
+ walletName: typeof opts.walletName === "string" ? opts.walletName : undefined,
66
+ role: typeof opts.role === "string" ? opts.role : undefined,
67
+ rpcUrl: typeof opts.rpcUrl === "string" ? opts.rpcUrl : undefined,
68
+ force: Boolean(opts.force),
69
+ nonInteractive: Boolean(opts.nonInteractive),
70
+ json: Boolean(opts.json)
71
+ });
72
+ });
73
+ });
74
+ wallet.command("import").description("Import an owner-only Solana keypair through the native signer lifecycle").option("--wallet-id <id>", "Named wallet id").option("--wallet-name <name>", "Wallet display name").option("--role <role>", "Permanent signer role: agent|mining|vault").option("--file <absolute-path>", "Owner-only Solana keypair JSON").option("--rpc-url <url>", "One primary Solana RPC URL").option("--non-interactive", "Do not prompt; require all inputs", false).option("--json", "Print JSON output", false).action(async (opts) => {
75
+ await runCommandWithRuntime(defaultRuntime, async () => {
76
+ await walletSetupCommand(defaultRuntime, {
77
+ mode: "local-signer-import",
78
+ chain: "solana",
79
+ walletId: typeof opts.walletId === "string" ? opts.walletId : undefined,
80
+ walletName: typeof opts.walletName === "string" ? opts.walletName : undefined,
81
+ role: typeof opts.role === "string" ? opts.role : undefined,
82
+ importFile: typeof opts.file === "string" ? opts.file : undefined,
83
+ rpcUrl: typeof opts.rpcUrl === "string" ? opts.rpcUrl : undefined,
84
+ nonInteractive: Boolean(opts.nonInteractive),
85
+ json: Boolean(opts.json)
86
+ });
87
+ });
88
+ });
89
+ addGatewayClientOptions(wallet.command("retire").description("Safely retire and replace the active signer-owned Mining wallet").requiredOption("--wallet-id <id>", "Active Mining wallet id").requiredOption("--successor-wallet-id <id>", "New distinct Mining wallet id").requiredOption("--successor-wallet-name <name>", "New Mining wallet display name").requiredOption("--recovery-file <absolute-path>", "Encrypted recovery package for the old wallet").requiredOption("--rpc-url <url>", "One primary Solana RPC URL for the successor").option("--json", "Print JSON output", false)).action(async (opts) => {
90
+ await runCommandWithRuntime(defaultRuntime, async () => {
91
+ let liveMiningStatus = {};
92
+ try {
93
+ await callGatewayFromCli("sat.stopMining", opts, {}, { progress: opts.json !== true });
94
+ liveMiningStatus = await callGatewayFromCli("sat.getMiningStatus", opts, {}, { progress: opts.json !== true });
95
+ } catch (error) {
96
+ liveMiningStatus = { retirementGatewayError: error instanceof Error ? error.message : String(error) };
97
+ }
98
+ await walletRetireCommand(defaultRuntime, {
99
+ walletId: String(opts.walletId),
100
+ successorWalletId: String(opts.successorWalletId),
101
+ successorWalletName: String(opts.successorWalletName),
102
+ recoveryFile: String(opts.recoveryFile),
103
+ rpcUrl: String(opts.rpcUrl),
104
+ liveMiningStatus,
105
+ json: opts.json === true
106
+ });
107
+ });
108
+ });
109
+ const rpc = wallet.command("rpc").description("Signer-owned Solana RPC configuration");
110
+ rpc.command("set").description("Verify and set one primary Solana RPC").requiredOption("--wallet-id <id>", "Registered signer-owned wallet id").requiredOption("--rpc-url <url>", "Primary Solana RPC URL").option("--json", "Print JSON output", false).action(async (opts) => {
111
+ await runCommandWithRuntime(defaultRuntime, async () => {
112
+ await walletRpcSetCommand(defaultRuntime, {
113
+ walletId: String(opts.walletId),
114
+ rpcUrl: String(opts.rpcUrl),
115
+ json: Boolean(opts.json)
116
+ });
117
+ });
118
+ });
49
119
  wallet.command("setup").description("Create a signer-owned Solana wallet or configure a supported provider").option("--mode <mode>", "local-signer-create|local-signer-import|local-signer-recovery-import|local-signer|turnkey|alchemy").option("--chain <chain>", "solana", "solana").option("--wallet-id <id>", "Named wallet id (examples: agent, mining, vault)").option("--wallet-name <value>", "Friendly wallet display name (for UI/skills/plugins)").option("--role <role>", "Permanent signer role: agent|mining|vault").option("--import-file <absolute-path>", "Owner-only Solana keypair JSON for local-signer-import; secret is passed by file descriptor, never argv/env").option("--recovery-file <absolute-path>", "Owner-only encrypted package for local-signer-recovery-import").option("--api-key <value>", "Alchemy API key").option("--rpc-url <url>", "Solana RPC URL").option("--turnkey-api-public-key <value>", "Turnkey API public key (turnkey mode)").option("--turnkey-api-private-key <value>", "Turnkey API private key (turnkey mode)").option("--turnkey-organization-id <value>", "Turnkey organization ID (turnkey mode)").option("--turnkey-policy-id <value>", "Turnkey policy ID (turnkey mode)").option("--turnkey-base-url <value>", "Turnkey base URL override (turnkey mode)").option("--enable-limit-orders", "Legacy alias: configure Gateway Jupiter Swap API access (Trigger is signer-owned)", false).option("--disable-limit-orders", "Remove stored Gateway Jupiter Swap API key", false).option("--jupiter-api-key <value>", "Jupiter API key for Gateway swap crafting only").option("--non-interactive", "Do not prompt; require mode/inputs", false).option("--no-doctor", "Skip signer doctor in local-signer mode", false).option("--json", "Print JSON output", false).action(async (opts) => {
50
120
  await runCommandWithRuntime(defaultRuntime, async () => {
51
121
  await walletSetupCommand(defaultRuntime, {
@@ -83,9 +153,12 @@ function registerWalletCommands(program) {
83
153
  });
84
154
  });
85
155
  });
86
- wallet.command("status").description("Show wallet service and policy status").option("--json", "Print JSON output", false).action(async (opts) => {
156
+ wallet.command("status").description("Show wallet service and policy status").option("--wallet-id <id>", "Show one registered wallet").option("--json", "Print JSON output", false).action(async (opts) => {
87
157
  await runCommandWithRuntime(defaultRuntime, async () => {
88
- await walletStatusCommand(defaultRuntime, { json: Boolean(opts.json) });
158
+ await walletStatusCommand(defaultRuntime, {
159
+ json: Boolean(opts.json),
160
+ walletId: typeof opts.walletId === "string" ? opts.walletId : undefined
161
+ });
89
162
  });
90
163
  });
91
164
  wallet.command("rotate-keys").description("Removed Gateway key rotation; prints native/provider authority guidance").option("--json", "Print JSON output", false).action(async (opts) => {
@@ -102,7 +175,7 @@ function registerWalletCommands(program) {
102
175
  });
103
176
  });
104
177
  });
105
- wallet.command("role set <wallet-id> <role>").description("Set primary Agent fallback or initialize a missing Agent/Vault purpose. Existing purpose stays permanent.").option("--primary", "Make this Agent wallet the primary fallback", false).option("--json", "Print JSON output", false).action(async (walletId, role, opts) => {
178
+ wallet.command("role set <wallet-id> <role>").description("Set Default Agent wallet fallback or initialize a missing Agent/Vault purpose. Existing purpose stays permanent.").option("--primary", "Make this the Default Agent wallet fallback", false).option("--json", "Print JSON output", false).action(async (walletId, role, opts) => {
106
179
  await runCommandWithRuntime(defaultRuntime, async () => {
107
180
  await walletRoleSetCommand(defaultRuntime, {
108
181
  walletId: String(walletId),
@@ -128,6 +201,16 @@ function registerWalletCommands(program) {
128
201
  });
129
202
  });
130
203
  const policy = wallet.command("policy").description("Wallet policy presets and controls");
204
+ policy.command("activate-role-baseline").description("Explicitly migrate one existing deny-all signer wallet to its role baseline").requiredOption("--wallet-id <id>", "Registered signer-owned wallet id").requiredOption("--role <role>", "Immutable signer role: agent|mining|vault").requiredOption("--confirm", "Confirm activation after reviewing the selected role").option("--json", "Print JSON output", false).action(async (opts) => {
205
+ await runCommandWithRuntime(defaultRuntime, async () => {
206
+ await walletPolicyActivateRoleBaselineCommand(defaultRuntime, {
207
+ walletId: String(opts.walletId),
208
+ role: String(opts.role),
209
+ confirm: Boolean(opts.confirm),
210
+ json: Boolean(opts.json)
211
+ });
212
+ });
213
+ });
131
214
  policy.command("profile <name>").description("Apply wallet policy profile (autonomous-strict|autonomous-moderate|manual-owner)").option("--allow-skill <id>", "Allow skill id (repeatable)", (v, acc) => [...acc, v], []).option("--allow-source <id>", "Allow source id (repeatable)", (v, acc) => [...acc, v], []).option("--json", "Print JSON output", false).action(async (name, opts) => {
132
215
  if (name !== "autonomous-strict" && name !== "autonomous-moderate" && name !== "manual-owner") {
133
216
  throw new Error("profile must be one of: autonomous-strict, autonomous-moderate, manual-owner");