opentool 0.10.5 → 0.12.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/dist/adapters/hyperliquid/index.d.ts +1 -1
- package/dist/adapters/polymarket/index.d.ts +319 -0
- package/dist/adapters/polymarket/index.js +831 -0
- package/dist/adapters/polymarket/index.js.map +1 -0
- package/dist/backtest/index.d.ts +58 -0
- package/dist/backtest/index.js +122 -0
- package/dist/backtest/index.js.map +1 -0
- package/dist/cli/index.d.ts +17 -4
- package/dist/{validate-DbhJ_r0Z.d.ts → index-9Z3wo28l.d.ts} +2 -25
- package/dist/index-BnQsRvND.d.ts +13 -0
- package/dist/index.d.ts +8 -376
- package/dist/index.js +29 -1110
- package/dist/index.js.map +1 -1
- package/dist/{payment-orkZA9se.d.ts → payment-BLm1ltur.d.ts} +1 -1
- package/dist/{types-rAQrDrah.d.ts → types-BaTmu0gS.d.ts} +1 -1
- package/dist/validation/index.d.ts +4 -0
- package/dist/validation/index.js +1255 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/wallet/browser.d.ts +1 -1
- package/dist/wallet/index.d.ts +2 -2
- package/dist/x402/index.d.ts +1 -1
- package/package.json +9 -1
- package/templates/base/package.json +1 -1
|
@@ -0,0 +1,831 @@
|
|
|
1
|
+
import { createHmac, randomBytes } from 'crypto';
|
|
2
|
+
import { parseUnits } from 'viem';
|
|
3
|
+
|
|
4
|
+
// src/adapters/polymarket/base.ts
|
|
5
|
+
var PolymarketApiError = class extends Error {
|
|
6
|
+
constructor(message, response) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.response = response;
|
|
9
|
+
this.name = "PolymarketApiError";
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var PolymarketAuthError = class extends Error {
|
|
13
|
+
constructor(message) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.name = "PolymarketAuthError";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var POLYMARKET_ENDPOINTS = {
|
|
19
|
+
gamma: {
|
|
20
|
+
mainnet: "https://gamma-api.polymarket.com",
|
|
21
|
+
testnet: "https://gamma-api.polymarket.com"
|
|
22
|
+
},
|
|
23
|
+
clob: {
|
|
24
|
+
mainnet: "https://clob.polymarket.com",
|
|
25
|
+
testnet: "https://clob.polymarket.com"
|
|
26
|
+
},
|
|
27
|
+
data: {
|
|
28
|
+
mainnet: "https://data-api.polymarket.com",
|
|
29
|
+
testnet: "https://data-api.polymarket.com"
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var POLYMARKET_CHAIN_ID = {
|
|
33
|
+
mainnet: 137,
|
|
34
|
+
testnet: 80002
|
|
35
|
+
};
|
|
36
|
+
var POLYMARKET_EXCHANGE_ADDRESSES = {
|
|
37
|
+
mainnet: {
|
|
38
|
+
ctf: "0x4bfb41d5b3570defd03c39a9a4d8de6bd8b8982e",
|
|
39
|
+
negRisk: "0xc5d563a36ae78145c45a50134d48a1215220f80a"
|
|
40
|
+
},
|
|
41
|
+
testnet: {
|
|
42
|
+
ctf: "0xdfe02eb6733538f8ea35d585af8de5958ad99e40",
|
|
43
|
+
negRisk: "0xdfe02eb6733538f8ea35d585af8de5958ad99e40"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var POLYMARKET_CLOB_DOMAIN = {
|
|
47
|
+
name: "Polymarket CTF Exchange",
|
|
48
|
+
version: "1"
|
|
49
|
+
};
|
|
50
|
+
var POLYMARKET_CLOB_AUTH_DOMAIN = {
|
|
51
|
+
name: "ClobAuthDomain",
|
|
52
|
+
version: "1"
|
|
53
|
+
};
|
|
54
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
55
|
+
function resolvePolymarketBaseUrl(service, environment) {
|
|
56
|
+
return POLYMARKET_ENDPOINTS[service][environment];
|
|
57
|
+
}
|
|
58
|
+
function assertWalletSigner(wallet) {
|
|
59
|
+
if (!wallet?.account || !wallet.walletClient) {
|
|
60
|
+
throw new Error("Polymarket requires a wallet with signing capabilities.");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function toDecimalString(value) {
|
|
64
|
+
if (typeof value === "string") return value;
|
|
65
|
+
if (typeof value === "bigint") return value.toString();
|
|
66
|
+
if (!Number.isFinite(value)) {
|
|
67
|
+
throw new Error("Numeric values must be finite.");
|
|
68
|
+
}
|
|
69
|
+
const asString = value.toString();
|
|
70
|
+
if (/e/i.test(asString)) {
|
|
71
|
+
const [mantissa, exponentPart] = asString.split(/e/i);
|
|
72
|
+
const exponent = Number(exponentPart);
|
|
73
|
+
const [integerPart, fractionalPart = ""] = mantissa.split(".");
|
|
74
|
+
if (exponent >= 0) {
|
|
75
|
+
return integerPart + fractionalPart.padEnd(exponent + fractionalPart.length, "0");
|
|
76
|
+
}
|
|
77
|
+
const zeros = "0".repeat(Math.abs(exponent) - 1);
|
|
78
|
+
return `0.${zeros}${integerPart}${fractionalPart}`.replace(/\.0+$/, "");
|
|
79
|
+
}
|
|
80
|
+
return asString;
|
|
81
|
+
}
|
|
82
|
+
function normalizeArrayish(value) {
|
|
83
|
+
if (Array.isArray(value)) return value;
|
|
84
|
+
if (typeof value === "string") {
|
|
85
|
+
const trimmed = value.trim();
|
|
86
|
+
if (!trimmed) return [];
|
|
87
|
+
if (trimmed.startsWith("[")) {
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(trimmed);
|
|
90
|
+
return Array.isArray(parsed) ? parsed : [];
|
|
91
|
+
} catch {
|
|
92
|
+
return [];
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return [trimmed];
|
|
96
|
+
}
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
function normalizeStringArrayish(value) {
|
|
100
|
+
return normalizeArrayish(value).map((entry) => entry == null ? "" : String(entry).trim()).filter((entry) => entry.length > 0);
|
|
101
|
+
}
|
|
102
|
+
function normalizeNumberArrayish(value) {
|
|
103
|
+
return normalizeArrayish(value).map((entry) => typeof entry === "number" ? entry : Number.parseFloat(String(entry))).filter((entry) => Number.isFinite(entry));
|
|
104
|
+
}
|
|
105
|
+
function normalizeTags(value) {
|
|
106
|
+
if (!Array.isArray(value)) return [];
|
|
107
|
+
const tags = value.map((entry) => {
|
|
108
|
+
if (entry && typeof entry === "object") {
|
|
109
|
+
const record = entry;
|
|
110
|
+
const label = record.label ?? record.id ?? record.tag;
|
|
111
|
+
return label ? String(label).trim() : "";
|
|
112
|
+
}
|
|
113
|
+
return String(entry ?? "").trim();
|
|
114
|
+
}).filter((entry) => entry.length > 0);
|
|
115
|
+
return Array.from(new Set(tags));
|
|
116
|
+
}
|
|
117
|
+
function parseOptionalDate(value) {
|
|
118
|
+
if (!value) return null;
|
|
119
|
+
if (typeof value === "string") {
|
|
120
|
+
const trimmed = value.trim();
|
|
121
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
122
|
+
}
|
|
123
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
124
|
+
const ts = value > 1e12 ? value : value * 1e3;
|
|
125
|
+
const date = new Date(ts);
|
|
126
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
function buildHmacSignature(args) {
|
|
131
|
+
const timestamp = args.timestamp.toString();
|
|
132
|
+
const method = args.method.toUpperCase();
|
|
133
|
+
const path = args.path;
|
|
134
|
+
const body = args.body == null ? "" : typeof args.body === "string" ? args.body : JSON.stringify(args.body);
|
|
135
|
+
const payload = `${timestamp}${method}${path}${body}`;
|
|
136
|
+
const key = Buffer.from(args.secret, "base64");
|
|
137
|
+
return createHmac("sha256", key).update(payload).digest("hex");
|
|
138
|
+
}
|
|
139
|
+
function buildL2Headers(args) {
|
|
140
|
+
const timestamp = args.timestamp ?? Math.floor(Date.now() / 1e3);
|
|
141
|
+
const signature = buildHmacSignature({
|
|
142
|
+
secret: args.credentials.secret,
|
|
143
|
+
timestamp,
|
|
144
|
+
method: args.method,
|
|
145
|
+
path: args.path,
|
|
146
|
+
body: args.body ?? null
|
|
147
|
+
});
|
|
148
|
+
return {
|
|
149
|
+
POLY_ADDRESS: args.address,
|
|
150
|
+
POLY_API_KEY: args.credentials.apiKey,
|
|
151
|
+
POLY_PASSPHRASE: args.credentials.passphrase,
|
|
152
|
+
POLY_TIMESTAMP: timestamp.toString(),
|
|
153
|
+
POLY_SIGNATURE: signature
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
async function buildL1Headers(args) {
|
|
157
|
+
assertWalletSigner(args.wallet);
|
|
158
|
+
const timestamp = args.timestamp ?? Math.floor(Date.now() / 1e3);
|
|
159
|
+
const nonce = args.nonce ?? Date.now();
|
|
160
|
+
const chainId = POLYMARKET_CHAIN_ID[args.environment ?? "mainnet"];
|
|
161
|
+
const address = args.wallet.address;
|
|
162
|
+
const message = args.message ?? "Create or derive a Polymarket API key";
|
|
163
|
+
const signature = await args.wallet.walletClient.signTypedData({
|
|
164
|
+
account: args.wallet.account,
|
|
165
|
+
domain: {
|
|
166
|
+
...POLYMARKET_CLOB_AUTH_DOMAIN,
|
|
167
|
+
chainId
|
|
168
|
+
},
|
|
169
|
+
types: {
|
|
170
|
+
ClobAuth: [
|
|
171
|
+
{ name: "address", type: "address" },
|
|
172
|
+
{ name: "timestamp", type: "string" },
|
|
173
|
+
{ name: "nonce", type: "uint256" },
|
|
174
|
+
{ name: "message", type: "string" }
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
primaryType: "ClobAuth",
|
|
178
|
+
message: {
|
|
179
|
+
address,
|
|
180
|
+
timestamp: timestamp.toString(),
|
|
181
|
+
nonce: BigInt(nonce),
|
|
182
|
+
message
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
return {
|
|
186
|
+
POLY_ADDRESS: address,
|
|
187
|
+
POLY_TIMESTAMP: timestamp.toString(),
|
|
188
|
+
POLY_NONCE: nonce.toString(),
|
|
189
|
+
POLY_SIGNATURE: signature
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function resolveExchangeAddress(args) {
|
|
193
|
+
if (args.exchangeAddress) return args.exchangeAddress;
|
|
194
|
+
const env = args.environment;
|
|
195
|
+
return args.negRisk ? POLYMARKET_EXCHANGE_ADDRESSES[env].negRisk : POLYMARKET_EXCHANGE_ADDRESSES[env].ctf;
|
|
196
|
+
}
|
|
197
|
+
function parseUintString(value, name) {
|
|
198
|
+
const trimmed = value.trim();
|
|
199
|
+
if (!/^\d+$/.test(trimmed)) {
|
|
200
|
+
throw new Error(`${name} must be a base-10 integer string.`);
|
|
201
|
+
}
|
|
202
|
+
return BigInt(trimmed);
|
|
203
|
+
}
|
|
204
|
+
function buildPolymarketOrderAmounts(args) {
|
|
205
|
+
const priceStr = toDecimalString(args.price);
|
|
206
|
+
const sizeStr = toDecimalString(args.size);
|
|
207
|
+
if (!priceStr || !sizeStr) {
|
|
208
|
+
throw new Error("Order price and size are required.");
|
|
209
|
+
}
|
|
210
|
+
const priceFloat = Number(priceStr);
|
|
211
|
+
if (!Number.isFinite(priceFloat) || priceFloat <= 0 || priceFloat >= 1) {
|
|
212
|
+
throw new Error("Order price must be between 0 and 1 (exclusive).");
|
|
213
|
+
}
|
|
214
|
+
const sizeFloat = Number(sizeStr);
|
|
215
|
+
if (!Number.isFinite(sizeFloat) || sizeFloat <= 0) {
|
|
216
|
+
throw new Error("Order size must be positive.");
|
|
217
|
+
}
|
|
218
|
+
let priceUnits = parseUnits(priceStr, 6);
|
|
219
|
+
if (args.tickSize !== void 0) {
|
|
220
|
+
const tickUnits = parseUnits(toDecimalString(args.tickSize), 6);
|
|
221
|
+
if (tickUnits <= 0n) {
|
|
222
|
+
throw new Error("tickSize must be positive.");
|
|
223
|
+
}
|
|
224
|
+
priceUnits = priceUnits / tickUnits * tickUnits;
|
|
225
|
+
}
|
|
226
|
+
const sizeUnits = parseUnits(sizeStr, 6);
|
|
227
|
+
const quoteUnits = priceUnits * sizeUnits / 1000000n;
|
|
228
|
+
if (args.side === "BUY") {
|
|
229
|
+
return { makerAmount: quoteUnits, takerAmount: sizeUnits };
|
|
230
|
+
}
|
|
231
|
+
return { makerAmount: sizeUnits, takerAmount: quoteUnits };
|
|
232
|
+
}
|
|
233
|
+
async function buildSignedOrderPayload(args) {
|
|
234
|
+
assertWalletSigner(args.wallet);
|
|
235
|
+
const environment = args.environment ?? "mainnet";
|
|
236
|
+
const chainId = POLYMARKET_CHAIN_ID[environment];
|
|
237
|
+
const exchangeAddress = resolveExchangeAddress({
|
|
238
|
+
environment,
|
|
239
|
+
...args.negRisk !== void 0 ? { negRisk: args.negRisk } : {},
|
|
240
|
+
...args.exchangeAddress ? { exchangeAddress: args.exchangeAddress } : {}
|
|
241
|
+
});
|
|
242
|
+
const maker = args.maker ?? args.wallet.address;
|
|
243
|
+
const signer = args.signer ?? args.wallet.address;
|
|
244
|
+
const taker = args.taker ?? ZERO_ADDRESS;
|
|
245
|
+
const sideValue = args.side === "BUY" ? 0 : 1;
|
|
246
|
+
const signatureType = args.signatureType ?? 0;
|
|
247
|
+
const tokenIdValue = args.tokenId.startsWith("0x") ? BigInt(args.tokenId) : parseUintString(args.tokenId, "tokenId");
|
|
248
|
+
const { makerAmount, takerAmount } = buildPolymarketOrderAmounts({
|
|
249
|
+
side: args.side,
|
|
250
|
+
price: args.price,
|
|
251
|
+
size: args.size,
|
|
252
|
+
...args.tickSize !== void 0 ? { tickSize: args.tickSize } : {}
|
|
253
|
+
});
|
|
254
|
+
const salt = BigInt(`0x${randomBytes(16).toString("hex")}`);
|
|
255
|
+
const expiration = BigInt(args.expiration ?? 0);
|
|
256
|
+
const nonce = BigInt(args.nonce ?? 0);
|
|
257
|
+
const feeRateBps = BigInt(args.feeRateBps ?? 0);
|
|
258
|
+
const message = {
|
|
259
|
+
salt,
|
|
260
|
+
maker,
|
|
261
|
+
signer,
|
|
262
|
+
taker,
|
|
263
|
+
tokenId: tokenIdValue,
|
|
264
|
+
makerAmount,
|
|
265
|
+
takerAmount,
|
|
266
|
+
expiration,
|
|
267
|
+
nonce,
|
|
268
|
+
feeRateBps,
|
|
269
|
+
side: sideValue,
|
|
270
|
+
signatureType
|
|
271
|
+
};
|
|
272
|
+
const signature = await args.wallet.walletClient.signTypedData({
|
|
273
|
+
account: args.wallet.account,
|
|
274
|
+
domain: {
|
|
275
|
+
...POLYMARKET_CLOB_DOMAIN,
|
|
276
|
+
chainId,
|
|
277
|
+
verifyingContract: exchangeAddress
|
|
278
|
+
},
|
|
279
|
+
types: {
|
|
280
|
+
Order: [
|
|
281
|
+
{ name: "salt", type: "uint256" },
|
|
282
|
+
{ name: "maker", type: "address" },
|
|
283
|
+
{ name: "signer", type: "address" },
|
|
284
|
+
{ name: "taker", type: "address" },
|
|
285
|
+
{ name: "tokenId", type: "uint256" },
|
|
286
|
+
{ name: "makerAmount", type: "uint256" },
|
|
287
|
+
{ name: "takerAmount", type: "uint256" },
|
|
288
|
+
{ name: "expiration", type: "uint256" },
|
|
289
|
+
{ name: "nonce", type: "uint256" },
|
|
290
|
+
{ name: "feeRateBps", type: "uint256" },
|
|
291
|
+
{ name: "side", type: "uint8" },
|
|
292
|
+
{ name: "signatureType", type: "uint8" }
|
|
293
|
+
]
|
|
294
|
+
},
|
|
295
|
+
primaryType: "Order",
|
|
296
|
+
message
|
|
297
|
+
});
|
|
298
|
+
return {
|
|
299
|
+
salt: message.salt.toString(),
|
|
300
|
+
maker,
|
|
301
|
+
signer,
|
|
302
|
+
taker,
|
|
303
|
+
tokenId: tokenIdValue.toString(),
|
|
304
|
+
makerAmount: message.makerAmount.toString(),
|
|
305
|
+
takerAmount: message.takerAmount.toString(),
|
|
306
|
+
expiration: message.expiration.toString(),
|
|
307
|
+
nonce: message.nonce.toString(),
|
|
308
|
+
feeRateBps: message.feeRateBps.toString(),
|
|
309
|
+
side: sideValue,
|
|
310
|
+
signatureType,
|
|
311
|
+
signature
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/adapters/polymarket/exchange.ts
|
|
316
|
+
async function resolveAuthContext(args) {
|
|
317
|
+
if (args.wallet) {
|
|
318
|
+
const credentials = args.credentials ?? await createPolymarketApiKey({
|
|
319
|
+
wallet: args.wallet,
|
|
320
|
+
...args.environment ? { environment: args.environment } : {}
|
|
321
|
+
});
|
|
322
|
+
return {
|
|
323
|
+
credentials,
|
|
324
|
+
address: args.wallet.address
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
if (args.walletAddress && args.credentials) {
|
|
328
|
+
return { credentials: args.credentials, address: args.walletAddress };
|
|
329
|
+
}
|
|
330
|
+
throw new PolymarketAuthError(
|
|
331
|
+
"Polymarket auth requires a wallet (preferred) or credentials + walletAddress."
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
async function requestJson(url, init) {
|
|
335
|
+
const response = await fetch(url, init);
|
|
336
|
+
const text = await response.text().catch(() => "");
|
|
337
|
+
let data = null;
|
|
338
|
+
try {
|
|
339
|
+
data = text ? JSON.parse(text) : null;
|
|
340
|
+
} catch {
|
|
341
|
+
data = text;
|
|
342
|
+
}
|
|
343
|
+
if (!response.ok) {
|
|
344
|
+
throw new PolymarketApiError(
|
|
345
|
+
`Polymarket request failed (${response.status}).`,
|
|
346
|
+
data ?? { status: response.status }
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
return data;
|
|
350
|
+
}
|
|
351
|
+
function resolvePath(url) {
|
|
352
|
+
const parsed = new URL(url);
|
|
353
|
+
return `${parsed.pathname}${parsed.search}`;
|
|
354
|
+
}
|
|
355
|
+
async function createPolymarketApiKey(args) {
|
|
356
|
+
const environment = args.environment ?? "mainnet";
|
|
357
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
358
|
+
const url = `${baseUrl}/auth/api-key`;
|
|
359
|
+
const headers = await buildL1Headers({
|
|
360
|
+
wallet: args.wallet,
|
|
361
|
+
environment,
|
|
362
|
+
...args.timestamp !== void 0 ? { timestamp: args.timestamp } : {},
|
|
363
|
+
...args.nonce !== void 0 ? { nonce: args.nonce } : {},
|
|
364
|
+
...args.message !== void 0 ? { message: args.message } : {}
|
|
365
|
+
});
|
|
366
|
+
const data = await requestJson(url, {
|
|
367
|
+
method: "POST",
|
|
368
|
+
headers: {
|
|
369
|
+
"content-type": "application/json",
|
|
370
|
+
...headers
|
|
371
|
+
},
|
|
372
|
+
body: JSON.stringify({})
|
|
373
|
+
});
|
|
374
|
+
if (!data?.apiKey || !data?.secret || !data?.passphrase) {
|
|
375
|
+
throw new PolymarketAuthError("Failed to create Polymarket API key.");
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
apiKey: data.apiKey,
|
|
379
|
+
secret: data.secret,
|
|
380
|
+
passphrase: data.passphrase
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
async function derivePolymarketApiKey(args) {
|
|
384
|
+
const environment = args.environment ?? "mainnet";
|
|
385
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
386
|
+
const url = `${baseUrl}/auth/derive-api-key`;
|
|
387
|
+
const headers = await buildL1Headers({
|
|
388
|
+
wallet: args.wallet,
|
|
389
|
+
environment,
|
|
390
|
+
...args.timestamp !== void 0 ? { timestamp: args.timestamp } : {},
|
|
391
|
+
...args.nonce !== void 0 ? { nonce: args.nonce } : {},
|
|
392
|
+
...args.message !== void 0 ? { message: args.message } : {}
|
|
393
|
+
});
|
|
394
|
+
const data = await requestJson(url, {
|
|
395
|
+
method: "GET",
|
|
396
|
+
headers: {
|
|
397
|
+
"content-type": "application/json",
|
|
398
|
+
...headers
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
if (!data?.apiKey || !data?.secret || !data?.passphrase) {
|
|
402
|
+
throw new PolymarketAuthError("Failed to derive Polymarket API key.");
|
|
403
|
+
}
|
|
404
|
+
return {
|
|
405
|
+
apiKey: data.apiKey,
|
|
406
|
+
secret: data.secret,
|
|
407
|
+
passphrase: data.passphrase
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
async function placePolymarketOrder(args) {
|
|
411
|
+
const environment = args.environment ?? "mainnet";
|
|
412
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
413
|
+
const url = `${baseUrl}/order`;
|
|
414
|
+
const signedOrder = await buildSignedOrderPayload({
|
|
415
|
+
wallet: args.wallet,
|
|
416
|
+
environment,
|
|
417
|
+
...args.order
|
|
418
|
+
});
|
|
419
|
+
const auth = await resolveAuthContext({
|
|
420
|
+
wallet: args.wallet,
|
|
421
|
+
...args.credentials ? { credentials: args.credentials } : {},
|
|
422
|
+
environment
|
|
423
|
+
});
|
|
424
|
+
const body = {
|
|
425
|
+
order: signedOrder,
|
|
426
|
+
owner: auth.credentials.apiKey,
|
|
427
|
+
orderType: args.orderType ?? "GTC"
|
|
428
|
+
};
|
|
429
|
+
const headers = buildL2Headers({
|
|
430
|
+
credentials: auth.credentials,
|
|
431
|
+
address: auth.address,
|
|
432
|
+
method: "POST",
|
|
433
|
+
path: resolvePath(url),
|
|
434
|
+
body
|
|
435
|
+
});
|
|
436
|
+
return await requestJson(url, {
|
|
437
|
+
method: "POST",
|
|
438
|
+
headers: {
|
|
439
|
+
"content-type": "application/json",
|
|
440
|
+
...headers
|
|
441
|
+
},
|
|
442
|
+
body: JSON.stringify(body)
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
async function cancelPolymarketOrder(args) {
|
|
446
|
+
const environment = args.environment ?? "mainnet";
|
|
447
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
448
|
+
const url = `${baseUrl}/order`;
|
|
449
|
+
const body = { orderID: args.orderId };
|
|
450
|
+
const auth = await resolveAuthContext({
|
|
451
|
+
...args.wallet ? { wallet: args.wallet } : {},
|
|
452
|
+
...args.walletAddress ? { walletAddress: args.walletAddress } : {},
|
|
453
|
+
...args.credentials ? { credentials: args.credentials } : {},
|
|
454
|
+
environment
|
|
455
|
+
});
|
|
456
|
+
const headers = buildL2Headers({
|
|
457
|
+
credentials: auth.credentials,
|
|
458
|
+
address: auth.address,
|
|
459
|
+
method: "DELETE",
|
|
460
|
+
path: resolvePath(url),
|
|
461
|
+
body
|
|
462
|
+
});
|
|
463
|
+
return await requestJson(url, {
|
|
464
|
+
method: "DELETE",
|
|
465
|
+
headers: {
|
|
466
|
+
"content-type": "application/json",
|
|
467
|
+
...headers
|
|
468
|
+
},
|
|
469
|
+
body: JSON.stringify(body)
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
async function cancelPolymarketOrders(args) {
|
|
473
|
+
const environment = args.environment ?? "mainnet";
|
|
474
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
475
|
+
const url = `${baseUrl}/orders`;
|
|
476
|
+
const body = { orderIDs: args.orderIds };
|
|
477
|
+
const auth = await resolveAuthContext({
|
|
478
|
+
...args.wallet ? { wallet: args.wallet } : {},
|
|
479
|
+
...args.walletAddress ? { walletAddress: args.walletAddress } : {},
|
|
480
|
+
...args.credentials ? { credentials: args.credentials } : {},
|
|
481
|
+
environment
|
|
482
|
+
});
|
|
483
|
+
const headers = buildL2Headers({
|
|
484
|
+
credentials: auth.credentials,
|
|
485
|
+
address: auth.address,
|
|
486
|
+
method: "DELETE",
|
|
487
|
+
path: resolvePath(url),
|
|
488
|
+
body
|
|
489
|
+
});
|
|
490
|
+
return await requestJson(url, {
|
|
491
|
+
method: "DELETE",
|
|
492
|
+
headers: {
|
|
493
|
+
"content-type": "application/json",
|
|
494
|
+
...headers
|
|
495
|
+
},
|
|
496
|
+
body: JSON.stringify(body)
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
async function cancelAllPolymarketOrders(args) {
|
|
500
|
+
const environment = args.environment ?? "mainnet";
|
|
501
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
502
|
+
const url = `${baseUrl}/cancel-all`;
|
|
503
|
+
const auth = await resolveAuthContext({
|
|
504
|
+
...args.wallet ? { wallet: args.wallet } : {},
|
|
505
|
+
...args.walletAddress ? { walletAddress: args.walletAddress } : {},
|
|
506
|
+
...args.credentials ? { credentials: args.credentials } : {},
|
|
507
|
+
environment
|
|
508
|
+
});
|
|
509
|
+
const headers = buildL2Headers({
|
|
510
|
+
credentials: auth.credentials,
|
|
511
|
+
address: auth.address,
|
|
512
|
+
method: "DELETE",
|
|
513
|
+
path: resolvePath(url)
|
|
514
|
+
});
|
|
515
|
+
return await requestJson(url, {
|
|
516
|
+
method: "DELETE",
|
|
517
|
+
headers: {
|
|
518
|
+
"content-type": "application/json",
|
|
519
|
+
...headers
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
async function cancelMarketPolymarketOrders(args) {
|
|
524
|
+
const environment = args.environment ?? "mainnet";
|
|
525
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
526
|
+
const url = `${baseUrl}/cancel-market-orders`;
|
|
527
|
+
const body = { market: args.tokenId };
|
|
528
|
+
const auth = await resolveAuthContext({
|
|
529
|
+
...args.wallet ? { wallet: args.wallet } : {},
|
|
530
|
+
...args.walletAddress ? { walletAddress: args.walletAddress } : {},
|
|
531
|
+
...args.credentials ? { credentials: args.credentials } : {},
|
|
532
|
+
environment
|
|
533
|
+
});
|
|
534
|
+
const headers = buildL2Headers({
|
|
535
|
+
credentials: auth.credentials,
|
|
536
|
+
address: auth.address,
|
|
537
|
+
method: "DELETE",
|
|
538
|
+
path: resolvePath(url),
|
|
539
|
+
body
|
|
540
|
+
});
|
|
541
|
+
return await requestJson(url, {
|
|
542
|
+
method: "DELETE",
|
|
543
|
+
headers: {
|
|
544
|
+
"content-type": "application/json",
|
|
545
|
+
...headers
|
|
546
|
+
},
|
|
547
|
+
body: JSON.stringify(body)
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
var PolymarketExchangeClient = class {
|
|
551
|
+
constructor(args) {
|
|
552
|
+
this.wallet = args.wallet;
|
|
553
|
+
this.credentials = args.credentials;
|
|
554
|
+
this.environment = args.environment ?? "mainnet";
|
|
555
|
+
}
|
|
556
|
+
async getCredentials() {
|
|
557
|
+
if (this.cachedCredentials) return this.cachedCredentials;
|
|
558
|
+
const resolved = await resolveAuthContext({
|
|
559
|
+
wallet: this.wallet,
|
|
560
|
+
...this.credentials ? { credentials: this.credentials } : {},
|
|
561
|
+
environment: this.environment
|
|
562
|
+
});
|
|
563
|
+
this.cachedCredentials = resolved.credentials;
|
|
564
|
+
return resolved.credentials;
|
|
565
|
+
}
|
|
566
|
+
async placeOrder(order, orderType) {
|
|
567
|
+
const credentials = await this.getCredentials();
|
|
568
|
+
return placePolymarketOrder({
|
|
569
|
+
wallet: this.wallet,
|
|
570
|
+
credentials,
|
|
571
|
+
environment: this.environment,
|
|
572
|
+
order,
|
|
573
|
+
...orderType !== void 0 ? { orderType } : {}
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
async cancelOrder(orderId) {
|
|
577
|
+
const credentials = await this.getCredentials();
|
|
578
|
+
return cancelPolymarketOrder({
|
|
579
|
+
orderId,
|
|
580
|
+
wallet: this.wallet,
|
|
581
|
+
credentials,
|
|
582
|
+
environment: this.environment
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
async cancelOrders(orderIds) {
|
|
586
|
+
const credentials = await this.getCredentials();
|
|
587
|
+
return cancelPolymarketOrders({
|
|
588
|
+
orderIds,
|
|
589
|
+
wallet: this.wallet,
|
|
590
|
+
credentials,
|
|
591
|
+
environment: this.environment
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
async cancelAll() {
|
|
595
|
+
const credentials = await this.getCredentials();
|
|
596
|
+
return cancelAllPolymarketOrders({
|
|
597
|
+
wallet: this.wallet,
|
|
598
|
+
credentials,
|
|
599
|
+
environment: this.environment
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
async cancelMarket(tokenId) {
|
|
603
|
+
const credentials = await this.getCredentials();
|
|
604
|
+
return cancelMarketPolymarketOrders({
|
|
605
|
+
tokenId,
|
|
606
|
+
wallet: this.wallet,
|
|
607
|
+
credentials,
|
|
608
|
+
environment: this.environment
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
|
|
613
|
+
// src/adapters/polymarket/info.ts
|
|
614
|
+
var DEFAULT_EVENT_LIMIT = 50;
|
|
615
|
+
async function requestJson2(url, init) {
|
|
616
|
+
const response = await fetch(url, init);
|
|
617
|
+
const text = await response.text().catch(() => "");
|
|
618
|
+
let data = null;
|
|
619
|
+
try {
|
|
620
|
+
data = text ? JSON.parse(text) : null;
|
|
621
|
+
} catch {
|
|
622
|
+
data = text;
|
|
623
|
+
}
|
|
624
|
+
if (!response.ok) {
|
|
625
|
+
throw new PolymarketApiError(
|
|
626
|
+
`Polymarket request failed (${response.status}).`,
|
|
627
|
+
data ?? { status: response.status }
|
|
628
|
+
);
|
|
629
|
+
}
|
|
630
|
+
return data;
|
|
631
|
+
}
|
|
632
|
+
function getString(value) {
|
|
633
|
+
if (value == null) return null;
|
|
634
|
+
const str = String(value).trim();
|
|
635
|
+
return str.length ? str : null;
|
|
636
|
+
}
|
|
637
|
+
function normalizeOrderbookLevels(raw) {
|
|
638
|
+
if (!Array.isArray(raw)) return [];
|
|
639
|
+
return raw.map((entry) => {
|
|
640
|
+
if (Array.isArray(entry)) {
|
|
641
|
+
const [price, size] = entry;
|
|
642
|
+
const p = Number(price);
|
|
643
|
+
const s = Number(size);
|
|
644
|
+
if (!Number.isFinite(p) || !Number.isFinite(s)) return null;
|
|
645
|
+
return { price: p, size: s };
|
|
646
|
+
}
|
|
647
|
+
if (entry && typeof entry === "object") {
|
|
648
|
+
const record = entry;
|
|
649
|
+
const p = Number(record.price ?? record.p);
|
|
650
|
+
const s = Number(record.size ?? record.s ?? record.quantity);
|
|
651
|
+
if (!Number.isFinite(p) || !Number.isFinite(s)) return null;
|
|
652
|
+
return { price: p, size: s };
|
|
653
|
+
}
|
|
654
|
+
return null;
|
|
655
|
+
}).filter((entry) => Boolean(entry));
|
|
656
|
+
}
|
|
657
|
+
function normalizeGammaMarket(market, event) {
|
|
658
|
+
const eventTags = normalizeTags(event?.tags);
|
|
659
|
+
const marketTags = normalizeTags(market.tags);
|
|
660
|
+
const mergedTags = Array.from(/* @__PURE__ */ new Set([...marketTags, ...eventTags]));
|
|
661
|
+
const category = getString(market.category) ?? getString(event?.category) ?? getString(event?.title) ?? null;
|
|
662
|
+
const normalized = {
|
|
663
|
+
id: getString(market.id) ?? "",
|
|
664
|
+
slug: getString(market.slug),
|
|
665
|
+
question: getString(market.question),
|
|
666
|
+
description: getString(market.description),
|
|
667
|
+
eventId: getString(market.eventId ?? event?.id),
|
|
668
|
+
eventSlug: getString(event?.slug),
|
|
669
|
+
conditionId: getString(market.conditionId),
|
|
670
|
+
marketMakerAddress: getString(market.marketMakerAddress),
|
|
671
|
+
category,
|
|
672
|
+
startDate: parseOptionalDate(market.startDate) ?? parseOptionalDate(event?.startDate) ?? parseOptionalDate(event?.eventStartTime),
|
|
673
|
+
endDate: parseOptionalDate(market.endDate) ?? parseOptionalDate(event?.endDate) ?? parseOptionalDate(event?.eventEndTime),
|
|
674
|
+
createdAt: parseOptionalDate(market.createdAt) ?? parseOptionalDate(event?.createdAt) ?? parseOptionalDate(event?.creationDate),
|
|
675
|
+
updatedAt: parseOptionalDate(market.updatedAt) ?? parseOptionalDate(event?.updatedAt),
|
|
676
|
+
closedTime: parseOptionalDate(market.closedTime) ?? parseOptionalDate(event?.closedTime),
|
|
677
|
+
volume: getString(market.volume),
|
|
678
|
+
liquidity: getString(market.liquidity),
|
|
679
|
+
openInterest: getString(market.openInterest),
|
|
680
|
+
outcomes: normalizeStringArrayish(market.outcomes),
|
|
681
|
+
outcomePrices: normalizeNumberArrayish(market.outcomePrices),
|
|
682
|
+
clobTokenIds: normalizeStringArrayish(market.clobTokenIds),
|
|
683
|
+
icon: getString(market.icon),
|
|
684
|
+
image: getString(market.image)
|
|
685
|
+
};
|
|
686
|
+
if (mergedTags.length) {
|
|
687
|
+
normalized.tags = mergedTags;
|
|
688
|
+
}
|
|
689
|
+
if (typeof market.active === "boolean") {
|
|
690
|
+
normalized.active = market.active;
|
|
691
|
+
}
|
|
692
|
+
if (typeof market.closed === "boolean") {
|
|
693
|
+
normalized.closed = market.closed;
|
|
694
|
+
}
|
|
695
|
+
if (typeof market.resolved === "boolean") {
|
|
696
|
+
normalized.resolved = market.resolved;
|
|
697
|
+
}
|
|
698
|
+
return normalized;
|
|
699
|
+
}
|
|
700
|
+
var PolymarketInfoClient = class {
|
|
701
|
+
constructor(environment = "mainnet") {
|
|
702
|
+
this.environment = environment;
|
|
703
|
+
}
|
|
704
|
+
markets(params = {}) {
|
|
705
|
+
return fetchPolymarketMarkets({ ...params, environment: this.environment });
|
|
706
|
+
}
|
|
707
|
+
market(params) {
|
|
708
|
+
return fetchPolymarketMarket({ ...params, environment: this.environment });
|
|
709
|
+
}
|
|
710
|
+
orderbook(tokenId) {
|
|
711
|
+
return fetchPolymarketOrderbook({ tokenId, environment: this.environment });
|
|
712
|
+
}
|
|
713
|
+
price(tokenId, side) {
|
|
714
|
+
return fetchPolymarketPrice({ tokenId, side, environment: this.environment });
|
|
715
|
+
}
|
|
716
|
+
midpoint(tokenId) {
|
|
717
|
+
return fetchPolymarketMidpoint({ tokenId, environment: this.environment });
|
|
718
|
+
}
|
|
719
|
+
priceHistory(params) {
|
|
720
|
+
return fetchPolymarketPriceHistory({ ...params, environment: this.environment });
|
|
721
|
+
}
|
|
722
|
+
};
|
|
723
|
+
async function fetchPolymarketMarkets(params = {}) {
|
|
724
|
+
if (params.active !== void 0 && params.active !== true) {
|
|
725
|
+
throw new Error("Polymarket market list requires active=true.");
|
|
726
|
+
}
|
|
727
|
+
if (params.closed !== void 0 && params.closed !== false) {
|
|
728
|
+
throw new Error("Polymarket market list requires closed=false.");
|
|
729
|
+
}
|
|
730
|
+
const environment = params.environment ?? "mainnet";
|
|
731
|
+
const baseUrl = resolvePolymarketBaseUrl("gamma", environment);
|
|
732
|
+
const url = new URL("/events", baseUrl);
|
|
733
|
+
const limit = params.limit ?? DEFAULT_EVENT_LIMIT;
|
|
734
|
+
const offset = params.offset ?? 0;
|
|
735
|
+
url.searchParams.set("limit", String(limit));
|
|
736
|
+
url.searchParams.set("offset", String(offset));
|
|
737
|
+
url.searchParams.set("active", "true");
|
|
738
|
+
url.searchParams.set("closed", "false");
|
|
739
|
+
url.searchParams.set("order", params.order ?? "id");
|
|
740
|
+
url.searchParams.set("ascending", params.ascending ? "true" : "false");
|
|
741
|
+
if (params.tagId) url.searchParams.set("tag_id", params.tagId);
|
|
742
|
+
if (params.relatedTags) url.searchParams.set("related_tags", "true");
|
|
743
|
+
if (params.excludeTagId) url.searchParams.set("exclude_tag_id", params.excludeTagId);
|
|
744
|
+
if (params.slug) url.searchParams.set("slug", params.slug);
|
|
745
|
+
const data = await requestJson2(url.toString());
|
|
746
|
+
const markets = data.flatMap(
|
|
747
|
+
(event) => Array.isArray(event?.markets) ? event.markets.map((market) => normalizeGammaMarket(market, event)) : []
|
|
748
|
+
);
|
|
749
|
+
const filtered = params.category ? markets.filter(
|
|
750
|
+
(market) => (market.category ?? "").toLowerCase().includes(params.category.toLowerCase())
|
|
751
|
+
) : markets;
|
|
752
|
+
return typeof params.limit === "number" ? filtered.slice(0, params.limit) : filtered;
|
|
753
|
+
}
|
|
754
|
+
async function fetchPolymarketMarket(params) {
|
|
755
|
+
const environment = params.environment ?? "mainnet";
|
|
756
|
+
const baseUrl = resolvePolymarketBaseUrl("gamma", environment);
|
|
757
|
+
if (params.slug) {
|
|
758
|
+
const url = new URL(`/markets/slug/${params.slug}`, baseUrl);
|
|
759
|
+
const data = await requestJson2(url.toString());
|
|
760
|
+
if (!data) return null;
|
|
761
|
+
return normalizeGammaMarket(data);
|
|
762
|
+
}
|
|
763
|
+
if (params.id) {
|
|
764
|
+
const url = new URL(`/markets/${params.id}`, baseUrl);
|
|
765
|
+
const data = await requestJson2(url.toString());
|
|
766
|
+
if (!data) return null;
|
|
767
|
+
return normalizeGammaMarket(data);
|
|
768
|
+
}
|
|
769
|
+
if (params.conditionId) {
|
|
770
|
+
const url = new URL(`/markets`, baseUrl);
|
|
771
|
+
url.searchParams.set("condition_id", params.conditionId);
|
|
772
|
+
const data = await requestJson2(url.toString());
|
|
773
|
+
if (!data) return null;
|
|
774
|
+
const market = Array.isArray(data) ? data[0] : data;
|
|
775
|
+
return market ? normalizeGammaMarket(market) : null;
|
|
776
|
+
}
|
|
777
|
+
throw new Error("id, slug, or conditionId is required.");
|
|
778
|
+
}
|
|
779
|
+
async function fetchPolymarketOrderbook(params) {
|
|
780
|
+
const environment = params.environment ?? "mainnet";
|
|
781
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
782
|
+
const url = new URL("/book", baseUrl);
|
|
783
|
+
url.searchParams.set("token_id", params.tokenId);
|
|
784
|
+
const data = await requestJson2(url.toString());
|
|
785
|
+
return {
|
|
786
|
+
market: params.tokenId,
|
|
787
|
+
bids: normalizeOrderbookLevels(data.bids),
|
|
788
|
+
asks: normalizeOrderbookLevels(data.asks),
|
|
789
|
+
timestamp: getString(data.timestamp)
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
async function fetchPolymarketPrice(params) {
|
|
793
|
+
const environment = params.environment ?? "mainnet";
|
|
794
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
795
|
+
const url = new URL("/price", baseUrl);
|
|
796
|
+
url.searchParams.set("token_id", params.tokenId);
|
|
797
|
+
url.searchParams.set("side", params.side);
|
|
798
|
+
const data = await requestJson2(url.toString());
|
|
799
|
+
const price = Number(data.price ?? data?.p);
|
|
800
|
+
return Number.isFinite(price) ? price : null;
|
|
801
|
+
}
|
|
802
|
+
async function fetchPolymarketMidpoint(params) {
|
|
803
|
+
const baseArgs = {
|
|
804
|
+
tokenId: params.tokenId,
|
|
805
|
+
...params.environment ? { environment: params.environment } : {}
|
|
806
|
+
};
|
|
807
|
+
const buy = await fetchPolymarketPrice({ ...baseArgs, side: "BUY" });
|
|
808
|
+
const sell = await fetchPolymarketPrice({ ...baseArgs, side: "SELL" });
|
|
809
|
+
if (buy == null || sell == null) return null;
|
|
810
|
+
return (buy + sell) / 2;
|
|
811
|
+
}
|
|
812
|
+
async function fetchPolymarketPriceHistory(params) {
|
|
813
|
+
const environment = params.environment ?? "mainnet";
|
|
814
|
+
const baseUrl = resolvePolymarketBaseUrl("clob", environment);
|
|
815
|
+
const url = new URL("/prices-history", baseUrl);
|
|
816
|
+
url.searchParams.set("market", params.tokenId);
|
|
817
|
+
if (params.startTs) url.searchParams.set("startTs", params.startTs.toString());
|
|
818
|
+
if (params.endTs) url.searchParams.set("endTs", params.endTs.toString());
|
|
819
|
+
if (params.interval) url.searchParams.set("interval", params.interval);
|
|
820
|
+
if (params.fidelity) url.searchParams.set("fidelity", params.fidelity.toString());
|
|
821
|
+
const data = await requestJson2(url.toString());
|
|
822
|
+
const points = Array.isArray(data) ? data : data?.history ?? [];
|
|
823
|
+
return points.map((point) => ({
|
|
824
|
+
t: Number(point.t),
|
|
825
|
+
p: Number(point.p)
|
|
826
|
+
})).filter((point) => Number.isFinite(point.t) && Number.isFinite(point.p));
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
export { POLYMARKET_CHAIN_ID, POLYMARKET_CLOB_AUTH_DOMAIN, POLYMARKET_CLOB_DOMAIN, POLYMARKET_ENDPOINTS, POLYMARKET_EXCHANGE_ADDRESSES, PolymarketApiError, PolymarketAuthError, PolymarketExchangeClient, PolymarketInfoClient, buildHmacSignature, buildL1Headers, buildL2Headers, buildPolymarketOrderAmounts, buildSignedOrderPayload, cancelAllPolymarketOrders, cancelMarketPolymarketOrders, cancelPolymarketOrder, cancelPolymarketOrders, createPolymarketApiKey, derivePolymarketApiKey, fetchPolymarketMarket, fetchPolymarketMarkets, fetchPolymarketMidpoint, fetchPolymarketOrderbook, fetchPolymarketPrice, fetchPolymarketPriceHistory, normalizeNumberArrayish, normalizeStringArrayish, placePolymarketOrder, resolveExchangeAddress, resolvePolymarketBaseUrl };
|
|
830
|
+
//# sourceMappingURL=index.js.map
|
|
831
|
+
//# sourceMappingURL=index.js.map
|