@palmyr/cli 1.8.3 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -121,9 +121,6 @@ PALMYR_WALLET_PASSPHRASE="your-passphrase" palmyr wallet create --name agent-pro
121
121
  # Equivalent — flag form (less safe, ends up in shell history)
122
122
  palmyr wallet create --name agent-prod --passphrase "your-passphrase"
123
123
 
124
- # Managed: same passphrase rules; also prints a setup link to send to a human
125
- PALMYR_WALLET_PASSPHRASE="..." palmyr wallet create --name treasury --managed
126
-
127
124
  # Single-chain: skip the other chain's account
128
125
  PALMYR_WALLET_PASSPHRASE="..." palmyr wallet create --name sol-only --solana
129
126
  PALMYR_WALLET_PASSPHRASE="..." palmyr wallet create --name base-only --base
@@ -136,8 +133,6 @@ On a TTY without env or flag, the CLI prompts twice with confirmation; non-TTY c
136
133
 
137
134
  By default a wallet derives both Solana and Base/EVM accounts. Pass `--solana` or `--base` (not both) to materialize only one side. The mnemonic always derives both — `--solana` / `--base` controls *which addresses are surfaced and stored*, not which keys exist cryptographically.
138
135
 
139
- The managed flow returns a one-time URL. The recipient opens it in a browser, registers a WebAuthn passkey, and sets spending limits. From that point on, transactions inside the limit sign instantly; transactions over the limit emit an `approvalUrl` that the human visits to authenticate and approve.
140
-
141
136
  ### Bulk creation with tags
142
137
 
143
138
  Group many wallets under one folder-like tag, then cascade-delete them together when done — ideal for spinning up demo, agent-cohort, or test wallets:
@@ -159,7 +154,7 @@ palmyr wallet tags # all tags + counts + chains
159
154
  palmyr wallet tag-delete palmyr-demo --confirm
160
155
  ```
161
156
 
162
- Bulk-create is unmanaged-only (managed wallets need per-wallet passkey setup) and capped at 500 per call. Names auto-suffix `-001..-N` with zero-padding based on count width.
157
+ Bulk-create caps at 500 per call. Names auto-suffix `-001..-N` with zero-padding based on count width.
163
158
 
164
159
  ### Importing an existing seed
165
160
 
@@ -426,11 +421,11 @@ palmyr compute exec my-vps -- bash -c 'cloud-init clean && cloud-init init --all
426
421
  | `palmyr domain check --name example.dev` | free | Availability check. |
427
422
  | `palmyr domain pricing --name example.dev` | free | TLD pricing. |
428
423
  | `palmyr domain buy --name example.dev` | $20.00 | One-year registration. Renewals are charged annually. |
429
- | `palmyr domain list` | $0.0001 *(ownership proof)* | List domains your wallet owns plus any shared with you. Each row tagged `access: owner | shared`. |
430
- | `palmyr domain dns --name example.dev` | $0.0001 *(ownership proof)* | View DNS records. Owners and shared wallets allowed. |
431
- | `palmyr domain transfer-ownership --name example.dev --to <wallet>` | $0.0001 *(ownership proof)* | Hand the domain to another wallet. Clears `shared_with` — the prior owner's collaborators don't travel with the domain. |
432
- | `palmyr domain share --name example.dev --with <wallet>` | $0.0001 *(ownership proof)* | Grant another wallet shared access (visible in `domain list`, can edit DNS). Owner-only. |
433
- | `palmyr domain unshare --name example.dev --from <wallet>` | $0.0001 *(ownership proof)* | Revoke a shared wallet's access. Owner-only. |
424
+ | `palmyr domain list` | $0.01 *(ownership proof)* | List domains your wallet owns plus any shared with you. Each row tagged `access: owner | shared`. |
425
+ | `palmyr domain dns --name example.dev` | $0.01 *(ownership proof)* | View DNS records. Owners and shared wallets allowed. |
426
+ | `palmyr domain transfer-ownership --name example.dev --to <wallet>` | $0.01 *(ownership proof)* | Hand the domain to another wallet. Clears `shared_with` — the prior owner's collaborators don't travel with the domain. |
427
+ | `palmyr domain share --name example.dev --with <wallet>` | $0.01 *(ownership proof)* | Grant another wallet shared access (visible in `domain list`, can edit DNS). Owner-only. |
428
+ | `palmyr domain unshare --name example.dev --from <wallet>` | $0.01 *(ownership proof)* | Revoke a shared wallet's access. Owner-only. |
434
429
 
435
430
  ### Wallet
436
431
 
@@ -438,8 +433,8 @@ All wallet operations except `addresses`, `api-key`, `config`, and `request-appr
438
433
 
439
434
  | Command | Network | Notes |
440
435
  |---|---|---|
441
- | `palmyr wallet create [--name N] [--managed] [--solana\|--base] [--tag T] [--count N] [--name-prefix P] (--passphrase P \| PALMYR_WALLET_PASSPHRASE env \| --session-only)` | local *(server only if `--managed`)* | New wallet. **Requires** either a passphrase (recoverable across reboot / OS-keychain loss / host migration) or explicit `--session-only` opt-out. On TTY without env/flag, prompts twice. Stores keychain secret + (with passphrase) a scrypt-sealed `owner_crypto` blob. `--count > 1` bulk-creates N unmanaged wallets under a required `--tag` (max 500/call, batched DPAPI seal on Windows). |
442
- | `palmyr wallet import --mnemonic "..." [--name N] [--managed] [--solana\|--base] [--tag T] (--passphrase P \| PALMYR_WALLET_PASSPHRASE env \| --session-only)` | local | Restore from BIP-39. Same passphrase rules as `create` — re-importing on a new machine to recover from keychain loss should always set a passphrase so you don't get trapped again. |
436
+ | `palmyr wallet create [--name N] [--solana\|--base] [--tag T] [--count N] [--name-prefix P] (--passphrase P \| PALMYR_WALLET_PASSPHRASE env \| --session-only)` | local | New wallet. **Requires** either a passphrase (recoverable across reboot / OS-keychain loss / host migration) or explicit `--session-only` opt-out. On TTY without env/flag, prompts twice. Stores keychain secret + (with passphrase) a scrypt-sealed `owner_crypto` blob. `--count > 1` bulk-creates N wallets under a required `--tag` (max 500/call, batched DPAPI seal on Windows). |
437
+ | `palmyr wallet import --mnemonic "..." [--name N] [--solana\|--base] [--tag T] (--passphrase P \| PALMYR_WALLET_PASSPHRASE env \| --session-only)` | local | Restore from BIP-39. Same passphrase rules as `create` — re-importing on a new machine to recover from keychain loss should always set a passphrase so you don't get trapped again. |
443
438
  | `palmyr wallet rekey <ID> --passphrase P` | local | Add (or rotate) the scrypt passphrase fallback on an existing wallet. Wallet must be decryptable right now (session secret still works, or `--current-passphrase` provided). Run on the original machine, then `PALMYR_WALLET_PASSPHRASE` decrypts the wallet anywhere. |
444
439
  | `palmyr wallet list [--tag T]` | local | Lists wallets in the local vault. `--tag` filters to one folder. |
445
440
  | `palmyr wallet info <ID>` | local | Show one wallet (id, name, addresses, mode, tag). |
@@ -451,7 +446,6 @@ All wallet operations except `addresses`, `api-key`, `config`, and `request-appr
451
446
  | `palmyr wallet api-key <ID> [--name N]` | API | Mint an agent API key bound to the wallet. |
452
447
  | `palmyr wallet config <ID>` | API | Pull the agent's runtime config. |
453
448
  | `palmyr wallet use <ID> [--chain solana\|base]` | local | Set default payer and payment chain. |
454
- | `palmyr wallet request-approval <ID> [--action limits] [--daily N] [--per-tx N]` | API | Managed wallets only — generate an approval URL for a human. |
455
449
  | `palmyr wallet export <ID> --confirm` | local | Print mnemonic. Requires explicit `--confirm`. |
456
450
 
457
451
  **Trading.** Thesis-tracked positions on Solana + Base persist at `~/.palmyr/trading/` (overridable via `PALMYR_TRADING_PATH`). Swaps route through Jupiter v6 on Solana and ParaSwap on Base. Positions, sells, journal, and watchlist live as JSON / JSONL.
@@ -588,7 +582,7 @@ Local credentials are encrypted with AES-256-GCM (per-account session secret in
588
582
  | `palmyr twitter banner <username> --file path.png` *(or `--url ...`)* | $0.005 | |
589
583
  | `palmyr twitter username <username> --to <new-handle>` | $0.005 | Pre-flight validates handle (4–15 chars, `[A-Za-z0-9_]`) before payment. May trigger X's password re-auth modal — handled automatically. |
590
584
  | `palmyr twitter transfer <username> --to <wallet> --confirm` | $0.0001 ownership proof + $0.0011 lookup; **adds $0.01 if auto-register runs**; **plus ~$0.001 in poll fees** ($0.0001 × ~10 polls) | Atomically hand the X account to another wallet. End-to-end one-command: looks up the account in both server tables (`x_accounts` + `social_registered_accounts`), auto-registers if only in local vault, then kicks off an async rotation job. Server returns `{ transfer_id }` immediately and the CLI polls `/transfers/:id` every 5s until `completed` or `failed` (rotation takes 30-90s in the background — async so it survives Cloudflare's HTTP timeout). Password is rotated and other sessions revoked before ownership flips, so the local copy of credentials becomes useless. Requires `--confirm`. Local vault entry is removed on success — receiver picks up fresh creds with `palmyr twitter list` (which shows server-only accounts) and/or `palmyr twitter claim`. |
591
- | `palmyr twitter share <username> --with <wallet>` | $0.0001 *(ownership proof)* | Grant another wallet shared access — same login, no credential rotation. Both wallets see the account via `palmyr twitter claim`. Owner-only. Same pool / registered dispatch as transfer. |
585
+ | `palmyr twitter share <username> --with <wallet>` | $0.01 *(ownership proof)* | Grant another wallet shared access — same login, no credential rotation. Both wallets see the account via `palmyr twitter claim`. Owner-only. Same pool / registered dispatch as transfer. |
592
586
  | `palmyr twitter unshare <username> --from <wallet> [--rotate]` | $0.0001 ownership proof + $0.0011 lookup; **with `--rotate`: kicks off async rotation, ~$0.001 in poll fees plus another lookup to sync local vault** | Revoke a wallet's shared access. Without `--rotate`, the wallet is removed from `shared_with` immediately but their previously exported cookies / password remain valid until X-side expiry. With `--rotate`, the unshare is immediate AND the server kicks off an async password rotation (same machinery as transfer — Playwright + polling so it survives Cloudflare's HTTP timeout). On completion, the CLI fetches the new credentials from the appropriate `/mine` endpoint and updates the local vault in place. Owner-only. Same pool / registered dispatch. |
593
587
  | `palmyr twitter claim` | $0.0011 *(ownership proof on both `/x/accounts/mine` and `/social/twitter/registered/mine`)* | Pull every X account on the server bound to your wallet (owner or shared) into the local vault, with session cookies pre-warmed. Queries both server tables in parallel. The fast path for a wallet that just received a transferred account. |
594
588
 
@@ -833,7 +827,6 @@ If the server doesn't offer the chosen chain for an endpoint, the CLI errors lou
833
827
  ├── wallet/
834
828
  │ ├── wallets/ # Encrypted wallet files (AES-256-GCM)
835
829
  │ ├── keys/ # API key metadata
836
- │ ├── policies/ # Spending policies for managed wallets
837
830
  │ └── spends/ # Per-day spend ledgers
838
831
  ├── secrets/ # Windows DPAPI fallback (macOS/Linux use OS keychain)
839
832
  ├── data/ # Local cache of phones, inboxes, servers, domains
@@ -866,7 +859,7 @@ The CLI uses distinct exit codes so scripts and agents can branch on failure mod
866
859
 
867
860
  ## Security Model
868
861
 
869
- - **Keys never leave the machine.** `wallet create` and `wallet import` never transmit seed material to the server. Even managed wallets register only the wallet ID and the derived public addresses with the server.
862
+ - **Keys never leave the machine.** `wallet create` and `wallet import` never transmit seed material to the server.
870
863
  - **Encryption at rest.** The wallet file is AES-256-GCM with the session secret as the key. The session secret is generated on wallet creation and never stored on disk in plaintext.
871
864
  - **OS credential store.** Session secrets live in DPAPI (Windows), Keychain (macOS), or `secret-tool` (libsecret on Linux). If none is available the CLI errors rather than falling back to plaintext.
872
865
  - **Recoverable by default.** `wallet create` and `wallet import` require a scrypt passphrase fallback (via `--passphrase` or `PALMYR_WALLET_PASSPHRASE`) or an explicit `--session-only` opt-out. The passphrase blob is a second AES-256-GCM ciphertext keyed by scrypt(passphrase, random salt) and lets the wallet decrypt on a different machine / user / headless box where the OS keychain isn't reachable. Decryption tries the OS session secret first, then falls back to the env/flag passphrase. Session-only wallets are bound to this machine's OS keychain — explicit opt-in for ephemeral use only.
@@ -889,7 +882,6 @@ Common issues:
889
882
  - **`SECURITY` exit code on any wallet command.** The vault file or its derived accounts have drifted. Restore the wallet file from backup, or re-import from the mnemonic.
890
883
  - **`Server did not offer <chain> as option`.** Either the endpoint only supports the other chain, or your `defaultPayChain` is misconfigured. Use `palmyr wallet use <ID> --chain <other>` and retry.
891
884
  - **`No session secret found`.** The wallet was created on a different machine, or the OS credential store is unavailable. Re-import the wallet and let the CLI store the secret again.
892
- - **Managed wallet, `REQUIRES_APPROVAL`.** The transaction exceeded a per-tx or daily limit. Run `palmyr wallet request-approval <ID>` and forward the URL to the human reviewer.
893
885
 
894
886
  ---
895
887