@elsoul/erpc-sdk 0.7.0 → 0.8.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/README.md +154 -5
- package/dist/index.cjs +2484 -101
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +235 -5
- package/dist/index.d.ts +235 -5
- package/dist/index.js +2470 -102
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,11 +7,88 @@ var credentialVariants = (credential) => {
|
|
|
7
7
|
componentEncoded = encodeURIComponent(credential);
|
|
8
8
|
} catch {
|
|
9
9
|
}
|
|
10
|
-
return [
|
|
10
|
+
return [
|
|
11
|
+
.../* @__PURE__ */ new Set([
|
|
12
|
+
credential,
|
|
13
|
+
componentEncoded,
|
|
14
|
+
queryEncoded
|
|
15
|
+
])
|
|
16
|
+
].filter((value) => Boolean(value)).sort((left, right) => right.length - left.length);
|
|
17
|
+
};
|
|
18
|
+
var directEndpointVariants = (endpoint) => {
|
|
19
|
+
const values = [];
|
|
20
|
+
const add = (value) => {
|
|
21
|
+
if (value) values.push(value);
|
|
22
|
+
};
|
|
23
|
+
for (const value of endpoint.searchParams.values()) add(value);
|
|
24
|
+
const rawQuery = endpoint.search.startsWith("?") ? endpoint.search.slice(1) : endpoint.search;
|
|
25
|
+
for (const part of rawQuery.split("&")) {
|
|
26
|
+
const separator = part.indexOf("=");
|
|
27
|
+
const rawValue = separator === -1 ? "" : part.slice(separator + 1);
|
|
28
|
+
add(rawValue);
|
|
29
|
+
if (rawValue) {
|
|
30
|
+
try {
|
|
31
|
+
add(decodeURIComponent(rawValue.replaceAll("+", " ")));
|
|
32
|
+
} catch {
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return values;
|
|
37
|
+
};
|
|
38
|
+
var headerVariants = (headers) => {
|
|
39
|
+
const values = [];
|
|
40
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
41
|
+
values.push(value);
|
|
42
|
+
if (name.toLowerCase() !== "authorization" && name.toLowerCase() !== "proxy-authorization") continue;
|
|
43
|
+
const match = /^\s*[^\s]+\s+(.+?)\s*$/u.exec(value);
|
|
44
|
+
if (match?.[1]) values.push(match[1]);
|
|
45
|
+
if (match?.[1] && /^basic$/iu.test(value.trim().split(/\s+/u, 1)[0] ?? "")) {
|
|
46
|
+
try {
|
|
47
|
+
const decoded = globalThis.atob(match[1]);
|
|
48
|
+
values.push(decoded);
|
|
49
|
+
const separator = decoded.indexOf(":");
|
|
50
|
+
if (separator !== -1) {
|
|
51
|
+
values.push(decoded.slice(0, separator), decoded.slice(separator + 1));
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return values;
|
|
58
|
+
};
|
|
59
|
+
var directRedactionVariants = (endpoint, headers = {}) => [.../* @__PURE__ */ new Set([...directEndpointVariants(endpoint), ...headerVariants(headers)])].flatMap((value) => credentialVariants(value)).filter((value, index, all) => all.indexOf(value) === index).sort((left, right) => right.length - left.length);
|
|
60
|
+
var escapeRegex = (value) => value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
61
|
+
var hexCharacterPattern = (value) => {
|
|
62
|
+
const lower = value.toLowerCase();
|
|
63
|
+
const upper = value.toUpperCase();
|
|
64
|
+
if (lower === upper) return escapeRegex(value);
|
|
65
|
+
return `[${lower}${upper}]`;
|
|
66
|
+
};
|
|
67
|
+
var percentTripletPattern = (value) => {
|
|
68
|
+
const pattern = /%([0-9a-f])([0-9a-f])/giu;
|
|
69
|
+
let result = "";
|
|
70
|
+
let offset = 0;
|
|
71
|
+
for (const match of value.matchAll(pattern)) {
|
|
72
|
+
const index = match.index ?? 0;
|
|
73
|
+
result += escapeRegex(value.slice(offset, index));
|
|
74
|
+
result += `%${hexCharacterPattern(match[1] ?? "")}${hexCharacterPattern(
|
|
75
|
+
match[2] ?? ""
|
|
76
|
+
)}`;
|
|
77
|
+
offset = index + match[0].length;
|
|
78
|
+
}
|
|
79
|
+
return result + escapeRegex(value.slice(offset));
|
|
11
80
|
};
|
|
12
81
|
var redactString = (value, variants) => {
|
|
13
82
|
let redacted = value;
|
|
14
|
-
for (const variant of variants)
|
|
83
|
+
for (const variant of variants) {
|
|
84
|
+
if (!variant) continue;
|
|
85
|
+
const pattern = percentTripletPattern(variant);
|
|
86
|
+
if (pattern === escapeRegex(variant)) {
|
|
87
|
+
redacted = redacted.replaceAll(variant, REDACTED);
|
|
88
|
+
} else {
|
|
89
|
+
redacted = redacted.replace(new RegExp(pattern, "gu"), REDACTED);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
15
92
|
return redacted;
|
|
16
93
|
};
|
|
17
94
|
var redactValue = (value, variants, seen, depth) => {
|
|
@@ -24,7 +101,7 @@ var redactValue = (value, variants, seen, depth) => {
|
|
|
24
101
|
}
|
|
25
102
|
const result = {};
|
|
26
103
|
for (const [key, item] of Object.entries(value)) {
|
|
27
|
-
Object.defineProperty(result, key, {
|
|
104
|
+
Object.defineProperty(result, redactString(key, variants), {
|
|
28
105
|
configurable: true,
|
|
29
106
|
enumerable: true,
|
|
30
107
|
value: redactValue(item, variants, seen, depth + 1),
|
|
@@ -33,9 +110,12 @@ var redactValue = (value, variants, seen, depth) => {
|
|
|
33
110
|
}
|
|
34
111
|
return result;
|
|
35
112
|
};
|
|
36
|
-
var redactJsonRpcError = (error, credential) => {
|
|
37
|
-
|
|
38
|
-
|
|
113
|
+
var redactJsonRpcError = (error, credential, additionalCredentials = []) => {
|
|
114
|
+
const variants = [.../* @__PURE__ */ new Set([
|
|
115
|
+
...credential ? credentialVariants(credential) : [],
|
|
116
|
+
...additionalCredentials
|
|
117
|
+
])].sort((left, right) => right.length - left.length);
|
|
118
|
+
if (variants.length === 0) return error;
|
|
39
119
|
const result = {
|
|
40
120
|
code: error.code,
|
|
41
121
|
message: redactString(error.message, variants)
|
|
@@ -59,6 +139,14 @@ var ErpcConfigError = class extends ErpcError {
|
|
|
59
139
|
this.name = "ErpcConfigError";
|
|
60
140
|
}
|
|
61
141
|
};
|
|
142
|
+
var ErpcNotConfiguredError = class extends ErpcError {
|
|
143
|
+
namespace;
|
|
144
|
+
constructor(namespace) {
|
|
145
|
+
super("ERPC_NOT_CONFIGURED", `ERPC namespace '${namespace}' is not configured`);
|
|
146
|
+
this.name = "ErpcNotConfiguredError";
|
|
147
|
+
this.namespace = namespace;
|
|
148
|
+
}
|
|
149
|
+
};
|
|
62
150
|
var ErpcTransportError = class extends ErpcError {
|
|
63
151
|
constructor(message, options) {
|
|
64
152
|
super("ERPC_TRANSPORT", message, options);
|
|
@@ -165,12 +253,14 @@ var RestTransport = class {
|
|
|
165
253
|
#fetch;
|
|
166
254
|
#headers;
|
|
167
255
|
#timeoutMs;
|
|
256
|
+
#unavailableNamespace;
|
|
168
257
|
constructor(config) {
|
|
169
|
-
this.#apiKey = config.apiKey;
|
|
258
|
+
this.#apiKey = config.apiKey ?? "";
|
|
170
259
|
this.#endpoint = new URL(config.endpoint);
|
|
171
260
|
this.#fetch = config.fetch;
|
|
172
261
|
this.#headers = config.headers;
|
|
173
262
|
this.#timeoutMs = config.timeoutMs;
|
|
263
|
+
this.#unavailableNamespace = config.unavailableNamespace;
|
|
174
264
|
const endpoint = new URL(config.endpoint);
|
|
175
265
|
endpoint.search = "";
|
|
176
266
|
endpoint.hash = "";
|
|
@@ -184,6 +274,9 @@ var RestTransport = class {
|
|
|
184
274
|
return url;
|
|
185
275
|
}
|
|
186
276
|
async get(path, query, options = {}) {
|
|
277
|
+
if (this.#unavailableNamespace !== void 0) {
|
|
278
|
+
throw new ErpcNotConfiguredError(this.#unavailableNamespace);
|
|
279
|
+
}
|
|
187
280
|
const controlled = controlledSignal(this.#timeoutMs, options.signal);
|
|
188
281
|
try {
|
|
189
282
|
const response = await this.#get(path, query, controlled.signal);
|
|
@@ -201,6 +294,9 @@ var RestTransport = class {
|
|
|
201
294
|
}
|
|
202
295
|
}
|
|
203
296
|
async stream(path, query, options = {}) {
|
|
297
|
+
if (this.#unavailableNamespace !== void 0) {
|
|
298
|
+
throw new ErpcNotConfiguredError(this.#unavailableNamespace);
|
|
299
|
+
}
|
|
204
300
|
const controlled = controlledSignal(this.#timeoutMs, options.signal);
|
|
205
301
|
try {
|
|
206
302
|
const response = await this.#get(path, query, controlled.signal);
|
|
@@ -217,13 +313,16 @@ var RestTransport = class {
|
|
|
217
313
|
}
|
|
218
314
|
}
|
|
219
315
|
#get(path, query, signal) {
|
|
316
|
+
const headers = {
|
|
317
|
+
...this.#headers,
|
|
318
|
+
accept: "application/json"
|
|
319
|
+
};
|
|
320
|
+
if (this.#unavailableNamespace === void 0) {
|
|
321
|
+
headers.authorization = `Bearer ${this.#apiKey}`;
|
|
322
|
+
}
|
|
220
323
|
return this.#fetch(this.url(path, query), {
|
|
221
324
|
method: "GET",
|
|
222
|
-
headers
|
|
223
|
-
...this.#headers,
|
|
224
|
-
authorization: `Bearer ${this.#apiKey}`,
|
|
225
|
-
accept: "application/json"
|
|
226
|
-
},
|
|
325
|
+
headers,
|
|
227
326
|
signal
|
|
228
327
|
});
|
|
229
328
|
}
|
|
@@ -2447,22 +2546,97 @@ var requireFetch = (provided) => {
|
|
|
2447
2546
|
}
|
|
2448
2547
|
return implementation;
|
|
2449
2548
|
};
|
|
2549
|
+
var normalizeLegacyEndpoint = (endpoint) => {
|
|
2550
|
+
endpoint.search = "";
|
|
2551
|
+
endpoint.hash = "";
|
|
2552
|
+
endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
|
|
2553
|
+
return endpoint;
|
|
2554
|
+
};
|
|
2555
|
+
var explicitAuthority = (value) => /^[a-z][a-z\d+.-]*:\/\//iu.test(value);
|
|
2556
|
+
var hasUserInfo = (value) => {
|
|
2557
|
+
const separator = value.indexOf("://");
|
|
2558
|
+
if (separator === -1) return false;
|
|
2559
|
+
const authorityAndPath = value.slice(separator + 3);
|
|
2560
|
+
const authority = authorityAndPath.split(/[/?#]/u, 1)[0] ?? "";
|
|
2561
|
+
return authority.length === 0 || authority.includes("@");
|
|
2562
|
+
};
|
|
2563
|
+
var parseDirectUrl = (value, namespace, kind) => {
|
|
2564
|
+
if (typeof value !== "string") {
|
|
2565
|
+
throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
|
|
2566
|
+
}
|
|
2567
|
+
const input = value.trim();
|
|
2568
|
+
if (!input || !explicitAuthority(input) || input.includes("#") || hasUserInfo(input)) {
|
|
2569
|
+
throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
|
|
2570
|
+
}
|
|
2571
|
+
let url;
|
|
2572
|
+
try {
|
|
2573
|
+
url = new URL(input);
|
|
2574
|
+
} catch {
|
|
2575
|
+
throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
|
|
2576
|
+
}
|
|
2577
|
+
const allowed = kind === "HTTP(S)" ? url.protocol === "http:" || url.protocol === "https:" : url.protocol === "ws:" || url.protocol === "wss:";
|
|
2578
|
+
if (!allowed || !url.hostname || url.username || url.password) {
|
|
2579
|
+
throw new ErpcConfigError(`${namespace} URL must be an absolute ${kind} URL`);
|
|
2580
|
+
}
|
|
2581
|
+
return url;
|
|
2582
|
+
};
|
|
2583
|
+
var directHeaders = (value, namespace) => {
|
|
2584
|
+
if (value === void 0) return {};
|
|
2585
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2586
|
+
throw new ErpcConfigError(`${namespace} headers must be string values`);
|
|
2587
|
+
}
|
|
2588
|
+
const result = {};
|
|
2589
|
+
for (const [name, header] of Object.entries(value)) {
|
|
2590
|
+
if (typeof header !== "string") {
|
|
2591
|
+
throw new ErpcConfigError(`${namespace} headers must be string values`);
|
|
2592
|
+
}
|
|
2593
|
+
result[name] = header;
|
|
2594
|
+
}
|
|
2595
|
+
return Object.freeze(result);
|
|
2596
|
+
};
|
|
2597
|
+
var resolveRpcEndpoint = (value, namespace) => {
|
|
2598
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2599
|
+
throw new ErpcConfigError(`${namespace} must define an HTTP(S) URL`);
|
|
2600
|
+
}
|
|
2601
|
+
const config = value;
|
|
2602
|
+
const httpUrl = parseDirectUrl(config.httpUrl, `${namespace}.httpUrl`, "HTTP(S)");
|
|
2603
|
+
const webSocketUrl = config.webSocketUrl === void 0 ? void 0 : parseDirectUrl(
|
|
2604
|
+
config.webSocketUrl,
|
|
2605
|
+
`${namespace}.webSocketUrl`,
|
|
2606
|
+
"WS(S)"
|
|
2607
|
+
);
|
|
2608
|
+
const headers = directHeaders(config.headers, namespace);
|
|
2609
|
+
return {
|
|
2610
|
+
headers,
|
|
2611
|
+
httpUrl,
|
|
2612
|
+
...webSocketUrl === void 0 ? {} : { webSocketUrl }
|
|
2613
|
+
};
|
|
2614
|
+
};
|
|
2450
2615
|
var resolveConfig = (config) => {
|
|
2451
|
-
const
|
|
2452
|
-
|
|
2616
|
+
const configuredApiKey = config.apiKey === void 0 ? void 0 : typeof config.apiKey === "string" ? config.apiKey.trim() : (() => {
|
|
2617
|
+
throw new ErpcConfigError("apiKey must be a string");
|
|
2618
|
+
})();
|
|
2619
|
+
const solanaRpc = config.solanaRpc === void 0 ? void 0 : resolveRpcEndpoint(config.solanaRpc, "solanaRpc");
|
|
2620
|
+
const ethereumRpc = config.ethereumRpc === void 0 ? void 0 : resolveRpcEndpoint(config.ethereumRpc, "ethereumRpc");
|
|
2621
|
+
const avalancheCRpc = config.avalancheCRpc === void 0 ? void 0 : resolveRpcEndpoint(config.avalancheCRpc, "avalancheCRpc");
|
|
2622
|
+
const hasDirectRpc = solanaRpc !== void 0 || ethereumRpc !== void 0 || avalancheCRpc !== void 0;
|
|
2623
|
+
if (!configuredApiKey && !hasDirectRpc) {
|
|
2624
|
+
throw new ErpcConfigError("apiKey must not be empty");
|
|
2625
|
+
}
|
|
2626
|
+
const apiKey = configuredApiKey || void 0;
|
|
2453
2627
|
let endpoint;
|
|
2454
2628
|
let avalancheEndpoint;
|
|
2455
2629
|
let accountEndpoint;
|
|
2456
2630
|
let userEndpoint;
|
|
2457
2631
|
try {
|
|
2458
|
-
endpoint = new URL(config.endpoint ?? DEFAULT_ENDPOINT);
|
|
2459
|
-
avalancheEndpoint = new URL(
|
|
2632
|
+
endpoint = normalizeLegacyEndpoint(new URL(config.endpoint ?? DEFAULT_ENDPOINT));
|
|
2633
|
+
avalancheEndpoint = normalizeLegacyEndpoint(new URL(
|
|
2460
2634
|
config.avalancheEndpoint ?? DEFAULT_AVALANCHE_ENDPOINT
|
|
2461
|
-
);
|
|
2462
|
-
accountEndpoint = new URL(
|
|
2635
|
+
));
|
|
2636
|
+
accountEndpoint = normalizeLegacyEndpoint(new URL(
|
|
2463
2637
|
config.accountEndpoint ?? DEFAULT_ACCOUNT_ENDPOINT
|
|
2464
|
-
);
|
|
2465
|
-
userEndpoint = new URL(config.userEndpoint ?? DEFAULT_USER_ENDPOINT);
|
|
2638
|
+
));
|
|
2639
|
+
userEndpoint = normalizeLegacyEndpoint(new URL(config.userEndpoint ?? DEFAULT_USER_ENDPOINT));
|
|
2466
2640
|
} catch {
|
|
2467
2641
|
throw new ErpcConfigError("endpoint must be an absolute HTTP(S) URL");
|
|
2468
2642
|
}
|
|
@@ -2478,31 +2652,22 @@ var resolveConfig = (config) => {
|
|
|
2478
2652
|
if (userEndpoint.protocol !== "https:" && userEndpoint.protocol !== "http:") {
|
|
2479
2653
|
throw new ErpcConfigError("userEndpoint must use HTTP or HTTPS");
|
|
2480
2654
|
}
|
|
2481
|
-
endpoint.search = "";
|
|
2482
|
-
endpoint.hash = "";
|
|
2483
|
-
endpoint.pathname = endpoint.pathname.replace(/\/+$/, "") || "/";
|
|
2484
|
-
avalancheEndpoint.search = "";
|
|
2485
|
-
avalancheEndpoint.hash = "";
|
|
2486
|
-
avalancheEndpoint.pathname = avalancheEndpoint.pathname.replace(/\/+$/, "") || "/";
|
|
2487
|
-
accountEndpoint.search = "";
|
|
2488
|
-
accountEndpoint.hash = "";
|
|
2489
|
-
accountEndpoint.pathname = accountEndpoint.pathname.replace(/\/+$/, "") || "/";
|
|
2490
|
-
userEndpoint.search = "";
|
|
2491
|
-
userEndpoint.hash = "";
|
|
2492
|
-
userEndpoint.pathname = userEndpoint.pathname.replace(/\/+$/, "") || "/";
|
|
2493
2655
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
2494
2656
|
if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
|
|
2495
2657
|
throw new ErpcConfigError("timeoutMs must be a positive finite number");
|
|
2496
2658
|
}
|
|
2497
2659
|
return {
|
|
2498
2660
|
accountEndpoint,
|
|
2499
|
-
apiKey,
|
|
2500
2661
|
avalancheEndpoint,
|
|
2501
2662
|
endpoint,
|
|
2502
2663
|
fetch: requireFetch(config.fetch),
|
|
2503
2664
|
headers: config.headers ?? {},
|
|
2504
2665
|
timeoutMs,
|
|
2505
2666
|
userEndpoint,
|
|
2667
|
+
...apiKey === void 0 ? {} : { apiKey },
|
|
2668
|
+
...avalancheCRpc === void 0 ? {} : { avalancheCRpc },
|
|
2669
|
+
...ethereumRpc === void 0 ? {} : { ethereumRpc },
|
|
2670
|
+
...solanaRpc === void 0 ? {} : { solanaRpc },
|
|
2506
2671
|
...config.webSocket === void 0 ? {} : { webSocket: config.webSocket }
|
|
2507
2672
|
};
|
|
2508
2673
|
};
|
|
@@ -2844,16 +3009,16 @@ var nativeNamespace = (transport, methodPrefix) => createRpcNamespace({
|
|
|
2844
3009
|
transport,
|
|
2845
3010
|
validateBatch: rejectNativeBatch
|
|
2846
3011
|
});
|
|
2847
|
-
var createAvalancheClient = (transport, indexTransports) => ({
|
|
3012
|
+
var createAvalancheClient = (transport, indexTransports, nativeTransport = transport) => ({
|
|
2848
3013
|
...createEthereumClient(transport),
|
|
2849
|
-
avax: nativeNamespace(
|
|
2850
|
-
xChain: nativeNamespace(
|
|
2851
|
-
pChain: nativeNamespace(
|
|
3014
|
+
avax: nativeNamespace(nativeTransport, "avax"),
|
|
3015
|
+
xChain: nativeNamespace(nativeTransport, "avm"),
|
|
3016
|
+
pChain: nativeNamespace(nativeTransport, "platform"),
|
|
2852
3017
|
proposerVm: nativeNamespace(
|
|
2853
|
-
|
|
3018
|
+
nativeTransport,
|
|
2854
3019
|
"proposervm"
|
|
2855
3020
|
),
|
|
2856
|
-
info: nativeNamespace(
|
|
3021
|
+
info: nativeNamespace(nativeTransport, "info"),
|
|
2857
3022
|
index: {
|
|
2858
3023
|
cChainBlocks: nativeNamespace(
|
|
2859
3024
|
indexTransports.cChainBlocks,
|
|
@@ -3028,7 +3193,9 @@ var WebSocketJsonRpcTransport = class {
|
|
|
3028
3193
|
#credential;
|
|
3029
3194
|
#listeners = /* @__PURE__ */ new Set();
|
|
3030
3195
|
#pending = /* @__PURE__ */ new Map();
|
|
3196
|
+
#redactionVariants;
|
|
3031
3197
|
#timeoutMs;
|
|
3198
|
+
#unavailableNamespace;
|
|
3032
3199
|
#webSocket;
|
|
3033
3200
|
#connectPromise;
|
|
3034
3201
|
#nextId = 1;
|
|
@@ -3040,21 +3207,38 @@ var WebSocketJsonRpcTransport = class {
|
|
|
3040
3207
|
this.#connectionUrl = config.endpoint.toString();
|
|
3041
3208
|
this.endpoint = publicEndpoint(config.endpoint);
|
|
3042
3209
|
this.maxBatchSize = config.maxBatchSize ?? 256;
|
|
3210
|
+
this.#redactionVariants = directRedactionVariants(
|
|
3211
|
+
config.endpoint,
|
|
3212
|
+
config.redactionHeaders
|
|
3213
|
+
);
|
|
3043
3214
|
this.#timeoutMs = config.timeoutMs;
|
|
3215
|
+
this.#unavailableNamespace = config.unavailableNamespace;
|
|
3044
3216
|
}
|
|
3045
3217
|
async connect() {
|
|
3046
3218
|
if (this.#socket?.readyState === 1) return;
|
|
3047
3219
|
if (this.#connectPromise) return this.#connectPromise;
|
|
3220
|
+
if (this.#unavailableNamespace !== void 0) {
|
|
3221
|
+
throw new ErpcNotConfiguredError(this.#unavailableNamespace);
|
|
3222
|
+
}
|
|
3048
3223
|
if (!this.#webSocket) {
|
|
3049
3224
|
throw new ErpcConfigError(
|
|
3050
3225
|
"A WebSocket implementation is required for subscriptions"
|
|
3051
3226
|
);
|
|
3052
3227
|
}
|
|
3053
3228
|
this.#connectPromise = new Promise((resolve, reject) => {
|
|
3054
|
-
|
|
3229
|
+
let socket;
|
|
3230
|
+
try {
|
|
3231
|
+
socket = new this.#webSocket(this.#connectionUrl);
|
|
3232
|
+
} catch {
|
|
3233
|
+
reject(new ErpcTransportError("Unable to connect to ERPC WebSocket"));
|
|
3234
|
+
return;
|
|
3235
|
+
}
|
|
3055
3236
|
this.#socket = socket;
|
|
3056
3237
|
const timeout = setTimeout(() => {
|
|
3057
|
-
|
|
3238
|
+
try {
|
|
3239
|
+
socket.close();
|
|
3240
|
+
} catch {
|
|
3241
|
+
}
|
|
3058
3242
|
reject(new ErpcTimeoutError(this.#timeoutMs));
|
|
3059
3243
|
}, this.#timeoutMs);
|
|
3060
3244
|
socket.addEventListener(
|
|
@@ -3108,6 +3292,9 @@ var WebSocketJsonRpcTransport = class {
|
|
|
3108
3292
|
return promise;
|
|
3109
3293
|
}
|
|
3110
3294
|
async batch(calls, options = {}) {
|
|
3295
|
+
if (this.#unavailableNamespace !== void 0) {
|
|
3296
|
+
throw new ErpcNotConfiguredError(this.#unavailableNamespace);
|
|
3297
|
+
}
|
|
3111
3298
|
if (calls.length === 0) return [];
|
|
3112
3299
|
if (calls.length > this.maxBatchSize) {
|
|
3113
3300
|
throw new ErpcInvalidResponseError(
|
|
@@ -3214,7 +3401,11 @@ var WebSocketJsonRpcTransport = class {
|
|
|
3214
3401
|
if (isRpcError(message.error)) {
|
|
3215
3402
|
pending.reject(
|
|
3216
3403
|
new ErpcJsonRpcError(
|
|
3217
|
-
redactJsonRpcError(
|
|
3404
|
+
redactJsonRpcError(
|
|
3405
|
+
message.error,
|
|
3406
|
+
this.#credential,
|
|
3407
|
+
this.#redactionVariants
|
|
3408
|
+
)
|
|
3218
3409
|
)
|
|
3219
3410
|
);
|
|
3220
3411
|
} else if ("result" in message) pending.resolve(message.result);
|
|
@@ -3905,6 +4096,13 @@ function normalizeEvmAddress2(address) {
|
|
|
3905
4096
|
return address.toLowerCase();
|
|
3906
4097
|
}
|
|
3907
4098
|
|
|
4099
|
+
// src/generated/swap_execution_capabilities.ts
|
|
4100
|
+
var SWAP_EXECUTION_CAPABILITIES_JSON = '[{"swapExecutionCapabilityId":"swap-execution-0001","chainId":"eip155:1","dexDeploymentId":"dex-deployment-0001","poolDefinitionId":"pool-0001","factoryAddress":"0x5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f","routerAddress":"0x7a250d5630b4cf539739df2c5dacb4c659f2488d","routerKind":"uniswap-v2-router02","adapterKind":"evm-constant-product-v2","token0DeploymentId":"deployment-0008","token0Address":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","token0Standard":"erc20","token1DeploymentId":"deployment-0002","token1Address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","token1Standard":"erc20","wrappedNativeTokenDeploymentId":"deployment-0002","wrappedNativeTokenAddress":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","wrappedNativeFunctionSelector":"0xad5c4648","functionKind":"exact-input-erc20-to-erc20","functionSignature":"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)","functionSelector":"0x38ed1739","status":"active"},{"swapExecutionCapabilityId":"swap-execution-0002","chainId":"eip155:43114","dexDeploymentId":"dex-deployment-0002","poolDefinitionId":"pool-0002","factoryAddress":"0x9ad6c38be94206ca50bb0d90783181662f0cfa10","routerAddress":"0x60ae616a2155ee3d9a68541ba4544862310933d4","routerKind":"joe-v1-router02","adapterKind":"evm-constant-product-v2","token0DeploymentId":"deployment-0004","token0Address":"0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7","token0Standard":"erc20","token1DeploymentId":"deployment-0009","token1Address":"0xb97ef9ef8734c71904d8002f8b6bc66dd9c48a6e","token1Standard":"erc20","wrappedNativeTokenDeploymentId":"deployment-0004","wrappedNativeTokenAddress":"0xb31f66aa3c1e785363f0875a1b74e27b85fd66c7","wrappedNativeFunctionSelector":"0x73b295c2","functionKind":"exact-input-erc20-to-erc20","functionSignature":"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)","functionSelector":"0x38ed1739","status":"active"}]';
|
|
4101
|
+
var SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST = "84424dc48687e2cb1dd0c9a2446f820efd2c311e71ce5acacfeb6e882811875f";
|
|
4102
|
+
var SWAP_EXECUTION_CAPABILITIES_AS_OF_DATE = "2026-09-16";
|
|
4103
|
+
var SWAP_EXECUTION_FUNCTION_SIGNATURE = "swapExactTokensForTokens(uint256,uint256,address[],address,uint256)";
|
|
4104
|
+
var SWAP_EXECUTION_FUNCTION_SELECTOR = "0x38ed1739";
|
|
4105
|
+
|
|
3908
4106
|
// src/swap.ts
|
|
3909
4107
|
var SWAP_QUOTE_ERROR_MESSAGES = Object.freeze({
|
|
3910
4108
|
SWAP_INVALID_ARGUMENT: "Swap request is invalid",
|
|
@@ -3931,6 +4129,22 @@ var SwapQuoteError = class extends Error {
|
|
|
3931
4129
|
this.code = code;
|
|
3932
4130
|
}
|
|
3933
4131
|
};
|
|
4132
|
+
var SWAP_EXECUTION_ERROR_MESSAGES = Object.freeze({
|
|
4133
|
+
SWAP_EXECUTION_INVALID_ARGUMENT: "Swap execution request is invalid",
|
|
4134
|
+
SWAP_UNSUPPORTED_EXECUTION: "Swap execution is unsupported for the selected records",
|
|
4135
|
+
SWAP_PROGRAM_MISMATCH: "Swap program does not match the selected records",
|
|
4136
|
+
SWAP_INSUFFICIENT_ALLOWANCE: "Swap allowance is insufficient",
|
|
4137
|
+
SWAP_SIMULATION_REVERTED: "Swap simulation reverted",
|
|
4138
|
+
SWAP_INVALID_SIMULATION: "Swap simulation result is invalid"
|
|
4139
|
+
});
|
|
4140
|
+
var SwapExecutionError = class extends Error {
|
|
4141
|
+
code;
|
|
4142
|
+
constructor(code) {
|
|
4143
|
+
super(SWAP_EXECUTION_ERROR_MESSAGES[code]);
|
|
4144
|
+
this.name = "SwapExecutionError";
|
|
4145
|
+
this.code = code;
|
|
4146
|
+
}
|
|
4147
|
+
};
|
|
3934
4148
|
var SUPPORTED_QUOTE_ADAPTER = "evm-constant-product-v2";
|
|
3935
4149
|
var SUPPORTED_QUOTE_CAPABILITIES = Object.freeze([
|
|
3936
4150
|
Object.freeze({
|
|
@@ -4023,9 +4237,15 @@ var PAIR_FACTORY_SELECTOR = "0xc45a0155";
|
|
|
4023
4237
|
var PAIR_TOKEN0_SELECTOR = "0x0dfe1681";
|
|
4024
4238
|
var PAIR_TOKEN1_SELECTOR = "0xd21220a7";
|
|
4025
4239
|
var PAIR_GET_RESERVES_SELECTOR = "0x0902f1ac";
|
|
4240
|
+
var ROUTER_FACTORY_SELECTOR = "0xc45a0155";
|
|
4241
|
+
var ROUTER_GET_AMOUNTS_OUT_SELECTOR = "0xd06ca61f";
|
|
4242
|
+
var ERC20_ALLOWANCE_SELECTOR = "0xdd62ed3e";
|
|
4026
4243
|
function swapFail(code) {
|
|
4027
4244
|
throw new SwapQuoteError(code);
|
|
4028
4245
|
}
|
|
4246
|
+
function executionFail(code) {
|
|
4247
|
+
throw new SwapExecutionError(code);
|
|
4248
|
+
}
|
|
4029
4249
|
var isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4030
4250
|
var isKnownChain2 = (value) => value === DEX_CHAIN_IDS.ethereum || value === DEX_CHAIN_IDS.solana || value === DEX_CHAIN_IDS.avalancheC;
|
|
4031
4251
|
var isOpaqueId = (value) => /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u.test(value);
|
|
@@ -4215,6 +4435,43 @@ var uintWord = (value, maximum = UINT256_MAX) => {
|
|
|
4215
4435
|
if (parsed > maximum) swapFail("SWAP_INVALID_POOL_STATE");
|
|
4216
4436
|
return parsed;
|
|
4217
4437
|
};
|
|
4438
|
+
var parseExecutionHexBytes = (value, expectedBytes, code = "SWAP_INVALID_SIMULATION") => {
|
|
4439
|
+
if (typeof value !== "string") executionFail(code);
|
|
4440
|
+
if (!HEX_BYTES.test(value) || value.length % 2 !== 0 || expectedBytes !== void 0 && value.length !== expectedBytes * 2 + 2) {
|
|
4441
|
+
executionFail(code);
|
|
4442
|
+
}
|
|
4443
|
+
return value.toLowerCase();
|
|
4444
|
+
};
|
|
4445
|
+
var executionAddressWord = (value, code = "SWAP_INVALID_SIMULATION") => {
|
|
4446
|
+
const bytes = parseExecutionHexBytes(value, 32, code);
|
|
4447
|
+
const word = bytes.slice(2);
|
|
4448
|
+
if (!/^0{24}[0-9a-f]{40}$/u.test(word)) executionFail(code);
|
|
4449
|
+
return `0x${word.slice(24)}`;
|
|
4450
|
+
};
|
|
4451
|
+
var executionUintWord = (value, code = "SWAP_INVALID_SIMULATION") => {
|
|
4452
|
+
const bytes = parseExecutionHexBytes(value, 32, code);
|
|
4453
|
+
try {
|
|
4454
|
+
return BigInt(`0x${bytes.slice(2)}`);
|
|
4455
|
+
} catch {
|
|
4456
|
+
executionFail(code);
|
|
4457
|
+
}
|
|
4458
|
+
};
|
|
4459
|
+
var executionUintArrayOfTwo = (value) => {
|
|
4460
|
+
const bytes = parseExecutionHexBytes(value);
|
|
4461
|
+
const payload = bytes.slice(2);
|
|
4462
|
+
if (payload.length % 64 !== 0 || payload.length < 256) {
|
|
4463
|
+
executionFail("SWAP_INVALID_SIMULATION");
|
|
4464
|
+
}
|
|
4465
|
+
const offset = BigInt(`0x${payload.slice(0, 64)}`);
|
|
4466
|
+
const length = BigInt(`0x${payload.slice(64, 128)}`);
|
|
4467
|
+
if (offset !== 0x20n || length !== 2n || payload.length !== 256) {
|
|
4468
|
+
executionFail("SWAP_INVALID_SIMULATION");
|
|
4469
|
+
}
|
|
4470
|
+
return [
|
|
4471
|
+
executionUintWord(`0x${payload.slice(128, 192)}`),
|
|
4472
|
+
executionUintWord(`0x${payload.slice(192, 256)}`)
|
|
4473
|
+
];
|
|
4474
|
+
};
|
|
4218
4475
|
var reserveWords = (value) => {
|
|
4219
4476
|
const bytes = parseHexBytes(value, 96);
|
|
4220
4477
|
const payload = bytes.slice(2);
|
|
@@ -4260,8 +4517,101 @@ var currentClockSeconds = (clock) => {
|
|
|
4260
4517
|
if (!Number.isSafeInteger(value)) swapFail("SWAP_INVALID_ARGUMENT");
|
|
4261
4518
|
return value;
|
|
4262
4519
|
};
|
|
4263
|
-
var
|
|
4264
|
-
|
|
4520
|
+
var EXECUTION_REQUEST_KEYS = /* @__PURE__ */ new Set([
|
|
4521
|
+
"chainId",
|
|
4522
|
+
"poolDefinitionId",
|
|
4523
|
+
"inputTokenDeploymentId",
|
|
4524
|
+
"outputTokenDeploymentId",
|
|
4525
|
+
"amountIn",
|
|
4526
|
+
"freshness",
|
|
4527
|
+
"sender",
|
|
4528
|
+
"recipient",
|
|
4529
|
+
"slippageBps",
|
|
4530
|
+
"deadline"
|
|
4531
|
+
]);
|
|
4532
|
+
var snapshotExecutionRequest = (request) => {
|
|
4533
|
+
if (!isRecord3(request)) executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4534
|
+
if (Object.keys(request).some((key) => !EXECUTION_REQUEST_KEYS.has(key))) {
|
|
4535
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4536
|
+
}
|
|
4537
|
+
const freshness = request.freshness;
|
|
4538
|
+
const freshnessSnapshot = isRecord3(freshness) ? { ...freshness } : freshness;
|
|
4539
|
+
const quoteRequest = {
|
|
4540
|
+
chainId: request.chainId,
|
|
4541
|
+
poolDefinitionId: request.poolDefinitionId,
|
|
4542
|
+
inputTokenDeploymentId: request.inputTokenDeploymentId,
|
|
4543
|
+
outputTokenDeploymentId: request.outputTokenDeploymentId,
|
|
4544
|
+
amountIn: request.amountIn,
|
|
4545
|
+
...freshnessSnapshot === void 0 ? {} : { freshness: freshnessSnapshot }
|
|
4546
|
+
};
|
|
4547
|
+
return {
|
|
4548
|
+
quoteRequest,
|
|
4549
|
+
sender: request.sender,
|
|
4550
|
+
recipient: request.recipient,
|
|
4551
|
+
slippageBps: request.slippageBps,
|
|
4552
|
+
deadline: request.deadline
|
|
4553
|
+
};
|
|
4554
|
+
};
|
|
4555
|
+
var normalizeExecutionAddress = (value) => {
|
|
4556
|
+
if (typeof value !== "string" || !/^0x[0-9a-fA-F]{40}$/u.test(value)) {
|
|
4557
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4558
|
+
}
|
|
4559
|
+
const normalized = value.toLowerCase();
|
|
4560
|
+
if (normalized === `0x${"0".repeat(40)}`) {
|
|
4561
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4562
|
+
}
|
|
4563
|
+
return normalized;
|
|
4564
|
+
};
|
|
4565
|
+
var normalizeExecutionSlippage = (value) => {
|
|
4566
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 9999) {
|
|
4567
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4568
|
+
}
|
|
4569
|
+
return value;
|
|
4570
|
+
};
|
|
4571
|
+
var parseExecutionDeadline = (value) => {
|
|
4572
|
+
if (typeof value !== "string" || !UINT256_DECIMAL.test(value) || value.length > 78) {
|
|
4573
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4574
|
+
}
|
|
4575
|
+
let parsed;
|
|
4576
|
+
try {
|
|
4577
|
+
parsed = BigInt(value);
|
|
4578
|
+
} catch {
|
|
4579
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4580
|
+
}
|
|
4581
|
+
if (parsed <= 0n || parsed > UINT256_MAX) {
|
|
4582
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4583
|
+
}
|
|
4584
|
+
return { source: value, value: parsed };
|
|
4585
|
+
};
|
|
4586
|
+
var normalizeExecutionRequest = (request, clock) => {
|
|
4587
|
+
const snapshot = snapshotExecutionRequest(request);
|
|
4588
|
+
const sender = normalizeExecutionAddress(snapshot.sender);
|
|
4589
|
+
const recipient = normalizeExecutionAddress(snapshot.recipient);
|
|
4590
|
+
const slippageBps = normalizeExecutionSlippage(snapshot.slippageBps);
|
|
4591
|
+
const deadline = parseExecutionDeadline(snapshot.deadline);
|
|
4592
|
+
const initialClock = BigInt(currentClockSeconds(clock));
|
|
4593
|
+
if (deadline.value <= initialClock) {
|
|
4594
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4595
|
+
}
|
|
4596
|
+
let normalized;
|
|
4597
|
+
try {
|
|
4598
|
+
normalized = normalizeQuoteRequest(snapshot.quoteRequest);
|
|
4599
|
+
} catch (error) {
|
|
4600
|
+
if (error instanceof SwapQuoteError && (error.code === "SWAP_UNKNOWN_POOL" || error.code === "SWAP_UNSUPPORTED_ADAPTER" || error.code === "SWAP_UNSUPPORTED_TOKEN" || error.code === "SWAP_UNSUPPORTED_TOKEN_STANDARD")) {
|
|
4601
|
+
executionFail("SWAP_UNSUPPORTED_EXECUTION");
|
|
4602
|
+
}
|
|
4603
|
+
throw error;
|
|
4604
|
+
}
|
|
4605
|
+
return {
|
|
4606
|
+
normalized,
|
|
4607
|
+
sender,
|
|
4608
|
+
recipient,
|
|
4609
|
+
slippageBps,
|
|
4610
|
+
deadline: deadline.source,
|
|
4611
|
+
deadlineValue: deadline.value
|
|
4612
|
+
};
|
|
4613
|
+
};
|
|
4614
|
+
var assertFreshnessAtNow = (state, freshness, now) => {
|
|
4265
4615
|
const initialAge = now - state.initial.timestamp;
|
|
4266
4616
|
if (initialAge < -BigInt(freshness.maxClockSkewSeconds) || initialAge > BigInt(freshness.maxBlockAgeSeconds)) {
|
|
4267
4617
|
swapFail("SWAP_STATE_STALE");
|
|
@@ -4283,6 +4633,54 @@ var assertFreshness = (state, freshness, clock) => {
|
|
|
4283
4633
|
swapFail("SWAP_STATE_STALE");
|
|
4284
4634
|
}
|
|
4285
4635
|
};
|
|
4636
|
+
var assertFreshness = (state, freshness, clock) => {
|
|
4637
|
+
assertFreshnessAtNow(
|
|
4638
|
+
state,
|
|
4639
|
+
freshness,
|
|
4640
|
+
BigInt(currentClockSeconds(clock))
|
|
4641
|
+
);
|
|
4642
|
+
};
|
|
4643
|
+
var executionCapabilityFor = (normalized) => {
|
|
4644
|
+
const capability = EXECUTION_CAPABILITIES.find(
|
|
4645
|
+
(entry) => entry.poolDefinitionId === normalized.pool.poolDefinitionId
|
|
4646
|
+
);
|
|
4647
|
+
if (!capability || capability.status !== "active") {
|
|
4648
|
+
executionFail("SWAP_UNSUPPORTED_EXECUTION");
|
|
4649
|
+
}
|
|
4650
|
+
const token0 = getTokenDeployment(capability.token0DeploymentId);
|
|
4651
|
+
const token1 = getTokenDeployment(capability.token1DeploymentId);
|
|
4652
|
+
const wrapped = getTokenDeployment(capability.wrappedNativeTokenDeploymentId);
|
|
4653
|
+
const nativeWrap = NATIVE_WRAP_DEFINITIONS.find(
|
|
4654
|
+
(entry) => entry.chainId === capability.chainId && entry.wrappedTokenDeploymentId === capability.wrappedNativeTokenDeploymentId
|
|
4655
|
+
);
|
|
4656
|
+
const matchesCapabilityToken = (token, deploymentId, address, standard) => token?.deploymentId === deploymentId && token.chainId === capability.chainId && token.address === address && token.standard === standard && token.status === "active";
|
|
4657
|
+
const inputMatches = matchesCapabilityToken(
|
|
4658
|
+
normalized.input,
|
|
4659
|
+
capability.token0DeploymentId,
|
|
4660
|
+
capability.token0Address,
|
|
4661
|
+
capability.token0Standard
|
|
4662
|
+
) || matchesCapabilityToken(
|
|
4663
|
+
normalized.input,
|
|
4664
|
+
capability.token1DeploymentId,
|
|
4665
|
+
capability.token1Address,
|
|
4666
|
+
capability.token1Standard
|
|
4667
|
+
);
|
|
4668
|
+
const outputMatches = matchesCapabilityToken(
|
|
4669
|
+
normalized.output,
|
|
4670
|
+
capability.token0DeploymentId,
|
|
4671
|
+
capability.token0Address,
|
|
4672
|
+
capability.token0Standard
|
|
4673
|
+
) || matchesCapabilityToken(
|
|
4674
|
+
normalized.output,
|
|
4675
|
+
capability.token1DeploymentId,
|
|
4676
|
+
capability.token1Address,
|
|
4677
|
+
capability.token1Standard
|
|
4678
|
+
);
|
|
4679
|
+
if (capability.chainId !== normalized.pool.chainId || capability.dexDeploymentId !== normalized.pool.dexDeploymentId || capability.adapterKind !== SUPPORTED_QUOTE_ADAPTER || capability.functionKind !== "exact-input-erc20-to-erc20" || capability.functionSignature !== SWAP_EXECUTION_FUNCTION_SIGNATURE || capability.functionSelector !== SWAP_EXECUTION_FUNCTION_SELECTOR || normalized.dex.status !== "active" || normalized.dex.programAddress !== capability.factoryAddress || normalized.dex.adapterKind !== capability.adapterKind || normalized.pool.status !== "active" || normalized.pool.adapter.kind !== capability.adapterKind || normalized.pool.adapter.feeNumerator !== "3" || normalized.pool.adapter.feeDenominator !== "1000" || normalized.pool.token0DeploymentId !== capability.token0DeploymentId || normalized.pool.token1DeploymentId !== capability.token1DeploymentId || !inputMatches || !outputMatches || !token0 || !token1 || !wrapped || wrapped.chainId !== capability.chainId || wrapped.address !== capability.wrappedNativeTokenAddress || wrapped.standard !== "erc20" || wrapped.status !== "active" || !nativeWrap || nativeWrap.status !== "active" || nativeWrap.wrappedTokenDeploymentId !== capability.wrappedNativeTokenDeploymentId) {
|
|
4680
|
+
executionFail("SWAP_UNSUPPORTED_EXECUTION");
|
|
4681
|
+
}
|
|
4682
|
+
return capability;
|
|
4683
|
+
};
|
|
4286
4684
|
var readEvmState = async (transport, normalized, clock, options) => {
|
|
4287
4685
|
const { pool, dex } = normalized;
|
|
4288
4686
|
const chainId = await rpcRequest(transport, "eth_chainId", [], options);
|
|
@@ -4415,14 +4813,269 @@ var quoteResult = (normalized, state, result) => {
|
|
|
4415
4813
|
};
|
|
4416
4814
|
return deepFreeze5(output);
|
|
4417
4815
|
};
|
|
4816
|
+
var transportForNormalized = (normalized, options) => {
|
|
4817
|
+
const transport = normalized.pool.chainId === DEX_CHAIN_IDS.ethereum ? options.ethereum : normalized.pool.chainId === DEX_CHAIN_IDS.avalancheC ? options.avalanche : void 0;
|
|
4818
|
+
if (!transport) swapFail("SWAP_UNSUPPORTED_ADAPTER");
|
|
4819
|
+
return transport;
|
|
4820
|
+
};
|
|
4821
|
+
var encodeUint256Word = (value) => ensureUint256(value).toString(16).padStart(64, "0");
|
|
4822
|
+
var executionTokenAddress = (token) => {
|
|
4823
|
+
if (typeof token.address !== "string" || !EVM_ADDRESS.test(token.address)) {
|
|
4824
|
+
executionFail("SWAP_INVALID_SIMULATION");
|
|
4825
|
+
}
|
|
4826
|
+
return token.address.toLowerCase();
|
|
4827
|
+
};
|
|
4828
|
+
var executionGetAmountsOutData = (amountIn, inputAddress, outputAddress) => `${ROUTER_GET_AMOUNTS_OUT_SELECTOR}${encodeUint256Word(amountIn)}${encodeUint256Word(
|
|
4829
|
+
0x40n
|
|
4830
|
+
)}${encodeUint256Word(2n)}${encodeAddressArgument(
|
|
4831
|
+
inputAddress
|
|
4832
|
+
)}${encodeAddressArgument(outputAddress)}`;
|
|
4833
|
+
var executionSwapData = (amountIn, minimumAmountOut, inputAddress, outputAddress, recipient, deadline) => `${SWAP_EXECUTION_FUNCTION_SELECTOR}${encodeUint256Word(
|
|
4834
|
+
amountIn
|
|
4835
|
+
)}${encodeUint256Word(minimumAmountOut)}${encodeUint256Word(
|
|
4836
|
+
0xa0n
|
|
4837
|
+
)}${encodeAddressArgument(recipient)}${encodeUint256Word(
|
|
4838
|
+
deadline
|
|
4839
|
+
)}${encodeUint256Word(2n)}${encodeAddressArgument(
|
|
4840
|
+
inputAddress
|
|
4841
|
+
)}${encodeAddressArgument(outputAddress)}`;
|
|
4842
|
+
var buildExecutionPreparation = (execution, capability, quote) => {
|
|
4843
|
+
const inputAddress = executionTokenAddress(execution.normalized.input);
|
|
4844
|
+
const outputAddress = executionTokenAddress(execution.normalized.output);
|
|
4845
|
+
const quoteAmountOut = parseDecimalQuantity(quote.amountOut, "SWAP_ARITHMETIC");
|
|
4846
|
+
const minimumAmountOut = ensureUint256(
|
|
4847
|
+
quoteAmountOut * BigInt(1e4 - execution.slippageBps),
|
|
4848
|
+
"SWAP_ARITHMETIC"
|
|
4849
|
+
) / 10000n;
|
|
4850
|
+
if (minimumAmountOut <= 0n) {
|
|
4851
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4852
|
+
}
|
|
4853
|
+
const path = [
|
|
4854
|
+
{
|
|
4855
|
+
tokenDeploymentId: execution.normalized.input.deploymentId,
|
|
4856
|
+
address: inputAddress,
|
|
4857
|
+
standard: "erc20",
|
|
4858
|
+
representationKind: execution.normalized.input.representationKind
|
|
4859
|
+
},
|
|
4860
|
+
{
|
|
4861
|
+
tokenDeploymentId: execution.normalized.output.deploymentId,
|
|
4862
|
+
address: outputAddress,
|
|
4863
|
+
standard: "erc20",
|
|
4864
|
+
representationKind: execution.normalized.output.representationKind
|
|
4865
|
+
}
|
|
4866
|
+
];
|
|
4867
|
+
const transaction = {
|
|
4868
|
+
kind: "evm-unsigned-transaction",
|
|
4869
|
+
chainId: quote.chainId,
|
|
4870
|
+
from: execution.sender,
|
|
4871
|
+
to: capability.routerAddress,
|
|
4872
|
+
data: executionSwapData(
|
|
4873
|
+
execution.normalized.amountIn,
|
|
4874
|
+
minimumAmountOut,
|
|
4875
|
+
inputAddress,
|
|
4876
|
+
outputAddress,
|
|
4877
|
+
execution.recipient,
|
|
4878
|
+
execution.deadlineValue
|
|
4879
|
+
),
|
|
4880
|
+
value: "0"
|
|
4881
|
+
};
|
|
4882
|
+
return deepFreeze5({
|
|
4883
|
+
preparationKind: "evm-router-v2-exact-input",
|
|
4884
|
+
executionCapabilityId: capability.swapExecutionCapabilityId,
|
|
4885
|
+
executionCapabilityDigest: SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST,
|
|
4886
|
+
quote,
|
|
4887
|
+
minimumAmountOut: minimumAmountOut.toString(10),
|
|
4888
|
+
slippageBps: execution.slippageBps,
|
|
4889
|
+
deadline: execution.deadline,
|
|
4890
|
+
recipient: execution.recipient,
|
|
4891
|
+
path,
|
|
4892
|
+
transaction,
|
|
4893
|
+
allowance: {
|
|
4894
|
+
tokenDeploymentId: execution.normalized.input.deploymentId,
|
|
4895
|
+
tokenAddress: inputAddress,
|
|
4896
|
+
owner: execution.sender,
|
|
4897
|
+
spender: capability.routerAddress,
|
|
4898
|
+
requiredAmount: quote.amountIn
|
|
4899
|
+
}
|
|
4900
|
+
});
|
|
4901
|
+
};
|
|
4902
|
+
var assertExecutionDeadline = (execution, quoteTimestamp, completionClock) => {
|
|
4903
|
+
if (execution.deadlineValue <= quoteTimestamp || execution.deadlineValue <= completionClock) {
|
|
4904
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4905
|
+
}
|
|
4906
|
+
};
|
|
4907
|
+
var prepareExecutionContext = async (execution, capability, transport, options, requestOptions) => {
|
|
4908
|
+
const state = await readEvmState(
|
|
4909
|
+
transport,
|
|
4910
|
+
execution.normalized,
|
|
4911
|
+
options.clock,
|
|
4912
|
+
requestOptions
|
|
4913
|
+
);
|
|
4914
|
+
assertFreshness(state, execution.normalized.freshness, options.clock);
|
|
4915
|
+
const quote = quoteResult(
|
|
4916
|
+
execution.normalized,
|
|
4917
|
+
state,
|
|
4918
|
+
calculateQuote(execution.normalized, state)
|
|
4919
|
+
);
|
|
4920
|
+
if (execution.deadlineValue <= state.initial.timestamp) {
|
|
4921
|
+
executionFail("SWAP_EXECUTION_INVALID_ARGUMENT");
|
|
4922
|
+
}
|
|
4923
|
+
const inputAddress = executionTokenAddress(execution.normalized.input);
|
|
4924
|
+
const outputAddress = executionTokenAddress(execution.normalized.output);
|
|
4925
|
+
const selector = rpcSelector(state.initial.hash);
|
|
4926
|
+
const routerCodeRaw = await rpcRequest(transport, "eth_getCode", [
|
|
4927
|
+
capability.routerAddress,
|
|
4928
|
+
selector
|
|
4929
|
+
], requestOptions);
|
|
4930
|
+
const routerCode = parseExecutionHexBytes(routerCodeRaw);
|
|
4931
|
+
if (routerCode.length <= 2) executionFail("SWAP_INVALID_SIMULATION");
|
|
4932
|
+
const routerFactoryRaw = await rpcRequest(transport, "eth_call", [
|
|
4933
|
+
abiCall(capability.routerAddress, ROUTER_FACTORY_SELECTOR),
|
|
4934
|
+
selector
|
|
4935
|
+
], requestOptions);
|
|
4936
|
+
const routerFactory = executionAddressWord(routerFactoryRaw);
|
|
4937
|
+
if (routerFactory !== capability.factoryAddress) {
|
|
4938
|
+
executionFail("SWAP_PROGRAM_MISMATCH");
|
|
4939
|
+
}
|
|
4940
|
+
const wrappedNativeRaw = await rpcRequest(transport, "eth_call", [
|
|
4941
|
+
abiCall(capability.routerAddress, capability.wrappedNativeFunctionSelector),
|
|
4942
|
+
selector
|
|
4943
|
+
], requestOptions);
|
|
4944
|
+
const wrappedNative = executionAddressWord(wrappedNativeRaw);
|
|
4945
|
+
if (wrappedNative !== capability.wrappedNativeTokenAddress) {
|
|
4946
|
+
executionFail("SWAP_PROGRAM_MISMATCH");
|
|
4947
|
+
}
|
|
4948
|
+
const amountsOutRaw = await rpcRequest(transport, "eth_call", [
|
|
4949
|
+
abiCall(
|
|
4950
|
+
capability.routerAddress,
|
|
4951
|
+
executionGetAmountsOutData(
|
|
4952
|
+
execution.normalized.amountIn,
|
|
4953
|
+
inputAddress,
|
|
4954
|
+
outputAddress
|
|
4955
|
+
)
|
|
4956
|
+
),
|
|
4957
|
+
selector
|
|
4958
|
+
], requestOptions);
|
|
4959
|
+
const amountsOut = executionUintArrayOfTwo(amountsOutRaw);
|
|
4960
|
+
const quoteAmountOut = parseDecimalQuantity(quote.amountOut, "SWAP_ARITHMETIC");
|
|
4961
|
+
if (amountsOut[0] !== execution.normalized.amountIn || amountsOut[1] !== quoteAmountOut) {
|
|
4962
|
+
executionFail("SWAP_INVALID_SIMULATION");
|
|
4963
|
+
}
|
|
4964
|
+
const latestAfterRouterReads = blockHeader(
|
|
4965
|
+
await rpcRequest(
|
|
4966
|
+
transport,
|
|
4967
|
+
"eth_getBlockByNumber",
|
|
4968
|
+
["latest", false],
|
|
4969
|
+
requestOptions
|
|
4970
|
+
)
|
|
4971
|
+
);
|
|
4972
|
+
const completionClock = BigInt(currentClockSeconds(options.clock));
|
|
4973
|
+
assertFreshnessAtNow(
|
|
4974
|
+
{
|
|
4975
|
+
initial: state.initial,
|
|
4976
|
+
latestAfterReads: latestAfterRouterReads
|
|
4977
|
+
},
|
|
4978
|
+
execution.normalized.freshness,
|
|
4979
|
+
completionClock
|
|
4980
|
+
);
|
|
4981
|
+
const preparation = buildExecutionPreparation(execution, capability, quote);
|
|
4982
|
+
assertExecutionDeadline(
|
|
4983
|
+
execution,
|
|
4984
|
+
state.initial.timestamp,
|
|
4985
|
+
BigInt(currentClockSeconds(options.clock))
|
|
4986
|
+
);
|
|
4987
|
+
return { normalized: execution, capability, transport, state, quote, preparation };
|
|
4988
|
+
};
|
|
4989
|
+
var isRecognizedExecutionRevert = (error) => {
|
|
4990
|
+
if (!(error instanceof ErpcJsonRpcError)) return false;
|
|
4991
|
+
if (![3, -32e3, -32015, -32603].includes(error.rpcCode)) return false;
|
|
4992
|
+
const message = error.message.toLowerCase();
|
|
4993
|
+
return message.includes("execution reverted") || message.includes("transaction reverted") || message.includes("vm execution error") || /^revert(?:ed)?(?:\b|:)/u.test(message);
|
|
4994
|
+
};
|
|
4995
|
+
var simulateExecutionContext = async (context, options, requestOptions) => {
|
|
4996
|
+
const { normalized, capability, transport, state, preparation } = context;
|
|
4997
|
+
const selector = rpcSelector(state.initial.hash);
|
|
4998
|
+
const inputAddress = preparation.allowance.tokenAddress;
|
|
4999
|
+
const allowanceData = `${ERC20_ALLOWANCE_SELECTOR}${encodeAddressArgument(
|
|
5000
|
+
normalized.sender
|
|
5001
|
+
)}${encodeAddressArgument(capability.routerAddress)}`;
|
|
5002
|
+
const allowanceRaw = await rpcRequest(transport, "eth_call", [
|
|
5003
|
+
abiCall(inputAddress, allowanceData),
|
|
5004
|
+
selector
|
|
5005
|
+
], requestOptions);
|
|
5006
|
+
const currentAllowance = executionUintWord(
|
|
5007
|
+
allowanceRaw,
|
|
5008
|
+
"SWAP_INSUFFICIENT_ALLOWANCE"
|
|
5009
|
+
);
|
|
5010
|
+
if (currentAllowance < normalized.normalized.amountIn) {
|
|
5011
|
+
executionFail("SWAP_INSUFFICIENT_ALLOWANCE");
|
|
5012
|
+
}
|
|
5013
|
+
let simulationRaw;
|
|
5014
|
+
try {
|
|
5015
|
+
simulationRaw = await rpcRequest(transport, "eth_call", [
|
|
5016
|
+
{
|
|
5017
|
+
from: preparation.transaction.from,
|
|
5018
|
+
to: preparation.transaction.to,
|
|
5019
|
+
data: preparation.transaction.data,
|
|
5020
|
+
value: "0x0"
|
|
5021
|
+
},
|
|
5022
|
+
selector
|
|
5023
|
+
], requestOptions);
|
|
5024
|
+
} catch (error) {
|
|
5025
|
+
if (isRecognizedExecutionRevert(error)) {
|
|
5026
|
+
executionFail("SWAP_SIMULATION_REVERTED");
|
|
5027
|
+
}
|
|
5028
|
+
throw error;
|
|
5029
|
+
}
|
|
5030
|
+
const latestAfterSimulation = blockHeader(
|
|
5031
|
+
await rpcRequest(
|
|
5032
|
+
transport,
|
|
5033
|
+
"eth_getBlockByNumber",
|
|
5034
|
+
["latest", false],
|
|
5035
|
+
requestOptions
|
|
5036
|
+
)
|
|
5037
|
+
);
|
|
5038
|
+
const completionClock = BigInt(currentClockSeconds(options.clock));
|
|
5039
|
+
assertFreshnessAtNow(
|
|
5040
|
+
{ initial: state.initial, latestAfterReads: latestAfterSimulation },
|
|
5041
|
+
normalized.normalized.freshness,
|
|
5042
|
+
completionClock
|
|
5043
|
+
);
|
|
5044
|
+
const amounts = executionUintArrayOfTwo(simulationRaw);
|
|
5045
|
+
const quoteAmountOut = parseDecimalQuantity(
|
|
5046
|
+
preparation.quote.amountOut,
|
|
5047
|
+
"SWAP_ARITHMETIC"
|
|
5048
|
+
);
|
|
5049
|
+
const minimumAmountOut = parseDecimalQuantity(
|
|
5050
|
+
preparation.minimumAmountOut,
|
|
5051
|
+
"SWAP_ARITHMETIC"
|
|
5052
|
+
);
|
|
5053
|
+
if (amounts[0] !== normalized.normalized.amountIn || amounts[1] !== quoteAmountOut || amounts[1] < minimumAmountOut) {
|
|
5054
|
+
executionFail("SWAP_INVALID_SIMULATION");
|
|
5055
|
+
}
|
|
5056
|
+
assertExecutionDeadline(
|
|
5057
|
+
normalized,
|
|
5058
|
+
state.initial.timestamp,
|
|
5059
|
+
BigInt(currentClockSeconds(options.clock))
|
|
5060
|
+
);
|
|
5061
|
+
return deepFreeze5({
|
|
5062
|
+
simulationKind: "evm-call",
|
|
5063
|
+
preparation,
|
|
5064
|
+
snapshot: preparation.quote.snapshot,
|
|
5065
|
+
currentAllowance: currentAllowance.toString(10),
|
|
5066
|
+
amounts: [
|
|
5067
|
+
amounts[0].toString(10),
|
|
5068
|
+
amounts[1].toString(10)
|
|
5069
|
+
],
|
|
5070
|
+
amountOut: amounts[1].toString(10)
|
|
5071
|
+
});
|
|
5072
|
+
};
|
|
4418
5073
|
var quoteExactInputWithTransports = async (request, options, requestOptions) => {
|
|
4419
5074
|
const normalized = normalizeQuoteRequest(request);
|
|
4420
5075
|
if (normalized.pool.adapter.kind !== SUPPORTED_QUOTE_ADAPTER) {
|
|
4421
5076
|
swapFail("SWAP_UNSUPPORTED_ADAPTER");
|
|
4422
5077
|
}
|
|
4423
|
-
const
|
|
4424
|
-
if (!transport) swapFail("SWAP_UNSUPPORTED_ADAPTER");
|
|
4425
|
-
const selectedTransport = transport;
|
|
5078
|
+
const selectedTransport = transportForNormalized(normalized, options);
|
|
4426
5079
|
const state = await readEvmState(
|
|
4427
5080
|
selectedTransport,
|
|
4428
5081
|
normalized,
|
|
@@ -4432,6 +5085,32 @@ var quoteExactInputWithTransports = async (request, options, requestOptions) =>
|
|
|
4432
5085
|
assertFreshness(state, normalized.freshness, options.clock);
|
|
4433
5086
|
return quoteResult(normalized, state, calculateQuote(normalized, state));
|
|
4434
5087
|
};
|
|
5088
|
+
var prepareExactInputSwapWithTransports = async (request, options, requestOptions) => {
|
|
5089
|
+
const normalized = normalizeExecutionRequest(request, options.clock);
|
|
5090
|
+
const capability = executionCapabilityFor(normalized.normalized);
|
|
5091
|
+
const transport = transportForNormalized(normalized.normalized, options);
|
|
5092
|
+
const context = await prepareExecutionContext(
|
|
5093
|
+
normalized,
|
|
5094
|
+
capability,
|
|
5095
|
+
transport,
|
|
5096
|
+
options,
|
|
5097
|
+
requestOptions
|
|
5098
|
+
);
|
|
5099
|
+
return context.preparation;
|
|
5100
|
+
};
|
|
5101
|
+
var simulateExactInputSwapWithTransports = async (request, options, requestOptions) => {
|
|
5102
|
+
const normalized = normalizeExecutionRequest(request, options.clock);
|
|
5103
|
+
const capability = executionCapabilityFor(normalized.normalized);
|
|
5104
|
+
const transport = transportForNormalized(normalized.normalized, options);
|
|
5105
|
+
const context = await prepareExecutionContext(
|
|
5106
|
+
normalized,
|
|
5107
|
+
capability,
|
|
5108
|
+
transport,
|
|
5109
|
+
options,
|
|
5110
|
+
requestOptions
|
|
5111
|
+
);
|
|
5112
|
+
return simulateExecutionContext(context, options, requestOptions);
|
|
5113
|
+
};
|
|
4435
5114
|
var deepFreeze5 = (value) => {
|
|
4436
5115
|
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
4437
5116
|
Object.freeze(value);
|
|
@@ -4441,8 +5120,13 @@ var deepFreeze5 = (value) => {
|
|
|
4441
5120
|
}
|
|
4442
5121
|
return value;
|
|
4443
5122
|
};
|
|
5123
|
+
var EXECUTION_CAPABILITIES = deepFreeze5(
|
|
5124
|
+
JSON.parse(SWAP_EXECUTION_CAPABILITIES_JSON)
|
|
5125
|
+
);
|
|
4444
5126
|
var createSwapClient = (options) => Object.freeze({
|
|
4445
|
-
quoteExactInput: (request, requestOptions) => quoteExactInputWithTransports(request, options, requestOptions)
|
|
5127
|
+
quoteExactInput: (request, requestOptions) => quoteExactInputWithTransports(request, options, requestOptions),
|
|
5128
|
+
prepareExactInputSwap: (request, requestOptions) => prepareExactInputSwapWithTransports(request, options, requestOptions),
|
|
5129
|
+
simulateExactInputSwap: (request, requestOptions) => simulateExactInputSwapWithTransports(request, options, requestOptions)
|
|
4446
5130
|
});
|
|
4447
5131
|
|
|
4448
5132
|
// src/transport/http.ts
|
|
@@ -4474,19 +5158,45 @@ var parseJson = (text) => {
|
|
|
4474
5158
|
throw new ErpcInvalidResponseError("ERPC returned malformed JSON");
|
|
4475
5159
|
}
|
|
4476
5160
|
};
|
|
5161
|
+
var directRequestHeaders = (headers) => {
|
|
5162
|
+
try {
|
|
5163
|
+
const result = new Headers(headers);
|
|
5164
|
+
result.set("accept", "application/json");
|
|
5165
|
+
result.set("content-type", "application/json");
|
|
5166
|
+
return result;
|
|
5167
|
+
} catch {
|
|
5168
|
+
const result = {};
|
|
5169
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
5170
|
+
const lowerName = name.toLowerCase();
|
|
5171
|
+
if (lowerName === "accept" || lowerName === "content-type") continue;
|
|
5172
|
+
result[name] = value;
|
|
5173
|
+
}
|
|
5174
|
+
result.accept = "application/json";
|
|
5175
|
+
result["content-type"] = "application/json";
|
|
5176
|
+
return result;
|
|
5177
|
+
}
|
|
5178
|
+
};
|
|
4477
5179
|
var HttpJsonRpcTransport = class {
|
|
4478
5180
|
endpoint;
|
|
4479
5181
|
maxBatchSize;
|
|
4480
5182
|
#apiKey;
|
|
5183
|
+
#direct;
|
|
5184
|
+
#requestEndpoint;
|
|
4481
5185
|
#fetch;
|
|
4482
5186
|
#headers;
|
|
5187
|
+
#redactionVariants;
|
|
4483
5188
|
#timeoutMs;
|
|
5189
|
+
#unavailableNamespace;
|
|
4484
5190
|
#nextId = 1;
|
|
4485
5191
|
constructor(config) {
|
|
4486
|
-
this.#apiKey = config.apiKey;
|
|
5192
|
+
this.#apiKey = config.apiKey ?? "";
|
|
5193
|
+
this.#direct = config.direct ?? false;
|
|
5194
|
+
this.#requestEndpoint = new URL(config.endpoint);
|
|
4487
5195
|
this.#fetch = config.fetch;
|
|
4488
5196
|
this.#headers = config.headers;
|
|
5197
|
+
this.#redactionVariants = this.#direct ? directRedactionVariants(this.#requestEndpoint, this.#headers) : [];
|
|
4489
5198
|
this.#timeoutMs = config.timeoutMs;
|
|
5199
|
+
this.#unavailableNamespace = config.unavailableNamespace;
|
|
4490
5200
|
this.maxBatchSize = config.maxBatchSize ?? 256;
|
|
4491
5201
|
const endpoint = new URL(config.endpoint);
|
|
4492
5202
|
endpoint.search = "";
|
|
@@ -4494,12 +5204,14 @@ var HttpJsonRpcTransport = class {
|
|
|
4494
5204
|
this.endpoint = endpoint.toString();
|
|
4495
5205
|
}
|
|
4496
5206
|
async request(method, params, options = {}) {
|
|
5207
|
+
this.#ensureConfigured();
|
|
4497
5208
|
const id = this.#id();
|
|
4498
5209
|
const request = this.#request(id, method, params);
|
|
4499
5210
|
const response = await this.#post(request, options);
|
|
4500
5211
|
return this.#unwrap(response, id);
|
|
4501
5212
|
}
|
|
4502
5213
|
async batch(calls, options = {}) {
|
|
5214
|
+
this.#ensureConfigured();
|
|
4503
5215
|
if (calls.length === 0) return [];
|
|
4504
5216
|
if (calls.length > this.maxBatchSize) {
|
|
4505
5217
|
throw new ErpcInvalidResponseError(
|
|
@@ -4513,7 +5225,13 @@ var HttpJsonRpcTransport = class {
|
|
|
4513
5225
|
const raw = await this.#post(requests, options);
|
|
4514
5226
|
if (!Array.isArray(raw)) {
|
|
4515
5227
|
if (isFailure(raw)) {
|
|
4516
|
-
throw new ErpcJsonRpcError(
|
|
5228
|
+
throw new ErpcJsonRpcError(
|
|
5229
|
+
redactJsonRpcError(
|
|
5230
|
+
raw.error,
|
|
5231
|
+
this.#direct ? void 0 : this.#apiKey,
|
|
5232
|
+
this.#redactionVariants
|
|
5233
|
+
)
|
|
5234
|
+
);
|
|
4517
5235
|
}
|
|
4518
5236
|
throw new ErpcInvalidResponseError("ERPC returned a non-array batch response");
|
|
4519
5237
|
}
|
|
@@ -4555,24 +5273,34 @@ var HttpJsonRpcTransport = class {
|
|
|
4555
5273
|
this.#nextId = id >= Number.MAX_SAFE_INTEGER ? 1 : id + 1;
|
|
4556
5274
|
return id;
|
|
4557
5275
|
}
|
|
5276
|
+
#ensureConfigured() {
|
|
5277
|
+
if (this.#unavailableNamespace !== void 0) {
|
|
5278
|
+
throw new ErpcNotConfiguredError(this.#unavailableNamespace);
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
4558
5281
|
#request(id, method, params) {
|
|
4559
5282
|
const request = { jsonrpc: "2.0", id, method };
|
|
4560
5283
|
if (params !== void 0) request.params = params;
|
|
4561
5284
|
return request;
|
|
4562
5285
|
}
|
|
4563
5286
|
async #post(body, options) {
|
|
4564
|
-
|
|
4565
|
-
url
|
|
5287
|
+
this.#ensureConfigured();
|
|
5288
|
+
const url = new URL(this.#requestEndpoint);
|
|
5289
|
+
if (!this.#direct) url.searchParams.set("api-key", this.#apiKey);
|
|
4566
5290
|
const controlled = controlledSignal2(this.#timeoutMs, options.signal);
|
|
4567
5291
|
try {
|
|
4568
5292
|
const response = await this.#fetch(url, {
|
|
4569
5293
|
method: "POST",
|
|
4570
|
-
headers: {
|
|
5294
|
+
headers: this.#direct ? directRequestHeaders(this.#headers) : {
|
|
4571
5295
|
...this.#headers,
|
|
4572
5296
|
"content-type": "application/json"
|
|
4573
5297
|
},
|
|
4574
5298
|
body: JSON.stringify(body),
|
|
4575
|
-
signal: controlled.signal
|
|
5299
|
+
signal: controlled.signal,
|
|
5300
|
+
...this.#direct ? {
|
|
5301
|
+
credentials: "omit",
|
|
5302
|
+
redirect: "manual"
|
|
5303
|
+
} : {}
|
|
4576
5304
|
});
|
|
4577
5305
|
const text = await response.text();
|
|
4578
5306
|
if (!response.ok) throw new ErpcHttpError(response.status);
|
|
@@ -4595,7 +5323,11 @@ var HttpJsonRpcTransport = class {
|
|
|
4595
5323
|
}
|
|
4596
5324
|
if (isFailure(response)) {
|
|
4597
5325
|
throw new ErpcJsonRpcError(
|
|
4598
|
-
redactJsonRpcError(
|
|
5326
|
+
redactJsonRpcError(
|
|
5327
|
+
response.error,
|
|
5328
|
+
this.#direct ? void 0 : this.#apiKey,
|
|
5329
|
+
this.#redactionVariants
|
|
5330
|
+
)
|
|
4599
5331
|
);
|
|
4600
5332
|
}
|
|
4601
5333
|
if (!("result" in response)) throw new ErpcInvalidResponseError();
|
|
@@ -4689,62 +5421,81 @@ var UsageClient = class {
|
|
|
4689
5421
|
};
|
|
4690
5422
|
|
|
4691
5423
|
// src/client.ts
|
|
5424
|
+
var unavailableEndpoint = (namespace) => new URL(
|
|
5425
|
+
`https://unconfigured.invalid/${namespace.replace(/[^a-z\d._-]+/giu, "-")}`
|
|
5426
|
+
);
|
|
4692
5427
|
var createErpcClient = (config) => {
|
|
4693
5428
|
const resolved = resolveConfig(config);
|
|
4694
|
-
const
|
|
4695
|
-
apiKey: resolved.apiKey,
|
|
5429
|
+
const legacyTransport = {
|
|
4696
5430
|
fetch: resolved.fetch,
|
|
4697
5431
|
headers: resolved.headers,
|
|
4698
|
-
timeoutMs: resolved.timeoutMs
|
|
5432
|
+
timeoutMs: resolved.timeoutMs,
|
|
5433
|
+
...resolved.apiKey === void 0 ? {} : { apiKey: resolved.apiKey }
|
|
4699
5434
|
};
|
|
4700
|
-
const
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
const ethereumEndpoint = endpointWithPath(resolved.endpoint, "/eth");
|
|
4705
|
-
const ethereumTransport = new HttpJsonRpcTransport({
|
|
4706
|
-
...sharedTransport,
|
|
4707
|
-
endpoint: ethereumEndpoint
|
|
4708
|
-
});
|
|
4709
|
-
const avalancheTransport = new HttpJsonRpcTransport({
|
|
4710
|
-
...sharedTransport,
|
|
4711
|
-
endpoint: endpointWithPath(resolved.avalancheEndpoint, "/ava")
|
|
4712
|
-
});
|
|
4713
|
-
const avalancheIndexTransport = (path) => new HttpJsonRpcTransport({
|
|
4714
|
-
...sharedTransport,
|
|
4715
|
-
endpoint: endpointWithPath(resolved.avalancheEndpoint, path)
|
|
4716
|
-
});
|
|
4717
|
-
const solanaWebSocket = new WebSocketJsonRpcTransport({
|
|
4718
|
-
endpoint: websocketUrl(resolved.endpoint, resolved.apiKey),
|
|
5435
|
+
const createUnavailableHttp = (namespace) => new HttpJsonRpcTransport({
|
|
5436
|
+
endpoint: unavailableEndpoint(namespace),
|
|
5437
|
+
fetch: resolved.fetch,
|
|
5438
|
+
headers: {},
|
|
4719
5439
|
timeoutMs: resolved.timeoutMs,
|
|
4720
|
-
|
|
5440
|
+
unavailableNamespace: namespace
|
|
4721
5441
|
});
|
|
4722
|
-
const
|
|
4723
|
-
endpoint:
|
|
5442
|
+
const createUnavailableWebSocket = (namespace) => new WebSocketJsonRpcTransport({
|
|
5443
|
+
endpoint: unavailableEndpoint(namespace),
|
|
4724
5444
|
timeoutMs: resolved.timeoutMs,
|
|
4725
|
-
|
|
5445
|
+
unavailableNamespace: namespace
|
|
4726
5446
|
});
|
|
4727
|
-
const
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
5447
|
+
const createDirectHttp = (endpoint) => new HttpJsonRpcTransport({
|
|
5448
|
+
direct: true,
|
|
5449
|
+
endpoint: endpoint.httpUrl,
|
|
5450
|
+
fetch: resolved.fetch,
|
|
5451
|
+
headers: endpoint.headers,
|
|
5452
|
+
timeoutMs: resolved.timeoutMs
|
|
5453
|
+
});
|
|
5454
|
+
const createDirectWebSocket = (endpoint, namespace) => {
|
|
5455
|
+
if (endpoint.webSocketUrl === void 0) {
|
|
5456
|
+
return createUnavailableWebSocket(namespace);
|
|
5457
|
+
}
|
|
5458
|
+
return new WebSocketJsonRpcTransport({
|
|
5459
|
+
endpoint: endpoint.webSocketUrl,
|
|
5460
|
+
redactionHeaders: endpoint.headers,
|
|
5461
|
+
timeoutMs: resolved.timeoutMs,
|
|
5462
|
+
...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
|
|
5463
|
+
});
|
|
5464
|
+
};
|
|
5465
|
+
const createLegacyHttp = (endpoint) => new HttpJsonRpcTransport({ ...legacyTransport, endpoint });
|
|
5466
|
+
const createLegacyWebSocket = (endpoint) => new WebSocketJsonRpcTransport({
|
|
5467
|
+
endpoint,
|
|
4733
5468
|
timeoutMs: resolved.timeoutMs,
|
|
4734
5469
|
...resolved.webSocket === void 0 ? {} : { webSocket: resolved.webSocket }
|
|
4735
5470
|
});
|
|
4736
|
-
const
|
|
4737
|
-
|
|
4738
|
-
|
|
5471
|
+
const solanaTransport = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("solana.rpc") : createLegacyHttp(resolved.endpoint) : createDirectHttp(resolved.solanaRpc);
|
|
5472
|
+
const ethereumTransport = resolved.ethereumRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("ethereum.rpc") : createLegacyHttp(endpointWithPath(resolved.endpoint, "/eth")) : createDirectHttp(resolved.ethereumRpc);
|
|
5473
|
+
const avalancheTransport = resolved.avalancheCRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.rpc") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava")) : createDirectHttp(resolved.avalancheCRpc);
|
|
5474
|
+
const avalancheNativeTransport = resolved.apiKey === void 0 ? createUnavailableHttp("avalanche.native") : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, "/ava"));
|
|
5475
|
+
const avalancheIndexTransport = (path, namespace) => resolved.apiKey === void 0 ? createUnavailableHttp(namespace) : createLegacyHttp(endpointWithPath(resolved.avalancheEndpoint, path));
|
|
5476
|
+
const solanaWebSocket = resolved.solanaRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("solana.subscriptions") : createLegacyWebSocket(websocketUrl(resolved.endpoint, resolved.apiKey)) : createDirectWebSocket(resolved.solanaRpc, "solana.subscriptions");
|
|
5477
|
+
const ethereumWebSocket = resolved.ethereumRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("ethereum.subscriptions") : createLegacyWebSocket(
|
|
5478
|
+
websocketUrl(resolved.endpoint, resolved.apiKey, "/eth")
|
|
5479
|
+
) : createDirectWebSocket(resolved.ethereumRpc, "ethereum.subscriptions");
|
|
5480
|
+
const avalancheWebSocket = resolved.avalancheCRpc === void 0 ? resolved.apiKey === void 0 ? createUnavailableWebSocket("avalanche.subscriptions") : createLegacyWebSocket(
|
|
5481
|
+
websocketUrl(resolved.avalancheEndpoint, resolved.apiKey, "/ava-ws")
|
|
5482
|
+
) : createDirectWebSocket(
|
|
5483
|
+
resolved.avalancheCRpc,
|
|
5484
|
+
"avalanche.subscriptions"
|
|
5485
|
+
);
|
|
5486
|
+
const createUnavailableRest = (namespace) => new RestTransport({
|
|
5487
|
+
endpoint: unavailableEndpoint(namespace),
|
|
5488
|
+
fetch: resolved.fetch,
|
|
5489
|
+
headers: {},
|
|
5490
|
+
timeoutMs: resolved.timeoutMs,
|
|
5491
|
+
unavailableNamespace: namespace
|
|
4739
5492
|
});
|
|
4740
|
-
const
|
|
4741
|
-
|
|
5493
|
+
const priceTransport = resolved.apiKey === void 0 ? createUnavailableRest("price") : new RestTransport({ ...legacyTransport, endpoint: resolved.endpoint });
|
|
5494
|
+
const accountTransport = resolved.apiKey === void 0 ? createUnavailableRest("account") : new RestTransport({
|
|
5495
|
+
...legacyTransport,
|
|
4742
5496
|
endpoint: resolved.accountEndpoint
|
|
4743
5497
|
});
|
|
4744
|
-
const userTransport = new RestTransport({
|
|
4745
|
-
...sharedTransport,
|
|
4746
|
-
endpoint: resolved.userEndpoint
|
|
4747
|
-
});
|
|
5498
|
+
const userTransport = resolved.apiKey === void 0 ? createUnavailableRest("usage") : new RestTransport({ ...legacyTransport, endpoint: resolved.userEndpoint });
|
|
4748
5499
|
const solana = {
|
|
4749
5500
|
...createSolanaClient(solanaTransport),
|
|
4750
5501
|
subscriptions: new SolanaSubscriptions(solanaWebSocket)
|
|
@@ -4755,11 +5506,23 @@ var createErpcClient = (config) => {
|
|
|
4755
5506
|
};
|
|
4756
5507
|
const avalanche = {
|
|
4757
5508
|
...createAvalancheClient(avalancheTransport, {
|
|
4758
|
-
cChainBlocks: avalancheIndexTransport(
|
|
4759
|
-
|
|
4760
|
-
|
|
4761
|
-
|
|
4762
|
-
|
|
5509
|
+
cChainBlocks: avalancheIndexTransport(
|
|
5510
|
+
"/ava/ext/index/C/block",
|
|
5511
|
+
"avalanche.index.cChainBlocks"
|
|
5512
|
+
),
|
|
5513
|
+
pChainBlocks: avalancheIndexTransport(
|
|
5514
|
+
"/ava/ext/index/P/block",
|
|
5515
|
+
"avalanche.index.pChainBlocks"
|
|
5516
|
+
),
|
|
5517
|
+
xChainBlocks: avalancheIndexTransport(
|
|
5518
|
+
"/ava/ext/index/X/block",
|
|
5519
|
+
"avalanche.index.xChainBlocks"
|
|
5520
|
+
),
|
|
5521
|
+
xChainTransactions: avalancheIndexTransport(
|
|
5522
|
+
"/ava/ext/index/X/tx",
|
|
5523
|
+
"avalanche.index.xChainTransactions"
|
|
5524
|
+
)
|
|
5525
|
+
}, avalancheNativeTransport),
|
|
4763
5526
|
subscriptions: new EthereumSubscriptions(avalancheWebSocket)
|
|
4764
5527
|
};
|
|
4765
5528
|
const swap = createSwapClient({
|
|
@@ -4998,6 +5761,1611 @@ var createErpcCloudClient = (config) => {
|
|
|
4998
5761
|
};
|
|
4999
5762
|
};
|
|
5000
5763
|
|
|
5001
|
-
|
|
5764
|
+
// src/generated/bridge_capabilities.ts
|
|
5765
|
+
var BRIDGE_CAPABILITIES_JSON = '[{"bridgeCapabilityId":"bridge-mayan-swift-v2-eurc-eth-sol","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"eip155:1","destinationChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","sourceTokenDeploymentId":"deployment-0011","destinationTokenDeploymentId":"deployment-0013","sourceTokenAddress":"0x1abaea1f7c830bd89acc67ec4af516284b1bc33c","destinationTokenAddress":"HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr","sourceTokenStandard":"erc20","destinationTokenStandard":"spl-token","sourceTokenDecimals":6,"destinationTokenDecimals":6,"sourceProviderChainName":"ethereum","destinationProviderChainName":"solana","sourceProviderChainId":1,"destinationProviderChainId":0,"sourceWormholeChainId":2,"destinationWormholeChainId":1,"sourceUsdcDeploymentId":"deployment-0008","sourceUsdcAddress":"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","sourceUsdcStandard":"erc20","sourceUsdcDecimals":6,"swiftContract":"0x40ffe85a28dc9993541449464d7529a922142960","forwarderAddress":"0x337685fdab40d39bd02028545a4ffa7d287cc3e2","forwarderFunctionSelector":"0x30dedc57","jupiterProgramAddress":null,"builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","mayan-hosted-source-swap-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer"],"status":"active"},{"bridgeCapabilityId":"bridge-mayan-swift-v2-eurc-sol-eth","providerId":"mayan-swift-v2","capabilityKind":"external-provider-dynamic","sourceChainId":"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp","destinationChainId":"eip155:1","sourceTokenDeploymentId":"deployment-0013","destinationTokenDeploymentId":"deployment-0011","sourceTokenAddress":"HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr","destinationTokenAddress":"0x1abaea1f7c830bd89acc67ec4af516284b1bc33c","sourceTokenStandard":"spl-token","destinationTokenStandard":"erc20","sourceTokenDecimals":6,"destinationTokenDecimals":6,"sourceProviderChainName":"solana","destinationProviderChainName":"ethereum","sourceProviderChainId":0,"destinationProviderChainId":1,"sourceWormholeChainId":1,"destinationWormholeChainId":2,"sourceUsdcDeploymentId":"deployment-0010","sourceUsdcAddress":"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v","sourceUsdcStandard":"spl-token","sourceUsdcDecimals":6,"swiftContract":"mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny","forwarderAddress":null,"forwarderFunctionSelector":null,"jupiterProgramAddress":"JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4","builderEndpoint":"https://tx-builder.mayan.finance","explorerEndpoint":"https://explorer-api.mayan.finance/v3","dependencies":["mayan-hosted-quote-api","mayan-hosted-transaction-builder","mayan-hosted-source-swap-builder","swift-auction-solvers","relayers","wormhole-guardian-messaging","mayan-explorer-indexer","jupiter-v6-source-swap"],"status":"active"}]';
|
|
5766
|
+
var BRIDGE_CAPABILITIES_CONTENT_DIGEST = "fe698f99218057f8cb40b3e24421d1d78e4e2cd7508cf6e3eb2457b329e5141b";
|
|
5767
|
+
var BRIDGE_CAPABILITIES_AS_OF_DATE = "2026-09-16";
|
|
5768
|
+
|
|
5769
|
+
// src/bridge.ts
|
|
5770
|
+
var BRIDGE_ERROR_MESSAGES = Object.freeze({
|
|
5771
|
+
BRIDGE_INVALID_ARGUMENT: "Bridge request is invalid",
|
|
5772
|
+
BRIDGE_UNSUPPORTED_ROUTE: "Bridge route is unsupported",
|
|
5773
|
+
BRIDGE_PROVIDER_AUTH_REQUIRED: "Bridge provider authentication is required",
|
|
5774
|
+
BRIDGE_PROVIDER_TRANSPORT: "Bridge provider transport failed",
|
|
5775
|
+
BRIDGE_PROVIDER_HTTP: "Bridge provider HTTP request failed",
|
|
5776
|
+
BRIDGE_PROVIDER_INVALID_RESPONSE: "Bridge provider response is invalid",
|
|
5777
|
+
BRIDGE_QUOTE_UNAVAILABLE: "Bridge quote is unavailable",
|
|
5778
|
+
BRIDGE_QUOTE_EXPIRED: "Bridge quote is expired",
|
|
5779
|
+
BRIDGE_QUOTE_MISMATCH: "Bridge quote does not match the request",
|
|
5780
|
+
BRIDGE_BUILD_INVALID: "Bridge provider build is invalid",
|
|
5781
|
+
BRIDGE_STATUS_NOT_FOUND: "Bridge status was not found",
|
|
5782
|
+
BRIDGE_TIMEOUT: "Bridge provider request timed out",
|
|
5783
|
+
BRIDGE_ABORTED: "Bridge provider request was aborted"
|
|
5784
|
+
});
|
|
5785
|
+
var BridgeError = class extends Error {
|
|
5786
|
+
code;
|
|
5787
|
+
status;
|
|
5788
|
+
constructor(code, status) {
|
|
5789
|
+
super(BRIDGE_ERROR_MESSAGES[code]);
|
|
5790
|
+
this.name = "BridgeError";
|
|
5791
|
+
this.code = code;
|
|
5792
|
+
if (status !== void 0) this.status = status;
|
|
5793
|
+
}
|
|
5794
|
+
};
|
|
5795
|
+
var ETHEREUM_CHAIN_ID = TOKEN_CHAIN_IDS.ethereumMainnet;
|
|
5796
|
+
var SOLANA_CHAIN_ID = TOKEN_CHAIN_IDS.solanaMainnet;
|
|
5797
|
+
var ETHEREUM_NAME = "ethereum";
|
|
5798
|
+
var SOLANA_NAME = "solana";
|
|
5799
|
+
var ETHEREUM_PROVIDER_CHAIN_ID = 1;
|
|
5800
|
+
var SOLANA_PROVIDER_CHAIN_ID = 0;
|
|
5801
|
+
var ETHEREUM_WORMHOLE_CHAIN_ID = 2;
|
|
5802
|
+
var SOLANA_WORMHOLE_CHAIN_ID = 1;
|
|
5803
|
+
var ETHEREUM_EURC_DEPLOYMENT_ID = "deployment-0011";
|
|
5804
|
+
var SOLANA_EURC_DEPLOYMENT_ID = "deployment-0013";
|
|
5805
|
+
var ETHEREUM_USDC_DEPLOYMENT_ID = "deployment-0008";
|
|
5806
|
+
var SOLANA_USDC_DEPLOYMENT_ID = "deployment-0010";
|
|
5807
|
+
var ETHEREUM_EURC_ADDRESS = "0x1abaea1f7c830bd89acc67ec4af516284b1bc33c";
|
|
5808
|
+
var SOLANA_EURC_ADDRESS = "HzwqbKZw8HxMN6bF2yFZNrht3c2iXXzpKcFu7uBEDKtr";
|
|
5809
|
+
var ETHEREUM_USDC_ADDRESS = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
|
|
5810
|
+
var SOLANA_USDC_ADDRESS = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
|
|
5811
|
+
var ETHEREUM_SWIFT_CONTRACT = "0x40ffe85a28dc9993541449464d7529a922142960";
|
|
5812
|
+
var SOLANA_SWIFT_PROGRAM = "mayan34VedncxdK2XobtvWFDXQASUTBXhUVzt2kKgny";
|
|
5813
|
+
var ETHEREUM_FORWARDER = "0x337685fdab40d39bd02028545a4ffa7d287cc3e2";
|
|
5814
|
+
var SOLANA_JUPITER_V6 = "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4";
|
|
5815
|
+
var ETHEREUM_FORWARDER_SELECTOR = "0x30dedc57";
|
|
5816
|
+
var DEFAULT_BUILDER_ENDPOINT = "https://tx-builder.mayan.finance";
|
|
5817
|
+
var DEFAULT_EXPLORER_ENDPOINT = "https://explorer-api.mayan.finance/v3";
|
|
5818
|
+
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
5819
|
+
var MAX_RESPONSE_BYTES = 1024 * 1024;
|
|
5820
|
+
var MAX_RAW_QUOTE_BYTES = 256 * 1024;
|
|
5821
|
+
var MAX_JSON_DEPTH = 32;
|
|
5822
|
+
var MAX_QUOTES = 16;
|
|
5823
|
+
var UINT64_MAX = (1n << 64n) - 1n;
|
|
5824
|
+
var CANONICAL_UINT64 = /^(0|[1-9][0-9]*)$/u;
|
|
5825
|
+
var POSITIVE_UINT64 = /^[1-9][0-9]*$/u;
|
|
5826
|
+
var EVM_ADDRESS2 = /^0x[0-9a-fA-F]{40}$/u;
|
|
5827
|
+
var EVM_HASH = /^0x[0-9a-fA-F]{64}$/u;
|
|
5828
|
+
var EVM_SIGNATURE = /^0x[0-9a-fA-F]{130}$/u;
|
|
5829
|
+
var HEX_BYTES2 = /^0x[0-9a-fA-F]*$/u;
|
|
5830
|
+
var BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
|
|
5831
|
+
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
5832
|
+
var DEPENDENCIES = Object.freeze([
|
|
5833
|
+
"mayan-hosted-quote-api",
|
|
5834
|
+
"mayan-hosted-transaction-builder",
|
|
5835
|
+
"mayan-hosted-source-swap-builder",
|
|
5836
|
+
"swift-auction-solvers",
|
|
5837
|
+
"relayers",
|
|
5838
|
+
"wormhole-guardian-messaging",
|
|
5839
|
+
"mayan-explorer-indexer"
|
|
5840
|
+
]);
|
|
5841
|
+
var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5842
|
+
var deepFreeze6 = (value) => {
|
|
5843
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
5844
|
+
Object.freeze(value);
|
|
5845
|
+
for (const child of Object.values(value)) deepFreeze6(child);
|
|
5846
|
+
}
|
|
5847
|
+
return value;
|
|
5848
|
+
};
|
|
5849
|
+
var parsedCapabilities = JSON.parse(BRIDGE_CAPABILITIES_JSON);
|
|
5850
|
+
var BRIDGE_CAPABILITIES = deepFreeze6(
|
|
5851
|
+
Array.isArray(parsedCapabilities) ? parsedCapabilities : isRecord4(parsedCapabilities) && Array.isArray(parsedCapabilities.capabilities) ? parsedCapabilities.capabilities : []
|
|
5852
|
+
);
|
|
5853
|
+
var fail = (code, status) => {
|
|
5854
|
+
throw new BridgeError(code, status);
|
|
5855
|
+
};
|
|
5856
|
+
var requireRecord = (value, code) => {
|
|
5857
|
+
if (!isRecord4(value)) fail(code);
|
|
5858
|
+
return value;
|
|
5859
|
+
};
|
|
5860
|
+
var requireString = (value, code, nonempty = true) => {
|
|
5861
|
+
if (typeof value !== "string" || nonempty && value.length === 0) fail(code);
|
|
5862
|
+
return value;
|
|
5863
|
+
};
|
|
5864
|
+
var normalizeEvmAddress3 = (value, code) => {
|
|
5865
|
+
const address = requireString(value, code);
|
|
5866
|
+
if (!EVM_ADDRESS2.test(address) || /^0x0{40}$/iu.test(address)) fail(code);
|
|
5867
|
+
return address.toLowerCase();
|
|
5868
|
+
};
|
|
5869
|
+
var normalizePositiveUint64 = (value, code) => {
|
|
5870
|
+
const source = requireString(value, code);
|
|
5871
|
+
if (!POSITIVE_UINT64.test(source) || source.length > 20) fail(code);
|
|
5872
|
+
let parsed;
|
|
5873
|
+
try {
|
|
5874
|
+
parsed = BigInt(source);
|
|
5875
|
+
} catch {
|
|
5876
|
+
return fail(code);
|
|
5877
|
+
}
|
|
5878
|
+
const valueParsed = parsed;
|
|
5879
|
+
if (valueParsed <= 0n || valueParsed > UINT64_MAX) fail(code);
|
|
5880
|
+
return { source, value: valueParsed };
|
|
5881
|
+
};
|
|
5882
|
+
var normalizeCanonicalUint64 = (value, code) => {
|
|
5883
|
+
const source = requireString(value, code);
|
|
5884
|
+
if (!CANONICAL_UINT64.test(source) || source.length > 20) fail(code);
|
|
5885
|
+
let parsed;
|
|
5886
|
+
try {
|
|
5887
|
+
parsed = BigInt(source);
|
|
5888
|
+
} catch {
|
|
5889
|
+
return fail(code);
|
|
5890
|
+
}
|
|
5891
|
+
const valueParsed = parsed;
|
|
5892
|
+
if (valueParsed > UINT64_MAX) fail(code);
|
|
5893
|
+
return { source, value: valueParsed };
|
|
5894
|
+
};
|
|
5895
|
+
var normalizeSlippage = (value, code) => {
|
|
5896
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 500) {
|
|
5897
|
+
fail(code);
|
|
5898
|
+
}
|
|
5899
|
+
return value;
|
|
5900
|
+
};
|
|
5901
|
+
var providerAddressEquals = (value, expected) => typeof value === "string" && (EVM_ADDRESS2.test(value) ? value.toLowerCase() === expected.toLowerCase() : value === expected);
|
|
5902
|
+
var catalogTokenMatches = (token, expected) => token?.deploymentId === expected.deploymentId && token.chainId === expected.chainId && token.address !== null && (expected.chainId === ETHEREUM_CHAIN_ID ? token.address.toLowerCase() === expected.address.toLowerCase() : token.address === expected.address) && token.standard === expected.standard && token.decimals === expected.decimals && token.status === "active";
|
|
5903
|
+
var directionFacts = (sourceChainId, destinationChainId) => {
|
|
5904
|
+
if (sourceChainId === ETHEREUM_CHAIN_ID && destinationChainId === SOLANA_CHAIN_ID) {
|
|
5905
|
+
return {
|
|
5906
|
+
sourceChainId,
|
|
5907
|
+
destinationChainId,
|
|
5908
|
+
bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-eth-sol",
|
|
5909
|
+
sourceTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
|
|
5910
|
+
destinationTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
|
|
5911
|
+
sourceTokenAddress: ETHEREUM_EURC_ADDRESS,
|
|
5912
|
+
destinationTokenAddress: SOLANA_EURC_ADDRESS,
|
|
5913
|
+
sourceTokenStandard: "erc20",
|
|
5914
|
+
destinationTokenStandard: "spl-token",
|
|
5915
|
+
sourceProviderChainId: ETHEREUM_PROVIDER_CHAIN_ID,
|
|
5916
|
+
destinationProviderChainId: SOLANA_PROVIDER_CHAIN_ID,
|
|
5917
|
+
sourceWormholeChainId: ETHEREUM_WORMHOLE_CHAIN_ID,
|
|
5918
|
+
destinationWormholeChainId: SOLANA_WORMHOLE_CHAIN_ID,
|
|
5919
|
+
sourceName: ETHEREUM_NAME,
|
|
5920
|
+
destinationName: SOLANA_NAME,
|
|
5921
|
+
sourceEurcMint: "",
|
|
5922
|
+
destinationEurcMint: SOLANA_EURC_ADDRESS,
|
|
5923
|
+
sourceUsdcDeploymentId: ETHEREUM_USDC_DEPLOYMENT_ID,
|
|
5924
|
+
sourceUsdcAddress: ETHEREUM_USDC_ADDRESS,
|
|
5925
|
+
sourceUsdcStandard: "erc20",
|
|
5926
|
+
swiftContract: ETHEREUM_SWIFT_CONTRACT
|
|
5927
|
+
};
|
|
5928
|
+
}
|
|
5929
|
+
if (sourceChainId === SOLANA_CHAIN_ID && destinationChainId === ETHEREUM_CHAIN_ID) {
|
|
5930
|
+
return {
|
|
5931
|
+
sourceChainId,
|
|
5932
|
+
destinationChainId,
|
|
5933
|
+
bridgeCapabilityId: "bridge-mayan-swift-v2-eurc-sol-eth",
|
|
5934
|
+
sourceTokenDeploymentId: SOLANA_EURC_DEPLOYMENT_ID,
|
|
5935
|
+
destinationTokenDeploymentId: ETHEREUM_EURC_DEPLOYMENT_ID,
|
|
5936
|
+
sourceTokenAddress: SOLANA_EURC_ADDRESS,
|
|
5937
|
+
destinationTokenAddress: ETHEREUM_EURC_ADDRESS,
|
|
5938
|
+
sourceTokenStandard: "spl-token",
|
|
5939
|
+
destinationTokenStandard: "erc20",
|
|
5940
|
+
sourceProviderChainId: SOLANA_PROVIDER_CHAIN_ID,
|
|
5941
|
+
destinationProviderChainId: ETHEREUM_PROVIDER_CHAIN_ID,
|
|
5942
|
+
sourceWormholeChainId: SOLANA_WORMHOLE_CHAIN_ID,
|
|
5943
|
+
destinationWormholeChainId: ETHEREUM_WORMHOLE_CHAIN_ID,
|
|
5944
|
+
sourceName: SOLANA_NAME,
|
|
5945
|
+
destinationName: ETHEREUM_NAME,
|
|
5946
|
+
sourceEurcMint: SOLANA_EURC_ADDRESS,
|
|
5947
|
+
destinationEurcMint: "",
|
|
5948
|
+
sourceUsdcDeploymentId: SOLANA_USDC_DEPLOYMENT_ID,
|
|
5949
|
+
sourceUsdcAddress: SOLANA_USDC_ADDRESS,
|
|
5950
|
+
sourceUsdcStandard: "spl-token",
|
|
5951
|
+
swiftContract: SOLANA_SWIFT_PROGRAM
|
|
5952
|
+
};
|
|
5953
|
+
}
|
|
5954
|
+
return fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
5955
|
+
};
|
|
5956
|
+
var findCapability = (facts) => {
|
|
5957
|
+
const capability = BRIDGE_CAPABILITIES.find(
|
|
5958
|
+
(entry) => entry.bridgeCapabilityId === facts.bridgeCapabilityId && entry.sourceChainId === facts.sourceChainId && entry.destinationChainId === facts.destinationChainId && entry.sourceTokenDeploymentId === facts.sourceTokenDeploymentId && entry.destinationTokenDeploymentId === facts.destinationTokenDeploymentId
|
|
5959
|
+
);
|
|
5960
|
+
if (!capability) fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
5961
|
+
return capability;
|
|
5962
|
+
};
|
|
5963
|
+
var validateCatalogDirection = (facts) => {
|
|
5964
|
+
const sourceToken = getTokenDeployment(facts.sourceTokenDeploymentId);
|
|
5965
|
+
const destinationToken = getTokenDeployment(facts.destinationTokenDeploymentId);
|
|
5966
|
+
const sourceUsdc = getTokenDeployment(facts.sourceUsdcDeploymentId);
|
|
5967
|
+
if (!catalogTokenMatches(sourceToken, {
|
|
5968
|
+
deploymentId: facts.sourceTokenDeploymentId,
|
|
5969
|
+
chainId: facts.sourceChainId,
|
|
5970
|
+
address: facts.sourceTokenAddress,
|
|
5971
|
+
standard: facts.sourceTokenStandard,
|
|
5972
|
+
decimals: 6
|
|
5973
|
+
}) || !catalogTokenMatches(destinationToken, {
|
|
5974
|
+
deploymentId: facts.destinationTokenDeploymentId,
|
|
5975
|
+
chainId: facts.destinationChainId,
|
|
5976
|
+
address: facts.destinationTokenAddress,
|
|
5977
|
+
standard: facts.destinationTokenStandard,
|
|
5978
|
+
decimals: 6
|
|
5979
|
+
}) || !catalogTokenMatches(sourceUsdc, {
|
|
5980
|
+
deploymentId: facts.sourceUsdcDeploymentId,
|
|
5981
|
+
chainId: facts.sourceChainId,
|
|
5982
|
+
address: facts.sourceUsdcAddress,
|
|
5983
|
+
standard: facts.sourceUsdcStandard,
|
|
5984
|
+
decimals: 6
|
|
5985
|
+
})) {
|
|
5986
|
+
fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
5987
|
+
}
|
|
5988
|
+
};
|
|
5989
|
+
var validateCapability = (capability, facts) => {
|
|
5990
|
+
const expected = {
|
|
5991
|
+
bridgeCapabilityId: facts.bridgeCapabilityId,
|
|
5992
|
+
providerId: "mayan-swift-v2",
|
|
5993
|
+
capabilityKind: "external-provider-dynamic",
|
|
5994
|
+
sourceChainId: facts.sourceChainId,
|
|
5995
|
+
destinationChainId: facts.destinationChainId,
|
|
5996
|
+
sourceTokenDeploymentId: facts.sourceTokenDeploymentId,
|
|
5997
|
+
destinationTokenDeploymentId: facts.destinationTokenDeploymentId,
|
|
5998
|
+
sourceTokenAddress: facts.sourceTokenAddress,
|
|
5999
|
+
destinationTokenAddress: facts.destinationTokenAddress,
|
|
6000
|
+
sourceTokenStandard: facts.sourceTokenStandard,
|
|
6001
|
+
destinationTokenStandard: facts.destinationTokenStandard,
|
|
6002
|
+
sourceTokenDecimals: 6,
|
|
6003
|
+
destinationTokenDecimals: 6,
|
|
6004
|
+
sourceProviderChainName: facts.sourceName,
|
|
6005
|
+
destinationProviderChainName: facts.destinationName,
|
|
6006
|
+
sourceProviderChainId: facts.sourceProviderChainId,
|
|
6007
|
+
destinationProviderChainId: facts.destinationProviderChainId,
|
|
6008
|
+
sourceWormholeChainId: facts.sourceWormholeChainId,
|
|
6009
|
+
destinationWormholeChainId: facts.destinationWormholeChainId,
|
|
6010
|
+
sourceUsdcDeploymentId: facts.sourceUsdcDeploymentId,
|
|
6011
|
+
sourceUsdcAddress: facts.sourceUsdcAddress,
|
|
6012
|
+
sourceUsdcStandard: facts.sourceUsdcStandard,
|
|
6013
|
+
sourceUsdcDecimals: 6,
|
|
6014
|
+
swiftContract: facts.swiftContract,
|
|
6015
|
+
forwarderAddress: facts.sourceChainId === ETHEREUM_CHAIN_ID ? ETHEREUM_FORWARDER : null,
|
|
6016
|
+
forwarderFunctionSelector: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "0x30dedc57" : null,
|
|
6017
|
+
jupiterProgramAddress: facts.sourceChainId === SOLANA_CHAIN_ID ? SOLANA_JUPITER_V6 : null,
|
|
6018
|
+
builderEndpoint: DEFAULT_BUILDER_ENDPOINT,
|
|
6019
|
+
explorerEndpoint: DEFAULT_EXPLORER_ENDPOINT,
|
|
6020
|
+
dependencies: facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES],
|
|
6021
|
+
status: "active"
|
|
6022
|
+
};
|
|
6023
|
+
const actualKeys = Object.keys(capability).sort();
|
|
6024
|
+
const expectedKeys = Object.keys(expected).sort();
|
|
6025
|
+
if (actualKeys.length !== expectedKeys.length || actualKeys.some((key, index) => key !== expectedKeys[index])) {
|
|
6026
|
+
fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
6027
|
+
}
|
|
6028
|
+
for (const key of expectedKeys) {
|
|
6029
|
+
const actual = capability[key];
|
|
6030
|
+
const wanted = expected[key];
|
|
6031
|
+
if (Array.isArray(actual) || Array.isArray(wanted)) {
|
|
6032
|
+
if (JSON.stringify(actual) !== JSON.stringify(wanted)) fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
6033
|
+
} else if (actual !== wanted) {
|
|
6034
|
+
fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
6037
|
+
};
|
|
6038
|
+
var validateBridgeRoute = (request) => {
|
|
6039
|
+
const value = requireRecord(request, "BRIDGE_INVALID_ARGUMENT");
|
|
6040
|
+
const keys = /* @__PURE__ */ new Set([
|
|
6041
|
+
"sourceChainId",
|
|
6042
|
+
"destinationChainId",
|
|
6043
|
+
"sourceTokenDeploymentId",
|
|
6044
|
+
"destinationTokenDeploymentId",
|
|
6045
|
+
"amountIn",
|
|
6046
|
+
"slippageBps"
|
|
6047
|
+
]);
|
|
6048
|
+
if (Object.keys(value).some((key) => !keys.has(key))) fail("BRIDGE_INVALID_ARGUMENT");
|
|
6049
|
+
const sourceChainId = requireString(value.sourceChainId, "BRIDGE_INVALID_ARGUMENT");
|
|
6050
|
+
const destinationChainId = requireString(value.destinationChainId, "BRIDGE_INVALID_ARGUMENT");
|
|
6051
|
+
const sourceTokenDeploymentId = requireString(
|
|
6052
|
+
value.sourceTokenDeploymentId,
|
|
6053
|
+
"BRIDGE_INVALID_ARGUMENT"
|
|
6054
|
+
);
|
|
6055
|
+
const destinationTokenDeploymentId = requireString(
|
|
6056
|
+
value.destinationTokenDeploymentId,
|
|
6057
|
+
"BRIDGE_INVALID_ARGUMENT"
|
|
6058
|
+
);
|
|
6059
|
+
const amountIn = normalizePositiveUint64(value.amountIn, "BRIDGE_INVALID_ARGUMENT");
|
|
6060
|
+
const slippageBps = normalizeSlippage(value.slippageBps, "BRIDGE_INVALID_ARGUMENT");
|
|
6061
|
+
const facts = directionFacts(sourceChainId, destinationChainId);
|
|
6062
|
+
if (sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) {
|
|
6063
|
+
fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
6064
|
+
}
|
|
6065
|
+
validateCatalogDirection(facts);
|
|
6066
|
+
const capability = findCapability(facts);
|
|
6067
|
+
validateCapability(capability, facts);
|
|
6068
|
+
return {
|
|
6069
|
+
request: {
|
|
6070
|
+
sourceChainId,
|
|
6071
|
+
destinationChainId,
|
|
6072
|
+
sourceTokenDeploymentId,
|
|
6073
|
+
destinationTokenDeploymentId,
|
|
6074
|
+
amountIn: amountIn.source,
|
|
6075
|
+
slippageBps
|
|
6076
|
+
},
|
|
6077
|
+
facts,
|
|
6078
|
+
capability
|
|
6079
|
+
};
|
|
6080
|
+
};
|
|
6081
|
+
var isJsonWhitespace = (character) => character === " " || character === "\n" || character === "\r" || character === " ";
|
|
6082
|
+
var StrictJsonParser = class {
|
|
6083
|
+
#source;
|
|
6084
|
+
#index = 0;
|
|
6085
|
+
constructor(source) {
|
|
6086
|
+
this.#source = source;
|
|
6087
|
+
}
|
|
6088
|
+
parse() {
|
|
6089
|
+
this.#skipWhitespace();
|
|
6090
|
+
const value = this.#value(0);
|
|
6091
|
+
this.#skipWhitespace();
|
|
6092
|
+
if (this.#index !== this.#source.length) this.#invalid();
|
|
6093
|
+
return value;
|
|
6094
|
+
}
|
|
6095
|
+
#value(depth) {
|
|
6096
|
+
if (depth > MAX_JSON_DEPTH) this.#invalid();
|
|
6097
|
+
const start = this.#index;
|
|
6098
|
+
const character = this.#source[this.#index];
|
|
6099
|
+
if (character === "{") return this.#object(start, depth);
|
|
6100
|
+
if (character === "[") return this.#array(start, depth);
|
|
6101
|
+
if (character === '"') {
|
|
6102
|
+
const value = this.#string();
|
|
6103
|
+
return { value, start, end: this.#index };
|
|
6104
|
+
}
|
|
6105
|
+
if (character === "t" && this.#source.startsWith("true", this.#index)) {
|
|
6106
|
+
this.#index += 4;
|
|
6107
|
+
return { value: true, start, end: this.#index };
|
|
6108
|
+
}
|
|
6109
|
+
if (character === "f" && this.#source.startsWith("false", this.#index)) {
|
|
6110
|
+
this.#index += 5;
|
|
6111
|
+
return { value: false, start, end: this.#index };
|
|
6112
|
+
}
|
|
6113
|
+
if (character === "n" && this.#source.startsWith("null", this.#index)) {
|
|
6114
|
+
this.#index += 4;
|
|
6115
|
+
return { value: null, start, end: this.#index };
|
|
6116
|
+
}
|
|
6117
|
+
if (character === "-" || character !== void 0 && /[0-9]/u.test(character)) {
|
|
6118
|
+
const rawNumber = this.#number();
|
|
6119
|
+
const value = Number(rawNumber);
|
|
6120
|
+
if (!Number.isFinite(value)) this.#invalid();
|
|
6121
|
+
return { value, start, end: this.#index, rawNumber };
|
|
6122
|
+
}
|
|
6123
|
+
return this.#invalid();
|
|
6124
|
+
}
|
|
6125
|
+
#object(start, depth) {
|
|
6126
|
+
this.#index += 1;
|
|
6127
|
+
this.#skipWhitespace();
|
|
6128
|
+
const object = /* @__PURE__ */ Object.create(null);
|
|
6129
|
+
const entries = /* @__PURE__ */ new Map();
|
|
6130
|
+
if (this.#source[this.#index] === "}") {
|
|
6131
|
+
this.#index += 1;
|
|
6132
|
+
return { value: object, start, end: this.#index, objectEntries: entries };
|
|
6133
|
+
}
|
|
6134
|
+
while (true) {
|
|
6135
|
+
if (this.#source[this.#index] !== '"') this.#invalid();
|
|
6136
|
+
const key = this.#string();
|
|
6137
|
+
if (entries.has(key)) this.#invalid();
|
|
6138
|
+
this.#skipWhitespace();
|
|
6139
|
+
if (this.#source[this.#index] !== ":") this.#invalid();
|
|
6140
|
+
this.#index += 1;
|
|
6141
|
+
this.#skipWhitespace();
|
|
6142
|
+
const child = this.#value(depth + 1);
|
|
6143
|
+
Object.defineProperty(object, key, {
|
|
6144
|
+
configurable: true,
|
|
6145
|
+
enumerable: true,
|
|
6146
|
+
value: child.value,
|
|
6147
|
+
writable: true
|
|
6148
|
+
});
|
|
6149
|
+
entries.set(key, child);
|
|
6150
|
+
this.#skipWhitespace();
|
|
6151
|
+
const delimiter = this.#source[this.#index];
|
|
6152
|
+
if (delimiter === "}") {
|
|
6153
|
+
this.#index += 1;
|
|
6154
|
+
return {
|
|
6155
|
+
value: object,
|
|
6156
|
+
start,
|
|
6157
|
+
end: this.#index,
|
|
6158
|
+
objectEntries: entries
|
|
6159
|
+
};
|
|
6160
|
+
}
|
|
6161
|
+
if (delimiter !== ",") this.#invalid();
|
|
6162
|
+
this.#index += 1;
|
|
6163
|
+
this.#skipWhitespace();
|
|
6164
|
+
}
|
|
6165
|
+
}
|
|
6166
|
+
#array(start, depth) {
|
|
6167
|
+
this.#index += 1;
|
|
6168
|
+
this.#skipWhitespace();
|
|
6169
|
+
const items = [];
|
|
6170
|
+
if (this.#source[this.#index] === "]") {
|
|
6171
|
+
this.#index += 1;
|
|
6172
|
+
return { value: items, start, end: this.#index, arrayItems: items };
|
|
6173
|
+
}
|
|
6174
|
+
while (true) {
|
|
6175
|
+
items.push(this.#value(depth + 1));
|
|
6176
|
+
this.#skipWhitespace();
|
|
6177
|
+
const delimiter = this.#source[this.#index];
|
|
6178
|
+
if (delimiter === "]") {
|
|
6179
|
+
this.#index += 1;
|
|
6180
|
+
return { value: items, start, end: this.#index, arrayItems: items };
|
|
6181
|
+
}
|
|
6182
|
+
if (delimiter !== ",") this.#invalid();
|
|
6183
|
+
this.#index += 1;
|
|
6184
|
+
this.#skipWhitespace();
|
|
6185
|
+
}
|
|
6186
|
+
}
|
|
6187
|
+
#string() {
|
|
6188
|
+
const start = this.#index;
|
|
6189
|
+
this.#index += 1;
|
|
6190
|
+
while (this.#index < this.#source.length) {
|
|
6191
|
+
const character = this.#source[this.#index];
|
|
6192
|
+
if (character === '"') {
|
|
6193
|
+
this.#index += 1;
|
|
6194
|
+
const raw = this.#source.slice(start, this.#index);
|
|
6195
|
+
try {
|
|
6196
|
+
return JSON.parse(raw);
|
|
6197
|
+
} catch {
|
|
6198
|
+
this.#invalid();
|
|
6199
|
+
}
|
|
6200
|
+
}
|
|
6201
|
+
if (character === "\\") {
|
|
6202
|
+
this.#index += 1;
|
|
6203
|
+
const escape = this.#source[this.#index];
|
|
6204
|
+
if (escape === "u") {
|
|
6205
|
+
const digits = this.#source.slice(this.#index + 1, this.#index + 5);
|
|
6206
|
+
if (!/^[0-9a-fA-F]{4}$/u.test(digits)) this.#invalid();
|
|
6207
|
+
this.#index += 5;
|
|
6208
|
+
continue;
|
|
6209
|
+
}
|
|
6210
|
+
if (escape === void 0 || !'"\\/bfnrt'.includes(escape)) this.#invalid();
|
|
6211
|
+
this.#index += 1;
|
|
6212
|
+
continue;
|
|
6213
|
+
}
|
|
6214
|
+
if (character === void 0 || character.charCodeAt(0) < 32) this.#invalid();
|
|
6215
|
+
this.#index += 1;
|
|
6216
|
+
}
|
|
6217
|
+
return this.#invalid();
|
|
6218
|
+
}
|
|
6219
|
+
#number() {
|
|
6220
|
+
const match = /-?(?:0|[1-9][0-9]*)(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?/uy.exec(
|
|
6221
|
+
this.#source.slice(this.#index)
|
|
6222
|
+
);
|
|
6223
|
+
if (!match) this.#invalid();
|
|
6224
|
+
const raw = match?.[0];
|
|
6225
|
+
this.#index += raw.length;
|
|
6226
|
+
return raw;
|
|
6227
|
+
}
|
|
6228
|
+
#skipWhitespace() {
|
|
6229
|
+
while (this.#index < this.#source.length && isJsonWhitespace(this.#source[this.#index] ?? "")) {
|
|
6230
|
+
this.#index += 1;
|
|
6231
|
+
}
|
|
6232
|
+
}
|
|
6233
|
+
#invalid() {
|
|
6234
|
+
return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6235
|
+
}
|
|
6236
|
+
};
|
|
6237
|
+
var parseProviderResponse = (text) => {
|
|
6238
|
+
let root;
|
|
6239
|
+
try {
|
|
6240
|
+
root = new StrictJsonParser(text).parse();
|
|
6241
|
+
} catch (error) {
|
|
6242
|
+
if (error instanceof BridgeError) throw error;
|
|
6243
|
+
return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6244
|
+
}
|
|
6245
|
+
return { text, root };
|
|
6246
|
+
};
|
|
6247
|
+
var objectEntry = (node, key) => node.objectEntries?.get(key);
|
|
6248
|
+
var objectValue5 = (node, key) => objectEntry(node, key)?.value;
|
|
6249
|
+
var byteLength = (value) => new TextEncoder().encode(value).byteLength;
|
|
6250
|
+
var requestAbortError = () => new DOMException("The bridge provider request was aborted", "AbortError");
|
|
6251
|
+
var throwIfRequestAborted = (controlled, external) => {
|
|
6252
|
+
if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
|
|
6253
|
+
if (external?.aborted) fail("BRIDGE_ABORTED");
|
|
6254
|
+
};
|
|
6255
|
+
var readWithSignal = async (reader, signal) => {
|
|
6256
|
+
if (signal.aborted) throw signal.reason ?? requestAbortError();
|
|
6257
|
+
return new Promise((resolve, reject) => {
|
|
6258
|
+
let settled = false;
|
|
6259
|
+
const cleanup = () => {
|
|
6260
|
+
signal.removeEventListener("abort", onAbort);
|
|
6261
|
+
};
|
|
6262
|
+
const onAbort = () => {
|
|
6263
|
+
if (settled) return;
|
|
6264
|
+
settled = true;
|
|
6265
|
+
cleanup();
|
|
6266
|
+
reject(signal.reason ?? requestAbortError());
|
|
6267
|
+
};
|
|
6268
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
6269
|
+
let read;
|
|
6270
|
+
try {
|
|
6271
|
+
read = reader.read();
|
|
6272
|
+
} catch (error) {
|
|
6273
|
+
if (settled) return;
|
|
6274
|
+
settled = true;
|
|
6275
|
+
cleanup();
|
|
6276
|
+
reject(error);
|
|
6277
|
+
return;
|
|
6278
|
+
}
|
|
6279
|
+
void read.then(
|
|
6280
|
+
(result) => {
|
|
6281
|
+
if (settled) return;
|
|
6282
|
+
settled = true;
|
|
6283
|
+
cleanup();
|
|
6284
|
+
resolve(result);
|
|
6285
|
+
},
|
|
6286
|
+
(error) => {
|
|
6287
|
+
if (settled) return;
|
|
6288
|
+
settled = true;
|
|
6289
|
+
cleanup();
|
|
6290
|
+
reject(error);
|
|
6291
|
+
}
|
|
6292
|
+
);
|
|
6293
|
+
});
|
|
6294
|
+
};
|
|
6295
|
+
var cancelResponseBody = (response) => {
|
|
6296
|
+
const body = response.body;
|
|
6297
|
+
if (body === null || response.bodyUsed) return;
|
|
6298
|
+
try {
|
|
6299
|
+
void body.cancel().catch(() => void 0);
|
|
6300
|
+
} catch {
|
|
6301
|
+
}
|
|
6302
|
+
};
|
|
6303
|
+
var decodeResponseBody = async (response, controlled, external) => {
|
|
6304
|
+
throwIfRequestAborted(controlled, external);
|
|
6305
|
+
const contentLength = response.headers.get("content-length");
|
|
6306
|
+
if (contentLength !== null && /^\d+$/u.test(contentLength)) {
|
|
6307
|
+
try {
|
|
6308
|
+
if (BigInt(contentLength) > BigInt(MAX_RESPONSE_BYTES)) {
|
|
6309
|
+
fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6310
|
+
}
|
|
6311
|
+
} catch {
|
|
6312
|
+
}
|
|
6313
|
+
}
|
|
6314
|
+
const body = response.body;
|
|
6315
|
+
if (body === null) return "";
|
|
6316
|
+
let reader;
|
|
6317
|
+
try {
|
|
6318
|
+
reader = body.getReader();
|
|
6319
|
+
} catch {
|
|
6320
|
+
return fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6321
|
+
}
|
|
6322
|
+
const chunks = [];
|
|
6323
|
+
let totalBytes = 0;
|
|
6324
|
+
let bodyComplete = false;
|
|
6325
|
+
const releaseReader = () => {
|
|
6326
|
+
try {
|
|
6327
|
+
reader.releaseLock();
|
|
6328
|
+
} catch {
|
|
6329
|
+
}
|
|
6330
|
+
};
|
|
6331
|
+
try {
|
|
6332
|
+
while (true) {
|
|
6333
|
+
let result;
|
|
6334
|
+
try {
|
|
6335
|
+
result = await readWithSignal(reader, controlled.signal);
|
|
6336
|
+
} catch (error) {
|
|
6337
|
+
throwIfRequestAborted(controlled, external);
|
|
6338
|
+
if (error instanceof BridgeError) throw error;
|
|
6339
|
+
return fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6340
|
+
}
|
|
6341
|
+
throwIfRequestAborted(controlled, external);
|
|
6342
|
+
if (result.done) {
|
|
6343
|
+
bodyComplete = true;
|
|
6344
|
+
break;
|
|
6345
|
+
}
|
|
6346
|
+
const chunk = result.value;
|
|
6347
|
+
if (!(chunk instanceof Uint8Array)) return fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6348
|
+
totalBytes += chunk.byteLength;
|
|
6349
|
+
if (totalBytes > MAX_RESPONSE_BYTES) {
|
|
6350
|
+
fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6351
|
+
}
|
|
6352
|
+
chunks.push(chunk);
|
|
6353
|
+
}
|
|
6354
|
+
throwIfRequestAborted(controlled, external);
|
|
6355
|
+
const bytes = new Uint8Array(totalBytes);
|
|
6356
|
+
let offset = 0;
|
|
6357
|
+
for (const chunk of chunks) {
|
|
6358
|
+
bytes.set(chunk, offset);
|
|
6359
|
+
offset += chunk.byteLength;
|
|
6360
|
+
}
|
|
6361
|
+
try {
|
|
6362
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
|
|
6363
|
+
} catch {
|
|
6364
|
+
return fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6365
|
+
}
|
|
6366
|
+
} finally {
|
|
6367
|
+
if (!bodyComplete) {
|
|
6368
|
+
try {
|
|
6369
|
+
const cancellation = reader.cancel();
|
|
6370
|
+
void cancellation.then(releaseReader, releaseReader);
|
|
6371
|
+
} catch {
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
releaseReader();
|
|
6375
|
+
}
|
|
6376
|
+
};
|
|
6377
|
+
var CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
6378
|
+
"builderEndpoint",
|
|
6379
|
+
"explorerEndpoint",
|
|
6380
|
+
"builderApiKey",
|
|
6381
|
+
"allowUnauthenticatedBuild",
|
|
6382
|
+
"minimumQuoteValiditySeconds",
|
|
6383
|
+
"timeoutMs",
|
|
6384
|
+
"fetch"
|
|
6385
|
+
]);
|
|
6386
|
+
var endpointWithPath2 = (base, path) => new URL(path.replace(/^\/+/, ""), `${base.toString().replace(/\/+$/u, "")}/`);
|
|
6387
|
+
var normalizeProviderEndpoint = (value, fallback, label) => {
|
|
6388
|
+
const sourceValue = value === void 0 ? fallback : value;
|
|
6389
|
+
if (typeof sourceValue !== "string") return fail("BRIDGE_INVALID_ARGUMENT");
|
|
6390
|
+
const source = sourceValue;
|
|
6391
|
+
if (source.length === 0 || source.trim() !== source) {
|
|
6392
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6393
|
+
}
|
|
6394
|
+
if (!/^[a-z][a-z\d+.-]*:\/\//iu.test(source) || source.includes("#")) {
|
|
6395
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6396
|
+
}
|
|
6397
|
+
const authorityStart = source.indexOf("://") + 3;
|
|
6398
|
+
const authority = source.slice(authorityStart).split(/[/?#]/u, 1)[0] ?? "";
|
|
6399
|
+
if (authority.length === 0 || authority.includes("@")) fail("BRIDGE_INVALID_ARGUMENT");
|
|
6400
|
+
let endpoint;
|
|
6401
|
+
try {
|
|
6402
|
+
endpoint = new URL(source);
|
|
6403
|
+
} catch {
|
|
6404
|
+
return fail("BRIDGE_INVALID_ARGUMENT");
|
|
6405
|
+
}
|
|
6406
|
+
if (endpoint.protocol !== "https:" && !(endpoint.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]", "::1"].includes(endpoint.hostname))) {
|
|
6407
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6408
|
+
}
|
|
6409
|
+
if (!endpoint.hostname || endpoint.username || endpoint.password || source.includes("?") || endpoint.search || endpoint.hash) {
|
|
6410
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6411
|
+
}
|
|
6412
|
+
if (endpoint.port !== "" && (!/^\d+$/u.test(endpoint.port) || Number(endpoint.port) > 65535)) {
|
|
6413
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6414
|
+
}
|
|
6415
|
+
endpoint.pathname = endpoint.pathname.replace(/\/+$/u, "") || "/";
|
|
6416
|
+
if (!endpoint.pathname.startsWith("/")) fail("BRIDGE_INVALID_ARGUMENT");
|
|
6417
|
+
return endpoint;
|
|
6418
|
+
};
|
|
6419
|
+
var normalizeBridgeConfig = (config) => {
|
|
6420
|
+
const value = config === void 0 ? {} : requireRecord(config, "BRIDGE_INVALID_ARGUMENT");
|
|
6421
|
+
if (Object.keys(value).some((key) => !CONFIG_KEYS.has(key))) {
|
|
6422
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6423
|
+
}
|
|
6424
|
+
const builderEndpoint = normalizeProviderEndpoint(
|
|
6425
|
+
value.builderEndpoint,
|
|
6426
|
+
DEFAULT_BUILDER_ENDPOINT);
|
|
6427
|
+
const explorerEndpoint = normalizeProviderEndpoint(
|
|
6428
|
+
value.explorerEndpoint,
|
|
6429
|
+
DEFAULT_EXPLORER_ENDPOINT);
|
|
6430
|
+
let builderApiKey;
|
|
6431
|
+
if (value.builderApiKey !== void 0) {
|
|
6432
|
+
const builderApiKeyValue = value.builderApiKey;
|
|
6433
|
+
if (typeof builderApiKeyValue !== "string" || /[\u0000-\u001f\u007f]/u.test(builderApiKeyValue)) {
|
|
6434
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6435
|
+
}
|
|
6436
|
+
const validatedBuilderApiKey = builderApiKeyValue;
|
|
6437
|
+
builderApiKey = validatedBuilderApiKey.length === 0 ? void 0 : validatedBuilderApiKey;
|
|
6438
|
+
}
|
|
6439
|
+
const allowUnauthenticatedBuildValue = value.allowUnauthenticatedBuild ?? false;
|
|
6440
|
+
if (typeof allowUnauthenticatedBuildValue !== "boolean") {
|
|
6441
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6442
|
+
}
|
|
6443
|
+
const allowUnauthenticatedBuild = allowUnauthenticatedBuildValue;
|
|
6444
|
+
const minimumQuoteValiditySecondsValue = value.minimumQuoteValiditySeconds ?? 60;
|
|
6445
|
+
if (typeof minimumQuoteValiditySecondsValue !== "number" || !Number.isSafeInteger(minimumQuoteValiditySecondsValue) || minimumQuoteValiditySecondsValue < 0 || minimumQuoteValiditySecondsValue > 300) {
|
|
6446
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6447
|
+
}
|
|
6448
|
+
const minimumQuoteValiditySeconds = minimumQuoteValiditySecondsValue;
|
|
6449
|
+
const timeoutMsValue = value.timeoutMs ?? DEFAULT_TIMEOUT_MS2;
|
|
6450
|
+
if (typeof timeoutMsValue !== "number" || !Number.isSafeInteger(timeoutMsValue) || timeoutMsValue <= 0) {
|
|
6451
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
6452
|
+
}
|
|
6453
|
+
const timeoutMs = timeoutMsValue;
|
|
6454
|
+
const implementation = value.fetch ?? globalThis.fetch;
|
|
6455
|
+
if (typeof implementation !== "function") fail("BRIDGE_INVALID_ARGUMENT");
|
|
6456
|
+
return Object.freeze({
|
|
6457
|
+
builderEndpoint,
|
|
6458
|
+
explorerEndpoint,
|
|
6459
|
+
...builderApiKey === void 0 ? {} : { builderApiKey },
|
|
6460
|
+
allowUnauthenticatedBuild,
|
|
6461
|
+
minimumQuoteValiditySeconds,
|
|
6462
|
+
timeoutMs,
|
|
6463
|
+
fetch: implementation
|
|
6464
|
+
});
|
|
6465
|
+
};
|
|
6466
|
+
var requestSignal = (timeoutMs, external) => {
|
|
6467
|
+
const controller = new AbortController();
|
|
6468
|
+
let timedOut = false;
|
|
6469
|
+
const timeout = setTimeout(() => {
|
|
6470
|
+
timedOut = true;
|
|
6471
|
+
controller.abort();
|
|
6472
|
+
}, timeoutMs);
|
|
6473
|
+
const onAbort = () => controller.abort();
|
|
6474
|
+
if (external?.aborted) controller.abort();
|
|
6475
|
+
else external?.addEventListener("abort", onAbort, { once: true });
|
|
6476
|
+
return {
|
|
6477
|
+
signal: controller.signal,
|
|
6478
|
+
timedOut: () => timedOut,
|
|
6479
|
+
cleanup: () => {
|
|
6480
|
+
clearTimeout(timeout);
|
|
6481
|
+
external?.removeEventListener("abort", onAbort);
|
|
6482
|
+
}
|
|
6483
|
+
};
|
|
6484
|
+
};
|
|
6485
|
+
var providerRequest = async (config, endpoint, method, body, includeBuilderKey, options) => {
|
|
6486
|
+
if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
|
|
6487
|
+
const controlled = requestSignal(config.timeoutMs, options?.signal);
|
|
6488
|
+
try {
|
|
6489
|
+
const headers = {};
|
|
6490
|
+
headers.accept = "application/json";
|
|
6491
|
+
if (body !== void 0) headers["content-type"] = "application/json";
|
|
6492
|
+
if (includeBuilderKey && config.builderApiKey !== void 0) {
|
|
6493
|
+
headers["x-api-key"] = config.builderApiKey;
|
|
6494
|
+
}
|
|
6495
|
+
let response;
|
|
6496
|
+
try {
|
|
6497
|
+
response = await config.fetch(endpoint, {
|
|
6498
|
+
method,
|
|
6499
|
+
headers,
|
|
6500
|
+
...body === void 0 ? {} : { body },
|
|
6501
|
+
signal: controlled.signal,
|
|
6502
|
+
credentials: "omit",
|
|
6503
|
+
redirect: "manual"
|
|
6504
|
+
});
|
|
6505
|
+
if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
|
|
6506
|
+
if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
|
|
6507
|
+
} catch {
|
|
6508
|
+
if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
|
|
6509
|
+
if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
|
|
6510
|
+
return fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6511
|
+
}
|
|
6512
|
+
return {
|
|
6513
|
+
response,
|
|
6514
|
+
controlled,
|
|
6515
|
+
external: options?.signal
|
|
6516
|
+
};
|
|
6517
|
+
} catch (error) {
|
|
6518
|
+
controlled.cleanup();
|
|
6519
|
+
if (error instanceof BridgeError) throw error;
|
|
6520
|
+
if (controlled.timedOut()) fail("BRIDGE_TIMEOUT");
|
|
6521
|
+
if (options?.signal?.aborted) fail("BRIDGE_ABORTED");
|
|
6522
|
+
return fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6523
|
+
}
|
|
6524
|
+
};
|
|
6525
|
+
var providerHttpStatus = (response, kind) => {
|
|
6526
|
+
if (kind === "status" && response.status === 404) fail("BRIDGE_STATUS_NOT_FOUND");
|
|
6527
|
+
if (response.status >= 300 && response.status < 400) {
|
|
6528
|
+
fail("BRIDGE_PROVIDER_TRANSPORT");
|
|
6529
|
+
}
|
|
6530
|
+
if (kind === "build" && (response.status === 401 || response.status === 403)) {
|
|
6531
|
+
fail("BRIDGE_PROVIDER_AUTH_REQUIRED");
|
|
6532
|
+
}
|
|
6533
|
+
if (response.status !== 200 && response.status !== 201) {
|
|
6534
|
+
fail("BRIDGE_PROVIDER_HTTP", response.status);
|
|
6535
|
+
}
|
|
6536
|
+
};
|
|
6537
|
+
var providerJson = async (request, kind) => {
|
|
6538
|
+
try {
|
|
6539
|
+
providerHttpStatus(request.response, kind);
|
|
6540
|
+
const text = await decodeResponseBody(
|
|
6541
|
+
request.response,
|
|
6542
|
+
request.controlled,
|
|
6543
|
+
request.external
|
|
6544
|
+
);
|
|
6545
|
+
throwIfRequestAborted(request.controlled, request.external);
|
|
6546
|
+
const parsed = parseProviderResponse(text);
|
|
6547
|
+
throwIfRequestAborted(request.controlled, request.external);
|
|
6548
|
+
return parsed;
|
|
6549
|
+
} finally {
|
|
6550
|
+
cancelResponseBody(request.response);
|
|
6551
|
+
request.controlled.cleanup();
|
|
6552
|
+
}
|
|
6553
|
+
};
|
|
6554
|
+
var encodeBase58 = (bytes) => {
|
|
6555
|
+
let zeroes = 0;
|
|
6556
|
+
while (zeroes < bytes.length && bytes[zeroes] === 0) zeroes += 1;
|
|
6557
|
+
if (zeroes === bytes.length) return "1".repeat(zeroes);
|
|
6558
|
+
const digits = [0];
|
|
6559
|
+
for (const byte of bytes) {
|
|
6560
|
+
let carry = byte;
|
|
6561
|
+
for (let index = 0; index < digits.length; index += 1) {
|
|
6562
|
+
const value = (digits[index] ?? 0) * 256 + carry;
|
|
6563
|
+
digits[index] = value % 58;
|
|
6564
|
+
carry = Math.floor(value / 58);
|
|
6565
|
+
}
|
|
6566
|
+
while (carry > 0) {
|
|
6567
|
+
digits.push(carry % 58);
|
|
6568
|
+
carry = Math.floor(carry / 58);
|
|
6569
|
+
}
|
|
6570
|
+
}
|
|
6571
|
+
let result = "1".repeat(zeroes);
|
|
6572
|
+
for (let index = digits.length - 1; index >= 0; index -= 1) {
|
|
6573
|
+
result += BASE58_ALPHABET[digits[index] ?? 0] ?? "";
|
|
6574
|
+
}
|
|
6575
|
+
return result === "" ? "1" : result;
|
|
6576
|
+
};
|
|
6577
|
+
var decodeBase58 = (value, expectedBytes, code) => {
|
|
6578
|
+
const text = requireString(value, code);
|
|
6579
|
+
if (text.length > expectedBytes * 2 || [...text].some((char) => !BASE58_ALPHABET.includes(char))) {
|
|
6580
|
+
fail(code);
|
|
6581
|
+
}
|
|
6582
|
+
const bytes = [0];
|
|
6583
|
+
for (const char of text) {
|
|
6584
|
+
const digit = BASE58_ALPHABET.indexOf(char);
|
|
6585
|
+
let carry = digit;
|
|
6586
|
+
for (let index = 0; index < bytes.length; index += 1) {
|
|
6587
|
+
const current = (bytes[index] ?? 0) * 58 + carry;
|
|
6588
|
+
bytes[index] = current % 256;
|
|
6589
|
+
carry = Math.floor(current / 256);
|
|
6590
|
+
}
|
|
6591
|
+
while (carry > 0) {
|
|
6592
|
+
bytes.push(carry % 256);
|
|
6593
|
+
carry = Math.floor(carry / 256);
|
|
6594
|
+
}
|
|
6595
|
+
}
|
|
6596
|
+
let zeroes = 0;
|
|
6597
|
+
while (zeroes < text.length && text[zeroes] === "1") zeroes += 1;
|
|
6598
|
+
const result = new Uint8Array(zeroes + (bytes.length === 1 && bytes[0] === 0 ? 0 : bytes.length));
|
|
6599
|
+
for (let index = 0; index < bytes.length && !(bytes.length === 1 && bytes[0] === 0); index += 1) {
|
|
6600
|
+
result[result.length - 1 - index] = bytes[index] ?? 0;
|
|
6601
|
+
}
|
|
6602
|
+
if (result.length !== expectedBytes || encodeBase58(result) !== text) fail(code);
|
|
6603
|
+
return result;
|
|
6604
|
+
};
|
|
6605
|
+
var decodeBase64 = (value, code) => {
|
|
6606
|
+
const text = requireString(value, code);
|
|
6607
|
+
if (!BASE64.test(text)) fail(code);
|
|
6608
|
+
let binary;
|
|
6609
|
+
try {
|
|
6610
|
+
binary = globalThis.atob(text);
|
|
6611
|
+
} catch {
|
|
6612
|
+
return fail(code);
|
|
6613
|
+
}
|
|
6614
|
+
const result = Uint8Array.from(binary, (character) => character.charCodeAt(0));
|
|
6615
|
+
let canonical;
|
|
6616
|
+
try {
|
|
6617
|
+
canonical = globalThis.btoa(binary);
|
|
6618
|
+
} catch {
|
|
6619
|
+
return fail(code);
|
|
6620
|
+
}
|
|
6621
|
+
if (canonical !== text) fail(code);
|
|
6622
|
+
return result;
|
|
6623
|
+
};
|
|
6624
|
+
var readBytes = (cursor, count, code) => {
|
|
6625
|
+
if (!Number.isSafeInteger(count) || count < 0 || cursor.index + count > cursor.bytes.length) fail(code);
|
|
6626
|
+
const value = cursor.bytes.slice(cursor.index, cursor.index + count);
|
|
6627
|
+
cursor.index += count;
|
|
6628
|
+
return value;
|
|
6629
|
+
};
|
|
6630
|
+
var readShortVec = (cursor, maximum, code) => {
|
|
6631
|
+
let value = 0;
|
|
6632
|
+
let shift = 0;
|
|
6633
|
+
for (let count = 0; count < 5; count += 1) {
|
|
6634
|
+
const byte = readBytes(cursor, 1, code)[0] ?? 0;
|
|
6635
|
+
const payload = byte & 127;
|
|
6636
|
+
if (shift >= 28 || payload > Math.floor(Number.MAX_SAFE_INTEGER / 2 ** shift)) fail(code);
|
|
6637
|
+
value += payload * 2 ** shift;
|
|
6638
|
+
if ((byte & 128) === 0) {
|
|
6639
|
+
if (count > 0 && payload === 0) fail(code);
|
|
6640
|
+
if (!Number.isSafeInteger(value) || value > maximum) fail(code);
|
|
6641
|
+
return value;
|
|
6642
|
+
}
|
|
6643
|
+
shift += 7;
|
|
6644
|
+
}
|
|
6645
|
+
return fail(code);
|
|
6646
|
+
};
|
|
6647
|
+
var allZero = (bytes) => bytes.every((byte) => byte === 0);
|
|
6648
|
+
var validateSolanaTransaction = (encoded, feePayer) => {
|
|
6649
|
+
const bytes = decodeBase64(encoded, "BRIDGE_BUILD_INVALID");
|
|
6650
|
+
if (bytes.byteLength === 0 || bytes.byteLength > 1232) fail("BRIDGE_BUILD_INVALID");
|
|
6651
|
+
const cursor = { bytes, index: 0 };
|
|
6652
|
+
const signatureCount = readShortVec(cursor, 1, "BRIDGE_BUILD_INVALID");
|
|
6653
|
+
if (signatureCount !== 1 || !allZero(readBytes(cursor, 64, "BRIDGE_BUILD_INVALID"))) {
|
|
6654
|
+
fail("BRIDGE_BUILD_INVALID");
|
|
6655
|
+
}
|
|
6656
|
+
const version = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0];
|
|
6657
|
+
if (version !== 128) fail("BRIDGE_BUILD_INVALID");
|
|
6658
|
+
const requiredSignatures = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
|
|
6659
|
+
const readonlySigned = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
|
|
6660
|
+
const readonlyUnsigned = readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0;
|
|
6661
|
+
if (requiredSignatures !== 1 || readonlySigned !== 0) fail("BRIDGE_BUILD_INVALID");
|
|
6662
|
+
const staticKeyCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
|
|
6663
|
+
if (staticKeyCount === 0 || readonlyUnsigned >= staticKeyCount) fail("BRIDGE_BUILD_INVALID");
|
|
6664
|
+
const staticKeys = readBytes(cursor, staticKeyCount * 32, "BRIDGE_BUILD_INVALID");
|
|
6665
|
+
const payerBytes = decodeBase58(feePayer, 32, "BRIDGE_BUILD_INVALID");
|
|
6666
|
+
if (!staticKeys.slice(0, 32).every((byte, index) => byte === payerBytes[index])) fail("BRIDGE_BUILD_INVALID");
|
|
6667
|
+
readBytes(cursor, 32, "BRIDGE_BUILD_INVALID");
|
|
6668
|
+
const instructionCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
|
|
6669
|
+
let largestAccountIndex = -1;
|
|
6670
|
+
for (let instruction = 0; instruction < instructionCount; instruction += 1) {
|
|
6671
|
+
largestAccountIndex = Math.max(
|
|
6672
|
+
largestAccountIndex,
|
|
6673
|
+
readBytes(cursor, 1, "BRIDGE_BUILD_INVALID")[0] ?? 0
|
|
6674
|
+
);
|
|
6675
|
+
const accountCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
|
|
6676
|
+
const accountIndices = readBytes(cursor, accountCount, "BRIDGE_BUILD_INVALID");
|
|
6677
|
+
for (const index of accountIndices) largestAccountIndex = Math.max(largestAccountIndex, index);
|
|
6678
|
+
const dataLength = readShortVec(cursor, 1024, "BRIDGE_BUILD_INVALID");
|
|
6679
|
+
readBytes(cursor, dataLength, "BRIDGE_BUILD_INVALID");
|
|
6680
|
+
}
|
|
6681
|
+
const lookupCount = readShortVec(cursor, 32, "BRIDGE_BUILD_INVALID");
|
|
6682
|
+
let loadedAddressCount = 0;
|
|
6683
|
+
for (let lookup = 0; lookup < lookupCount; lookup += 1) {
|
|
6684
|
+
readBytes(cursor, 32, "BRIDGE_BUILD_INVALID");
|
|
6685
|
+
const writableCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
|
|
6686
|
+
readBytes(cursor, writableCount, "BRIDGE_BUILD_INVALID");
|
|
6687
|
+
const readonlyCount = readShortVec(cursor, 64, "BRIDGE_BUILD_INVALID");
|
|
6688
|
+
readBytes(cursor, readonlyCount, "BRIDGE_BUILD_INVALID");
|
|
6689
|
+
loadedAddressCount += writableCount + readonlyCount;
|
|
6690
|
+
if (loadedAddressCount > 256) fail("BRIDGE_BUILD_INVALID");
|
|
6691
|
+
}
|
|
6692
|
+
if (largestAccountIndex >= staticKeyCount + loadedAddressCount || cursor.index !== bytes.length) {
|
|
6693
|
+
fail("BRIDGE_BUILD_INVALID");
|
|
6694
|
+
}
|
|
6695
|
+
return requireString(encoded, "BRIDGE_BUILD_INVALID");
|
|
6696
|
+
};
|
|
6697
|
+
var providerInvalid = () => fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6698
|
+
var requiredNode = (node, key) => {
|
|
6699
|
+
const child = objectEntry(node, key);
|
|
6700
|
+
if (!child) providerInvalid();
|
|
6701
|
+
return child;
|
|
6702
|
+
};
|
|
6703
|
+
var providerString = (node, key, allowEmpty = false) => {
|
|
6704
|
+
const value = requiredNode(node, key).value;
|
|
6705
|
+
if (typeof value !== "string" || !allowEmpty && value.length === 0) {
|
|
6706
|
+
providerInvalid();
|
|
6707
|
+
}
|
|
6708
|
+
return value;
|
|
6709
|
+
};
|
|
6710
|
+
var providerBoolean = (node, key) => {
|
|
6711
|
+
const value = requiredNode(node, key).value;
|
|
6712
|
+
if (typeof value !== "boolean") providerInvalid();
|
|
6713
|
+
return value;
|
|
6714
|
+
};
|
|
6715
|
+
var providerNumber = (node, key) => {
|
|
6716
|
+
const value = requiredNode(node, key).value;
|
|
6717
|
+
if (typeof value !== "number" || !Number.isFinite(value)) providerInvalid();
|
|
6718
|
+
return value;
|
|
6719
|
+
};
|
|
6720
|
+
var providerInteger = (node, key) => {
|
|
6721
|
+
const value = providerNumber(node, key);
|
|
6722
|
+
if (!Number.isSafeInteger(value)) providerInvalid();
|
|
6723
|
+
return value;
|
|
6724
|
+
};
|
|
6725
|
+
var providerAddress = (node, key, expected) => {
|
|
6726
|
+
const value = providerString(node, key);
|
|
6727
|
+
if (!providerAddressEquals(value, expected)) providerInvalid();
|
|
6728
|
+
return EVM_ADDRESS2.test(value) ? value.toLowerCase() : value;
|
|
6729
|
+
};
|
|
6730
|
+
var providerUint64 = (node, key, positive) => {
|
|
6731
|
+
const value = providerString(node, key);
|
|
6732
|
+
try {
|
|
6733
|
+
return positive ? normalizePositiveUint64(value, "BRIDGE_PROVIDER_INVALID_RESPONSE") : normalizeCanonicalUint64(value, "BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
6734
|
+
} catch (error) {
|
|
6735
|
+
if (error instanceof BridgeError) throw error;
|
|
6736
|
+
return providerInvalid();
|
|
6737
|
+
}
|
|
6738
|
+
};
|
|
6739
|
+
var providerToken = (node, expected) => {
|
|
6740
|
+
if (!isRecord4(node.value)) providerInvalid();
|
|
6741
|
+
const contract = providerString(node, "contract");
|
|
6742
|
+
if (!providerAddressEquals(contract, expected.address)) providerInvalid();
|
|
6743
|
+
const mint = providerString(node, "mint", true);
|
|
6744
|
+
if (mint !== expected.mint) providerInvalid();
|
|
6745
|
+
const realOrigin = providerString(node, "realOriginContractAddress");
|
|
6746
|
+
if (!providerAddressEquals(realOrigin, expected.address)) providerInvalid();
|
|
6747
|
+
if (providerString(node, "name") !== "EuroC") providerInvalid();
|
|
6748
|
+
if (providerString(node, "standard") !== expected.standard) providerInvalid();
|
|
6749
|
+
if (providerInteger(node, "chainId") !== expected.chainId) providerInvalid();
|
|
6750
|
+
if (providerInteger(node, "wChainId") !== expected.wormholeChainId) providerInvalid();
|
|
6751
|
+
if (providerInteger(node, "realOriginChainId") !== expected.wormholeChainId) providerInvalid();
|
|
6752
|
+
if (providerInteger(node, "decimals") !== 6) providerInvalid();
|
|
6753
|
+
};
|
|
6754
|
+
var quoteProviderStandard = (facts) => facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl";
|
|
6755
|
+
var ensureQuoteDeadline = (deadlineValue, margin) => {
|
|
6756
|
+
const now = BigInt(Math.floor(Date.now() / 1e3));
|
|
6757
|
+
if (!Number.isSafeInteger(Number(now)) || deadlineValue < now + BigInt(margin)) {
|
|
6758
|
+
fail("BRIDGE_QUOTE_EXPIRED");
|
|
6759
|
+
}
|
|
6760
|
+
};
|
|
6761
|
+
var validateProviderQuote = (node, text, request, facts, config) => {
|
|
6762
|
+
if (!isRecord4(node.value)) providerInvalid();
|
|
6763
|
+
const raw = text.slice(node.start, node.end);
|
|
6764
|
+
if (byteLength(raw) > MAX_RAW_QUOTE_BYTES) providerInvalid();
|
|
6765
|
+
if (providerString(node, "type") !== "SWIFT") providerInvalid();
|
|
6766
|
+
if (providerString(node, "swiftVersion") !== "V2") providerInvalid();
|
|
6767
|
+
if (providerBoolean(node, "gasless")) providerInvalid();
|
|
6768
|
+
if (providerString(node, "fromChain") !== facts.sourceName) providerInvalid();
|
|
6769
|
+
if (providerString(node, "toChain") !== facts.destinationName) providerInvalid();
|
|
6770
|
+
if (providerInteger(node, "slippageBps") !== request.slippageBps) providerInvalid();
|
|
6771
|
+
if (providerBoolean(node, "onlyBridging")) providerInvalid();
|
|
6772
|
+
const effectiveAmount = providerUint64(node, "effectiveAmountIn64", true);
|
|
6773
|
+
if (effectiveAmount.source !== request.amountIn) providerInvalid();
|
|
6774
|
+
const expectedAmountOut = providerUint64(node, "expectedAmountOutBaseUnits", true);
|
|
6775
|
+
const minimumAmountOut = providerUint64(node, "minAmountOutBaseUnits", true);
|
|
6776
|
+
const minimumReceived = providerUint64(node, "minReceivedBaseUnits", true);
|
|
6777
|
+
if (minimumAmountOut.value > expectedAmountOut.value || minimumReceived.value > minimumAmountOut.value) {
|
|
6778
|
+
providerInvalid();
|
|
6779
|
+
}
|
|
6780
|
+
const deadline = providerUint64(node, "deadline64", true);
|
|
6781
|
+
ensureQuoteDeadline(deadline.value, config.minimumQuoteValiditySeconds);
|
|
6782
|
+
const sourceToken = requiredNode(node, "fromToken");
|
|
6783
|
+
const destinationToken = requiredNode(node, "toToken");
|
|
6784
|
+
providerToken(sourceToken, {
|
|
6785
|
+
address: facts.sourceTokenAddress,
|
|
6786
|
+
standard: facts.sourceChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
|
|
6787
|
+
chainId: facts.sourceProviderChainId,
|
|
6788
|
+
wormholeChainId: facts.sourceWormholeChainId,
|
|
6789
|
+
mint: facts.sourceEurcMint
|
|
6790
|
+
});
|
|
6791
|
+
providerToken(destinationToken, {
|
|
6792
|
+
address: facts.destinationTokenAddress,
|
|
6793
|
+
standard: facts.destinationChainId === ETHEREUM_CHAIN_ID ? "erc20" : "spl",
|
|
6794
|
+
chainId: facts.destinationProviderChainId,
|
|
6795
|
+
wormholeChainId: facts.destinationWormholeChainId,
|
|
6796
|
+
mint: facts.destinationEurcMint
|
|
6797
|
+
});
|
|
6798
|
+
const sourceUsdcStandard = quoteProviderStandard(facts);
|
|
6799
|
+
if (providerAddress(node, "swiftInputContract", facts.sourceUsdcAddress) !== facts.sourceUsdcAddress) {
|
|
6800
|
+
providerInvalid();
|
|
6801
|
+
}
|
|
6802
|
+
if (providerString(node, "swiftInputContractStandard") !== sourceUsdcStandard) providerInvalid();
|
|
6803
|
+
if (providerInteger(node, "swiftInputDecimals") !== 6) providerInvalid();
|
|
6804
|
+
if (providerAddress(node, "swiftMayanContract", facts.swiftContract) !== facts.swiftContract) {
|
|
6805
|
+
providerInvalid();
|
|
6806
|
+
}
|
|
6807
|
+
const middleNode = requiredNode(node, "minMiddleAmount");
|
|
6808
|
+
if (middleNode.rawNumber === void 0 || typeof middleNode.value !== "number" || !Number.isFinite(middleNode.value) || middleNode.value <= 0) {
|
|
6809
|
+
providerInvalid();
|
|
6810
|
+
}
|
|
6811
|
+
let routerAddress;
|
|
6812
|
+
let routerKind;
|
|
6813
|
+
if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
|
|
6814
|
+
routerAddress = normalizeEvmAddress3(
|
|
6815
|
+
providerString(node, "evmSwapRouterAddress"),
|
|
6816
|
+
"BRIDGE_PROVIDER_INVALID_RESPONSE"
|
|
6817
|
+
);
|
|
6818
|
+
routerKind = "provider-selected-evm";
|
|
6819
|
+
} else {
|
|
6820
|
+
routerAddress = SOLANA_JUPITER_V6;
|
|
6821
|
+
routerKind = "jupiter-v6";
|
|
6822
|
+
const evmRouter = objectValue5(node, "evmSwapRouterAddress");
|
|
6823
|
+
if (evmRouter !== void 0 && evmRouter !== null) providerInvalid();
|
|
6824
|
+
}
|
|
6825
|
+
const quoteId = providerString(node, "quoteId");
|
|
6826
|
+
if (!/^0x[0-9a-fA-F]{32}$/u.test(quoteId)) providerInvalid();
|
|
6827
|
+
const signature = providerString(node, "signature");
|
|
6828
|
+
if (!EVM_SIGNATURE.test(signature)) providerInvalid();
|
|
6829
|
+
const dependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
|
|
6830
|
+
const quote = {
|
|
6831
|
+
quoteKind: "mayan-swift-v2",
|
|
6832
|
+
providerId: "mayan-swift-v2",
|
|
6833
|
+
sourceChainId: request.sourceChainId,
|
|
6834
|
+
destinationChainId: request.destinationChainId,
|
|
6835
|
+
sourceTokenDeploymentId: request.sourceTokenDeploymentId,
|
|
6836
|
+
destinationTokenDeploymentId: request.destinationTokenDeploymentId,
|
|
6837
|
+
amountIn: effectiveAmount.source,
|
|
6838
|
+
expectedAmountOut: expectedAmountOut.source,
|
|
6839
|
+
minimumAmountOut: minimumAmountOut.source,
|
|
6840
|
+
minimumReceived: minimumReceived.source,
|
|
6841
|
+
deadline: deadline.source,
|
|
6842
|
+
slippageBps: request.slippageBps,
|
|
6843
|
+
quoteId: quoteId.toLowerCase(),
|
|
6844
|
+
providerSignature: signature.toLowerCase(),
|
|
6845
|
+
sourceSwap: {
|
|
6846
|
+
required: true,
|
|
6847
|
+
inputTokenDeploymentId: facts.sourceTokenDeploymentId,
|
|
6848
|
+
intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
|
|
6849
|
+
intermediateTokenAddress: facts.sourceUsdcAddress,
|
|
6850
|
+
intermediateTokenStandard: sourceUsdcStandard,
|
|
6851
|
+
intermediateTokenDecimals: 6,
|
|
6852
|
+
providerMinimumAmount: middleNode.rawNumber,
|
|
6853
|
+
routerKind,
|
|
6854
|
+
routerAddress
|
|
6855
|
+
},
|
|
6856
|
+
dependencies,
|
|
6857
|
+
quoteVerification: "provider-signed-not-locally-verified",
|
|
6858
|
+
rawSignedQuoteJson: raw
|
|
6859
|
+
};
|
|
6860
|
+
return {
|
|
6861
|
+
quote: deepFreeze6(quote),
|
|
6862
|
+
rawNode: node,
|
|
6863
|
+
deadlineValue: deadline.value
|
|
6864
|
+
};
|
|
6865
|
+
};
|
|
6866
|
+
var QUOTE_KEYS = [
|
|
6867
|
+
"quoteKind",
|
|
6868
|
+
"providerId",
|
|
6869
|
+
"sourceChainId",
|
|
6870
|
+
"destinationChainId",
|
|
6871
|
+
"sourceTokenDeploymentId",
|
|
6872
|
+
"destinationTokenDeploymentId",
|
|
6873
|
+
"amountIn",
|
|
6874
|
+
"expectedAmountOut",
|
|
6875
|
+
"minimumAmountOut",
|
|
6876
|
+
"minimumReceived",
|
|
6877
|
+
"deadline",
|
|
6878
|
+
"slippageBps",
|
|
6879
|
+
"quoteId",
|
|
6880
|
+
"providerSignature",
|
|
6881
|
+
"sourceSwap",
|
|
6882
|
+
"dependencies",
|
|
6883
|
+
"quoteVerification",
|
|
6884
|
+
"rawSignedQuoteJson"
|
|
6885
|
+
];
|
|
6886
|
+
var SOURCE_SWAP_KEYS = [
|
|
6887
|
+
"required",
|
|
6888
|
+
"inputTokenDeploymentId",
|
|
6889
|
+
"intermediateTokenDeploymentId",
|
|
6890
|
+
"intermediateTokenAddress",
|
|
6891
|
+
"intermediateTokenStandard",
|
|
6892
|
+
"intermediateTokenDecimals",
|
|
6893
|
+
"providerMinimumAmount",
|
|
6894
|
+
"routerKind",
|
|
6895
|
+
"routerAddress"
|
|
6896
|
+
];
|
|
6897
|
+
var exactObjectKeys = (value, expected, code) => {
|
|
6898
|
+
const actual = Object.keys(value).sort();
|
|
6899
|
+
const wanted = [...expected].sort();
|
|
6900
|
+
if (actual.length !== wanted.length || actual.some((key, index) => key !== wanted[index])) {
|
|
6901
|
+
fail(code);
|
|
6902
|
+
}
|
|
6903
|
+
};
|
|
6904
|
+
var stableJson = (value) => {
|
|
6905
|
+
if (Array.isArray(value)) return `[${value.map(stableJson).join(",")}]`;
|
|
6906
|
+
if (isRecord4(value)) {
|
|
6907
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
6908
|
+
}
|
|
6909
|
+
return JSON.stringify(value);
|
|
6910
|
+
};
|
|
6911
|
+
var cloneQuote = (quote) => {
|
|
6912
|
+
try {
|
|
6913
|
+
return JSON.parse(JSON.stringify(quote));
|
|
6914
|
+
} catch {
|
|
6915
|
+
return fail("BRIDGE_INVALID_ARGUMENT");
|
|
6916
|
+
}
|
|
6917
|
+
};
|
|
6918
|
+
var validateNormalizedQuoteShape = (quote, code) => {
|
|
6919
|
+
const value = requireRecord(quote, code);
|
|
6920
|
+
exactObjectKeys(value, QUOTE_KEYS, code);
|
|
6921
|
+
if (value.quoteKind !== "mayan-swift-v2" || value.providerId !== "mayan-swift-v2") fail(code);
|
|
6922
|
+
const sourceChainId = requireString(value.sourceChainId, code);
|
|
6923
|
+
const destinationChainId = requireString(value.destinationChainId, code);
|
|
6924
|
+
const facts = directionFacts(sourceChainId, destinationChainId);
|
|
6925
|
+
if (value.sourceTokenDeploymentId !== facts.sourceTokenDeploymentId || value.destinationTokenDeploymentId !== facts.destinationTokenDeploymentId) fail(code);
|
|
6926
|
+
const amountIn = normalizePositiveUint64(value.amountIn, code);
|
|
6927
|
+
const expectedAmountOut = normalizePositiveUint64(value.expectedAmountOut, code);
|
|
6928
|
+
const minimumAmountOut = normalizePositiveUint64(value.minimumAmountOut, code);
|
|
6929
|
+
const minimumReceived = normalizePositiveUint64(value.minimumReceived, code);
|
|
6930
|
+
if (minimumAmountOut.value > expectedAmountOut.value || minimumReceived.value > minimumAmountOut.value) fail(code);
|
|
6931
|
+
const deadline = normalizePositiveUint64(value.deadline, code);
|
|
6932
|
+
const slippageBps = normalizeSlippage(value.slippageBps, code);
|
|
6933
|
+
if (value.quoteVerification !== "provider-signed-not-locally-verified") fail(code);
|
|
6934
|
+
const quoteId = requireString(value.quoteId, code);
|
|
6935
|
+
if (!/^0x[0-9a-fA-F]{32}$/u.test(quoteId)) fail(code);
|
|
6936
|
+
const signature = requireString(value.providerSignature, code);
|
|
6937
|
+
if (!EVM_SIGNATURE.test(signature)) fail(code);
|
|
6938
|
+
const sourceSwap = requireRecord(value.sourceSwap, code);
|
|
6939
|
+
exactObjectKeys(sourceSwap, SOURCE_SWAP_KEYS, code);
|
|
6940
|
+
if (sourceSwap.required !== true) fail(code);
|
|
6941
|
+
if (sourceSwap.inputTokenDeploymentId !== facts.sourceTokenDeploymentId || sourceSwap.intermediateTokenDeploymentId !== facts.sourceUsdcDeploymentId) fail(code);
|
|
6942
|
+
if (sourceSwap.intermediateTokenAddress !== facts.sourceUsdcAddress) fail(code);
|
|
6943
|
+
const providerStandard = quoteProviderStandard(facts);
|
|
6944
|
+
if (sourceSwap.intermediateTokenStandard !== providerStandard || sourceSwap.intermediateTokenDecimals !== 6) fail(code);
|
|
6945
|
+
const providerMinimumAmount = sourceSwap.providerMinimumAmount;
|
|
6946
|
+
if (typeof providerMinimumAmount !== "string" || providerMinimumAmount.length === 0) fail(code);
|
|
6947
|
+
let normalizedRouterAddress;
|
|
6948
|
+
let normalizedRouterKind;
|
|
6949
|
+
if (facts.sourceChainId === ETHEREUM_CHAIN_ID) {
|
|
6950
|
+
const routerAddress = sourceSwap.routerAddress;
|
|
6951
|
+
if (sourceSwap.routerKind !== "provider-selected-evm" || typeof routerAddress !== "string" || !EVM_ADDRESS2.test(routerAddress) || /^0x0{40}$/iu.test(routerAddress)) return fail(code);
|
|
6952
|
+
normalizedRouterAddress = routerAddress.toLowerCase();
|
|
6953
|
+
normalizedRouterKind = "provider-selected-evm";
|
|
6954
|
+
} else if (sourceSwap.routerKind !== "jupiter-v6" || sourceSwap.routerAddress !== SOLANA_JUPITER_V6) {
|
|
6955
|
+
return fail(code);
|
|
6956
|
+
} else {
|
|
6957
|
+
normalizedRouterAddress = SOLANA_JUPITER_V6;
|
|
6958
|
+
normalizedRouterKind = "jupiter-v6";
|
|
6959
|
+
}
|
|
6960
|
+
if (!Array.isArray(value.dependencies)) fail(code);
|
|
6961
|
+
const wantedDependencies = facts.sourceChainId === SOLANA_CHAIN_ID ? [...DEPENDENCIES, "jupiter-v6-source-swap"] : [...DEPENDENCIES];
|
|
6962
|
+
if (stableJson(value.dependencies) !== stableJson(wantedDependencies)) fail(code);
|
|
6963
|
+
const rawSignedQuoteJson = requireString(value.rawSignedQuoteJson, code);
|
|
6964
|
+
if (byteLength(rawSignedQuoteJson) > MAX_RAW_QUOTE_BYTES) fail(code);
|
|
6965
|
+
return {
|
|
6966
|
+
quoteKind: "mayan-swift-v2",
|
|
6967
|
+
providerId: "mayan-swift-v2",
|
|
6968
|
+
sourceChainId,
|
|
6969
|
+
destinationChainId,
|
|
6970
|
+
sourceTokenDeploymentId: facts.sourceTokenDeploymentId,
|
|
6971
|
+
destinationTokenDeploymentId: facts.destinationTokenDeploymentId,
|
|
6972
|
+
amountIn: amountIn.source,
|
|
6973
|
+
expectedAmountOut: expectedAmountOut.source,
|
|
6974
|
+
minimumAmountOut: minimumAmountOut.source,
|
|
6975
|
+
minimumReceived: minimumReceived.source,
|
|
6976
|
+
deadline: deadline.source,
|
|
6977
|
+
slippageBps,
|
|
6978
|
+
quoteId: quoteId.toLowerCase(),
|
|
6979
|
+
providerSignature: signature.toLowerCase(),
|
|
6980
|
+
sourceSwap: {
|
|
6981
|
+
required: true,
|
|
6982
|
+
inputTokenDeploymentId: facts.sourceTokenDeploymentId,
|
|
6983
|
+
intermediateTokenDeploymentId: facts.sourceUsdcDeploymentId,
|
|
6984
|
+
intermediateTokenAddress: facts.sourceUsdcAddress,
|
|
6985
|
+
intermediateTokenStandard: providerStandard,
|
|
6986
|
+
intermediateTokenDecimals: 6,
|
|
6987
|
+
providerMinimumAmount,
|
|
6988
|
+
routerKind: normalizedRouterKind,
|
|
6989
|
+
routerAddress: normalizedRouterAddress
|
|
6990
|
+
},
|
|
6991
|
+
dependencies: wantedDependencies,
|
|
6992
|
+
quoteVerification: "provider-signed-not-locally-verified",
|
|
6993
|
+
rawSignedQuoteJson
|
|
6994
|
+
};
|
|
6995
|
+
};
|
|
6996
|
+
var quoteRequestBody = (route) => JSON.stringify({
|
|
6997
|
+
fromToken: route.facts.sourceTokenAddress,
|
|
6998
|
+
fromChain: route.facts.sourceName,
|
|
6999
|
+
toToken: route.facts.destinationTokenAddress,
|
|
7000
|
+
toChain: route.facts.destinationName,
|
|
7001
|
+
amountIn64: route.request.amountIn,
|
|
7002
|
+
slippageBps: route.request.slippageBps,
|
|
7003
|
+
swift: true,
|
|
7004
|
+
mctp: false,
|
|
7005
|
+
fastMctp: false,
|
|
7006
|
+
wormhole: false,
|
|
7007
|
+
monoChain: false,
|
|
7008
|
+
gasless: false,
|
|
7009
|
+
fullList: true,
|
|
7010
|
+
guaranteedOutput: true,
|
|
7011
|
+
gasDrop: 0
|
|
7012
|
+
});
|
|
7013
|
+
var quoteFromResponse = (response, request, facts, config) => {
|
|
7014
|
+
if (!isRecord4(response.root.value) || response.root.objectEntries === void 0) {
|
|
7015
|
+
providerInvalid();
|
|
7016
|
+
}
|
|
7017
|
+
if (objectValue5(response.root, "success") !== true) providerInvalid();
|
|
7018
|
+
const quotesNode = requiredNode(response.root, "quotes");
|
|
7019
|
+
const quoteNodes = quotesNode.arrayItems;
|
|
7020
|
+
if (!quoteNodes || quoteNodes.length > MAX_QUOTES) return providerInvalid();
|
|
7021
|
+
const selected = [];
|
|
7022
|
+
for (const quoteNode of quoteNodes) {
|
|
7023
|
+
if (!isRecord4(quoteNode.value)) continue;
|
|
7024
|
+
if (quoteNode.value.type !== "SWIFT" || quoteNode.value.swiftVersion !== "V2" || quoteNode.value.gasless !== false) continue;
|
|
7025
|
+
const validated = validateProviderQuote(
|
|
7026
|
+
quoteNode,
|
|
7027
|
+
response.text,
|
|
7028
|
+
request,
|
|
7029
|
+
facts,
|
|
7030
|
+
config
|
|
7031
|
+
);
|
|
7032
|
+
selected.push(validated.quote);
|
|
7033
|
+
}
|
|
7034
|
+
if (selected.length === 0) fail("BRIDGE_QUOTE_UNAVAILABLE");
|
|
7035
|
+
for (const quote of selected) {
|
|
7036
|
+
ensureQuoteDeadline(
|
|
7037
|
+
normalizePositiveUint64(quote.deadline, "BRIDGE_PROVIDER_INVALID_RESPONSE").value,
|
|
7038
|
+
config.minimumQuoteValiditySeconds
|
|
7039
|
+
);
|
|
7040
|
+
}
|
|
7041
|
+
return deepFreeze6(selected);
|
|
7042
|
+
};
|
|
7043
|
+
var buildRequestSnapshot = (value) => {
|
|
7044
|
+
const request = requireRecord(value, "BRIDGE_INVALID_ARGUMENT");
|
|
7045
|
+
const allowed = /* @__PURE__ */ new Set(["quote", "swapperAddress", "destinationAddress", "refundAddress"]);
|
|
7046
|
+
if (Object.keys(request).some((key) => !allowed.has(key))) fail("BRIDGE_INVALID_ARGUMENT");
|
|
7047
|
+
if (!Object.hasOwn(request, "quote") || !Object.hasOwn(request, "swapperAddress") || !Object.hasOwn(request, "destinationAddress")) {
|
|
7048
|
+
fail("BRIDGE_INVALID_ARGUMENT");
|
|
7049
|
+
}
|
|
7050
|
+
const rawQuote = request.quote;
|
|
7051
|
+
if (!isRecord4(rawQuote)) fail("BRIDGE_INVALID_ARGUMENT");
|
|
7052
|
+
let quote;
|
|
7053
|
+
try {
|
|
7054
|
+
quote = cloneQuote(rawQuote);
|
|
7055
|
+
} catch {
|
|
7056
|
+
return fail("BRIDGE_INVALID_ARGUMENT");
|
|
7057
|
+
}
|
|
7058
|
+
return {
|
|
7059
|
+
quote,
|
|
7060
|
+
swapperAddress: request.swapperAddress,
|
|
7061
|
+
destinationAddress: request.destinationAddress,
|
|
7062
|
+
refundAddress: request.refundAddress
|
|
7063
|
+
};
|
|
7064
|
+
};
|
|
7065
|
+
var normalizeChainAddress = (value, chainId, code) => {
|
|
7066
|
+
if (chainId === ETHEREUM_CHAIN_ID) return normalizeEvmAddress3(value, code);
|
|
7067
|
+
const address = requireString(value, code);
|
|
7068
|
+
decodeBase58(address, 32, code);
|
|
7069
|
+
return address;
|
|
7070
|
+
};
|
|
7071
|
+
var isCanonicalSolanaAddress = (value) => {
|
|
7072
|
+
if (typeof value !== "string") return false;
|
|
7073
|
+
try {
|
|
7074
|
+
decodeBase58(value, 32, "BRIDGE_INVALID_ARGUMENT");
|
|
7075
|
+
return true;
|
|
7076
|
+
} catch {
|
|
7077
|
+
return false;
|
|
7078
|
+
}
|
|
7079
|
+
};
|
|
7080
|
+
var rejectAddressFromOtherChain = (value, expectedChainId) => {
|
|
7081
|
+
const isEvm = typeof value === "string" && EVM_ADDRESS2.test(value) && !/^0x0{40}$/iu.test(value);
|
|
7082
|
+
const isSolana = isCanonicalSolanaAddress(value);
|
|
7083
|
+
if (expectedChainId === ETHEREUM_CHAIN_ID && isSolana || expectedChainId === SOLANA_CHAIN_ID && isEvm) {
|
|
7084
|
+
fail("BRIDGE_QUOTE_MISMATCH");
|
|
7085
|
+
}
|
|
7086
|
+
};
|
|
7087
|
+
var normalizeDestinationAddress = (value, destinationChainId) => {
|
|
7088
|
+
return normalizeChainAddress(value, destinationChainId, "BRIDGE_INVALID_ARGUMENT");
|
|
7089
|
+
};
|
|
7090
|
+
var buildRouteFromQuote = (quote) => {
|
|
7091
|
+
let normalizedQuote;
|
|
7092
|
+
try {
|
|
7093
|
+
normalizedQuote = validateNormalizedQuoteShape(quote, "BRIDGE_QUOTE_MISMATCH");
|
|
7094
|
+
} catch (error) {
|
|
7095
|
+
if (error instanceof BridgeError) throw error;
|
|
7096
|
+
return fail("BRIDGE_QUOTE_MISMATCH");
|
|
7097
|
+
}
|
|
7098
|
+
if (stableJson(quote) !== stableJson(normalizedQuote)) fail("BRIDGE_QUOTE_MISMATCH");
|
|
7099
|
+
const route = validateBridgeRoute({
|
|
7100
|
+
sourceChainId: normalizedQuote.sourceChainId,
|
|
7101
|
+
destinationChainId: normalizedQuote.destinationChainId,
|
|
7102
|
+
sourceTokenDeploymentId: normalizedQuote.sourceTokenDeploymentId,
|
|
7103
|
+
destinationTokenDeploymentId: normalizedQuote.destinationTokenDeploymentId,
|
|
7104
|
+
amountIn: normalizedQuote.amountIn,
|
|
7105
|
+
slippageBps: normalizedQuote.slippageBps
|
|
7106
|
+
});
|
|
7107
|
+
return { route, normalizedQuote };
|
|
7108
|
+
};
|
|
7109
|
+
var validateRawQuoteForBuild = (quote, route, config) => {
|
|
7110
|
+
let response;
|
|
7111
|
+
try {
|
|
7112
|
+
response = parseProviderResponse(quote.rawSignedQuoteJson);
|
|
7113
|
+
} catch (error) {
|
|
7114
|
+
if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") throw error;
|
|
7115
|
+
return fail("BRIDGE_QUOTE_MISMATCH");
|
|
7116
|
+
}
|
|
7117
|
+
if (!isRecord4(response.root.value) || response.root.start !== 0 || response.root.end !== response.text.length) {
|
|
7118
|
+
fail("BRIDGE_QUOTE_MISMATCH");
|
|
7119
|
+
}
|
|
7120
|
+
let rebuilt;
|
|
7121
|
+
try {
|
|
7122
|
+
rebuilt = validateProviderQuote(
|
|
7123
|
+
response.root,
|
|
7124
|
+
response.text,
|
|
7125
|
+
route.request,
|
|
7126
|
+
route.facts,
|
|
7127
|
+
config
|
|
7128
|
+
);
|
|
7129
|
+
} catch (error) {
|
|
7130
|
+
if (error instanceof BridgeError && error.code === "BRIDGE_QUOTE_EXPIRED") throw error;
|
|
7131
|
+
return fail("BRIDGE_QUOTE_MISMATCH");
|
|
7132
|
+
}
|
|
7133
|
+
if (stableJson(rebuilt.quote) !== stableJson(quote)) fail("BRIDGE_QUOTE_MISMATCH");
|
|
7134
|
+
return deepFreeze6(quote);
|
|
7135
|
+
};
|
|
7136
|
+
var numericZero = (value) => {
|
|
7137
|
+
if (typeof value === "number") return Number.isFinite(value) && value === 0;
|
|
7138
|
+
if (typeof value !== "string") return false;
|
|
7139
|
+
if (value === "0") return true;
|
|
7140
|
+
return /^0x0+$/iu.test(value);
|
|
7141
|
+
};
|
|
7142
|
+
var validateEvmBuildResult = (wrapper, swapperAddress) => {
|
|
7143
|
+
if (providerString(wrapper, "chainCategory") !== "evm") providerInvalid();
|
|
7144
|
+
if (providerString(wrapper, "quoteType") !== "SWIFT") providerInvalid();
|
|
7145
|
+
if (providerBoolean(wrapper, "gasless")) providerInvalid();
|
|
7146
|
+
const transaction = requiredNode(wrapper, "transaction");
|
|
7147
|
+
if (!isRecord4(transaction.value)) providerInvalid();
|
|
7148
|
+
const to = providerString(transaction, "to");
|
|
7149
|
+
if (!providerAddressEquals(to, ETHEREUM_FORWARDER)) providerInvalid();
|
|
7150
|
+
const chainId = providerInteger(transaction, "chainId");
|
|
7151
|
+
if (chainId !== ETHEREUM_PROVIDER_CHAIN_ID) providerInvalid();
|
|
7152
|
+
if (!numericZero(objectValue5(transaction, "value"))) providerInvalid();
|
|
7153
|
+
const data = providerString(transaction, "data").toLowerCase();
|
|
7154
|
+
if (!HEX_BYTES2.test(data) || data.length % 2 !== 0 || !data.startsWith(ETHEREUM_FORWARDER_SELECTOR) || data.length < 2 + 8 + 13 * 64) {
|
|
7155
|
+
providerInvalid();
|
|
7156
|
+
}
|
|
7157
|
+
return {
|
|
7158
|
+
kind: "evm-unsigned-transaction",
|
|
7159
|
+
chainId: "eip155:1",
|
|
7160
|
+
from: swapperAddress,
|
|
7161
|
+
to: ETHEREUM_FORWARDER,
|
|
7162
|
+
data,
|
|
7163
|
+
value: "0"
|
|
7164
|
+
};
|
|
7165
|
+
};
|
|
7166
|
+
var validateSolanaBuildResult = (wrapper, swapperAddress) => {
|
|
7167
|
+
if (providerString(wrapper, "chainCategory") !== "svm") providerInvalid();
|
|
7168
|
+
if (providerString(wrapper, "quoteType") !== "SWIFT") providerInvalid();
|
|
7169
|
+
const gaslessNode = objectEntry(wrapper, "gasless");
|
|
7170
|
+
if (gaslessNode !== void 0 && gaslessNode.value !== false) providerInvalid();
|
|
7171
|
+
const transaction = requiredNode(wrapper, "transaction");
|
|
7172
|
+
const encoded = validateSolanaTransaction(transaction.value, swapperAddress);
|
|
7173
|
+
return {
|
|
7174
|
+
kind: "solana-v0-unsigned-transaction",
|
|
7175
|
+
chainId: SOLANA_CHAIN_ID,
|
|
7176
|
+
feePayer: swapperAddress,
|
|
7177
|
+
transactionBase64: encoded
|
|
7178
|
+
};
|
|
7179
|
+
};
|
|
7180
|
+
var validateBuildResponse = (response, quote, facts, swapperAddress) => {
|
|
7181
|
+
if (!isRecord4(response.root.value) || objectValue5(response.root, "success") !== true) {
|
|
7182
|
+
fail("BRIDGE_BUILD_INVALID");
|
|
7183
|
+
}
|
|
7184
|
+
const wrapper = requiredNode(response.root, "transaction");
|
|
7185
|
+
if (!isRecord4(wrapper.value)) fail("BRIDGE_BUILD_INVALID");
|
|
7186
|
+
const signers = objectValue5(wrapper, "signers");
|
|
7187
|
+
if (signers !== void 0 && signers !== null && (!Array.isArray(signers) || signers.length !== 0)) {
|
|
7188
|
+
fail("BRIDGE_BUILD_INVALID");
|
|
7189
|
+
}
|
|
7190
|
+
const swapMessageV0Params = objectValue5(wrapper, "swapMessageV0Params");
|
|
7191
|
+
if (swapMessageV0Params !== void 0 && swapMessageV0Params !== null) {
|
|
7192
|
+
fail("BRIDGE_BUILD_INVALID");
|
|
7193
|
+
}
|
|
7194
|
+
let transaction;
|
|
7195
|
+
try {
|
|
7196
|
+
transaction = facts.sourceChainId === ETHEREUM_CHAIN_ID ? validateEvmBuildResult(wrapper, swapperAddress) : validateSolanaBuildResult(wrapper, swapperAddress);
|
|
7197
|
+
} catch (error) {
|
|
7198
|
+
if (error instanceof BridgeError) {
|
|
7199
|
+
if (error.code === "BRIDGE_BUILD_INVALID") throw error;
|
|
7200
|
+
return fail("BRIDGE_BUILD_INVALID");
|
|
7201
|
+
}
|
|
7202
|
+
return fail("BRIDGE_BUILD_INVALID");
|
|
7203
|
+
}
|
|
7204
|
+
return deepFreeze6({
|
|
7205
|
+
buildKind: "mayan-swift-v2-unsigned",
|
|
7206
|
+
providerId: "mayan-swift-v2",
|
|
7207
|
+
quote,
|
|
7208
|
+
sourceChainId: quote.sourceChainId,
|
|
7209
|
+
destinationChainId: quote.destinationChainId,
|
|
7210
|
+
transaction,
|
|
7211
|
+
allowance: facts.sourceChainId === ETHEREUM_CHAIN_ID ? {
|
|
7212
|
+
tokenDeploymentId: "deployment-0011",
|
|
7213
|
+
tokenAddress: ETHEREUM_EURC_ADDRESS,
|
|
7214
|
+
owner: swapperAddress,
|
|
7215
|
+
spender: ETHEREUM_FORWARDER,
|
|
7216
|
+
requiredAmount: quote.amountIn
|
|
7217
|
+
} : null,
|
|
7218
|
+
validation: {
|
|
7219
|
+
level: "structural",
|
|
7220
|
+
quoteSignatureLocallyVerified: false,
|
|
7221
|
+
transactionSemanticsLocallyVerified: false,
|
|
7222
|
+
settlementLocallyVerified: false
|
|
7223
|
+
},
|
|
7224
|
+
rawProviderBuildJson: response.text
|
|
7225
|
+
});
|
|
7226
|
+
};
|
|
7227
|
+
var boundedProviderString = (value, code, maximum = 1024) => {
|
|
7228
|
+
if (typeof value !== "string" || value.length === 0 || value.length > maximum) fail(code);
|
|
7229
|
+
return value;
|
|
7230
|
+
};
|
|
7231
|
+
var statusRequestSnapshot = (value) => {
|
|
7232
|
+
const request = requireRecord(value, "BRIDGE_INVALID_ARGUMENT");
|
|
7233
|
+
exactObjectKeys(request, ["sourceChainId", "sourceTransactionHash"], "BRIDGE_INVALID_ARGUMENT");
|
|
7234
|
+
return {
|
|
7235
|
+
sourceChainId: requireString(request.sourceChainId, "BRIDGE_INVALID_ARGUMENT"),
|
|
7236
|
+
sourceTransactionHash: requireString(request.sourceTransactionHash, "BRIDGE_INVALID_ARGUMENT")
|
|
7237
|
+
};
|
|
7238
|
+
};
|
|
7239
|
+
var normalizeStatusRequest = (value) => {
|
|
7240
|
+
const request = statusRequestSnapshot(value);
|
|
7241
|
+
if (request.sourceChainId === ETHEREUM_CHAIN_ID) {
|
|
7242
|
+
if (!EVM_HASH.test(request.sourceTransactionHash)) fail("BRIDGE_INVALID_ARGUMENT");
|
|
7243
|
+
return {
|
|
7244
|
+
sourceChainId: request.sourceChainId,
|
|
7245
|
+
sourceTransactionHash: request.sourceTransactionHash.toLowerCase()
|
|
7246
|
+
};
|
|
7247
|
+
}
|
|
7248
|
+
if (request.sourceChainId === SOLANA_CHAIN_ID) {
|
|
7249
|
+
decodeBase58(request.sourceTransactionHash, 64, "BRIDGE_INVALID_ARGUMENT");
|
|
7250
|
+
return request;
|
|
7251
|
+
}
|
|
7252
|
+
return fail("BRIDGE_UNSUPPORTED_ROUTE");
|
|
7253
|
+
};
|
|
7254
|
+
var statusFromResponse = (response, request) => {
|
|
7255
|
+
if (!isRecord4(response.root.value)) fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
7256
|
+
const providerClientStatus = boundedProviderString(
|
|
7257
|
+
objectValue5(response.root, "clientStatus"),
|
|
7258
|
+
"BRIDGE_PROVIDER_INVALID_RESPONSE",
|
|
7259
|
+
128
|
|
7260
|
+
);
|
|
7261
|
+
const providerStatusValue = objectValue5(response.root, "status");
|
|
7262
|
+
if (providerStatusValue !== null && providerStatusValue !== void 0 && (typeof providerStatusValue !== "string" || providerStatusValue.length > 1024)) {
|
|
7263
|
+
fail("BRIDGE_PROVIDER_INVALID_RESPONSE");
|
|
7264
|
+
}
|
|
7265
|
+
const providerStatus = providerStatusValue === void 0 ? null : providerStatusValue;
|
|
7266
|
+
const state = providerClientStatus === "INPROGRESS" ? "in-progress" : providerClientStatus === "COMPLETED" ? "completed" : providerClientStatus === "REFUNDED" ? "refunded" : "unknown";
|
|
7267
|
+
return deepFreeze6({
|
|
7268
|
+
statusKind: "mayan-explorer-index",
|
|
7269
|
+
providerId: "mayan-swift-v2",
|
|
7270
|
+
sourceChainId: request.sourceChainId,
|
|
7271
|
+
sourceTransactionHash: request.sourceTransactionHash,
|
|
7272
|
+
state,
|
|
7273
|
+
providerClientStatus,
|
|
7274
|
+
providerStatus,
|
|
7275
|
+
statusVerification: "provider-indexed-not-locally-verified",
|
|
7276
|
+
rawProviderStatusJson: response.text
|
|
7277
|
+
});
|
|
7278
|
+
};
|
|
7279
|
+
var buildBody = (quote, sourceChainId, swapperAddress, destinationAddress, refundAddress) => {
|
|
7280
|
+
const params = {
|
|
7281
|
+
swapperAddress,
|
|
7282
|
+
destinationAddress
|
|
7283
|
+
};
|
|
7284
|
+
if (sourceChainId === ETHEREUM_CHAIN_ID) params.signerChainId = 1;
|
|
7285
|
+
if (refundAddress !== void 0) params.swiftRefundAddress = refundAddress;
|
|
7286
|
+
return `{"quote":${quote.rawSignedQuoteJson},"params":${JSON.stringify(params)}}`;
|
|
7287
|
+
};
|
|
7288
|
+
var quoteRequestBodyForRoute = (route) => quoteRequestBody(route);
|
|
7289
|
+
var MayanSwiftV2BridgeClient = class {
|
|
7290
|
+
#config;
|
|
7291
|
+
constructor(config) {
|
|
7292
|
+
this.#config = normalizeBridgeConfig(config);
|
|
7293
|
+
}
|
|
7294
|
+
async quoteExactInput(request, options) {
|
|
7295
|
+
const route = validateBridgeRoute(request);
|
|
7296
|
+
const response = await providerRequest(
|
|
7297
|
+
this.#config,
|
|
7298
|
+
endpointWithPath2(this.#config.builderEndpoint, "/quote"),
|
|
7299
|
+
"POST",
|
|
7300
|
+
quoteRequestBodyForRoute(route),
|
|
7301
|
+
false,
|
|
7302
|
+
options
|
|
7303
|
+
);
|
|
7304
|
+
const parsed = await providerJson(response, "quote");
|
|
7305
|
+
const quotes = quoteFromResponse(parsed, route.request, route.facts, this.#config);
|
|
7306
|
+
return deepFreeze6([...quotes]);
|
|
7307
|
+
}
|
|
7308
|
+
async buildUnsigned(request, options) {
|
|
7309
|
+
const snapshot = buildRequestSnapshot(request);
|
|
7310
|
+
const { route, normalizedQuote } = buildRouteFromQuote(snapshot.quote);
|
|
7311
|
+
rejectAddressFromOtherChain(snapshot.swapperAddress, route.facts.sourceChainId);
|
|
7312
|
+
const sourceAddress = normalizeChainAddress(
|
|
7313
|
+
snapshot.swapperAddress,
|
|
7314
|
+
route.facts.sourceChainId,
|
|
7315
|
+
"BRIDGE_INVALID_ARGUMENT"
|
|
7316
|
+
);
|
|
7317
|
+
const destinationAddress = normalizeDestinationAddress(
|
|
7318
|
+
snapshot.destinationAddress,
|
|
7319
|
+
route.facts.destinationChainId
|
|
7320
|
+
);
|
|
7321
|
+
let refundAddress;
|
|
7322
|
+
if (snapshot.refundAddress !== void 0) {
|
|
7323
|
+
refundAddress = normalizeChainAddress(
|
|
7324
|
+
snapshot.refundAddress,
|
|
7325
|
+
route.facts.sourceChainId,
|
|
7326
|
+
"BRIDGE_INVALID_ARGUMENT"
|
|
7327
|
+
);
|
|
7328
|
+
}
|
|
7329
|
+
if (this.#config.builderApiKey === void 0 && !this.#config.allowUnauthenticatedBuild) {
|
|
7330
|
+
fail("BRIDGE_PROVIDER_AUTH_REQUIRED");
|
|
7331
|
+
}
|
|
7332
|
+
const quote = validateRawQuoteForBuild(normalizedQuote, route, this.#config);
|
|
7333
|
+
const response = await providerRequest(
|
|
7334
|
+
this.#config,
|
|
7335
|
+
endpointWithPath2(this.#config.builderEndpoint, "/build"),
|
|
7336
|
+
"POST",
|
|
7337
|
+
buildBody(quote, route.facts.sourceChainId, sourceAddress, destinationAddress, refundAddress),
|
|
7338
|
+
true,
|
|
7339
|
+
options
|
|
7340
|
+
);
|
|
7341
|
+
const parsed = await providerJson(response, "build");
|
|
7342
|
+
ensureQuoteDeadline(
|
|
7343
|
+
normalizePositiveUint64(quote.deadline, "BRIDGE_QUOTE_EXPIRED").value,
|
|
7344
|
+
this.#config.minimumQuoteValiditySeconds
|
|
7345
|
+
);
|
|
7346
|
+
return validateBuildResponse(parsed, quote, route.facts, sourceAddress);
|
|
7347
|
+
}
|
|
7348
|
+
async getStatus(request, options) {
|
|
7349
|
+
const normalized = normalizeStatusRequest(request);
|
|
7350
|
+
const response = await providerRequest(
|
|
7351
|
+
this.#config,
|
|
7352
|
+
endpointWithPath2(
|
|
7353
|
+
this.#config.explorerEndpoint,
|
|
7354
|
+
`/swap/trx/${encodeURIComponent(normalized.sourceTransactionHash)}`
|
|
7355
|
+
),
|
|
7356
|
+
"GET",
|
|
7357
|
+
void 0,
|
|
7358
|
+
false,
|
|
7359
|
+
options
|
|
7360
|
+
);
|
|
7361
|
+
const parsed = await providerJson(response, "status");
|
|
7362
|
+
return statusFromResponse(parsed, normalized);
|
|
7363
|
+
}
|
|
7364
|
+
close() {
|
|
7365
|
+
}
|
|
7366
|
+
};
|
|
7367
|
+
var createMayanSwiftV2BridgeClient = (config) => new MayanSwiftV2BridgeClient(config);
|
|
7368
|
+
|
|
7369
|
+
export { AVALANCHE_AVAX_METHODS, AVALANCHE_INDEX_METHODS, AVALANCHE_INFO_METHODS, AVALANCHE_PROPOSER_VM_METHODS, AVALANCHE_P_CHAIN_METHODS, AVALANCHE_X_CHAIN_METHODS, AccountClient, BRIDGE_CAPABILITIES_AS_OF_DATE, BRIDGE_CAPABILITIES_CONTENT_DIGEST, BRIDGE_CAPABILITIES_JSON, BRIDGE_ERROR_MESSAGES, BridgeError, CloudCatalogClient, CloudCreditClient, CloudResourcesClient, DEFAULT_ACCOUNT_ENDPOINT, DEFAULT_AVALANCHE_ENDPOINT, DEFAULT_ENDPOINT, DEFAULT_TIMEOUT_MS, DEFAULT_USER_ENDPOINT, DEX_ALIASES, DEX_CATALOG_AS_OF_DATE, DEX_CATALOG_CONTENT_DIGEST, DEX_CATALOG_VERSION, DEX_CHAIN_IDS, DEX_DEPLOYMENTS, ETHEREUM_RPC_METHODS, ETHEREUM_SUBSCRIPTION_METHODS, ErpcAbortedError, ErpcBatchPolicyError, ErpcConfigError, ErpcError, ErpcHttpError, ErpcInvalidResponseError, ErpcJsonRpcError, ErpcNotConfiguredError, ErpcTimeoutError, ErpcTransportError, EthereumSubscriptions, MayanSwiftV2BridgeClient, NATIVE_WRAP_DEFINITIONS, POOL_DEFINITIONS, PendingRpcBatchRequest, PendingRpcRequest, PriceClient, RpcSubscription, SOLANA_ANALYTICS_METHODS, SOLANA_DAS_METHODS, SOLANA_ENHANCED_SUBSCRIPTION_METHODS, SOLANA_HISTORY_METHODS, SOLANA_LEADER_METHODS, SOLANA_RPC_METHODS, SWAP_EXECUTION_CAPABILITIES_AS_OF_DATE, SWAP_EXECUTION_CAPABILITIES_CONTENT_DIGEST, SWAP_EXECUTION_CAPABILITIES_JSON, SWAP_EXECUTION_ERROR_MESSAGES, SWAP_EXECUTION_FUNCTION_SELECTOR, SWAP_EXECUTION_FUNCTION_SIGNATURE, SWAP_QUOTE_ERROR_MESSAGES, SolanaSubscriptions, SwapExecutionError, SwapQuoteError, TOKEN_ALIASES, TOKEN_ASSETS, TOKEN_CATALOG_AS_OF_DATE, TOKEN_CATALOG_CONTENT_DIGEST, TOKEN_CATALOG_VERSION, TOKEN_CHAIN_IDS, TOKEN_DEPLOYMENTS, TOKEN_RANKINGS, TOKEN_RANKINGS_BY_CHAIN, TOKEN_RANKINGS_CONTENT_DIGEST, TOKEN_RANKINGS_METADATA, UsageClient, createErpcClient, createErpcCloudClient, createMayanSwiftV2BridgeClient, dexes, findPoolDefinitionByAddress, findPoolDefinitionsByPair, findTokenDeploymentByAddress, findTokenDeploymentsBySymbol, getDexDeployment, getNativeTokenDeployment, getNativeWrapDefinition, getPoolDefinition, getTokenAsset, getTokenDeployment, listPoolDefinitions, listTokenDeployments, listTokenRankings, pools, tokens };
|
|
5002
7370
|
//# sourceMappingURL=index.js.map
|
|
5003
7371
|
//# sourceMappingURL=index.js.map
|