@anywalletkit/protocol-swap2-core 0.10.2 → 0.11.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 +21 -0
- package/dist/{chunk-AY7DVYAN.js → chunk-HADKPUH4.js} +2 -2
- package/dist/{chunk-PN76KVPT.js → chunk-MVEAEYYJ.js} +67 -10
- package/dist/chunk-MVEAEYYJ.js.map +1 -0
- package/dist/index.cjs +66 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -2
- package/dist/swap2/base.cjs +66 -9
- package/dist/swap2/base.cjs.map +1 -1
- package/dist/swap2/base.d.cts +60 -1
- package/dist/swap2/base.d.ts +60 -1
- package/dist/swap2/base.js +3 -1
- package/dist/swap2/single.cjs +65 -9
- package/dist/swap2/single.cjs.map +1 -1
- package/dist/swap2/single.js +2 -2
- package/package.json +3 -3
- package/dist/chunk-PN76KVPT.js.map +0 -1
- /package/dist/{chunk-AY7DVYAN.js.map → chunk-HADKPUH4.js.map} +0 -0
package/dist/index.d.cts
CHANGED
|
@@ -3,7 +3,7 @@ export { Swap2ConfigurationError, Swap2Error, Swap2ErrorCode, Swap2ExecutionErro
|
|
|
3
3
|
export { SLIPPAGE_ROUNDING_BPS, remotePinRefusal, slippageFloor, validQuote } from './validate.cjs';
|
|
4
4
|
export { RemoteProviderOptions, remoteProvider } from './remote.cjs';
|
|
5
5
|
export { evmRef, isEvm, namespace, redactUrls, sourceAssetOf, tonRawAddress } from './util.cjs';
|
|
6
|
-
export { BaseSwap2Protocol, NATIVE_DECIMALS, SWAP2_CHAIN_ALIASES, SWAP2_ID_PREFIX, SerializedExecutionExpectation, Swap2Account, Swap2EngineConfig, Swap2ExecutionPhase, Swap2ExecutionPhaseDetail, Swap2ExecutionPlan, TonBodySummary, nativeDecimals, nativeUnits, swap2ChainId } from './swap2/base.cjs';
|
|
6
|
+
export { BaseSwap2Protocol, NATIVE_DECIMALS, NATIVE_FEE_CEILING_MAX_MULTIPLE, SWAP2_CHAIN_ALIASES, SWAP2_ID_PREFIX, SerializedExecutionExpectation, Swap2Account, Swap2EngineConfig, Swap2ExecutionPhase, Swap2ExecutionPhaseDetail, Swap2ExecutionPlan, Swap2NativeFeeCeilingContext, TonBodySummary, nativeDecimals, nativeUnits, swap2ChainId } from './swap2/base.cjs';
|
|
7
7
|
export { SingleProviderSwap2 } from './swap2/single.cjs';
|
|
8
8
|
export { SwapActivityOptions, assetLabel, assetMetaFor, callSelector, calledContract, callsContract, chainLabel, describeSwapLike, matchesCall, ownerAssets, shortAddress } from './activity.cjs';
|
|
9
9
|
export { SlippageClass, SlippageContext, SlippageOptions, SlippageSuggestion, slippageClassOf, suggestSlippage } from './slippage.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { Swap2ConfigurationError, Swap2Error, Swap2ErrorCode, Swap2ExecutionErro
|
|
|
3
3
|
export { SLIPPAGE_ROUNDING_BPS, remotePinRefusal, slippageFloor, validQuote } from './validate.js';
|
|
4
4
|
export { RemoteProviderOptions, remoteProvider } from './remote.js';
|
|
5
5
|
export { evmRef, isEvm, namespace, redactUrls, sourceAssetOf, tonRawAddress } from './util.js';
|
|
6
|
-
export { BaseSwap2Protocol, NATIVE_DECIMALS, SWAP2_CHAIN_ALIASES, SWAP2_ID_PREFIX, SerializedExecutionExpectation, Swap2Account, Swap2EngineConfig, Swap2ExecutionPhase, Swap2ExecutionPhaseDetail, Swap2ExecutionPlan, TonBodySummary, nativeDecimals, nativeUnits, swap2ChainId } from './swap2/base.js';
|
|
6
|
+
export { BaseSwap2Protocol, NATIVE_DECIMALS, NATIVE_FEE_CEILING_MAX_MULTIPLE, SWAP2_CHAIN_ALIASES, SWAP2_ID_PREFIX, SerializedExecutionExpectation, Swap2Account, Swap2EngineConfig, Swap2ExecutionPhase, Swap2ExecutionPhaseDetail, Swap2ExecutionPlan, Swap2NativeFeeCeilingContext, TonBodySummary, nativeDecimals, nativeUnits, swap2ChainId } from './swap2/base.js';
|
|
7
7
|
export { SingleProviderSwap2 } from './swap2/single.js';
|
|
8
8
|
export { SwapActivityOptions, assetLabel, assetMetaFor, callSelector, calledContract, callsContract, chainLabel, describeSwapLike, matchesCall, ownerAssets, shortAddress } from './activity.js';
|
|
9
9
|
export { SlippageClass, SlippageContext, SlippageOptions, SlippageSuggestion, slippageClassOf, suggestSlippage } from './slippage.js';
|
package/dist/index.js
CHANGED
|
@@ -12,16 +12,17 @@ import {
|
|
|
12
12
|
} from "./chunk-J4WXUNK2.js";
|
|
13
13
|
import {
|
|
14
14
|
SingleProviderSwap2
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-HADKPUH4.js";
|
|
16
16
|
import {
|
|
17
17
|
BaseSwap2Protocol,
|
|
18
18
|
NATIVE_DECIMALS,
|
|
19
|
+
NATIVE_FEE_CEILING_MAX_MULTIPLE,
|
|
19
20
|
SWAP2_CHAIN_ALIASES,
|
|
20
21
|
SWAP2_ID_PREFIX,
|
|
21
22
|
nativeDecimals,
|
|
22
23
|
nativeUnits,
|
|
23
24
|
swap2ChainId
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-MVEAEYYJ.js";
|
|
25
26
|
import "./chunk-55J6XMHW.js";
|
|
26
27
|
import {
|
|
27
28
|
Swap2ConfigurationError,
|
|
@@ -60,6 +61,7 @@ import {
|
|
|
60
61
|
export {
|
|
61
62
|
BaseSwap2Protocol,
|
|
62
63
|
NATIVE_DECIMALS,
|
|
64
|
+
NATIVE_FEE_CEILING_MAX_MULTIPLE,
|
|
63
65
|
SLIPPAGE_ROUNDING_BPS,
|
|
64
66
|
SWAP2_CHAIN_ALIASES,
|
|
65
67
|
SWAP2_ID_PREFIX,
|
package/dist/swap2/base.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var base_exports = {};
|
|
|
22
22
|
__export(base_exports, {
|
|
23
23
|
BaseSwap2Protocol: () => BaseSwap2Protocol,
|
|
24
24
|
NATIVE_DECIMALS: () => NATIVE_DECIMALS,
|
|
25
|
+
NATIVE_FEE_CEILING_MAX_MULTIPLE: () => NATIVE_FEE_CEILING_MAX_MULTIPLE,
|
|
25
26
|
SWAP2_CHAIN_ALIASES: () => SWAP2_CHAIN_ALIASES,
|
|
26
27
|
SWAP2_ID_PREFIX: () => SWAP2_ID_PREFIX,
|
|
27
28
|
nativeDecimals: () => nativeDecimals,
|
|
@@ -230,17 +231,71 @@ var NATIVE_FEE_CAP = Object.freeze({
|
|
|
230
231
|
// 20 MNT (≈ $0.53 each)
|
|
231
232
|
"eip155:14": nativeUnits("eip155:14", 1500),
|
|
232
233
|
// 1500 FLR (≈ $0.0067 each)
|
|
233
|
-
"eip155:5042": nativeUnits("eip155:5042", 10)
|
|
234
|
+
"eip155:5042": nativeUnits("eip155:5042", 10),
|
|
234
235
|
// 10 USDC — Arc's gas token, in its 18-decimal native units
|
|
235
236
|
// Katana and Morph are ETH-denominated: the 0.005 ETH default applies.
|
|
237
|
+
// 2026-11-10: Elysium pays gas in HYPE (18 decimals, ≈ $74.5 on li.quest that day) — HyperEVM's 0.1 HYPE ceiling, not
|
|
238
|
+
// the ETH default (0.005 HYPE ≈ $0.37 would refuse ordinary bridge fees).
|
|
239
|
+
"eip155:99901": nativeUnits("eip155:99901", "0.1")
|
|
240
|
+
// 0.1 HYPE
|
|
236
241
|
});
|
|
237
242
|
var DEFAULT_NATIVE_FEE_CAP = 5000000000000000n;
|
|
238
|
-
|
|
243
|
+
var NATIVE_FEE_CEILING_MAX_MULTIPLE = 20n;
|
|
244
|
+
function describeCeilingAnswer(value) {
|
|
245
|
+
if (value === null) return "null";
|
|
246
|
+
if (typeof value === "bigint") return String(value);
|
|
247
|
+
if (typeof value === "string") return `the string "${value.slice(0, 40)}"`;
|
|
248
|
+
if (typeof value === "number" || typeof value === "boolean") return `the ${typeof value} ${String(value)}`;
|
|
249
|
+
if (typeof value === "function") return "a function";
|
|
250
|
+
let thenable = false;
|
|
251
|
+
try {
|
|
252
|
+
thenable = typeof value.then === "function";
|
|
253
|
+
if (thenable) value.then(void 0, () => {
|
|
254
|
+
});
|
|
255
|
+
} catch {
|
|
256
|
+
}
|
|
257
|
+
return thenable ? "a Promise (the hook must answer synchronously)" : typeof value === "object" ? "an object" : `a ${typeof value}`;
|
|
258
|
+
}
|
|
259
|
+
function nativeFeeCap(chain, fee, route) {
|
|
260
|
+
const defaultCap = NATIVE_FEE_CAP[chain] ?? DEFAULT_NATIVE_FEE_CAP;
|
|
261
|
+
const hook = route?.ceiling;
|
|
262
|
+
if (hook === void 0) return defaultCap;
|
|
263
|
+
const maxCeiling = defaultCap * NATIVE_FEE_CEILING_MAX_MULTIPLE;
|
|
264
|
+
const where = `${route.provider} ${chain} \u2192 ${route.destChain}`;
|
|
265
|
+
if (typeof hook !== "function") {
|
|
266
|
+
throw new Swap2ConfigurationError(`swap2: nativeFeeCeiling is ${describeCeilingAnswer(hook)}, not a function \u2014 the native fee of ${where} is refused`);
|
|
267
|
+
}
|
|
268
|
+
const ctx = Object.freeze({
|
|
269
|
+
provider: route.provider,
|
|
270
|
+
intentId: route.intentId,
|
|
271
|
+
fromChain: chain,
|
|
272
|
+
destChain: route.destChain,
|
|
273
|
+
nativeFee: fee,
|
|
274
|
+
defaultCap,
|
|
275
|
+
maxCeiling
|
|
276
|
+
});
|
|
277
|
+
let answer;
|
|
278
|
+
try {
|
|
279
|
+
answer = hook(ctx);
|
|
280
|
+
} catch (error) {
|
|
281
|
+
const why = (error instanceof Error ? error.message : String(error)).slice(0, 160);
|
|
282
|
+
throw new Swap2ConfigurationError(`swap2: nativeFeeCeiling threw for ${where} (${why}) \u2014 the native fee is refused`, { cause: error });
|
|
283
|
+
}
|
|
284
|
+
if (answer === void 0) return defaultCap;
|
|
285
|
+
if (typeof answer !== "bigint" || answer < 0n) {
|
|
286
|
+
throw new Swap2ConfigurationError(`swap2: nativeFeeCeiling returned ${describeCeilingAnswer(answer)} for ${where}, not a non-negative bigint or undefined \u2014 the native fee is refused`);
|
|
287
|
+
}
|
|
288
|
+
if (answer > maxCeiling) {
|
|
289
|
+
throw new Swap2ConfigurationError(`swap2: nativeFeeCeiling returned ${answer} for ${where}, above the hard maximum ${maxCeiling} (${NATIVE_FEE_CEILING_MAX_MULTIPLE} \xD7 the default cap ${defaultCap}) \u2014 the native fee is refused`);
|
|
290
|
+
}
|
|
291
|
+
return answer;
|
|
292
|
+
}
|
|
293
|
+
function declaredNativeFee(q, chain, route) {
|
|
239
294
|
const raw = q.txRequest?.nativeFee;
|
|
240
295
|
if (raw === void 0) return 0n;
|
|
241
296
|
if (!/^\d+$/.test(raw)) throw new Error("swap2: quote declares a malformed native fee");
|
|
242
297
|
const fee = BigInt(raw);
|
|
243
|
-
const cap =
|
|
298
|
+
const cap = nativeFeeCap(chain, fee, route);
|
|
244
299
|
if (fee > cap) throw new Error(`swap2: quoted native fee ${fee} exceeds the cap ${cap} for ${chain}`);
|
|
245
300
|
return fee;
|
|
246
301
|
}
|
|
@@ -864,16 +919,18 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
864
919
|
const source = this.sourceAsset(executionOptions);
|
|
865
920
|
if (!source) throw new Error(`swap2: unknown source token '${executionOptions.fromToken}' on ${this.fromChain}`);
|
|
866
921
|
const executionValue = BigInt(unsigned.value);
|
|
922
|
+
const ceiling = this._config.nativeFeeCeiling;
|
|
923
|
+
const feeRoute = { provider: q.provider, intentId: q.intentId, destChain: params.destChain, ...ceiling !== void 0 ? { ceiling } : {} };
|
|
867
924
|
if (serialized) {
|
|
868
925
|
if (executionValue !== (source.contract ? 0n : BigInt(q.sourceAmount))) {
|
|
869
926
|
throw new Error("swap2: provider execution amount does not match the validated quote");
|
|
870
927
|
}
|
|
871
928
|
} else if (source.contract && this.fromChain.startsWith("eip155:")) {
|
|
872
|
-
const declared = declaredNativeFee(q, this.fromChain);
|
|
929
|
+
const declared = declaredNativeFee(q, this.fromChain, feeRoute);
|
|
873
930
|
if (executionValue !== declared) {
|
|
874
931
|
throw new Error(declared === 0n ? "swap2: token execution attempted to attach native value" : `swap2: token execution value ${executionValue} does not match the quoted native fee ${declared}`);
|
|
875
932
|
}
|
|
876
|
-
} else if (!unsigned.typedData && !unsigned.bodyBoc && executionValue !== BigInt(q.sourceAmount) + declaredNativeFee(q, this.fromChain)) {
|
|
933
|
+
} else if (!unsigned.typedData && !unsigned.bodyBoc && executionValue !== BigInt(q.sourceAmount) + declaredNativeFee(q, this.fromChain, feeRoute)) {
|
|
877
934
|
throw new Error("swap2: provider execution amount does not match the validated quote");
|
|
878
935
|
}
|
|
879
936
|
let tonBody;
|
|
@@ -882,13 +939,13 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
882
939
|
throw new Swap2ValidationError(`swap2: TON cell-body build refused \u2014 ${why}`);
|
|
883
940
|
};
|
|
884
941
|
const raw = this._config.tonGasCeiling;
|
|
885
|
-
const
|
|
886
|
-
if (
|
|
942
|
+
const ceiling2 = raw === void 0 ? DEFAULT_TON_GAS_CEILING : BigInt(raw);
|
|
943
|
+
if (ceiling2 < 0n) throw new Swap2ConfigurationError("swap2: tonGasCeiling must be non-negative");
|
|
887
944
|
if (provider.remote === true && provider.verifiesBuilds !== true) refuse("a remote provider's cell body needs the app's own validator (remoteProvider verifyBuild)");
|
|
888
945
|
tonBody = readTonBody(cellBody);
|
|
889
946
|
const input = BigInt(q.sourceAmount);
|
|
890
947
|
if (source.contract) {
|
|
891
|
-
if (executionValue >
|
|
948
|
+
if (executionValue > ceiling2) refuse(`it attaches ${executionValue} nanoTON to a jetton transfer, more than the ${ceiling2} gas ceiling`);
|
|
892
949
|
const t = tonBody.jettonTransfer;
|
|
893
950
|
if (!t) refuse("a jetton-source body must be a jetton transfer");
|
|
894
951
|
if (t.amount !== input) refuse(`the jetton transfer moves ${t.amount}, not the swap's ${input}`);
|
|
@@ -898,7 +955,7 @@ var BaseSwap2Protocol = class extends import_core.Swap2Protocol {
|
|
|
898
955
|
if (!own) refuse("the account cannot name its own jetton wallet (getJettonWalletAddress), so the target cannot be checked");
|
|
899
956
|
if (tonRawAddress(unsigned.to) !== own) refuse(`it is sent to ${unsigned.to}, not this account's ${source.symbol ?? "source"} jetton wallet`);
|
|
900
957
|
} else {
|
|
901
|
-
if (executionValue < input || executionValue - input >
|
|
958
|
+
if (executionValue < input || executionValue - input > ceiling2) refuse(`it attaches ${executionValue} nanoTON for a ${input} input, more than the ${ceiling2} gas ceiling on top`);
|
|
902
959
|
const pinned = provider.remote === true ? [...provider.callTargets?.(this.fromChain) ?? [], ...q.depositAddress ? [q.depositAddress] : []].map(tonRawAddress).filter((a) => !!a) : [];
|
|
903
960
|
if (pinned.length && !pinned.includes(tonRawAddress(unsigned.to) ?? "")) refuse(`remote provider '${q.provider}' sends it to ${unsigned.to}, which the app did not pin (remoteProvider callTargets)`);
|
|
904
961
|
}
|