File size: 3,746 Bytes
75cbf21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bb5dc5
 
 
75cbf21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bb5dc5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75cbf21
6bb5dc5
 
 
 
 
 
 
75cbf21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6bb5dc5
75cbf21
6bb5dc5
75cbf21
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env bash
# scripts/setenv.sh — set or append KEY=VALUE lines in .env, safely.
#
# Why this exists: the operator administers this box from an iPhone, through
# the AWS console's browser terminal. In that environment `nano` is close to
# unusable and a pasted multi-line block gets swallowed by whatever the first
# line started. Every config change therefore has to be ONE line, with no
# interactive editor and no heredoc.
#
#   ./scripts/setenv.sh SOLANA_LEG2_HAIRCUT_BPS=2 MIN_PROFIT_FLOOR_USD=0.20
#
# Behaviour:
#   • replaces the line if the key already exists (commented or not)
#   • appends it if it doesn't
#   • takes ONE timestamped backup per run, so a bad paste is recoverable
#   • redacts by KEY NAME — anything matching KEY/TOKEN/SECRET/PASSWORD/
#     PRIVATE/RPC/URL prints as `[REDACTED — n chars set]`, with no
#     recoverable characters, so the output is safe to screenshot
#
# Values are written verbatim, quoted or not, so URLs with `/` and `?` are
# safe — this uses awk on exact key matches rather than a sed substitution
# whose delimiter the value could contain. That is the specific bug that
# makes `sed -i "s|^KEY=.*|KEY=$URL|"` a bad idea for RPC endpoints.

set -euo pipefail

cd "$(dirname "$0")/.."
ENV_FILE="${ENV_FILE:-.env}"

if [ "$#" -eq 0 ]; then
  echo "usage: ./scripts/setenv.sh KEY=VALUE [KEY=VALUE ...]" >&2
  exit 64
fi

[ -f "$ENV_FILE" ] || { echo "no $ENV_FILE here — are you in ~/Garden-Angel-Terminal?" >&2; exit 66; }

BACKUP="${ENV_FILE}.bak.$(date +%Y%m%d-%H%M%S)"
cp "$ENV_FILE" "$BACKUP"

# Decide from the KEY NAME, not the value's length.
#
# The first version of this inspected only the value: a `case` branch that
# did nothing, then "print in full if 24 chars or shorter". That got both
# halves wrong. A short API key printed verbatim, and even a long one leaked
# a 6-character prefix and 4-character suffix — on a script whose entire
# stated purpose is being safe to screenshot.
#
# Key names are the reliable signal. A value cannot tell you whether it is a
# secret; `PUMPFUN_API_KEY` can. Secrets now print a FIXED placeholder with
# no recoverable characters and no length hint, regardless of how long they
# are. Non-secret settings (thresholds, booleans, sizes) print in full,
# because seeing those confirmed is the point of the output.
is_secret_key() {
  case "$(printf '%s' "$1" | tr '[:lower:]' '[:upper:]')" in
    *KEY*|*TOKEN*|*SECRET*|*PASSWORD*|*PASSPHRASE*|*PRIVATE*|*RPC*|*URL*|*DSN*|*WEBHOOK*)
      return 0 ;;
  esac
  return 1
}

mask() {
  local k="$1" v="$2"
  if is_secret_key "$k"; then
    printf '[REDACTED — %d chars set]' "${#v}"
  else
    printf '%s' "$v"
  fi
}

for pair in "$@"; do
  case "$pair" in
    *=*) : ;;
    *) echo "skipping '$pair' — expected KEY=VALUE" >&2; continue ;;
  esac
  key="${pair%%=*}"
  val="${pair#*=}"

  before="$(grep -c "^[#[:space:]]*${key}=" "$ENV_FILE" || true)"

  # awk, not sed: the value may contain any delimiter character (RPC URLs
  # contain `/` and sometimes `?`), and awk never re-interprets it.
  KEY="$key" VAL="$val" awk '
    BEGIN { k = ENVIRON["KEY"]; v = ENVIRON["VAL"]; done = 0 }
    {
      line = $0
      stripped = line
      sub(/^[#[:space:]]*/, "", stripped)
      if (!done && index(stripped, k "=") == 1) { print k "=" v; done = 1; next }
      print line
    }
    END { if (!done) print k "=" v }
  ' "$ENV_FILE" > "${ENV_FILE}.tmp"
  mv "${ENV_FILE}.tmp" "$ENV_FILE"

  if [ "$before" -gt 0 ]; then
    printf '  updated  %-34s = %s\n' "$key" "$(mask "$key" "$val")"
  else
    printf '  ADDED    %-34s = %s\n' "$key" "$(mask "$key" "$val")"
  fi
done

chmod 600 "$ENV_FILE"
echo
echo "backup: $BACKUP"
echo "restore with:  cp $BACKUP $ENV_FILE"