Skip to content

feat: launchpad connectors (pump.fun, Meteora DBC, Raydium LaunchLab) - #721

Open
fengtality wants to merge 2 commits into
developmentfrom
feat/launch-connectors
Open

fengtality wants to merge 2 commits into
developmentfrom
feat/launch-connectors

Conversation

@fengtality

@fengtality fengtality commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR adds three launchpad connectors (pump.fun, Meteora Dynamic Bonding Curve and Raydium LaunchLab) and the /trading/launch routes. Hummingbot API and Condor can then create tokens and trade bonding curves.

The stateless build/sign/submit work (#682) is no longer in this PR. It moved to the draft PR #734, which is stacked on this one.

Two commits:

  1. chore(raydium): Raydium SDK 0.1.141 to 0.2.73. 0.2 is the first SDK that builds LaunchLab instructions. The commit message lists the renamed fields and math helpers that Gateway reads.
  2. feat(trading): connectors, launch routes, tests and the regenerated openapi.json. create-token takes a pinned metadataUri (required), and Gateway fetches no caller URLs (CodeQL js/request-forgery).

Connectors

pump (new connector, namespace pump)

  • router: swaps on the pump.fun bonding curve. After graduation, a swap goes to the token's canonical PumpSwap pool. BUY is exact token out; SELL is exact token in.
  • amm: PumpSwap pools: quote-swap, execute-swap, pool-info, position-info, quote-liquidity, add, remove, create-pool.
  • launch: token creation (create_v2: Token-2022, 6 decimals, 1B supply) from a metadataUri the caller pinned, with an optional atomic dev buy. Creator fees, claim, migrate and launch history.
  • Config: conf/connectors/pump.yml (slippagePct, lookupTableAddress). lookupTableAddress is empty by default. A create with a dev buy is larger than a legacy transaction, so it needs a lookup table. When none is set, Gateway refuses it with a clear error. Create without a dev buy, then buy through /trading/router.
  • SDKs: @pump-fun/pump-sdk 1.36.0, @pump-fun/pump-swap-sdk 1.19.0, and @pump-fun/pump-sdk-v2 (alias of pump-sdk 2.0.0) for migrate only. 1.36's migrate does not have the accounts that the live program reads, and 2.0 everywhere would make a create with a dev buy too large.

meteora launch (Dynamic Bonding Curve)

  • The new trading type launch on the existing meteora connector, with @meteora-ag/dynamic-bonding-curve-sdk 1.5.12.
  • Curve quote-swap, execute-quote, execute-swap and pool-info. Both sides are exact-in.
  • Token creation from a DBC config: the request's configAddress, or else meteora.launch.configAddress (empty by default; when it is empty, a create without configAddress is refused).
  • After migration, the token trades on DAMM v2 through meteora's amm surface.
  • meteora.yml gets a launch: block (slippagePct, configAddress). Existing configs get it from the template when they load.

raydium launch (LaunchLab)

  • The new trading type launch on the existing raydium connector. It uses Raydium's own LaunchLab platform, curves in SOL or USDC, and graduation to CPMM.
  • Instructions come from the SDK's low-level builders. All accounts are read from the chain, not from Raydium's HTTP API.
  • Token creation (Metaplex metadata limits: name 32, symbol 10, URI 200 bytes) with an optional first buy. Curve quote and swaps. pool-info finds the pool by mint, whatever the quote. Creator fees.

Routes

/trading/launch (new)

Route What it does
POST create-token Creates a token on pump, meteora or raydium from a metadataUri the caller pinned, and signs with the Gateway wallet. Gateway uploads no images or metadata and fetches no caller URL.
GET pool-info Curve state for a launched token (reserves, price, progress, graduated pool)
GET quote-swap Quotes a swap on a launch curve (meteora, raydium)
POST execute-quote / execute-swap Executes on the curve
GET creator-fees Unclaimed pump creator fees for a creator
POST claim-creator-fees Collects pump creator fees (curve and PumpSwap vaults)
POST migrate Migrates a completed pump curve to PumpSwap (permissionless)
GET launch-history A pump token's create, trade and migrate transactions with amounts and fees

Changes to existing behavior a reviewer should know

  • Quote ids are bound to their connector. quoteCache.get/getRequest take the connector. A quoteId from one connector cannot run through another connector's execute path; it gets 400 "Quote not found or expired". Jupiter, 0x, Uniswap and PancakeSwap did not check this before.
  • No /trading/amm/close. test/app.integration.test.ts says the AMM surface must not have them; remove at 100% closes.
  • Security gate: the launch routes that sign (create-token, execute-*, claim-creator-fees, migrate) are behind the API-token gate. test/spec/signing-routes-are-gated.test.ts covers this.
  • pump is added to the amm and router connector enums. meteora and raydium advertise the launch trading type.

Not included

  • Stateless build/sign/submit, the signer seam and Privy wallets: see the draft PR feat: stateless build and submit, one signer seam per chain, Privy wallets (#682) #734.
  • Image or metadata upload by Gateway (imageUrl): Gateway would fetch a URL the caller chose from inside the operator's network. The caller pins the metadata and passes metadataUri.
  • Swig smart-wallet routes and the swigWallet descriptor on build routes.
  • Forked-validator (surfpool) support: refreshForkedAccounts, the Jupiter/DFlow dexes allowlist.
  • Vault and agent-token programs and their routes.
  • Reading Transaction v1 (SIMD-0385) in launch history.
  • A Gateway-owned launch lookup table and the newer fee-claim builds.

Testing

  • pnpm build, pnpm lint (0 errors), pnpm test: 182 suites, 1622 tests pass. I ran them from a clean conf/, as CI does.
  • pnpm generate:openapi leaves openapi.json unchanged.
  • New tests: launch create-token and pool-info routes, pump curve, AMM and router quote math, LaunchLab instruction bytes against a reference mainnet transaction, DBC prepare and quote, and the connector binding of quotes.
  • Docker image built from this branch. It started with an existing config whose root.yml has $namespace pump. GET /config?namespace=pump returns the pump config, and GET /config/connectors lists pump (router, amm, launch), meteora (clmm, amm, launch) and raydium (amm, clmm, launch). The development image does not start with this config, because it has no pump-schema.json.

Lockfile

pnpm-lock.yaml changes a lot. Most of the change is not from this PR. development's lock is already out of sync with its package.json: running pnpm install --lockfile-only with pnpm 10 on development alone rewrites about 7,000 lines. This lock was made with pnpm 11, which the Dockerfile uses with --frozen-lockfile. The image above was built from it.

🤖 Generated with Claude Code

0.2 is the first SDK that can build LaunchLab instructions. It also renames
parts of the CLMM math and a few fields Gateway read untyped:

- PoolInfoLayout's config is `configId` (was `ammConfig`); CLMM pool-info
  read the old name and would lose its fee.
- PoolUtils.isOverflowDefaultTickarrayBitmap moved to PoolUtil; TickUtils,
  LiquidityMath and SqrtPriceMath's tick helpers became TickArrayUtil,
  TickUtil and LiquidityMathUtil (same numbers).
- getAmountsFromLiquidity's slippage amounts are below the amount even for
  `add`, so quotePosition computes the deposit maximums itself.
- CurveCalculator.swap/swapBaseOut became swapBaseInput/swapBaseOutput,
  which also charge the CPMM creator fee; the quote applies it as the
  program does.
- CLMM quotes take the bitmap extension and the chain's block time.
- DEV_CREATE_CPMM_POOL_* are gone; devnet uses DEVNET_PROGRAM_ID.
Comment thread src/connectors/pump/pump.utils.ts Fixed
Comment thread src/trading/pool-swap-routes.ts Fixed
fengtality added a commit that referenced this pull request Oct 20, 2026
…adroom

Raydium AMM v4 deposits failed with "Exceeded desired slippage limit" (0x1e)
whenever the quote side was the limiting one: the v4 branch capped the other
side at the user's raw amount, while the program computes that side from live
vault reserves slightly off the API reserves the quote used. The fixed side
stays what the user gave; the other side's max is the quoted amount times
(1 + slippage), the AmountMax quote-liquidity already reports. CPMM is
untouched.

Ported from feat/stateless-build-endpoints (a8eeb27f1), which #721 did not
take.
@fengtality
fengtality marked this pull request as ready for review October 20, 2026 18:31
@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 3/5

[High impact] The changes reach token launches and asset trades across several Solana workflows.

Do not merge yet: existing configurations can fail startup, and a DBC first buy can spend the wrong currency and amount.

Findings

  1. P1 Older configurations stop startup ▶
  2. P1 First buy spends wrong currency ▶
  3. P2 Shortened history looks complete ▶

Summary

Adds Pump, Meteora DBC, and Raydium LaunchLab connectors, launch routes, and connector-bound quote lookups.

  • Pump.fun tokens trade on curves and PumpSwap pools.
  • Meteora DBC launches tokens and trades their curves.
  • Raydium LaunchLab creates tokens and trades their curves.
  • One launch API routes token creation and curve activity.
  • Swap quotes only run through their issuing connector.
  • Raydium swaps and positions use the newer SDK math.
  • Existing route checks and dependency setup support the connector changes.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Client[Client] --> Launch[Launch routes]
  Launch --> Pump[Pump]
  Launch --> DBC[Meteora DBC]
  Launch --> Raydium[Raydium LaunchLab]
  Pump --> Solana[Shared Solana transaction service]
  DBC --> Solana
  Raydium --> Solana
  Solana --> Wallet[Wallet signs]
  Wallet --> Chain[Solana]
Loading

Reviews (2) · Last reviewed commit: "feat(trading): launchpad connectors (pum..." · Reviewed by Greptile

Comment on lines +29 to +30
slippagePct: ConfigManagerV2.getInstance().get('pump.slippagePct'),
lookupTableAddress: ConfigManagerV2.getInstance().get('pump.lookupTableAddress'),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Older configurations stop startup

If an existing conf/root.yml lacks $namespace pump, Gateway cannot start after this upgrade. PumpConfig.config reads pump.slippagePct during import, but ConfigManagerV2 only copies the new root template when no root file exists. The lookup throws even when the operator never uses Pump.

Add the namespace to existing roots before importing the connector, or load its defaults without requiring a root-file change.

Comment thread src/trading/trading-amm-routes/add.ts Resolved
Comment on lines +105 to +107
if (firstBuy) {
const config = await dbc.getPoolConfig(configAddress);
const buyAmount = toRawAmount(params.firstBuySol, 9);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 First buy spends wrong currency

firstBuySol accepts any DBC configAddress, but this path assumes the config’s quote token is SOL. If the config uses USDC, firstBuySol: 0.1 becomes 100,000,000 raw USDC units—100 USDC—not 0.1 SOL. Both the quote and first-buy builder receive that amount, so a funded wallet can spend the wrong asset and amount.

Reject a positive firstBuySol unless config.quoteMint equals NATIVE_MINT, or expose an amount explicitly measured in the config’s quote token.

Suggested change
if (firstBuy) {
const config = await dbc.getPoolConfig(configAddress);
const buyAmount = toRawAmount(params.firstBuySol, 9);
if (firstBuy) {
const config = await dbc.getPoolConfig(configAddress);
if (!config.quoteMint.equals(NATIVE_MINT)) {
throw httpErrors.badRequest('firstBuySol requires a DBC config quoted in SOL');
}
const buyAmount = toRawAmount(params.firstBuySol, 9);

Comment on lines +143 to +146
if (page.length < PAGE || signatures.length >= maxTransactions) break;
before = page[page.length - 1].signature;
}
const complete = signatures.length <= maxTransactions;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Shortened history looks complete

complete becomes true when the request stops at exactly maxTransactions, even if older transactions remain. With the default limit of 1,000, a token with more than 1,000 transactions returns one full page and reports complete: true. Clients can then leave older trades out of their accounting.

Track whether the last page exhausted the history, or fetch one extra signature before claiming completeness.

…aunchLab)

Launch connectors
- pump: pump.fun bonding-curve swaps on the router surface (auto-routing to
  the token's PumpSwap pool after graduation), PumpSwap pools on the amm
  surface, and token creation (create_v2, optional atomic dev buy).
  New namespace `pump` (connectors/pump.yml, pump-schema.json).
- meteora/launch: the Dynamic Bonding Curve as the `launch` trading type of
  the meteora connector: curve quotes and swaps, pool state, token creation
  from a named DBC config (request `configAddress`, else
  meteora.launch.configAddress).
- raydium/launch: Raydium LaunchLab on Raydium's own platform: token creation
  in SOL or USDC, curve quotes and swaps, pool state (found by mint, whatever
  the quote), creator fees.

/trading/launch routes: create-token, pool-info, quote-swap, execute-quote,
execute-swap, creator-fees, claim-creator-fees, migrate, launch-history.
The routes that sign are behind the API-token gate.

create-token takes a metadataUri that the caller pinned. Gateway fetches no
caller URLs and uploads nothing: metadataUri is required on pump, meteora
and raydium, and imageUrl, description, twitter, telegram, website and
pump.metadataUploadUrl do not exist. An existing conf/connectors/pump.yml
that still has a metadataUploadUrl line is refused at startup until the
line is removed.

Fixes
- A quote executes only at the connector that priced it: the quote cache
  stores each quote under its connector and hands it back to that
  connector only. The launch execute-quote routes use it, and so does every
  router connector.
- The amm and clmm quote-swap and execute-swap routes refuse a pool
  connector that does not run on the chain the caller named.

openapi.json is regenerated.
fengtality added a commit that referenced this pull request Oct 20, 2026
…and Privy wallets (#673, #682)

Every Gateway route that sends a transaction gets a build-* twin that
returns the unsigned transaction, and POST /chains/{chain}/submit
broadcasts what the caller signed. Every execute route signs through one
signer seam per chain, with local, hardware, external and Privy wallets
behind it. This is the build half of the old #721 and the content of
#727, #730, #728, #732 and #729, on top of the launch connectors.

Solana build mode (from #721)
- A build-* route runs the connector's own code and captures the
  transaction at Solana.sendAndConfirmTransactionForWallet instead of
  signing it: simulated, compute budget sized, fresh blockhash, ephemeral
  keypairs partial-signed, fee-payer slot empty. A broadcast attempted
  during a build throws; nothing is sent.
- Routes: router build-swap and build-quote; clmm build-swap, build-open,
  build-add, build-remove, build-collect-fees, build-close and
  build-create-pool; amm build-swap, build-add, build-remove and
  build-create-pool; launch build-swap and build-create-token;
  POST /chains/{chain}/build-transaction for caller instructions; and
  POST /chains/{chain}/submit, which re-merges the ephemeral signatures and
  verifies every signature and the blockhash before it broadcasts.
- The build shape on every build route: extraInstructions, feePayer,
  format (transaction or instructions), memo, references (Solana Pay) and
  priority (normal, high, urgent).
- platformFee on builds, paid to a recipient the caller names (Jupiter
  through its feeAccount, other venues by a transfer after the
  operation). Router quotes take platformFeeBps.
- pancakeswap-sol build routes are refused by name. poll reports
  currentBlockHeight beside the slot.
- Build routes are behind the API-token gate with their execute routes;
  submit stays public like poll.

Build coverage (#727)
- One build response for an operation of several transactions; a wide
  Meteora DLMM open, add, remove, close or collect builds as one response.
- collect-fees and build-collect-fees for Meteora DAMM v2.
- build-claim-creator-fees and build-migrate; creator-fee claims on
  meteora and raydium.
- pump: a dev-buy create names its lookup table, or has one made for it;
  each new lookup table gets its own slot, and a create after a new table
  compiles with the build's fee payer.
- build-transaction takes feePayer, memo and priority. A legacy build's
  compute is sized against the RPC's own blockhash.
- raydium AMM v4 add gives the non-limiting side its slippage headroom.

Signer seam (#730)
- The signer seam interface and the wallet record. Every Solana and EVM
  transaction is signed through it.
- External wallets: Gateway holds no key, and a route that would sign for
  one refuses and names its build twin.
- The key-handling helpers the seam replaced are deleted, with the old
  ledger helpers.
- The route-coverage test: every route that sends a transaction is listed
  with its build twin, and only the seam signs.

EVM build and submit (#728)
- build-* twins and submit for every EVM transaction route. A build
  returns the unsigned transaction with the approvals it needs first.
- Tests for build mode, approvals, submit and the EVM build routes.
- The uniswap execute-quote Permit2 check moved to
  Ethereum.requirePermit2Allowance, so its own test
  (executeQuote-permit2-expiration.test.ts) is deleted; the EVM build-mode
  tests cover the Permit2 path with the max uint48 expiration.

The last build twins (#732)
- Solana build-wrap and build-unwrap, and launch build-quote. The route
  table has no gaps.

Privy wallets (#729)
- A Privy server-wallet REST client with request signing and error
  mapping.
- The privy signer backend on the seam, and the add-privy and
  create-privy routes.
- EVM quantities go to Privy as minimal hex. Wallet list stores change
  through updateListStore, one update at a time.
- The Privy seam test calls the EVM chokepoint the way #728 left it.

openapi.json is regenerated.

Closes #682
@fengtality
fengtality force-pushed the feat/launch-connectors branch from 1d90e39 to 00d543e Compare October 20, 2026 19:14
@fengtality fengtality changed the title feat: launchpad connectors (pump.fun, Meteora DBC, Raydium LaunchLab) and stateless build/submit routes feat: launchpad connectors (pump.fun, Meteora DBC, Raydium LaunchLab) Oct 20, 2026
@rapcmia rapcmia self-assigned this Oct 21, 2026
@rapcmia rapcmia moved this to Under Review in Pull Request Board Oct 21, 2026
@rapcmia

rapcmia commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

00d543e

  • Build, typecheck, lint (0 errors) and OpenAPI pass; regenerated openapi.json is identical to the committed one ✅
  • Connector registration, schemas, metadata and signing-route security checks pass ✅

Pump (launchpad + PumpSwap AMM)

image
  • Create token works on mainnet: new mint, metadata URI echoed back, no pool address ✅
  • Curve buy and sell work through /trading/router: the SOL the curve took and paid back matches the quote to the lamport ✅
  • PumpSwap create pool, add liquidity, buy, sell and remove 100% work on mainnet: deposits and swap amounts match the quotes, and LP returns to 0 ✅
  • Migrate refuses an incomplete curve and an invalid mint with a clear 400 ✅
  • A creator's first fee claim nets far less than the reported claimed amount ❌
    • On mainnet, claimed was 0.002424 SOL but the wallet gained only 0.000925 SOL.
    • collectCoinCreatorFeeInstructions always runs the PumpSwap step, which creates a WSOL account for the PumpSwap creator vault. The creator pays its 0.00149 SOL rent, which goes into an account the creator can't close.
    • Here that rent bought nothing: the PumpSwap step logged "No coin creator fee to collect".
    • A first claim under ~0.0015 SOL loses money.
  • Create-pool and add-liquidity overstate the SOL deposited :exclamati
    • quoteTokenAmountAdded is the wallet's whole SOL change, rent included.
    • Creating a pool with 0.003 SOL reported 0.0107.
    • Fix: report the vault deposit.
  • Not run yet: the migrate success case. On mainnet, completed curves migrate automatically almost immediately, so it needs devnet ⏳

Meteora DBC (launchpad)

image
  • Create token, curve buy and curve sell work on mainnet: the pool uses the requested config and creator, the buy and sell match the quotes exactly, and the 1% fee splits as configured ✅
  • A launch test fails about 5% of the time on valid keys ❌
    • test/connectors/meteora/launch-routes/launch-prepare.test.ts:39 expects every Solana public key string to be 44 characters long, but valid keys can be 43.
    • 544 of 10,000 generated keys were 43 characters.
  • A user can't get a DBC config through Gateway, and nothing explains how ❗
    image
    • create-token needs configAddress, the default is empty, and the PR adds no route or docs for creating one (src/connectors/meteora/launch-routes/createToken.ts:106).
    • Users can create one on Meteora's website (it has a DBC create-config flow), or with the PR's own SDK: QA config AyCRwx…scAh cost 0.006 SOL.
  • On the launch swap route, BUY swaps the base and quote balance changes ❗
    • A 0.01 SOL buy reported baseTokenBalanceChange −0.0115 SOL and quoteTokenBalanceChange +329,899 tokens, although the request named the token as base.
    • Cause: side is passed as undefined to handleConfirmation (src/connectors/meteora/launch-routes/executeQuote.ts:68).
  • Todo/optional: create token with firstBuySol > 0, and migration to DAMM v2 (needs ~86 SOL of buys)

Raydium (LaunchLab + AMM/CLMM)
image

  • LaunchLab and the SDK upgrade's deterministic tests pass, including instruction bytes checked against a reference mainnet transaction ✅
  • LaunchLab token creation works on mainnet with explicit 1B supply / 80% curve / 85 SOL raise terms; the returned mint and pool match pool-info and the expected SOL global ✅
  • LaunchLab buy and sell work on mainnet: retry 1/3 bought exactly the quoted 372,387.596171 tokens for 0.01 SOL, and the full-balance sell returned exactly the quoted 0.009791101 SOL; token balance returned to zero ✅
  • LaunchLab swap responses use the same swapped base/quote labels as Meteora ❗
    • Same cause at src/connectors/raydium/launch-routes/swap.ts:217 (side passed as undefined).
    • Fix: pass the side.
  • AMM v4 buy and sell work on mainnet: exactly 0.02 SOL each way, within the quotes ✅
  • CPMM add and remove liquidity, buy and sell work on mainnet (existing SOL/USDC pool); the PR's rewritten CPMM swap math holds on both exact-in and exact-out ✅
  • CLMM sell, open position (range snaps to ticks), add, remove 100%, collect fees and close work on mainnet ✅
  • Every CLMM BUY fails with HTTP 500 "Non-base58 character" ❌
     #Live mainnet test buy 0.02 SOL with USDC on the Raydium CLMM SOL/USDC pool
     curl -sS -X POST 'http://127.0.0.1:15888/trading/clmm/execute-swap' \
       -H 'Content-Type: application/json' \
       --data '{"connector":"raydium","chainNetwork":"solana-mainnet-beta","walletAddress":"AbCpsXy2HAC5yWe3YwfysYk4x4FSd13WduKkCooREZK2","baseToken":"SOL","quoteToken":"USDC","amount":0.02,"side":"BUY","poolAddress":"3ucNos4NbumPLZNWztqGHNFFgkHeRMBQAVemeeomsUxv","slippagePct":1}'
     
     {"statusCode":500,"error":"HttpError","message":"Failed to execute clmm swap: Non-base58 character"}
    
    • A 0.02 SOL buy quote or execute on the main SOL/USDC CLMM pool (3ucNos4N…) fails before signing; sells work.
    • Cause: the SDK upgrade (0.1.141 → 0.2.73). The new computeAmountIn calls new PublicKey(key) on each tickArrayCache key, but fetchMultiplePoolTickArrays keys the cache by tick index ("-22500"). Called from src/connectors/raydium/clmm-routes/quoteSwap.ts:68.
  • Found during testing but already on development, so not caused by this PR:
  • Todo/optional: create CPMM pool. Raydium charges a 0.15 SOL create fee on every config, so it needs a budget decision

Test notes

  • "Curve" means the bonding curve, the launchpad's own trading venue for a new token. The full supply starts in it, and a formula sets the price: each buy raises it and each sell lowers it. Once enough SOL has gone in, the token graduates to a normal AMM pool (PumpSwap, DAMM v2 or CPMM). "Curve buy/sell" means trading before graduation; "AMM buy/sell" means trading in a pool. The test tokens never graduated.
  • All live requests use chainNetwork: "solana-mainnet-beta". The slash form solana/mainnet-beta fails schema validation.
  • Pump curve trades go through /trading/router with connector: pump, where BUY amount is in tokens. /trading/launch/*-swap accepts only meteora and raydium.
  • launch/pool-info takes baseMint, not baseToken.
  • A Pump create with devBuyAmount needs pump.lookupTableAddress; without it Gateway refuses with a clear 400. The Pump token was created without a dev buy and then bought through the router.
  • Meteora DBC used a QA-owned config created with the PR's SDK create-dbc-config.js
  • Live cost on mainnet: Pump 0.0156 SOL; Meteora 0.0223 SOL plus 0.006 SOL for the config; Raydium AMM/CLMM 0.0164 SOL + 0.0154 USDC (0.0148 SOL of it is CLMM position metadata rent).

@rapcmia rapcmia added this to the v2.18 milestone Oct 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Under Review

Development

Successfully merging this pull request may close these issues.

3 participants