@toon-protocol/sdk 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-Z6S56VPV.js → chunk-7LBYFU4L.js} +658 -204
- package/dist/chunk-7LBYFU4L.js.map +1 -0
- package/dist/index.d.ts +29 -6
- package/dist/index.js +361 -1
- package/dist/index.js.map +1 -1
- package/dist/swap-Oub-0vqU.d.ts +911 -0
- package/dist/swap.d.ts +1 -1
- package/dist/swap.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-Z6S56VPV.js.map +0 -1
- package/dist/swap-DF4ghKio.d.ts +0 -484
package/dist/index.js
CHANGED
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
unwrapSwapPacketFromToon,
|
|
30
30
|
wrapSwapPacket,
|
|
31
31
|
wrapSwapPacketToToon
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-7LBYFU4L.js";
|
|
33
33
|
import "./chunk-UP2VWCW5.js";
|
|
34
34
|
|
|
35
35
|
// src/handler-context.ts
|
|
@@ -1997,6 +1997,360 @@ async function uploadBlobChunked(node, blob, destination, options) {
|
|
|
1997
1997
|
return lastResult.eventId;
|
|
1998
1998
|
}
|
|
1999
1999
|
|
|
2000
|
+
// src/adaptive-controller.ts
|
|
2001
|
+
import { ToonError as ToonError3 } from "@toon-protocol/core";
|
|
2002
|
+
var SwapControllerError = class extends ToonError3 {
|
|
2003
|
+
constructor(message, cause) {
|
|
2004
|
+
super(message, "SWAP_CONTROLLER_ERROR", cause);
|
|
2005
|
+
this.name = "SwapControllerError";
|
|
2006
|
+
}
|
|
2007
|
+
};
|
|
2008
|
+
var DECIMAL_UINT_REGEX = /^(0|[1-9]\d*)$/;
|
|
2009
|
+
function isSwapControllerState(value) {
|
|
2010
|
+
if (!value || typeof value !== "object") return false;
|
|
2011
|
+
const s = value;
|
|
2012
|
+
return s["v"] === 1 && typeof s["delta"] === "string" && DECIMAL_UINT_REGEX.test(s["delta"]) && typeof s["W"] === "number" && Number.isInteger(s["W"]) && s["W"] >= 1 && typeof s["vEwma"] === "number" && Number.isFinite(s["vEwma"]) && s["vEwma"] >= 0 && typeof s["tauEwma"] === "number" && Number.isFinite(s["tauEwma"]) && s["tauEwma"] >= 0 && typeof s["cleanStreak"] === "number" && Number.isInteger(s["cleanStreak"]) && s["cleanStreak"] >= 0 && typeof s["everShrunk"] === "boolean" && (s["lastWidened"] === "delta" || s["lastWidened"] === "window") && typeof s["updatedAt"] === "number";
|
|
2013
|
+
}
|
|
2014
|
+
function swapControllerStateKey(params) {
|
|
2015
|
+
const { makerPubkey, pair } = params;
|
|
2016
|
+
const from = `${pair.from.assetCode}@${pair.from.chain}`;
|
|
2017
|
+
const to = `${pair.to.assetCode}@${pair.to.chain}`;
|
|
2018
|
+
return `${pair.from.chain}:${makerPubkey}:${from}:${to}`;
|
|
2019
|
+
}
|
|
2020
|
+
var InMemorySwapControllerStateStore = class {
|
|
2021
|
+
states = /* @__PURE__ */ new Map();
|
|
2022
|
+
async load(key) {
|
|
2023
|
+
const hit = this.states.get(key);
|
|
2024
|
+
return hit === void 0 ? void 0 : { ...hit };
|
|
2025
|
+
}
|
|
2026
|
+
async save(key, state) {
|
|
2027
|
+
this.states.set(key, { ...state });
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
var JsonFileSwapControllerStateStore = class {
|
|
2031
|
+
constructor(filePath) {
|
|
2032
|
+
this.filePath = filePath;
|
|
2033
|
+
if (typeof filePath !== "string" || filePath.length === 0) {
|
|
2034
|
+
throw new SwapControllerError(
|
|
2035
|
+
"JsonFileSwapControllerStateStore requires a non-empty filePath"
|
|
2036
|
+
);
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
async readAll() {
|
|
2040
|
+
const fs = await import("fs/promises");
|
|
2041
|
+
let raw;
|
|
2042
|
+
try {
|
|
2043
|
+
raw = await fs.readFile(this.filePath, "utf8");
|
|
2044
|
+
} catch (err) {
|
|
2045
|
+
if (err.code === "ENOENT") return {};
|
|
2046
|
+
throw new SwapControllerError(
|
|
2047
|
+
`Failed to read controller state file ${this.filePath}`,
|
|
2048
|
+
err instanceof Error ? err : void 0
|
|
2049
|
+
);
|
|
2050
|
+
}
|
|
2051
|
+
try {
|
|
2052
|
+
const parsed = JSON.parse(raw);
|
|
2053
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2054
|
+
return parsed;
|
|
2055
|
+
}
|
|
2056
|
+
} catch {
|
|
2057
|
+
}
|
|
2058
|
+
return {};
|
|
2059
|
+
}
|
|
2060
|
+
async load(key) {
|
|
2061
|
+
const all = await this.readAll();
|
|
2062
|
+
const candidate = all[key];
|
|
2063
|
+
return isSwapControllerState(candidate) ? { ...candidate } : void 0;
|
|
2064
|
+
}
|
|
2065
|
+
async save(key, state) {
|
|
2066
|
+
const fs = await import("fs/promises");
|
|
2067
|
+
const path = await import("path");
|
|
2068
|
+
const all = await this.readAll();
|
|
2069
|
+
all[key] = { ...state };
|
|
2070
|
+
const dir = path.dirname(this.filePath);
|
|
2071
|
+
await fs.mkdir(dir, { recursive: true });
|
|
2072
|
+
const tmp = `${this.filePath}.${process.pid}.${Date.now()}.tmp`;
|
|
2073
|
+
await fs.writeFile(tmp, JSON.stringify(all, null, 2), "utf8");
|
|
2074
|
+
await fs.rename(tmp, this.filePath);
|
|
2075
|
+
}
|
|
2076
|
+
};
|
|
2077
|
+
var DEFAULT_EPSILON_HALF_SPREAD_FRACTION = 0.5;
|
|
2078
|
+
var DEFAULT_MAX_WINDOW = 8;
|
|
2079
|
+
var DEFAULT_CLEAN_STREAK_LENGTH = 16;
|
|
2080
|
+
var DEFAULT_COLD_START_DIVISOR = 256;
|
|
2081
|
+
var DEFAULT_EWMA_ALPHA = 0.2;
|
|
2082
|
+
var CAP_SCALE = 1000000000000n;
|
|
2083
|
+
var CAP_SCALE_NUM = 1e12;
|
|
2084
|
+
function rateToNumber(rate) {
|
|
2085
|
+
const n = Number(rate);
|
|
2086
|
+
return Number.isFinite(n) && n > 0 ? n : NaN;
|
|
2087
|
+
}
|
|
2088
|
+
var AdaptiveDeltaController = class _AdaptiveDeltaController {
|
|
2089
|
+
/** Persistence key for this tuple (see {@link swapControllerStateKey}). */
|
|
2090
|
+
key;
|
|
2091
|
+
store;
|
|
2092
|
+
pair;
|
|
2093
|
+
epsilon;
|
|
2094
|
+
maxPacketAmount;
|
|
2095
|
+
minPacketAmount;
|
|
2096
|
+
maxWindow;
|
|
2097
|
+
cleanStreakLength;
|
|
2098
|
+
coldStartDivisor;
|
|
2099
|
+
alpha;
|
|
2100
|
+
now;
|
|
2101
|
+
stateInternal;
|
|
2102
|
+
/** δ in-memory as bigint (mirrors `stateInternal.delta`). */
|
|
2103
|
+
delta;
|
|
2104
|
+
/** Cold-start δ_0 — also the additive widen increment. Set on first nextDelta(). */
|
|
2105
|
+
delta0 = null;
|
|
2106
|
+
/** Previous tape entry for the per-second volatility measurement. */
|
|
2107
|
+
lastRate = null;
|
|
2108
|
+
lastRateTimestamp = null;
|
|
2109
|
+
constructor(config, key, store, state) {
|
|
2110
|
+
this.key = key;
|
|
2111
|
+
this.store = store;
|
|
2112
|
+
this.pair = config.pair;
|
|
2113
|
+
const epsilonFraction = config.epsilonHalfSpreadFraction ?? DEFAULT_EPSILON_HALF_SPREAD_FRACTION;
|
|
2114
|
+
this.epsilon = epsilonFraction * (config.advertisedSpread / 2);
|
|
2115
|
+
this.maxPacketAmount = config.maxPacketAmount;
|
|
2116
|
+
this.minPacketAmount = config.minPacketAmount ?? 1n;
|
|
2117
|
+
this.maxWindow = config.maxWindow ?? DEFAULT_MAX_WINDOW;
|
|
2118
|
+
this.cleanStreakLength = config.cleanStreakLength ?? DEFAULT_CLEAN_STREAK_LENGTH;
|
|
2119
|
+
this.coldStartDivisor = BigInt(
|
|
2120
|
+
config.coldStartDivisor ?? DEFAULT_COLD_START_DIVISOR
|
|
2121
|
+
);
|
|
2122
|
+
this.alpha = config.ewmaAlpha ?? DEFAULT_EWMA_ALPHA;
|
|
2123
|
+
this.now = config.now ?? Date.now;
|
|
2124
|
+
this.stateInternal = state;
|
|
2125
|
+
this.delta = BigInt(state.delta);
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Create a controller for one swap session: loads the persisted state for
|
|
2129
|
+
* the tuple from the store, or starts cold (`δ` unset until the first
|
|
2130
|
+
* `nextDelta()`, `W = 1`).
|
|
2131
|
+
*/
|
|
2132
|
+
static async create(config) {
|
|
2133
|
+
validateConfig(config);
|
|
2134
|
+
const key = swapControllerStateKey({
|
|
2135
|
+
makerPubkey: config.makerPubkey,
|
|
2136
|
+
pair: config.pair
|
|
2137
|
+
});
|
|
2138
|
+
const store = config.store ?? new InMemorySwapControllerStateStore();
|
|
2139
|
+
const now = config.now ?? Date.now;
|
|
2140
|
+
const loaded = await store.load(key);
|
|
2141
|
+
const state = isSwapControllerState(loaded) ? loaded : {
|
|
2142
|
+
v: 1,
|
|
2143
|
+
delta: "0",
|
|
2144
|
+
W: 1,
|
|
2145
|
+
vEwma: 0,
|
|
2146
|
+
tauEwma: 0,
|
|
2147
|
+
cleanStreak: 0,
|
|
2148
|
+
everShrunk: false,
|
|
2149
|
+
// 'window' so the FIRST widen step hits δ (alternation starts on δ).
|
|
2150
|
+
lastWidened: "window",
|
|
2151
|
+
updatedAt: now()
|
|
2152
|
+
};
|
|
2153
|
+
return new _AdaptiveDeltaController(config, key, store, state);
|
|
2154
|
+
}
|
|
2155
|
+
/** Defensive snapshot of the current controller state. */
|
|
2156
|
+
get state() {
|
|
2157
|
+
return { ...this.stateInternal, delta: this.delta.toString() };
|
|
2158
|
+
}
|
|
2159
|
+
/** Current in-flight window W. */
|
|
2160
|
+
get window() {
|
|
2161
|
+
return this.stateInternal.W;
|
|
2162
|
+
}
|
|
2163
|
+
/**
|
|
2164
|
+
* Current `delta_cap = ε/(v·τ)` as a fraction of remaining notional.
|
|
2165
|
+
* `Infinity` while `v·τ` has no measurement yet (cold tape) — the
|
|
2166
|
+
* cold-start `δ_0` and absolute caps bound δ in that regime.
|
|
2167
|
+
*/
|
|
2168
|
+
get deltaCapFraction() {
|
|
2169
|
+
const vTau = this.stateInternal.vEwma * this.stateInternal.tauEwma;
|
|
2170
|
+
if (!(vTau > 0)) return Infinity;
|
|
2171
|
+
return this.epsilon / vTau;
|
|
2172
|
+
}
|
|
2173
|
+
/** `delta_cap` in absolute source micro-units for a given remaining notional. */
|
|
2174
|
+
deltaCapAbsolute(remaining) {
|
|
2175
|
+
const frac = this.deltaCapFraction;
|
|
2176
|
+
if (!Number.isFinite(frac) || frac >= 1) return remaining;
|
|
2177
|
+
if (frac <= 0) return this.minPacketAmount;
|
|
2178
|
+
const scaled = BigInt(Math.floor(frac * CAP_SCALE_NUM));
|
|
2179
|
+
return remaining * scaled / CAP_SCALE;
|
|
2180
|
+
}
|
|
2181
|
+
/**
|
|
2182
|
+
* Decide the next packet size (source micro-units) for a session with
|
|
2183
|
+
* `remaining` notional left. Enforces, in order: the measured
|
|
2184
|
+
* `delta_cap = ε/(v·τ)` bound, the absolute `maxPacketAmount` cap, the
|
|
2185
|
+
* remaining notional, and the `minPacketAmount` floor. Seeds the
|
|
2186
|
+
* cold-start `δ_0 = min(delta_cap, notional/256, maxPacketAmount)` on
|
|
2187
|
+
* first call.
|
|
2188
|
+
*/
|
|
2189
|
+
nextDelta(remaining) {
|
|
2190
|
+
if (typeof remaining !== "bigint" || remaining <= 0n) return 0n;
|
|
2191
|
+
if (this.delta0 === null) {
|
|
2192
|
+
let d0 = remaining / this.coldStartDivisor;
|
|
2193
|
+
const capAbs2 = this.deltaCapAbsolute(remaining);
|
|
2194
|
+
if (d0 > capAbs2) d0 = capAbs2;
|
|
2195
|
+
if (this.maxPacketAmount !== void 0 && d0 > this.maxPacketAmount) {
|
|
2196
|
+
d0 = this.maxPacketAmount;
|
|
2197
|
+
}
|
|
2198
|
+
if (d0 < this.minPacketAmount) d0 = this.minPacketAmount;
|
|
2199
|
+
this.delta0 = d0;
|
|
2200
|
+
if (this.delta <= 0n) {
|
|
2201
|
+
this.delta = d0;
|
|
2202
|
+
this.stateInternal.delta = d0.toString();
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
let d = this.delta;
|
|
2206
|
+
const capAbs = this.deltaCapAbsolute(remaining);
|
|
2207
|
+
if (d > capAbs) d = capAbs;
|
|
2208
|
+
if (this.maxPacketAmount !== void 0 && d > this.maxPacketAmount) {
|
|
2209
|
+
d = this.maxPacketAmount;
|
|
2210
|
+
}
|
|
2211
|
+
if (d > remaining) d = remaining;
|
|
2212
|
+
const floor = this.minPacketAmount < remaining ? this.minPacketAmount : remaining;
|
|
2213
|
+
if (d < floor) d = floor;
|
|
2214
|
+
return d;
|
|
2215
|
+
}
|
|
2216
|
+
/**
|
|
2217
|
+
* Feed one packet observation: updates the measured EWMAs (`v`, `τ`),
|
|
2218
|
+
* applies at most ONE knob adjustment (asymmetric: multiplicative shrink /
|
|
2219
|
+
* additive widen), and persists the state.
|
|
2220
|
+
*/
|
|
2221
|
+
async observe(observation) {
|
|
2222
|
+
const s = this.stateInternal;
|
|
2223
|
+
if (typeof observation.rttMs === "number" && Number.isFinite(observation.rttMs) && observation.rttMs > 0) {
|
|
2224
|
+
const tauSec = observation.rttMs / 1e3;
|
|
2225
|
+
s.tauEwma = s.tauEwma === 0 ? tauSec : this.alpha * tauSec + (1 - this.alpha) * s.tauEwma;
|
|
2226
|
+
}
|
|
2227
|
+
if (typeof observation.rate === "string" && typeof observation.rateTimestamp === "number" && Number.isFinite(observation.rateTimestamp)) {
|
|
2228
|
+
const r = rateToNumber(observation.rate);
|
|
2229
|
+
if (!Number.isNaN(r)) {
|
|
2230
|
+
if (this.lastRate !== null && this.lastRateTimestamp !== null && observation.rateTimestamp > this.lastRateTimestamp) {
|
|
2231
|
+
const dtSec = (observation.rateTimestamp - this.lastRateTimestamp) / 1e3;
|
|
2232
|
+
const inst = Math.abs(r - this.lastRate) / this.lastRate / dtSec;
|
|
2233
|
+
if (Number.isFinite(inst)) {
|
|
2234
|
+
s.vEwma = s.vEwma === 0 ? inst : this.alpha * inst + (1 - this.alpha) * s.vEwma;
|
|
2235
|
+
}
|
|
2236
|
+
}
|
|
2237
|
+
if (this.lastRateTimestamp === null || observation.rateTimestamp >= this.lastRateTimestamp) {
|
|
2238
|
+
this.lastRate = r;
|
|
2239
|
+
this.lastRateTimestamp = observation.rateTimestamp;
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
const slip = this.realizedSlip(observation);
|
|
2244
|
+
const isShrink = observation.resolution !== "fulfill" || slip > this.epsilon;
|
|
2245
|
+
if (isShrink) {
|
|
2246
|
+
if (observation.resolution === "timeout") {
|
|
2247
|
+
s.W = Math.max(1, Math.ceil(s.W / 2));
|
|
2248
|
+
} else {
|
|
2249
|
+
let d = this.delta / 2n;
|
|
2250
|
+
if (d < this.minPacketAmount) d = this.minPacketAmount;
|
|
2251
|
+
this.delta = d;
|
|
2252
|
+
s.delta = d.toString();
|
|
2253
|
+
}
|
|
2254
|
+
s.cleanStreak = 0;
|
|
2255
|
+
s.everShrunk = true;
|
|
2256
|
+
} else {
|
|
2257
|
+
s.cleanStreak += 1;
|
|
2258
|
+
if (s.cleanStreak >= this.cleanStreakLength) {
|
|
2259
|
+
s.cleanStreak = 0;
|
|
2260
|
+
const knob = s.lastWidened === "delta" ? "window" : "delta";
|
|
2261
|
+
if (knob === "window") {
|
|
2262
|
+
s.W = Math.min(this.maxWindow, s.W + 1);
|
|
2263
|
+
} else {
|
|
2264
|
+
const increment = this.delta0 ?? this.minPacketAmount;
|
|
2265
|
+
let d = s.everShrunk ? this.delta + increment : this.delta * 2n;
|
|
2266
|
+
if (this.maxPacketAmount !== void 0 && d > this.maxPacketAmount) {
|
|
2267
|
+
d = this.maxPacketAmount;
|
|
2268
|
+
}
|
|
2269
|
+
if (observation.remaining !== void 0 && observation.remaining > 0n) {
|
|
2270
|
+
const capAbs = this.deltaCapAbsolute(observation.remaining);
|
|
2271
|
+
if (d > capAbs) d = capAbs;
|
|
2272
|
+
}
|
|
2273
|
+
if (d < this.minPacketAmount) d = this.minPacketAmount;
|
|
2274
|
+
if (d < this.delta) d = this.delta;
|
|
2275
|
+
this.delta = d;
|
|
2276
|
+
s.delta = d.toString();
|
|
2277
|
+
}
|
|
2278
|
+
s.lastWidened = knob;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
s.updatedAt = this.now();
|
|
2282
|
+
await this.store.save(this.key, { ...s });
|
|
2283
|
+
}
|
|
2284
|
+
/**
|
|
2285
|
+
* Realized per-packet slip as a fraction: shortfall of the delivered
|
|
2286
|
+
* target amount vs the amount implied by the packet's own tape rate `R_i`
|
|
2287
|
+
* (spec §7.1 `Δcumulative` vs `⌊δ · R_i⌋` cross-check). `0` when the
|
|
2288
|
+
* inputs are unavailable or delivery met the tape.
|
|
2289
|
+
*/
|
|
2290
|
+
realizedSlip(observation) {
|
|
2291
|
+
if (observation.resolution !== "fulfill" || observation.rate === void 0 || observation.sourceAmount === void 0 || observation.targetAmount === void 0 || observation.sourceAmount <= 0n) {
|
|
2292
|
+
return 0;
|
|
2293
|
+
}
|
|
2294
|
+
let expected;
|
|
2295
|
+
try {
|
|
2296
|
+
expected = applyRate({
|
|
2297
|
+
sourceAmount: observation.sourceAmount,
|
|
2298
|
+
fromScale: this.pair.from.assetScale,
|
|
2299
|
+
toScale: this.pair.to.assetScale,
|
|
2300
|
+
rate: observation.rate
|
|
2301
|
+
});
|
|
2302
|
+
} catch {
|
|
2303
|
+
return 0;
|
|
2304
|
+
}
|
|
2305
|
+
if (expected <= 0n || observation.targetAmount >= expected) return 0;
|
|
2306
|
+
const shortfall = expected - observation.targetAmount;
|
|
2307
|
+
return Number(shortfall * 1000000n / expected) / 1e6;
|
|
2308
|
+
}
|
|
2309
|
+
};
|
|
2310
|
+
function validateConfig(config) {
|
|
2311
|
+
if (typeof config.makerPubkey !== "string" || config.makerPubkey.length === 0) {
|
|
2312
|
+
throw new SwapControllerError("makerPubkey must be a non-empty string");
|
|
2313
|
+
}
|
|
2314
|
+
if (!config.pair || typeof config.pair !== "object" || !config.pair.from || !config.pair.to || typeof config.pair.from.chain !== "string" || typeof config.pair.to.chain !== "string") {
|
|
2315
|
+
throw new SwapControllerError(
|
|
2316
|
+
"pair must be a SwapPair with from/to chain descriptors"
|
|
2317
|
+
);
|
|
2318
|
+
}
|
|
2319
|
+
if (typeof config.advertisedSpread !== "number" || !Number.isFinite(config.advertisedSpread) || config.advertisedSpread <= 0) {
|
|
2320
|
+
throw new SwapControllerError(
|
|
2321
|
+
`advertisedSpread must be a positive finite fraction, got ${String(
|
|
2322
|
+
config.advertisedSpread
|
|
2323
|
+
)}`
|
|
2324
|
+
);
|
|
2325
|
+
}
|
|
2326
|
+
if (config.epsilonHalfSpreadFraction !== void 0 && (typeof config.epsilonHalfSpreadFraction !== "number" || !Number.isFinite(config.epsilonHalfSpreadFraction) || config.epsilonHalfSpreadFraction <= 0)) {
|
|
2327
|
+
throw new SwapControllerError(
|
|
2328
|
+
"epsilonHalfSpreadFraction must be a positive finite number"
|
|
2329
|
+
);
|
|
2330
|
+
}
|
|
2331
|
+
if (config.maxPacketAmount !== void 0 && (typeof config.maxPacketAmount !== "bigint" || config.maxPacketAmount <= 0n)) {
|
|
2332
|
+
throw new SwapControllerError("maxPacketAmount must be a positive bigint");
|
|
2333
|
+
}
|
|
2334
|
+
if (config.minPacketAmount !== void 0 && (typeof config.minPacketAmount !== "bigint" || config.minPacketAmount <= 0n)) {
|
|
2335
|
+
throw new SwapControllerError("minPacketAmount must be a positive bigint");
|
|
2336
|
+
}
|
|
2337
|
+
if (config.minPacketAmount !== void 0 && config.maxPacketAmount !== void 0 && config.minPacketAmount > config.maxPacketAmount) {
|
|
2338
|
+
throw new SwapControllerError("minPacketAmount must be <= maxPacketAmount");
|
|
2339
|
+
}
|
|
2340
|
+
if (config.maxWindow !== void 0 && (!Number.isInteger(config.maxWindow) || config.maxWindow < 1)) {
|
|
2341
|
+
throw new SwapControllerError("maxWindow must be an integer >= 1");
|
|
2342
|
+
}
|
|
2343
|
+
if (config.cleanStreakLength !== void 0 && (!Number.isInteger(config.cleanStreakLength) || config.cleanStreakLength < 1)) {
|
|
2344
|
+
throw new SwapControllerError("cleanStreakLength must be an integer >= 1");
|
|
2345
|
+
}
|
|
2346
|
+
if (config.coldStartDivisor !== void 0 && (!Number.isInteger(config.coldStartDivisor) || config.coldStartDivisor < 1)) {
|
|
2347
|
+
throw new SwapControllerError("coldStartDivisor must be an integer >= 1");
|
|
2348
|
+
}
|
|
2349
|
+
if (config.ewmaAlpha !== void 0 && (typeof config.ewmaAlpha !== "number" || !(config.ewmaAlpha > 0) || config.ewmaAlpha > 1)) {
|
|
2350
|
+
throw new SwapControllerError("ewmaAlpha must be in (0, 1]");
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
|
|
2000
2354
|
// src/settlement/evm.ts
|
|
2001
2355
|
import { secp256k1 } from "@noble/curves/secp256k1.js";
|
|
2002
2356
|
import { keccak_256 } from "@noble/hashes/sha3.js";
|
|
@@ -3039,17 +3393,21 @@ function verifyAccumulatedClaim(claim, signer, minaSignerClient) {
|
|
|
3039
3393
|
};
|
|
3040
3394
|
}
|
|
3041
3395
|
export {
|
|
3396
|
+
AdaptiveDeltaController,
|
|
3042
3397
|
ChunkManager,
|
|
3043
3398
|
GiftWrapError,
|
|
3044
3399
|
HandlerError,
|
|
3045
3400
|
HandlerRegistry,
|
|
3046
3401
|
IdentityError,
|
|
3402
|
+
InMemorySwapControllerStateStore,
|
|
3403
|
+
JsonFileSwapControllerStateStore,
|
|
3047
3404
|
NodeError,
|
|
3048
3405
|
PricingError,
|
|
3049
3406
|
SWAP_HANDLER_REJECT_CODES,
|
|
3050
3407
|
SWAP_HANDLER_REJECT_MESSAGES,
|
|
3051
3408
|
SettlementTxError,
|
|
3052
3409
|
StreamSwapError,
|
|
3410
|
+
SwapControllerError,
|
|
3053
3411
|
SwapHandlerError,
|
|
3054
3412
|
SwarmCoordinator,
|
|
3055
3413
|
TurboUploadAdapter,
|
|
@@ -3085,10 +3443,12 @@ export {
|
|
|
3085
3443
|
generateMnemonic,
|
|
3086
3444
|
generateSolanaKeypair,
|
|
3087
3445
|
hexToBytes2 as hexToBytes,
|
|
3446
|
+
isSwapControllerState,
|
|
3088
3447
|
loadMinaSignerClient,
|
|
3089
3448
|
minaHashToField,
|
|
3090
3449
|
streamSwap,
|
|
3091
3450
|
streamSwapControlled,
|
|
3451
|
+
swapControllerStateKey,
|
|
3092
3452
|
unwrapSwapPacket,
|
|
3093
3453
|
unwrapSwapPacketFromToon,
|
|
3094
3454
|
uploadBlob,
|