@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.
- package/LICENSE +674 -0
- package/README.md +624 -0
- package/dist/client-options.d.ts +16 -0
- package/dist/client-options.d.ts.map +1 -0
- package/dist/client-options.js +22 -0
- package/dist/client-options.js.map +1 -0
- package/dist/config.d.ts +223 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +516 -0
- package/dist/config.js.map +1 -0
- package/dist/format.d.ts +79 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +164 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/sdk-port.d.ts +227 -0
- package/dist/sdk-port.d.ts.map +1 -0
- package/dist/sdk-port.js +144 -0
- package/dist/sdk-port.js.map +1 -0
- package/dist/server.d.ts +25 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +103 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/errors.d.ts +44 -0
- package/dist/tools/errors.d.ts.map +1 -0
- package/dist/tools/errors.js +231 -0
- package/dist/tools/errors.js.map +1 -0
- package/dist/tools/index.d.ts +35 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +59 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/launch-params.d.ts +27 -0
- package/dist/tools/launch-params.d.ts.map +1 -0
- package/dist/tools/launch-params.js +29 -0
- package/dist/tools/launch-params.js.map +1 -0
- package/dist/tools/pool.d.ts +84 -0
- package/dist/tools/pool.d.ts.map +1 -0
- package/dist/tools/pool.js +249 -0
- package/dist/tools/pool.js.map +1 -0
- package/dist/tools/quote.d.ts +53 -0
- package/dist/tools/quote.d.ts.map +1 -0
- package/dist/tools/quote.js +85 -0
- package/dist/tools/quote.js.map +1 -0
- package/dist/tools/read.d.ts +26 -0
- package/dist/tools/read.d.ts.map +1 -0
- package/dist/tools/read.js +920 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/resolve.d.ts +45 -0
- package/dist/tools/resolve.d.ts.map +1 -0
- package/dist/tools/resolve.js +75 -0
- package/dist/tools/resolve.js.map +1 -0
- package/dist/tools/schema.d.ts +98 -0
- package/dist/tools/schema.d.ts.map +1 -0
- package/dist/tools/schema.js +143 -0
- package/dist/tools/schema.js.map +1 -0
- package/dist/tools/spend.d.ts +45 -0
- package/dist/tools/spend.d.ts.map +1 -0
- package/dist/tools/spend.js +99 -0
- package/dist/tools/spend.js.map +1 -0
- package/dist/tools/venue.d.ts +67 -0
- package/dist/tools/venue.d.ts.map +1 -0
- package/dist/tools/venue.js +110 -0
- package/dist/tools/venue.js.map +1 -0
- package/dist/tools/write.d.ts +56 -0
- package/dist/tools/write.d.ts.map +1 -0
- package/dist/tools/write.js +950 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +55 -0
package/dist/config.js
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How this server is configured, and the one decision that matters.
|
|
3
|
+
*
|
|
4
|
+
* # A private key is never a tool argument
|
|
5
|
+
*
|
|
6
|
+
* Every write this server can do needs a key. That key is read **here**, from
|
|
7
|
+
* the process environment or from a file the operator names, and from nowhere
|
|
8
|
+
* else. No tool takes one, no tool schema has a field for one, and
|
|
9
|
+
* `test/unit/no-key-arguments.test.ts` walks every published schema to keep it
|
|
10
|
+
* that way.
|
|
11
|
+
*
|
|
12
|
+
* The reason is not that arguments are less secure than environment variables
|
|
13
|
+
* in general. It is that a tool argument is **written by a model, into a
|
|
14
|
+
* transcript**. It goes to the model provider, into whatever log the client
|
|
15
|
+
* keeps, into the context of every later turn, and into the bug report someone
|
|
16
|
+
* pastes into an issue. A key that has been through a tool call is a key that
|
|
17
|
+
* has been published, and there is no way to un-publish it. The environment is
|
|
18
|
+
* read by one process, in one place, at startup.
|
|
19
|
+
*
|
|
20
|
+
* The key never leaves this module either: {@link ServerConfig} holds a viem
|
|
21
|
+
* `Account` behind a private field and its `toJSON` is the redacted
|
|
22
|
+
* description, so a config object that ends up in a log line or an error dump
|
|
23
|
+
* carries an address and not a secret.
|
|
24
|
+
*
|
|
25
|
+
* # Read-only is the default, and writing is the operator's decision
|
|
26
|
+
*
|
|
27
|
+
* A key being present is **not** consent to spend it. Writing requires
|
|
28
|
+
* `--allow-writes` (or `ARCNOW_MCP_ALLOW_WRITES=1`) from whoever starts the
|
|
29
|
+
* process — a person editing a config file, not a model mid-conversation — and
|
|
30
|
+
* the mode is printed on stderr at startup and reported by the
|
|
31
|
+
* `arcnow_network` tool, so neither the operator nor the model has to guess.
|
|
32
|
+
*
|
|
33
|
+
* A key with no opt-in starts read-only and says so loudly. An opt-in with no
|
|
34
|
+
* key refuses to start: the operator asked for something this process cannot
|
|
35
|
+
* do, and a server that quietly downgrades is a server whose failures arrive
|
|
36
|
+
* later, as "why did it not buy".
|
|
37
|
+
*
|
|
38
|
+
* # Spend caps are per quote token, and a quote with no cap is refused
|
|
39
|
+
*
|
|
40
|
+
* A curve is priced in native USDC or an allowlisted ERC-20 such as EURC, and
|
|
41
|
+
* one number in USDC cannot cap a spend in EURC. So the operator sets one cap
|
|
42
|
+
* per quote token, each in that quote's own units:
|
|
43
|
+
*
|
|
44
|
+
* - `ARCNOW_MCP_MAX_SPEND_USDC` caps native USDC, and defaults to 100.
|
|
45
|
+
* - `ARCNOW_MCP_MAX_SPEND_<SYMBOL>` caps every other quote: `ARCNOW_MCP_MAX_SPEND_EURC=50`.
|
|
46
|
+
* The symbol is the quote's symbol upper-cased, with anything but a letter
|
|
47
|
+
* or a digit written as `_`.
|
|
48
|
+
*
|
|
49
|
+
* Fail-closed, in four ways. A quote with **no** cap is refused for every
|
|
50
|
+
* spending write — launch and buy — and non-native quotes get no default, so a
|
|
51
|
+
* cap can never be got round by switching quote. A symbol resolves **only**
|
|
52
|
+
* against the network's own `quoteTokens` (the SDK's `networks.json`, or the
|
|
53
|
+
* network file), never against a token's on-chain `symbol()`, so a token cannot
|
|
54
|
+
* call itself EURC and borrow EURC's cap; a quote the network does not list can
|
|
55
|
+
* have no cap and is always refused. A cap variable naming no quote token of
|
|
56
|
+
* the network is a startup error, which catches typos. And two quote tokens of
|
|
57
|
+
* the network sharing a symbol is a startup error, because their two caps would
|
|
58
|
+
* be one variable.
|
|
59
|
+
*
|
|
60
|
+
* # A network the SDK has no preset for
|
|
61
|
+
*
|
|
62
|
+
* `ARCNOW_MCP_NETWORK_FILE` names a JSON document in the SDK's `CustomNetwork`
|
|
63
|
+
* shape — `rpcUrl`, `chainId`, `contracts`, and optionally `quoteTokens` and
|
|
64
|
+
* `quoteAllowanceSlots` — for a local anvil stack or a fork. It is validated by
|
|
65
|
+
* the SDK's own `resolveNetwork`, and is mutually exclusive with a preset name.
|
|
66
|
+
*
|
|
67
|
+
* @module
|
|
68
|
+
*/
|
|
69
|
+
import { readFileSync } from "node:fs";
|
|
70
|
+
import { privateKeyToAccount } from "viem/accounts";
|
|
71
|
+
import { isArcNowError, NATIVE_USDC, QuoteAmount, resolveNetwork } from "@arcnow/sdk";
|
|
72
|
+
/** Bad configuration, phrased for the person who wrote it. */
|
|
73
|
+
export class ConfigError extends Error {
|
|
74
|
+
name = "ConfigError";
|
|
75
|
+
}
|
|
76
|
+
/** The environment variable that caps native USDC. */
|
|
77
|
+
export const NATIVE_CAP_VARIABLE = "ARCNOW_MCP_MAX_SPEND_USDC";
|
|
78
|
+
/** Every per-quote cap variable starts with this. */
|
|
79
|
+
export const CAP_VARIABLE_PREFIX = "ARCNOW_MCP_MAX_SPEND_";
|
|
80
|
+
/** The variable capping `token`: `ARCNOW_MCP_MAX_SPEND_USDC` if native, else `…_<SYMBOL>`. */
|
|
81
|
+
export function capVariableFor(token) {
|
|
82
|
+
if (token.isNative)
|
|
83
|
+
return NATIVE_CAP_VARIABLE;
|
|
84
|
+
return `${CAP_VARIABLE_PREFIX}${token.symbol.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* The resolved configuration.
|
|
88
|
+
*
|
|
89
|
+
* Deliberately a class and not a plain object: the signing account lives in a
|
|
90
|
+
* `#` field that nothing can enumerate, and `toJSON` is the redacted
|
|
91
|
+
* description. Anything that stringifies this — a log line, an error cause, a
|
|
92
|
+
* crash dump — gets an address.
|
|
93
|
+
*/
|
|
94
|
+
export class ServerConfig {
|
|
95
|
+
/** The network's name: the preset's, or the network file's. */
|
|
96
|
+
network;
|
|
97
|
+
/** The network, resolved by the SDK: what the client is built on and caps resolve against. */
|
|
98
|
+
networkConfig;
|
|
99
|
+
/** The network file it came from, when it did. */
|
|
100
|
+
networkFile;
|
|
101
|
+
/** Already redacted of any credential: this is the value that gets printed. */
|
|
102
|
+
rpcUrl;
|
|
103
|
+
mode;
|
|
104
|
+
signerAddress;
|
|
105
|
+
/**
|
|
106
|
+
* The ceiling this process will spend in any one write call, per quote token,
|
|
107
|
+
* whatever a tool argument asks for. The operator's numbers, not the model's.
|
|
108
|
+
*/
|
|
109
|
+
spendCaps;
|
|
110
|
+
logScan;
|
|
111
|
+
/** Things worth saying at startup that are not fatal. */
|
|
112
|
+
warnings;
|
|
113
|
+
#account;
|
|
114
|
+
/** The un-redacted endpoint, for the client. Never printed. */
|
|
115
|
+
#rpcUrlRaw;
|
|
116
|
+
constructor(init) {
|
|
117
|
+
this.network = init.network;
|
|
118
|
+
this.networkConfig = init.networkConfig;
|
|
119
|
+
this.networkFile = init.networkFile;
|
|
120
|
+
this.rpcUrl = init.rpcUrlDisplay;
|
|
121
|
+
this.mode = init.mode;
|
|
122
|
+
this.#account = init.account;
|
|
123
|
+
this.#rpcUrlRaw = init.rpcUrlRaw;
|
|
124
|
+
this.signerAddress = init.account?.address;
|
|
125
|
+
this.spendCaps = init.spendCaps;
|
|
126
|
+
this.logScan = init.logScan;
|
|
127
|
+
this.warnings = init.warnings;
|
|
128
|
+
}
|
|
129
|
+
/** The signer, when this server is in write mode. `undefined` otherwise. */
|
|
130
|
+
account() {
|
|
131
|
+
return this.mode === "write" ? this.#account : undefined;
|
|
132
|
+
}
|
|
133
|
+
/** The endpoint to actually connect to, credential and all. */
|
|
134
|
+
rpcUrlForClient() {
|
|
135
|
+
return this.#rpcUrlRaw;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* The cap for a quote token, by ADDRESS — never by symbol, so a token that
|
|
139
|
+
* calls itself EURC is not EURC. `undefined` for a quote the network does not
|
|
140
|
+
* list, which no variable can cap.
|
|
141
|
+
*/
|
|
142
|
+
spendCapFor(token) {
|
|
143
|
+
const address = (typeof token === "string" ? token : token.address).toLowerCase();
|
|
144
|
+
return this.spendCaps.find((cap) => cap.token.address === address);
|
|
145
|
+
}
|
|
146
|
+
/** The native USDC cap, which always exists: it defaults to 100. */
|
|
147
|
+
get maxSpendPerCallUsdc() {
|
|
148
|
+
const native = this.spendCaps.find((cap) => cap.token.isNative)?.cap;
|
|
149
|
+
if (native === undefined)
|
|
150
|
+
throw new Error("no native USDC cap: loadConfig always sets one");
|
|
151
|
+
return native;
|
|
152
|
+
}
|
|
153
|
+
/** True when write tools are published and callable. */
|
|
154
|
+
get canWrite() {
|
|
155
|
+
return this.mode === "write" && this.#account !== undefined;
|
|
156
|
+
}
|
|
157
|
+
describe() {
|
|
158
|
+
return {
|
|
159
|
+
network: this.network,
|
|
160
|
+
networkFile: this.networkFile ?? null,
|
|
161
|
+
rpcUrl: this.rpcUrl,
|
|
162
|
+
mode: this.mode,
|
|
163
|
+
signerAddress: this.signerAddress ?? null,
|
|
164
|
+
maxSpendPerCallUsdc: this.maxSpendPerCallUsdc.toString(),
|
|
165
|
+
maxSpendPerCall: Object.fromEntries(this.spendCaps.map((cap) => [cap.token.symbol, cap.cap?.toString() ?? null])),
|
|
166
|
+
logScan: {
|
|
167
|
+
chunkBlocks: this.logScan.chunkBlocks.toString(),
|
|
168
|
+
maxChunks: this.logScan.maxChunks,
|
|
169
|
+
},
|
|
170
|
+
warnings: [...this.warnings],
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/** Redacted by construction: whatever stringifies a config gets this. */
|
|
174
|
+
toJSON() {
|
|
175
|
+
return this.describe();
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Defaults, named so they can be quoted in documentation and in tests. */
|
|
179
|
+
export const DEFAULTS = {
|
|
180
|
+
network: "arc-testnet",
|
|
181
|
+
/**
|
|
182
|
+
* 100 USDC a call. Low enough that a prompt-injected "buy everything" is a
|
|
183
|
+
* bounded accident and not a bounded-by-your-balance one; high enough that
|
|
184
|
+
* the shipped 2 USDC launch fee plus a real first buy fits under it. An
|
|
185
|
+
* operator who means to spend more says so once, at startup, on purpose.
|
|
186
|
+
*
|
|
187
|
+
* Native USDC only. Every other quote has NO default: spending it is refused
|
|
188
|
+
* until the operator names a cap for it.
|
|
189
|
+
*/
|
|
190
|
+
maxSpendPerCallUsdc: "100",
|
|
191
|
+
/**
|
|
192
|
+
* Arc's public endpoint has not documented a `eth_getLogs` range limit, so
|
|
193
|
+
* the scan is chunked rather than asking for six million blocks and finding
|
|
194
|
+
* out. 10,000 blocks a request, twenty requests: a bounded amount of work for
|
|
195
|
+
* a tool call, and the result says how far back it actually reached instead
|
|
196
|
+
* of implying it saw everything.
|
|
197
|
+
*/
|
|
198
|
+
logChunkBlocks: 10000n,
|
|
199
|
+
logMaxChunks: 20,
|
|
200
|
+
};
|
|
201
|
+
const PRIVATE_KEY_PATTERN = /^0x[0-9a-fA-F]{64}$/;
|
|
202
|
+
/**
|
|
203
|
+
* Strip anything secret out of an endpoint before it is ever printed.
|
|
204
|
+
*
|
|
205
|
+
* A private RPC endpoint is very often `https://host/v2/<api-key>` or
|
|
206
|
+
* `https://user:pass@host`. This server prints its endpoint at startup and in
|
|
207
|
+
* `arcnow_network`, and a model reads that output — so the path and the
|
|
208
|
+
* userinfo go, and what is left is the origin plus a marker saying something
|
|
209
|
+
* was there.
|
|
210
|
+
*/
|
|
211
|
+
export function redactUrl(raw) {
|
|
212
|
+
let url;
|
|
213
|
+
try {
|
|
214
|
+
url = new URL(raw);
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return "<unparseable endpoint>";
|
|
218
|
+
}
|
|
219
|
+
const auth = url.username || url.password ? "<credentials>@" : "";
|
|
220
|
+
const tail = url.pathname !== "/" && url.pathname !== "" ? "/…" : url.search ? "/…" : "";
|
|
221
|
+
return `${url.protocol}//${auth}${url.host}${tail}`;
|
|
222
|
+
}
|
|
223
|
+
function truthy(value) {
|
|
224
|
+
if (value === undefined)
|
|
225
|
+
return false;
|
|
226
|
+
return ["1", "true", "yes", "on"].includes(value.trim().toLowerCase());
|
|
227
|
+
}
|
|
228
|
+
function readKeyFile(path, readFile) {
|
|
229
|
+
try {
|
|
230
|
+
return readFile(path).trim();
|
|
231
|
+
}
|
|
232
|
+
catch (cause) {
|
|
233
|
+
throw new ConfigError(`ARCNOW_PRIVATE_KEY_FILE points at ${path} and it could not be read. `
|
|
234
|
+
+ "Nothing was logged about its contents and nothing was guessed; fix the path "
|
|
235
|
+
+ "or the permissions.", { cause });
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Turn an environment and a command line into a {@link ServerConfig}.
|
|
240
|
+
*
|
|
241
|
+
* Pure apart from the `readFile` it is handed, so the whole configuration
|
|
242
|
+
* surface — including every refusal — is testable without a process, a file or
|
|
243
|
+
* a key that is worth anything.
|
|
244
|
+
*/
|
|
245
|
+
export function loadConfig(env, argv = [], readFile = (path) => readFileSync(path, "utf8")) {
|
|
246
|
+
const warnings = [];
|
|
247
|
+
for (const arg of argv) {
|
|
248
|
+
if (arg !== "--allow-writes" && arg !== "--read-only" && !arg.startsWith("--network=")) {
|
|
249
|
+
throw new ConfigError(`unknown option ${arg}. This server takes --allow-writes, --read-only and `
|
|
250
|
+
+ "--network=<name>; everything else is an environment variable, because an "
|
|
251
|
+
+ "MCP client's config file is where the operator's decisions belong.");
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
const networkArg = argv.find((a) => a.startsWith("--network="))?.slice("--network=".length);
|
|
255
|
+
const networkFile = env.ARCNOW_MCP_NETWORK_FILE?.trim() || undefined;
|
|
256
|
+
const namedNetwork = networkArg ?? (env.ARCNOW_MCP_NETWORK?.trim() || undefined);
|
|
257
|
+
if (networkFile !== undefined && namedNetwork !== undefined) {
|
|
258
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE and a network name are mutually exclusive: the file is `
|
|
259
|
+
+ `${networkFile} and the name is ${namedNetwork}. Either the operator means the preset `
|
|
260
|
+
+ "or the deployment the file describes, and guessing which one gets real addresses wrong.");
|
|
261
|
+
}
|
|
262
|
+
const network = namedNetwork ?? DEFAULTS.network;
|
|
263
|
+
// Refused here rather than at the first call, so the operator finds out when
|
|
264
|
+
// they start the server instead of when a model tries to trade. The SDK
|
|
265
|
+
// refuses it too, by name; this is the same refusal, said earlier.
|
|
266
|
+
if (networkFile === undefined && network === "arc-mainnet") {
|
|
267
|
+
throw new ConfigError("arc-mainnet does not exist. arcnow.io is not deployed to an Arc mainnet, every "
|
|
268
|
+
+ "address in the SDK's preset for it is null on purpose, and this server will not "
|
|
269
|
+
+ "invent one. Use arc-testnet, or point ARCNOW_MCP_NETWORK at a network name the "
|
|
270
|
+
+ "SDK knows.");
|
|
271
|
+
}
|
|
272
|
+
const networkConfig = networkFile === undefined
|
|
273
|
+
? resolvePreset(network)
|
|
274
|
+
: readNetworkFile(networkFile, readFile);
|
|
275
|
+
const rpcUrlRaw = env.ARCNOW_RPC_URL?.trim() || undefined;
|
|
276
|
+
if (rpcUrlRaw !== undefined) {
|
|
277
|
+
try {
|
|
278
|
+
new URL(rpcUrlRaw);
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
throw new ConfigError(`ARCNOW_RPC_URL is not a URL: ${redactUrl(rpcUrlRaw)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
// ── the key ────────────────────────────────────────────────────────────────
|
|
285
|
+
const inlineKey = env.ARCNOW_PRIVATE_KEY?.trim() || undefined;
|
|
286
|
+
const keyFile = env.ARCNOW_PRIVATE_KEY_FILE?.trim() || undefined;
|
|
287
|
+
if (inlineKey !== undefined && keyFile !== undefined) {
|
|
288
|
+
throw new ConfigError("both ARCNOW_PRIVATE_KEY and ARCNOW_PRIVATE_KEY_FILE are set. Pick one: guessing "
|
|
289
|
+
+ "which key the operator meant is not a thing a program should do with a key.");
|
|
290
|
+
}
|
|
291
|
+
const rawKey = inlineKey ?? (keyFile === undefined ? undefined : readKeyFile(keyFile, readFile));
|
|
292
|
+
let account;
|
|
293
|
+
if (rawKey !== undefined) {
|
|
294
|
+
if (!PRIVATE_KEY_PATTERN.test(rawKey)) {
|
|
295
|
+
// Deliberately says nothing about the value, not even its length: an error
|
|
296
|
+
// message about a key is an error message that will be pasted somewhere.
|
|
297
|
+
throw new ConfigError("the private key is not a 32-byte hex key (0x followed by 64 hex characters). "
|
|
298
|
+
+ "Nothing about its value is reported here on purpose.");
|
|
299
|
+
}
|
|
300
|
+
try {
|
|
301
|
+
account = privateKeyToAccount(rawKey);
|
|
302
|
+
}
|
|
303
|
+
catch (cause) {
|
|
304
|
+
throw new ConfigError("the private key could not be turned into an account.", { cause });
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// ── the opt-in ─────────────────────────────────────────────────────────────
|
|
308
|
+
const forcedReadOnly = argv.includes("--read-only");
|
|
309
|
+
const wantsWrites = !forcedReadOnly
|
|
310
|
+
&& (argv.includes("--allow-writes") || truthy(env.ARCNOW_MCP_ALLOW_WRITES));
|
|
311
|
+
if (wantsWrites && account === undefined) {
|
|
312
|
+
throw new ConfigError("writes are enabled and there is no key to sign with. Set ARCNOW_PRIVATE_KEY (or "
|
|
313
|
+
+ "ARCNOW_PRIVATE_KEY_FILE) in the environment this process is started with, or drop "
|
|
314
|
+
+ "the write opt-in and run read-only. This refuses to start rather than quietly "
|
|
315
|
+
+ "downgrading, because a server that silently cannot write fails later, in the "
|
|
316
|
+
+ "middle of somebody's trade.");
|
|
317
|
+
}
|
|
318
|
+
if (!wantsWrites && account !== undefined && !forcedReadOnly) {
|
|
319
|
+
warnings.push(`a signing key is present (${account.address}) and writes are NOT enabled, so this `
|
|
320
|
+
+ "server is read-only and that key will not be used. Add --allow-writes, or "
|
|
321
|
+
+ "ARCNOW_MCP_ALLOW_WRITES=1, if you meant to let an assistant spend from it.");
|
|
322
|
+
}
|
|
323
|
+
if (forcedReadOnly && (argv.includes("--allow-writes") || truthy(env.ARCNOW_MCP_ALLOW_WRITES))) {
|
|
324
|
+
warnings.push("--read-only was passed alongside a write opt-in; --read-only wins.");
|
|
325
|
+
}
|
|
326
|
+
const mode = wantsWrites ? "write" : "read-only";
|
|
327
|
+
// ── the spend ceilings, one per quote token ────────────────────────────────
|
|
328
|
+
const spendCaps = resolveSpendCaps(env, networkConfig);
|
|
329
|
+
for (const { token, variable, cap } of spendCaps) {
|
|
330
|
+
if (mode === "write" && cap?.isZero() === true) {
|
|
331
|
+
warnings.push(`${variable} is 0, so every write that spends ${token.symbol} will be refused. That is `
|
|
332
|
+
+ "a legitimate way to run — launch and buy off, migrate and sell still on — but it is "
|
|
333
|
+
+ "probably not what was meant.");
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
const chunkBlocks = parseBigint(env.ARCNOW_MCP_LOG_CHUNK_BLOCKS, DEFAULTS.logChunkBlocks, "ARCNOW_MCP_LOG_CHUNK_BLOCKS");
|
|
337
|
+
const maxChunks = Number(parseBigint(env.ARCNOW_MCP_LOG_MAX_CHUNKS, BigInt(DEFAULTS.logMaxChunks), "ARCNOW_MCP_LOG_MAX_CHUNKS"));
|
|
338
|
+
return new ServerConfig({
|
|
339
|
+
network: networkFile === undefined ? network : networkConfig.name,
|
|
340
|
+
networkConfig,
|
|
341
|
+
networkFile,
|
|
342
|
+
rpcUrlRaw,
|
|
343
|
+
rpcUrlDisplay: rpcUrlRaw === undefined
|
|
344
|
+
? networkFile === undefined ? "(the network preset's endpoint)" : "(the network file's endpoint)"
|
|
345
|
+
: redactUrl(rpcUrlRaw),
|
|
346
|
+
mode,
|
|
347
|
+
account,
|
|
348
|
+
spendCaps,
|
|
349
|
+
logScan: { chunkBlocks, maxChunks },
|
|
350
|
+
warnings,
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
/** A preset, resolved by the SDK; its refusal said as a configuration error. */
|
|
354
|
+
function resolvePreset(network) {
|
|
355
|
+
try {
|
|
356
|
+
return resolveNetwork(network);
|
|
357
|
+
}
|
|
358
|
+
catch (cause) {
|
|
359
|
+
throw new ConfigError(`${network} is not a network the SDK can build a client for: ${describeSdkError(cause)} `
|
|
360
|
+
+ "Use a preset the SDK knows, or describe the deployment in ARCNOW_MCP_NETWORK_FILE.", { cause });
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* `ARCNOW_MCP_NETWORK_FILE`: a `CustomNetwork` document, validated by the SDK.
|
|
365
|
+
*
|
|
366
|
+
* JSON has no bigint, so an allowance slot may be written as a number or a
|
|
367
|
+
* decimal string; everything else is passed to `resolveNetwork` as it is.
|
|
368
|
+
*/
|
|
369
|
+
function readNetworkFile(path, readFile) {
|
|
370
|
+
let text;
|
|
371
|
+
try {
|
|
372
|
+
text = readFile(path);
|
|
373
|
+
}
|
|
374
|
+
catch (cause) {
|
|
375
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE points at ${path} and it could not be read. Fix the path or `
|
|
376
|
+
+ "the permissions; no network was guessed in its place.", { cause });
|
|
377
|
+
}
|
|
378
|
+
let document;
|
|
379
|
+
try {
|
|
380
|
+
document = JSON.parse(text);
|
|
381
|
+
}
|
|
382
|
+
catch (cause) {
|
|
383
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE ${path} is not JSON.`, { cause });
|
|
384
|
+
}
|
|
385
|
+
if (typeof document !== "object" || document === null || Array.isArray(document)) {
|
|
386
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE ${path} is not a JSON object in the SDK's CustomNetwork shape `
|
|
387
|
+
+ "({ rpcUrl, chainId, contracts, quoteTokens?, quoteAllowanceSlots? }).");
|
|
388
|
+
}
|
|
389
|
+
const raw = document;
|
|
390
|
+
const slots = raw.quoteAllowanceSlots;
|
|
391
|
+
const quoteAllowanceSlots = {};
|
|
392
|
+
if (slots !== undefined && slots !== null) {
|
|
393
|
+
if (typeof slots !== "object" || Array.isArray(slots)) {
|
|
394
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE ${path}: quoteAllowanceSlots is not an object.`);
|
|
395
|
+
}
|
|
396
|
+
for (const [address, slot] of Object.entries(slots)) {
|
|
397
|
+
if (!(typeof slot === "number" && Number.isSafeInteger(slot) && slot >= 0)
|
|
398
|
+
&& !(typeof slot === "string" && /^\d+$/.test(slot))) {
|
|
399
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE ${path}: the allowance slot for ${address} is not a `
|
|
400
|
+
+ `non-negative integer: ${JSON.stringify(slot)}.`);
|
|
401
|
+
}
|
|
402
|
+
quoteAllowanceSlots[address] = BigInt(slot);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
try {
|
|
406
|
+
return resolveNetwork({ ...raw, quoteAllowanceSlots });
|
|
407
|
+
}
|
|
408
|
+
catch (cause) {
|
|
409
|
+
throw new ConfigError(`ARCNOW_MCP_NETWORK_FILE ${path} is not a network the SDK accepts: ${describeSdkError(cause)}`, { cause });
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
function describeSdkError(error) {
|
|
413
|
+
if (isArcNowError(error))
|
|
414
|
+
return `${error.code}: ${error.message}`;
|
|
415
|
+
return error instanceof Error ? error.message : String(error);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* One cap per quote token of the network, each in its own units.
|
|
419
|
+
*
|
|
420
|
+
* Refuses, at startup: a cap variable naming no quote token of the network; two
|
|
421
|
+
* quote tokens whose symbols make the same variable; a cap that is not an
|
|
422
|
+
* amount of its quote (more decimals than it has, included).
|
|
423
|
+
*/
|
|
424
|
+
function resolveSpendCaps(env, networkConfig) {
|
|
425
|
+
const tokens = networkConfig.quoteTokens.some((token) => token.isNative)
|
|
426
|
+
? networkConfig.quoteTokens
|
|
427
|
+
: [NATIVE_USDC, ...networkConfig.quoteTokens];
|
|
428
|
+
const byVariable = new Map();
|
|
429
|
+
for (const token of tokens) {
|
|
430
|
+
const variable = capVariableFor(token);
|
|
431
|
+
const other = byVariable.get(variable);
|
|
432
|
+
if (other !== undefined) {
|
|
433
|
+
const symbol = variable.slice(CAP_VARIABLE_PREFIX.length);
|
|
434
|
+
throw new ConfigError(`the quote tokens ${other.address} (${other.symbol}) and ${token.address} (${token.symbol}) `
|
|
435
|
+
+ `of ${networkConfig.name} share the symbol ${symbol}, so one variable, ${variable}, would `
|
|
436
|
+
+ "cap both. A spend cap is per quote token, and two tokens under one cap is a cap that "
|
|
437
|
+
+ "does not mean what it says. Fix the network's quoteTokens.");
|
|
438
|
+
}
|
|
439
|
+
byVariable.set(variable, token);
|
|
440
|
+
}
|
|
441
|
+
for (const key of Object.keys(env)) {
|
|
442
|
+
if (!key.startsWith(CAP_VARIABLE_PREFIX) || byVariable.has(key))
|
|
443
|
+
continue;
|
|
444
|
+
const known = [...byVariable.entries()]
|
|
445
|
+
.map(([variable, token]) => `${variable} (${token.symbol})`).join(", ");
|
|
446
|
+
throw new ConfigError(`${key} names no quote token of ${networkConfig.name}. Its quote tokens take these caps: `
|
|
447
|
+
+ `${known}. A symbol is matched upper-cased against the network's own quoteTokens and `
|
|
448
|
+
+ "nothing else — never a token's on-chain symbol() — so this variable would cap nothing, "
|
|
449
|
+
+ "and it is refused rather than ignored, in case it is a typo for one of those.");
|
|
450
|
+
}
|
|
451
|
+
return [...byVariable.entries()].map(([variable, token]) => {
|
|
452
|
+
const given = env[variable]?.trim() || undefined;
|
|
453
|
+
const raw = token.isNative ? (given ?? DEFAULTS.maxSpendPerCallUsdc) : given;
|
|
454
|
+
if (raw === undefined)
|
|
455
|
+
return { token, variable, cap: undefined };
|
|
456
|
+
try {
|
|
457
|
+
return { token, variable, cap: QuoteAmount.parse(token, raw) };
|
|
458
|
+
}
|
|
459
|
+
catch (cause) {
|
|
460
|
+
throw new ConfigError(token.isNative
|
|
461
|
+
? `${variable} is not a decimal USDC amount: ${raw}. It is USDC, in whole units, the way `
|
|
462
|
+
+ "a person writes it — \"100\", \"2.5\" — not a wei-scale integer."
|
|
463
|
+
: `${variable} is not an amount of ${token.symbol}: ${raw}. It is whole ${token.symbol}, the `
|
|
464
|
+
+ `way a person writes it — "50", "2.5" — with at most ${token.decimals} decimals, `
|
|
465
|
+
+ `${token.symbol}'s own, and never a raw integer.`, { cause });
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
function parseBigint(raw, fallback, name) {
|
|
470
|
+
if (raw === undefined || raw.trim() === "")
|
|
471
|
+
return fallback;
|
|
472
|
+
let value;
|
|
473
|
+
try {
|
|
474
|
+
value = BigInt(raw.trim());
|
|
475
|
+
}
|
|
476
|
+
catch {
|
|
477
|
+
throw new ConfigError(`${name} is not an integer: ${raw}`);
|
|
478
|
+
}
|
|
479
|
+
if (value <= 0n)
|
|
480
|
+
throw new ConfigError(`${name} must be positive; got ${value}.`);
|
|
481
|
+
return value;
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* The startup banner, on **stderr**.
|
|
485
|
+
*
|
|
486
|
+
* stdout belongs to the MCP transport and a stray byte there corrupts the
|
|
487
|
+
* protocol frame, so nothing in this server ever writes to it. The banner says
|
|
488
|
+
* the mode first, because that is the fact an operator is checking for.
|
|
489
|
+
*/
|
|
490
|
+
export function startupBanner(config) {
|
|
491
|
+
const lines = [];
|
|
492
|
+
lines.push("arcnow.io MCP server");
|
|
493
|
+
lines.push(config.mode === "write"
|
|
494
|
+
? ` mode WRITES ENABLED — this server can spend from ${config.signerAddress ?? "?"}`
|
|
495
|
+
: " mode READ-ONLY — no tool here can spend, launch or sign anything");
|
|
496
|
+
lines.push(config.networkFile === undefined
|
|
497
|
+
? ` network ${config.network}`
|
|
498
|
+
: ` network ${config.network} (from ARCNOW_MCP_NETWORK_FILE ${config.networkFile})`);
|
|
499
|
+
lines.push(` endpoint ${config.rpcUrl}`);
|
|
500
|
+
if (config.mode === "write") {
|
|
501
|
+
config.spendCaps.forEach(({ token, variable, cap }, index) => {
|
|
502
|
+
lines.push(` ${index === 0 ? "spend cap " : " "} ${cap === undefined
|
|
503
|
+
? `${token.symbol} none — every spend in ${token.symbol} is refused; set ${variable} to allow it`
|
|
504
|
+
: `${cap.format()} per write call (${variable})`}`);
|
|
505
|
+
});
|
|
506
|
+
lines.push(" reminder a launch is irreversible and a token's parameters can never be changed.");
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
lines.push(" to write restart with --allow-writes and a key in ARCNOW_PRIVATE_KEY. The key is "
|
|
510
|
+
+ "read from the environment and is never a tool argument.");
|
|
511
|
+
}
|
|
512
|
+
for (const warning of config.warnings)
|
|
513
|
+
lines.push(` warning ${warning}`);
|
|
514
|
+
return lines.join("\n");
|
|
515
|
+
}
|
|
516
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtF,8DAA8D;AAC9D,MAAM,OAAO,WAAY,SAAQ,KAAK;IAClB,IAAI,GAAG,aAAa,CAAC;CACxC;AAWD,sDAAsD;AACtD,MAAM,CAAC,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAE/D,qDAAqD;AACrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,uBAAuB,CAAC;AAY3D,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,IAAI,KAAK,CAAC,QAAQ;QAAE,OAAO,mBAAmB,CAAC;IAC/C,OAAO,GAAG,mBAAmB,GAAG,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,EAAE,CAAC;AAC1F,CAAC;AAkBD;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACvB,+DAA+D;IACtD,OAAO,CAAS;IACzB,8FAA8F;IACrF,aAAa,CAAgB;IACtC,kDAAkD;IACzC,WAAW,CAAqB;IACzC,+EAA+E;IACtE,MAAM,CAAS;IACf,IAAI,CAAa;IACjB,aAAa,CAAsB;IAC5C;;;OAGG;IACM,SAAS,CAAsB;IAC/B,OAAO,CAAgB;IAChC,yDAAyD;IAChD,QAAQ,CAAoB;IAE5B,QAAQ,CAAsB;IACvC,+DAA+D;IACtD,UAAU,CAAqB;IAExC,YAAY,IAWX;QACC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;QACxC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACpC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;QACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC;QAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC5B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;IAChC,CAAC;IAED,4EAA4E;IAC5E,OAAO;QACL,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,CAAC;IAED,+DAA+D;IAC/D,eAAe;QACb,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,KAA8B;QACxC,MAAM,OAAO,GAAG,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC;IACrE,CAAC;IAED,oEAAoE;IACpE,IAAI,mBAAmB;QACrB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC;QACrE,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC5F,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,wDAAwD;IACxD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,CAAC;IAC9D,CAAC;IAED,QAAQ;QACN,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;YACrC,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,IAAI;YACzC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE;YACxD,eAAe,EAAE,MAAM,CAAC,WAAW,CACjC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;YAC/E,OAAO,EAAE;gBACP,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE;gBAChD,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;aAClC;YACD,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;SAC7B,CAAC;IACJ,CAAC;IAED,yEAAyE;IACzE,MAAM;QACJ,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;CACF;AAED,2EAA2E;AAC3E,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,aAAa;IACtB;;;;;;;;OAQG;IACH,mBAAmB,EAAE,KAAK;IAC1B;;;;;;OAMG;IACH,cAAc,EAAE,MAAO;IACvB,YAAY,EAAE,EAAE;CACR,CAAC;AAEX,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAElD;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,wBAAwB,CAAC;IAClC,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC;IAClE,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,KAAK,GAAG,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzF,OAAO,GAAG,GAAG,CAAC,QAAQ,KAAK,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,MAAM,CAAC,KAAyB;IACvC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACtC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,QAA+B;IAChE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,qCAAqC,IAAI,6BAA6B;cACpE,8EAA8E;cAC9E,qBAAqB,EACvB,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CACxB,GAAiD,EACjD,OAA0B,EAAE,EAC5B,WAAqC,CAAC,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC;IAEzE,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,gBAAgB,IAAI,GAAG,KAAK,aAAa,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YACvF,MAAM,IAAI,WAAW,CACnB,kBAAkB,GAAG,sDAAsD;kBACzE,2EAA2E;kBAC3E,oEAAoE,CACvE,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,EAAE,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5F,MAAM,WAAW,GAAG,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACrE,MAAM,YAAY,GAAG,UAAU,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC,CAAC;IACjF,IAAI,WAAW,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC5D,MAAM,IAAI,WAAW,CACnB,iFAAiF;cAC/E,GAAG,WAAW,oBAAoB,YAAY,yCAAyC;cACvF,yFAAyF,CAC5F,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,YAAY,IAAI,QAAQ,CAAC,OAAO,CAAC;IAEjD,6EAA6E;IAC7E,wEAAwE;IACxE,mEAAmE;IACnE,IAAI,WAAW,KAAK,SAAS,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;QAC3D,MAAM,IAAI,WAAW,CACnB,iFAAiF;cAC/E,kFAAkF;cAClF,iFAAiF;cACjF,YAAY,CACf,CAAC;IACJ,CAAC;IAED,MAAM,aAAa,GAAG,WAAW,KAAK,SAAS;QAC7C,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC;QACxB,CAAC,CAAC,eAAe,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAE3C,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC1D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,WAAW,CAAC,gCAAgC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAChF,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,SAAS,GAAG,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAC9D,MAAM,OAAO,GAAG,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IACjE,IAAI,SAAS,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACrD,MAAM,IAAI,WAAW,CACnB,kFAAkF;cAChF,6EAA6E,CAChF,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEjG,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACtC,2EAA2E;YAC3E,yEAAyE;YACzE,MAAM,IAAI,WAAW,CACnB,+EAA+E;kBAC7E,sDAAsD,CACzD,CAAC;QACJ,CAAC;QACD,IAAI,CAAC;YACH,OAAO,GAAG,mBAAmB,CAAC,MAAuB,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,WAAW,CAAC,sDAAsD,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,WAAW,GAAG,CAAC,cAAc;WAC9B,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE9E,IAAI,WAAW,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACzC,MAAM,IAAI,WAAW,CACnB,kFAAkF;cAChF,oFAAoF;cACpF,gFAAgF;cAChF,+EAA+E;cAC/E,6BAA6B,CAChC,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,WAAW,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;QAC7D,QAAQ,CAAC,IAAI,CACX,6BAA6B,OAAO,CAAC,OAAO,wCAAwC;cAClF,4EAA4E;cAC5E,4EAA4E,CAC/E,CAAC;IACJ,CAAC;IACD,IAAI,cAAc,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC;QAC/F,QAAQ,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,IAAI,GAAe,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC;IAE7D,8EAA8E;IAC9E,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;IACvD,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,SAAS,EAAE,CAAC;QACjD,IAAI,IAAI,KAAK,OAAO,IAAI,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;YAC/C,QAAQ,CAAC,IAAI,CACX,GAAG,QAAQ,qCAAqC,KAAK,CAAC,MAAM,4BAA4B;kBACtF,sFAAsF;kBACtF,8BAA8B,CACjC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,2BAA2B,EAAE,QAAQ,CAAC,cAAc,EACtF,6BAA6B,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,yBAAyB,EAChE,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,2BAA2B,CAAC,CAAC,CAAC;IAE/D,OAAO,IAAI,YAAY,CAAC;QACtB,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI;QACjE,aAAa;QACb,WAAW;QACX,SAAS;QACT,aAAa,EAAE,SAAS,KAAK,SAAS;YACpC,CAAC,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,+BAA+B;YACjG,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC;QACxB,IAAI;QACJ,OAAO;QACP,SAAS;QACT,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;QACnC,QAAQ;KACT,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,SAAS,aAAa,CAAC,OAAe;IACpC,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,OAAwB,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,GAAG,OAAO,qDAAqD,gBAAgB,CAAC,KAAK,CAAC,GAAG;cACvF,oFAAoF,EACtF,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,QAA+B;IACpE,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,qCAAqC,IAAI,6CAA6C;cACpF,uDAAuD,EACzD,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,IAAI,QAAiB,CAAC;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CAAC,2BAA2B,IAAI,eAAe,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjF,MAAM,IAAI,WAAW,CACnB,2BAA2B,IAAI,yDAAyD;cACtF,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,MAAM,GAAG,GAAG,QAAmC,CAAC;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,mBAAmB,CAAC;IACtC,MAAM,mBAAmB,GAA2B,EAAE,CAAC;IACvD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACtD,MAAM,IAAI,WAAW,CAAC,2BAA2B,IAAI,yCAAyC,CAAC,CAAC;QAClG,CAAC;QACD,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,EAAE,CAAC;YAC/E,IAAI,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;mBACrE,CAAC,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;gBACvD,MAAM,IAAI,WAAW,CACnB,2BAA2B,IAAI,4BAA4B,OAAO,YAAY;sBAC5E,yBAAyB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CACnD,CAAC;YACJ,CAAC;YACD,mBAAmB,CAAC,OAAO,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,OAAO,cAAc,CAAC,EAAE,GAAI,GAAgC,EAAE,mBAAmB,EAAE,CAAC,CAAC;IACvF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,2BAA2B,IAAI,sCAAsC,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAC9F,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,aAAa,CAAC,KAAK,CAAC;QAAE,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACnE,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CACvB,GAAiD,EACjD,aAA4B;IAE5B,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC;QACtE,CAAC,CAAC,aAAa,CAAC,WAAW;QAC3B,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0B,CAAC;IACrD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;YAC1D,MAAM,IAAI,WAAW,CACnB,oBAAoB,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,SAAS,KAAK,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM,IAAI;kBAC3F,MAAM,aAAa,CAAC,IAAI,qBAAqB,MAAM,sBAAsB,QAAQ,UAAU;kBAC3F,uFAAuF;kBACvF,4DAA4D,CAC/D,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,mBAAmB,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC1E,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC;aACpC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,GAAG,QAAQ,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1E,MAAM,IAAI,WAAW,CACnB,GAAG,GAAG,4BAA4B,aAAa,CAAC,IAAI,sCAAsC;cACxF,GAAG,KAAK,8EAA8E;cACtF,yFAAyF;cACzF,+EAA+E,CAClF,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE;QACzD,MAAM,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACjD,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAC7E,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC;QAClE,IAAI,CAAC;YACH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;QACjE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,WAAW,CACnB,KAAK,CAAC,QAAQ;gBACZ,CAAC,CAAC,GAAG,QAAQ,kCAAkC,GAAG,wCAAwC;sBACxF,kEAAkE;gBACpE,CAAC,CAAC,GAAG,QAAQ,wBAAwB,KAAK,CAAC,MAAM,KAAK,GAAG,iBAAiB,KAAK,CAAC,MAAM,QAAQ;sBAC1F,uDAAuD,KAAK,CAAC,QAAQ,aAAa;sBAClF,GAAG,KAAK,CAAC,MAAM,kCAAkC,EACvD,EAAE,KAAK,EAAE,CACV,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,GAAuB,EAAE,QAAgB,EAAE,IAAY;IAC1E,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC5D,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,WAAW,CAAC,GAAG,IAAI,uBAAuB,GAAG,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,IAAI,KAAK,IAAI,EAAE;QAAE,MAAM,IAAI,WAAW,CAAC,GAAG,IAAI,0BAA0B,KAAK,GAAG,CAAC,CAAC;IAClF,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,MAAoB;IAChD,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,IAAI,KAAK,OAAO;QACrB,CAAC,CAAC,6DAA6D,MAAM,CAAC,aAAa,IAAI,GAAG,EAAE;QAC5F,CAAC,CAAC,2EAA2E,CAChF,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,KAAK,SAAS;QACzC,CAAC,CAAC,iBAAiB,MAAM,CAAC,OAAO,EAAE;QACnC,CAAC,CAAC,iBAAiB,MAAM,CAAC,OAAO,kCAAkC,MAAM,CAAC,WAAW,GAAG,CAAC,CAAC;IAC5F,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,EAAE;YAC3D,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,KAAK,SAAS;gBAC7E,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,0BAA0B,KAAK,CAAC,MAAM,oBAAoB,QAAQ,cAAc;gBACjG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,oBAAoB,QAAQ,GAAG,EAAE,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,IAAI,CACR,uFAAuF,CACxF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,IAAI,CACR,wFAAwF;cACtF,yDAAyD,CAC5D,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,QAAQ;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,OAAO,EAAE,CAAC,CAAC;IAC9E,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/format.d.ts
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How numbers and addresses reach the model.
|
|
3
|
+
*
|
|
4
|
+
* # Every amount is printed with its own quote token, every time
|
|
5
|
+
*
|
|
6
|
+
* A curve is priced in one quote token for life: native USDC (18 decimals, the
|
|
7
|
+
* gas currency) or an allowlisted ERC-20 such as EURC (6 decimals). An amount
|
|
8
|
+
* is a `QuoteAmount` from the SDK, which carries the token it is denominated
|
|
9
|
+
* in, so a figure is always printed as `1.5 EURC` or `25 USDC` — the symbol of
|
|
10
|
+
* the quote it is actually in, never "USDC" for a EURC amount.
|
|
11
|
+
*
|
|
12
|
+
* On Arc, native USDC is 18-decimal and the USDC ERC-20 predeploy is the same
|
|
13
|
+
* asset at **6**. A bare `1000000` is a dollar under one reading and a
|
|
14
|
+
* millionth of a dollar under the other, which is why nothing here ever emits
|
|
15
|
+
* a bare number for money.
|
|
16
|
+
*
|
|
17
|
+
* # Text, not structured content
|
|
18
|
+
*
|
|
19
|
+
* Every tool returns one readable report. There is no parallel
|
|
20
|
+
* `structuredContent` payload, and that is a choice: two renderings of the same
|
|
21
|
+
* numbers is two places for a unit to be wrong, and only one of them is the one
|
|
22
|
+
* a person reads when they check what the assistant was told. The report
|
|
23
|
+
* carries exact decimal strings, so nothing is lost to rounding on the way.
|
|
24
|
+
*
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import type { Address } from "viem";
|
|
28
|
+
import type { Bps, CurveParams, NetworkConfig, QuoteTokenInfo, Tokens } from "@arcnow/sdk";
|
|
29
|
+
import { QuoteAmount } from "@arcnow/sdk";
|
|
30
|
+
/** The zero address, which on Arc is a real account, not a null. */
|
|
31
|
+
export declare const ZERO_ADDRESS: "0x0000000000000000000000000000000000000000";
|
|
32
|
+
/** `123.75 USDC`, `1.5 EURC`: always with the symbol of the quote the amount is in. */
|
|
33
|
+
export declare function money(amount: QuoteAmount): string;
|
|
34
|
+
/** Money plus its raw integers, for anything that has to be exact. */
|
|
35
|
+
export declare function moneyExact(amount: QuoteAmount): string;
|
|
36
|
+
export declare function qty(amount: Tokens, symbol?: string): string;
|
|
37
|
+
/** A price is the quote **per whole token**; saying so every time is the point. */
|
|
38
|
+
export declare function price(p: QuoteAmount): string;
|
|
39
|
+
/**
|
|
40
|
+
* One quote token, said in full: `EURC — ERC-20 0x89b5…, 6 decimals` or
|
|
41
|
+
* `USDC — native (the gas currency, paid as msg.value), 18 decimals`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function quoteLine(token: QuoteTokenInfo): string;
|
|
44
|
+
/** Checksummed, because that is the form a person pastes back. */
|
|
45
|
+
export declare function addr(value: string): string;
|
|
46
|
+
/** A share of the fee, said both ways — the single easiest thing to misread. */
|
|
47
|
+
export declare function share(bps: Bps, tradeFeeBps: Bps): string;
|
|
48
|
+
/** Graduation progress. `progressBps` is out of 10,000, not out of 100. */
|
|
49
|
+
export declare function progress(bps: Bps): string;
|
|
50
|
+
/**
|
|
51
|
+
* The average price a whole order actually filled at.
|
|
52
|
+
*
|
|
53
|
+
* Not the same number as `spotPrice`, which is the marginal price of the next
|
|
54
|
+
* infinitesimal token. The curve integrates price across an order, so a buyer
|
|
55
|
+
* pays a rising price over their own trade and this is what they paid.
|
|
56
|
+
*/
|
|
57
|
+
export declare function effectivePrice(spent: QuoteAmount, received: Tokens): QuoteAmount | undefined;
|
|
58
|
+
/** Percentage difference between two prices in the same quote, as a signed string. */
|
|
59
|
+
export declare function priceMove(from: QuoteAmount, to: QuoteAmount): string;
|
|
60
|
+
/**
|
|
61
|
+
* Which venue a migrator address is, by asking the deployment rather than
|
|
62
|
+
* assuming. A token graduates to the migrator **its own curve snapshotted at
|
|
63
|
+
* launch**, which need not be the one this network would choose today.
|
|
64
|
+
*/
|
|
65
|
+
export declare function venueOf(migrator: Address, config: NetworkConfig): string;
|
|
66
|
+
/**
|
|
67
|
+
* A curve's immutable parameters. arcnow.io has one curve, the constant-product
|
|
68
|
+
* `arcnow/bonding-curve@3.x.x`, and the SDK prices no other: `r0Wad` is its
|
|
69
|
+
* virtual quote reserve at launch, in 18-decimal WAD of its quote token, and
|
|
70
|
+
* `y0Wad` its virtual token reserve at launch.
|
|
71
|
+
*/
|
|
72
|
+
export declare function curveParamsLine(params: CurveParams, quote: QuoteTokenInfo): string;
|
|
73
|
+
/** A titled block of `label value` lines. */
|
|
74
|
+
export declare function section(title: string, rows: readonly (readonly [string, string])[]): string;
|
|
75
|
+
/** Joins sections with a blank line, dropping the ones that had nothing to say. */
|
|
76
|
+
export declare function report(...parts: readonly (string | undefined)[]): string;
|
|
77
|
+
/** A paragraph the model is meant to act on, set apart from the figures. */
|
|
78
|
+
export declare function note(text: string): string;
|
|
79
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,WAAW,EAAO,MAAM,aAAa,CAAC;AAE/C,oEAAoE;AACpE,eAAO,MAAM,YAAY,EAAG,4CAAqD,CAAC;AAElF,uFAAuF;AACvF,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAEjD;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAGtD;AAED,wBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,mFAAmF;AACnF,wBAAgB,KAAK,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CAE5C;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAMvD;AAED,kEAAkE;AAClE,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1C;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,GAAG,MAAM,CAGxD;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAGzC;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAG5F;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,WAAW,GAAG,MAAM,CAKpE;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,CAexE;AAID;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,GAAG,MAAM,CAGlF;AAED,8CAA8C;AAC9C,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,MAAM,CAI3F;AAED,mFAAmF;AACnF,wBAAgB,MAAM,CAAC,GAAG,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GAAG,MAAM,CAExE;AAED,4EAA4E;AAC5E,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC"}
|