@palmyr/cli 1.1.0 → 1.2.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/dist/cli.js CHANGED
@@ -74,7 +74,7 @@ const BOOLEAN_FLAGS = new Set([
74
74
  // compute deploy/ssh flags
75
75
  'wait', 'generate-ssh-key', 'generate', 'progress',
76
76
  // wallet trading flags
77
- 'dry-run', 'all', 'protected', 'auto-slippage',
77
+ 'dry-run', 'all', 'protected', 'auto-slippage', 'degen',
78
78
  // wallet daemon + triggers flags
79
79
  'auto', 'clear',
80
80
  // wallet brief flags
@@ -226,10 +226,11 @@ const WALLET_HELP = {
226
226
  { flag: '--hold-if "..."', desc: 'Free-form hold condition (informational)' },
227
227
  { flag: '--wallet <id|name>', desc: 'Vault wallet to sign with (else env WALLET_SECRET_KEY)' },
228
228
  { flag: '--slippage <bps>', desc: 'Explicit slippage in basis points', hint: 'overrides --auto-slippage' },
229
- { flag: '--auto-slippage', desc: 'Dynamic slippage from DexScreener 5m volatility (solana)', hint: 'implied by --protected' },
230
- { flag: '--protected', desc: 'MEV-protected execution', hint: 'sol: Jito tip + dyn slippage. base: priority-fee bump + PALMYR_BASE_PROTECTED_RPC' },
231
- { flag: '--tip <amount>', desc: 'sol: Jito tip lamports (default 10000). base: priority fee in gwei (default 0.001)' },
232
- { flag: '--rpc <url>', desc: 'Override RPC endpoint (base: maps to provider URL; bypasses --protected default)' },
229
+ { flag: '--degen', desc: 'Disable MEV protection + dynamic slippage. Faster / cheaper, no sandwich defense.' },
230
+ { flag: '--no-protected', desc: 'Disable MEV protection only (keep dynamic slippage)' },
231
+ { flag: '--no-auto-slippage', desc: 'Disable dynamic slippage only (use config default or --slippage)' },
232
+ { flag: '--tip <amount>', desc: 'Override the protection tip — sol: Jito tip lamports (default 10000); base: priority fee gwei (default 0.001)' },
233
+ { flag: '--rpc <url>', desc: 'Override RPC endpoint (base only; default uses PALMYR_BASE_PROTECTED_RPC env if set)' },
233
234
  { flag: '--template <name>', desc: 'YAML strategy template (see `wallet template list`). CLI flags win on conflict.' },
234
235
  { flag: '--dry-run', desc: 'Simulate without sending the swap' },
235
236
  ],
@@ -264,10 +265,11 @@ const WALLET_HELP = {
264
265
  { flag: '--reason "..."', desc: 'Why are you exiting? (required)' },
265
266
  { flag: '--wallet <id|name>', desc: 'Vault wallet to sign with (else env)' },
266
267
  { flag: '--slippage <bps>', desc: 'Explicit slippage in basis points', hint: 'overrides --auto-slippage' },
267
- { flag: '--auto-slippage', desc: 'Dynamic slippage from DexScreener 5m volatility (solana)', hint: 'implied by --protected' },
268
- { flag: '--protected', desc: 'MEV-protected execution', hint: 'sol: Jito tip + dyn slippage. base: priority-fee bump + PALMYR_BASE_PROTECTED_RPC' },
269
- { flag: '--tip <amount>', desc: 'sol: Jito tip lamports (default 10000). base: priority fee in gwei (default 0.001)' },
270
- { flag: '--rpc <url>', desc: 'Override RPC endpoint (base only currently)' },
268
+ { flag: '--degen', desc: 'Disable MEV protection + dynamic slippage' },
269
+ { flag: '--no-protected', desc: 'Disable MEV protection only' },
270
+ { flag: '--no-auto-slippage', desc: 'Disable dynamic slippage only' },
271
+ { flag: '--tip <amount>', desc: 'Override protection tip (sol: Jito lamports; base: priority fee gwei)' },
272
+ { flag: '--rpc <url>', desc: 'Override RPC endpoint (base only)' },
271
273
  { flag: '--dry-run', desc: 'Simulate without sending the swap' },
272
274
  ],
273
275
  sync: [
@@ -1934,6 +1936,30 @@ async function main() {
1934
1936
  const cliTrail = flags.trail || undefined;
1935
1937
  const cliTimeLimit = flags['time-limit'] || undefined;
1936
1938
  const cliThesisCheck = flags['thesis-check'] || undefined;
1939
+ // Safe-by-default — protectedExec and autoSlippage default to true
1940
+ // (MEV-protected with dynamic slippage). `--degen` opts out of both
1941
+ // for fast/raw execution. `--no-protected` / `--no-auto-slippage`
1942
+ // disable each individually. Explicit `--protected` is a no-op now
1943
+ // (kept for back-compat with scripts that pass it).
1944
+ const degen = !!flags.degen;
1945
+ const resolveProtected = () => {
1946
+ if (degen)
1947
+ return false;
1948
+ if (flags.protected === false)
1949
+ return false; // --no-protected
1950
+ if (flags.protected === true)
1951
+ return true; // --protected (redundant but explicit)
1952
+ return undefined; // fall through to template, then default true at lib layer
1953
+ };
1954
+ const resolveAutoSlippage = () => {
1955
+ if (degen)
1956
+ return false;
1957
+ if (flags['auto-slippage'] === false)
1958
+ return false; // --no-auto-slippage
1959
+ if (flags['auto-slippage'] === true)
1960
+ return true;
1961
+ return undefined;
1962
+ };
1937
1963
  // Base path — Phase 5b buy, 5c sell+sync, 5d --protected + private RPC.
1938
1964
  if (chain === 'base') {
1939
1965
  if (!walletRef)
@@ -1953,7 +1979,7 @@ async function main() {
1953
1979
  timeLimit: cliTimeLimit,
1954
1980
  thesisCheck: cliThesisCheck,
1955
1981
  slippageBps: cliSlippage,
1956
- protectedExec: flags.protected === true ? true : undefined,
1982
+ protectedExec: resolveProtected(),
1957
1983
  rpcUrl: flags.rpc || undefined,
1958
1984
  priorityFeeWei: cliPriorityFeeWei,
1959
1985
  };
@@ -1961,6 +1987,10 @@ async function main() {
1961
1987
  const { applyTemplateToBuyOpts } = await import('./wallet-strategy-templates.js');
1962
1988
  opts = applyTemplateToBuyOpts(template, opts);
1963
1989
  }
1990
+ // Final default: protected ON unless user/template said otherwise. --degen already
1991
+ // forced it false above.
1992
+ if (opts.protectedExec === undefined)
1993
+ opts.protectedExec = !degen;
1964
1994
  if (!opts.amount)
1965
1995
  err(`--amount required (e.g. --amount 0.01eth) — not in template or CLI`, EXIT.BAD_INPUT);
1966
1996
  const { buyBase } = await import('./wallet-trading.js');
@@ -2007,8 +2037,8 @@ async function main() {
2007
2037
  timeLimit: cliTimeLimit,
2008
2038
  thesisCheck: cliThesisCheck,
2009
2039
  slippageBps: cliSlippage,
2010
- protectedExec: flags.protected === true ? true : undefined,
2011
- autoSlippage: flags['auto-slippage'] === true ? true : undefined,
2040
+ protectedExec: resolveProtected(),
2041
+ autoSlippage: resolveAutoSlippage(),
2012
2042
  jitoTipLamports: flags.tip !== undefined ? Number(flags.tip) : undefined,
2013
2043
  };
2014
2044
  if (template) {
@@ -2017,9 +2047,12 @@ async function main() {
2017
2047
  }
2018
2048
  if (!solOpts.amount)
2019
2049
  err(`--amount required (e.g. --amount 0.5sol) — not in template or CLI`, EXIT.BAD_INPUT);
2020
- // Normalize booleans for downstream call (undefined false)
2021
- solOpts.protectedExec = !!solOpts.protectedExec;
2022
- solOpts.autoSlippage = !!solOpts.autoSlippage;
2050
+ // Final defaults: MEV protection + dynamic slippage are ON unless --degen, --no-protected,
2051
+ // --no-auto-slippage, or a template set them off.
2052
+ if (solOpts.protectedExec === undefined)
2053
+ solOpts.protectedExec = !degen;
2054
+ if (solOpts.autoSlippage === undefined)
2055
+ solOpts.autoSlippage = !degen;
2023
2056
  const { buy } = await import('./wallet-trading.js');
2024
2057
  let result;
2025
2058
  try {
@@ -2138,6 +2171,26 @@ async function main() {
2138
2171
  const dryRun = !!flags['dry-run'] || process.env.DRY_RUN === '1';
2139
2172
  const cliTipGwei = flags.tip !== undefined && chain === 'base' ? Number(flags.tip) : undefined;
2140
2173
  const cliPriorityFeeWei = cliTipGwei !== undefined ? BigInt(Math.round(cliTipGwei * 1e9)) : undefined;
2174
+ // Safe-by-default for cohort legs. --degen disables; --no-protected / --no-auto-slippage individually disable.
2175
+ const cohortDegen = !!flags.degen;
2176
+ const cohortResolveProtected = () => {
2177
+ if (cohortDegen)
2178
+ return false;
2179
+ if (flags.protected === false)
2180
+ return false;
2181
+ if (flags.protected === true)
2182
+ return true;
2183
+ return undefined;
2184
+ };
2185
+ const cohortResolveAutoSlippage = () => {
2186
+ if (cohortDegen)
2187
+ return false;
2188
+ if (flags['auto-slippage'] === false)
2189
+ return false;
2190
+ if (flags['auto-slippage'] === true)
2191
+ return true;
2192
+ return undefined;
2193
+ };
2141
2194
  // Build opts with CLI values; merge template defaults for the rest.
2142
2195
  let cohortOpts = {
2143
2196
  chain: chain,
@@ -2154,8 +2207,8 @@ async function main() {
2154
2207
  timeLimit: flags['time-limit'] || undefined,
2155
2208
  thesisCheck: flags['thesis-check'] || undefined,
2156
2209
  slippageBps: flags.slippage !== undefined ? Number(flags.slippage) : undefined,
2157
- protectedExec: flags.protected === true ? true : undefined,
2158
- autoSlippage: flags['auto-slippage'] === true ? true : undefined,
2210
+ protectedExec: cohortResolveProtected(),
2211
+ autoSlippage: cohortResolveAutoSlippage(),
2159
2212
  jitoTipLamports: flags.tip !== undefined && chain === 'solana' ? Number(flags.tip) : undefined,
2160
2213
  priorityFeeWei: cliPriorityFeeWei,
2161
2214
  rpcUrl: flags.rpc || undefined,
@@ -2171,9 +2224,11 @@ async function main() {
2171
2224
  cohortOpts.jitterMs = jitterMs;
2172
2225
  cohortOpts.dryRun = dryRun;
2173
2226
  }
2174
- // Normalize booleans (template may leave them undefined)
2175
- cohortOpts.protectedExec = !!cohortOpts.protectedExec;
2176
- cohortOpts.autoSlippage = !!cohortOpts.autoSlippage;
2227
+ // Final defaults: protected + auto-slippage ON unless user/template/degen disabled.
2228
+ if (cohortOpts.protectedExec === undefined)
2229
+ cohortOpts.protectedExec = !cohortDegen;
2230
+ if (cohortOpts.autoSlippage === undefined)
2231
+ cohortOpts.autoSlippage = !cohortDegen;
2177
2232
  const { cohortBuy } = await import('./wallet-trading.js');
2178
2233
  let result;
2179
2234
  try {
@@ -2472,11 +2527,18 @@ async function main() {
2472
2527
  const walletRef = flags.wallet || undefined;
2473
2528
  const slippageBps = flags.slippage ? Number(flags.slippage) : undefined;
2474
2529
  const dryRun = !!flags['dry-run'] || process.env.DRY_RUN === '1';
2530
+ // Safe-by-default: protected ON unless --degen or --no-protected.
2531
+ const sellDegen = !!flags.degen;
2532
+ const sellProtected = sellDegen
2533
+ ? false
2534
+ : flags.protected === false ? false : true;
2535
+ const sellAutoSlippage = sellDegen
2536
+ ? false
2537
+ : flags['auto-slippage'] === false ? false : true;
2475
2538
  // Base sell path — Phase 5c, plus 5d --protected + private RPC.
2476
2539
  if (chain === 'base') {
2477
2540
  if (!walletRef)
2478
2541
  err('--wallet required for Base. Use a vault wallet name/id or `trading:N`.', EXIT.BAD_INPUT);
2479
- const baseProtected = !!flags.protected;
2480
2542
  const baseRpc = flags.rpc || undefined;
2481
2543
  const tipGwei = flags.tip ? Number(flags.tip) : undefined;
2482
2544
  const priorityFeeWei = tipGwei !== undefined
@@ -2492,7 +2554,7 @@ async function main() {
2492
2554
  walletRef,
2493
2555
  slippageBps,
2494
2556
  dryRun,
2495
- protectedExec: baseProtected,
2557
+ protectedExec: sellProtected,
2496
2558
  rpcUrl: baseRpc,
2497
2559
  priorityFeeWei,
2498
2560
  });
@@ -2529,8 +2591,6 @@ async function main() {
2529
2591
  }
2530
2592
  break;
2531
2593
  }
2532
- const protectedExec = !!flags.protected;
2533
- const autoSlippage = !!flags['auto-slippage'];
2534
2594
  const jitoTipLamports = flags.tip ? Number(flags.tip) : undefined;
2535
2595
  const { sell } = await import('./wallet-trading.js');
2536
2596
  let result;
@@ -2542,8 +2602,8 @@ async function main() {
2542
2602
  walletRef,
2543
2603
  slippageBps,
2544
2604
  dryRun,
2545
- protectedExec,
2546
- autoSlippage,
2605
+ protectedExec: sellProtected,
2606
+ autoSlippage: sellAutoSlippage,
2547
2607
  jitoTipLamports,
2548
2608
  });
2549
2609
  }