How Echo works
Client-side Solana copy desk. Echo watches wallets you add, books paper copies by default, and spends SOL from a trading key only when a wallet is armed live. Background desk keeps copies firing after you leave the tab. Live only copies SOL pairs.
First run
- Open Desk. Paste an HTTPS RPC. Save. Websocket is derived automatically.
- Optional: import a trading key. Dedicated burner. Passphrase of 8+ characters encrypts it in this browser.
- Open Wallets. Add a caller. First screen: label, address, enabled, Paper, buy SOL, standard profile, copy sells. Turn Enabled on.
- Header should read watching. Echo now mirrors that wallet.
- Paper fills land on Fills and Positions. Live does nothing until you flip that wallet and unlock the key. Click Live locked in the header and enter the passphrase. Click Live armed to lock it again.
How a copy fires
- Tracked wallet buys a mint. Non-SOL pairs are dropped and never booked.
- Desk caps run first: min caller size, skip-if-already-bought, max buy per mint, exclude wallet.
- Gate path follows this wallet’s live gate (from Profile). Fast (standard / sniper): local caps then send. Strict (conservative) and all paper: snapshot and every set gate must pass. Miss any one → skip. Unreadable metric → fail closed. Birth tape is not paged for tokens older than 20 min.
- Paper books the fill. Live signs a swap (PumpPortal, then Jupiter). Sender races Helius / Jito / RPC and keeps the first signature. Jupiter attaches both a priority fee and a Jito/Sender tip. Echo waits for on-chain confirmation, then books actual SOL in and tokens from your tx. A live fill without a chain signature is ERROR, not FILLED. Sniper outbids the caller’s CU/tip on that send.
- Position stays open until copy-sell, TP, SL, trail, spike, max hold, or Flatten. Live auto-exits (TP/SL/spike/timeout/copy-sell) only fire on a fresh mark, and only close if executeSwap returned a signature. Failed sell → fill exit-failed, bag stays open, retry, then halt auto-exit on that wallet. solOut 0 never books −100%. Manual Close can drop a ghost bag (no tokens) as no-bag / buy never landed — never as stop-loss.
Tickers open Padre. Click a ticker or CA to copy. Click a wallet name to open that mirror’s settings. Skips are fills, not opens.
Header
- PnL / Unreal — click to Blotter. Tape shows live open bags only; click to Positions.
- Live armed / locked — lock the key, or unlock with the passphrase. BG means Background desk is on.
- Flatten closes every open copy. Live flatten still needs a sell signature unless the bag is empty (manual ghost drop). Halt stops the engine.
Pages
- Blotter — KPIs, equity, tape. Defaults to live. Switch Live / Paper / All.
- Wallets — first screen is ~7 controls + profile. Collapse a row for gates. Sort. Filter live/paper (stats follow the filter). Hide off. Global buy / max buy / min caller / skip-if-bought. Import merge (default) or replace. Icons: On, Paper/Live, coach (green after apply), history, reset PnL, edit, trash.
- Positions — open inventory. Closed book filters All / Live / Paper. Sparkline is mark vs entry since fill.
- Fills — filled / skipped / failed. Filter to filled only. Token size is compact with % of supply.
- Log — one row per trigger, including skips. Shadow gates. Timing, venue, send path, fees, entry/exit signatures. Every flatten attempt logs exitSignature, sellVenue, sellError. JSONL export.
- Desk — RPC, Jupiter key, send path, background, trading key. Fee mode and live gate here are desk fallbacks; sniper/conservative profiles override per wallet.
Profiles
Always shown on Add/Edit. Writes slip, prio, tip, and live gate. Prio/tip stay off the first screen unless Customize. Slip shows on sniper or Customize. Exits and extra gates sit behind disclosures. Tape is one switch (13 / 0.5 SOL / top-3 80%). Pair is one-way — mutual pair is rejected.
| Profile | Slip | Prio | Tip | Live gate | Send |
|---|---|---|---|---|---|
| conservative | 10 | 0.00015 | 0.00003 | strict | desk feeMode |
| standard | 18 | 0.0003 | 0.00008 | fast | desk feeMode |
| sniper | 25 | 0.0005 | 0.00015 | fast | outbid caller |
| custom | yours | yours | yours | yours | desk feeMode |
Paper vs live
Paper books copies that pass gates. No SOL leaves the key. Live uses the same desk caps (and snapshot gates if strict), then signs. A skip in paper is a skip in live. Live PnL, log, and exits use on-chain SOL in/out. Live FILLED requires an entry signature. Live TP/SL/spike do not close without a sell signature. Failed sells stay open as exit-failed. solOut 0 is never −100%. Auto-exits need a fresh quote. Mode is per wallet. Header Halt is global. Unlock from the Live locked pill.
Launch quality
On by default for new wallets. Pages pump trades from birth — not the last 32 signatures. Quiet-clean launches pass. Headcount alone is not a reject. Fast live skips this wait and only runs local desk caps. Tokens older than 20 min are not birth-paged.
≤ 20 min, birth reached. Skip instant-bond over $200k, dev-sold, snipers ≥ 40% or first-10 ≥ 60%. Caution band (20–40% / 40–60%) only rejects if buyers are under the ghost floor (default 10).
Older than 20 min. If aged liveness is on: pass when last-60s buyers ≥ 20 and liq ≥ $10k. Off skips those. This is what killed “1m buyers unavailable.”
Fetch failed. Skip. Age is not treated as failure.
Coach
Brain icon. Fits gates and exits on this wallet’s paper closes (not skips). Needs 5 paper closes. Apply and stay paper, or apply and flip live. Brain turns green after apply. In-sample only.
Import / export
JSON or CSV. Keys are the column in each table. Address aliases: address, wallet, pubkey. Booleans: true/false, 1/0, yes/no, on/off. Blank optional numbers = off.
Re-uploading defaults to merge (gates, size, profile update; book stays). Toggle import to replace to wipe that wallet’s PnL and fills. Omitted columns in replace come back as defaults.
PnL cards
Share on a closed position. Stock backgrounds or upload one (saved on this desk). Share posts to X when the browser allows files.
Rotate on a wallet row resets that book. Reset PnL on Wallets clears the whole desk book. Size, gates, and mode stay.
Log
Append-only. Every trigger is a row: FILLED, SKIPPED, or ERROR. Skips record which gate closed and whether the metric was missing (fail-closed) or a real threshold. Shadow gates record what every protection would have said even if it was off. Live FILLED requires an entry signature. Live rows record detect/gate/build/send/land ms, venue, send path, fees used, caller cu/tip, slot delta, entry and exit signatures separately, on-chain vs marked SOL out, skip-if-bought / open SOL in mint, token age, whether live used an on-chain fill vs quoted price, and every flatten attempt (exitSignature, sellVenue, sellError). Failed live sells stay open as exit-failed; solOut 0 never writes −100%. Download JSONL from the page.
Skip & exit reasons
- not a SOL pair — Echo only copies SOL-quoted buys. USDC/USDT (and other) pairs are dropped, not booked.
- already bought — Global skip-if-bought is on and this mint is already on the book.
- caller buy … < X SOL — Tracked wallet spent less than the global min caller size.
- exclude wallet already in — The exclude pubkey is already on the tape.
- instant bond mcap … > $200k — Bonded in ≤60s and mcap already above $200k. Instant-bond trap.
- dev sold at launch — Creator sold in the first 60 seconds.
- snipers N% ≥ 40% — First-60s buyers still hold ≥40% of supply.
- birth top10 N% ≥ 60% — First 10 distinct buyers still hold ≥60% of supply.
- thin + concentrated — Caution-band snipers (20–40% or top10 40–60%) and buyer count under the ghost floor.
- aged thin — Token older than 20 min, last-60s buyers < 20 or liquidity < $10k.
- aged, birth not reachable — Token is old and this wallet has aged-liveness off.
- aged liveness unavailable — Could not count last-60s buyers or liquidity on an aged token.
- launch tape failed — Pump coin/trades fetch missed. Genuine unknown — fail closed.
- launch birth unreachable — Under 20 min, but the first-60s set was not reached in the page budget.
- tape unavailable — Older build. Missing pair tape is not a skip anymore.
- stand down: … — Crowded small-ticket tape. Echo refused the chase.
- tape not concentrated — Early book is not thin + top-3 concentrated enough.
- max buy N SOL, already X in — Desk-wide cap. This mint already has as much SOL in open copies as Max buy allows.
- would skip: … — Paper still booked historically; those are no longer opened. Hover the fill.
- max hold — Held past max-hold minutes. Flattened. (Engine code: timeout.)
- 1m buyers unavailable — Old gate. Birth window had scrolled out of 32 signatures. Launch quality replaced it.
- no signature — Live buy never returned a chain signature. Logged ERROR, not FILLED. No open bag.
- no bag — Close/exit found zero tokens in the desk wallet. Book dropped without a swap.
- buy never landed — Live entry signature never confirmed. Ghost fill — PnL 0.
- No route — PumpPortal and Jupiter both failed to land a swap — Neither builder produced a landing tx.
- exit-failed — Live sell did not return a signature or tokens did not leave. Position stays open. Auto-exit retries, then halts that wallet. netPct is not booked as −100%.
Wallet fields
Identity
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Label | label | Display name on the desk. Does not affect copies. | Any string | Wallet | Wallet |
| Address | address | Tracked Solana pubkey Echo mirrors. Buys and sells from this address are the signal. | Base58 pubkey, 32–44 chars | Rejected — required | — |
| Enabled | enabled | Master switch for this mirror. Off = Echo ignores the wallet even if the engine is running. | true / false (also 1/0, yes/no, on/off) | true on new rows | true |
| Mode | mode | Paper books fills with no chain spend. Live signs a swap from your trading key when gates pass. | paper | live | paper | paper |
| Profile | profile | Writes slip, prio, tip, and live gate. conservative = slip 10 / prio 0.00015 / tip 0.00003 / strict. standard = 18 / 0.0003 / 0.00008 / fast. sniper = 25 / 0.0005 / 0.00015 / fast and outbids the caller on that send. custom keeps your numbers. First screen of the form is label, address, enabled, paper/live, buy SOL, profile, copy sells, notes. Prio/tip stay off that screen unless Customize. Slip shows on sniper or Customize. | conservative | standard | sniper | custom | standard | standard |
| Live gate | liveGateProfile | Per-wallet. fast = local desk caps then send. strict = snapshot + launch/tape gates. Profile writes this. Desk liveGateProfile is the fallback. | fast | strict | Desk default (fast) | fast |
| Notes | notes | Your comment. Not used by the engine. | Any string | Blank | blank |
Size and fees
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Buy amount (SOL) | buyAmountSol | SOL size of each copy buy for this wallet. Paper and live use the same size. | Number > 0 | Desk default | 0.05 (or Desk default) |
| Slippage % | slippagePct | Max price move allowed on the swap. Fill fails if the coin ran past this. Profile writes it. Visible on sniper or Customize only. | Number ≥ 0 | Desk default or profile | 18 (standard profile) |
| Priority fee (SOL) | priorityFeeSol | Compute-unit priority on the live swap. Attached together with the Jito/Sender tip. Hidden on the first form screen unless Customize. Profile writes it. | Number ≥ 0, SOL not lamports | Desk default or profile | 0.0003 (standard) |
| Jito tip (SOL) | jitoTipSol | Landing tip. Sender min is ~0.00008 SOL. Capped with priority so fees stay under 3% of buy size. Hidden unless Customize. Profile writes it. | Number ≥ 0, SOL | Desk default or profile | 0.00008 (standard) |
Exits
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Copy their sells | copySells | When the tracked wallet sells this mint, Echo flattens the open copy. Reason: copy sell. | true / false | true | true |
| Take profit % | takeProfitPct | Close when mark is this % above entry. | Number ≥ 0, or blank | Off | 100 |
| Stop loss % | stopLossPct | Close when mark is this % below entry. Stored as a positive number. | Number ≥ 0, or blank | Off | 30 |
| Trailing stop % | trailingStopPct | After price makes a high, close if it drops this % off the high-water mark. | Number ≥ 0, or blank | Off | off |
| Max hold (minutes) | maxHoldMinutes | Flatten after this many minutes, even if TP/SL have not hit. Fill reason shows as max hold (raw code: timeout). | Integer ≥ 0, or blank | Off | off |
| Spike exit | spikeExit | Arm after the call-wave, then trail off the local top. Separate from trailing stop. | true / false | false | false |
| Arm at +% | spikeArmPct | Unrealized gain that arms spike exit. | Number ≥ 0 | 20 if spike is on | 20 |
| Trail % off local top | spikeTrailPct | Once armed, flatten if price drops this % from the post-arm high. | Number ≥ 0 | 5 if spike is on | 5 |
Entry filters
Empty = off. Miss any set gate → skip. Nested filters skip when the metric is unavailable.
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Min market cap ($) | minMarketCapUsd | Skip if Dexscreener mcap/FDV is below this. | USD number, or blank | Off | off |
| Min 1m volume ($) | minVolume1mUsd | Skip if one-minute USD volume is below this. | USD number, or blank | Off | off |
| Min pool liquidity ($) | minLiquidityUsd | Skip if pool USD liquidity is below this. | USD number, or blank | Off | off |
| Min unique holders | minHolders | Skip if holder count is below this (Rugcheck). | Integer, or blank | Off | off |
| Top 10 holders own less than % | maxTop10Pct | Skip if the top 10 (incl. LP / curve) own more than this %. | 0–100, or blank | Off | off |
Tape safety
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Tape safety | tapeFilter | Form is one switch: Stand down on crowded tape. When on, numbers are hardcoded (13 / 0.5 / 10 / 80). The four tape number columns still import/export. | true / false | false | false |
| Stand down above N buyers | tapeStandDownBuyers | If unique buyers exceed this and tickets are small/dispersed, skip (stand down). Hidden on the form; hardcoded to 13 when tape is on. | Integer ≥ 1 | 13 if tape is on | 13 |
| Small ticket (SOL) | tapeSmallTicketSol | Median buy below this counts as small-ticket for stand-down. | SOL number ≥ 0 | 0.5 | 0.5 |
| Safer max buyers | tapeSafeMaxBuyers | Safe path: unique buyers at or below this, with top-3 concentration met. | Integer ≥ 1 | 10 | 10 |
| Safer top-3 buy % | tapeTop3BuyPct | Share of early buy SOL that must sit in the top 3 wallets to count as concentrated. | 0–100 | 80 | 80 |
Coordination and launch
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| Pair wallet | pairWallet | Wait up to 90s for this second pubkey to also buy the mint. Skip if they never show. One-way only — A cannot wait on B if B already waits on A. | Solana pubkey, or blank | Off — no wait | off |
| Exclude wallet | excludeWallet | Skip if this pubkey is already in the tape (or already bought). | Solana pubkey, or blank | Off | off |
| Launch quality | launchGate | Three-state launch screen. Replaces the old first-minute buyer count. See Launch quality. | true / false | true on new wallets; existing wallets inherit on if they had a 1m floor | true |
| Aged tokens use liveness | launchAgedLiveness | If the coin is older than 20 min, pass when last-60s buyers ≥ 20 and liq ≥ $10k. Off skips aged tokens. | true / false | true | true |
| Ghost-town floor | minBuyers1m | Distinct first-60s buyers. Only rejects when sniper concentration is in the caution band. Not a hard count gate. | Integer ≥ 0, or blank (= 10) | 10 | 10 |
| Max run-up % since their buy | maxRunupPct | Anti-chase. Skip if price already ran this % from the tracked wallet’s fill to now. | Number ≥ 0, or blank | Off | off |
Desk fields
| Field | Key | What it does | Accepted | Empty | Default |
|---|---|---|---|---|---|
| RPC endpoint | — | HTTPS Solana RPC. Websocket is derived. Needed to watch logs and send live swaps. | https://… URL | Engine cannot watch | blank |
| Jupiter API key | — | Optional. Routes live non-pump swaps through Jupiter with your key. | API key string | Public Jupiter / lite | blank |
| Engine | — | Global halt. Off stops all copies. Per-wallet Enabled still applies when the engine is on. | Play / pause in the header | — | on |
| Default size / slip / prio / tip | — | Used when a new wallet is added or a CSV omits those columns. | Same units as wallet fields | — | 0.05 / 15 / 0.0003 / 0.00008 |
| Min caller buy | — | Desk-wide. Skip if the tracked wallet spent less than this SOL on the signal. | SOL | off | off |
| Skip if already bought | — | Desk-wide. If this mint is already on the book (open or closed), later mirrors skip it. | on / off | off | off |
| Max buy (SOL) | — | Desk-wide cap per mint. Open copies of the same coin cannot sum past this. Extra mirrors skip (max buy). | SOL, or blank | off | off |
| Background desk | — | Keeps watching after you leave the tab. Paper always. Live also holds the unlocked key in this app’s server memory until Halt. | on / off | on | on |
| Fee mode | — | static = desk/wallet floors. outbid = 10% over the caller’s prio/tip when those can be read from their tx (no tip_floor RPC). Desk setting. Sniper profile forces outbid on that wallet’s send. No per-wallet feeMode radio. | static | outbid | static | static |
| Live gate profile | — | Desk fallback. Per-wallet liveGateProfile (from Profile) wins. fast = local caps then send. strict = snapshot + launch/tape, 250ms live budget. Birth tape is not paged for tokens older than 20 min. | fast | strict | fast | fast |
| Live send path | — | How a signed live swap is submitted. sender (default) races Helius Sender + Jito + RPC and returns the first signature. Jupiter swap attaches both a priority fee and a Jito/Sender tip (CU patched after deserialize if the API is exclusive). PumpPortal then Jupiter build. Does not replace those builders. | sender | jito | rpc | sender | sender |
| Trading key | — | Browser keypair that signs live buys. Passphrase (≥8 chars) encrypts it in this browser. Background live also holds it in this app’s server memory until Halt. Do not import a vault. | Secret key / JSON array / base58 | Live wallets cannot fire | none |
Fail-closed: if a gate is on and Echo cannot read the metric, it skips. Fast live only runs local desk caps. Use a funded burner for live. Do not import a vault. Live FILLED implies an entry signature. Live close (TP/SL/spike/timeout/copy-sell) implies a sell signature — otherwise the bag stays open as exit-failed and auto-exit retries, then halts that wallet. solOut 0 is never −100%. Auto-exits only fire on a fresh mark.