@anywalletkit/protocol-swap2-chainflip 0.4.6 → 0.4.7
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/activity.cjs +36 -14
- package/dist/activity.cjs.map +1 -1
- package/dist/activity.js +2 -2
- package/dist/{chunk-ZH5XKSCP.js → chunk-C2OITXU4.js} +2 -2
- package/dist/{chunk-RRCQYT67.js → chunk-G5FZLGMT.js} +3 -3
- package/dist/{chunk-DGLXKJQ7.js → chunk-IQSAPDND.js} +35 -15
- package/dist/chunk-IQSAPDND.js.map +1 -0
- package/dist/{chunk-RU2NXJTL.js → chunk-XUMGQNH4.js} +66 -40
- package/dist/chunk-XUMGQNH4.js.map +1 -0
- package/dist/config.cjs +34 -14
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +2 -12
- package/dist/config.d.ts +2 -12
- package/dist/config.js +1 -1
- package/dist/index.cjs +99 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +4 -4
- package/dist/protocol.cjs +99 -51
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.js +4 -4
- package/dist/provider.cjs +99 -51
- package/dist/provider.cjs.map +1 -1
- package/dist/provider.js +3 -3
- package/package.json +3 -3
- package/dist/chunk-DGLXKJQ7.js.map +0 -1
- package/dist/chunk-RU2NXJTL.js.map +0 -1
- /package/dist/{chunk-ZH5XKSCP.js.map → chunk-C2OITXU4.js.map} +0 -0
- /package/dist/{chunk-RRCQYT67.js.map → chunk-G5FZLGMT.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -47,6 +47,9 @@ __export(src_exports, {
|
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(src_exports);
|
|
49
49
|
|
|
50
|
+
// src/config.ts
|
|
51
|
+
var import_errors = require("@anywalletkit/protocol-swap2-core/errors");
|
|
52
|
+
|
|
50
53
|
// src/codec.ts
|
|
51
54
|
var import_base = require("@scure/base");
|
|
52
55
|
var import_sha2 = require("@noble/hashes/sha2.js");
|
|
@@ -227,50 +230,69 @@ var chainflip = {
|
|
|
227
230
|
supportsChain: (chain) => !!CF_CHAINS[chain],
|
|
228
231
|
supports: (from, to) => CF_SOURCE_CHAINS.has(from) && !!CF_CHAINS[to] && from !== to
|
|
229
232
|
};
|
|
233
|
+
var notes = (0, import_errors.refusalNotes)();
|
|
234
|
+
var unparsed = /* @__PURE__ */ new Set();
|
|
235
|
+
function decodeFailure(text, requestParsed) {
|
|
236
|
+
unparsed.delete(text);
|
|
237
|
+
if (requestParsed) return notes.note(text, "upstream_unavailable");
|
|
238
|
+
unparsed.add(text);
|
|
239
|
+
if (unparsed.size > 64) unparsed.delete(unparsed.values().next().value);
|
|
240
|
+
return text;
|
|
241
|
+
}
|
|
242
|
+
var reasonOf = (text) => unparsed.has(text) ? void 0 : notes.reasonOf(text);
|
|
230
243
|
function chainflipVerifyQuote(params, quote) {
|
|
244
|
+
let readingRequest = false;
|
|
231
245
|
try {
|
|
232
246
|
const src = cfAsset(params.sourceChain, params.sourceToken);
|
|
233
247
|
const dst = cfAsset(params.destChain, params.destToken);
|
|
234
248
|
const dstChain = CF_CHAINS[params.destChain];
|
|
235
249
|
const vault = Object.prototype.hasOwnProperty.call(CF_VAULTS, params.sourceChain) ? CF_VAULTS[params.sourceChain] : void 0;
|
|
236
|
-
if (!src || !dst || !dstChain || !vault || !CF_SOURCE_CHAINS.has(params.sourceChain)) return "not a vault swap this release signs";
|
|
250
|
+
if (!src || !dst || !dstChain || !vault || !CF_SOURCE_CHAINS.has(params.sourceChain)) return notes.note("not a vault swap this release signs", "unsupported_pair");
|
|
237
251
|
if (!quote.txRequest && !quote.depositAddress) return null;
|
|
238
|
-
if (!params.refundAddress) return "a live quote needs the refund address";
|
|
252
|
+
if (!params.refundAddress) return notes.note("a live quote needs the refund address", "policy_refused");
|
|
253
|
+
readingRequest = true;
|
|
239
254
|
const amountIn = BigInt(params.amountIn);
|
|
240
255
|
const dest = destAddressBytes(params.destChain, params.destAddress);
|
|
241
256
|
const refund = destAddressBytes(params.sourceChain, params.refundAddress);
|
|
257
|
+
readingRequest = false;
|
|
242
258
|
const checkParams = (p) => {
|
|
243
|
-
if (!sameBytes(fromHex(p.refundAddress), refund)) return "the refund address is not the sender";
|
|
244
|
-
if (minOutOf(amountIn, p.minPriceX128) < BigInt(quote.minDestAmount)) return "the minimum price does not guarantee the quoted minimum";
|
|
245
|
-
if (p.dca !== null || p.boostFeeBps !== 0 || p.broker.feeBps !== 0 || p.affiliates.length) return "DCA, boost, a broker fee or affiliates";
|
|
259
|
+
if (!sameBytes(fromHex(p.refundAddress), refund)) return notes.note("the refund address is not the sender", "recipient_mismatch");
|
|
260
|
+
if (minOutOf(amountIn, p.minPriceX128) < BigInt(quote.minDestAmount)) return notes.note("the minimum price does not guarantee the quoted minimum", "price_check_failed");
|
|
261
|
+
if (p.dca !== null || p.boostFeeBps !== 0 || p.broker.feeBps !== 0 || p.affiliates.length) return notes.note("DCA, boost, a broker fee or affiliates", "policy_refused");
|
|
246
262
|
return null;
|
|
247
263
|
};
|
|
248
264
|
if (params.sourceChain.startsWith("eip155:")) {
|
|
249
265
|
const tx = quote.txRequest;
|
|
250
|
-
if (quote.depositAddress || !tx?.data || tx.serializedTx !== void 0) return "an EVM vault swap is a vault call, not a deposit";
|
|
251
|
-
if (!tx.to || tx.to.toLowerCase() !== vault.toLowerCase()) return `the call targets ${tx.to}, not the Vault
|
|
266
|
+
if (quote.depositAddress || !tx?.data || tx.serializedTx !== void 0) return notes.note("an EVM vault swap is a vault call, not a deposit", "policy_refused");
|
|
267
|
+
if (!tx.to || tx.to.toLowerCase() !== vault.toLowerCase()) return notes.note(`the call targets ${tx.to}, not the Vault`, "vault_mismatch");
|
|
252
268
|
const v = decodeEvmVaultCall(tx.data);
|
|
253
|
-
if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, dest)) return "the vault call names another destination";
|
|
269
|
+
if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, dest)) return notes.note("the vault call names another destination", "recipient_mismatch");
|
|
254
270
|
if (src.token === null) {
|
|
255
|
-
if (!v.native || BigInt(tx.value ?? "0") !== amountIn || tx.approvalAddress) return "the native vault call moves another amount";
|
|
271
|
+
if (!v.native || BigInt(tx.value ?? "0") !== amountIn || tx.approvalAddress) return notes.note("the native vault call moves another amount", "policy_refused");
|
|
256
272
|
} else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(tx.value ?? "0") !== 0n || tx.approvalAddress?.toLowerCase() !== vault.toLowerCase()) {
|
|
257
|
-
return "the token vault call moves another token or amount";
|
|
273
|
+
return notes.note("the token vault call moves another token or amount", "policy_refused");
|
|
258
274
|
}
|
|
259
275
|
return checkParams(v.params);
|
|
260
276
|
}
|
|
261
|
-
if (quote.txRequest || quote.depositAddress !== vault || !quote.depositMemo)
|
|
277
|
+
if (quote.txRequest || quote.depositAddress !== vault || !quote.depositMemo) {
|
|
278
|
+
return notes.note(
|
|
279
|
+
"a Tron vault swap is a send to the Tron Vault with its note",
|
|
280
|
+
quote.txRequest ? "policy_refused" : quote.depositAddress !== vault ? "vault_mismatch" : "recipient_unverifiable"
|
|
281
|
+
);
|
|
282
|
+
}
|
|
262
283
|
const n = decodeTronNote(quote.depositMemo);
|
|
263
|
-
if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, dest)) return "the note names another destination";
|
|
284
|
+
if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, dest)) return notes.note("the note names another destination", "recipient_mismatch");
|
|
264
285
|
return checkParams(n.params);
|
|
265
286
|
} catch (e) {
|
|
266
|
-
return `the vault swap does not decode (${(e instanceof Error ? e.message : String(e)).slice(0, 120)})
|
|
287
|
+
return decodeFailure(`the vault swap does not decode (${(e instanceof Error ? e.message : String(e)).slice(0, 120)})`, !readingRequest);
|
|
267
288
|
}
|
|
268
289
|
}
|
|
269
290
|
var chainflipPins = Object.freeze({
|
|
270
291
|
callTargets: (chain) => chainflipVaultFor(chain),
|
|
271
292
|
spenders: (chain) => chainflipVaultFor(chain),
|
|
272
293
|
verifyQuote: chainflipVerifyQuote,
|
|
273
|
-
verifyBuild: (quote, tx) => quote.depositMemo && tx.memoEncoding !== "hex" ? "the Tron note is not sent as hex bytes" : null,
|
|
294
|
+
verifyBuild: (quote, tx) => quote.depositMemo && tx.memoEncoding !== "hex" ? notes.note("the Tron note is not sent as hex bytes", "policy_refused") : null,
|
|
295
|
+
reasonOf,
|
|
274
296
|
depositAddressRoutes: true
|
|
275
297
|
});
|
|
276
298
|
function chainflipVaultFor(chain) {
|
|
@@ -292,6 +314,7 @@ function describeChainflipActivity(tx, ctx) {
|
|
|
292
314
|
}
|
|
293
315
|
|
|
294
316
|
// src/provider.ts
|
|
317
|
+
var import_errors2 = require("@anywalletkit/protocol-swap2-core/errors");
|
|
295
318
|
var import_util = require("@anywalletkit/protocol-swap2-core/util");
|
|
296
319
|
var import_viem2 = require("viem");
|
|
297
320
|
var QUOTE_TTL_MS = 6e4;
|
|
@@ -299,6 +322,25 @@ var RETRY_BLOCKS = 50;
|
|
|
299
322
|
var MAX_RETRY_BLOCKS = 600;
|
|
300
323
|
var ERC20 = (0, import_viem2.parseAbi)(["function transfer(address to, uint256 amount) returns (bool)"]);
|
|
301
324
|
var INTENT_PREFIX = "cfvault:";
|
|
325
|
+
var notes2 = (0, import_errors2.refusalNotes)();
|
|
326
|
+
function backendRefusal(status, body, retryAfter) {
|
|
327
|
+
const http = (0, import_errors2.httpRefusal)(status, retryAfter);
|
|
328
|
+
const byStatus = http?.reason === "key_rejected" ? { reason: "upstream_unavailable", httpStatus: status } : http;
|
|
329
|
+
if (byStatus?.reason === "rate_limited") return byStatus;
|
|
330
|
+
const m = body?.message;
|
|
331
|
+
const said = typeof m === "string" ? backendReason(m) : void 0;
|
|
332
|
+
return said && said !== byStatus?.reason ? { reason: said } : byStatus;
|
|
333
|
+
}
|
|
334
|
+
function backendReason(message) {
|
|
335
|
+
if (/liquidity/i.test(message)) return "insufficient_liquidity";
|
|
336
|
+
if (/maximum (?:swap )?amount|above (?:the )?max|too (?:large|big|high)|exceeds? (?:the )?max/i.test(message)) return "amount_too_large";
|
|
337
|
+
if (/minimum (?:swap |deposit )?amount|below (?:the )?minimum|lower than (?:the )?(?:estimated|minimum)|too (?:small|low)/i.test(message)) return "amount_too_small";
|
|
338
|
+
if (/halt|paus|maintenance|disabled|suspend|not enabled/i.test(message)) return "chain_halted";
|
|
339
|
+
if (/rate.?limit|too many requests/i.test(message)) return "rate_limited";
|
|
340
|
+
if (/not supported|unsupported|unknown asset|invalid asset/i.test(message)) return "unsupported_pair";
|
|
341
|
+
if (/no (?:route|quote)|could not find/i.test(message)) return "no_route";
|
|
342
|
+
return void 0;
|
|
343
|
+
}
|
|
302
344
|
function chainflipProvider(config = {}) {
|
|
303
345
|
config = Object.freeze({ ...config });
|
|
304
346
|
const base = new URL(config.apiUrl ?? CF_API_DEFAULT).toString().replace(/\/$/, "");
|
|
@@ -310,18 +352,18 @@ function chainflipProvider(config = {}) {
|
|
|
310
352
|
await new Promise((r) => setTimeout(r, 1200));
|
|
311
353
|
continue;
|
|
312
354
|
}
|
|
313
|
-
return { ok: res.ok, status: res.status, body };
|
|
355
|
+
return { ok: res.ok, status: res.status, body, retryAfter: res.headers?.get?.("retry-after") ?? null };
|
|
314
356
|
}
|
|
315
357
|
};
|
|
316
358
|
const checkParams = (p, want) => {
|
|
317
|
-
if (!sameBytes(fromHex(p.refundAddress), want.refund)) return `refund address ${p.refundAddress} is not the sender
|
|
318
|
-
if (p.minPriceX128 < want.minPriceX128) return "minimum price is below the one requested";
|
|
319
|
-
if (p.retryDurationBlocks > MAX_RETRY_BLOCKS) return `retry window ${p.retryDurationBlocks} blocks is too long
|
|
320
|
-
if (p.maxOraclePriceSlippageBps !== want.oracle) return "oracle slippage guard differs from the request";
|
|
321
|
-
if (p.dca !== null) return "unexpected DCA parameters";
|
|
322
|
-
if (p.boostFeeBps !== 0) return "unexpected boost fee";
|
|
323
|
-
if (p.broker.feeBps !== 0) return `broker takes ${p.broker.feeBps} bps
|
|
324
|
-
if (p.affiliates.length) return "unexpected affiliates";
|
|
359
|
+
if (!sameBytes(fromHex(p.refundAddress), want.refund)) return notes2.note(`refund address ${p.refundAddress} is not the sender`, "recipient_mismatch");
|
|
360
|
+
if (p.minPriceX128 < want.minPriceX128) return notes2.note("minimum price is below the one requested", "price_check_failed");
|
|
361
|
+
if (p.retryDurationBlocks > MAX_RETRY_BLOCKS) return notes2.note(`retry window ${p.retryDurationBlocks} blocks is too long`, "policy_refused");
|
|
362
|
+
if (p.maxOraclePriceSlippageBps !== want.oracle) return notes2.note("oracle slippage guard differs from the request", "price_check_failed");
|
|
363
|
+
if (p.dca !== null) return notes2.note("unexpected DCA parameters", "policy_refused");
|
|
364
|
+
if (p.boostFeeBps !== 0) return notes2.note("unexpected boost fee", "policy_refused");
|
|
365
|
+
if (p.broker.feeBps !== 0) return notes2.note(`broker takes ${p.broker.feeBps} bps`, "policy_refused");
|
|
366
|
+
if (p.affiliates.length) return notes2.note("unexpected affiliates", "policy_refused");
|
|
325
367
|
return null;
|
|
326
368
|
};
|
|
327
369
|
return {
|
|
@@ -337,16 +379,19 @@ function chainflipProvider(config = {}) {
|
|
|
337
379
|
},
|
|
338
380
|
async getQuote(params, signal) {
|
|
339
381
|
const dry = params.dry !== false;
|
|
340
|
-
const refuse = (reason) => {
|
|
341
|
-
|
|
382
|
+
const refuse = (reason, why) => {
|
|
383
|
+
const info = typeof why === "string" ? { reason: why } : why;
|
|
384
|
+
if (info) params.onRefusal?.(`chainflip: ${reason}`, info);
|
|
385
|
+
else params.onRefusal?.(`chainflip: ${reason}`);
|
|
342
386
|
return null;
|
|
343
387
|
};
|
|
344
|
-
|
|
388
|
+
const unreachable = () => signal?.aborted ? void 0 : "upstream_unavailable";
|
|
389
|
+
if (!chainflip.supports(params.sourceChain, params.destChain)) return refuse(`no vault swap ${params.sourceChain} \u2192 ${params.destChain}`, "unsupported_pair");
|
|
345
390
|
const src = cfAsset(params.sourceChain, params.sourceToken);
|
|
346
391
|
const dst = cfAsset(params.destChain, params.destToken);
|
|
347
|
-
if (!src || !dst) return refuse(`asset not listed (${params.sourceToken} on ${params.sourceChain} \u2192 ${params.destToken} on ${params.destChain})
|
|
392
|
+
if (!src || !dst) return refuse(`asset not listed (${params.sourceToken} on ${params.sourceChain} \u2192 ${params.destToken} on ${params.destChain})`, "unsupported_pair");
|
|
348
393
|
const amountIn = BigInt(params.amountIn);
|
|
349
|
-
if (amountIn < src.minDeposit) return refuse(`below the minimum deposit (${src.minDeposit} ${src.asset})
|
|
394
|
+
if (amountIn < src.minDeposit) return refuse(`below the minimum deposit (${src.minDeposit} ${src.asset})`, "amount_too_small");
|
|
350
395
|
let destBytes;
|
|
351
396
|
try {
|
|
352
397
|
destBytes = destAddressBytes(params.destChain, params.destAddress);
|
|
@@ -355,21 +400,23 @@ function chainflipProvider(config = {}) {
|
|
|
355
400
|
}
|
|
356
401
|
const qs = new URLSearchParams({ amount: params.amountIn, srcChain: src.chain, srcAsset: src.asset, destChain: dst.chain, destAsset: dst.asset, isVaultSwap: "true", isOnChain: "false", dcaV2Enabled: "false" });
|
|
357
402
|
let q;
|
|
403
|
+
let answered;
|
|
358
404
|
try {
|
|
359
405
|
const r = await call(`/v2/quote?${qs.toString()}`, {}, signal);
|
|
360
|
-
if (!r.ok) return refuse(`quote ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}
|
|
406
|
+
if (!r.ok) return refuse(`quote ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}`, backendRefusal(r.status, r.body, r.retryAfter));
|
|
407
|
+
answered = r.body;
|
|
361
408
|
q = r.body?.find((x) => x.type === "REGULAR") ?? r.body?.[0];
|
|
362
409
|
} catch (e) {
|
|
363
|
-
return refuse(`quote failed: ${e.message.slice(0, 160)}
|
|
410
|
+
return refuse(`quote failed: ${e.message.slice(0, 160)}`, unreachable());
|
|
364
411
|
}
|
|
365
|
-
if (!q?.egressAmount || !/^\d+$/.test(q.egressAmount)) return refuse("quote without an egress amount");
|
|
366
|
-
if (q.type && q.type !== "REGULAR") return refuse(`${q.type} quotes are not supported
|
|
412
|
+
if (!q?.egressAmount || !/^\d+$/.test(q.egressAmount)) return refuse("quote without an egress amount", Array.isArray(answered) && answered.length === 0 ? "no_route" : unreachable());
|
|
413
|
+
if (q.type && q.type !== "REGULAR") return refuse(`${q.type} quotes are not supported`, "unsupported_pair");
|
|
367
414
|
const expected = BigInt(q.egressAmount);
|
|
368
415
|
const slipBps = params.slippageBps ?? Math.round((q.recommendedSlippageTolerancePercent ?? 1) * 100);
|
|
369
416
|
const byTolerance = expected * BigInt(1e4 - Math.min(9999, Math.max(0, slipBps))) / 10000n;
|
|
370
417
|
const callerFloor = params.minAmountOut !== void 0 ? BigInt(params.minAmountOut) : void 0;
|
|
371
418
|
const minOut = callerFloor === void 0 ? byTolerance : params.slippageBps !== void 0 && byTolerance > callerFloor ? byTolerance : callerFloor;
|
|
372
|
-
if (minOut > expected) return refuse(`floor ${minOut} above the expected output ${expected}
|
|
419
|
+
if (minOut > expected) return refuse(`floor ${minOut} above the expected output ${expected}`, "price_check_failed");
|
|
373
420
|
const minPriceX128 = minPriceX128For(amountIn, minOut);
|
|
374
421
|
const guaranteed = minOutOf(amountIn, minPriceX128);
|
|
375
422
|
const oracle = config.maxOraclePriceSlippageBps !== void 0 ? config.maxOraclePriceSlippageBps : q.recommendedLivePriceSlippageTolerancePercent !== void 0 ? Math.round(q.recommendedLivePriceSlippageTolerancePercent * 100) : null;
|
|
@@ -387,7 +434,7 @@ function chainflipProvider(config = {}) {
|
|
|
387
434
|
validUntilMs: Date.now() + QUOTE_TTL_MS
|
|
388
435
|
};
|
|
389
436
|
if (dry) return { ...common, intentId: `dry:${crypto.randomUUID()}`, depositAddress: "", depositMemo: null };
|
|
390
|
-
if (!params.refundAddress) return refuse("live quote without a refund address");
|
|
437
|
+
if (!params.refundAddress) return refuse("live quote without a refund address", "policy_refused");
|
|
391
438
|
let refund;
|
|
392
439
|
try {
|
|
393
440
|
refund = destAddressBytes(params.sourceChain, params.refundAddress);
|
|
@@ -406,26 +453,26 @@ function chainflipProvider(config = {}) {
|
|
|
406
453
|
let enc;
|
|
407
454
|
try {
|
|
408
455
|
const r = await call("/api/encodeVaultSwapData", { method: "POST", body: JSON.stringify(body) }, signal);
|
|
409
|
-
if (!r.ok) return refuse(`encode ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}
|
|
456
|
+
if (!r.ok) return refuse(`encode ${r.status}: ${String(r.body?.message ?? "").slice(0, 160)}`, backendRefusal(r.status, r.body, r.retryAfter));
|
|
410
457
|
enc = r.body ?? {};
|
|
411
458
|
} catch (e) {
|
|
412
|
-
return refuse(`encode failed: ${e.message.slice(0, 160)}
|
|
459
|
+
return refuse(`encode failed: ${e.message.slice(0, 160)}`, unreachable());
|
|
413
460
|
}
|
|
414
461
|
const want = { refund, minPriceX128, oracle };
|
|
415
462
|
const vault = CF_VAULTS[params.sourceChain];
|
|
416
463
|
const dstChain = CF_CHAINS[params.destChain];
|
|
417
464
|
try {
|
|
418
465
|
if (params.sourceChain.startsWith("eip155:")) {
|
|
419
|
-
if (!enc.to || enc.to.toLowerCase() !== vault.toLowerCase()) return refuse(`encoder targets ${enc.to}, not the ${src.chain} Vault
|
|
466
|
+
if (!enc.to || enc.to.toLowerCase() !== vault.toLowerCase()) return refuse(`encoder targets ${enc.to}, not the ${src.chain} Vault`, !enc.to ? unreachable() : "vault_mismatch");
|
|
420
467
|
const v = decodeEvmVaultCall(enc.calldata ?? "0x");
|
|
421
|
-
if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, destBytes)) return refuse("encoded destination differs from the request");
|
|
468
|
+
if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, destBytes)) return refuse("encoded destination differs from the request", "recipient_mismatch");
|
|
422
469
|
if (src.token === null) {
|
|
423
|
-
if (!v.native || BigInt(enc.value ?? "0") !== amountIn) return refuse("native vault call with a different amount");
|
|
470
|
+
if (!v.native || BigInt(enc.value ?? "0") !== amountIn) return refuse("native vault call with a different amount", "policy_refused");
|
|
424
471
|
} else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(enc.value ?? "0") !== 0n) {
|
|
425
|
-
return refuse("token vault call with a different token or amount");
|
|
472
|
+
return refuse("token vault call with a different token or amount", "policy_refused");
|
|
426
473
|
}
|
|
427
474
|
const bad2 = checkParams(v.params, want);
|
|
428
|
-
if (bad2) return refuse(bad2);
|
|
475
|
+
if (bad2) return refuse(bad2, notes2.reasonOf(bad2));
|
|
429
476
|
return {
|
|
430
477
|
...common,
|
|
431
478
|
intentId: `${INTENT_PREFIX}${params.sourceChain}`,
|
|
@@ -435,17 +482,18 @@ function chainflipProvider(config = {}) {
|
|
|
435
482
|
providerData: { kind: "evm", srcAsset: String(src.id), dstAsset: String(dst.id) }
|
|
436
483
|
};
|
|
437
484
|
}
|
|
438
|
-
if (enc.to !== vault) return refuse(`encoder targets ${enc.to}, not the Tron Vault
|
|
439
|
-
if (!enc.note) return refuse("Tron vault swap without a note");
|
|
485
|
+
if (enc.to !== vault) return refuse(`encoder targets ${enc.to}, not the Tron Vault`, !enc.to ? unreachable() : "vault_mismatch");
|
|
486
|
+
if (!enc.note) return refuse("Tron vault swap without a note", "recipient_unverifiable");
|
|
440
487
|
if (src.token !== null) {
|
|
441
|
-
if (enc.sourceTokenAddress !== src.token) return refuse(`source token ${enc.sourceTokenAddress} is not ${src.asset}
|
|
488
|
+
if (enc.sourceTokenAddress !== src.token) return refuse(`source token ${enc.sourceTokenAddress} is not ${src.asset}`, "policy_refused");
|
|
442
489
|
const t = (0, import_viem2.decodeFunctionData)({ abi: ERC20, data: enc.calldata ?? "0x" });
|
|
443
|
-
|
|
490
|
+
const toVault = sameBytes(fromHex(String(t.args[0])), tronToBytes(vault));
|
|
491
|
+
if (!toVault || t.args[1] !== amountIn) return refuse("TRC-20 transfer is not the amount to the Vault", toVault ? "policy_refused" : "vault_mismatch");
|
|
444
492
|
}
|
|
445
493
|
const n = decodeTronNote(enc.note);
|
|
446
|
-
if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, destBytes)) return refuse("note names another destination");
|
|
494
|
+
if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, destBytes)) return refuse("note names another destination", "recipient_mismatch");
|
|
447
495
|
const bad = checkParams(n.params, want);
|
|
448
|
-
if (bad) return refuse(bad);
|
|
496
|
+
if (bad) return refuse(bad, notes2.reasonOf(bad));
|
|
449
497
|
return {
|
|
450
498
|
...common,
|
|
451
499
|
intentId: `${INTENT_PREFIX}${params.sourceChain}`,
|
|
@@ -454,20 +502,20 @@ function chainflipProvider(config = {}) {
|
|
|
454
502
|
providerData: { kind: "tron", memoEncoding: "hex", srcAsset: String(src.id), dstAsset: String(dst.id) }
|
|
455
503
|
};
|
|
456
504
|
} catch (e) {
|
|
457
|
-
return refuse(`encoder output does not decode: ${e.message.slice(0, 160)}
|
|
505
|
+
return refuse(`encoder output does not decode: ${e.message.slice(0, 160)}`, "upstream_unavailable");
|
|
458
506
|
}
|
|
459
507
|
},
|
|
460
508
|
async buildDeposit(quote) {
|
|
461
509
|
if (quote.providerData?.kind === "evm") {
|
|
462
510
|
const tx = quote.txRequest;
|
|
463
|
-
if (!tx?.to || !tx.data) throw
|
|
511
|
+
if (!tx?.to || !tx.data) throw (0, import_errors2.refusal)("policy_refused", "chainflip: quote has no vault call");
|
|
464
512
|
return { chain: "", to: tx.to, value: tx.value ?? "0", data: tx.data, ...tx.chainId !== void 0 ? { chainId: tx.chainId } : {}, ...tx.approvalAddress ? { approvalAddress: tx.approvalAddress } : {} };
|
|
465
513
|
}
|
|
466
514
|
if (quote.providerData?.kind === "tron") {
|
|
467
|
-
if (!quote.depositAddress || !quote.depositMemo) throw
|
|
515
|
+
if (!quote.depositAddress || !quote.depositMemo) throw (0, import_errors2.refusal)("policy_refused", "chainflip: Tron quote without vault or note");
|
|
468
516
|
return { chain: "", to: quote.depositAddress, value: quote.sourceAmount, memo: quote.depositMemo, memoEncoding: "hex" };
|
|
469
517
|
}
|
|
470
|
-
throw
|
|
518
|
+
throw (0, import_errors2.refusal)("policy_refused", "chainflip: not a live vault-swap quote");
|
|
471
519
|
},
|
|
472
520
|
async trackIntent(ref) {
|
|
473
521
|
if (!ref.sourceTxHash) return { state: "pending" };
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/codec.ts","../src/config.ts","../src/activity.ts","../src/provider.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./config.js\";\nexport * from \"./provider.js\";\nexport * from \"./codec.js\";\nexport {ChainflipSwap2Protocol, type ChainflipSwap2Config} from \"./protocol.js\";\nexport {ChainflipSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\n","/**\n * Decoders for what Chainflip's encoder returns, so a vault swap is checked byte by byte before anyone signs it:\n * - VersionedCfParameters (SCALE): retry window, refund address, minimum price (X128), oracle slippage, DCA, boost,\n * broker + its fee, affiliates — the EVM vault call's `cfParameters` and the tail of the Tron note;\n * - the Tron note: output asset id, encoded destination address, CCM option, then the length-prefixed parameters;\n * - the EVM vault calls xSwapNative / xSwapToken.\n * Layouts were decoded from live encoder outputs (2026-10-20) and match the state chain's types.\n */\nimport {base58} from \"@scure/base\";\nimport {sha256} from \"@noble/hashes/sha2.js\";\nimport {decodeFunctionData, parseAbi, type Hex} from \"viem\";\n\nexport interface CfParameters {\n version: number;\n retryDurationBlocks: number;\n /** raw refund address bytes (20 for EVM / Tron, 32 for Solana) as 0x-hex */\n refundAddress: Hex;\n /** minimum output price × 2^128, scaled by 10^(destDecimals − srcDecimals) */\n minPriceX128: bigint;\n refundCcm: boolean;\n maxOraclePriceSlippageBps: number | null;\n dca: {chunks: number; intervalBlocks: number} | null;\n boostFeeBps: number;\n broker: {account: Hex; feeBps: number};\n affiliates: {account: number; feeBps: number}[];\n}\n\nclass Reader {\n i = 0;\n constructor(readonly b: Uint8Array) {}\n need(n: number) { if (this.i + n > this.b.length) throw new Error(`chainflip codec: truncated at ${this.i} (+${n} of ${this.b.length})`); }\n u8() { this.need(1); return this.b[this.i++]!; }\n bytes(n: number) { this.need(n); const out = this.b.slice(this.i, this.i + n); this.i += n; return out; }\n uLE(n: number): bigint { const x = this.bytes(n); let v = 0n; for (let k = n - 1; k >= 0; k--) v = (v << 8n) | BigInt(x[k]!); return v; }\n /** Little-endian unsigned of up to 6 bytes as a number (exact: below 2^48). */\n uNum(n: number): number { if (n > 6) throw new Error(\"chainflip codec: uNum takes at most 6 bytes\"); const x = this.bytes(n); let v = 0; for (let k = n - 1; k >= 0; k--) v = v * 256 + x[k]!; return v; }\n /** SCALE compact integer */\n compact(): number {\n const first = this.u8();\n const mode = first & 3;\n if (mode === 0) return first >> 2;\n if (mode === 1) return ((this.u8() << 8) | first) >> 2;\n if (mode === 2) { const rest = this.uNum(3); return ((rest << 8) | first) >>> 2; }\n throw new Error(\"chainflip codec: big compact integers are not used here\");\n }\n done() { if (this.i !== this.b.length) throw new Error(`chainflip codec: ${this.b.length - this.i} trailing bytes`); }\n}\n\nexport const toHex = (b: Uint8Array): Hex => `0x${[...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\")}` as Hex;\nexport function fromHex(h: string): Uint8Array {\n const s = h.startsWith(\"0x\") ? h.slice(2) : h;\n if (s.length % 2 || /[^0-9a-f]/i.test(s)) throw new Error(\"chainflip codec: not hex\");\n return Uint8Array.from(s.match(/../g) ?? [], (x) => Number.parseInt(x, 16));\n}\n\n/** VersionedCfParameters V1. `refundLen` = 20 for EVM / Tron sources, 32 for Solana. */\nexport function decodeCfParameters(bytes: Uint8Array, refundLen: 20 | 32): CfParameters {\n const r = new Reader(bytes);\n const p = readCfParameters(r, refundLen);\n r.done();\n return p;\n}\n\nfunction readCfParameters(r: Reader, refundLen: number): CfParameters {\n const version = r.u8();\n if (version !== 1) throw new Error(`chainflip codec: cf parameters version ${version}`);\n // ccm_additional_data is `()` for non-CCM swaps: zero bytes\n const retryDurationBlocks = r.uNum(4);\n const refundAddress = toHex(r.bytes(refundLen));\n const minPriceX128 = r.uLE(32);\n const refundCcm = r.u8() !== 0;\n if (refundCcm) throw new Error(\"chainflip codec: refund CCM metadata is not expected\");\n const maxOraclePriceSlippageBps = r.u8() ? r.uNum(2) : null;\n const dca = r.u8() ? {chunks: r.uNum(4), intervalBlocks: r.uNum(4)} : null;\n const boostFeeBps = r.u8();\n const broker = {account: toHex(r.bytes(32)), feeBps: r.uNum(2)};\n const n = r.compact();\n const affiliates = Array.from({length: n}, () => ({account: r.u8(), feeBps: r.uNum(2)}));\n return {version, retryDurationBlocks, refundAddress, minPriceX128, refundCcm, maxOraclePriceSlippageBps, dca, boostFeeBps, broker, affiliates};\n}\n\nexport interface TronNote {\n outputAsset: number;\n /** EncodedAddress variant of the destination (Eth 0, Dot 1, Btc 2, Arb 3, Sol 4, Hub 5, Tron 6) and its raw bytes */\n destTag: number;\n destAddress: Uint8Array;\n ccm: boolean;\n params: CfParameters;\n}\n\n/** Address byte length per encoded-address tag (EncodedAddress enum: Eth, Dot, Btc, Arb, Sol, Hub, Tron …). */\nconst TAG_LEN: Record<number, number | \"vec\"> = {0: 20, 1: 32, 2: \"vec\", 3: 20, 4: 32, 5: 32, 6: 20};\n\n/** The note a Tron vault swap carries in raw_data.data. */\nexport function decodeTronNote(note: string): TronNote {\n const r = new Reader(fromHex(note));\n const outputAsset = r.u8();\n const destTag = r.u8();\n const len = TAG_LEN[destTag];\n if (len === undefined) throw new Error(`chainflip codec: unknown address tag ${destTag}`);\n const destAddress = len === \"vec\" ? r.bytes(r.compact()) : r.bytes(len);\n const ccm = r.u8() !== 0;\n if (ccm) throw new Error(\"chainflip codec: CCM swaps are not expected\");\n const paramsLen = r.compact();\n const start = r.i;\n const params = readCfParameters(r, 20);\n if (r.i - start !== paramsLen) throw new Error(`chainflip codec: cf parameters length ${r.i - start} ≠ declared ${paramsLen}`);\n r.done();\n return {outputAsset, destTag, destAddress, ccm, params};\n}\n\nconst VAULT_ABI = parseAbi([\n \"function xSwapNative(uint32 dstChain, bytes dstAddress, uint32 dstToken, bytes cfParameters) payable\",\n \"function xSwapToken(uint32 dstChain, bytes dstAddress, uint32 dstToken, address srcToken, uint256 amount, bytes cfParameters)\",\n]);\n\nexport interface EvmVaultCall {\n native: boolean;\n dstChain: number;\n dstAddress: Uint8Array;\n dstToken: number;\n srcToken: string | null;\n amount: bigint | null;\n params: CfParameters;\n}\n\nexport function decodeEvmVaultCall(data: string): EvmVaultCall {\n const d = decodeFunctionData({abi: VAULT_ABI, data: data as Hex});\n if (d.functionName === \"xSwapNative\") {\n const [dstChain, dstAddress, dstToken, cf] = d.args;\n return {native: true, dstChain, dstAddress: fromHex(dstAddress), dstToken, srcToken: null, amount: null, params: decodeCfParameters(fromHex(cf), 20)};\n }\n const [dstChain, dstAddress, dstToken, srcToken, amount, cf] = d.args;\n return {native: false, dstChain, dstAddress: fromHex(dstAddress), dstToken, srcToken, amount, params: decodeCfParameters(fromHex(cf), 20)};\n}\n\n/** Tron base58check `T…` ↔ the 20 raw bytes Chainflip encodes (0x41 prefix dropped). */\nexport function tronToBytes(address: string): Uint8Array {\n const b = base58.decode(address);\n if (b.length !== 25 || b[0] !== 0x41) throw new Error(`not a Tron address: ${address}`);\n const check = sha256(sha256(b.subarray(0, 21))).subarray(0, 4);\n if (toHex(check) !== toHex(b.subarray(21))) throw new Error(`bad Tron checksum: ${address}`);\n return b.subarray(1, 21);\n}\n\n/** The raw bytes a destination address is encoded with, per destination chain (EVM / Tron 20, Solana 32, BTC ASCII). */\nexport function destAddressBytes(chain: string, address: string): Uint8Array {\n if (chain.startsWith(\"eip155:\")) return fromHex(address);\n if (chain.startsWith(\"tron:\")) return tronToBytes(address);\n if (chain.startsWith(\"solana:\")) { const b = base58.decode(address); if (b.length !== 32) throw new Error(`not a Solana address: ${address}`); return b; }\n if (chain.startsWith(\"bitcoin:\")) return new TextEncoder().encode(address);\n throw new Error(`chainflip: no address encoding for ${chain}`);\n}\n\nexport const sameBytes = (a: Uint8Array, b: Uint8Array) => a.length === b.length && a.every((x, i) => x === b[i]);\n\n/** minPriceX128 for a guaranteed output: ceil(minOut × 2^128 / amountIn) (base units on both sides carry the decimals). */\nexport function minPriceX128For(amountIn: bigint, minOut: bigint): bigint {\n return (minOut * 2n ** 128n + amountIn - 1n) / amountIn;\n}\n/** The output a min price guarantees for `amountIn` (floor). */\nexport function minOutOf(amountIn: bigint, minPriceX128: bigint): bigint {\n return (amountIn * minPriceX128) / 2n ** 128n;\n}\n","/**\n * Chainflip (JIT-AMM state chain) — chains, assets and contracts as the public backend and the vault encodings name them.\n * Asset ids, chain ids and decimals are the protocol's own (`cf_environment` / networkInfo, verified 2026-10-20); the\n * contract addresses are Chainflip's mainnet deployments (docs mainnet-addresses, confirmed by live encodings).\n *\n * Only VAULT SWAPS are offered: the donor signs a transaction whose every Chainflip parameter (destination, minimum price,\n * refund address) is decoded and checked locally before signing — no off-chain deposit channel to trust, and on Tron no\n * 3.4 USDT ingress fee. Sources: EVM (Ethereum, Arbitrum) and Tron in this release; Solana / Bitcoin vault swaps need an\n * instruction / OP_RETURN builder and come next. Destinations: every live chain.\n */\nimport type {Quote, QuoteParams, RemotePins, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeEvmVaultCall, decodeTronNote, destAddressBytes, fromHex, minOutOf, sameBytes, type CfParameters} from \"./codec.js\";\n\nexport type CfChain = \"Ethereum\" | \"Bitcoin\" | \"Arbitrum\" | \"Solana\" | \"Tron\";\n\nexport interface CfAsset {\n chain: CfChain;\n /** the API's asset symbol */\n asset: string;\n /** the u32 asset id inside vault encodings */\n id: number;\n decimals: number;\n /** token contract / mint on its chain, null for the native coin */\n token: string | null;\n /** smallest deposit the state chain accepts (base units) */\n minDeposit: bigint;\n}\n\n/**\n * CAIP-2 → Chainflip chain: `id` = the ForeignChain number an EVM vault call names (`dstChain`), `addrTag` = the\n * EncodedAddress variant a Tron note names (Eth 0, Dot 1, Btc 2, Arb 3, Sol 4, Hub 5, Tron 6) — two different enums.\n */\nexport const CF_CHAINS: Readonly<Record<string, {name: CfChain; id: number; addrTag: number}>> = {\n \"eip155:1\": {name: \"Ethereum\", id: 1, addrTag: 0},\n \"bitcoin:mainnet\": {name: \"Bitcoin\", id: 3, addrTag: 2},\n \"eip155:42161\": {name: \"Arbitrum\", id: 4, addrTag: 3},\n \"solana:mainnet\": {name: \"Solana\", id: 5, addrTag: 4},\n \"tron:728126428\": {name: \"Tron\", id: 7, addrTag: 6},\n};\n\nexport const CF_ASSETS: readonly CfAsset[] = [\n {chain: \"Ethereum\", asset: \"ETH\", id: 1, decimals: 18, token: null, minDeposit: 10n ** 16n},\n {chain: \"Ethereum\", asset: \"USDC\", id: 3, decimals: 6, token: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\", minDeposit: 20_000_000n},\n {chain: \"Ethereum\", asset: \"USDT\", id: 8, decimals: 6, token: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\", minDeposit: 20_000_000n},\n {chain: \"Ethereum\", asset: \"WBTC\", id: 14, decimals: 8, token: \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\", minDeposit: 40_000n},\n {chain: \"Bitcoin\", asset: \"BTC\", id: 5, decimals: 8, token: null, minDeposit: 40_000n},\n {chain: \"Arbitrum\", asset: \"ETH\", id: 6, decimals: 18, token: null, minDeposit: 3_900_000_000_000_000n},\n {chain: \"Arbitrum\", asset: \"USDC\", id: 7, decimals: 6, token: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\", minDeposit: 10_000_000n},\n {chain: \"Arbitrum\", asset: \"USDT\", id: 15, decimals: 6, token: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\", minDeposit: 10_000_000n},\n {chain: \"Solana\", asset: \"SOL\", id: 9, decimals: 9, token: null, minDeposit: 68_000_000n},\n {chain: \"Solana\", asset: \"USDC\", id: 10, decimals: 6, token: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\", minDeposit: 10_000_000n},\n {chain: \"Solana\", asset: \"USDT\", id: 16, decimals: 6, token: \"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\", minDeposit: 10_000_000n},\n {chain: \"Tron\", asset: \"TRX\", id: 17, decimals: 6, token: null, minDeposit: 30_000_000n},\n {chain: \"Tron\", asset: \"USDT\", id: 18, decimals: 6, token: \"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t\", minDeposit: 10_000_000n},\n];\n\n/** Vault contracts that receive vault swaps (the deposit transaction's target). */\nexport const CF_VAULTS: Readonly<Record<string, string>> = {\n \"eip155:1\": \"0xF5e10380213880111522dd0efD3dbb45b9f62Bcc\",\n \"eip155:42161\": \"0x79001a5e762f3bEFC8e5871b42F6734e00498920\",\n \"tron:728126428\": \"TEcDijvKSXcfWT7S6rd44H5vNgufm7Y4XC\",\n};\n\n/** Sources this release signs (vault swaps the engine can execute and the verifier can decode). */\nexport const CF_SOURCE_CHAINS = new Set([\"eip155:1\", \"eip155:42161\", \"tron:728126428\"]);\n\nexport const CF_API_DEFAULT = \"https://chainflip-swap.chainflip.io\";\n\nconst sameToken = (chain: string, a: string, b: string) => (chain.startsWith(\"eip155:\") ? a.toLowerCase() === b.toLowerCase() : a === b);\nconst NATIVE = new Set([\"\", \"native\", \"0x0000000000000000000000000000000000000000\"]);\n\n/** The Chainflip asset for a CAIP-2 chain + token (contract / mint, a native marker, or the asset symbol). */\nexport function cfAsset(chain: string, token: string): CfAsset | undefined {\n const c = CF_CHAINS[chain];\n if (!c) return undefined;\n const on = CF_ASSETS.filter((a) => a.chain === c.name);\n if (NATIVE.has(token.toLowerCase())) return on.find((a) => a.token === null);\n return on.find((a) => (a.token !== null && sameToken(chain, a.token, token)) || a.asset === token.toUpperCase());\n}\n\nexport const chainflip = {\n supportsChain: (chain: string) => !!CF_CHAINS[chain],\n supports: (from: string, to: string) => CF_SOURCE_CHAINS.has(from) && !!CF_CHAINS[to] && from !== to,\n};\n\n/**\n * The provider's own decode of a vault swap, run on the client against the app's request (scan 2026-10-28, F9): an\n * EVM source is a vault call (`xSwapNative` / `xSwapToken`) on the pinned Vault, a Tron source a send to the pinned\n * Tron Vault whose note carries the swap; either way the destination chain, asset and address, the source token and\n * amount, the refund address and a minimum price that guarantees the quoted minimum must be the app's, with no DCA,\n * boost, broker fee or affiliates. The reason it fails, or null.\n */\nexport function chainflipVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n try {\n const src = cfAsset(params.sourceChain, params.sourceToken);\n const dst = cfAsset(params.destChain, params.destToken);\n const dstChain = CF_CHAINS[params.destChain];\n const vault = Object.prototype.hasOwnProperty.call(CF_VAULTS, params.sourceChain) ? CF_VAULTS[params.sourceChain] : undefined;\n if (!src || !dst || !dstChain || !vault || !CF_SOURCE_CHAINS.has(params.sourceChain)) return \"not a vault swap this release signs\";\n // A dry quote lists a route and pays nobody; execution re-quotes live.\n if (!quote.txRequest && !quote.depositAddress) return null;\n if (!params.refundAddress) return \"a live quote needs the refund address\";\n const amountIn = BigInt(params.amountIn);\n const dest = destAddressBytes(params.destChain, params.destAddress);\n const refund = destAddressBytes(params.sourceChain, params.refundAddress);\n const checkParams = (p: CfParameters): string | null => {\n if (!sameBytes(fromHex(p.refundAddress), refund)) return \"the refund address is not the sender\";\n if (minOutOf(amountIn, p.minPriceX128) < BigInt(quote.minDestAmount)) return \"the minimum price does not guarantee the quoted minimum\";\n if (p.dca !== null || p.boostFeeBps !== 0 || p.broker.feeBps !== 0 || p.affiliates.length) return \"DCA, boost, a broker fee or affiliates\";\n return null;\n };\n if (params.sourceChain.startsWith(\"eip155:\")) {\n const tx = quote.txRequest;\n if (quote.depositAddress || !tx?.data || tx.serializedTx !== undefined) return \"an EVM vault swap is a vault call, not a deposit\";\n if (!tx.to || tx.to.toLowerCase() !== vault.toLowerCase()) return `the call targets ${tx.to}, not the Vault`;\n const v = decodeEvmVaultCall(tx.data);\n if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, dest)) return \"the vault call names another destination\";\n if (src.token === null) {\n if (!v.native || BigInt(tx.value ?? \"0\") !== amountIn || tx.approvalAddress) return \"the native vault call moves another amount\";\n } else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(tx.value ?? \"0\") !== 0n ||\n tx.approvalAddress?.toLowerCase() !== vault.toLowerCase()) {\n return \"the token vault call moves another token or amount\";\n }\n return checkParams(v.params);\n }\n // Tron: the deposit is a send of the input to the Vault, the swap riding in the note.\n if (quote.txRequest || quote.depositAddress !== vault || !quote.depositMemo) return \"a Tron vault swap is a send to the Tron Vault with its note\";\n const n = decodeTronNote(quote.depositMemo);\n if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, dest)) return \"the note names another destination\";\n return checkParams(n.params);\n } catch (e) {\n return `the vault swap does not decode (${(e instanceof Error ? e.message : String(e)).slice(0, 120)})`;\n }\n}\n\n/**\n * The Chainflip Vault a vault swap calls and approves on an EVM chain ({@link CF_VAULTS}), and\n * {@link chainflipVerifyQuote} — the app's pins for `remoteProvider({name: \"chainflip\", baseUrl, ...chainflipPins})`\n * (scan 2026-10-27 modules, F8/F16). A Tron vault swap is a send to the Tron Vault the verifier pins, so the stub is\n * opened to that deposit route (`depositAddressRoutes`, scan 2026-10-28 F9); its note must ride as hex bytes.\n */\nexport const chainflipPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => chainflipVaultFor(chain),\n spenders: (chain: string): readonly string[] => chainflipVaultFor(chain),\n verifyQuote: chainflipVerifyQuote,\n verifyBuild: (quote: Quote, tx: UnsignedTx): string | null =>\n quote.depositMemo && tx.memoEncoding !== \"hex\" ? \"the Tron note is not sent as hex bytes\" : null,\n depositAddressRoutes: true,\n});\nfunction chainflipVaultFor(chain: string): readonly string[] {\n const vault = chain.startsWith(\"eip155:\") && Object.prototype.hasOwnProperty.call(CF_VAULTS, chain) ? CF_VAULTS[chain] : undefined;\n return vault ? [vault] : [];\n}\n","/**\n * Activity recognition for Chainflip vault swaps: the source leg is a call to (EVM) or a transfer into (Tron) the\n * Chainflip Vault — a fixed, well-known counterparty, so the leg is recognizable offline. The destination leg is a\n * transfer from Chainflip's egress keys (rotating), tied back through the intent journal.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {CF_VAULTS} from \"./config.js\";\n\nexport const CHAINFLIP_MODULE = \"@anywalletkit/protocol-swap2-chainflip\";\n\nconst same = (chain: string, a: string | null | undefined, b: string) => !!a && (chain.startsWith(\"eip155:\") ? a.toLowerCase() === b.toLowerCase() : a === b);\n\n/** Wallet history names Tron by its genesis-hash form (`tron:0x2b6653dc`); swap2 routes by chain id (`tron:728126428`). */\nconst CHAIN_ALIAS: Readonly<Record<string, string>> = {\"tron:0x2b6653dc\": \"tron:728126428\"};\n\nexport function describeChainflipActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n const vault = CF_VAULTS[CHAIN_ALIAS[tx.chain] ?? tx.chain];\n if (!vault) return null;\n const toVault = same(tx.chain, (tx as {to?: string}).to, vault) || tx.transfers.some((t) => same(tx.chain, t.to, vault) && ctx.own.has(t.from));\n if (!toVault) return null;\n return describeSwapLike(tx, ctx, {protocol: CHAINFLIP_MODULE, subtitle: \"Chainflip\", kind: \"bridge\", counterparty: vault, inSuffix: \"via Chainflip\"});\n}\n","/**\n * Chainflip provider — VAULT SWAPS through the public backend (chainflip-swap.chainflip.io), Chainflip's own broker at\n * 0 bps, no account or key:\n * quote GET /v2/quote?isVaultSwap=true → expected output, fees, ETA, recommended slippage\n * encode POST /api/encodeVaultSwapData → EVM vault calldata / Tron TRC-20 transfer + note (live quotes only)\n * status GET /v2/swaps/{source tx hash} → RECEIVING … COMPLETED | FAILED, egress / refund tx refs\n * The encoder runs on a server we do not control, so every byte it returns is decoded here and checked against the\n * request before the quote is handed out: vault address, source token and amount, destination chain / asset / address,\n * refund address, the minimum price (it must guarantee our minimum), no boost / DCA / CCM / affiliates, broker fee 0.\n * Fill-or-kill is always on: a price below the minimum after the retry window refunds to the source address.\n */\nimport {describeChainflipActivity} from \"./activity.js\";\nimport {CF_API_DEFAULT, CF_CHAINS, CF_VAULTS, cfAsset, chainflip as cfg} from \"./config.js\";\nimport {decodeEvmVaultCall, decodeTronNote, destAddressBytes, fromHex, minOutOf, minPriceX128For, sameBytes, tronToBytes, type CfParameters} from \"./codec.js\";\nimport {timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {decodeFunctionData, parseAbi, type Hex} from \"viem\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\nconst QUOTE_TTL_MS = 60_000;\n/** 50 state-chain blocks ≈ 5 min of retries before a fill-or-kill refund (the backend's recommendation). */\nconst RETRY_BLOCKS = 50;\nconst MAX_RETRY_BLOCKS = 600;\nconst ERC20 = parseAbi([\"function transfer(address to, uint256 amount) returns (bool)\"]);\n\nexport interface ChainflipProviderConfig {\n enabled?: boolean;\n /** Backend base URL (default the public chainflip-swap.chainflip.io). */\n apiUrl?: string;\n /** Live-price (oracle) slippage guard in bps; null turns it off. Default: the quote's recommendation. */\n maxOraclePriceSlippageBps?: number | null;\n}\n\ninterface CfQuote {\n type?: string;\n egressAmount?: string;\n depositAmount?: string;\n estimatedDurationSeconds?: number;\n recommendedSlippageTolerancePercent?: number;\n recommendedLivePriceSlippageTolerancePercent?: number;\n includedFees?: {type: string; chain: string; asset: string; amount: string}[];\n lowLiquidityWarning?: boolean;\n}\n\n/** The intent id: `cfvault:<source chain>` — vault swaps are tracked by their source transaction. */\nconst INTENT_PREFIX = \"cfvault:\";\n\nexport function chainflipProvider(config: ChainflipProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const base = new URL(config.apiUrl ?? CF_API_DEFAULT).toString().replace(/\\/$/, \"\");\n\n /** One GET/POST with a single back-off on 429 (the backend sits behind a rate-limiting CDN). */\n const call = async (path: string, init: RequestInit = {}, signal?: AbortSignal): Promise<{ok: boolean; status: number; body: unknown}> => {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(`${base}${path}`, {...init, headers: {accept: \"application/json\", ...(init.body ? {\"content-type\": \"application/json\"} : {}), ...(init.headers ?? {})}, signal: signal ?? timeoutSignal(12_000)});\n const body = await res.json().catch(() => null);\n if (res.status === 429 && attempt === 0 && !signal?.aborted) { await new Promise((r) => setTimeout(r, 1200)); continue; }\n return {ok: res.ok, status: res.status, body};\n }\n };\n\n /** Everything the encoder returned must say exactly what we asked; any difference refuses the quote. */\n const checkParams = (p: CfParameters, want: {refund: Uint8Array; minPriceX128: bigint; oracle: number | null}): string | null => {\n if (!sameBytes(fromHex(p.refundAddress), want.refund)) return `refund address ${p.refundAddress} is not the sender`;\n if (p.minPriceX128 < want.minPriceX128) return \"minimum price is below the one requested\";\n if (p.retryDurationBlocks > MAX_RETRY_BLOCKS) return `retry window ${p.retryDurationBlocks} blocks is too long`;\n if (p.maxOraclePriceSlippageBps !== want.oracle) return \"oracle slippage guard differs from the request\";\n if (p.dca !== null) return \"unexpected DCA parameters\";\n if (p.boostFeeBps !== 0) return \"unexpected boost fee\";\n if (p.broker.feeBps !== 0) return `broker takes ${p.broker.feeBps} bps`;\n if (p.affiliates.length) return \"unexpected affiliates\";\n return null;\n };\n\n return {\n name: \"chainflip\",\n describeActivity: describeChainflipActivity,\n enabled: () => config.enabled ?? true,\n supportsChain: (chain: string) => cfg.supportsChain(chain),\n supportsChainPair: (from: string, to: string) => cfg.supports(from, to),\n supportsRoute(from: Asset, to: Asset): boolean {\n if (!cfg.supports(from.chain, to.chain)) return false;\n const a = cfAsset(from.chain, from.token), b = cfAsset(to.chain, to.token);\n return !!a && !!b && a.id !== b.id;\n },\n\n async getQuote(params: QuoteParams, signal?: AbortSignal): Promise<Quote | null> {\n const dry = params.dry !== false;\n const refuse = (reason: string): null => {\n params.onRefusal?.(`chainflip: ${reason}`);\n return null;\n };\n if (!cfg.supports(params.sourceChain, params.destChain)) return refuse(`no vault swap ${params.sourceChain} → ${params.destChain}`);\n const src = cfAsset(params.sourceChain, params.sourceToken);\n const dst = cfAsset(params.destChain, params.destToken);\n if (!src || !dst) return refuse(`asset not listed (${params.sourceToken} on ${params.sourceChain} → ${params.destToken} on ${params.destChain})`);\n const amountIn = BigInt(params.amountIn);\n if (amountIn < src.minDeposit) return refuse(`below the minimum deposit (${src.minDeposit} ${src.asset})`);\n let destBytes: Uint8Array;\n try { destBytes = destAddressBytes(params.destChain, params.destAddress); } catch (e) { return refuse((e as Error).message); }\n\n const qs = new URLSearchParams({amount: params.amountIn, srcChain: src.chain, srcAsset: src.asset, destChain: dst.chain, destAsset: dst.asset, isVaultSwap: \"true\", isOnChain: \"false\", dcaV2Enabled: \"false\"});\n let q: CfQuote | undefined;\n try {\n const r = await call(`/v2/quote?${qs.toString()}`, {}, signal);\n if (!r.ok) return refuse(`quote ${r.status}: ${String((r.body as {message?: string} | null)?.message ?? \"\").slice(0, 160)}`);\n q = (r.body as CfQuote[] | null)?.find((x) => x.type === \"REGULAR\") ?? (r.body as CfQuote[] | null)?.[0];\n } catch (e) { return refuse(`quote failed: ${(e as Error).message.slice(0, 160)}`); }\n if (!q?.egressAmount || !/^\\d+$/.test(q.egressAmount)) return refuse(\"quote without an egress amount\");\n if (q.type && q.type !== \"REGULAR\") return refuse(`${q.type} quotes are not supported`);\n const expected = BigInt(q.egressAmount);\n // Minimum: the expected output less the slippage (the caller's, else the backend's advice), or the\n // caller's floor. A caller who names both is held to both — the engine checks the quote against\n // each (execution sends a floor under the listed quote AND the slippage the list was quoted at).\n const slipBps = params.slippageBps ?? Math.round((q.recommendedSlippageTolerancePercent ?? 1) * 100);\n const byTolerance = (expected * BigInt(10_000 - Math.min(9_999, Math.max(0, slipBps)))) / 10_000n;\n const callerFloor = params.minAmountOut !== undefined ? BigInt(params.minAmountOut) : undefined;\n const minOut = callerFloor === undefined ? byTolerance\n : params.slippageBps !== undefined && byTolerance > callerFloor ? byTolerance : callerFloor;\n if (minOut > expected) return refuse(`floor ${minOut} above the expected output ${expected}`);\n const minPriceX128 = minPriceX128For(amountIn, minOut);\n const guaranteed = minOutOf(amountIn, minPriceX128);\n const oracle = config.maxOraclePriceSlippageBps !== undefined ? config.maxOraclePriceSlippageBps\n : q.recommendedLivePriceSlippageTolerancePercent !== undefined ? Math.round(q.recommendedLivePriceSlippageTolerancePercent * 100) : null;\n const fees = (q.includedFees ?? []).map((f) => ({type: (f.type === \"NETWORK\" ? \"protocol\" : f.type === \"BROKER\" ? \"affiliate\" : \"network\") as \"network\" | \"protocol\" | \"affiliate\", amount: f.amount, token: `${f.chain}:${f.asset}`, included: true, description: `Chainflip ${f.type.toLowerCase()} fee`}));\n const stableUsd = (f: {asset: string; amount: string}) => (f.asset === \"USDC\" || f.asset === \"USDT\" ? Number(f.amount) / 1e6 : 0);\n const common = {\n provider: \"chainflip\",\n sourceAmount: params.amountIn,\n destAmount: q.egressAmount,\n minDestAmount: guaranteed.toString(),\n feeUsd: (q.includedFees ?? []).reduce((s, f) => s + stableUsd(f), 0),\n fees,\n etaSeconds: Math.round(q.estimatedDurationSeconds ?? 180),\n reliability: q.lowLiquidityWarning ? 0.75 : 0.9,\n validUntilMs: Date.now() + QUOTE_TTL_MS,\n };\n if (dry) return {...common, intentId: `dry:${crypto.randomUUID()}`, depositAddress: \"\", depositMemo: null};\n\n if (!params.refundAddress) return refuse(\"live quote without a refund address\");\n let refund: Uint8Array;\n try { refund = destAddressBytes(params.sourceChain, params.refundAddress); } catch (e) { return refuse(`refund address: ${(e as Error).message}`); }\n const body = {\n srcAsset: {chain: src.chain, asset: src.asset}, destAsset: {chain: dst.chain, asset: dst.asset},\n srcAddress: params.refundAddress, destAddress: params.destAddress, amount: params.amountIn,\n fillOrKillParams: {retryDurationBlocks: RETRY_BLOCKS, refundAddress: params.refundAddress, minPriceX128: minPriceX128.toString(), maxOraclePriceSlippage: oracle},\n commissionBps: 0,\n };\n let enc: {to?: string; calldata?: string; value?: string; note?: string; sourceTokenAddress?: string; chain?: string};\n try {\n const r = await call(\"/api/encodeVaultSwapData\", {method: \"POST\", body: JSON.stringify(body)}, signal);\n if (!r.ok) return refuse(`encode ${r.status}: ${String((r.body as {message?: string} | null)?.message ?? \"\").slice(0, 160)}`);\n enc = (r.body ?? {}) as typeof enc;\n } catch (e) { return refuse(`encode failed: ${(e as Error).message.slice(0, 160)}`); }\n const want = {refund, minPriceX128, oracle};\n const vault = CF_VAULTS[params.sourceChain]!;\n const dstChain = CF_CHAINS[params.destChain]!;\n\n try {\n if (params.sourceChain.startsWith(\"eip155:\")) {\n if (!enc.to || enc.to.toLowerCase() !== vault.toLowerCase()) return refuse(`encoder targets ${enc.to}, not the ${src.chain} Vault`);\n const v = decodeEvmVaultCall(enc.calldata ?? \"0x\");\n if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, destBytes)) return refuse(\"encoded destination differs from the request\");\n if (src.token === null) {\n if (!v.native || BigInt(enc.value ?? \"0\") !== amountIn) return refuse(\"native vault call with a different amount\");\n } else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(enc.value ?? \"0\") !== 0n) {\n return refuse(\"token vault call with a different token or amount\");\n }\n const bad = checkParams(v.params, want);\n if (bad) return refuse(bad);\n return {\n ...common,\n intentId: `${INTENT_PREFIX}${params.sourceChain}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: vault, data: enc.calldata!, value: src.token === null ? params.amountIn : \"0\", chainId: Number(params.sourceChain.slice(7)), ...(src.token ? {approvalAddress: vault} : {})},\n providerData: {kind: \"evm\", srcAsset: String(src.id), dstAsset: String(dst.id)},\n };\n }\n // Tron: the deposit IS a plain transfer to the Vault; the swap parameters ride in the transaction note.\n if (enc.to !== vault) return refuse(`encoder targets ${enc.to}, not the Tron Vault`);\n if (!enc.note) return refuse(\"Tron vault swap without a note\");\n if (src.token !== null) {\n if (enc.sourceTokenAddress !== src.token) return refuse(`source token ${enc.sourceTokenAddress} is not ${src.asset}`);\n const t = decodeFunctionData({abi: ERC20, data: (enc.calldata ?? \"0x\") as Hex});\n if (!sameBytes(fromHex(String(t.args[0])), tronToBytes(vault)) || t.args[1] !== amountIn) return refuse(\"TRC-20 transfer is not the amount to the Vault\");\n }\n const n = decodeTronNote(enc.note);\n if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, destBytes)) return refuse(\"note names another destination\");\n const bad = checkParams(n.params, want);\n if (bad) return refuse(bad);\n return {\n ...common,\n intentId: `${INTENT_PREFIX}${params.sourceChain}`,\n depositAddress: vault,\n depositMemo: enc.note,\n providerData: {kind: \"tron\", memoEncoding: \"hex\", srcAsset: String(src.id), dstAsset: String(dst.id)},\n };\n } catch (e) {\n return refuse(`encoder output does not decode: ${(e as Error).message.slice(0, 160)}`);\n }\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n if (quote.providerData?.kind === \"evm\") {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw new Error(\"chainflip: quote has no vault call\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.approvalAddress ? {approvalAddress: tx.approvalAddress} : {})};\n }\n if (quote.providerData?.kind === \"tron\") {\n if (!quote.depositAddress || !quote.depositMemo) throw new Error(\"chainflip: Tron quote without vault or note\");\n return {chain: \"\", to: quote.depositAddress, value: quote.sourceAmount, memo: quote.depositMemo, memoEncoding: \"hex\"};\n }\n throw new Error(\"chainflip: not a live vault-swap quote\");\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const id = ref.intentId.startsWith(`${INTENT_PREFIX}tron:`) ? ref.sourceTxHash.replace(/^0x/, \"\") : ref.sourceTxHash;\n try {\n const r = await call(`/v2/swaps/${encodeURIComponent(id)}`);\n if (r.status === 404) return {state: \"pending\"}; // not witnessed yet\n if (!r.ok) return {state: \"pending\"};\n const s = (r.body ?? {}) as {state?: string; swapEgress?: {txRef?: string}; refundEgress?: {txRef?: string}; fallbackEgress?: {txRef?: string}; deposit?: {txRef?: string}};\n const egress = s.swapEgress?.txRef;\n const refunded = !!(s.refundEgress || s.fallbackEgress);\n if (s.state === \"COMPLETED\" || (s.state === \"SENT\" && egress)) {\n // Fill-or-kill: only a refund went out → refunded; swapped in part and refunded the rest → partial (round 3, M26).\n if (!s.swapEgress && refunded) return {state: \"refunded\", depositReceived: true};\n if (s.swapEgress && refunded) return {state: \"partial\", depositReceived: true, ...(egress ? {destTxHash: egress} : {})};\n return {state: \"completed\", depositReceived: true, ...(egress ? {destTxHash: egress} : {})};\n }\n if (s.state === \"FAILED\") return s.refundEgress || s.fallbackEgress ? {state: \"refunded\", depositReceived: true} : {state: \"failed\", depositReceived: true};\n const received = s.state === \"RECEIVING\" || s.state === \"SWAPPING\" || s.state === \"SENDING\" || s.state === \"SENT\";\n return {state: \"pending\", depositReceived: received};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {chainflip as cfCfg} from \"./config.js\";\nimport {chainflipProvider, type ChainflipProviderConfig} from \"./provider.js\";\n\nexport interface ChainflipSwap2Config extends Swap2EngineConfig, ChainflipProviderConfig {}\n\n/** Standalone Chainflip swap2: vault swaps from Ethereum, Arbitrum and Tron to every Chainflip chain. */\nexport class ChainflipSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n constructor(account: Swap2Account | undefined, config: ChainflipSwap2Config) {\n super(account, config);\n this.provider = chainflipProvider(config);\n }\n protected override chainSupported(caip2: string): boolean {\n return cfCfg.supportsChain(caip2);\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return cfCfg.supports(fromChain, toChain);\n }\n}\n"],"mappings":"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","names":["dstChain","dstAddress","dstToken","cf","import_viem","bad"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/codec.ts","../src/activity.ts","../src/provider.ts","../src/protocol.ts"],"sourcesContent":["export * from \"./config.js\";\nexport * from \"./provider.js\";\nexport * from \"./codec.js\";\nexport {ChainflipSwap2Protocol, type ChainflipSwap2Config} from \"./protocol.js\";\nexport {ChainflipSwap2Protocol as default} from \"./protocol.js\";\nexport * from \"./activity.js\";\n","/**\n * Chainflip (JIT-AMM state chain) — chains, assets and contracts as the public backend and the vault encodings name them.\n * Asset ids, chain ids and decimals are the protocol's own (`cf_environment` / networkInfo, verified 2026-10-20); the\n * contract addresses are Chainflip's mainnet deployments (docs mainnet-addresses, confirmed by live encodings).\n *\n * Only VAULT SWAPS are offered: the donor signs a transaction whose every Chainflip parameter (destination, minimum price,\n * refund address) is decoded and checked locally before signing — no off-chain deposit channel to trust, and on Tron no\n * 3.4 USDT ingress fee. Sources: EVM (Ethereum, Arbitrum) and Tron in this release; Solana / Bitcoin vault swaps need an\n * instruction / OP_RETURN builder and come next. Destinations: every live chain.\n */\nimport {refusalNotes} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport type {Quote, QuoteParams, RemotePins, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\nimport {decodeEvmVaultCall, decodeTronNote, destAddressBytes, fromHex, minOutOf, sameBytes, type CfParameters} from \"./codec.js\";\n\nexport type CfChain = \"Ethereum\" | \"Bitcoin\" | \"Arbitrum\" | \"Solana\" | \"Tron\";\n\nexport interface CfAsset {\n chain: CfChain;\n /** the API's asset symbol */\n asset: string;\n /** the u32 asset id inside vault encodings */\n id: number;\n decimals: number;\n /** token contract / mint on its chain, null for the native coin */\n token: string | null;\n /** smallest deposit the state chain accepts (base units) */\n minDeposit: bigint;\n}\n\n/**\n * CAIP-2 → Chainflip chain: `id` = the ForeignChain number an EVM vault call names (`dstChain`), `addrTag` = the\n * EncodedAddress variant a Tron note names (Eth 0, Dot 1, Btc 2, Arb 3, Sol 4, Hub 5, Tron 6) — two different enums.\n */\nexport const CF_CHAINS: Readonly<Record<string, {name: CfChain; id: number; addrTag: number}>> = {\n \"eip155:1\": {name: \"Ethereum\", id: 1, addrTag: 0},\n \"bitcoin:mainnet\": {name: \"Bitcoin\", id: 3, addrTag: 2},\n \"eip155:42161\": {name: \"Arbitrum\", id: 4, addrTag: 3},\n \"solana:mainnet\": {name: \"Solana\", id: 5, addrTag: 4},\n \"tron:728126428\": {name: \"Tron\", id: 7, addrTag: 6},\n};\n\nexport const CF_ASSETS: readonly CfAsset[] = [\n {chain: \"Ethereum\", asset: \"ETH\", id: 1, decimals: 18, token: null, minDeposit: 10n ** 16n},\n {chain: \"Ethereum\", asset: \"USDC\", id: 3, decimals: 6, token: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\", minDeposit: 20_000_000n},\n {chain: \"Ethereum\", asset: \"USDT\", id: 8, decimals: 6, token: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\", minDeposit: 20_000_000n},\n {chain: \"Ethereum\", asset: \"WBTC\", id: 14, decimals: 8, token: \"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599\", minDeposit: 40_000n},\n {chain: \"Bitcoin\", asset: \"BTC\", id: 5, decimals: 8, token: null, minDeposit: 40_000n},\n {chain: \"Arbitrum\", asset: \"ETH\", id: 6, decimals: 18, token: null, minDeposit: 3_900_000_000_000_000n},\n {chain: \"Arbitrum\", asset: \"USDC\", id: 7, decimals: 6, token: \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\", minDeposit: 10_000_000n},\n {chain: \"Arbitrum\", asset: \"USDT\", id: 15, decimals: 6, token: \"0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9\", minDeposit: 10_000_000n},\n {chain: \"Solana\", asset: \"SOL\", id: 9, decimals: 9, token: null, minDeposit: 68_000_000n},\n {chain: \"Solana\", asset: \"USDC\", id: 10, decimals: 6, token: \"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\", minDeposit: 10_000_000n},\n {chain: \"Solana\", asset: \"USDT\", id: 16, decimals: 6, token: \"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\", minDeposit: 10_000_000n},\n {chain: \"Tron\", asset: \"TRX\", id: 17, decimals: 6, token: null, minDeposit: 30_000_000n},\n {chain: \"Tron\", asset: \"USDT\", id: 18, decimals: 6, token: \"TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t\", minDeposit: 10_000_000n},\n];\n\n/** Vault contracts that receive vault swaps (the deposit transaction's target). */\nexport const CF_VAULTS: Readonly<Record<string, string>> = {\n \"eip155:1\": \"0xF5e10380213880111522dd0efD3dbb45b9f62Bcc\",\n \"eip155:42161\": \"0x79001a5e762f3bEFC8e5871b42F6734e00498920\",\n \"tron:728126428\": \"TEcDijvKSXcfWT7S6rd44H5vNgufm7Y4XC\",\n};\n\n/** Sources this release signs (vault swaps the engine can execute and the verifier can decode). */\nexport const CF_SOURCE_CHAINS = new Set([\"eip155:1\", \"eip155:42161\", \"tron:728126428\"]);\n\nexport const CF_API_DEFAULT = \"https://chainflip-swap.chainflip.io\";\n\nconst sameToken = (chain: string, a: string, b: string) => (chain.startsWith(\"eip155:\") ? a.toLowerCase() === b.toLowerCase() : a === b);\nconst NATIVE = new Set([\"\", \"native\", \"0x0000000000000000000000000000000000000000\"]);\n\n/** The Chainflip asset for a CAIP-2 chain + token (contract / mint, a native marker, or the asset symbol). */\nexport function cfAsset(chain: string, token: string): CfAsset | undefined {\n const c = CF_CHAINS[chain];\n if (!c) return undefined;\n const on = CF_ASSETS.filter((a) => a.chain === c.name);\n if (NATIVE.has(token.toLowerCase())) return on.find((a) => a.token === null);\n return on.find((a) => (a.token !== null && sameToken(chain, a.token, token)) || a.asset === token.toUpperCase());\n}\n\nexport const chainflip = {\n supportsChain: (chain: string) => !!CF_CHAINS[chain],\n supports: (from: string, to: string) => CF_SOURCE_CHAINS.has(from) && !!CF_CHAINS[to] && from !== to,\n};\n\n/** The reason behind each text {@link chainflipVerifyQuote} and the pins' verifyBuild return (`chainflipPins.reasonOf`). */\nconst notes = refusalNotes();\n/**\n * Decode-failure texts last returned for the app's own field (destination, refund address, amount) that did not parse:\n * the caller's argument, so `reasonOf` leaves them unclassified. The same text can come from a quote that does not\n * decode, so the latest verdict wins; kept to the last 64.\n */\nconst unparsed = new Set<string>();\nfunction decodeFailure(text: string, requestParsed: boolean): string {\n unparsed.delete(text);\n if (requestParsed) return notes.note(text, \"upstream_unavailable\");\n unparsed.add(text);\n if (unparsed.size > 64) unparsed.delete(unparsed.values().next().value!);\n return text;\n}\nconst reasonOf = (text: string) => (unparsed.has(text) ? undefined : notes.reasonOf(text));\n\n/**\n * The provider's own decode of a vault swap, run on the client against the app's request (scan 2026-10-28, F9): an\n * EVM source is a vault call (`xSwapNative` / `xSwapToken`) on the pinned Vault, a Tron source a send to the pinned\n * Tron Vault whose note carries the swap; either way the destination chain, asset and address, the source token and\n * amount, the refund address and a minimum price that guarantees the quoted minimum must be the app's, with no DCA,\n * boost, broker fee or affiliates. The reason it fails, or null.\n */\nexport function chainflipVerifyQuote(params: QuoteParams, quote: Quote): string | null {\n // True while the app's own fields are read: a throw then is the caller's argument, not the quote's.\n let readingRequest = false;\n try {\n const src = cfAsset(params.sourceChain, params.sourceToken);\n const dst = cfAsset(params.destChain, params.destToken);\n const dstChain = CF_CHAINS[params.destChain];\n const vault = Object.prototype.hasOwnProperty.call(CF_VAULTS, params.sourceChain) ? CF_VAULTS[params.sourceChain] : undefined;\n if (!src || !dst || !dstChain || !vault || !CF_SOURCE_CHAINS.has(params.sourceChain)) return notes.note(\"not a vault swap this release signs\", \"unsupported_pair\");\n // A dry quote lists a route and pays nobody; execution re-quotes live.\n if (!quote.txRequest && !quote.depositAddress) return null;\n if (!params.refundAddress) return notes.note(\"a live quote needs the refund address\", \"policy_refused\");\n readingRequest = true;\n const amountIn = BigInt(params.amountIn);\n const dest = destAddressBytes(params.destChain, params.destAddress);\n const refund = destAddressBytes(params.sourceChain, params.refundAddress);\n readingRequest = false;\n const checkParams = (p: CfParameters): string | null => {\n if (!sameBytes(fromHex(p.refundAddress), refund)) return notes.note(\"the refund address is not the sender\", \"recipient_mismatch\");\n if (minOutOf(amountIn, p.minPriceX128) < BigInt(quote.minDestAmount)) return notes.note(\"the minimum price does not guarantee the quoted minimum\", \"price_check_failed\");\n if (p.dca !== null || p.boostFeeBps !== 0 || p.broker.feeBps !== 0 || p.affiliates.length) return notes.note(\"DCA, boost, a broker fee or affiliates\", \"policy_refused\");\n return null;\n };\n if (params.sourceChain.startsWith(\"eip155:\")) {\n const tx = quote.txRequest;\n if (quote.depositAddress || !tx?.data || tx.serializedTx !== undefined) return notes.note(\"an EVM vault swap is a vault call, not a deposit\", \"policy_refused\");\n if (!tx.to || tx.to.toLowerCase() !== vault.toLowerCase()) return notes.note(`the call targets ${tx.to}, not the Vault`, \"vault_mismatch\");\n const v = decodeEvmVaultCall(tx.data);\n if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, dest)) return notes.note(\"the vault call names another destination\", \"recipient_mismatch\");\n if (src.token === null) {\n if (!v.native || BigInt(tx.value ?? \"0\") !== amountIn || tx.approvalAddress) return notes.note(\"the native vault call moves another amount\", \"policy_refused\");\n } else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(tx.value ?? \"0\") !== 0n ||\n tx.approvalAddress?.toLowerCase() !== vault.toLowerCase()) {\n return notes.note(\"the token vault call moves another token or amount\", \"policy_refused\");\n }\n return checkParams(v.params);\n }\n // Tron: the deposit is a send of the input to the Vault, the swap riding in the note.\n if (quote.txRequest || quote.depositAddress !== vault || !quote.depositMemo) {\n // A send elsewhere is the wrong vault; a send to the Vault without its note binds no destination.\n return notes.note(\"a Tron vault swap is a send to the Tron Vault with its note\",\n quote.txRequest ? \"policy_refused\" : quote.depositAddress !== vault ? \"vault_mismatch\" : \"recipient_unverifiable\");\n }\n const n = decodeTronNote(quote.depositMemo);\n if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, dest)) return notes.note(\"the note names another destination\", \"recipient_mismatch\");\n return checkParams(n.params);\n } catch (e) {\n return decodeFailure(`the vault swap does not decode (${(e instanceof Error ? e.message : String(e)).slice(0, 120)})`, !readingRequest);\n }\n}\n\n/**\n * The Chainflip Vault a vault swap calls and approves on an EVM chain ({@link CF_VAULTS}), and\n * {@link chainflipVerifyQuote} — the app's pins for `remoteProvider({name: \"chainflip\", baseUrl, ...chainflipPins})`\n * (scan 2026-10-27 modules, F8/F16). A Tron vault swap is a send to the Tron Vault the verifier pins, so the stub is\n * opened to that deposit route (`depositAddressRoutes`, scan 2026-10-28 F9); its note must ride as hex bytes. `reasonOf`\n * classifies each text the verifiers return (`Swap2RefusalReason`), so a remote stub's refusal carries it.\n */\nexport const chainflipPins: RemotePins = Object.freeze({\n callTargets: (chain: string): readonly string[] => chainflipVaultFor(chain),\n spenders: (chain: string): readonly string[] => chainflipVaultFor(chain),\n verifyQuote: chainflipVerifyQuote,\n verifyBuild: (quote: Quote, tx: UnsignedTx): string | null =>\n quote.depositMemo && tx.memoEncoding !== \"hex\" ? notes.note(\"the Tron note is not sent as hex bytes\", \"policy_refused\") : null,\n reasonOf,\n depositAddressRoutes: true,\n});\nfunction chainflipVaultFor(chain: string): readonly string[] {\n const vault = chain.startsWith(\"eip155:\") && Object.prototype.hasOwnProperty.call(CF_VAULTS, chain) ? CF_VAULTS[chain] : undefined;\n return vault ? [vault] : [];\n}\n","/**\n * Decoders for what Chainflip's encoder returns, so a vault swap is checked byte by byte before anyone signs it:\n * - VersionedCfParameters (SCALE): retry window, refund address, minimum price (X128), oracle slippage, DCA, boost,\n * broker + its fee, affiliates — the EVM vault call's `cfParameters` and the tail of the Tron note;\n * - the Tron note: output asset id, encoded destination address, CCM option, then the length-prefixed parameters;\n * - the EVM vault calls xSwapNative / xSwapToken.\n * Layouts were decoded from live encoder outputs (2026-10-20) and match the state chain's types.\n */\nimport {base58} from \"@scure/base\";\nimport {sha256} from \"@noble/hashes/sha2.js\";\nimport {decodeFunctionData, parseAbi, type Hex} from \"viem\";\n\nexport interface CfParameters {\n version: number;\n retryDurationBlocks: number;\n /** raw refund address bytes (20 for EVM / Tron, 32 for Solana) as 0x-hex */\n refundAddress: Hex;\n /** minimum output price × 2^128, scaled by 10^(destDecimals − srcDecimals) */\n minPriceX128: bigint;\n refundCcm: boolean;\n maxOraclePriceSlippageBps: number | null;\n dca: {chunks: number; intervalBlocks: number} | null;\n boostFeeBps: number;\n broker: {account: Hex; feeBps: number};\n affiliates: {account: number; feeBps: number}[];\n}\n\nclass Reader {\n i = 0;\n constructor(readonly b: Uint8Array) {}\n need(n: number) { if (this.i + n > this.b.length) throw new Error(`chainflip codec: truncated at ${this.i} (+${n} of ${this.b.length})`); }\n u8() { this.need(1); return this.b[this.i++]!; }\n bytes(n: number) { this.need(n); const out = this.b.slice(this.i, this.i + n); this.i += n; return out; }\n uLE(n: number): bigint { const x = this.bytes(n); let v = 0n; for (let k = n - 1; k >= 0; k--) v = (v << 8n) | BigInt(x[k]!); return v; }\n /** Little-endian unsigned of up to 6 bytes as a number (exact: below 2^48). */\n uNum(n: number): number { if (n > 6) throw new Error(\"chainflip codec: uNum takes at most 6 bytes\"); const x = this.bytes(n); let v = 0; for (let k = n - 1; k >= 0; k--) v = v * 256 + x[k]!; return v; }\n /** SCALE compact integer */\n compact(): number {\n const first = this.u8();\n const mode = first & 3;\n if (mode === 0) return first >> 2;\n if (mode === 1) return ((this.u8() << 8) | first) >> 2;\n if (mode === 2) { const rest = this.uNum(3); return ((rest << 8) | first) >>> 2; }\n throw new Error(\"chainflip codec: big compact integers are not used here\");\n }\n done() { if (this.i !== this.b.length) throw new Error(`chainflip codec: ${this.b.length - this.i} trailing bytes`); }\n}\n\nexport const toHex = (b: Uint8Array): Hex => `0x${[...b].map((x) => x.toString(16).padStart(2, \"0\")).join(\"\")}` as Hex;\nexport function fromHex(h: string): Uint8Array {\n const s = h.startsWith(\"0x\") ? h.slice(2) : h;\n if (s.length % 2 || /[^0-9a-f]/i.test(s)) throw new Error(\"chainflip codec: not hex\");\n return Uint8Array.from(s.match(/../g) ?? [], (x) => Number.parseInt(x, 16));\n}\n\n/** VersionedCfParameters V1. `refundLen` = 20 for EVM / Tron sources, 32 for Solana. */\nexport function decodeCfParameters(bytes: Uint8Array, refundLen: 20 | 32): CfParameters {\n const r = new Reader(bytes);\n const p = readCfParameters(r, refundLen);\n r.done();\n return p;\n}\n\nfunction readCfParameters(r: Reader, refundLen: number): CfParameters {\n const version = r.u8();\n if (version !== 1) throw new Error(`chainflip codec: cf parameters version ${version}`);\n // ccm_additional_data is `()` for non-CCM swaps: zero bytes\n const retryDurationBlocks = r.uNum(4);\n const refundAddress = toHex(r.bytes(refundLen));\n const minPriceX128 = r.uLE(32);\n const refundCcm = r.u8() !== 0;\n if (refundCcm) throw new Error(\"chainflip codec: refund CCM metadata is not expected\");\n const maxOraclePriceSlippageBps = r.u8() ? r.uNum(2) : null;\n const dca = r.u8() ? {chunks: r.uNum(4), intervalBlocks: r.uNum(4)} : null;\n const boostFeeBps = r.u8();\n const broker = {account: toHex(r.bytes(32)), feeBps: r.uNum(2)};\n const n = r.compact();\n const affiliates = Array.from({length: n}, () => ({account: r.u8(), feeBps: r.uNum(2)}));\n return {version, retryDurationBlocks, refundAddress, minPriceX128, refundCcm, maxOraclePriceSlippageBps, dca, boostFeeBps, broker, affiliates};\n}\n\nexport interface TronNote {\n outputAsset: number;\n /** EncodedAddress variant of the destination (Eth 0, Dot 1, Btc 2, Arb 3, Sol 4, Hub 5, Tron 6) and its raw bytes */\n destTag: number;\n destAddress: Uint8Array;\n ccm: boolean;\n params: CfParameters;\n}\n\n/** Address byte length per encoded-address tag (EncodedAddress enum: Eth, Dot, Btc, Arb, Sol, Hub, Tron …). */\nconst TAG_LEN: Record<number, number | \"vec\"> = {0: 20, 1: 32, 2: \"vec\", 3: 20, 4: 32, 5: 32, 6: 20};\n\n/** The note a Tron vault swap carries in raw_data.data. */\nexport function decodeTronNote(note: string): TronNote {\n const r = new Reader(fromHex(note));\n const outputAsset = r.u8();\n const destTag = r.u8();\n const len = TAG_LEN[destTag];\n if (len === undefined) throw new Error(`chainflip codec: unknown address tag ${destTag}`);\n const destAddress = len === \"vec\" ? r.bytes(r.compact()) : r.bytes(len);\n const ccm = r.u8() !== 0;\n if (ccm) throw new Error(\"chainflip codec: CCM swaps are not expected\");\n const paramsLen = r.compact();\n const start = r.i;\n const params = readCfParameters(r, 20);\n if (r.i - start !== paramsLen) throw new Error(`chainflip codec: cf parameters length ${r.i - start} ≠ declared ${paramsLen}`);\n r.done();\n return {outputAsset, destTag, destAddress, ccm, params};\n}\n\nconst VAULT_ABI = parseAbi([\n \"function xSwapNative(uint32 dstChain, bytes dstAddress, uint32 dstToken, bytes cfParameters) payable\",\n \"function xSwapToken(uint32 dstChain, bytes dstAddress, uint32 dstToken, address srcToken, uint256 amount, bytes cfParameters)\",\n]);\n\nexport interface EvmVaultCall {\n native: boolean;\n dstChain: number;\n dstAddress: Uint8Array;\n dstToken: number;\n srcToken: string | null;\n amount: bigint | null;\n params: CfParameters;\n}\n\nexport function decodeEvmVaultCall(data: string): EvmVaultCall {\n const d = decodeFunctionData({abi: VAULT_ABI, data: data as Hex});\n if (d.functionName === \"xSwapNative\") {\n const [dstChain, dstAddress, dstToken, cf] = d.args;\n return {native: true, dstChain, dstAddress: fromHex(dstAddress), dstToken, srcToken: null, amount: null, params: decodeCfParameters(fromHex(cf), 20)};\n }\n const [dstChain, dstAddress, dstToken, srcToken, amount, cf] = d.args;\n return {native: false, dstChain, dstAddress: fromHex(dstAddress), dstToken, srcToken, amount, params: decodeCfParameters(fromHex(cf), 20)};\n}\n\n/** Tron base58check `T…` ↔ the 20 raw bytes Chainflip encodes (0x41 prefix dropped). */\nexport function tronToBytes(address: string): Uint8Array {\n const b = base58.decode(address);\n if (b.length !== 25 || b[0] !== 0x41) throw new Error(`not a Tron address: ${address}`);\n const check = sha256(sha256(b.subarray(0, 21))).subarray(0, 4);\n if (toHex(check) !== toHex(b.subarray(21))) throw new Error(`bad Tron checksum: ${address}`);\n return b.subarray(1, 21);\n}\n\n/** The raw bytes a destination address is encoded with, per destination chain (EVM / Tron 20, Solana 32, BTC ASCII). */\nexport function destAddressBytes(chain: string, address: string): Uint8Array {\n if (chain.startsWith(\"eip155:\")) return fromHex(address);\n if (chain.startsWith(\"tron:\")) return tronToBytes(address);\n if (chain.startsWith(\"solana:\")) { const b = base58.decode(address); if (b.length !== 32) throw new Error(`not a Solana address: ${address}`); return b; }\n if (chain.startsWith(\"bitcoin:\")) return new TextEncoder().encode(address);\n throw new Error(`chainflip: no address encoding for ${chain}`);\n}\n\nexport const sameBytes = (a: Uint8Array, b: Uint8Array) => a.length === b.length && a.every((x, i) => x === b[i]);\n\n/** minPriceX128 for a guaranteed output: ceil(minOut × 2^128 / amountIn) (base units on both sides carry the decimals). */\nexport function minPriceX128For(amountIn: bigint, minOut: bigint): bigint {\n return (minOut * 2n ** 128n + amountIn - 1n) / amountIn;\n}\n/** The output a min price guarantees for `amountIn` (floor). */\nexport function minOutOf(amountIn: bigint, minPriceX128: bigint): bigint {\n return (amountIn * minPriceX128) / 2n ** 128n;\n}\n","/**\n * Activity recognition for Chainflip vault swaps: the source leg is a call to (EVM) or a transfer into (Tron) the\n * Chainflip Vault — a fixed, well-known counterparty, so the leg is recognizable offline. The destination leg is a\n * transfer from Chainflip's egress keys (rotating), tied back through the intent journal.\n */\nimport type {ActivityItem, ChainTx, DescribeActivityContext} from \"@anywalletkit/core\";\nimport {describeSwapLike} from \"@anywalletkit/protocol-swap2-core/activity\";\nimport {CF_VAULTS} from \"./config.js\";\n\nexport const CHAINFLIP_MODULE = \"@anywalletkit/protocol-swap2-chainflip\";\n\nconst same = (chain: string, a: string | null | undefined, b: string) => !!a && (chain.startsWith(\"eip155:\") ? a.toLowerCase() === b.toLowerCase() : a === b);\n\n/** Wallet history names Tron by its genesis-hash form (`tron:0x2b6653dc`); swap2 routes by chain id (`tron:728126428`). */\nconst CHAIN_ALIAS: Readonly<Record<string, string>> = {\"tron:0x2b6653dc\": \"tron:728126428\"};\n\nexport function describeChainflipActivity(tx: ChainTx, ctx: DescribeActivityContext): ActivityItem | null {\n const vault = CF_VAULTS[CHAIN_ALIAS[tx.chain] ?? tx.chain];\n if (!vault) return null;\n const toVault = same(tx.chain, (tx as {to?: string}).to, vault) || tx.transfers.some((t) => same(tx.chain, t.to, vault) && ctx.own.has(t.from));\n if (!toVault) return null;\n return describeSwapLike(tx, ctx, {protocol: CHAINFLIP_MODULE, subtitle: \"Chainflip\", kind: \"bridge\", counterparty: vault, inSuffix: \"via Chainflip\"});\n}\n","/**\n * Chainflip provider — VAULT SWAPS through the public backend (chainflip-swap.chainflip.io), Chainflip's own broker at\n * 0 bps, no account or key:\n * quote GET /v2/quote?isVaultSwap=true → expected output, fees, ETA, recommended slippage\n * encode POST /api/encodeVaultSwapData → EVM vault calldata / Tron TRC-20 transfer + note (live quotes only)\n * status GET /v2/swaps/{source tx hash} → RECEIVING … COMPLETED | FAILED, egress / refund tx refs\n * The encoder runs on a server we do not control, so every byte it returns is decoded here and checked against the\n * request before the quote is handed out: vault address, source token and amount, destination chain / asset / address,\n * refund address, the minimum price (it must guarantee our minimum), no boost / DCA / CCM / affiliates, broker fee 0.\n * Fill-or-kill is always on: a price below the minimum after the retry window refunds to the source address.\n */\nimport {describeChainflipActivity} from \"./activity.js\";\nimport {CF_API_DEFAULT, CF_CHAINS, CF_VAULTS, cfAsset, chainflip as cfg} from \"./config.js\";\nimport {decodeEvmVaultCall, decodeTronNote, destAddressBytes, fromHex, minOutOf, minPriceX128For, sameBytes, tronToBytes, type CfParameters} from \"./codec.js\";\nimport {httpRefusal, refusal, refusalNotes, type Swap2RefusalInfo, type Swap2RefusalReason} from \"@anywalletkit/protocol-swap2-core/errors\";\nimport {timeoutSignal} from \"@anywalletkit/protocol-swap2-core/util\";\nimport {decodeFunctionData, parseAbi, type Hex} from \"viem\";\nimport type {Asset, CrossChainProvider, IntentRef, IntentStatus, Quote, QuoteParams, UnsignedTx} from \"@anywalletkit/protocol-swap2-core/types\";\n\nconst QUOTE_TTL_MS = 60_000;\n/** 50 state-chain blocks ≈ 5 min of retries before a fill-or-kill refund (the backend's recommendation). */\nconst RETRY_BLOCKS = 50;\nconst MAX_RETRY_BLOCKS = 600;\nconst ERC20 = parseAbi([\"function transfer(address to, uint256 amount) returns (bool)\"]);\n\nexport interface ChainflipProviderConfig {\n enabled?: boolean;\n /** Backend base URL (default the public chainflip-swap.chainflip.io). */\n apiUrl?: string;\n /** Live-price (oracle) slippage guard in bps; null turns it off. Default: the quote's recommendation. */\n maxOraclePriceSlippageBps?: number | null;\n}\n\ninterface CfQuote {\n type?: string;\n egressAmount?: string;\n depositAmount?: string;\n estimatedDurationSeconds?: number;\n recommendedSlippageTolerancePercent?: number;\n recommendedLivePriceSlippageTolerancePercent?: number;\n includedFees?: {type: string; chain: string; asset: string; amount: string}[];\n lowLiquidityWarning?: boolean;\n}\n\n/** The intent id: `cfvault:<source chain>` — vault swaps are tracked by their source transaction. */\nconst INTENT_PREFIX = \"cfvault:\";\n\n/** The reason behind each text `checkParams` returns. */\nconst notes = refusalNotes();\n\n/**\n * What a failed backend answer means: the backend's own message first (limits, liquidity, a halted pool), else the\n * status (429 with Retry-After, 408 / 425 / 5xx). The backend takes no key, so a 401 / 403 (a CDN, WAF or region block\n * in front of it) is `upstream_unavailable` with its status, never `key_rejected`. Undefined when neither says.\n */\nfunction backendRefusal(status: number, body: unknown, retryAfter: string | null): Swap2RefusalInfo | undefined {\n const http = httpRefusal(status, retryAfter);\n const byStatus: Swap2RefusalInfo | undefined = http?.reason === \"key_rejected\" ? {reason: \"upstream_unavailable\", httpStatus: status} : http;\n if (byStatus?.reason === \"rate_limited\") return byStatus;\n const m = (body as {message?: unknown} | null)?.message;\n const said = typeof m === \"string\" ? backendReason(m) : undefined;\n return said && said !== byStatus?.reason ? {reason: said} : byStatus;\n}\nfunction backendReason(message: string): Swap2RefusalReason | undefined {\n if (/liquidity/i.test(message)) return \"insufficient_liquidity\";\n if (/maximum (?:swap )?amount|above (?:the )?max|too (?:large|big|high)|exceeds? (?:the )?max/i.test(message)) return \"amount_too_large\";\n if (/minimum (?:swap |deposit )?amount|below (?:the )?minimum|lower than (?:the )?(?:estimated|minimum)|too (?:small|low)/i.test(message)) return \"amount_too_small\";\n if (/halt|paus|maintenance|disabled|suspend|not enabled/i.test(message)) return \"chain_halted\";\n if (/rate.?limit|too many requests/i.test(message)) return \"rate_limited\";\n if (/not supported|unsupported|unknown asset|invalid asset/i.test(message)) return \"unsupported_pair\";\n if (/no (?:route|quote)|could not find/i.test(message)) return \"no_route\";\n return undefined;\n}\n\nexport function chainflipProvider(config: ChainflipProviderConfig = {}): CrossChainProvider {\n config = Object.freeze({...config});\n const base = new URL(config.apiUrl ?? CF_API_DEFAULT).toString().replace(/\\/$/, \"\");\n\n /** One GET/POST with a single back-off on 429 (the backend sits behind a rate-limiting CDN). */\n const call = async (path: string, init: RequestInit = {}, signal?: AbortSignal): Promise<{ok: boolean; status: number; body: unknown; retryAfter: string | null}> => {\n for (let attempt = 0; ; attempt++) {\n const res = await fetch(`${base}${path}`, {...init, headers: {accept: \"application/json\", ...(init.body ? {\"content-type\": \"application/json\"} : {}), ...(init.headers ?? {})}, signal: signal ?? timeoutSignal(12_000)});\n const body = await res.json().catch(() => null);\n if (res.status === 429 && attempt === 0 && !signal?.aborted) { await new Promise((r) => setTimeout(r, 1200)); continue; }\n return {ok: res.ok, status: res.status, body, retryAfter: res.headers?.get?.(\"retry-after\") ?? null};\n }\n };\n\n /** Everything the encoder returned must say exactly what we asked; any difference refuses the quote. */\n const checkParams = (p: CfParameters, want: {refund: Uint8Array; minPriceX128: bigint; oracle: number | null}): string | null => {\n if (!sameBytes(fromHex(p.refundAddress), want.refund)) return notes.note(`refund address ${p.refundAddress} is not the sender`, \"recipient_mismatch\");\n if (p.minPriceX128 < want.minPriceX128) return notes.note(\"minimum price is below the one requested\", \"price_check_failed\");\n if (p.retryDurationBlocks > MAX_RETRY_BLOCKS) return notes.note(`retry window ${p.retryDurationBlocks} blocks is too long`, \"policy_refused\");\n if (p.maxOraclePriceSlippageBps !== want.oracle) return notes.note(\"oracle slippage guard differs from the request\", \"price_check_failed\");\n if (p.dca !== null) return notes.note(\"unexpected DCA parameters\", \"policy_refused\");\n if (p.boostFeeBps !== 0) return notes.note(\"unexpected boost fee\", \"policy_refused\");\n if (p.broker.feeBps !== 0) return notes.note(`broker takes ${p.broker.feeBps} bps`, \"policy_refused\");\n if (p.affiliates.length) return notes.note(\"unexpected affiliates\", \"policy_refused\");\n return null;\n };\n\n return {\n name: \"chainflip\",\n describeActivity: describeChainflipActivity,\n enabled: () => config.enabled ?? true,\n supportsChain: (chain: string) => cfg.supportsChain(chain),\n supportsChainPair: (from: string, to: string) => cfg.supports(from, to),\n supportsRoute(from: Asset, to: Asset): boolean {\n if (!cfg.supports(from.chain, to.chain)) return false;\n const a = cfAsset(from.chain, from.token), b = cfAsset(to.chain, to.token);\n return !!a && !!b && a.id !== b.id;\n },\n\n async getQuote(params: QuoteParams, signal?: AbortSignal): Promise<Quote | null> {\n const dry = params.dry !== false;\n const refuse = (reason: string, why?: Swap2RefusalReason | Swap2RefusalInfo): null => {\n const info = typeof why === \"string\" ? {reason: why} : why;\n if (info) params.onRefusal?.(`chainflip: ${reason}`, info);\n else params.onRefusal?.(`chainflip: ${reason}`);\n return null;\n };\n // A network failure or our own timeout is the backend's; the caller's abort is not.\n const unreachable = (): Swap2RefusalReason | undefined => (signal?.aborted ? undefined : \"upstream_unavailable\");\n if (!cfg.supports(params.sourceChain, params.destChain)) return refuse(`no vault swap ${params.sourceChain} → ${params.destChain}`, \"unsupported_pair\");\n const src = cfAsset(params.sourceChain, params.sourceToken);\n const dst = cfAsset(params.destChain, params.destToken);\n if (!src || !dst) return refuse(`asset not listed (${params.sourceToken} on ${params.sourceChain} → ${params.destToken} on ${params.destChain})`, \"unsupported_pair\");\n const amountIn = BigInt(params.amountIn);\n if (amountIn < src.minDeposit) return refuse(`below the minimum deposit (${src.minDeposit} ${src.asset})`, \"amount_too_small\");\n let destBytes: Uint8Array;\n try { destBytes = destAddressBytes(params.destChain, params.destAddress); } catch (e) { return refuse((e as Error).message); }\n\n const qs = new URLSearchParams({amount: params.amountIn, srcChain: src.chain, srcAsset: src.asset, destChain: dst.chain, destAsset: dst.asset, isVaultSwap: \"true\", isOnChain: \"false\", dcaV2Enabled: \"false\"});\n let q: CfQuote | undefined;\n let answered: unknown;\n try {\n const r = await call(`/v2/quote?${qs.toString()}`, {}, signal);\n if (!r.ok) return refuse(`quote ${r.status}: ${String((r.body as {message?: string} | null)?.message ?? \"\").slice(0, 160)}`, backendRefusal(r.status, r.body, r.retryAfter));\n answered = r.body;\n q = (r.body as CfQuote[] | null)?.find((x) => x.type === \"REGULAR\") ?? (r.body as CfQuote[] | null)?.[0];\n } catch (e) { return refuse(`quote failed: ${(e as Error).message.slice(0, 160)}`, unreachable()); }\n // An empty list is no quote for the pair; anything else without an amount is an answer of another shape, unless\n // the caller aborted while the body was read (it reads as null then).\n if (!q?.egressAmount || !/^\\d+$/.test(q.egressAmount)) return refuse(\"quote without an egress amount\", Array.isArray(answered) && answered.length === 0 ? \"no_route\" : unreachable());\n if (q.type && q.type !== \"REGULAR\") return refuse(`${q.type} quotes are not supported`, \"unsupported_pair\");\n const expected = BigInt(q.egressAmount);\n // Minimum: the expected output less the slippage (the caller's, else the backend's advice), or the\n // caller's floor. A caller who names both is held to both — the engine checks the quote against\n // each (execution sends a floor under the listed quote AND the slippage the list was quoted at).\n const slipBps = params.slippageBps ?? Math.round((q.recommendedSlippageTolerancePercent ?? 1) * 100);\n const byTolerance = (expected * BigInt(10_000 - Math.min(9_999, Math.max(0, slipBps)))) / 10_000n;\n const callerFloor = params.minAmountOut !== undefined ? BigInt(params.minAmountOut) : undefined;\n const minOut = callerFloor === undefined ? byTolerance\n : params.slippageBps !== undefined && byTolerance > callerFloor ? byTolerance : callerFloor;\n if (minOut > expected) return refuse(`floor ${minOut} above the expected output ${expected}`, \"price_check_failed\");\n const minPriceX128 = minPriceX128For(amountIn, minOut);\n const guaranteed = minOutOf(amountIn, minPriceX128);\n const oracle = config.maxOraclePriceSlippageBps !== undefined ? config.maxOraclePriceSlippageBps\n : q.recommendedLivePriceSlippageTolerancePercent !== undefined ? Math.round(q.recommendedLivePriceSlippageTolerancePercent * 100) : null;\n const fees = (q.includedFees ?? []).map((f) => ({type: (f.type === \"NETWORK\" ? \"protocol\" : f.type === \"BROKER\" ? \"affiliate\" : \"network\") as \"network\" | \"protocol\" | \"affiliate\", amount: f.amount, token: `${f.chain}:${f.asset}`, included: true, description: `Chainflip ${f.type.toLowerCase()} fee`}));\n const stableUsd = (f: {asset: string; amount: string}) => (f.asset === \"USDC\" || f.asset === \"USDT\" ? Number(f.amount) / 1e6 : 0);\n const common = {\n provider: \"chainflip\",\n sourceAmount: params.amountIn,\n destAmount: q.egressAmount,\n minDestAmount: guaranteed.toString(),\n feeUsd: (q.includedFees ?? []).reduce((s, f) => s + stableUsd(f), 0),\n fees,\n etaSeconds: Math.round(q.estimatedDurationSeconds ?? 180),\n reliability: q.lowLiquidityWarning ? 0.75 : 0.9,\n validUntilMs: Date.now() + QUOTE_TTL_MS,\n };\n if (dry) return {...common, intentId: `dry:${crypto.randomUUID()}`, depositAddress: \"\", depositMemo: null};\n\n if (!params.refundAddress) return refuse(\"live quote without a refund address\", \"policy_refused\");\n let refund: Uint8Array;\n try { refund = destAddressBytes(params.sourceChain, params.refundAddress); } catch (e) { return refuse(`refund address: ${(e as Error).message}`); }\n const body = {\n srcAsset: {chain: src.chain, asset: src.asset}, destAsset: {chain: dst.chain, asset: dst.asset},\n srcAddress: params.refundAddress, destAddress: params.destAddress, amount: params.amountIn,\n fillOrKillParams: {retryDurationBlocks: RETRY_BLOCKS, refundAddress: params.refundAddress, minPriceX128: minPriceX128.toString(), maxOraclePriceSlippage: oracle},\n commissionBps: 0,\n };\n let enc: {to?: string; calldata?: string; value?: string; note?: string; sourceTokenAddress?: string; chain?: string};\n try {\n const r = await call(\"/api/encodeVaultSwapData\", {method: \"POST\", body: JSON.stringify(body)}, signal);\n if (!r.ok) return refuse(`encode ${r.status}: ${String((r.body as {message?: string} | null)?.message ?? \"\").slice(0, 160)}`, backendRefusal(r.status, r.body, r.retryAfter));\n enc = (r.body ?? {}) as typeof enc;\n } catch (e) { return refuse(`encode failed: ${(e as Error).message.slice(0, 160)}`, unreachable()); }\n const want = {refund, minPriceX128, oracle};\n const vault = CF_VAULTS[params.sourceChain]!;\n const dstChain = CF_CHAINS[params.destChain]!;\n\n // An answer without a target at all is a malformed one (a body that is not JSON, `{}`, or the caller's abort while\n // it was read), not another vault.\n try {\n if (params.sourceChain.startsWith(\"eip155:\")) {\n if (!enc.to || enc.to.toLowerCase() !== vault.toLowerCase()) return refuse(`encoder targets ${enc.to}, not the ${src.chain} Vault`, !enc.to ? unreachable() : \"vault_mismatch\");\n const v = decodeEvmVaultCall(enc.calldata ?? \"0x\");\n if (v.dstChain !== dstChain.id || v.dstToken !== dst.id || !sameBytes(v.dstAddress, destBytes)) return refuse(\"encoded destination differs from the request\", \"recipient_mismatch\");\n if (src.token === null) {\n if (!v.native || BigInt(enc.value ?? \"0\") !== amountIn) return refuse(\"native vault call with a different amount\", \"policy_refused\");\n } else if (v.native || v.srcToken?.toLowerCase() !== src.token.toLowerCase() || v.amount !== amountIn || BigInt(enc.value ?? \"0\") !== 0n) {\n return refuse(\"token vault call with a different token or amount\", \"policy_refused\");\n }\n const bad = checkParams(v.params, want);\n if (bad) return refuse(bad, notes.reasonOf(bad));\n return {\n ...common,\n intentId: `${INTENT_PREFIX}${params.sourceChain}`,\n depositAddress: \"\",\n depositMemo: null,\n txRequest: {to: vault, data: enc.calldata!, value: src.token === null ? params.amountIn : \"0\", chainId: Number(params.sourceChain.slice(7)), ...(src.token ? {approvalAddress: vault} : {})},\n providerData: {kind: \"evm\", srcAsset: String(src.id), dstAsset: String(dst.id)},\n };\n }\n // Tron: the deposit IS a plain transfer to the Vault; the swap parameters ride in the transaction note.\n if (enc.to !== vault) return refuse(`encoder targets ${enc.to}, not the Tron Vault`, !enc.to ? unreachable() : \"vault_mismatch\");\n if (!enc.note) return refuse(\"Tron vault swap without a note\", \"recipient_unverifiable\");\n if (src.token !== null) {\n if (enc.sourceTokenAddress !== src.token) return refuse(`source token ${enc.sourceTokenAddress} is not ${src.asset}`, \"policy_refused\");\n const t = decodeFunctionData({abi: ERC20, data: (enc.calldata ?? \"0x\") as Hex});\n const toVault = sameBytes(fromHex(String(t.args[0])), tronToBytes(vault));\n if (!toVault || t.args[1] !== amountIn) return refuse(\"TRC-20 transfer is not the amount to the Vault\", toVault ? \"policy_refused\" : \"vault_mismatch\");\n }\n const n = decodeTronNote(enc.note);\n if (n.outputAsset !== dst.id || n.destTag !== dstChain.addrTag || !sameBytes(n.destAddress, destBytes)) return refuse(\"note names another destination\", \"recipient_mismatch\");\n const bad = checkParams(n.params, want);\n if (bad) return refuse(bad, notes.reasonOf(bad));\n return {\n ...common,\n intentId: `${INTENT_PREFIX}${params.sourceChain}`,\n depositAddress: vault,\n depositMemo: enc.note,\n providerData: {kind: \"tron\", memoEncoding: \"hex\", srcAsset: String(src.id), dstAsset: String(dst.id)},\n };\n } catch (e) {\n return refuse(`encoder output does not decode: ${(e as Error).message.slice(0, 160)}`, \"upstream_unavailable\");\n }\n },\n\n async buildDeposit(quote: Quote): Promise<UnsignedTx> {\n if (quote.providerData?.kind === \"evm\") {\n const tx = quote.txRequest;\n if (!tx?.to || !tx.data) throw refusal(\"policy_refused\", \"chainflip: quote has no vault call\");\n return {chain: \"\", to: tx.to, value: tx.value ?? \"0\", data: tx.data, ...(tx.chainId !== undefined ? {chainId: tx.chainId} : {}), ...(tx.approvalAddress ? {approvalAddress: tx.approvalAddress} : {})};\n }\n if (quote.providerData?.kind === \"tron\") {\n if (!quote.depositAddress || !quote.depositMemo) throw refusal(\"policy_refused\", \"chainflip: Tron quote without vault or note\");\n return {chain: \"\", to: quote.depositAddress, value: quote.sourceAmount, memo: quote.depositMemo, memoEncoding: \"hex\"};\n }\n throw refusal(\"policy_refused\", \"chainflip: not a live vault-swap quote\");\n },\n\n async trackIntent(ref: IntentRef): Promise<IntentStatus> {\n if (!ref.sourceTxHash) return {state: \"pending\"};\n const id = ref.intentId.startsWith(`${INTENT_PREFIX}tron:`) ? ref.sourceTxHash.replace(/^0x/, \"\") : ref.sourceTxHash;\n try {\n const r = await call(`/v2/swaps/${encodeURIComponent(id)}`);\n if (r.status === 404) return {state: \"pending\"}; // not witnessed yet\n if (!r.ok) return {state: \"pending\"};\n const s = (r.body ?? {}) as {state?: string; swapEgress?: {txRef?: string}; refundEgress?: {txRef?: string}; fallbackEgress?: {txRef?: string}; deposit?: {txRef?: string}};\n const egress = s.swapEgress?.txRef;\n const refunded = !!(s.refundEgress || s.fallbackEgress);\n if (s.state === \"COMPLETED\" || (s.state === \"SENT\" && egress)) {\n // Fill-or-kill: only a refund went out → refunded; swapped in part and refunded the rest → partial (round 3, M26).\n if (!s.swapEgress && refunded) return {state: \"refunded\", depositReceived: true};\n if (s.swapEgress && refunded) return {state: \"partial\", depositReceived: true, ...(egress ? {destTxHash: egress} : {})};\n return {state: \"completed\", depositReceived: true, ...(egress ? {destTxHash: egress} : {})};\n }\n if (s.state === \"FAILED\") return s.refundEgress || s.fallbackEgress ? {state: \"refunded\", depositReceived: true} : {state: \"failed\", depositReceived: true};\n const received = s.state === \"RECEIVING\" || s.state === \"SWAPPING\" || s.state === \"SENDING\" || s.state === \"SENT\";\n return {state: \"pending\", depositReceived: received};\n } catch {\n return {state: \"pending\"};\n }\n },\n };\n}\n\n","import {SingleProviderSwap2} from \"@anywalletkit/protocol-swap2-core/swap2/single\";\nimport type {Swap2Account, Swap2EngineConfig} from \"@anywalletkit/protocol-swap2-core/swap2/base\";\nimport {chainflip as cfCfg} from \"./config.js\";\nimport {chainflipProvider, type ChainflipProviderConfig} from \"./provider.js\";\n\nexport interface ChainflipSwap2Config extends Swap2EngineConfig, ChainflipProviderConfig {}\n\n/** Standalone Chainflip swap2: vault swaps from Ethereum, Arbitrum and Tron to every Chainflip chain. */\nexport class ChainflipSwap2Protocol extends SingleProviderSwap2 {\n protected readonly provider;\n constructor(account: Swap2Account | undefined, config: ChainflipSwap2Config) {\n super(account, config);\n this.provider = chainflipProvider(config);\n }\n protected override chainSupported(caip2: string): boolean {\n return cfCfg.supportsChain(caip2);\n }\n protected override pairSupported(fromChain: string, toChain: string): boolean {\n return cfCfg.supports(fromChain, toChain);\n }\n}\n"],"mappings":"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","names":["dstChain","dstAddress","dstToken","cf","import_errors","import_viem","notes","bad"]}
|