@arcnow/mcp 0.1.0

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.
Files changed (71) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +624 -0
  3. package/dist/client-options.d.ts +16 -0
  4. package/dist/client-options.d.ts.map +1 -0
  5. package/dist/client-options.js +22 -0
  6. package/dist/client-options.js.map +1 -0
  7. package/dist/config.d.ts +223 -0
  8. package/dist/config.d.ts.map +1 -0
  9. package/dist/config.js +516 -0
  10. package/dist/config.js.map +1 -0
  11. package/dist/format.d.ts +79 -0
  12. package/dist/format.d.ts.map +1 -0
  13. package/dist/format.js +164 -0
  14. package/dist/format.js.map +1 -0
  15. package/dist/index.d.ts +17 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +50 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/sdk-port.d.ts +227 -0
  20. package/dist/sdk-port.d.ts.map +1 -0
  21. package/dist/sdk-port.js +144 -0
  22. package/dist/sdk-port.js.map +1 -0
  23. package/dist/server.d.ts +25 -0
  24. package/dist/server.d.ts.map +1 -0
  25. package/dist/server.js +103 -0
  26. package/dist/server.js.map +1 -0
  27. package/dist/tools/errors.d.ts +44 -0
  28. package/dist/tools/errors.d.ts.map +1 -0
  29. package/dist/tools/errors.js +231 -0
  30. package/dist/tools/errors.js.map +1 -0
  31. package/dist/tools/index.d.ts +35 -0
  32. package/dist/tools/index.d.ts.map +1 -0
  33. package/dist/tools/index.js +59 -0
  34. package/dist/tools/index.js.map +1 -0
  35. package/dist/tools/launch-params.d.ts +27 -0
  36. package/dist/tools/launch-params.d.ts.map +1 -0
  37. package/dist/tools/launch-params.js +29 -0
  38. package/dist/tools/launch-params.js.map +1 -0
  39. package/dist/tools/pool.d.ts +84 -0
  40. package/dist/tools/pool.d.ts.map +1 -0
  41. package/dist/tools/pool.js +249 -0
  42. package/dist/tools/pool.js.map +1 -0
  43. package/dist/tools/quote.d.ts +53 -0
  44. package/dist/tools/quote.d.ts.map +1 -0
  45. package/dist/tools/quote.js +85 -0
  46. package/dist/tools/quote.js.map +1 -0
  47. package/dist/tools/read.d.ts +26 -0
  48. package/dist/tools/read.d.ts.map +1 -0
  49. package/dist/tools/read.js +920 -0
  50. package/dist/tools/read.js.map +1 -0
  51. package/dist/tools/resolve.d.ts +45 -0
  52. package/dist/tools/resolve.d.ts.map +1 -0
  53. package/dist/tools/resolve.js +75 -0
  54. package/dist/tools/resolve.js.map +1 -0
  55. package/dist/tools/schema.d.ts +98 -0
  56. package/dist/tools/schema.d.ts.map +1 -0
  57. package/dist/tools/schema.js +143 -0
  58. package/dist/tools/schema.js.map +1 -0
  59. package/dist/tools/spend.d.ts +45 -0
  60. package/dist/tools/spend.d.ts.map +1 -0
  61. package/dist/tools/spend.js +99 -0
  62. package/dist/tools/spend.js.map +1 -0
  63. package/dist/tools/venue.d.ts +67 -0
  64. package/dist/tools/venue.d.ts.map +1 -0
  65. package/dist/tools/venue.js +110 -0
  66. package/dist/tools/venue.js.map +1 -0
  67. package/dist/tools/write.d.ts +56 -0
  68. package/dist/tools/write.d.ts.map +1 -0
  69. package/dist/tools/write.js +950 -0
  70. package/dist/tools/write.js.map +1 -0
  71. package/package.json +55 -0
@@ -0,0 +1,25 @@
1
+ /**
2
+ * The MCP surface: a thin wrapper over {@link listTools} and {@link callTool}.
3
+ *
4
+ * Everything that decides anything lives in `tools/`, which is why this file is
5
+ * short and why the test suite never has to stand up a transport to prove a
6
+ * property of the server.
7
+ *
8
+ * @module
9
+ */
10
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
11
+ import type { ServerConfig } from "./config.js";
12
+ import type { ArcNowPort } from "./sdk-port.js";
13
+ export declare const SERVER_NAME = "arcnow-io";
14
+ export declare const SERVER_VERSION = "0.1.0";
15
+ /**
16
+ * What the model is told before it sees a single tool.
17
+ *
18
+ * Three things, because these are the three that produce expensive mistakes:
19
+ * the mode, so it never offers to do something this server cannot; the decimal
20
+ * trap, so it never quotes a price out by a factor of a trillion; and the key
21
+ * rule, so it never asks a user to paste one into a chat.
22
+ */
23
+ export declare function instructionsFor(config: ServerConfig): string;
24
+ export declare function createServer(port: ArcNowPort, config: ServerConfig): Server;
25
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAIhD,eAAO,MAAM,WAAW,cAAc,CAAC;AACvC,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0D5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,GAAG,MAAM,CA2B3E"}
package/dist/server.js ADDED
@@ -0,0 +1,103 @@
1
+ /**
2
+ * The MCP surface: a thin wrapper over {@link listTools} and {@link callTool}.
3
+ *
4
+ * Everything that decides anything lives in `tools/`, which is why this file is
5
+ * short and why the test suite never has to stand up a transport to prove a
6
+ * property of the server.
7
+ *
8
+ * @module
9
+ */
10
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
11
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
12
+ import { capsSummary } from "./tools/spend.js";
13
+ import { callTool, listTools } from "./tools/index.js";
14
+ export const SERVER_NAME = "arcnow-io";
15
+ export const SERVER_VERSION = "0.1.0";
16
+ /**
17
+ * What the model is told before it sees a single tool.
18
+ *
19
+ * Three things, because these are the three that produce expensive mistakes:
20
+ * the mode, so it never offers to do something this server cannot; the decimal
21
+ * trap, so it never quotes a price out by a factor of a trillion; and the key
22
+ * rule, so it never asks a user to paste one into a chat.
23
+ */
24
+ export function instructionsFor(config) {
25
+ const mode = config.canWrite
26
+ ? "This server HAS WRITES ENABLED. It can launch tokens, buy, sell and migrate, signing "
27
+ + `as ${config.signerAddress ?? "an address it was configured with"}. Its operator capped `
28
+ + `any single write per quote token: ${capsSummary(config)}. A quote with no cap is refused `
29
+ + "for every launch and buy — do not offer one in it. Quote before you act, show the "
30
+ + "user the cost, and get their agreement — especially for a launch, which is "
31
+ + "irreversible in every respect: name, symbol, supply, curve and graduation venue are "
32
+ + "fixed at the launch transaction and no contract anywhere can change them afterwards."
33
+ : "This server is READ-ONLY. It cannot sign, spend, launch or trade, and the write tools "
34
+ + "are not published. Do not offer to buy, sell or launch anything. Enabling writes is "
35
+ + "the operator's decision, made by restarting the server — it is not something that "
36
+ + "can be granted during a conversation.";
37
+ return [
38
+ `arcnow.io on Arc (${config.network}) — bonding-curve token launches, trading and `
39
+ + "graduation, read straight from the contracts.",
40
+ "",
41
+ mode,
42
+ "",
43
+ "NEVER ask anyone for a private key, and never put one in a tool argument. No tool here "
44
+ + "takes one, and an argument named like a credential is refused rather than ignored. A "
45
+ + "tool call is written into a transcript; a key that has been through a transcript has "
46
+ + "been published and must be rotated. Signing is configured in the server's environment "
47
+ + "by whoever starts it.",
48
+ "",
49
+ "MONEY ON THIS CHAIN. Every token is priced for life in ONE quote token, fixed at its "
50
+ + "launch: native USDC — the gas currency, 18 decimals, paid as msg.value — or an allowlisted "
51
+ + "ERC-20 such as EURC (6 decimals), pulled with an exact ERC-20 approval. arcnow_token names "
52
+ + "a token's quote; arcnow_quote_tokens lists the ones a launch may use. Every amount a tool "
53
+ + "takes or reports is in that token's own quote, and is labelled with its symbol: never "
54
+ + "read a EURC figure as dollars, and never add amounts of two quotes together. Amounts cross "
55
+ + "these tools as decimal strings in whole units (\"25\", \"1.5\") with no more decimals than "
56
+ + "the quote has — never as JSON numbers, which cannot hold 18 decimals. Gas is always native "
57
+ + "USDC. The USDC ERC-20 predeploy is native USDC's 6-decimal view, pays for nothing, and is "
58
+ + "not a quote token.",
59
+ "",
60
+ "PRICES. A curve's spot price is the marginal price of the next infinitesimal token, not "
61
+ + "what an order fills at — the curve integrates price across an order. Answer \"what "
62
+ + "would 50 EURC get me\" with arcnow_quote_buy, never by multiplying.",
63
+ "",
64
+ "GRADUATION. A curve retires permanently once it collects its target, and the buy that "
65
+ + "fills it migrates the curve into a Uniswap v4 pool in that same transaction. From then "
66
+ + "on the token trades in that pool, through arcnow.io's router, and the quote and trade "
67
+ + "tools route there on their own — every pool quote says it is one, and names the pool's "
68
+ + "own LP fee on top of arcnow.io's 1%. Where a token graduates to is snapshotted into its "
69
+ + "own curve at launch: ask the curve, not a network-wide list. A token can be graduated "
70
+ + "and NOT migrated — trading over, no market anywhere — until somebody runs the "
71
+ + "permissionless migrate().",
72
+ "",
73
+ "SELLING IN A POOL needs an ERC-20 approval to the router first: a separate transaction "
74
+ + "granting it spending rights. arcnow_sell grants one only when told to (approveRouter: "
75
+ + "true), only for exactly the amount being sold, and reports it. Tell the user about the "
76
+ + "approval before you set that flag.",
77
+ "",
78
+ "There is no arcnow.io mainnet. If someone asks for one, say so; do not substitute an "
79
+ + "address from anywhere.",
80
+ ].join("\n");
81
+ }
82
+ export function createServer(port, config) {
83
+ const ctx = { port, config };
84
+ const server = new Server({ name: SERVER_NAME, version: SERVER_VERSION }, { capabilities: { tools: {} }, instructions: instructionsFor(config) });
85
+ server.setRequestHandler(ListToolsRequestSchema, () => ({
86
+ tools: listTools(config).map((tool) => ({
87
+ name: tool.name,
88
+ title: tool.title,
89
+ description: tool.description,
90
+ inputSchema: tool.inputSchema,
91
+ annotations: tool.annotations,
92
+ })),
93
+ }));
94
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
95
+ const result = await callTool(request.params.name, request.params.arguments, ctx);
96
+ return {
97
+ content: [{ type: "text", text: result.text }],
98
+ ...(result.isError === true ? { isError: true } : {}),
99
+ };
100
+ });
101
+ return server;
102
+ }
103
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Turning whatever went wrong into something a model can act on.
3
+ *
4
+ * The SDK's errors are already good — decoded by selector across every pinned
5
+ * ABI, carrying their parameters and a sentence saying what to do — so the job
6
+ * here is mostly to not lose them, and to add the one thing the SDK cannot
7
+ * know: which tool was being run.
8
+ *
9
+ * # Three kinds of failure, said as three different things
10
+ *
11
+ * - **The chain said no:** a decoded contract error, or one of the SDK's codes
12
+ * for a revert (`WrappedRevert`, `UnknownRevert`, `RevertString`, `Panic`,
13
+ * `EmptyRevert`). "failed on-chain".
14
+ * - **The SDK refused before building a transaction:** every other code in the
15
+ * SDK's own `SDK_ERROR_CODES` — an unknown curve, platform or hook version, an address
16
+ * that is not a curve. "refused".
17
+ * - **The question never reached the chain:** `RpcFailure`. "could not reach the
18
+ * chain" — a rate limit or a timeout, which says nothing about the token.
19
+ *
20
+ * A revert that came back through Uniswap v4's `WrappedError` keeps the layers
21
+ * it came through, which the SDK decodes onto `details.wrappedBy` — including
22
+ * which transfer out of the PoolManager failed.
23
+ *
24
+ * Its own module, rather than a function in the dispatcher, because a write
25
+ * tool sometimes has to render an error *inside* a report: a pool sell whose
26
+ * router approval went through and whose swap then did not has to say both.
27
+ *
28
+ * @module
29
+ */
30
+ export declare function renderError(tool: string, error: unknown): string;
31
+ /**
32
+ * A pool quote or trade, rendered — naming what failed when the SDK could.
33
+ *
34
+ * Uniswap v4 wraps a failing hook call, and a failing transfer out of the
35
+ * PoolManager, in `WrappedError`. The SDK unwraps it: a known inner error keeps
36
+ * its own code, and an empty reason is `WrappedRevert`, whose layers the SDK
37
+ * decodes — `NativeTransferFailed` or `ERC20TransferFailed` for a transfer.
38
+ *
39
+ * This server adds no cause of its own on top. It says which transfer failed
40
+ * when a layer names one, tells the model which tool to use next, and shows the
41
+ * SDK's explanation and the layers once, beneath.
42
+ */
43
+ export declare function renderPoolError(tool: string, side: "buy" | "sell", error: unknown): string;
44
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/tools/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AA6CH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAgChE;AAoJD;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,CAwB1F"}
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Turning whatever went wrong into something a model can act on.
3
+ *
4
+ * The SDK's errors are already good — decoded by selector across every pinned
5
+ * ABI, carrying their parameters and a sentence saying what to do — so the job
6
+ * here is mostly to not lose them, and to add the one thing the SDK cannot
7
+ * know: which tool was being run.
8
+ *
9
+ * # Three kinds of failure, said as three different things
10
+ *
11
+ * - **The chain said no:** a decoded contract error, or one of the SDK's codes
12
+ * for a revert (`WrappedRevert`, `UnknownRevert`, `RevertString`, `Panic`,
13
+ * `EmptyRevert`). "failed on-chain".
14
+ * - **The SDK refused before building a transaction:** every other code in the
15
+ * SDK's own `SDK_ERROR_CODES` — an unknown curve, platform or hook version, an address
16
+ * that is not a curve. "refused".
17
+ * - **The question never reached the chain:** `RpcFailure`. "could not reach the
18
+ * chain" — a rate limit or a timeout, which says nothing about the token.
19
+ *
20
+ * A revert that came back through Uniswap v4's `WrappedError` keeps the layers
21
+ * it came through, which the SDK decodes onto `details.wrappedBy` — including
22
+ * which transfer out of the PoolManager failed.
23
+ *
24
+ * Its own module, rather than a function in the dispatcher, because a write
25
+ * tool sometimes has to render an error *inside* a report: a pool sell whose
26
+ * router approval went through and whose swap then did not has to say both.
27
+ *
28
+ * @module
29
+ */
30
+ import { AmountParseError, isArcNowError, SDK_ERROR_CODES, WRAPPED_ERROR_SELECTOR, } from "@arcnow/sdk";
31
+ import { addr, note, report, section } from "../format.js";
32
+ import { QuoteInputError } from "./quote.js";
33
+ import { NotACurveOrTokenError, NotArcNowError } from "./resolve.js";
34
+ /** The SDK's codes for a revert it decoded, or could not: the chain refused. */
35
+ const REVERT_CODES = new Set([
36
+ "WrappedRevert", "UnknownRevert", "RevertString", "Panic", "EmptyRevert",
37
+ ]);
38
+ /** Every code the SDK raises itself, as opposed to a contract error's name. */
39
+ const SDK_CODES = new Set(SDK_ERROR_CODES);
40
+ /**
41
+ * What a quote-token contract error means, for a model deciding what to tell a
42
+ * user. Only the ones whose name alone does not say what to do next.
43
+ */
44
+ const QUOTE_ERROR_NOTES = {
45
+ QuoteTokenNotSupported: "The launchpad does not accept this quote token for a launch. Nothing was launched. "
46
+ + "arcnow_quote_tokens lists what its quote registry accepts; launch in one of those, or in "
47
+ + "native USDC. If an ERC-20 approve was sent first, it still stands.",
48
+ QuoteNotEnabledOnPlatform: "This platform serves no curve template for that quote, so it cannot launch in it. Nothing "
49
+ + "was launched. Launch in a quote the platform enables — native USDC always is on "
50
+ + "arcnow.io's own — or under another platform.",
51
+ MigratorDoesNotSupportQuote: "The graduation venue chosen cannot migrate a curve priced in this quote. Nothing was launched.",
52
+ LaunchFeeAboveMaximum: "The launch fee for this quote was raised after it was quoted, and the launch refused to pay "
53
+ + "more than the fee it was shown. Nothing was launched. Re-quote and show the new total.",
54
+ QuoteTransferShortfall: "The quote token delivered less than the amount pulled — a token that takes a fee on "
55
+ + "transfer, or a paused or blocklisted account. Nothing was traded.",
56
+ };
57
+ export function renderError(tool, error) {
58
+ if (error instanceof QuoteInputError)
59
+ return error.message;
60
+ if (error instanceof NotACurveOrTokenError)
61
+ return notACurveOrToken(tool, error.refusal);
62
+ if (isArcNowError(error)) {
63
+ if (error.code === "QuoteTransferOutOfGas")
64
+ return quoteTransferOutOfGas(tool, error);
65
+ if (error.code === "UnknownCurveVersion")
66
+ return unknownCurveVersion(tool, error);
67
+ if (error.code === "RpcFailure")
68
+ return transportFailure(tool, error);
69
+ if (SDK_CODES.has(error.code) && !REVERT_CODES.has(error.code))
70
+ return sdkRefusal(tool, error);
71
+ const args = Object.entries(error.args);
72
+ return report(`${tool} failed on-chain: ${error.code}`, error.message, args.length === 0
73
+ ? undefined
74
+ : `Details: ${args.map(([k, v]) => `${k}=${String(v)}`).join(", ")}`, wrapperSection(error), QUOTE_ERROR_NOTES[error.code] === undefined ? undefined : note(QUOTE_ERROR_NOTES[error.code] ?? ""));
75
+ }
76
+ if (error instanceof NotArcNowError)
77
+ return error.message;
78
+ if (error instanceof AmountParseError) {
79
+ return report(`${tool}: that amount could not be read.`, error.message, note("Amounts here are decimal strings in whole units — \"25\", \"1.5\" — not raw "
80
+ + "integers and not JSON numbers. Token quantities have 18 decimals; an amount of a quote "
81
+ + "token has that quote's own — native USDC 18, EURC 6 — and an amount with more decimal "
82
+ + "places than that is rejected rather than quietly truncated."));
83
+ }
84
+ if (error instanceof Error)
85
+ return `${tool} failed: ${error.message}`;
86
+ return `${tool} failed: ${String(error)}`;
87
+ }
88
+ function detail(error, key) {
89
+ const value = error.details[key];
90
+ return typeof value === "string" ? value : undefined;
91
+ }
92
+ const ADDRESS = /^0x[0-9a-fA-F]{40}$/;
93
+ function sdkRefusal(tool, error) {
94
+ const details = Object.entries(error.details)
95
+ .filter(([key, value]) => key !== "wrappedBy"
96
+ && (typeof value === "string" || typeof value === "number" || typeof value === "bigint"));
97
+ return report(`${tool} refused: ${error.code}`, error.message, details.length === 0
98
+ ? undefined
99
+ : `Details: ${details.map(([k, v]) => `${k}=${typeof v === "string" && ADDRESS.test(v) ? addr(v) : String(v)}`).join(", ")}`, error.code === "ReadOnlyClient"
100
+ ? note("That means this server has no signer even though a write tool ran, which "
101
+ + "should not be reachable — report it rather than retrying.")
102
+ : error.code === "QuoteAmountNotRepresentable"
103
+ ? note("The SDK refused this call itself, before building its transaction: the amount is "
104
+ + "not a whole number of its quote token's raw units, and an ERC-20 cannot move a "
105
+ + "fraction of one. Pass an amount with no more decimals than the quote has.")
106
+ : error.code === "QuoteTokenMismatch"
107
+ ? note("The SDK refused this call itself, before building its transaction: an amount of "
108
+ + "one quote token was offered where another is priced. Nothing converts between "
109
+ + "quotes here.")
110
+ : note("The SDK refused this call itself, before building its transaction."));
111
+ }
112
+ /**
113
+ * An ERC-20 trade or launch that ran out of gas inside a fee-share transfer.
114
+ *
115
+ * The contracts' gas guard on ERC-20 fee shares (contracts#23,
116
+ * `QuoteTransfer.tryPushBounded`) reverts with no data when too little gas is
117
+ * left, and the SDK names that `QuoteTransferOutOfGas`. It is a gas limit too
118
+ * tight — not an unknown revert, and not a refusal made before anything was
119
+ * attempted — so it is said as exactly that, with the one thing to do about it.
120
+ */
121
+ function quoteTransferOutOfGas(tool, error) {
122
+ const quote = detail(error, "quoteToken");
123
+ const limit = error.details.gasLimit;
124
+ return report(`${tool} failed on-chain: QuoteTransferOutOfGas — the transaction ran out of gas paying an `
125
+ + `ERC-20 fee share${quote === undefined ? "" : ` in the quote token ${addr(quote)}`}.`, error.message, section("details", [
126
+ ["quote token", quote === undefined ? "(not reported)" : addr(quote)],
127
+ ["gas limit", typeof limit === "bigint" || typeof limit === "number"
128
+ ? `gasLimit=${limit.toString()}`
129
+ : "none set — the node's estimate plus the SDK's headroom"],
130
+ ]), note("arcnow.io's contracts send each ERC-20 fee share through a gas guard that reverts with no "
131
+ + "data when too little gas is left for the transfer, so this is a gas limit too tight for the "
132
+ + "transfers, not a rejection of the trade and nothing wrong with the token. To fix it, leave "
133
+ + "the gas limit unset, or raise it: with none set the SDK sends the node's estimate plus a "
134
+ + "fifth — at least 150,000 more for a curve trade or a launch, at least 400,000 more for a "
135
+ + "pool swap — and a trade that graduates the curve gets 8,000,000. A trade "
136
+ + "is simulated before it is sent, so this normally means nothing was sent; check the balance "
137
+ + "before retrying anyway."));
138
+ }
139
+ function transportFailure(tool, error) {
140
+ return report(`${tool} could not reach the chain: RpcFailure`, error.message, note("This is the transport — the endpoint, a rate limit or a timeout — and it says "
141
+ + "nothing about the address, the token or the trade. If it happened while a transaction "
142
+ + "was being sent, check the balance before trying again; otherwise try again after a "
143
+ + "pause."));
144
+ }
145
+ function notACurveOrToken(tool, refusal) {
146
+ return report(`${tool} refused: AddressIsNotACurve — this address is not an arcnow.io bonding curve, and `
147
+ + "it is not an arcnow.io token either.", refusal.message, note("Read as a token, it named no arcnow.io curve. Nothing was quoted and nothing was sent. "
148
+ + "A launch gives two addresses — the token and its curve — and either one works here; "
149
+ + "anything else, an ordinary ERC-20 such as the USDC interface predeploy included, does "
150
+ + "not."));
151
+ }
152
+ /** What the SDK refused, by the component whose `VERSION()` it read. */
153
+ const REFUSED_COMPONENT = {
154
+ "bonding-curve": "this curve",
155
+ "platform-config": "this platform",
156
+ "platform-registry": "this platform registry",
157
+ "quote-registry": "this quote registry",
158
+ "launchpad": "this launchpad",
159
+ "arc-now-fee-hook": "this fee hook",
160
+ };
161
+ function unknownCurveVersion(tool, error) {
162
+ const version = detail(error, "version") ?? "(not reported)";
163
+ const component = detail(error, "component") ?? "bonding-curve";
164
+ const what = REFUSED_COMPONENT[component] ?? `this ${component}`;
165
+ return report(`${tool} refused: UnknownCurveVersion — ${what} answers VERSION() `
166
+ + `${JSON.stringify(version)}, which is not a version this server prices.`, error.message, note("Nothing was quoted and nothing was sent. arcnow.io has one bonding curve, the "
167
+ + "constant-product arcnow/bonding-curve@3.x.x, priced in a quote token and launched under "
168
+ + "arcnow/platform-config@3.x.x platforms through arcnow/launchpad@3.x.x, whose quote "
169
+ + "registry is arcnow/quote-registry@1.x.x. Any other version — the 2.x contracts Arc "
170
+ + "testnet ran until the multi-quote reset and the retired linear curve, @1.x.x, included "
171
+ + "— is refused rather "
172
+ + "than priced, because another build can keep another quantity in the same slots and a "
173
+ + "guess would be a plausible, wrong number. Do not estimate a price for it some other way."));
174
+ }
175
+ /** The `WrappedError` layers the SDK peeled off a revert, outermost first. */
176
+ function wrappedLayers(error) {
177
+ const layers = error.details.wrappedBy;
178
+ return Array.isArray(layers) ? layers : [];
179
+ }
180
+ function wrapperSection(error) {
181
+ const layers = wrappedLayers(error);
182
+ if (layers.length === 0)
183
+ return undefined;
184
+ const rows = layers.map((layer, index) => [
185
+ index === 0 ? "wrapped by" : "inside that",
186
+ `${layer.selectorName ?? layer.selector} on ${addr(layer.target)}`
187
+ + (layer.detailsName === undefined ? "" : ` (${layer.detailsName})`),
188
+ ]);
189
+ if (error.code === "WrappedRevert") {
190
+ const reason = detail(error, "reason");
191
+ rows.push(["inner revert", reason === undefined
192
+ ? "not reported"
193
+ : reason === "0x"
194
+ ? "no data at all"
195
+ : `${reason} — in none of the ABIs the SDK carries`]);
196
+ }
197
+ return section(`Uniswap v4 WrappedError (${WRAPPED_ERROR_SELECTOR}) layers, outermost first`, rows);
198
+ }
199
+ /**
200
+ * A pool quote or trade, rendered — naming what failed when the SDK could.
201
+ *
202
+ * Uniswap v4 wraps a failing hook call, and a failing transfer out of the
203
+ * PoolManager, in `WrappedError`. The SDK unwraps it: a known inner error keeps
204
+ * its own code, and an empty reason is `WrappedRevert`, whose layers the SDK
205
+ * decodes — `NativeTransferFailed` or `ERC20TransferFailed` for a transfer.
206
+ *
207
+ * This server adds no cause of its own on top. It says which transfer failed
208
+ * when a layer names one, tells the model which tool to use next, and shows the
209
+ * SDK's explanation and the layers once, beneath.
210
+ */
211
+ export function renderPoolError(tool, side, error) {
212
+ if (!isArcNowError(error) || error.code !== "WrappedRevert") {
213
+ return renderError(tool, error);
214
+ }
215
+ const failed = wrappedLayers(error).map((layer) => layer.detailsName);
216
+ const transfer = failed.includes("NativeTransferFailed")
217
+ ? "a native USDC transfer"
218
+ : failed.includes("ERC20TransferFailed") ? "an ERC-20 transfer" : undefined;
219
+ return report(transfer === undefined
220
+ ? `${tool}: the pool refused this ${side}, for a reason the SDK could not decode.`
221
+ : `${tool}: the pool refused this ${side} — ${transfer} out of the PoolManager failed `
222
+ + "inside the swap.", note(transfer === undefined
223
+ ? "A call inside the swap reverted with a reason the SDK could not decode; the layers "
224
+ + "below name which call. Nothing here says what the cause was. A smaller amount may go "
225
+ + `through; quote it first with arcnow_quote_${side}.`
226
+ : "The SDK decoded which transfer failed and gives its reason below. Before trying again, "
227
+ + `quote a smaller amount with arcnow_quote_${side}, and do not tell the user the pool `
228
+ + "is empty or broken: nothing here shows either."), note("A trade is simulated before it is sent, so a revert reported like this normally "
229
+ + "means nothing was sent. Check the balance before retrying anyway."), renderError(tool, error));
230
+ }
231
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/tools/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The tool registry, and the one place a call is dispatched.
3
+ *
4
+ * `listTools` and `callTool` here are plain functions over plain data. The MCP
5
+ * transport in `server.ts` is a thin wrapper around them, which is what lets
6
+ * the whole surface — what is published in each mode, what a refusal says, how
7
+ * an on-chain revert is rendered — be tested without a transport, a client or a
8
+ * chain.
9
+ *
10
+ * @module
11
+ */
12
+ import type { ServerConfig } from "../config.js";
13
+ import { renderError } from "./errors.js";
14
+ import type { AnyTool, ToolContext, ToolOutput } from "./schema.js";
15
+ export { renderError };
16
+ /** Every tool this server knows about, in either mode. */
17
+ export declare const ALL_TOOLS: readonly AnyTool[];
18
+ /**
19
+ * What the client is told exists.
20
+ *
21
+ * In read-only mode the write tools are **not listed**. A model offered a
22
+ * `arcnow_launch` it cannot use will try it, and the interesting failure is not
23
+ * the one where a tool exists and refuses — it is the one where a user is told
24
+ * "I could launch that for you" on the strength of a tool listing. So they are
25
+ * absent from the list, and still refused by name if called anyway, because a
26
+ * client may have cached an older list.
27
+ */
28
+ export declare function listTools(config: ServerConfig): readonly AnyTool[];
29
+ export declare function findTool(name: string): AnyTool | undefined;
30
+ /**
31
+ * Run one tool call. Never throws: an MCP tool error is a result with
32
+ * `isError`, so the model can read what went wrong and do something else.
33
+ */
34
+ export declare function callTool(name: string, args: unknown, ctx: ToolContext): Promise<ToolOutput>;
35
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,0DAA0D;AAC1D,eAAO,MAAM,SAAS,EAAE,SAAS,OAAO,EAAoC,CAAC;AAE7E;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,OAAO,EAAE,CAElE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAE1D;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,UAAU,CAAC,CAqBrB"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * The tool registry, and the one place a call is dispatched.
3
+ *
4
+ * `listTools` and `callTool` here are plain functions over plain data. The MCP
5
+ * transport in `server.ts` is a thin wrapper around them, which is what lets
6
+ * the whole surface — what is published in each mode, what a refusal says, how
7
+ * an on-chain revert is rendered — be tested without a transport, a client or a
8
+ * chain.
9
+ *
10
+ * @module
11
+ */
12
+ import { renderError } from "./errors.js";
13
+ import { READ_TOOLS } from "./read.js";
14
+ import { WRITE_TOOLS, writeRefusal } from "./write.js";
15
+ export { renderError };
16
+ /** Every tool this server knows about, in either mode. */
17
+ export const ALL_TOOLS = [...READ_TOOLS, ...WRITE_TOOLS];
18
+ /**
19
+ * What the client is told exists.
20
+ *
21
+ * In read-only mode the write tools are **not listed**. A model offered a
22
+ * `arcnow_launch` it cannot use will try it, and the interesting failure is not
23
+ * the one where a tool exists and refuses — it is the one where a user is told
24
+ * "I could launch that for you" on the strength of a tool listing. So they are
25
+ * absent from the list, and still refused by name if called anyway, because a
26
+ * client may have cached an older list.
27
+ */
28
+ export function listTools(config) {
29
+ return config.canWrite ? ALL_TOOLS : READ_TOOLS;
30
+ }
31
+ export function findTool(name) {
32
+ return ALL_TOOLS.find((tool) => tool.name === name);
33
+ }
34
+ /**
35
+ * Run one tool call. Never throws: an MCP tool error is a result with
36
+ * `isError`, so the model can read what went wrong and do something else.
37
+ */
38
+ export async function callTool(name, args, ctx) {
39
+ const tool = findTool(name);
40
+ if (tool === undefined) {
41
+ return {
42
+ isError: true,
43
+ text: `There is no tool called ${name} on this server. It has: `
44
+ + `${listTools(ctx.config).map((t) => t.name).join(", ")}.`,
45
+ };
46
+ }
47
+ // The gate. It is here, in dispatch, and not inside each write handler —
48
+ // one check that cannot be forgotten when a seventh write tool is added.
49
+ if (tool.access === "write" && !ctx.config.canWrite) {
50
+ return writeRefusal(name);
51
+ }
52
+ try {
53
+ return await tool.run(args, ctx);
54
+ }
55
+ catch (error) {
56
+ return { isError: true, text: renderError(name, error) };
57
+ }
58
+ }
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEvD,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,0DAA0D;AAC1D,MAAM,CAAC,MAAM,SAAS,GAAuB,CAAC,GAAG,UAAU,EAAE,GAAG,WAAW,CAAC,CAAC;AAE7E;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,MAAoB;IAC5C,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAY,EACZ,IAAa,EACb,GAAgB;IAEhB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,2BAA2B,IAAI,2BAA2B;kBAC5D,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;SAC9D,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,yEAAyE;IACzE,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Turning launch arguments into the SDK's `LaunchParams`.
3
+ *
4
+ * Shared by `arcnow_quote_launch` and `arcnow_launch` on purpose: the quote a
5
+ * user is shown and the transaction that is sent have to be built from the same
6
+ * function, or the quote is describing something slightly different from what
7
+ * happens. The only difference between the two is `minTokensOut`, which a quote
8
+ * does not use and a launch must not omit.
9
+ *
10
+ * **The launch's quote is the initial buy's token.** The SDK has no separate
11
+ * quote field to disagree with it: `initialBuy` is parsed, exactly, in the quote
12
+ * the `quote` argument named, and a zero initial buy is zero of that quote.
13
+ *
14
+ * @module
15
+ */
16
+ import type { LaunchParams, QuoteTokenInfo } from "@arcnow/sdk";
17
+ import { Tokens } from "@arcnow/sdk";
18
+ export interface LaunchArgs {
19
+ readonly name: string;
20
+ readonly symbol: string;
21
+ readonly metadataUri: string;
22
+ readonly initialBuy: string;
23
+ readonly platform?: string | undefined;
24
+ readonly migrator?: string | undefined;
25
+ }
26
+ export declare function launchParams(args: LaunchArgs, quote: QuoteTokenInfo, minTokensOut?: Tokens): LaunchParams;
27
+ //# sourceMappingURL=launch-params.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-params.d.ts","sourceRoot":"","sources":["../../src/tools/launch-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACxC;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,cAAc,EACrB,YAAY,GAAE,MAAoB,GACjC,YAAY,CAUd"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Turning launch arguments into the SDK's `LaunchParams`.
3
+ *
4
+ * Shared by `arcnow_quote_launch` and `arcnow_launch` on purpose: the quote a
5
+ * user is shown and the transaction that is sent have to be built from the same
6
+ * function, or the quote is describing something slightly different from what
7
+ * happens. The only difference between the two is `minTokensOut`, which a quote
8
+ * does not use and a launch must not omit.
9
+ *
10
+ * **The launch's quote is the initial buy's token.** The SDK has no separate
11
+ * quote field to disagree with it: `initialBuy` is parsed, exactly, in the quote
12
+ * the `quote` argument named, and a zero initial buy is zero of that quote.
13
+ *
14
+ * @module
15
+ */
16
+ import { Tokens } from "@arcnow/sdk";
17
+ import { parseQuoteAmount } from "./quote.js";
18
+ export function launchParams(args, quote, minTokensOut = Tokens.ZERO) {
19
+ return {
20
+ name: args.name,
21
+ symbol: args.symbol,
22
+ metadataUri: args.metadataUri,
23
+ initialBuy: parseQuoteAmount(quote, args.initialBuy, "initialBuy"),
24
+ minTokensOut,
25
+ ...(args.platform === undefined ? {} : { platform: args.platform }),
26
+ ...(args.migrator === undefined ? {} : { migrator: args.migrator }),
27
+ };
28
+ }
29
+ //# sourceMappingURL=launch-params.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-params.js","sourceRoot":"","sources":["../../src/tools/launch-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAW9C,MAAM,UAAU,YAAY,CAC1B,IAAgB,EAChB,KAAqB,EACrB,eAAuB,MAAM,CAAC,IAAI;IAElC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,YAAY,CAAC;QAClE,YAAY;QACZ,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAmB,EAAE,CAAC;QAC9E,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAmB,EAAE,CAAC;KAC/E,CAAC;AACJ,CAAC"}