feat(transmute): sell-route detection (Jupiter) + design Rev 3
Re-prioritizes the core loop (sell→feed→close; burn for unsellable only) per
user direction. READ-ONLY this increment — quotes + risk flags only, no swap
build/sign, no funds moved.
- docs: Rev 3 — §5 scope, §6 TRANSMUTABLE active, new §6.1 (Jupiter Ultra
routing incl. pump.fun pre/post-graduation + Token-2022; 3rd-party-swap trust
model = simulate + lamports-delta ≥ min-out + sole-signer + no
SetAuthority/Approve/bad-CloseAccount; Shield; price-impact/slippage/dust
guards; Essence model 1 = opt-in off-chain tally, no custody).
- @pyre/core: SellInfo type + TokenAccountDto.sell.
- @pyre/api: keyless Jupiter client (lite-api: /swap/v1/quote + /ultra/v1/shield);
bounded /api/scan enrichment — upgrades INCINERATE_ONLY→TRANSMUTABLE when a
worthwhile route exists; dust gate (proceeds ≤ fee+rent → keep burn); price
impact >10% blocks; graceful degrade if Jupiter down.
- @pyre/web: shows "Sellable for ~X SOL", price impact, Shield chips; disabled
"Sell & feed the PYRE (soon)" CTA (execution is the next, audited step).
Tracker: Phase 6 "swap candidate detection" + "route quote preview" done.
typecheck 8/8, core 85, solana 19, web build green.
LIVE FINDING: both pump.fun tokens ARE routable via Jupiter (so no pump.fun
engine needed) but quote ~0.0000097 SOL each — far below their ~0.002 SOL rent,
so the dust gate correctly keeps them INCINERATE_ONLY ("not worth selling").
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,13 @@
|
||||
> dust. PYRE supports Token-2022 conservatively, gating on account/mint
|
||||
> **extensions** (see §7.1). The original brief's "skip Token-2022" stance is
|
||||
> superseded by this revision.
|
||||
>
|
||||
> **Revision note — Rev 3 (2026-05-31):** The core loop is *sell sellable tokens
|
||||
> → feed the PYRE (opt-in Essence) → close the emptied account*; **burning is for
|
||||
> unsellable tokens only**. Selling (TRANSMUTABLE) is pulled into near-term scope
|
||||
> via the **Jupiter** aggregator (§6.1) — PYRE builds no swap math and runs no
|
||||
> pump.fun engine. Essence is **model 1**: net SOL stays in the user's wallet and
|
||||
> is recorded as an opt-in off-chain tally; **no custody** until the v1.0 program.
|
||||
|
||||
---
|
||||
|
||||
@@ -144,10 +151,16 @@ account/mint extensions are safe to act on (see §7.1). Token-2022 accounts with
|
||||
unhandled extensions (confidential transfer, withheld transfer fees, unknown
|
||||
extensions) and all frozen accounts are skipped.
|
||||
|
||||
**v0.1 must NOT include:** automatic Pump.fun launch, user-contributed Essence
|
||||
vault, custom PYRE Solana program, NFT handling, automatic valuable-token
|
||||
sacrifice, custodial signing, background wallet automation, on-chain swap routing
|
||||
(TRANSMUTABLE), or any Token-2022 confidential-transfer / fee-harvest flows.
|
||||
**Selling scraps (Transmute) is now near-term scope** (Rev 3 — see §6.1): the core
|
||||
loop is *sell sellable tokens for SOL → feed the PYRE (opt-in Essence) → close the
|
||||
emptied account*; burning is reserved for genuinely unsellable tokens. Selling is
|
||||
routed through Jupiter (third-party aggregator); PYRE never builds the swap math
|
||||
itself and never takes custody (Essence is an opt-in off-chain tally — model 1).
|
||||
|
||||
**v0.1 must NOT include:** automatic Pump.fun launch, custom PYRE Solana program,
|
||||
NFT handling, automatic valuable-token sacrifice, custodial signing, background
|
||||
wallet automation, any Essence VAULT/custody (no "deposit" until the v1.0 on-chain
|
||||
program), or any Token-2022 confidential-transfer / fee-harvest flows.
|
||||
|
||||
### MVP v0.2 — Prometheus Meta Mixer
|
||||
AI generation from burned/cleaned token context.
|
||||
@@ -194,9 +207,12 @@ Token accounts are classified into conservative categories.
|
||||
- **INCINERATE_ONLY** — no safe swap route but may be burnable. *Action:* user
|
||||
may burn balance to zero; if account becomes empty, close it; recovered rent
|
||||
returns to user.
|
||||
- **TRANSMUTABLE** — has a safe swap route and passes risk checks. *Action:* user
|
||||
may swap token into SOL; net swapped SOL may become Essence **only if the user
|
||||
opts in**.
|
||||
- **TRANSMUTABLE** — has a safe swap route (via Jupiter, §6.1) that passes the
|
||||
price-impact / slippage / dust guards. *Action:* user may swap the token into
|
||||
SOL; the net SOL stays in the user's wallet, and may be recorded as Essence
|
||||
("feed the PYRE") **only if the user opts in** (off-chain tally, no custody).
|
||||
This is the preferred outcome for any token with real liquidity — burning is
|
||||
for unsellable tokens only.
|
||||
- **PROTECTED_SKIP** — not touched by default. Examples: SOL/WSOL special cases,
|
||||
USDC/USDT/major assets, valuable meme tokens, NFTs, LP tokens, receipt tokens,
|
||||
staked tokens, suspicious tokens, frozen accounts, delegated accounts,
|
||||
@@ -217,6 +233,43 @@ excluded from any future swap.
|
||||
> **Default rule: Unknown means skip** — unknown token program *or* unknown/unsafe
|
||||
> Token-2022 extension.
|
||||
|
||||
### 6.1 Selling scraps (Transmute) — Jupiter + the third-party-swap trust model
|
||||
|
||||
A non-empty token is **TRANSMUTABLE** (preferred over burning) when it has a safe
|
||||
route to SOL. PYRE does **not** implement swap math or run a pump.fun engine — it
|
||||
uses **Jupiter** as the aggregator:
|
||||
|
||||
- **Routing:** Jupiter **Ultra** (`/ultra/v1/order` → user signs → `/ultra/v1/execute`,
|
||||
keyless via `lite-api.jup.ag`) routes both **pre- and post-"graduation" pump.fun**
|
||||
tokens and **Token-2022**. If Ultra returns no route for a mint, optionally fall
|
||||
back to **PumpPortal**'s keyless local-trade API (bonding-curve sell); if neither
|
||||
routes, the token is unsellable → INCINERATE_ONLY or close-for-rent.
|
||||
- **Output:** sell to wSOL with `wrapAndUnwrapSol` so the user receives **native SOL**.
|
||||
- **Risk pre-screen:** call Jupiter's **Shield** API per mint; surface
|
||||
freeze/mint-authority and low-liquidity warnings.
|
||||
- **Guards (a route alone is not enough):** block if `priceImpactPct` exceeds the
|
||||
threshold (warn ~2–3%, hard cap ~10%); cap slippage; and a **dust gate** — if the
|
||||
estimated NET SOL ≤ (tx fee + reclaimable rent), selling is not worth it → keep it
|
||||
INCINERATE_ONLY / suggest close-for-rent instead.
|
||||
|
||||
**Trust model for a third-party-built swap tx (critical).** The swap transaction is
|
||||
built by Jupiter, not PYRE, and is multi-instruction with address-lookup-tables —
|
||||
so it **cannot be byte-matched** the way our own close/burn tx is (§16). Before the
|
||||
user signs, PYRE must instead:
|
||||
|
||||
1. **Simulate** the transaction and confirm the user's **SOL balance delta ≥
|
||||
`otherAmountThreshold`** (the quote's min-out) with no simulation error — this
|
||||
validates the economic effect regardless of route structure.
|
||||
2. Confirm the **only required signer is the user** (no co-signer / foreign fee payer).
|
||||
3. Scan instructions and **reject any `SetAuthority`, delegate `Approve` to a foreign
|
||||
address, or `CloseAccount` whose destination is not the user**.
|
||||
4. Confirm proceeds credit the **user's** account.
|
||||
|
||||
The user always signs in their own wallet (PYRE never holds keys). **Essence
|
||||
("feed the PYRE") = the net SOL is recorded as an opt-in, off-chain tally only;
|
||||
proceeds stay in the user's wallet and PYRE takes no custody** until the v1.0
|
||||
on-chain program. Rent and Essence are always kept separate (§3).
|
||||
|
||||
---
|
||||
|
||||
## 7. Token Safety Rules
|
||||
|
||||
Reference in New Issue
Block a user