@parabolicfamily/mcp 0.2.0 → 0.2.1
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/README.md +17 -4
- package/abi/ParabolicSessionModule.json +362 -0
- package/dist/abi.d.ts +0 -2
- package/dist/abi.js +0 -2
- package/dist/abi.js.map +1 -1
- package/dist/coins.js +2 -1
- package/dist/coins.js.map +1 -1
- package/dist/docs.js +1 -1
- package/dist/format.d.ts +2 -1
- package/dist/format.js +3 -2
- package/dist/format.js.map +1 -1
- package/dist/parabolic.d.ts +1 -0
- package/dist/parabolic.js +10 -5
- package/dist/parabolic.js.map +1 -1
- package/dist/routed.d.ts +1 -1
- package/dist/routed.js +1 -1
- package/dist/server.js +7 -1
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/src/abi.ts +0 -3
- package/src/coins.ts +2 -1
- package/src/docs.ts +1 -1
- package/src/format.ts +3 -2
- package/src/parabolic.ts +10 -5
- package/src/routed.ts +2 -2
- package/src/server.ts +7 -1
package/src/parabolic.ts
CHANGED
|
@@ -9,7 +9,7 @@ import { DEPLOYMENTS, NATIVE_QUOTE, chainName, explorerUrl, siteBase, type Confi
|
|
|
9
9
|
import { deployedAt } from "./deployed.js";
|
|
10
10
|
import { applySlippage, graduationMarketCap, graduationSplit, marketCap, passesPriceBound, poolIdOf, priceImpact, quoteBuy, quoteSell, reservedTokensFor, spotPrice, toNumber, type CurveTerms } from "./curve.js";
|
|
11
11
|
import { docsText } from "./docs.js";
|
|
12
|
-
import { addrOf, amount, big, bool, endpointHost, num, parseAddress, parseAmount, safeMessage, str } from "./format.js";
|
|
12
|
+
import { addrOf, amount, big, bool, endpointHost, num, parseAddress, parseAmount, safeMessage, shortAddr, str } from "./format.js";
|
|
13
13
|
import { quoteBlock, quoteUnitOf, defaultQuoteOf, type QuoteBlock, type QuoteUnit } from "./quote-unit.js";
|
|
14
14
|
import { RestApi, type PairFilter } from "./restapi.js";
|
|
15
15
|
import { RoutedTrades } from "./routed.js";
|
|
@@ -300,7 +300,7 @@ export class Parabolic {
|
|
|
300
300
|
const unit = quoteUnitOf(gas.symbol, chainId);
|
|
301
301
|
return { pairToken: NATIVE_QUOTE, symbol: gas.symbol, decimals: gas.decimals, unit, isNative: true, block: quoteBlock(unit, NATIVE_QUOTE, gas.decimals, true) };
|
|
302
302
|
}
|
|
303
|
-
const short =
|
|
303
|
+
const short = shortAddr(pairToken);
|
|
304
304
|
const raw = await this.read(pairToken, tokenAbi, "decimals").catch(() => undefined);
|
|
305
305
|
const decimals = num(raw);
|
|
306
306
|
if (raw === undefined || !Number.isInteger(decimals) || decimals < 0 || decimals > 36) {
|
|
@@ -584,7 +584,7 @@ export class Parabolic {
|
|
|
584
584
|
private async chainDetail(l: Launch) {
|
|
585
585
|
const [tk, c, hook, quote] = await Promise.all([
|
|
586
586
|
this.readMany(l.token, tokenAbi, ["name", "symbol", "totalSupply", "getTokenInfo"]),
|
|
587
|
-
this.readMany(l.curve, curveAbi, ["getReserves", "realQuoteReserve", "graduated", "readyToGraduate", "launchedAt", "currentSnipeTaxBps", "snipeTaxStartBps", "snipeTaxSeconds", "feeBps", "creatorTaxBps", "phantomQuote", "reservedTokens", "sellableTokens", "protocolFeeShareBps", "buybackBurnBps", "isNativeQuote"]),
|
|
587
|
+
this.readMany(l.curve, curveAbi, ["getReserves", "realQuoteReserve", "graduated", "readyToGraduate", "launchedAt", "currentSnipeTaxBps", "snipeTaxStartBps", "snipeTaxSeconds", "feeBps", "creatorTaxBps", "phantomQuote", "reservedTokens", "sellableTokens", "protocolFeeShareBps", "buybackBurnBps", "buybackEnabled", "isNativeQuote"]),
|
|
588
588
|
this.hookAddress(),
|
|
589
589
|
this.quoteAsset(l.pairToken),
|
|
590
590
|
]);
|
|
@@ -609,7 +609,12 @@ export class Parabolic {
|
|
|
609
609
|
const currentSnipeBps = num(c.currentSnipeTaxBps);
|
|
610
610
|
const protocolShareBps = num(c.protocolFeeShareBps);
|
|
611
611
|
const buybackBurnBps = num(c.buybackBurnBps);
|
|
612
|
-
|
|
612
|
+
// The creator's switch, read off the curve (MONEY-5): a pre-17-Sep coin whose creator called
|
|
613
|
+
// `setBuybackEnabled(false)` earmarks no buyback slice, so its whole creator bucket is the creator's. The site
|
|
614
|
+
// and /api/v1 pass the same switch to `feeSplit` (web/lib/curve.ts); without it this tool showed 50/30/20 for a
|
|
615
|
+
// coin the site shows as 70/30.
|
|
616
|
+
const buybackEnabled = bool(c.buybackEnabled);
|
|
617
|
+
const buybackOfFeeBps = buybackEnabled ? Math.round(((10_000 - protocolShareBps) * buybackBurnBps) / 10_000) : 0;
|
|
613
618
|
const poolId = l.poolFee !== undefined && l.tickSpacing !== undefined && hook ? poolIdOf(l.token, l.pairToken, l.poolFee, l.tickSpacing, hook) : undefined;
|
|
614
619
|
const chainId = this.config.chainId;
|
|
615
620
|
return {
|
|
@@ -644,7 +649,7 @@ export class Parabolic {
|
|
|
644
649
|
feeBps: num(c.feeBps),
|
|
645
650
|
creatorTaxBps: num(c.creatorTaxBps),
|
|
646
651
|
split: { protocolBps: protocolShareBps, buybackBps: buybackOfFeeBps, creatorBps: 10_000 - protocolShareBps - buybackOfFeeBps, note: "shares of the base fee (and of snipe-tax revenue); the creator tax goes entirely to the creator" },
|
|
647
|
-
policy: { protocolFeeShareBps: protocolShareBps, buybackBurnBps },
|
|
652
|
+
policy: { protocolFeeShareBps: protocolShareBps, buybackBurnBps, buybackEnabled },
|
|
648
653
|
},
|
|
649
654
|
snipeTax: {
|
|
650
655
|
currentBps: currentSnipeBps,
|
package/src/routed.ts
CHANGED
|
@@ -28,7 +28,7 @@ import { VENUES, VENUE_KEYS, isVenueKey, venueOn, type VenueChain, type VenueInf
|
|
|
28
28
|
* encodes, argument for argument (test/routed.test.ts holds it against digests produced by the site's encoder, two
|
|
29
29
|
* of which Foundry's `cast calldata` produced first). Two differences, both deliberate:
|
|
30
30
|
*
|
|
31
|
-
* - **No voucher.** A Pro or
|
|
31
|
+
* - **No voucher.** A Pro or Ultra voucher is a site feature signed for one wallet by the site's backend; this server
|
|
32
32
|
* sends the router's own "none" (a zeroed struct and an empty signature) and so pays the router's default fee,
|
|
33
33
|
* which it reads at every call rather than assuming.
|
|
34
34
|
* - **A plain allowance instead of a Permit2 signature** for an ERC-20 input (a USDG-quoted buy, every sell). The
|
|
@@ -434,7 +434,7 @@ export class RoutedTrades {
|
|
|
434
434
|
minOut: { ...amount(minOut, outDecimals), slippageBps: Number(slippage) },
|
|
435
435
|
...(q.gross !== undefined ? { grossFromVenue: amount(q.gross, qd) } : {}),
|
|
436
436
|
fees: {
|
|
437
|
-
parabolic: { bps: p.feeBps, ...amount(q.fee, qd), note: `Parabolic's routed fee: the router's defaultFeeBps, read now (the Free tier's; a Pro or
|
|
437
|
+
parabolic: { bps: p.feeBps, ...amount(q.fee, qd), note: `Parabolic's routed fee: the router's defaultFeeBps, read now (the Free tier's; a Pro or Ultra voucher lowers it on the site, and this server sends none). Charged on the ${p.side === "buy" ? "input" : "venue's payout"}, on top of ${p.venue.name}'s own fee.` },
|
|
438
438
|
venue: { name: p.venue.name, ...(q.venueFee !== undefined ? amount(q.venueFee, qd) : { amount: null, raw: null }), note: p.via === "curve" ? `${p.venue.name}'s own curve fee and creator tax on this fill, read off the curve` : `${p.venue.name}'s hook takes its own fee on the pool swap (about ${p.venue.ownFeeBps} bps), already inside the quoted output` },
|
|
439
439
|
snipeTax: { bps: q.snipeBps, note: q.snipeBps > 0 ? `${p.venue.name} charges a snipe tax on this buy right now, keyed on the RECIPIENT; it decays every second` : "none now" },
|
|
440
440
|
},
|
package/src/server.ts
CHANGED
|
@@ -116,6 +116,12 @@ export function createServer(opts: ServerOptions = {}): McpServer {
|
|
|
116
116
|
// Tool arguments are validated strictly: an argument the tool does not know (a misspelling, or
|
|
117
117
|
// `referral` at the top level instead of inside `memo`) is an error, not something silently dropped
|
|
118
118
|
// and quietly changing what the tool does.
|
|
119
|
+
/**
|
|
120
|
+
* The creator-tax ceiling both factories answer today (`maxCreatorTaxBps()` 500 on 5042 and 4663, read 6 Oct 2026;
|
|
121
|
+
* CON-23). The schema refuses above it so an agent learns the bound before it builds a launch that reverts; the
|
|
122
|
+
* launch builder still reads the factory's own figure and refuses above that, which is what holds if an owner lowers it.
|
|
123
|
+
*/
|
|
124
|
+
const MAX_CREATOR_TAX_BPS = 500;
|
|
119
125
|
const strictArgs = <T extends z.ZodRawShape>(shape: T) => z.object(shape).strict();
|
|
120
126
|
|
|
121
127
|
const readOnly = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true } as const;
|
|
@@ -227,7 +233,7 @@ const readOnly = { readOnlyHint: true, destructiveHint: false, idempotentHint: t
|
|
|
227
233
|
socials: z.object({ twitter: z.string().max(256).optional(), telegram: z.string().max(256).optional(), discord: z.string().max(256).optional(), website: z.string().max(256).optional(), farcaster: z.string().max(256).optional() }).optional(),
|
|
228
234
|
pair: z.enum(["USDC", "EURC"]).optional().describe("Which quote asset to launch against: \"USDC\" means the chain's gas token (native-quoted, which is USDC on Arc and is NOT a dollar on a chain paying gas in ETH), \"EURC\" the configured ERC-20. The answer's `quoteAsset` names what was actually resolved, read off the asset itself."),
|
|
229
235
|
devBuy: whole.optional().describe("Creator's own first buy, whole quote units; returned as a second, snipe-tax-exempt transaction"),
|
|
230
|
-
creatorTaxBps: z.number().int().min(0).max(
|
|
236
|
+
creatorTaxBps: z.number().int().min(0).max(MAX_CREATOR_TAX_BPS).optional().describe(`Creator tax in basis points, 0 to ${MAX_CREATOR_TAX_BPS} (5%): both factories' maxCreatorTaxBps() read ${MAX_CREATOR_TAX_BPS}, and a higher figure reverts on chain`),
|
|
231
237
|
creator: z.string().describe("Wallet that signs the launch; becomes deployer and creatorFeeRecipient"),
|
|
232
238
|
buybackEnabled: z.boolean().optional().describe("Default true"),
|
|
233
239
|
memo: z.object({ referral: z.string().optional().describe("Referrer's 16-hex referral code or wallet address"), note: z.string().max(280).optional().describe("Note kept on the coin; defaults to \"mcp\", which lists the coin on parabolic.family/agents") }).nullable().optional().describe("The memo-wrapped variant's referral and note (returned as `memo` beside `tx`); null leaves it out"),
|