@anywalletkit/protocol-swap2-omniston 0.2.8 → 0.3.1
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 +20 -1
- package/dist/{chunk-KNT2XSQU.js → chunk-HOTFZYSW.js} +136 -9
- package/dist/chunk-HOTFZYSW.js.map +1 -0
- package/dist/{chunk-KVDPDEJB.js → chunk-RW4XZWNC.js} +2 -2
- package/dist/index.cjs +136 -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 +10 -4
- package/dist/protocol.cjs +52 -8
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +1 -1
- package/dist/protocol.d.ts +1 -1
- package/dist/protocol.js +2 -2
- package/dist/provider-BBG2zhpu.d.cts +772 -0
- package/dist/provider-BBG2zhpu.d.ts +772 -0
- package/dist/provider.cjs +136 -9
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.d.cts +2 -590
- package/dist/provider.d.ts +2 -590
- package/dist/provider.js +9 -3
- package/dist/validators.cjs +144 -32
- package/dist/validators.cjs.map +1 -1
- package/dist/validators.d.cts +2 -93
- package/dist/validators.d.ts +2 -93
- package/dist/validators.js +144 -32
- package/dist/validators.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-KNT2XSQU.js.map +0 -1
- /package/dist/{chunk-KVDPDEJB.js.map → chunk-RW4XZWNC.js.map} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
omnistonProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HOTFZYSW.js";
|
|
4
4
|
import {
|
|
5
5
|
omniston
|
|
6
6
|
} from "./chunk-QDXFC6BC.js";
|
|
@@ -24,4 +24,4 @@ var OmnistonSwap2Protocol = class extends SingleProviderSwap2 {
|
|
|
24
24
|
export {
|
|
25
25
|
OmnistonSwap2Protocol
|
|
26
26
|
};
|
|
27
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
//# sourceMappingURL=chunk-RW4XZWNC.js.map
|
package/dist/index.cjs
CHANGED
|
@@ -43,8 +43,11 @@ __export(src_exports, {
|
|
|
43
43
|
inMemoryQuoteStore: () => inMemoryQuoteStore,
|
|
44
44
|
inMemorySecretStore: () => inMemorySecretStore,
|
|
45
45
|
omniston: () => omniston,
|
|
46
|
+
omnistonPins: () => omnistonPins,
|
|
46
47
|
omnistonProvider: () => omnistonProvider,
|
|
47
|
-
|
|
48
|
+
omnistonVerifyBuild: () => omnistonVerifyBuild,
|
|
49
|
+
validateEvmToTonOrderExtension: () => validateEvmToTonOrderExtension,
|
|
50
|
+
validateEvmTypedOrder: () => validateEvmTypedOrder
|
|
48
51
|
});
|
|
49
52
|
module.exports = __toCommonJS(src_exports);
|
|
50
53
|
|
|
@@ -465,7 +468,12 @@ function inMemoryQuoteStore() {
|
|
|
465
468
|
return {
|
|
466
469
|
save: (id, v) => void map.set(id, v),
|
|
467
470
|
load: (id) => map.get(id),
|
|
468
|
-
clear: (id) => void map.delete(id)
|
|
471
|
+
clear: (id) => void map.delete(id),
|
|
472
|
+
claim: (id, v) => {
|
|
473
|
+
if (map.has(id)) return false;
|
|
474
|
+
map.set(id, v);
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
469
477
|
};
|
|
470
478
|
}
|
|
471
479
|
function inMemorySecretStore() {
|
|
@@ -1039,6 +1047,13 @@ function validSwapSettlement(q) {
|
|
|
1039
1047
|
const v = q.settlementData.value;
|
|
1040
1048
|
return Array.isArray(v.routes) && v.routes.length > 0 && v.routes.every((route) => Array.isArray(route?.steps) && route.steps.length > 0 && route.steps.every((step) => Array.isArray(step?.chunks) && step.chunks.length > 0 && step.chunks.every((chunk) => typeof chunk?.protocol === "string" && chunk.protocol.length > 0 && isPositiveInteger(chunk.inputUnits) && isPositiveInteger(chunk.outputUnits)))) && isPositiveInteger(v.minOutputAmount) && BigInt(v.minOutputAmount) <= BigInt(q.outputUnits) && (v.recommendedMinOutputAmount === void 0 || isPositiveInteger(v.recommendedMinOutputAmount) && BigInt(v.recommendedMinOutputAmount) <= BigInt(q.outputUnits)) && (q.gasBudget === void 0 || isPositiveInteger(q.gasBudget));
|
|
1041
1049
|
}
|
|
1050
|
+
function swapSteps(v) {
|
|
1051
|
+
if (v.routes.length !== 1) return [{ protocol: `${v.routes.length}-routes`, inputJetton: void 0, outputJetton: void 0 }];
|
|
1052
|
+
return v.routes[0].steps.map((step) => {
|
|
1053
|
+
if (step.chunks.length !== 1) return { protocol: `split(${step.chunks.map((c) => c.protocol).join("|")})`, inputJetton: void 0, outputJetton: void 0 };
|
|
1054
|
+
return { protocol: step.chunks[0].protocol, inputJetton: stepJetton(step.inputAsset), outputJetton: stepJetton(step.outputAsset) };
|
|
1055
|
+
});
|
|
1056
|
+
}
|
|
1042
1057
|
function swapProtocols(v) {
|
|
1043
1058
|
const names = /* @__PURE__ */ new Set();
|
|
1044
1059
|
for (const route of v.routes) for (const step of route.steps) for (const chunk of step.chunks) names.add(chunk.protocol);
|
|
@@ -1215,6 +1230,86 @@ function mapOrderStatus(order) {
|
|
|
1215
1230
|
return { state: "pending", depositReceived };
|
|
1216
1231
|
}
|
|
1217
1232
|
}
|
|
1233
|
+
function omnistonPins(trustedEvmOrderProtocols) {
|
|
1234
|
+
const byChain = new Map(Object.entries(trustedEvmOrderProtocols).map(([chain, list]) => [chain, list.map((a) => (0, import_viem.getAddress)(a))]));
|
|
1235
|
+
return Object.freeze({ callTargets: () => [], spenders: (chain) => byChain.get(chain) ?? [] });
|
|
1236
|
+
}
|
|
1237
|
+
function omnistonVerifyBuild(hooks) {
|
|
1238
|
+
return async (quote, tx, params) => {
|
|
1239
|
+
if (tx.bodyBoc === void 0) return null;
|
|
1240
|
+
if (!params) return "the request this quote answered is unknown";
|
|
1241
|
+
if (quote.providerData?.settlement !== "swap") {
|
|
1242
|
+
if (params.sourceChain.startsWith("ton:") && params.destChain.startsWith("eip155:")) {
|
|
1243
|
+
if (!hooks.verifyTonEscrowBuild) return "a TON \u2192 EVM escrow body needs verifyTonEscrowBuild (createOmnistonTonValidators)";
|
|
1244
|
+
if (!params.refundAddress) return "the trader's TON address (refundAddress) is unknown";
|
|
1245
|
+
const floor = [quote.minDestAmount, params.minAmountOut ?? "0"].filter((v) => /^\d{1,80}$/.test(v)).map((v) => BigInt(v)).reduce((a, b) => a > b ? a : b, 0n);
|
|
1246
|
+
try {
|
|
1247
|
+
return await hooks.verifyTonEscrowBuild({
|
|
1248
|
+
payloadBocHex: import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"),
|
|
1249
|
+
ownerAddress: params.refundAddress,
|
|
1250
|
+
inputUnits: quote.sourceAmount,
|
|
1251
|
+
destinationChain: params.destChain,
|
|
1252
|
+
destinationAddress: params.destAddress,
|
|
1253
|
+
outputTokenAddress: params.destToken,
|
|
1254
|
+
minResolverSendsUnits: floor.toString()
|
|
1255
|
+
});
|
|
1256
|
+
} catch {
|
|
1257
|
+
return "the escrow body could not be checked";
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
return "only TON swap and TON \u2192 EVM escrow bodies can be checked on the client";
|
|
1261
|
+
}
|
|
1262
|
+
let steps;
|
|
1263
|
+
try {
|
|
1264
|
+
steps = JSON.parse(quote.providerData.routeSteps ?? "");
|
|
1265
|
+
} catch {
|
|
1266
|
+
return "the quote carries no route steps";
|
|
1267
|
+
}
|
|
1268
|
+
if (!Array.isArray(steps) || steps.length === 0) return "the quote carries no route steps";
|
|
1269
|
+
const source = (0, import_swap2_assets.ccAsset)(params.sourceChain, params.sourceToken);
|
|
1270
|
+
const dest = (0, import_swap2_assets.ccAssetByToken)(params.destChain, params.destToken);
|
|
1271
|
+
if (!source || !dest) return "unknown source or destination token";
|
|
1272
|
+
const protocols = (quote.providerData.protocols ?? "").split(",").filter(Boolean);
|
|
1273
|
+
let checked;
|
|
1274
|
+
try {
|
|
1275
|
+
checked = checkTonSwapPayload({
|
|
1276
|
+
payloadHex: import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"),
|
|
1277
|
+
targetAddress: tx.to,
|
|
1278
|
+
sendAmount: BigInt(tx.value),
|
|
1279
|
+
trader: params.refundAddress ?? "",
|
|
1280
|
+
dest: params.destAddress,
|
|
1281
|
+
inputUnits: quote.sourceAmount,
|
|
1282
|
+
minOutputAmount: quote.minDestAmount,
|
|
1283
|
+
inputJetton: source.contract ?? null,
|
|
1284
|
+
outputJetton: dest.contract ?? null,
|
|
1285
|
+
steps: steps.map((st) => ({ protocol: String(st.protocol), inputJetton: st.inputJetton, outputJetton: st.outputJetton })),
|
|
1286
|
+
integratorAddress: hooks.integratorAddress ?? null
|
|
1287
|
+
});
|
|
1288
|
+
} catch (e) {
|
|
1289
|
+
return e instanceof Error ? e.message.replace(/^omniston: /, "") : String(e);
|
|
1290
|
+
}
|
|
1291
|
+
const payload = parseSwapPayload(import_buffer2.Buffer.from(tx.bodyBoc, "base64").toString("hex"));
|
|
1292
|
+
const target = source.contract ? payload.jettonTransfer?.destination : tx.to;
|
|
1293
|
+
if (!target) return "the body names no swap destination";
|
|
1294
|
+
try {
|
|
1295
|
+
if (!await hooks.validateTonSwapTarget({ address: target, protocols })) return `${target} is not a recognized DEX contract for ${protocols.join("+")}`;
|
|
1296
|
+
} catch {
|
|
1297
|
+
return "the swap target could not be checked";
|
|
1298
|
+
}
|
|
1299
|
+
if (hooks.validateTonSwapLeg) {
|
|
1300
|
+
for (const leg of checked.legs) {
|
|
1301
|
+
let ok = false;
|
|
1302
|
+
try {
|
|
1303
|
+
ok = await hooks.validateTonSwapLeg(leg);
|
|
1304
|
+
} catch {
|
|
1305
|
+
ok = false;
|
|
1306
|
+
}
|
|
1307
|
+
if (!ok) return `${leg.kind} v${leg.version} leg not verified`;
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
return null;
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1218
1313
|
function omnistonProvider(opts = {}) {
|
|
1219
1314
|
opts = Object.freeze({ ...opts });
|
|
1220
1315
|
const apiUrl = opts.apiUrl ?? "wss://omni-ws.ston.fi";
|
|
@@ -1332,6 +1427,26 @@ function omnistonProvider(opts = {}) {
|
|
|
1332
1427
|
async function saveBuilt(quoteId, entry) {
|
|
1333
1428
|
await quotes.save(quoteId, JSON.stringify(entry));
|
|
1334
1429
|
}
|
|
1430
|
+
async function claimBuilt(quoteId, entry) {
|
|
1431
|
+
const json = JSON.stringify(entry);
|
|
1432
|
+
if (typeof quotes.claim === "function") {
|
|
1433
|
+
if (await quotes.claim(quoteId, json)) return true;
|
|
1434
|
+
} else if (!await quotes.load(quoteId)) {
|
|
1435
|
+
await quotes.save(quoteId, json);
|
|
1436
|
+
return true;
|
|
1437
|
+
}
|
|
1438
|
+
const existing = await loadBuilt(quoteId);
|
|
1439
|
+
if (!existing) {
|
|
1440
|
+
if (typeof quotes.claim === "function") return await quotes.claim(quoteId, json);
|
|
1441
|
+
await quotes.save(quoteId, json);
|
|
1442
|
+
return true;
|
|
1443
|
+
}
|
|
1444
|
+
const a = existing.bound, b = entry.bound;
|
|
1445
|
+
const same = !!a && !!b && a.kind === b.kind && a.srcChain === b.srcChain && sameIntentAddress(a.trader, b.trader) && sameIntentAddress(a.dest, b.dest);
|
|
1446
|
+
if (!same) return false;
|
|
1447
|
+
await quotes.save(quoteId, json);
|
|
1448
|
+
return true;
|
|
1449
|
+
}
|
|
1335
1450
|
async function loadBuilt(quoteId) {
|
|
1336
1451
|
const raw2 = await quotes.load(quoteId);
|
|
1337
1452
|
if (!raw2) return void 0;
|
|
@@ -1498,7 +1613,10 @@ function omnistonProvider(opts = {}) {
|
|
|
1498
1613
|
if (BigInt(swap.minOutputAmount) < requiredMin(q.outputUnits)) return null;
|
|
1499
1614
|
if (q.gasBudget !== void 0 && BigInt(q.gasBudget) > BigInt(maxTonExecutionNano)) return null;
|
|
1500
1615
|
const minOut = swap.minOutputAmount;
|
|
1501
|
-
await
|
|
1616
|
+
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "swap" } })) {
|
|
1617
|
+
traceFor(q.quoteId)("quote-id-reused", { kind: "swap" });
|
|
1618
|
+
return null;
|
|
1619
|
+
}
|
|
1502
1620
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
1503
1621
|
const stableOut = /^(USDT|USDC|USD₮|jUSDT)$/.test(dest.symbol);
|
|
1504
1622
|
const feeUsd = stableOut ? feeUnits / 10 ** dest.decimals : 0;
|
|
@@ -1525,6 +1643,8 @@ function omnistonProvider(opts = {}) {
|
|
|
1525
1643
|
providerData: {
|
|
1526
1644
|
settlement: "swap",
|
|
1527
1645
|
protocols: swapProtocols(swap).join(","),
|
|
1646
|
+
// For the app's own check of a remote build (omnistonVerifyBuild): the route the body must follow.
|
|
1647
|
+
routeSteps: JSON.stringify(swapSteps(swap)),
|
|
1528
1648
|
...q.gasBudget ? { gasBudget: q.gasBudget } : {},
|
|
1529
1649
|
...q.estimatedGasConsumption ? { gasEstimate: q.estimatedGasConsumption } : {}
|
|
1530
1650
|
}
|
|
@@ -1625,10 +1745,7 @@ function omnistonProvider(opts = {}) {
|
|
|
1625
1745
|
minOutputAmount: swap.minOutputAmount,
|
|
1626
1746
|
inputJetton,
|
|
1627
1747
|
outputJetton: assetContract(q.outputAsset),
|
|
1628
|
-
steps: swap
|
|
1629
|
-
if (step.chunks.length !== 1) return { protocol: `split(${step.chunks.map((c) => c.protocol).join("|")})`, inputJetton: void 0, outputJetton: void 0 };
|
|
1630
|
-
return { protocol: step.chunks[0].protocol, inputJetton: stepJetton(step.inputAsset), outputJetton: stepJetton(step.outputAsset) };
|
|
1631
|
-
}) : [{ protocol: `${swap.routes.length}-routes`, inputJetton: void 0, outputJetton: void 0 }],
|
|
1748
|
+
steps: swapSteps(swap),
|
|
1632
1749
|
integratorAddress: q.integratorAddress?.chain.$case === "ton" ? q.integratorAddress.chain.value : null
|
|
1633
1750
|
});
|
|
1634
1751
|
} catch (error) {
|
|
@@ -1916,7 +2033,9 @@ function omnistonProvider(opts = {}) {
|
|
|
1916
2033
|
const outputScaled = BigInt(q.outputUnits) * 10n ** BigInt(source.decimals);
|
|
1917
2034
|
if (outputScaled * 2n < inputScaled || outputScaled > inputScaled * 2n) return refuse2("quoted output is outside 0.5x\u20132x of the input");
|
|
1918
2035
|
if (await quoteIdInUse(q.quoteId)) return refuse2("the platform reused a quote id that already belongs to an order");
|
|
1919
|
-
await
|
|
2036
|
+
if (!await claimBuilt(q.quoteId, { quote: q, at: Date.now(), bound: { trader, dest: params.destAddress, srcChain: params.sourceChain, kind: "order" } })) {
|
|
2037
|
+
return refuse2("the platform reused a quote id that already holds another user's quote");
|
|
2038
|
+
}
|
|
1920
2039
|
const feeUnits = Number(q.protocolFeeUnits || "0") + Number(q.integratorFeeUnits || "0");
|
|
1921
2040
|
const feeUsd = feeUnits / 10 ** dest.decimals;
|
|
1922
2041
|
return {
|
|
@@ -2048,6 +2167,7 @@ function omnistonProvider(opts = {}) {
|
|
|
2048
2167
|
await forget();
|
|
2049
2168
|
throw error;
|
|
2050
2169
|
}
|
|
2170
|
+
await saveBuilt(ref.quoteId, { quote: q, at: Date.now(), ...cached.bound ? { bound: cached.bound } : {} });
|
|
2051
2171
|
return {
|
|
2052
2172
|
chain: srcChain,
|
|
2053
2173
|
to: message.targetAddress,
|
|
@@ -2091,8 +2211,15 @@ function omnistonProvider(opts = {}) {
|
|
|
2091
2211
|
})
|
|
2092
2212
|
);
|
|
2093
2213
|
if (!order) return { state: "pending" };
|
|
2094
|
-
|
|
2214
|
+
let secretsHex = await store.load(decoded.quoteId);
|
|
2095
2215
|
if (!secretsHex || cached?.quote.settlementData.$case !== "order") trace("disclosure-skipped", { gate: "context", secrets: !!secretsHex, cached: !!cached, feedStatus: order.status });
|
|
2216
|
+
if (secretsHex && cached?.quote.settlementData.$case === "order") {
|
|
2217
|
+
const [lockedTo] = await store.load(bindKey(decoded.quoteId)) ?? [];
|
|
2218
|
+
if (lockedTo !== orderBinding(bound, cached.quote)) {
|
|
2219
|
+
trace("disclosure-skipped", { gate: "binding", bound: lockedTo !== void 0, feedStatus: order.status });
|
|
2220
|
+
secretsHex = void 0;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2096
2223
|
if (secretsHex && cached?.quote.settlementData.$case === "order") {
|
|
2097
2224
|
const q = cached.quote;
|
|
2098
2225
|
const settlement = q.settlementData.value;
|